feat(desktop): add zh locale support and localize navigation/menu labels#8639
feat(desktop): add zh locale support and localize navigation/menu labels#8639lingrany wants to merge 7 commits intoaaif-goose:mainfrom
Conversation
Signed-off-by: lingrany <250338893@qq.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: aecd7db973
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| }; | ||
|
|
||
| function isZhLocale(): boolean { | ||
| const locale = app.getLocale()?.toLowerCase() ?? ''; |
There was a problem hiding this comment.
Honor GOOSE_LOCALE when deciding menu language
isZhLocale() only consults app.getLocale(), but desktop i18n gives GOOSE_LOCALE highest priority for UI language selection. In the common override case (GOOSE_LOCALE=zh on a non-Chinese OS), the React UI will switch to Chinese while the native app menu remains English because this check returns false, producing a mixed-language experience and bypassing the explicit locale override. Use the same configured locale source as the renderer before falling back to OS locale.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Thanks! Addressed in dfb964f.
I updated the native menu locale check to honor GOOSE_LOCALE first, then fall back to app.getLocale(), so menu localization matches desktop i18n locale precedence.
Signed-off-by: lingrany <250338893@qq.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dfb964fede
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
|
||
| /** The set of locales that have translation catalogs. */ | ||
| const SUPPORTED_LOCALES = new Set(['en']); | ||
| const SUPPORTED_LOCALES = new Set(['en', 'zh', 'zh-CN']); |
There was a problem hiding this comment.
Normalize underscore locale tags before matching locales
With zh/zh-CN now listed as supported, GOOSE_LOCALE=zh_CN becomes a practical input, but getLocale() still compares the raw tag and only derives a base via split('-'), so zh_CN misses both checks and falls back to English. Meanwhile isZhLocale() in main.ts already normalizes _ to -, so this produces a mixed-language app (Chinese native menu, English renderer). Normalize candidate tags in getLocale() before matching/canonicalizing to keep renderer and menu localization consistent.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Thanks! Addressed in 1acf963.
I updated i18n locale resolution to normalize underscore tags (e.g. zh_CN -> zh-CN) before canonicalization/matching, so renderer locale selection stays consistent with native menu locale handling.
Signed-off-by: lingrany <250338893@qq.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1acf963035
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (SUPPORTED_LOCALES.has(base)) { | ||
| // Validate the full tag is a well-formed BCP 47 locale before using it | ||
| // for formatting. Invalid tags (e.g. "en-") would cause RangeError in | ||
| // Intl APIs, so fall back to the base language in that case. | ||
| let locale = base; | ||
| try { | ||
| [locale] = Intl.getCanonicalLocales(tag); | ||
| } catch { | ||
| // tag is not valid BCP 47 — use the base language instead | ||
| } | ||
| return { locale, messageLocale: base }; | ||
| return { locale: canonical, messageLocale: base }; |
There was a problem hiding this comment.
Fall back to base locale when canonicalization fails
If Intl.getCanonicalLocales(normalized) throws (for example GOOSE_LOCALE=en- or zh_), this branch still returns the invalid canonical tag as locale. That value is exported as currentLocale and later used by IntlProvider and date/time formatters (e.g. in renderer.tsx and timeUtils.ts), where invalid locale tags can raise RangeError: Incorrect locale information provided at runtime. Preserve the previous behavior by returning base when canonicalization fails so malformed but base-supported locale inputs degrade safely.
Useful? React with 👍 / 👎.
Signed-off-by: lingrany <250338893@qq.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 739b333891
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
|
||
| /** The set of locales that have translation catalogs. */ | ||
| const SUPPORTED_LOCALES = new Set(['en']); | ||
| const SUPPORTED_LOCALES = new Set(['en', 'zh', 'zh-CN']); |
There was a problem hiding this comment.
Keep zh locales unsupported until catalogs exist
Adding 'zh' and 'zh-CN' to SUPPORTED_LOCALES makes getLocale() return those values, so the renderer now calls loadMessages('zh' | 'zh-CN'); however the repo only ships src/i18n/messages/en.json (and i18n-compile only compiles files in that folder), so those imports fall back to {} and the app runs with Chinese locale formatting but English UI strings plus a warning on startup. This is a user-visible regression for anyone setting GOOSE_LOCALE=zh*; either commit the corresponding zh catalog(s) or defer advertising these locales as supported.
Useful? React with 👍 / 👎.
Signed-off-by: lingrany <250338893@qq.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 26b8f2c057
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| @@ -0,0 +1,4706 @@ | |||
| { | |||
| "alertBox.autoCompactAt": { | |||
| "defaultMessage": "Auto compact at" | |||
There was a problem hiding this comment.
Populate zh catalogs with actual Chinese strings
Adding zh/zh-CN as supported locales now routes renderer message loading to these new catalogs, but the catalog content is still English. Fresh evidence: src/i18n/messages/zh.json and src/i18n/messages/zh-CN.json are byte-identical to en.json (for example, alertBox.autoCompactAt is still "Auto compact at"), so users with GOOSE_LOCALE=zh* get English UI strings while other surfaces (like menu/date formatting) switch locale, resulting in a mixed-language experience. This should either ship with real Chinese translations or keep zh* unsupported until translations exist.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Thanks! Addressed in 1ffccb1.
I populated zh/zh-CN catalogs with actual Chinese strings for core, user-visible desktop areas (navigation, settings tabs, queue and key list views), so these locales are no longer byte-identical copies of en.json.
Signed-off-by: lingrany <250338893@qq.com>
… flows Signed-off-by: lingrany <250338893@qq.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 612b5b4356
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| "defaultMessage": "选择语音转文本方式" | ||
| }, | ||
| "dictationSettings.configureApiKey": { | ||
| "defaultMessage": "配置 the API key in <b>{设置Path}</b>" |
There was a problem hiding this comment.
Keep ICU variable keys untranslated in zh catalogs
The new Chinese catalogs changed ICU placeholder names (for example {settingsPath} became {设置Path} and {providerName} became {提供方Name}), but call sites still provide settingsPath/providerName values (see dictation/provider settings components). In zh locales, formatMessage cannot resolve these renamed variables, which triggers formatting errors and forces fallback/default text instead of the intended localized string; placeholder identifiers must remain exactly the same as the source message keys in both zh.json and zh-CN.json.
Useful? React with 👍 / 👎.
Summary
This PR improves Chinese localization support in Goose Desktop by addressing two major gaps:
Changes
1) Enable Chinese locale support
ui/desktop/src/i18n/index.tszhandzh-CNtoSUPPORTED_LOCALES2) Localize sidebar navigation labels at runtime
ui/desktop/src/components/Layout/NavigationPanel.tsxuseIntl/formatMessage3) Localize native Electron app menu in zh locale
ui/desktop/src/main.tsMenu.setApplicationMenu(menu)Why
Before this change, Chinese message files existed/loaded for many UI areas, but:
This caused visible mixed-language UI for Chinese users.
Testing
Scope
This PR intentionally focuses on locale wiring + hardcoded label fixes for high-visibility UI areas.
It does not attempt to fully translate every desktop message key.
Notes
ui/desktop)