From d2ecffb455ad372debc7ed62c2af849700747262 Mon Sep 17 00:00:00 2001 From: James Pine Date: Mon, 20 Apr 2026 04:31:53 -0700 Subject: [PATCH] fix(i18n): address PR review feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bugs: - GeneralPage: network access toast used the keep-server-running title key (wrong semantic scope). Add networkAccess.updatedTitle and use it. - GeneralPage: fallback "Unknown" version was stored as a translated string in state, so it stayed stale across language switches. Store null, resolve the label at render time. - GeneralPage: memoize the zod resolver on t and retrigger validation when the locale changes so existing error messages retranslate. - GpuPage: adding t to the CUDA progress EventSource effect deps caused the SSE connection to be torn down and reopened on every language change, potentially dropping in-flight download events. Capture t in a ref. - HistoryTable: Effects dialog still rendered English "Source" / "Select source version" / "Cancel" / "Apply" / "Applying..." — localize them. - Locales: zh-CN / zh-TW / ja devSuffix was missing the leading space before "(开发版)"/"(開發版)"/"(開発版)", so dev builds rendered "v0.4.2(开发版)" instead of "v0.4.2 (开发版)". Nits: - ModelManagement: rename .find((t) => ...) callback param to avoid shadowing useTranslation().t. - GenerationPage: rename chunkLimit.value interpolation key from count → chars so i18next doesn't silently activate pluralization if a translator later adds _one/_other forms. - LanguageSelect: narrow onValueChange handler param to LanguageCode. Key count now 559 across en/zh-CN/zh-TW/ja (added 4 effectsDialog keys plus networkAccess.updatedTitle). Co-Authored-By: Claude Opus 4.7 (1M context) --- app/src/components/History/HistoryTable.tsx | 12 ++++++--- .../ServerSettings/ModelManagement.tsx | 4 +-- app/src/components/ServerTab/GeneralPage.tsx | 27 ++++++++++++++----- .../components/ServerTab/GenerationPage.tsx | 2 +- app/src/components/ServerTab/GpuPage.tsx | 10 +++++-- .../components/ServerTab/LanguageSelect.tsx | 4 +-- app/src/i18n/locales/en/translation.json | 9 +++++-- app/src/i18n/locales/ja/translation.json | 11 +++++--- app/src/i18n/locales/zh-CN/translation.json | 11 +++++--- app/src/i18n/locales/zh-TW/translation.json | 11 +++++--- 10 files changed, 72 insertions(+), 29 deletions(-) diff --git a/app/src/components/History/HistoryTable.tsx b/app/src/components/History/HistoryTable.tsx index 8aa47f53..3465beb9 100644 --- a/app/src/components/History/HistoryTable.tsx +++ b/app/src/components/History/HistoryTable.tsx @@ -897,13 +897,15 @@ export function HistoryTable() { {effectsTargetVersions.length > 1 && (
- + { - void i18n.changeLanguage(value); + void i18n.changeLanguage(value as LanguageCode); }} > diff --git a/app/src/i18n/locales/en/translation.json b/app/src/i18n/locales/en/translation.json index b9de81cf..a449b25f 100644 --- a/app/src/i18n/locales/en/translation.json +++ b/app/src/i18n/locales/en/translation.json @@ -518,7 +518,11 @@ }, "effectsDialog": { "title": "Apply Effects", - "body": "Configure post-processing effects to apply to this generation. A new version will be created." + "body": "Configure post-processing effects to apply to this generation. A new version will be created.", + "sourceLabel": "Source", + "sourcePlaceholder": "Select source version", + "apply": "Apply", + "applying": "Applying…" } }, "generation": { @@ -598,6 +602,7 @@ "networkAccess": { "title": "Allow network access", "description": "Makes the server accessible from other devices on your network. Restart the app after changing.", + "updatedTitle": "Setting updated", "enabled": "Network access enabled. Restart the app to apply.", "disabled": "Network access disabled. Restart the app to apply." }, @@ -651,7 +656,7 @@ "chunkLimit": { "title": "Auto-chunking limit", "description": "Long text is split into chunks at sentence boundaries. Lower values can improve quality for long outputs.", - "value": "{{count}} chars" + "value": "{{chars}} chars" }, "crossfade": { "title": "Chunk crossfade", diff --git a/app/src/i18n/locales/ja/translation.json b/app/src/i18n/locales/ja/translation.json index 4580e4f0..bcc2d712 100644 --- a/app/src/i18n/locales/ja/translation.json +++ b/app/src/i18n/locales/ja/translation.json @@ -518,7 +518,11 @@ }, "effectsDialog": { "title": "エフェクトを適用", - "body": "この生成に適用するポストプロセッシングのエフェクトを設定します。新しいバージョンが作成されます。" + "body": "この生成に適用するポストプロセッシングのエフェクトを設定します。新しいバージョンが作成されます。", + "sourceLabel": "ソース", + "sourcePlaceholder": "ソースバージョンを選択", + "apply": "適用", + "applying": "適用中…" } }, "generation": { @@ -598,6 +602,7 @@ "networkAccess": { "title": "ネットワークアクセスを許可", "description": "ネットワーク上の他のデバイスからサーバーにアクセスできるようにします。変更後はアプリを再起動してください。", + "updatedTitle": "設定を更新しました", "enabled": "ネットワークアクセスが有効になりました。適用するにはアプリを再起動してください。", "disabled": "ネットワークアクセスが無効になりました。適用するにはアプリを再起動してください。" }, @@ -608,7 +613,7 @@ }, "updates": { "title": "アプリの更新", - "devSuffix": "(開発版)", + "devSuffix": " (開発版)", "devMode": { "title": "開発モード", "description": "開発モードでは自動更新が無効になっています。" @@ -651,7 +656,7 @@ "chunkLimit": { "title": "自動チャンク分割の上限", "description": "長文は文境界でチャンクに分割されます。値を小さくすると長い出力の品質が向上することがあります。", - "value": "{{count}} 文字" + "value": "{{chars}} 文字" }, "crossfade": { "title": "チャンク間のクロスフェード", diff --git a/app/src/i18n/locales/zh-CN/translation.json b/app/src/i18n/locales/zh-CN/translation.json index 176381d7..e5e9df37 100644 --- a/app/src/i18n/locales/zh-CN/translation.json +++ b/app/src/i18n/locales/zh-CN/translation.json @@ -518,7 +518,11 @@ }, "effectsDialog": { "title": "应用效果", - "body": "配置应用于此次生成的后处理效果。将会创建一个新版本。" + "body": "配置应用于此次生成的后处理效果。将会创建一个新版本。", + "sourceLabel": "来源", + "sourcePlaceholder": "选择来源版本", + "apply": "应用", + "applying": "应用中…" } }, "generation": { @@ -598,6 +602,7 @@ "networkAccess": { "title": "允许网络访问", "description": "使网络上的其他设备可以访问服务器。更改后请重启应用。", + "updatedTitle": "设置已更新", "enabled": "已启用网络访问。重启应用以应用更改。", "disabled": "已禁用网络访问。重启应用以应用更改。" }, @@ -608,7 +613,7 @@ }, "updates": { "title": "应用更新", - "devSuffix": "(开发版)", + "devSuffix": " (开发版)", "devMode": { "title": "开发模式", "description": "开发模式下已禁用自动更新。" @@ -651,7 +656,7 @@ "chunkLimit": { "title": "自动分块上限", "description": "长文本在句子边界处分块。较低的值可以提高长输出的质量。", - "value": "{{count}} 字符" + "value": "{{chars}} 字符" }, "crossfade": { "title": "块间淡入淡出", diff --git a/app/src/i18n/locales/zh-TW/translation.json b/app/src/i18n/locales/zh-TW/translation.json index 3e3a8e7f..b855acd2 100644 --- a/app/src/i18n/locales/zh-TW/translation.json +++ b/app/src/i18n/locales/zh-TW/translation.json @@ -518,7 +518,11 @@ }, "effectsDialog": { "title": "套用效果", - "body": "設定要套用於此生成的後製效果。將會建立一個新版本。" + "body": "設定要套用於此生成的後製效果。將會建立一個新版本。", + "sourceLabel": "來源", + "sourcePlaceholder": "選擇來源版本", + "apply": "套用", + "applying": "套用中…" } }, "generation": { @@ -598,6 +602,7 @@ "networkAccess": { "title": "允許網路存取", "description": "讓網路上的其他裝置可存取伺服器。變更後請重新啟動應用程式。", + "updatedTitle": "設定已更新", "enabled": "已啟用網路存取。重新啟動應用程式以套用。", "disabled": "已停用網路存取。重新啟動應用程式以套用。" }, @@ -608,7 +613,7 @@ }, "updates": { "title": "應用程式更新", - "devSuffix": "(開發版)", + "devSuffix": " (開發版)", "devMode": { "title": "開發模式", "description": "開發模式下已停用自動更新。" @@ -651,7 +656,7 @@ "chunkLimit": { "title": "自動分塊上限", "description": "長文字會在句子邊界處分塊。較低的值可以提升長輸出的品質。", - "value": "{{count}} 字元" + "value": "{{chars}} 字元" }, "crossfade": { "title": "區塊間淡入淡出",