mirror of
https://github.com/CodeZeno/Claude-Code-Usage-Monitor.git
synced 2026-06-20 10:19:27 +08:00
refactor: thread detailed flag through countdown formatter
Adds a `detailed: bool` parameter to `format_line`, `format_countdown`, `format_countdown_from_secs`, `time_until_display_change`, and `time_until_display_change_from_secs`. When `true`, sub-units are surfaced (Xh Ym for hours, Xd Yh for days) and the display-change tick fires on minute/hour boundaries to match. All callers pass `false`, so behavior is unchanged. The toggle that flips this is added in a later commit.
This commit is contained in:
parent
71ddfe3ccf
commit
8f8d5d072d
@ -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<SystemTime>, strings: Strings) -> String {
|
||||
fn format_countdown(resets_at: Option<SystemTime>, 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<SystemTime>, 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<SystemTime>) -> Option<Duration> {
|
||||
pub fn time_until_display_change(
|
||||
resets_at: Option<SystemTime>,
|
||||
detailed: bool,
|
||||
) -> Option<Duration> {
|
||||
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 {
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user