From 830f6f4c9bc9da2fc976b3309f67d9ffe595ef67 Mon Sep 17 00:00:00 2001 From: u_naro Date: Tue, 7 Apr 2026 12:46:56 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20add=20Korean=20(=ED=95=9C=EA=B5=AD?= =?UTF-8?q?=EC=96=B4)=20localization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Korean language support with full UI translations including menu items, update messages, and time format suffixes. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/localization/korean.rs | 37 +++++++++++++++++++++++++++++++++++++ src/localization/mod.rs | 10 +++++++++- src/window.rs | 5 ++++- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/localization/korean.rs diff --git a/src/localization/korean.rs b/src/localization/korean.rs new file mode 100644 index 0000000..4d4d217 --- /dev/null +++ b/src/localization/korean.rs @@ -0,0 +1,37 @@ +use super::Strings; + +pub(super) const UPDATE_VIA_WINGET_LABEL: &str = "WinGet으로 업데이트"; + +pub(super) const STRINGS: Strings = Strings { + window_title: "Claude Code 사용량 모니터", + refresh: "새로고침", + update_frequency: "업데이트 주기", + one_minute: "1분", + five_minutes: "5분", + fifteen_minutes: "15분", + one_hour: "1시간", + settings: "설정", + start_with_windows: "Windows 시작 시 자동 실행", + reset_position: "위치 초기화", + language: "언어", + system_default: "시스템 기본값", + check_for_updates: "업데이트 확인", + checking_for_updates: "업데이트 확인 중...", + updates: "업데이트", + update_in_progress: "이미 업데이트 확인이 진행 중입니다.", + up_to_date: "이미 최신 버전입니다.", + up_to_date_short: "최신", + update_failed: "자동 업데이트를 완료할 수 없습니다", + applying_update: "업데이트 적용 중...", + update_to: "업데이트 대상", + update_available: "업데이트 사용 가능", + update_prompt_now: "버전 {version}을 사용할 수 있습니다. 지금 업데이트하시겠습니까?", + exit: "종료", + session_window: "5h", + weekly_window: "7d", + now: "지금", + day_suffix: "일", + hour_suffix: "시간", + minute_suffix: "분", + second_suffix: "초", +}; diff --git a/src/localization/mod.rs b/src/localization/mod.rs index b5f8097..a7be025 100644 --- a/src/localization/mod.rs +++ b/src/localization/mod.rs @@ -2,6 +2,7 @@ mod english; mod french; mod german; mod japanese; +mod korean; mod spanish; use windows::core::PWSTR; @@ -17,15 +18,17 @@ pub enum LanguageId { French, German, Japanese, + Korean, } impl LanguageId { - pub const ALL: [LanguageId; 5] = [ + pub const ALL: [LanguageId; 6] = [ LanguageId::English, LanguageId::Spanish, LanguageId::French, LanguageId::German, LanguageId::Japanese, + LanguageId::Korean, ]; pub fn code(self) -> &'static str { @@ -35,6 +38,7 @@ impl LanguageId { Self::French => "fr", Self::German => "de", Self::Japanese => "ja", + Self::Korean => "ko", } } @@ -45,6 +49,7 @@ impl LanguageId { Self::French => "Français", Self::German => "Deutsch", Self::Japanese => "日本語", + Self::Korean => "한국어", } } @@ -55,6 +60,7 @@ impl LanguageId { Self::French => french::STRINGS, Self::German => german::STRINGS, Self::Japanese => japanese::STRINGS, + Self::Korean => korean::STRINGS, } } @@ -65,6 +71,7 @@ impl LanguageId { Self::French => french::UPDATE_VIA_WINGET_LABEL, Self::German => german::UPDATE_VIA_WINGET_LABEL, Self::Japanese => japanese::UPDATE_VIA_WINGET_LABEL, + Self::Korean => korean::UPDATE_VIA_WINGET_LABEL, } } @@ -80,6 +87,7 @@ impl LanguageId { "fr" => Some(Self::French), "de" => Some(Self::German), "ja" => Some(Self::Japanese), + "ko" => Some(Self::Korean), _ => None, } } diff --git a/src/window.rs b/src/window.rs index 2d1b284..b4fad5e 100644 --- a/src/window.rs +++ b/src/window.rs @@ -106,6 +106,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_LANG_KOREAN: u16 = 46; const DIVIDER_HIT_ZONE: i32 = 13; // LEFT_DIVIDER_W + DIVIDER_RIGHT_MARGIN @@ -1817,7 +1818,7 @@ unsafe extern "system" fn wnd_proc( SetTimer(hwnd, TIMER_POLL, new_interval, None); } IDM_LANG_SYSTEM | IDM_LANG_ENGLISH | IDM_LANG_SPANISH | IDM_LANG_FRENCH - | IDM_LANG_GERMAN | IDM_LANG_JAPANESE => { + | IDM_LANG_GERMAN | IDM_LANG_JAPANESE | IDM_LANG_KOREAN => { let language_override = match id { IDM_LANG_SYSTEM => None, IDM_LANG_ENGLISH => Some(LanguageId::English), @@ -1825,6 +1826,7 @@ unsafe extern "system" fn wnd_proc( IDM_LANG_FRENCH => Some(LanguageId::French), IDM_LANG_GERMAN => Some(LanguageId::German), IDM_LANG_JAPANESE => Some(LanguageId::Japanese), + IDM_LANG_KOREAN => Some(LanguageId::Korean), _ => None, }; { @@ -1991,6 +1993,7 @@ fn show_context_menu(hwnd: HWND) { LanguageId::French => IDM_LANG_FRENCH, LanguageId::German => IDM_LANG_GERMAN, LanguageId::Japanese => IDM_LANG_JAPANESE, + LanguageId::Korean => IDM_LANG_KOREAN, }; let label_str = native_interop::wide_str(language.native_name()); let flags = if language_override == Some(language) { From a37d9632c2498674a8684e2c3e9e6ebd8ed5f0fe Mon Sep 17 00:00:00 2001 From: u_naro Date: Tue, 7 Apr 2026 12:55:05 +0900 Subject: [PATCH 2/2] feat: localize "Show Widget" and session/weekly window labels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add `show_widget` field to Strings struct and all 6 language files - Replace hardcoded "Show Widget" in window.rs with strings.show_widget - Translate session_window ("5시간") and weekly_window ("7일") for Korean Co-Authored-By: Claude Opus 4.6 (1M context) --- src/localization/english.rs | 1 + src/localization/french.rs | 1 + src/localization/german.rs | 1 + src/localization/japanese.rs | 1 + src/localization/korean.rs | 5 +++-- src/localization/mod.rs | 1 + src/localization/spanish.rs | 1 + src/window.rs | 2 +- 8 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/localization/english.rs b/src/localization/english.rs index ce80505..d730842 100644 --- a/src/localization/english.rs +++ b/src/localization/english.rs @@ -27,6 +27,7 @@ pub(super) const STRINGS: Strings = Strings { update_available: "Update available", update_prompt_now: "Version {version} is available. Do you want to update now?", exit: "Exit", + show_widget: "Show Widget", session_window: "5h", weekly_window: "7d", now: "now", diff --git a/src/localization/french.rs b/src/localization/french.rs index a8ddf7c..e1d51b8 100644 --- a/src/localization/french.rs +++ b/src/localization/french.rs @@ -27,6 +27,7 @@ pub(super) const STRINGS: Strings = Strings { update_available: "Mise à jour disponible", update_prompt_now: "La version {version} est disponible. Voulez-vous mettre à jour maintenant ?", exit: "Quitter", + show_widget: "Afficher le widget", session_window: "5h", weekly_window: "7d", now: "maintenant", diff --git a/src/localization/german.rs b/src/localization/german.rs index 7640123..70de6fb 100644 --- a/src/localization/german.rs +++ b/src/localization/german.rs @@ -27,6 +27,7 @@ pub(super) const STRINGS: Strings = Strings { update_available: "Update verfügbar", update_prompt_now: "Version {version} ist verfügbar. Möchten Sie jetzt aktualisieren?", exit: "Beenden", + show_widget: "Widget anzeigen", session_window: "5h", weekly_window: "7d", now: "jetzt", diff --git a/src/localization/japanese.rs b/src/localization/japanese.rs index ec55d7e..5078a21 100644 --- a/src/localization/japanese.rs +++ b/src/localization/japanese.rs @@ -27,6 +27,7 @@ pub(super) const STRINGS: Strings = Strings { update_available: "更新が利用可能です", update_prompt_now: "バージョン {version} が利用可能です。今すぐ更新しますか?", exit: "終了", + show_widget: "ウィジェットを表示", session_window: "5h", weekly_window: "7d", now: "今", diff --git a/src/localization/korean.rs b/src/localization/korean.rs index 4d4d217..ca2a88e 100644 --- a/src/localization/korean.rs +++ b/src/localization/korean.rs @@ -27,8 +27,9 @@ pub(super) const STRINGS: Strings = Strings { update_available: "업데이트 사용 가능", update_prompt_now: "버전 {version}을 사용할 수 있습니다. 지금 업데이트하시겠습니까?", exit: "종료", - session_window: "5h", - weekly_window: "7d", + show_widget: "위젯 표시", + session_window: "5시간", + weekly_window: "7일", now: "지금", day_suffix: "일", hour_suffix: "시간", diff --git a/src/localization/mod.rs b/src/localization/mod.rs index a7be025..2b741f6 100644 --- a/src/localization/mod.rs +++ b/src/localization/mod.rs @@ -119,6 +119,7 @@ pub struct Strings { pub update_available: &'static str, pub update_prompt_now: &'static str, pub exit: &'static str, + pub show_widget: &'static str, pub session_window: &'static str, pub weekly_window: &'static str, pub now: &'static str, diff --git a/src/localization/spanish.rs b/src/localization/spanish.rs index d525cc3..f3adace 100644 --- a/src/localization/spanish.rs +++ b/src/localization/spanish.rs @@ -27,6 +27,7 @@ pub(super) const STRINGS: Strings = Strings { update_available: "Actualización disponible", update_prompt_now: "La versión {version} está disponible. ¿Quieres actualizar ahora?", exit: "Salir", + show_widget: "Mostrar widget", session_window: "5h", weekly_window: "7d", now: "ahora", diff --git a/src/window.rs b/src/window.rs index b4fad5e..43024c7 100644 --- a/src/window.rs +++ b/src/window.rs @@ -2043,7 +2043,7 @@ fn show_context_menu(hwnd: HWND) { PCWSTR::from_raw(settings_label.as_ptr()), ); - let widget_label = native_interop::wide_str("Show Widget"); + let widget_label = native_interop::wide_str(strings.show_widget); let widget_flags = if widget_visible { MF_CHECKED } else { MENU_ITEM_FLAGS(0) }; let _ = AppendMenuW( menu,