From 2fd319e24a072be007114338251fc10f71fe83e8 Mon Sep 17 00:00:00 2001 From: YANG1024 Date: Sat, 5 Sep 2026 09:33:25 +0000 Subject: [PATCH] fix(desktop): localize appearance settings in zh-CN --- desktop/src/App.test.tsx | 26 ++++++ desktop/src/app/i18n.ts | 20 +++++ .../features/settings/AppearanceSettings.tsx | 80 ++++++++++++++----- 3 files changed, 108 insertions(+), 18 deletions(-) diff --git a/desktop/src/App.test.tsx b/desktop/src/App.test.tsx index c6a61c57..5dfb7f1b 100644 --- a/desktop/src/App.test.tsx +++ b/desktop/src/App.test.tsx @@ -1977,6 +1977,32 @@ describe("desktop command center", () => { .map((button) => button.textContent), ).toEqual(["通用", "模型", "插件", "智能体预设"]); expect(screen.getByRole("button", { name: "打开配置文件" })).toBeTruthy(); + expect( + within(dialog).getByRole("group", { name: "外观模式" }), + ).toBeTruthy(); + expect( + within(dialog).getByRole("button", { name: "浅色" }), + ).toBeTruthy(); + expect( + within(dialog).getByRole("button", { name: "深色" }), + ).toBeTruthy(); + expect( + within(dialog).getByRole("button", { name: "跟随系统" }), + ).toBeTruthy(); + expect(within(dialog).getByLabelText(/^对话宽度/)).toBeTruthy(); + expect(within(dialog).getByLabelText(/^字号/)).toBeTruthy(); + expect(within(dialog).getByLabelText("首选字体")).toBeTruthy(); + expect( + within(dialog).getByRole("option", { name: "纸张 · 暖色低蓝光" }), + ).toBeTruthy(); + expect( + within(dialog).getByText( + "这些显示设置仅保存在本机,会立即生效,不属于项目配置。", + ), + ).toBeTruthy(); + expect( + within(dialog).getByRole("button", { name: "恢复默认设置" }), + ).toBeTruthy(); // Switching back restores English for the remaining tests' queries. fireEvent.change( diff --git a/desktop/src/app/i18n.ts b/desktop/src/app/i18n.ts index fbabf080..a3e6efe0 100644 --- a/desktop/src/app/i18n.ts +++ b/desktop/src/app/i18n.ts @@ -48,6 +48,26 @@ const ZH_CN: Record = { "settings.appearance.light": "浅色", "settings.appearance.dark": "深色", "settings.appearance.system": "跟随系统", + "settings.appearance.mode": "外观模式", + "settings.appearance.theme": "主题", + "settings.appearance.conversationWidth": "对话宽度", + "settings.appearance.fontSize": "字号", + "settings.appearance.fontFamily": "首选字体", + "settings.appearance.paper": "纸张 · 暖色低蓝光", + "settings.appearance.midnight": "午夜 · 深邃冷色", + "settings.appearance.claude": "Claude · 象牙白与陶土色", + "settings.appearance.claudeDark": "Claude 深色 · 石板灰与陶土色", + "settings.appearance.contrast": "高对比度 · AAA", + "settings.appearance.fontPlaceholder": "例如:更纱黑体 SC、Inter", + "settings.appearance.addInstalledFont": "添加已安装字体…", + "settings.appearance.fontGroup.interface": "界面字体", + "settings.appearance.fontGroup.monospace": "等宽字体", + "settings.appearance.fontGroup.cjk": "中日韩字体", + "settings.appearance.fontDescription": + "以逗号分隔的字体会优先于内置字体尝试,便于为中英文混排选择一致的字体。系统会跳过未安装的字体,因此可以安全地列出多个字体。", + "settings.appearance.localOnly": + "这些显示设置仅保存在本机,会立即生效,不属于项目配置。", + "settings.appearance.reset": "恢复默认设置", "settings.language.title": "语言", "settings.language.eyebrow": "界面语言", "settings.language.label": "界面语言", diff --git a/desktop/src/features/settings/AppearanceSettings.tsx b/desktop/src/features/settings/AppearanceSettings.tsx index bb26171f..711cea31 100644 --- a/desktop/src/features/settings/AppearanceSettings.tsx +++ b/desktop/src/features/settings/AppearanceSettings.tsx @@ -44,6 +44,29 @@ const THEME_LABELS: Record = { contrast: "High contrast — AAA", }; +function themeTranslationKey(preference: ThemePreference): string { + const suffix = preference === "claude-dark" ? "claudeDark" : preference; + return `settings.appearance.${suffix}`; +} + +const FONT_GROUPS = [ + { + value: "Interface", + key: "settings.appearance.fontGroup.interface", + defaultValue: "Interface", + }, + { + value: "Monospace", + key: "settings.appearance.fontGroup.monospace", + defaultValue: "Monospace", + }, + { + value: "CJK", + key: "settings.appearance.fontGroup.cjk", + defaultValue: "CJK", + }, +] as const; + /** * Appearance controls, rendered from `APPEARANCE_SETTINGS`. * @@ -77,7 +100,7 @@ export function AppearanceSettings() {
{MODE_CARDS.map((mode) => { const Icon = mode.icon; @@ -90,7 +113,7 @@ export function AppearanceSettings() { onClick={() => set("theme", mode.value)} > - {mode.label} + {t(themeTranslationKey(mode.value), mode.label)} ); })} @@ -100,11 +123,12 @@ export function AppearanceSettings() { {APPEARANCE_SETTINGS.map((setting) => { const id = `${fieldId}-${setting.key}`; const value = appearance[setting.key]; + const label = t(`settings.appearance.${setting.key}`, setting.label); if (setting.key === "theme") { return (