i18n: complete internationalization for settings panel

- Add missing translation keys for all hint texts and descriptions
- Remove all hardcoded defaultValue parameters from components
- Add translations for window behavior, directory settings, and theme settings
- Add translations for provider-related UI elements
- Improve consistency across Chinese and English translations

Translation additions:
- common.toggleTheme
- settings.windowBehaviorHint, claudeConfigDirDescription, codexConfigDirDescription
- provider.* (12 new keys)
- providerForm.* (15 new keys)
- providerPreset.* (4 new keys)

Modified files: 10
Lines changed: +132 -74
This commit is contained in:
Jason
2025-10-19 11:01:53 +08:00
parent b036a94281
commit bae6a1cf55
10 changed files with 132 additions and 74 deletions

View File

@@ -22,7 +22,7 @@ export function ModeToggle() {
<Sun className="h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" /> <Sun className="h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" /> <Moon className="absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only"> <span className="sr-only">
{t("common.toggleTheme", { defaultValue: "切换主题" })} {t("common.toggleTheme")}
</span> </span>
</Button> </Button>
); );

View File

@@ -75,9 +75,7 @@ export function AboutSection({ isPortable }: AboutSectionProps) {
} catch (error) { } catch (error) {
console.error("[AboutSection] Failed to open release notes", error); console.error("[AboutSection] Failed to open release notes", error);
toast.error( toast.error(
t("settings.openReleaseNotesFailed", { t("settings.openReleaseNotesFailed"),
defaultValue: "打开更新日志失败",
}),
); );
} }
}, [t, updateInfo?.availableVersion, version]); }, [t, updateInfo?.availableVersion, version]);
@@ -101,9 +99,7 @@ export function AboutSection({ isPortable }: AboutSectionProps) {
} catch (error) { } catch (error) {
console.error("[AboutSection] Update failed", error); console.error("[AboutSection] Update failed", error);
toast.error( toast.error(
t("settings.updateFailed", { t("settings.updateFailed"),
defaultValue: "更新安装失败,已尝试打开下载页面。",
}),
); );
try { try {
await settingsApi.checkUpdates(); await settingsApi.checkUpdates();
@@ -122,29 +118,25 @@ export function AboutSection({ isPortable }: AboutSectionProps) {
try { try {
const available = await checkUpdate(); const available = await checkUpdate();
if (!available) { if (!available) {
toast.success(t("settings.upToDate", { defaultValue: "已是最新版本" })); toast.success(t("settings.upToDate"));
} }
} catch (error) { } catch (error) {
console.error("[AboutSection] Check update failed", error); console.error("[AboutSection] Check update failed", error);
toast.error( toast.error(
t("settings.checkUpdateFailed", { t("settings.checkUpdateFailed"),
defaultValue: "检查更新失败,请稍后重试。",
}),
); );
} }
}, [checkUpdate, hasUpdate, isPortable, resetDismiss, t, updateHandle]); }, [checkUpdate, hasUpdate, isPortable, resetDismiss, t, updateHandle]);
const displayVersion = const displayVersion =
version ?? t("common.unknown", { defaultValue: "未知" }); version ?? t("common.unknown");
return ( return (
<section className="space-y-4"> <section className="space-y-4">
<header className="space-y-1"> <header className="space-y-1">
<h3 className="text-sm font-medium">{t("common.about")}</h3> <h3 className="text-sm font-medium">{t("common.about")}</h3>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
{t("settings.aboutHint", { {t("settings.aboutHint")}
defaultValue: "查看版本信息与更新状态。",
})}
</p> </p>
</header> </header>
@@ -163,9 +155,7 @@ export function AboutSection({ isPortable }: AboutSectionProps) {
{isPortable ? ( {isPortable ? (
<p className="inline-flex items-center gap-1 text-xs text-muted-foreground"> <p className="inline-flex items-center gap-1 text-xs text-muted-foreground">
<Info className="h-3 w-3" /> <Info className="h-3 w-3" />
{t("settings.portableMode", { {t("settings.portableMode")}
defaultValue: "当前为便携版,更新需手动下载。",
})}
</p> </p>
) : null} ) : null}
</div> </div>
@@ -190,20 +180,19 @@ export function AboutSection({ isPortable }: AboutSectionProps) {
{isDownloading ? ( {isDownloading ? (
<span className="inline-flex items-center gap-2"> <span className="inline-flex items-center gap-2">
<Loader2 className="h-4 w-4 animate-spin" /> <Loader2 className="h-4 w-4 animate-spin" />
{t("settings.updating", { defaultValue: "安装更新..." })} {t("settings.updating")}
</span> </span>
) : hasUpdate ? ( ) : hasUpdate ? (
<span className="inline-flex items-center gap-2"> <span className="inline-flex items-center gap-2">
<Download className="h-4 w-4" /> <Download className="h-4 w-4" />
{t("settings.updateTo", { {t("settings.updateTo", {
defaultValue: "更新到 {{version}}",
version: updateInfo?.availableVersion ?? "", version: updateInfo?.availableVersion ?? "",
})} })}
</span> </span>
) : isChecking ? ( ) : isChecking ? (
<span className="inline-flex items-center gap-2"> <span className="inline-flex items-center gap-2">
<RefreshCw className="h-4 w-4 animate-spin" /> <RefreshCw className="h-4 w-4 animate-spin" />
{t("settings.checking", { defaultValue: "检查中..." })} {t("settings.checking")}
</span> </span>
) : ( ) : (
t("settings.checkForUpdates") t("settings.checkForUpdates")
@@ -216,7 +205,6 @@ export function AboutSection({ isPortable }: AboutSectionProps) {
<div className="rounded-md bg-muted/40 px-3 py-2 text-xs text-muted-foreground"> <div className="rounded-md bg-muted/40 px-3 py-2 text-xs text-muted-foreground">
<p> <p>
{t("settings.updateAvailable", { {t("settings.updateAvailable", {
defaultValue: "检测到新版本:{{version}}",
version: updateInfo.availableVersion, version: updateInfo.availableVersion,
})} })}
</p> </p>

View File

@@ -57,9 +57,7 @@ export function DirectorySettings({
<DirectoryInput <DirectoryInput
label={t("settings.claudeConfigDir")} label={t("settings.claudeConfigDir")}
description={t("settings.claudeConfigDirDescription", { description={t("settings.claudeConfigDirDescription")}
defaultValue: "覆盖 Claude 配置目录 (settings.json)。",
})}
value={claudeDir} value={claudeDir}
resolvedValue={resolvedDirs.claude} resolvedValue={resolvedDirs.claude}
placeholder={t("settings.browsePlaceholderClaude")} placeholder={t("settings.browsePlaceholderClaude")}
@@ -70,9 +68,7 @@ export function DirectorySettings({
<DirectoryInput <DirectoryInput
label={t("settings.codexConfigDir")} label={t("settings.codexConfigDir")}
description={t("settings.codexConfigDirDescription", { description={t("settings.codexConfigDirDescription")}
defaultValue: "覆盖 Codex 配置目录。",
})}
value={codexDir} value={codexDir}
resolvedValue={resolvedDirs.codex} resolvedValue={resolvedDirs.codex}
placeholder={t("settings.browsePlaceholderCodex")} placeholder={t("settings.browsePlaceholderCodex")}

View File

@@ -47,9 +47,7 @@ export function ImportExportSection({
<header className="space-y-1"> <header className="space-y-1">
<h3 className="text-sm font-medium">{t("settings.importExport")}</h3> <h3 className="text-sm font-medium">{t("settings.importExport")}</h3>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
{t("settings.importExportHint", { {t("settings.importExportHint")}
defaultValue: "导入导出 cc-switch 配置,便于备份或迁移。",
})}
</p> </p>
</header> </header>
@@ -92,7 +90,7 @@ export function ImportExportSection({
{selectedFile ? ( {selectedFile ? (
<Button type="button" variant="ghost" onClick={onClear}> <Button type="button" variant="ghost" onClick={onClear}>
<XCircle className="mr-2 h-4 w-4" /> <XCircle className="mr-2 h-4 w-4" />
{t("common.clear", { defaultValue: "清除" })} {t("common.clear")}
</Button> </Button>
) : null} ) : null}
</div> </div>
@@ -103,9 +101,7 @@ export function ImportExportSection({
</p> </p>
) : ( ) : (
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
{t("settings.noFileSelected", { {t("settings.noFileSelected")}
defaultValue: "尚未选择配置文件。",
})}
</p> </p>
)} )}
</div> </div>
@@ -147,7 +143,7 @@ function ImportStatusMessage({
<div> <div>
<p className="font-medium">{t("settings.importing")}</p> <p className="font-medium">{t("settings.importing")}</p>
<p className="text-muted-foreground"> <p className="text-muted-foreground">
{t("common.loading", { defaultValue: "正在处理..." })} {t("common.loading")}
</p> </p>
</div> </div>
</div> </div>
@@ -164,10 +160,10 @@ function ImportStatusMessage({
<p className="font-medium">{t("settings.importSuccess")}</p> <p className="font-medium">{t("settings.importSuccess")}</p>
{backupId ? ( {backupId ? (
<p className="text-xs"> <p className="text-xs">
{t("settings.backupId", { defaultValue: "备份 ID" })}: {backupId} {t("settings.backupId")}: {backupId}
</p> </p>
) : null} ) : null}
<p>{t("settings.autoReload", { defaultValue: "即将刷新列表。" })}</p> <p>{t("settings.autoReload")}</p>
</div> </div>
</div> </div>
); );
@@ -175,14 +171,14 @@ function ImportStatusMessage({
const message = const message =
errorMessage || errorMessage ||
t("settings.importFailed", { defaultValue: "导入失败,请重试。" }); t("settings.importFailed");
return ( return (
<div className={`${baseClass} border-red-200 bg-red-100/70 text-red-600`}> <div className={`${baseClass} border-red-200 bg-red-100/70 text-red-600`}>
<AlertCircle className="mt-0.5 h-4 w-4" /> <AlertCircle className="mt-0.5 h-4 w-4" />
<div className="space-y-1"> <div className="space-y-1">
<p className="font-medium"> <p className="font-medium">
{t("settings.importFailed", { defaultValue: "导入失败" })} {t("settings.importFailed")}
</p> </p>
<p>{message}</p> <p>{message}</p>
</div> </div>

View File

@@ -15,9 +15,7 @@ export function LanguageSettings({ value, onChange }: LanguageSettingsProps) {
<header className="space-y-1"> <header className="space-y-1">
<h3 className="text-sm font-medium">{t("settings.language")}</h3> <h3 className="text-sm font-medium">{t("settings.language")}</h3>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
{t("settings.languageHint", { {t("settings.languageHint")}
defaultValue: "切换后立即预览界面语言,保存后永久生效。",
})}
</p> </p>
</header> </header>
<div className="inline-flex gap-1 rounded-md border border-border bg-background p-1"> <div className="inline-flex gap-1 rounded-md border border-border bg-background p-1">

View File

@@ -143,9 +143,7 @@ export function SettingsDialog({
setShowRestartPrompt(false); setShowRestartPrompt(false);
if (import.meta.env.DEV) { if (import.meta.env.DEV) {
toast.success( toast.success(
t("settings.devModeRestartHint", { t("settings.devModeRestartHint"),
defaultValue: "开发模式下不支持自动重启,请手动重新启动应用。",
}),
); );
closeAfterSave(); closeAfterSave();
return; return;
@@ -156,9 +154,7 @@ export function SettingsDialog({
} catch (error) { } catch (error) {
console.error("[SettingsDialog] Failed to restart app", error); console.error("[SettingsDialog] Failed to restart app", error);
toast.error( toast.error(
t("settings.restartFailed", { t("settings.restartFailed"),
defaultValue: "应用重启失败,请手动关闭后重新打开。",
}),
); );
} finally { } finally {
closeAfterSave(); closeAfterSave();
@@ -187,10 +183,10 @@ export function SettingsDialog({
> >
<TabsList className="grid w-full grid-cols-3"> <TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="general"> <TabsTrigger value="general">
{t("settings.tabGeneral", { defaultValue: "通用" })} {t("settings.tabGeneral")}
</TabsTrigger> </TabsTrigger>
<TabsTrigger value="advanced"> <TabsTrigger value="advanced">
{t("settings.tabAdvanced", { defaultValue: "高级" })} {t("settings.tabAdvanced")}
</TabsTrigger> </TabsTrigger>
<TabsTrigger value="about">{t("common.about")}</TabsTrigger> <TabsTrigger value="about">{t("common.about")}</TabsTrigger>
</TabsList> </TabsList>
@@ -262,7 +258,7 @@ export function SettingsDialog({
{isSaving ? ( {isSaving ? (
<span className="inline-flex items-center gap-2"> <span className="inline-flex items-center gap-2">
<Loader2 className="h-4 w-4 animate-spin" /> <Loader2 className="h-4 w-4 animate-spin" />
{t("settings.saving", { defaultValue: "正在保存..." })} {t("settings.saving")}
</span> </span>
) : ( ) : (
<> <>
@@ -284,9 +280,7 @@ export function SettingsDialog({
</DialogHeader> </DialogHeader>
<div className="px-6"> <div className="px-6">
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
{t("settings.restartRequiredMessage", { {t("settings.restartRequiredMessage")}
defaultValue: "配置目录已变更,需要重启应用生效。",
})}
</p> </p>
</div> </div>
<DialogFooter> <DialogFooter>

View File

@@ -13,9 +13,7 @@ export function ThemeSettings() {
<header className="space-y-1"> <header className="space-y-1">
<h3 className="text-sm font-medium">{t("settings.theme")}</h3> <h3 className="text-sm font-medium">{t("settings.theme")}</h3>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
{t("settings.themeHint", { {t("settings.themeHint")}
defaultValue: "选择应用的外观主题,立即生效。",
})}
</p> </p>
</header> </header>
<div className="inline-flex gap-1 rounded-md border border-border bg-background p-1"> <div className="inline-flex gap-1 rounded-md border border-border bg-background p-1">
@@ -24,21 +22,21 @@ export function ThemeSettings() {
onClick={() => setTheme("light")} onClick={() => setTheme("light")}
icon={Sun} icon={Sun}
> >
{t("settings.themeLight", { defaultValue: "浅色" })} {t("settings.themeLight")}
</ThemeButton> </ThemeButton>
<ThemeButton <ThemeButton
active={theme === "dark"} active={theme === "dark"}
onClick={() => setTheme("dark")} onClick={() => setTheme("dark")}
icon={Moon} icon={Moon}
> >
{t("settings.themeDark", { defaultValue: "深色" })} {t("settings.themeDark")}
</ThemeButton> </ThemeButton>
<ThemeButton <ThemeButton
active={theme === "system"} active={theme === "system"}
onClick={() => setTheme("system")} onClick={() => setTheme("system")}
icon={Monitor} icon={Monitor}
> >
{t("settings.themeSystem", { defaultValue: "跟随系统" })} {t("settings.themeSystem")}
</ThemeButton> </ThemeButton>
</div> </div>
</section> </section>

View File

@@ -15,9 +15,7 @@ export function WindowSettings({ settings, onChange }: WindowSettingsProps) {
<header className="space-y-1"> <header className="space-y-1">
<h3 className="text-sm font-medium">{t("settings.windowBehavior")}</h3> <h3 className="text-sm font-medium">{t("settings.windowBehavior")}</h3>
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
{t("settings.windowBehaviorHint", { {t("settings.windowBehaviorHint")}
defaultValue: "配置窗口最小化与 Claude 插件联动策略。",
})}
</p> </p>
</header> </header>

View File

@@ -20,7 +20,9 @@
"success": "Success", "success": "Success",
"error": "Error", "error": "Error",
"unknown": "Unknown", "unknown": "Unknown",
"enterValidValue": "Please enter a valid value" "enterValidValue": "Please enter a valid value",
"clear": "Clear",
"toggleTheme": "Toggle theme"
}, },
"apiKeyInput": { "apiKeyInput": {
"placeholder": "Enter API Key", "placeholder": "Enter API Key",
@@ -54,10 +56,12 @@
"enable": "Enable", "enable": "Enable",
"inUse": "In Use", "inUse": "In Use",
"editProvider": "Edit Provider", "editProvider": "Edit Provider",
"editProviderHint": "Configuration will be applied to the current provider immediately after update.",
"deleteProvider": "Delete Provider", "deleteProvider": "Delete Provider",
"addNewProvider": "Add New Provider", "addNewProvider": "Add New Provider",
"addClaudeProvider": "Add Claude Code Provider", "addClaudeProvider": "Add Claude Code Provider",
"addCodexProvider": "Add Codex Provider", "addCodexProvider": "Add Codex Provider",
"addProviderHint": "Fill in the information to quickly switch providers in the list.",
"editClaudeProvider": "Edit Claude Code Provider", "editClaudeProvider": "Edit Claude Code Provider",
"editCodexProvider": "Edit Codex Provider", "editCodexProvider": "Edit Codex Provider",
"configError": "Configuration Error", "configError": "Configuration Error",
@@ -65,7 +69,17 @@
"applyToClaudePlugin": "Apply to Claude plugin", "applyToClaudePlugin": "Apply to Claude plugin",
"removeFromClaudePlugin": "Remove from Claude plugin", "removeFromClaudePlugin": "Remove from Claude plugin",
"dragToReorder": "Drag to reorder", "dragToReorder": "Drag to reorder",
"sortUpdateFailed": "Failed to update sort order" "dragHandle": "Drag to reorder",
"sortUpdateFailed": "Failed to update sort order",
"configureUsage": "Configure usage query",
"name": "Provider Name",
"websiteUrl": "Website URL",
"configJson": "Config JSON",
"writeCommonConfig": "Write common config",
"editCommonConfigButton": "Edit common config",
"configJsonHint": "Please fill in complete Claude Code configuration",
"editCommonConfigTitle": "Edit common config snippet",
"editCommonConfigHint": "Common config snippet will be merged into all providers that enable it"
}, },
"notifications": { "notifications": {
"providerSaved": "Provider configuration saved", "providerSaved": "Provider configuration saved",
@@ -86,6 +100,8 @@
"settings": { "settings": {
"title": "Settings", "title": "Settings",
"general": "General", "general": "General",
"tabGeneral": "General",
"tabAdvanced": "Advanced",
"language": "Language", "language": "Language",
"languageHint": "Preview interface language immediately after switching, takes effect permanently after saving.", "languageHint": "Preview interface language immediately after switching, takes effect permanently after saving.",
"theme": "Theme", "theme": "Theme",
@@ -94,8 +110,10 @@
"themeDark": "Dark", "themeDark": "Dark",
"themeSystem": "System", "themeSystem": "System",
"importExport": "Import/Export Config", "importExport": "Import/Export Config",
"importExportHint": "Import or export cc-switch configuration for backup or migration.",
"exportConfig": "Export Config to File", "exportConfig": "Export Config to File",
"selectConfigFile": "Select Config File", "selectConfigFile": "Select Config File",
"noFileSelected": "No configuration file selected.",
"import": "Import", "import": "Import",
"importing": "Importing...", "importing": "Importing...",
"importSuccess": "Import Successful!", "importSuccess": "Import Successful!",
@@ -109,6 +127,7 @@
"languageOptionChinese": "中文", "languageOptionChinese": "中文",
"languageOptionEnglish": "English", "languageOptionEnglish": "English",
"windowBehavior": "Window Behavior", "windowBehavior": "Window Behavior",
"windowBehaviorHint": "Configure window minimize and Claude plugin integration policies.",
"minimizeToTray": "Minimize to tray on close", "minimizeToTray": "Minimize to tray on close",
"minimizeToTrayDescription": "When checked, clicking the close button will hide to system tray, otherwise the app will exit directly.", "minimizeToTrayDescription": "When checked, clicking the close button will hide to system tray, otherwise the app will exit directly.",
"enableClaudePluginIntegration": "Apply to Claude Code extension", "enableClaudePluginIntegration": "Apply to Claude Code extension",
@@ -119,7 +138,9 @@
"appConfigDirDescription": "Customize the storage location for CC-Switch configuration files (config.json, etc.)", "appConfigDirDescription": "Customize the storage location for CC-Switch configuration files (config.json, etc.)",
"browsePlaceholderApp": "e.g., C:\\Users\\Administrator\\.cc-switch", "browsePlaceholderApp": "e.g., C:\\Users\\Administrator\\.cc-switch",
"claudeConfigDir": "Claude Code Configuration Directory", "claudeConfigDir": "Claude Code Configuration Directory",
"claudeConfigDirDescription": "Override Claude configuration directory (settings.json).",
"codexConfigDir": "Codex Configuration Directory", "codexConfigDir": "Codex Configuration Directory",
"codexConfigDirDescription": "Override Codex configuration directory.",
"browsePlaceholderClaude": "e.g., /home/<your-username>/.claude", "browsePlaceholderClaude": "e.g., /home/<your-username>/.claude",
"browsePlaceholderCodex": "e.g., /home/<your-username>/.codex", "browsePlaceholderCodex": "e.g., /home/<your-username>/.codex",
"browseDirectory": "Browse Directory", "browseDirectory": "Browse Directory",
@@ -129,6 +150,12 @@
"updating": "Updating...", "updating": "Updating...",
"checking": "Checking...", "checking": "Checking...",
"upToDate": "Up to Date", "upToDate": "Up to Date",
"aboutHint": "View version information and update status.",
"portableMode": "Portable mode: updates require manual download.",
"updateAvailable": "New version available: {{version}}",
"updateFailed": "Update installation failed, attempted to open download page.",
"checkUpdateFailed": "Failed to check for updates, please try again later.",
"openReleaseNotesFailed": "Failed to open release notes",
"releaseNotes": "Release Notes", "releaseNotes": "Release Notes",
"viewReleaseNotes": "View release notes for this version", "viewReleaseNotes": "View release notes for this version",
"viewCurrentReleaseNotes": "View current version release notes", "viewCurrentReleaseNotes": "View current version release notes",
@@ -137,7 +164,9 @@
"restartRequiredMessage": "Modifying the CC-Switch configuration directory requires restarting the application to take effect. Restart now?", "restartRequiredMessage": "Modifying the CC-Switch configuration directory requires restarting the application to take effect. Restart now?",
"restartNow": "Restart Now", "restartNow": "Restart Now",
"restartLater": "Restart Later", "restartLater": "Restart Later",
"devModeRestartHint": "Dev Mode: Configuration saved. Please manually restart the application for changes to take effect" "restartFailed": "Application restart failed, please manually close and reopen.",
"devModeRestartHint": "Dev Mode: Automatic restart not supported, please manually restart the application.",
"saving": "Saving..."
}, },
"apps": { "apps": {
"claude": "Claude Code", "claude": "Claude Code",
@@ -177,9 +206,9 @@
"manualConfig": "Manually configure provider, requires complete configuration, or", "manualConfig": "Manually configure provider, requires complete configuration, or",
"officialNoApiKey": "Official login does not require API Key, save directly", "officialNoApiKey": "Official login does not require API Key, save directly",
"codexOfficialNoApiKey": "Official does not require API Key, save directly", "codexOfficialNoApiKey": "Official does not require API Key, save directly",
"codexApiKeyAutoFill": "Just fill in here, auth.json below will be auto-filled",
"kimiApiKeyHint": "Fill in to get model list", "kimiApiKeyHint": "Fill in to get model list",
"apiKeyAutoFill": "Just fill in here, config below will be auto-filled", "apiKeyAutoFill": "Just fill in here, config below will be auto-filled",
"codexApiKeyAutoFill": "Just fill in here, auth.json below will be auto-filled",
"getApiKey": "Get API Key", "getApiKey": "Get API Key",
"parameterConfig": "Parameter Config - {{name}} *", "parameterConfig": "Parameter Config - {{name}} *",
"mainModel": "Main Model (optional)", "mainModel": "Main Model (optional)",
@@ -192,12 +221,22 @@
"fillSupplierName": "Please fill in provider name", "fillSupplierName": "Please fill in provider name",
"fillConfigContent": "Please fill in configuration content", "fillConfigContent": "Please fill in configuration content",
"fillParameter": "Please fill in {{label}}", "fillParameter": "Please fill in {{label}}",
"fillTemplateValue": "Please fill in {{label}}",
"configJsonError": "Config JSON format error, please check syntax", "configJsonError": "Config JSON format error, please check syntax",
"authJsonRequired": "auth.json must be a JSON object", "authJsonRequired": "auth.json must be a JSON object",
"authJsonError": "auth.json format error, please check JSON syntax", "authJsonError": "auth.json format error, please check JSON syntax",
"fillAuthJson": "Please fill in auth.json configuration", "fillAuthJson": "Please fill in auth.json configuration",
"fillApiKey": "Please fill in OPENAI_API_KEY", "fillApiKey": "Please fill in OPENAI_API_KEY",
"visitWebsite": "Visit {{url}}" "visitWebsite": "Visit {{url}}",
"anthropicModel": "Main Model",
"anthropicSmallFastModel": "Fast Model",
"modelPlaceholder": "claude-3-7-sonnet-20250219",
"smallModelPlaceholder": "claude-3-5-haiku-20241022",
"modelHelper": "Optional: Specify default Claude model to use, leave blank to use system default.",
"categoryOfficial": "Official",
"categoryCnOfficial": "China Official",
"categoryAggregation": "Aggregation",
"categoryThirdParty": "Third Party"
}, },
"endpointTest": { "endpointTest": {
"title": "API Endpoint Management", "title": "API Endpoint Management",
@@ -252,6 +291,12 @@
"configPreview": "Configuration Preview", "configPreview": "Configuration Preview",
"applyConfig": "Apply Configuration" "applyConfig": "Apply Configuration"
}, },
"providerPreset": {
"label": "Provider Preset",
"custom": "Custom Configuration",
"other": "Other",
"hint": "You can continue to adjust the fields below after selecting a preset."
},
"kimiSelector": { "kimiSelector": {
"modelConfig": "Model Configuration", "modelConfig": "Model Configuration",
"mainModel": "Main Model", "mainModel": "Main Model",

View File

@@ -20,7 +20,9 @@
"success": "成功", "success": "成功",
"error": "错误", "error": "错误",
"unknown": "未知", "unknown": "未知",
"enterValidValue": "请输入有效的内容" "enterValidValue": "请输入有效的内容",
"clear": "清除",
"toggleTheme": "切换主题"
}, },
"apiKeyInput": { "apiKeyInput": {
"placeholder": "请输入API Key", "placeholder": "请输入API Key",
@@ -54,10 +56,12 @@
"enable": "启用", "enable": "启用",
"inUse": "使用中", "inUse": "使用中",
"editProvider": "编辑供应商", "editProvider": "编辑供应商",
"editProviderHint": "更新配置后将立即应用到当前供应商。",
"deleteProvider": "删除供应商", "deleteProvider": "删除供应商",
"addNewProvider": "添加新供应商", "addNewProvider": "添加新供应商",
"addClaudeProvider": "添加 Claude Code 供应商", "addClaudeProvider": "添加 Claude Code 供应商",
"addCodexProvider": "添加 Codex 供应商", "addCodexProvider": "添加 Codex 供应商",
"addProviderHint": "填写信息后即可在列表中快速切换供应商。",
"editClaudeProvider": "编辑 Claude Code 供应商", "editClaudeProvider": "编辑 Claude Code 供应商",
"editCodexProvider": "编辑 Codex 供应商", "editCodexProvider": "编辑 Codex 供应商",
"configError": "配置错误", "configError": "配置错误",
@@ -65,7 +69,17 @@
"applyToClaudePlugin": "应用到 Claude 插件", "applyToClaudePlugin": "应用到 Claude 插件",
"removeFromClaudePlugin": "从 Claude 插件移除", "removeFromClaudePlugin": "从 Claude 插件移除",
"dragToReorder": "拖拽以重新排序", "dragToReorder": "拖拽以重新排序",
"sortUpdateFailed": "排序更新失败" "dragHandle": "拖拽排序",
"sortUpdateFailed": "排序更新失败",
"configureUsage": "配置用量查询",
"name": "供应商名称",
"websiteUrl": "官网链接",
"configJson": "配置 JSON",
"writeCommonConfig": "写入通用配置",
"editCommonConfigButton": "编辑通用配置",
"configJsonHint": "请填写完整的 Claude Code 配置",
"editCommonConfigTitle": "编辑通用配置片段",
"editCommonConfigHint": "通用配置片段将合并到所有启用它的供应商配置中"
}, },
"notifications": { "notifications": {
"providerSaved": "供应商配置已保存", "providerSaved": "供应商配置已保存",
@@ -86,6 +100,8 @@
"settings": { "settings": {
"title": "设置", "title": "设置",
"general": "通用", "general": "通用",
"tabGeneral": "通用",
"tabAdvanced": "高级",
"language": "界面语言", "language": "界面语言",
"languageHint": "切换后立即预览界面语言,保存后永久生效。", "languageHint": "切换后立即预览界面语言,保存后永久生效。",
"theme": "外观主题", "theme": "外观主题",
@@ -94,8 +110,10 @@
"themeDark": "深色", "themeDark": "深色",
"themeSystem": "跟随系统", "themeSystem": "跟随系统",
"importExport": "导入导出配置", "importExport": "导入导出配置",
"importExportHint": "导入导出 cc-switch 配置,便于备份或迁移。",
"exportConfig": "导出配置到文件", "exportConfig": "导出配置到文件",
"selectConfigFile": "选择配置文件", "selectConfigFile": "选择配置文件",
"noFileSelected": "尚未选择配置文件。",
"import": "导入", "import": "导入",
"importing": "导入中...", "importing": "导入中...",
"importSuccess": "导入成功!", "importSuccess": "导入成功!",
@@ -109,6 +127,7 @@
"languageOptionChinese": "中文", "languageOptionChinese": "中文",
"languageOptionEnglish": "English", "languageOptionEnglish": "English",
"windowBehavior": "窗口行为", "windowBehavior": "窗口行为",
"windowBehaviorHint": "配置窗口最小化与 Claude 插件联动策略。",
"minimizeToTray": "关闭时最小化到托盘", "minimizeToTray": "关闭时最小化到托盘",
"minimizeToTrayDescription": "勾选后点击关闭按钮会隐藏到系统托盘,取消则直接退出应用。", "minimizeToTrayDescription": "勾选后点击关闭按钮会隐藏到系统托盘,取消则直接退出应用。",
"enableClaudePluginIntegration": "应用到 Claude Code 插件", "enableClaudePluginIntegration": "应用到 Claude Code 插件",
@@ -119,7 +138,9 @@
"appConfigDirDescription": "自定义 CC-Switch 的配置存储位置config.json 等文件)", "appConfigDirDescription": "自定义 CC-Switch 的配置存储位置config.json 等文件)",
"browsePlaceholderApp": "例如C:\\Users\\Administrator\\.cc-switch", "browsePlaceholderApp": "例如C:\\Users\\Administrator\\.cc-switch",
"claudeConfigDir": "Claude Code 配置目录", "claudeConfigDir": "Claude Code 配置目录",
"claudeConfigDirDescription": "覆盖 Claude 配置目录 (settings.json)。",
"codexConfigDir": "Codex 配置目录", "codexConfigDir": "Codex 配置目录",
"codexConfigDirDescription": "覆盖 Codex 配置目录。",
"browsePlaceholderClaude": "例如:/home/<你的用户名>/.claude", "browsePlaceholderClaude": "例如:/home/<你的用户名>/.claude",
"browsePlaceholderCodex": "例如:/home/<你的用户名>/.codex", "browsePlaceholderCodex": "例如:/home/<你的用户名>/.codex",
"browseDirectory": "浏览目录", "browseDirectory": "浏览目录",
@@ -129,6 +150,12 @@
"updating": "更新中...", "updating": "更新中...",
"checking": "检查中...", "checking": "检查中...",
"upToDate": "已是最新", "upToDate": "已是最新",
"aboutHint": "查看版本信息与更新状态。",
"portableMode": "当前为便携版,更新需手动下载。",
"updateAvailable": "检测到新版本:{{version}}",
"updateFailed": "更新安装失败,已尝试打开下载页面。",
"checkUpdateFailed": "检查更新失败,请稍后重试。",
"openReleaseNotesFailed": "打开更新日志失败",
"releaseNotes": "更新日志", "releaseNotes": "更新日志",
"viewReleaseNotes": "查看该版本更新日志", "viewReleaseNotes": "查看该版本更新日志",
"viewCurrentReleaseNotes": "查看当前版本更新日志", "viewCurrentReleaseNotes": "查看当前版本更新日志",
@@ -137,7 +164,9 @@
"restartRequiredMessage": "修改 CC-Switch 配置目录后需要重启应用才能生效,是否立即重启?", "restartRequiredMessage": "修改 CC-Switch 配置目录后需要重启应用才能生效,是否立即重启?",
"restartNow": "立即重启", "restartNow": "立即重启",
"restartLater": "稍后重启", "restartLater": "稍后重启",
"devModeRestartHint": "开发模式:配置已保存,请手动重启应用以使新配置生效" "restartFailed": "应用重启失败,请手动关闭后重新打开。",
"devModeRestartHint": "开发模式下不支持自动重启,请手动重新启动应用。",
"saving": "正在保存..."
}, },
"apps": { "apps": {
"claude": "Claude Code", "claude": "Claude Code",
@@ -177,9 +206,9 @@
"manualConfig": "手动配置供应商,需要填写完整的配置信息,或者", "manualConfig": "手动配置供应商,需要填写完整的配置信息,或者",
"officialNoApiKey": "官方登录无需填写 API Key直接保存即可", "officialNoApiKey": "官方登录无需填写 API Key直接保存即可",
"codexOfficialNoApiKey": "官方无需填写 API Key直接保存即可", "codexOfficialNoApiKey": "官方无需填写 API Key直接保存即可",
"codexApiKeyAutoFill": "只需要填这里,下方 auth.json 会自动填充",
"kimiApiKeyHint": "填写后可获取模型列表", "kimiApiKeyHint": "填写后可获取模型列表",
"apiKeyAutoFill": "只需要填这里,下方配置会自动填充", "apiKeyAutoFill": "只需要填这里,下方配置会自动填充",
"codexApiKeyAutoFill": "只需要填这里,下方 auth.json 会自动填充",
"getApiKey": "获取 API Key", "getApiKey": "获取 API Key",
"parameterConfig": "参数配置 - {{name}} *", "parameterConfig": "参数配置 - {{name}} *",
"mainModel": "主模型 (可选)", "mainModel": "主模型 (可选)",
@@ -192,12 +221,22 @@
"fillSupplierName": "请填写供应商名称", "fillSupplierName": "请填写供应商名称",
"fillConfigContent": "请填写配置内容", "fillConfigContent": "请填写配置内容",
"fillParameter": "请填写 {{label}}", "fillParameter": "请填写 {{label}}",
"fillTemplateValue": "请填写 {{label}}",
"configJsonError": "配置JSON格式错误请检查语法", "configJsonError": "配置JSON格式错误请检查语法",
"authJsonRequired": "auth.json 必须是 JSON 对象", "authJsonRequired": "auth.json 必须是 JSON 对象",
"authJsonError": "auth.json 格式错误请检查JSON语法", "authJsonError": "auth.json 格式错误请检查JSON语法",
"fillAuthJson": "请填写 auth.json 配置", "fillAuthJson": "请填写 auth.json 配置",
"fillApiKey": "请填写 OPENAI_API_KEY", "fillApiKey": "请填写 OPENAI_API_KEY",
"visitWebsite": "访问 {{url}}" "visitWebsite": "访问 {{url}}",
"anthropicModel": "主模型",
"anthropicSmallFastModel": "快速模型",
"modelPlaceholder": "claude-3-7-sonnet-20250219",
"smallModelPlaceholder": "claude-3-5-haiku-20241022",
"modelHelper": "可选:指定默认使用的 Claude 模型,留空则使用系统默认。",
"categoryOfficial": "官方",
"categoryCnOfficial": "国内官方",
"categoryAggregation": "聚合服务",
"categoryThirdParty": "第三方"
}, },
"endpointTest": { "endpointTest": {
"title": "请求地址管理", "title": "请求地址管理",
@@ -252,6 +291,12 @@
"configPreview": "配置预览", "configPreview": "配置预览",
"applyConfig": "应用配置" "applyConfig": "应用配置"
}, },
"providerPreset": {
"label": "预设供应商",
"custom": "自定义配置",
"other": "其他",
"hint": "选择预设后可继续调整下方字段。"
},
"kimiSelector": { "kimiSelector": {
"modelConfig": "模型配置", "modelConfig": "模型配置",
"mainModel": "主模型", "mainModel": "主模型",