mirror of
https://github.com/CodeZeno/Claude-Code-Usage-Monitor.git
synced 2026-06-20 10:19:27 +08:00
Merge b192e08064fbc05e3d58dd60e3d40247fea322b0 into 35f945daa9938d684dca2a5ff9dc0286993622e5
This commit is contained in:
commit
e9914f59be
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,6 @@
|
||||
# Visual Studio
|
||||
*.vs/
|
||||
|
||||
# Rust build artifacts
|
||||
/target/
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ pub(super) const STRINGS: Strings = Strings {
|
||||
fifteen_minutes: "15 Minutes",
|
||||
one_hour: "1 Hour",
|
||||
settings: "Settings",
|
||||
show_decimals: "Show Decimals",
|
||||
start_with_windows: "Start with Windows",
|
||||
reset_position: "Reset Position",
|
||||
language: "Language",
|
||||
|
||||
@ -11,6 +11,7 @@ pub(super) const STRINGS: Strings = Strings {
|
||||
fifteen_minutes: "15 minutes",
|
||||
one_hour: "1 heure",
|
||||
settings: "Paramètres",
|
||||
show_decimals: "Afficher les décimales",
|
||||
start_with_windows: "Démarrer avec Windows",
|
||||
reset_position: "Réinitialiser la position",
|
||||
language: "Langue",
|
||||
|
||||
@ -11,6 +11,7 @@ pub(super) const STRINGS: Strings = Strings {
|
||||
fifteen_minutes: "15 Minuten",
|
||||
one_hour: "1 Stunde",
|
||||
settings: "Einstellungen",
|
||||
show_decimals: "Dezimalstellen anzeigen",
|
||||
start_with_windows: "Mit Windows starten",
|
||||
reset_position: "Position zurücksetzen",
|
||||
language: "Sprache",
|
||||
|
||||
@ -11,6 +11,7 @@ pub(super) const STRINGS: Strings = Strings {
|
||||
fifteen_minutes: "15分",
|
||||
one_hour: "1時間",
|
||||
settings: "設定",
|
||||
show_decimals: "小数点を表示",
|
||||
start_with_windows: "Windows と同時に開始",
|
||||
reset_position: "位置をリセット",
|
||||
language: "言語",
|
||||
|
||||
@ -121,6 +121,7 @@ pub struct Strings {
|
||||
pub fifteen_minutes: &'static str,
|
||||
pub one_hour: &'static str,
|
||||
pub settings: &'static str,
|
||||
pub show_decimals: &'static str,
|
||||
pub start_with_windows: &'static str,
|
||||
pub reset_position: &'static str,
|
||||
pub language: &'static str,
|
||||
|
||||
@ -11,6 +11,7 @@ pub(super) const STRINGS: Strings = Strings {
|
||||
fifteen_minutes: "15 minutos",
|
||||
one_hour: "1 hora",
|
||||
settings: "Configuración",
|
||||
show_decimals: "Mostrar decimales",
|
||||
start_with_windows: "Iniciar con Windows",
|
||||
reset_position: "Restablecer posición",
|
||||
language: "Idioma",
|
||||
|
||||
@ -756,9 +756,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, show_decimals: bool) -> String {
|
||||
let pct = format!("{:.0}%", section.percentage);
|
||||
let cd = format_countdown(section.resets_at, strings);
|
||||
let cd = format_countdown(section.resets_at, strings, show_decimals);
|
||||
if cd.is_empty() {
|
||||
pct
|
||||
} else {
|
||||
@ -766,7 +766,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, show_decimals: bool) -> String {
|
||||
let reset = match resets_at {
|
||||
Some(t) => t,
|
||||
None => return String::new(),
|
||||
@ -792,11 +792,21 @@ fn format_countdown_from_secs(total_secs: u64, strings: Strings) -> String {
|
||||
let total_hours = total_secs / 3600;
|
||||
let total_days = total_secs / 86400;
|
||||
|
||||
if total_days >= 1 {
|
||||
let hours_fraction = total_mins / 60;
|
||||
let days_fraction = total_hours / 24;
|
||||
let minute_fraction = total_secs / 60;
|
||||
|
||||
if total_days > 0 && show_decimals && days_fraction > 0 {
|
||||
format!("{total_days}.{days_fraction:01}{}", strings.day_suffix)
|
||||
} else if total_days > 0 {
|
||||
format!("{total_days}{}", strings.day_suffix)
|
||||
} else if total_hours >= 1 {
|
||||
} else if total_hours > 0 && show_decimals && hours_fraction > 0 {
|
||||
format!("{total_hours}.{hours_fraction:01}{}", strings.hour_suffix)
|
||||
} else if total_hours > 0 {
|
||||
format!("{total_hours}{}", strings.hour_suffix)
|
||||
} else if total_mins >= 1 {
|
||||
} else if total_mins > 0 && show_decimals && minute_fraction > 0 {
|
||||
format!("{total_mins}.{minute_fraction:01}{}", strings.minute_suffix)
|
||||
} else if total_mins > 0 {
|
||||
format!("{total_mins}{}", strings.minute_suffix)
|
||||
} else {
|
||||
format!("{total_secs}{}", strings.second_suffix)
|
||||
|
||||
@ -76,6 +76,7 @@ struct AppState {
|
||||
dragging: bool,
|
||||
drag_start_mouse_x: i32,
|
||||
drag_start_offset: i32,
|
||||
show_decimals: bool,
|
||||
|
||||
widget_visible: bool,
|
||||
}
|
||||
@ -110,6 +111,7 @@ const IDM_LANG_SPANISH: u16 = 42;
|
||||
const IDM_LANG_FRENCH: u16 = 43;
|
||||
const IDM_LANG_GERMAN: u16 = 44;
|
||||
const IDM_LANG_JAPANESE: u16 = 45;
|
||||
const IDM_SHOW_DECIMALS: u16 = 50;
|
||||
const IDM_LANG_KOREAN: u16 = 46;
|
||||
const IDM_LANG_TRADITIONAL_CHINESE: u16 = 47;
|
||||
|
||||
@ -195,6 +197,8 @@ struct SettingsFile {
|
||||
language: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
last_update_check_unix: Option<u64>,
|
||||
#[serde(default)]
|
||||
show_decimals: bool,
|
||||
#[serde(default = "default_widget_visible")]
|
||||
widget_visible: bool,
|
||||
}
|
||||
@ -206,6 +210,7 @@ impl Default for SettingsFile {
|
||||
poll_interval_ms: default_poll_interval(),
|
||||
language: None,
|
||||
last_update_check_unix: None,
|
||||
show_decimals: true,
|
||||
widget_visible: true,
|
||||
}
|
||||
}
|
||||
@ -247,6 +252,7 @@ fn save_state_settings() {
|
||||
.language_override
|
||||
.map(|language| language.code().to_string()),
|
||||
last_update_check_unix: s.last_update_check_unix,
|
||||
show_decimals: s.show_decimals,
|
||||
widget_visible: s.widget_visible,
|
||||
});
|
||||
}
|
||||
@ -336,8 +342,8 @@ fn refresh_usage_texts(state: &mut AppState) {
|
||||
let strings = state.language.strings();
|
||||
let Some((session_text, weekly_text)) = state.data.as_ref().map(|data| {
|
||||
(
|
||||
poller::format_line(&data.session, strings),
|
||||
poller::format_line(&data.weekly, strings),
|
||||
poller::format_line(&data.session, strings, state.show_decimals),
|
||||
poller::format_line(&data.weekly, strings, state.show_decimals),
|
||||
)
|
||||
}) else {
|
||||
return;
|
||||
@ -728,7 +734,7 @@ const DIVIDER_RIGHT_MARGIN: i32 = 10;
|
||||
const LABEL_WIDTH: i32 = 18;
|
||||
const LABEL_RIGHT_MARGIN: i32 = 10;
|
||||
const BAR_RIGHT_MARGIN: i32 = 4;
|
||||
const TEXT_WIDTH: i32 = 62;
|
||||
const TEXT_WIDTH: i32 = 80;
|
||||
const RIGHT_MARGIN: i32 = 1;
|
||||
const WIDGET_HEIGHT: i32 = 46;
|
||||
|
||||
@ -870,6 +876,7 @@ pub fn run() {
|
||||
dragging: false,
|
||||
drag_start_mouse_x: 0,
|
||||
drag_start_offset: 0,
|
||||
show_decimals: settings.show_decimals,
|
||||
widget_visible: settings.widget_visible,
|
||||
});
|
||||
}
|
||||
@ -1920,6 +1927,16 @@ unsafe extern "system" fn wnd_proc(
|
||||
IDM_START_WITH_WINDOWS => {
|
||||
set_startup_enabled(!is_startup_enabled());
|
||||
}
|
||||
IDM_SHOW_DECIMALS => {
|
||||
{
|
||||
let mut state = lock_state();
|
||||
if let Some(s) = state.as_mut() {
|
||||
s.show_decimals = !s.show_decimals;
|
||||
}
|
||||
}
|
||||
save_state_settings();
|
||||
render_layered();
|
||||
}
|
||||
IDM_FREQ_1MIN | IDM_FREQ_5MIN | IDM_FREQ_15MIN | IDM_FREQ_1HOUR => {
|
||||
let new_interval = match id {
|
||||
IDM_FREQ_1MIN => POLL_1_MIN,
|
||||
@ -2100,6 +2117,23 @@ fn show_context_menu(hwnd: HWND) {
|
||||
PCWSTR::from_raw(reset_pos_str.as_ptr()),
|
||||
);
|
||||
|
||||
// Show Decimals toggle
|
||||
let show_decimals_str = native_interop::wide_str(strings.show_decimals);
|
||||
let show_checked_flags = if {
|
||||
let state = lock_state();
|
||||
state.as_ref().map(|s| s.show_decimals).unwrap_or(true)
|
||||
} {
|
||||
MF_CHECKED
|
||||
} else {
|
||||
MENU_ITEM_FLAGS(0)
|
||||
};
|
||||
let _ = AppendMenuW(
|
||||
settings_menu,
|
||||
show_checked_flags,
|
||||
IDM_SHOW_DECIMALS as usize,
|
||||
PCWSTR::from_raw(show_decimals_str.as_ptr()),
|
||||
);
|
||||
|
||||
let language_menu = CreatePopupMenu().unwrap();
|
||||
let system_label = native_interop::wide_str(strings.system_default);
|
||||
let system_flags = if language_override.is_none() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user