From 4594bc722ec6c234aaf7dbbb753756386a9fdf6e Mon Sep 17 00:00:00 2001 From: Jens Krause <47693+sectore@users.noreply.github.com> Date: Thu, 9 Oct 2025 20:04:29 +0200 Subject: [PATCH] feat(event): Show percentage `until` event (#122) using `get_percentage_done` --- src/app.rs | 4 +-- src/widgets/event.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index fbbc012..a419696 100644 --- a/src/app.rs +++ b/src/app.rs @@ -213,7 +213,7 @@ impl App { event: EventState::new(EventStateArgs { app_time, event_time: time::PrimitiveDateTime::parse( - "2030-10-03 15:00:00", + "2025-10-09 19:54:29", format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"), ) .unwrap(), @@ -427,7 +427,7 @@ impl App { Content::Countdown => Some(self.countdown.get_clock().get_percentage_done()), Content::Timer => None, Content::Pomodoro => Some(self.pomodoro.get_clock().get_percentage_done()), - Content::Event => None, + Content::Event => Some(self.event.get_percentage_done()), Content::LocalTime => None, } } diff --git a/src/widgets/event.rs b/src/widgets/event.rs index a77b130..e3499ab 100644 --- a/src/widgets/event.rs +++ b/src/widgets/event.rs @@ -20,6 +20,7 @@ pub struct EventState { title: String, event_time: OffsetDateTime, app_time: OffsetDateTime, + start_time: OffsetDateTime, with_decis: bool, } @@ -51,6 +52,7 @@ impl EventState { title: event_title, event_time: event_offset, app_time: app_datetime, + start_time: app_datetime, with_decis, } } @@ -63,6 +65,10 @@ impl EventState { pub fn set_with_decis(&mut self, with_decis: bool) { self.with_decis = with_decis; } + + pub fn get_percentage_done(&self) -> u16 { + get_percentage(self.start_time, self.event_time, self.app_time) + } } impl TuiEventHandler for EventState { @@ -71,6 +77,23 @@ impl TuiEventHandler for EventState { } } +fn get_percentage(start: OffsetDateTime, end: OffsetDateTime, current: OffsetDateTime) -> u16 { + let total_millis = (end - start).whole_milliseconds(); + + if total_millis <= 0 { + return 100; + } + + let elapsed_millis = (current - start).whole_milliseconds(); + + if elapsed_millis <= 0 { + return 0; + } + + let percentage = (elapsed_millis * 100 / total_millis).min(100); + percentage as u16 +} + #[derive(Debug)] pub struct EventWidget { pub style: Style, @@ -148,3 +171,45 @@ impl StatefulWidget for EventWidget { label_event.centered().render(v3, buf); } } + +#[cfg(test)] +mod tests { + use super::*; + use time::macros::datetime; + + #[test] + fn test_get_percentage() { + let start = datetime!(2024-01-01 10:00:00 UTC); + let end = datetime!(2024-01-01 20:00:00 UTC); + + // current == start: 0% + assert_eq!(get_percentage(start, end, start), 0); + + // current == end: 100% + assert_eq!(get_percentage(start, end, end), 100); + + // current halfway: 50% + let halfway = datetime!(2024-01-01 15:00:00 UTC); + assert_eq!(get_percentage(start, end, halfway), 50); + + // current 25% + let quarter = datetime!(2024-01-01 12:30:00 UTC); + assert_eq!(get_percentage(start, end, quarter), 25); + + // current 75% + let three_quarters = datetime!(2024-01-01 17:30:00 UTC); + assert_eq!(get_percentage(start, end, three_quarters), 75); + + // current > end: clamped to 100% + let after = datetime!(2024-01-01 22:00:00 UTC); + assert_eq!(get_percentage(start, end, after), 100); + + // current < start: 0% + let before = datetime!(2024-01-01 08:00:00 UTC); + assert_eq!(get_percentage(start, end, before), 0); + + // end <= start: 100% + assert_eq!(get_percentage(end, start, halfway), 100); + assert_eq!(get_percentage(start, start, start), 100); + } +}