fix(i18n): display language options in their native names
fix(i18n): display language options in their native names
This commit is contained in:
5 files changed
+23
-23
No files matched your search
+3
-10
@@ -28,17 +28,10 @@ import { QuotaPage } from './pages/QuotaPage';
|
||||
import { AgentsPage } from './pages/AgentsPage';
|
||||
import { ThinkingAliasesPage } from './pages/ThinkingAliasesPage';
|
||||
import { UsageRecordsPage } from './pages/UsageRecordsPage';
|
||||
import { useI18n } from './i18n';
|
||||
import { languageOptions, useI18n } from './i18n';
|
||||
|
||||
const CONTACT_URL = 'https://qm.qq.com/q/3queDaIG';
|
||||
|
||||
const languageOptions = [
|
||||
{ value: 'zh-CN', labelKey: 'app.language.zhCN' },
|
||||
{ value: 'zh-TW', labelKey: 'app.language.zhTW' },
|
||||
{ value: 'ja', labelKey: 'app.language.ja' },
|
||||
{ value: 'en', labelKey: 'app.language.en' },
|
||||
] as const;
|
||||
|
||||
const pages = [
|
||||
{
|
||||
id: 'kernel',
|
||||
@@ -282,7 +275,7 @@ function AppContent() {
|
||||
onClick={() => setLanguageMenuOpen((open) => !open)}
|
||||
>
|
||||
<Languages size={16} aria-hidden="true" />
|
||||
<span>{t(selectedLanguage.labelKey)}</span>
|
||||
<span lang={selectedLanguage.value}>{selectedLanguage.nativeLabel}</span>
|
||||
<ChevronUp
|
||||
size={14}
|
||||
aria-hidden="true"
|
||||
@@ -310,7 +303,7 @@ function AppContent() {
|
||||
setLanguageMenuOpen(false);
|
||||
}}
|
||||
>
|
||||
<span>{t(option.labelKey)}</span>
|
||||
<span lang={option.value}>{option.nativeLabel}</span>
|
||||
{selected ? <Check size={14} aria-hidden="true" /> : null}
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -4,6 +4,16 @@ import { en, ja, zhCN, zhTW, type MessageKey, type MessageVariables } from './re
|
||||
|
||||
export type AppLocale = 'zh-CN' | 'zh-TW' | 'ja' | 'en';
|
||||
|
||||
export const languageOptions: ReadonlyArray<{
|
||||
value: AppLocale;
|
||||
nativeLabel: string;
|
||||
}> = [
|
||||
{ value: 'zh-CN', nativeLabel: '简体中文' },
|
||||
{ value: 'zh-TW', nativeLabel: '繁體中文' },
|
||||
{ value: 'ja', nativeLabel: '日本語' },
|
||||
{ value: 'en', nativeLabel: 'English' },
|
||||
];
|
||||
|
||||
const STORAGE_KEY = 'easy-cli-proxy-api.locale';
|
||||
const resources = { 'zh-CN': zhCN, 'zh-TW': zhTW, ja, en } as const;
|
||||
let currentLocale: AppLocale = 'zh-CN';
|
||||
|
||||
@@ -2,10 +2,6 @@ import type { MessageKey } from './resources';
|
||||
|
||||
export const jaOverrides = {
|
||||
'app.language': '言語',
|
||||
'app.language.zhCN': '簡体字中国語',
|
||||
'app.language.zhTW': '繁体字中国語',
|
||||
'app.language.ja': '日本語',
|
||||
'app.language.en': 'English',
|
||||
'app.desktopConsole': 'デスクトップコンソール',
|
||||
'app.navigation': 'メインナビゲーション',
|
||||
'app.nav.kernel': 'コア',
|
||||
|
||||
@@ -5,10 +5,6 @@ export type MessageVariables = Record<string, string | number>;
|
||||
|
||||
export const zhCN = {
|
||||
'app.language': '语言',
|
||||
'app.language.zhCN': '简体中文',
|
||||
'app.language.zhTW': '繁体中文',
|
||||
'app.language.ja': '日语',
|
||||
'app.language.en': 'English',
|
||||
'app.desktopConsole': '桌面控制台',
|
||||
'app.navigation': '主导航',
|
||||
'app.nav.kernel': '内核',
|
||||
@@ -682,10 +678,6 @@ export type MessageKey = keyof typeof zhCN;
|
||||
|
||||
export const en: Record<MessageKey, string> = {
|
||||
'app.language': 'Language',
|
||||
'app.language.zhCN': '简体中文',
|
||||
'app.language.zhTW': 'Traditional Chinese',
|
||||
'app.language.ja': 'Japanese',
|
||||
'app.language.en': 'English',
|
||||
'app.desktopConsole': 'Desktop Console',
|
||||
'app.navigation': 'Main navigation',
|
||||
'app.nav.kernel': 'Core',
|
||||
|
||||
+10
-1
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from 'bun:test';
|
||||
import { normalizeLocale, translate } from '../src/i18n';
|
||||
import { languageOptions, normalizeLocale, translate } from '../src/i18n';
|
||||
import { en, ja, zhCN, zhTW } from '../src/i18n/resources';
|
||||
import { jaOverrides } from '../src/i18n/ja';
|
||||
|
||||
@@ -25,6 +25,15 @@ describe('i18n', () => {
|
||||
.toBe('1.2.3 をインストールしています');
|
||||
});
|
||||
|
||||
it('uses each language native name independently of the active locale', () => {
|
||||
expect(languageOptions).toEqual([
|
||||
{ value: 'zh-CN', nativeLabel: '简体中文' },
|
||||
{ value: 'zh-TW', nativeLabel: '繁體中文' },
|
||||
{ value: 'ja', nativeLabel: '日本語' },
|
||||
{ value: 'en', nativeLabel: 'English' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('keeps both locale dictionaries structurally aligned', () => {
|
||||
expect(Object.keys(en).sort()).toEqual(Object.keys(zhCN).sort());
|
||||
expect(Object.keys(zhTW).sort()).toEqual(Object.keys(zhCN).sort());
|
||||
|
||||
Reference in new issue
Block a user