feat: label remaining time with 'rem' in ETD mode and widen column to fit

This commit is contained in:
Carlos Miguel C. Resurreccion 2026-06-19 18:37:39 +08:00
parent 270f5c4226
commit ae55c05622
13 changed files with 28 additions and 11 deletions

View File

@ -44,5 +44,6 @@ pub(super) const STRINGS: Strings = Strings {
codex_window_title: "Codex-gebruiksmonitor",
show_etd: "Toon ETD",
etd_suffix: "ETD",
rem: "rem",
second_suffix: "s",
};

View File

@ -44,5 +44,6 @@ pub(super) const STRINGS: Strings = Strings {
codex_window_title: "Codex Usage Monitor",
show_etd: "Show ETD",
etd_suffix: "ETD",
rem: "rem",
second_suffix: "s",
};

View File

@ -44,5 +44,6 @@ pub(super) const STRINGS: Strings = Strings {
codex_window_title: "Moniteur d'utilisation Codex",
show_etd: "Afficher l'ETD",
etd_suffix: "ETD",
rem: "rem",
second_suffix: "s",
};

View File

@ -44,5 +44,6 @@ pub(super) const STRINGS: Strings = Strings {
codex_window_title: "Codex-Nutzungsmonitor",
show_etd: "ETD anzeigen",
etd_suffix: "ETD",
rem: "rem",
second_suffix: "s",
};

View File

@ -44,5 +44,6 @@ pub(super) const STRINGS: Strings = Strings {
codex_window_title: "Codex 使用量モニター",
show_etd: "ETD を表示",
etd_suffix: "ETD",
rem: "rem",
second_suffix: "秒",
};

View File

@ -44,5 +44,6 @@ pub(super) const STRINGS: Strings = Strings {
codex_window_title: "Codex 사용량 모니터",
show_etd: "ETD 표시",
etd_suffix: "ETD",
rem: "rem",
second_suffix: "초",
};

View File

@ -179,6 +179,7 @@ pub struct Strings {
pub codex_window_title: &'static str,
pub show_etd: &'static str,
pub etd_suffix: &'static str,
pub rem: &'static str,
}
pub fn resolve_language(language_override: Option<LanguageId>) -> LanguageId {

View File

@ -45,4 +45,5 @@ pub(super) const STRINGS: Strings = Strings {
codex_window_title: "Monitor de uso do Codex",
show_etd: "Mostrar ETD",
etd_suffix: "ETD",
rem: "rem",
};

View File

@ -45,4 +45,5 @@ pub(super) const STRINGS: Strings = Strings {
codex_window_title: "Монитор использования Codex",
show_etd: "Показывать ETD",
etd_suffix: "ETD",
rem: "rem",
};

View File

@ -44,5 +44,6 @@ pub(super) const STRINGS: Strings = Strings {
codex_window_title: "Monitor de uso de Codex",
show_etd: "Mostrar ETD",
etd_suffix: "ETD",
rem: "rem",
second_suffix: "s",
};

View File

@ -44,5 +44,6 @@ pub(super) const STRINGS: Strings = Strings {
codex_window_title: "Codex 使用量監控",
show_etd: "顯示 ETD",
etd_suffix: "ETD",
rem: "rem",
second_suffix: "秒",
};

View File

@ -1127,15 +1127,20 @@ fn etd_secs(actual_pct: f64, remaining_secs: u64, window_secs: u64) -> Option<u6
(secs < remaining_secs).then_some(secs)
}
/// The trailing " · 45m ETD" segment for a usage cell, or `None` when the
/// section is not on pace to deplete before reset. Reuses the same coarse,
/// The trailing " rem · 45m ETD" segment for a usage cell, or `None` when the
/// section is not on pace to deplete before reset. The leading `rem` labels the
/// preceding countdown (which `format_line` left unlabeled) so the remaining
/// time and the depletion estimate are distinguishable. Reuses the same coarse,
/// single-unit duration format as the countdown.
pub fn etd_suffix(section: &UsageSection, window_secs: u64, strings: Strings) -> Option<String> {
let reset = section.resets_at?;
let remaining_secs = reset.duration_since(SystemTime::now()).ok()?.as_secs();
let secs = etd_secs(section.percentage, remaining_secs, window_secs)?;
let dur = format_countdown_from_secs(secs, strings);
Some(format!(" \u{00b7} {dur} {}", strings.etd_suffix))
Some(format!(
" {} \u{00b7} {dur} {}",
strings.rem, strings.etd_suffix
))
}
#[cfg(test)]
@ -1158,7 +1163,8 @@ mod tests {
let out = etd_suffix(&s, 2 * 3600, LanguageId::English.strings());
let out = out.expect("expected a suffix when at risk");
assert!(out.contains("ETD"), "suffix was: {out}");
assert!(out.starts_with(" \u{00b7} "), "suffix was: {out}");
// Labels the preceding countdown with "rem", then the ETD segment.
assert!(out.starts_with(" rem \u{00b7} "), "suffix was: {out}");
}
#[test]

View File

@ -849,10 +849,10 @@ const LABEL_RIGHT_MARGIN: i32 = 10;
const BAR_RIGHT_MARGIN: i32 = 4;
const TEXT_WIDTH: i32 = 62; // fits the worst-case "100% · 59m"
/// Text column when the ETD suffix is shown. The ETD form is worst-case
/// "100% · 59m · 59m ETD" — the base "100% · 59m" plus a roughly equal-length
/// " · 59m ETD" suffix — so the column is sized to twice the base to fit the
/// widest possible remaining-time and ETD without clipping.
const ETD_TEXT_WIDTH: i32 = TEXT_WIDTH * 2;
/// "100% · 59m rem · 59m ETD" — the base "100% · 59m" plus a " rem · 59m ETD"
/// label-and-estimate of similar length — so the column is sized to fit the
/// widest possible remaining-time and ETD (~2.6x the base) without clipping.
const ETD_TEXT_WIDTH: i32 = 160;
const MODEL_RIGHT_MARGIN: i32 = 5;
const RIGHT_MARGIN: i32 = 1;
const WIDGET_HEIGHT: i32 = 46;
@ -2947,9 +2947,9 @@ mod tests {
use super::*;
#[test]
fn etd_text_column_is_twice_the_base() {
// Sized for the worst case "100% · 59m · 59m ETD" (~2x "100% · 59m").
assert_eq!(ETD_TEXT_WIDTH, TEXT_WIDTH * 2);
fn etd_text_column_is_wider_than_base() {
// Sized for the worst case "100% · 59m rem · 59m ETD".
assert!(ETD_TEXT_WIDTH > TEXT_WIDTH);
assert_eq!(text_width(false), TEXT_WIDTH);
assert_eq!(text_width(true), ETD_TEXT_WIDTH);
}