use super::prelude::*;
use crate::subprocess::spawn_shell;
use std::time::{Duration, Instant};
#[derive(Deserialize, Debug, SmartDefault)]
#[serde(deny_unknown_fields, default)]
pub struct Config {
pub format: FormatConfig,
pub increment: Option<u64>,
pub done_cmd: Option<String>,
}
pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
let mut actions = api.get_actions()?;
api.set_default_actions(&[
(MouseButton::Left, None, "increment"),
(MouseButton::WheelUp, None, "increment"),
(MouseButton::WheelDown, None, "decrement"),
(MouseButton::Right, None, "reset"),
])?;
let interval: Seconds = 1.into();
let mut timer = interval.timer();
let format = config
.format
.with_default(" $icon {$time.duration(hms:true) |}")?;
let increment = Duration::from_secs(config.increment.unwrap_or(30));
let mut timer_end = Instant::now();
let mut timer_was_active = false;
loop {
let mut widget = Widget::new().with_format(format.clone());
let remaining_time = timer_end - Instant::now();
let is_timer_active = !remaining_time.is_zero();
if !is_timer_active
&& timer_was_active
&& let Some(cmd) = &config.done_cmd
{
spawn_shell(cmd).error("done_cmd error")?;
}
timer_was_active = is_timer_active;
let mut values = map!(
"icon" => Value::icon("tea"),
);
if is_timer_active {
values.insert("time".into(), Value::duration(remaining_time));
let mut seconds = remaining_time.as_secs();
if format.contains_key("hours") {
let hours = seconds / 3_600;
values.insert("hours".into(), Value::text(format!("{hours:02}")));
seconds %= 3_600;
}
if format.contains_key("minutes") {
let minutes = seconds / 60;
values.insert("minutes".into(), Value::text(format!("{minutes:02}")));
seconds %= 60;
}
values.insert("seconds".into(), Value::text(format!("{seconds:02}")));
}
widget.set_values(values);
api.set_widget(widget)?;
select! {
_ = timer.tick(), if is_timer_active => (),
_ = api.wait_for_update_request() => (),
Some(action) = actions.recv() => {
let now = Instant::now();
match action.as_ref() {
"increment" if is_timer_active => timer_end += increment,
"increment" => timer_end = now + increment,
"decrement" if is_timer_active => timer_end -= increment,
"reset" => timer_end = now,
_ => (),
}
}
}
}
}