This commit is contained in:
2022-10-24 22:20:55 +02:00
parent 91ca707245
commit 2370faa718
3 changed files with 62 additions and 28 deletions

View File

@ -101,11 +101,17 @@ pub async fn lights_task(state: &State) {
ClientMessage::SetBulbWakeTime { id, day, time } => {
if let Err(e) = lights_state.update(|lights_state| {
let schedule = lights_state.wake_schedule.entry(id.clone()).or_default();
schedule.insert(day, time);
if let Some(time) = time {
schedule.insert(day, time);
}
else {
schedule.remove(&day);
}
}).await {
error!("Failed to save wake schedule: {e}");
};
if let Some(time) = time {
let handle = spawn(wake_task(
state.client_message.subscribe(),
cmd.clone(),
@ -113,8 +119,13 @@ pub async fn lights_task(state: &State) {
day,
time,
));
if let Some(old_handle) = wake_tasks.insert((id, day), handle) {
old_handle.abort();
}} else {
if let Some(old_handle) = wake_tasks.remove(&(id, day)) {
old_handle.abort();
}
}
}
_ => {}

View File

@ -38,7 +38,7 @@ pub enum ClientMessage {
SetBulbWakeTime {
id: BulbId,
day: Weekday,
time: NaiveTime,
time: Option<NaiveTime>,
},
}

View File

@ -6,23 +6,30 @@ use lighter_lib::{BulbId, BulbMode};
use seed::prelude::*;
use seed::{attrs, button, div, input, C};
use seed_router::Page;
use std::collections::{BTreeMap, HashSet};
use std::collections::{BTreeMap, HashSet, HashMap};
use std::fmt::Write;
/// /lights page
#[derive(Default)]
pub struct Model {
bulb_states: BTreeMap<BulbId, BulbMode>,
bulb_states: BTreeMap<BulbId, BulbState>,
bulb_map: BulbMap,
/// The currently selected bulb map groups
/// the currently selected bulb map groups
selected_groups: HashSet<usize>,
/// Whether the currently selected map groups have been interacted with
/// whether the currently selected map groups have been interacted with
groups_interacted: bool,
color_picker: ColorPicker,
}
#[derive(Default, Clone)]
struct BulbState {
mode: BulbMode,
wake_schedule: HashMap<Weekday, NaiveTime>,
}
#[derive(Debug)]
@ -50,7 +57,11 @@ impl Page for Model {
match msg {
Msg::ServerMessage(msg) => match msg {
ServerMessage::BulbState { id, mode: new_mode, wake_schedule } => {
*self.bulb_states.entry(id).or_default() = new_mode
*self.bulb_states.entry(id).or_default() = BulbState {
mode: new_mode,
wake_schedule,
};
//color_picker.set_color(mode.color);
}
ServerMessage::BulbMap(bulb_map) => {
@ -82,7 +93,7 @@ impl Page for Model {
.and_then(|id| self.bulb_states.get(id));
if let Some(bulb) = bulb {
self.color_picker.set_color(bulb.color);
self.color_picker.set_color(bulb.mode.color);
}
}
}
@ -111,12 +122,22 @@ impl Page for Model {
});
}
Msg::LightTime(time, day) => {
if let Ok(time) = NaiveTime::parse_from_str(&time, "%H:%M") {
if time == "" {
self.for_selected_bulbs(|id, _| {
let message = ClientMessage::SetBulbWakeTime {
id: id.clone(),
day,
time,
time: None,
};
orders.notify(message);
});
}
else if let Ok(time) = NaiveTime::parse_from_str(&time, "%H:%M") {
self.for_selected_bulbs(|id, _| {
let message = ClientMessage::SetBulbWakeTime {
id: id.clone(),
day,
time: Some(time),
};
orders.notify(message);
});
@ -200,27 +221,29 @@ fn view(&self) -> Node<Self::Msg> {
]
};
let calendar_day = |day: Weekday| {
div![
C![C.calendar_day],
day.to_string(),
input![
C![C.calendar_time_input],
attrs! {At::Placeholder => "7:30"},
input_ev(Ev::Input, move |input| Msg::LightTime(input, day))
],
]
};
let (_color, power) = self
let selected_bulb = self
.selected_groups
.iter()
.next()
.and_then(|&index| self.bulb_map.groups.get(index))
.and_then(|group| group.bulbs.first())
.and_then(|id| self.bulb_states.get(id))
.map(|bulb| (bulb.color, bulb.power))
.cloned() // TODO: remove clone
.unwrap_or_default();
let calendar_day = |day: Weekday| {
let time = selected_bulb.wake_schedule.get(&day).map(|t| t.to_string()).unwrap_or_default();
div![
C![C.calendar_day],
day.to_string(),
input![
C![C.calendar_time_input],
attrs! {At::Placeholder => time},
input_ev(Ev::Input, move |input| Msg::LightTime(input, day))
],
]
};
div![
C![C.bulb_box],
@ -238,12 +261,12 @@ fn view(&self) -> Node<Self::Msg> {
.view()
.map_msg(|msg| Msg::ColorPicker(msg)),
button![
if power {
if selected_bulb.mode.power {
C![C.bulb_power_button, C.bulb_power_button_on]
} else {
C![C.bulb_power_button]
},
ev(Ev::Click, move |_| Msg::SetBulbPower(!power)),
ev(Ev::Click, move |_| Msg::SetBulbPower(!selected_bulb.mode.power)),
div![attrs! { At::Id => "switch_socket" }],
div![attrs! { At::Id => "off_label" }, "Off"],
div![attrs! { At::Id => "on_label" }, "On"],
@ -266,7 +289,7 @@ fn view(&self) -> Node<Self::Msg> {
}
impl Model {
fn for_selected_bulbs(&self, mut f: impl FnMut(&BulbId, &BulbMode)) {
fn for_selected_bulbs(&self, mut f: impl FnMut(&BulbId, &BulbState)) {
self.selected_groups
.iter()
.filter_map(|&index| self.bulb_map.groups.get(index))