Skip to content

Commit 072594a

Browse files
authored
feat(i18n): localize zh-TW messages to Taiwan terms and show native language names (#1279)
## Summary Use Taiwan-prefered language across the `zh-TW.json` message catalog, and updates language labels in all locale files to display each language in its native script. ### zh-TW localization (commit a502892) Roughly 460 replacements across ~100 term pairs in `frontend/messages/zh-TW.json`: - 消息→訊息, 用戶→使用者, 加載→載入, 搜索→搜尋 - 緩存→快取, 默認→預設, 數據→資料, 質量→品質 - 代碼→程式碼, 連接→連線, 斷開→中斷, 遠程→遠端 - 令牌→權杖, 創建→建立, 項目→專案, 打開→開啟 - 運行→執行, 導出→匯出, 導入→匯入, 文件→檔案 - 周期→週期, 周一~周日→週一~週日 - 恢復→還原 (trash) / 繼續 (session resume) - 訪問→存取, 設置→設定, 字符→字元, 接口→介面, etc. Some references (in zh-TW) - https://hackmd.io/@l10n-tw/glossaries - https://zh.wikibooks.org/zh-tw/%E5%A4%A7%E9%99%86%E5%8F%B0%E6%B9%BE%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%9C%AF%E8%AF%AD%E5%AF%B9%E7%85%A7%E8%A1%A8 ### Language label changes (commits 3a1fb97, 7e231e6) - `en.json`, `fr.json`, `ko.json`, `zh-CN.json`: language names now shown in their native script (简体中文, 繁體中文, 한국어, Français, English) instead of translated descriptions - `LanguageSettings.svelte`: added a globe emoji (🌐) prefix to the language setting label for better visibility Co-authored-by: BoX Fan <coffee0127@users.noreply.github.com>
1 parent 5994e21 commit 072594a

9 files changed

Lines changed: 613 additions & 598 deletions

File tree

frontend/e2e/virtual-list.spec.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ test.describe("Virtual list behavior", () => {
6464
});
6565

6666
sp = new SessionsPage(page);
67-
await page.goto("/");
68-
await expect(sp.sessionItems.first()).toBeVisible();
67+
await sp.goto();
6968
});
7069

