diff --git a/src/poller.rs b/src/poller.rs index 5bd02bc..d379722 100644 --- a/src/poller.rs +++ b/src/poller.rs @@ -1021,9 +1021,9 @@ fn is_leap(y: u64) -> bool { } /// Format a usage section as "X% ยท Yh" style text -pub fn format_line(section: &UsageSection, strings: Strings) -> String { +pub fn format_line(section: &UsageSection, strings: Strings, detailed: bool) -> String { let pct = format!("{:.0}%", section.percentage); - let cd = format_countdown(section.resets_at, strings); + let cd = format_countdown(section.resets_at, strings, detailed); if cd.is_empty() { pct } else { @@ -1031,7 +1031,7 @@ pub fn format_line(section: &UsageSection, strings: Strings) -> String { } } -fn format_countdown(resets_at: Option, strings: Strings) -> String { +fn format_countdown(resets_at: Option, strings: Strings, detailed: bool) -> String { let reset = match resets_at { Some(t) => t, None => return String::new(), @@ -1042,25 +1042,47 @@ fn format_countdown(resets_at: Option, strings: Strings) -> String { Err(_) => return strings.now.to_string(), }; - format_countdown_from_secs(remaining.as_secs(), strings) + format_countdown_from_secs(remaining.as_secs(), strings, detailed) } /// Calculate how long until the display text would change -pub fn time_until_display_change(resets_at: Option) -> Option { +pub fn time_until_display_change( + resets_at: Option, + detailed: bool, +) -> Option { let reset = resets_at?; let remaining = reset.duration_since(SystemTime::now()).ok()?; - Some(time_until_display_change_from_secs(remaining.as_secs())) + Some(time_until_display_change_from_secs( + remaining.as_secs(), + detailed, + )) } -fn format_countdown_from_secs(total_secs: u64, strings: Strings) -> String { +fn format_countdown_from_secs(total_secs: u64, strings: Strings, detailed: bool) -> String { let total_mins = total_secs / 60; let total_hours = total_secs / 3600; let total_days = total_secs / 86400; if total_days >= 1 { - format!("{total_days}{}", strings.day_suffix) + if detailed { + let hours = total_hours % 24; + format!( + "{total_days}{} {hours}{}", + strings.day_suffix, strings.hour_suffix + ) + } else { + format!("{total_days}{}", strings.day_suffix) + } } else if total_hours >= 1 { - format!("{total_hours}{}", strings.hour_suffix) + if detailed { + let mins = total_mins % 60; + format!( + "{total_hours}{} {mins}{}", + strings.hour_suffix, strings.minute_suffix + ) + } else { + format!("{total_hours}{}", strings.hour_suffix) + } } else if total_mins >= 1 { format!("{total_mins}{}", strings.minute_suffix) } else { @@ -1068,15 +1090,23 @@ fn format_countdown_from_secs(total_secs: u64, strings: Strings) -> String { } } -fn time_until_display_change_from_secs(total_secs: u64) -> Duration { +fn time_until_display_change_from_secs(total_secs: u64, detailed: bool) -> Duration { let total_mins = total_secs / 60; let total_hours = total_secs / 3600; let total_days = total_secs / 86400; let current_bucket_start = if total_days >= 1 { - total_days * 86400 + if detailed { + total_hours * 3600 + } else { + total_days * 86400 + } } else if total_hours >= 1 { - total_hours * 3600 + if detailed { + total_mins * 60 + } else { + total_hours * 3600 + } } else if total_mins >= 1 { total_mins * 60 } else { diff --git a/src/window.rs b/src/window.rs index 7ce1dea..c9ab697 100644 --- a/src/window.rs +++ b/src/window.rs @@ -420,16 +420,16 @@ fn refresh_usage_texts(state: &mut AppState) { }; if let Some(claude_code) = data.claude_code.as_ref() { - state.session_text = poller::format_line(&claude_code.session, strings); - state.weekly_text = poller::format_line(&claude_code.weekly, strings); + state.session_text = poller::format_line(&claude_code.session, strings, false); + state.weekly_text = poller::format_line(&claude_code.weekly, strings, false); } else if state.show_claude_code { state.session_text = "!".to_string(); state.weekly_text = "!".to_string(); } if let Some(codex) = data.codex.as_ref() { - state.codex_session_text = poller::format_line(&codex.session, strings); - state.codex_weekly_text = poller::format_line(&codex.weekly, strings); + state.codex_session_text = poller::format_line(&codex.session, strings, false); + state.codex_weekly_text = poller::format_line(&codex.weekly, strings, false); } else if state.show_codex { state.codex_session_text = "!".to_string(); state.codex_weekly_text = "!".to_string(); @@ -1634,16 +1634,16 @@ fn schedule_countdown_timer() { let delays = [ data.claude_code .as_ref() - .and_then(|usage| poller::time_until_display_change(usage.session.resets_at)), + .and_then(|usage| poller::time_until_display_change(usage.session.resets_at, false)), data.claude_code .as_ref() - .and_then(|usage| poller::time_until_display_change(usage.weekly.resets_at)), + .and_then(|usage| poller::time_until_display_change(usage.weekly.resets_at, false)), data.codex .as_ref() - .and_then(|usage| poller::time_until_display_change(usage.session.resets_at)), + .and_then(|usage| poller::time_until_display_change(usage.session.resets_at, false)), data.codex .as_ref() - .and_then(|usage| poller::time_until_display_change(usage.weekly.resets_at)), + .and_then(|usage| poller::time_until_display_change(usage.weekly.resets_at, false)), ]; let min_delay = delays.into_iter().flatten().min();