7170
test("renders end of list when scrolling down", async () => {
@@ -85,6 +84,17 @@ test.describe("Virtual list behavior", () => {
8584
.poll(() => getScrollTop(sp.sessionListScroll))
8685
.toBeGreaterThan(0);
8786

87+
// Scrolling starts best-effort hydration for the newly visible rows.
88+
// Wait for those observable labels to settle before opening the
89+
// typeahead so late row updates cannot steal focus in WebKit.
90+
await expect
91+
.poll(async () => {
92+
const labels = await sp.sessionItems.allTextContents();
93+
return labels.length > 0 &&
94+
labels.every((label) => label.includes("Hello from session"));
95+
}, { timeout: 15_000 })
96+
.toBe(true);
97+
8898
await sp.filterByProject("tiny");
8999

90100
// Wait for filtered results to render before checking

frontend/messages/en.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -895,10 +895,10 @@
895895
"settings_language_description": "Choose the interface language.",
896896
"settings_language_label": "Interface language",
897897
"settings_language_english": "English",
898-
"settings_language_simplified_chinese": "Simplified Chinese",
899-
"settings_language_traditional_chinese": "Traditional Chinese",
900-
"settings_language_korean": "Korean",
901-
"settings_language_french": "French",
898+
"settings_language_simplified_chinese": "简体中文",
899+
"settings_language_traditional_chinese": "繁體中文",
900+
"settings_language_korean": "한국어",
901+
"settings_language_french": "Français",
902902
"settings_language_no_results": "No languages found",
903903
"nav_recent_edits": "Recent Edits",
904904
"recent_edits_title": "Recent Edits",

frontend/messages/fr.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -894,10 +894,10 @@
894894
"settings_language_title": "Langue",
895895
"settings_language_description": "Choisissez la langue de l'interface.",
896896
"settings_language_label": "Langue de l'interface",
897-
"settings_language_english": "Anglais",
898-
"settings_language_simplified_chinese": "Chinois simplifié",
899-
"settings_language_traditional_chinese": "Chinois traditionnel",
900-
"settings_language_korean": "Coréen",
897+
"settings_language_english": "English",
898+
"settings_language_simplified_chinese": "简体中文",
899+
"settings_language_traditional_chinese": "繁體中文",
900+
"settings_language_korean": "한국어",
901901
"settings_language_french": "Français",
902902
"settings_language_no_results": "Aucune langue trouvée",
903903
"nav_recent_edits": "Modifications récentes",

frontend/messages/ko.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -869,11 +869,11 @@
869869
"settings_language_title": "언어",
870870
"settings_language_description": "인터페이스 언어를 선택하세요.",
871871
"settings_language_label": "인터페이스 언어",
872-
"settings_language_english": "영어",
873-
"settings_language_simplified_chinese": "중국어 간체",
874-
"settings_language_traditional_chinese": "중국어 번체",
872+
"settings_language_english": "English",
873+
"settings_language_simplified_chinese": "简体中文",
874+
"settings_language_traditional_chinese": "繁體中文",
875875
"settings_language_korean": "한국어",
876-
"settings_language_french": "프랑스어",
876+
"settings_language_french": "Français",
877877
"settings_language_no_results": "언어를 찾을 수 없습니다",
878878
"nav_recent_edits": "최근 편집",
879879
"recent_edits_title": "최근 편집",

frontend/messages/zh-CN.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -869,9 +869,9 @@
869869
"settings_language_label": "界面语言",
870870
"settings_language_english": "English",
871871
"settings_language_simplified_chinese": "简体中文",
872-
"settings_language_traditional_chinese": "繁体中文",
873-
"settings_language_korean": "韩语",
874-
"settings_language_french": "法语",
872+
"settings_language_traditional_chinese": "繁體中文",
873+
"settings_language_korean": "한국어",
874+
"settings_language_french": "Français",
875875
"settings_language_no_results": "未找到语言",
876876
"nav_recent_edits": "最近编辑",
877877
"recent_edits_title": "最近编辑",

frontend/messages/zh-TW.json

Lines changed: 574 additions & 574 deletions
Large diffs are not rendered by default.

frontend/playwright.config.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import { defineConfig } from "@playwright/test";
22

33
const isCI = process.env.CI === "true";
4+
const isSelfHostedCI =
5+
isCI && process.env.RUNNER_ENVIRONMENT === "self-hosted";
46

57
export default defineConfig({
68
testDir: "e2e",
79
timeout: isCI ? 45_000 : 20_000,
8-
workers: isCI ? 8 : undefined,
10+
// The managed runner exposes more host CPUs than its pod can use, so keep
11+
// its worker count bounded. GitHub-hosted runners should retain Playwright's
12+
// adaptive default rather than overcommitting a smaller VM.
13+
workers: isSelfHostedCI ? 8 : undefined,
914
retries: 0,
1015
use: {
1116
baseURL: "http://127.0.0.1:8090",

frontend/src/lib/components/settings/SettingsPage.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ describe("SettingsPage", () => {
124124
trigger!.click();
125125
await tick();
126126

127-
const option = Array.from(document.body.querySelectorAll('[role="option"]')).find((el) =>
128-
el.textContent?.includes("Simplified Chinese"),
129-
);
127+
const option = Array.from(
128+
document.body.querySelectorAll('[role="option"]'),
129+
).find((el) => el.textContent?.includes("简体中文"));
130130
expect(option).toBeTruthy();
131131

132132
(option as HTMLElement).dispatchEvent(new MouseEvent("mousedown", { bubbles: true }));

frontend/src/lib/i18n/i18n.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,11 @@ describe("i18n locale selection", () => {
119119
})).toBe("12 个会话");
120120

121121
runtime.setLocale("zh-TW", { reload: false });
122-
expect(m.nav_sessions()).toBe("會話");
122+
expect(m.nav_sessions()).toBe("對話");
123123
expect(m.status_bar_sessions({
124124
count: 12,
125125
countLabel: "12",
126-
})).toBe("12 個會話");
126+
})).toBe("12 個對話");
127127

128128
runtime.setLocale("ko", { reload: false });
129129
expect(m.nav_sessions()).toBe("세션");
@@ -179,7 +179,7 @@ describe("i18n locale selection", () => {
179179
runtime.setLocale("zh-TW", { reload: false });
180180
expect(m.tool_call_group_call_count({ count: 1 })).toBe("1 次 tool call");
181181
expect(m.tool_call_group_call_count({ count: 3 })).toBe("3 次 tool call");
182-
expect(m.subagent_inline_message_count({ count: 1 })).toBe("1 條消息");
182+
expect(m.subagent_inline_message_count({ count: 1 })).toBe("1 則訊息");
183183

184184
// Korean has no plural distinction, so a single variant serves every count.
185185
runtime.setLocale("ko", { reload: false });

0 commit comments

Comments
 (0)