@@ -407,7 +409,7 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
type="button"
onClick={() => handleResetConfigDir("claude")}
className="px-2 py-2 text-xs text-gray-500 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors"
- title="恢复默认目录(需保存后生效)"
+ title={t("settings.resetDefault")}
>
@@ -416,7 +418,7 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
@@ -443,7 +445,7 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
type="button"
onClick={() => handleResetConfigDir("codex")}
className="px-2 py-2 text-xs text-gray-500 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors"
- title="恢复默认目录(需保存后生效)"
+ title={t("settings.resetDefault")}
>
@@ -455,7 +457,7 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
{/* 关于 */}
- 关于
+ {t("common.about")}
@@ -465,7 +467,7 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
CC Switch
- 版本 {version}
+ {t("common.version")} {version}
@@ -474,12 +476,14 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
onClick={handleOpenReleaseNotes}
className="px-2 py-1 text-xs font-medium text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300 rounded-lg hover:bg-blue-500/10 transition-colors"
title={
- hasUpdate ? "查看该版本更新日志" : "查看当前版本更新日志"
+ hasUpdate
+ ? t("settings.viewReleaseNotes")
+ : t("settings.viewCurrentReleaseNotes")
}
>
- 更新日志
+ {t("settings.releaseNotes")}
@@ -531,14 +537,14 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
onClick={onClose}
className="px-4 py-2 text-sm font-medium text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors"
>
- 取消
+ {t("common.cancel")}
diff --git a/src/i18n/index.ts b/src/i18n/index.ts
new file mode 100644
index 0000000..8c7d3e2
--- /dev/null
+++ b/src/i18n/index.ts
@@ -0,0 +1,29 @@
+import i18n from "i18next";
+import { initReactI18next } from "react-i18next";
+
+import en from "./locales/en.json";
+import zh from "./locales/zh.json";
+
+const resources = {
+ en: {
+ translation: en,
+ },
+ zh: {
+ translation: zh,
+ },
+};
+
+i18n.use(initReactI18next).init({
+ resources,
+ lng: "en", // 默认语言设置为英文
+ fallbackLng: "en", // 回退语言也设置为英文
+
+ interpolation: {
+ escapeValue: false, // React 已经默认转义
+ },
+
+ // 开发模式下显示调试信息
+ debug: false,
+});
+
+export default i18n;
diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json
new file mode 100644
index 0000000..c7b6b29
--- /dev/null
+++ b/src/i18n/locales/en.json
@@ -0,0 +1,111 @@
+{
+ "app": {
+ "title": "CC Switch",
+ "description": "Claude Code & Codex Provider Switching Tool"
+ },
+ "common": {
+ "add": "Add",
+ "edit": "Edit",
+ "delete": "Delete",
+ "save": "Save",
+ "cancel": "Cancel",
+ "confirm": "Confirm",
+ "close": "Close",
+ "settings": "Settings",
+ "about": "About",
+ "version": "Version",
+ "loading": "Loading...",
+ "success": "Success",
+ "error": "Error",
+ "unknown": "Unknown"
+ },
+ "header": {
+ "viewOnGithub": "View on GitHub",
+ "toggleDarkMode": "Switch to Dark Mode",
+ "toggleLightMode": "Switch to Light Mode",
+ "addProvider": "Add Provider",
+ "switchToChinese": "Switch to Chinese",
+ "switchToEnglish": "Switch to English"
+ },
+ "provider": {
+ "noProviders": "No providers added yet",
+ "noProvidersDescription": "Click the \"Add Provider\" button in the top right to configure your first API provider",
+ "currentlyUsing": "Currently Using",
+ "enable": "Enable",
+ "inUse": "In Use",
+ "editProvider": "Edit Provider",
+ "deleteProvider": "Delete Provider",
+ "addNewProvider": "Add New Provider",
+ "configError": "Configuration Error",
+ "notConfigured": "Not configured for official website",
+ "applyToVSCode": "Apply to VS Code",
+ "removeFromVSCode": "Remove from VS Code"
+ },
+ "notifications": {
+ "providerSaved": "Provider configuration saved",
+ "providerDeleted": "Provider deleted successfully",
+ "switchSuccess": "Switch successful! Please restart {{appName}} terminal to take effect",
+ "switchFailed": "Switch failed, please check configuration",
+ "autoImported": "Default provider created from existing configuration",
+ "appliedToVSCode": "Applied to VS Code, restart Codex plugin to take effect",
+ "removedFromVSCode": "Removed from VS Code, restart Codex plugin to take effect",
+ "syncedToVSCode": "Synced to VS Code",
+ "vscodeSettingsNotFound": "VS Code user settings file (settings.json) not found",
+ "missingBaseUrl": "Current configuration missing base_url, cannot write to VS Code",
+ "saveFailed": "Save failed: {{error}}",
+ "saveFailedGeneric": "Save failed, please try again",
+ "syncVSCodeFailed": "Sync to VS Code failed"
+ },
+ "confirm": {
+ "deleteProvider": "Delete Provider",
+ "deleteProviderMessage": "Are you sure you want to delete provider \"{{name}}\"? This action cannot be undone."
+ },
+ "settings": {
+ "title": "Settings",
+ "windowBehavior": "Window Behavior",
+ "minimizeToTray": "Minimize to tray on close",
+ "minimizeToTrayDescription": "When checked, clicking the close button will hide to system tray, otherwise the app will exit directly.",
+ "configFileLocation": "Configuration File Location",
+ "openFolder": "Open Folder",
+ "configDirectoryOverride": "Configuration Directory Override (Advanced)",
+ "configDirectoryDescription": "When using Claude Code or Codex in environments like WSL, you can manually specify the configuration directory in WSL to keep provider data consistent with the main environment.",
+ "claudeConfigDir": "Claude Code Configuration Directory",
+ "codexConfigDir": "Codex Configuration Directory",
+ "browsePlaceholderClaude": "e.g., /home/
/.claude",
+ "browsePlaceholderCodex": "e.g., /home//.codex",
+ "browseDirectory": "Browse Directory",
+ "resetDefault": "Reset to default directory (takes effect after saving)",
+ "checkForUpdates": "Check for Updates",
+ "updateTo": "Update to v{{version}}",
+ "updating": "Updating...",
+ "checking": "Checking...",
+ "upToDate": "Up to Date",
+ "releaseNotes": "Release Notes",
+ "viewReleaseNotes": "View release notes for this version",
+ "viewCurrentReleaseNotes": "View current version release notes"
+ },
+ "apps": {
+ "claude": "Claude Code",
+ "codex": "Codex"
+ },
+ "console": {
+ "providerSwitchReceived": "Received provider switch event:",
+ "setupListenerFailed": "Failed to setup provider switch listener:",
+ "updateProviderFailed": "Update provider failed:",
+ "syncToVSCodeFailed": "Sync to VS Code failed:",
+ "autoImportFailed": "Auto import default configuration failed:",
+ "openLinkFailed": "Failed to open link:",
+ "getVersionFailed": "Failed to get version info:",
+ "loadSettingsFailed": "Failed to load settings:",
+ "getConfigPathFailed": "Failed to get config path:",
+ "getConfigDirFailed": "Failed to get config directory:",
+ "detectPortableFailed": "Failed to detect portable mode:",
+ "saveSettingsFailed": "Failed to save settings:",
+ "updateFailed": "Update failed:",
+ "checkUpdateFailed": "Check for updates failed:",
+ "openConfigFolderFailed": "Failed to open config folder:",
+ "selectConfigDirFailed": "Failed to select config directory:",
+ "getDefaultConfigDirFailed": "Failed to get default config directory:",
+ "openReleaseNotesFailed": "Failed to open release notes:"
+ }
+}
diff --git a/src/i18n/locales/zh.json b/src/i18n/locales/zh.json
new file mode 100644
index 0000000..8cf5767
--- /dev/null
+++ b/src/i18n/locales/zh.json
@@ -0,0 +1,111 @@
+{
+ "app": {
+ "title": "CC Switch",
+ "description": "Claude Code & Codex 供应商切换工具"
+ },
+ "common": {
+ "add": "添加",
+ "edit": "编辑",
+ "delete": "删除",
+ "save": "保存",
+ "cancel": "取消",
+ "confirm": "确定",
+ "close": "关闭",
+ "settings": "设置",
+ "about": "关于",
+ "version": "版本",
+ "loading": "加载中...",
+ "success": "成功",
+ "error": "错误",
+ "unknown": "未知"
+ },
+ "header": {
+ "viewOnGithub": "在 GitHub 上查看",
+ "toggleDarkMode": "切换到暗色模式",
+ "toggleLightMode": "切换到亮色模式",
+ "addProvider": "添加供应商",
+ "switchToChinese": "切换到中文",
+ "switchToEnglish": "切换到英文"
+ },
+ "provider": {
+ "noProviders": "还没有添加任何供应商",
+ "noProvidersDescription": "点击右上角的\"添加供应商\"按钮开始配置您的第一个API供应商",
+ "currentlyUsing": "当前使用",
+ "enable": "启用",
+ "inUse": "使用中",
+ "editProvider": "编辑供应商",
+ "deleteProvider": "删除供应商",
+ "addNewProvider": "添加新供应商",
+ "configError": "配置错误",
+ "notConfigured": "未配置官网地址",
+ "applyToVSCode": "应用到 VS Code",
+ "removeFromVSCode": "从 VS Code 移除"
+ },
+ "notifications": {
+ "providerSaved": "供应商配置已保存",
+ "providerDeleted": "供应商删除成功",
+ "switchSuccess": "切换成功!请重启 {{appName}} 终端以生效",
+ "switchFailed": "切换失败,请检查配置",
+ "autoImported": "已从现有配置创建默认供应商",
+ "appliedToVSCode": "已应用到 VS Code,重启 Codex 插件以生效",
+ "removedFromVSCode": "已从 VS Code 移除,重启 Codex 插件以生效",
+ "syncedToVSCode": "已同步到 VS Code",
+ "vscodeSettingsNotFound": "未找到 VS Code 用户设置文件 (settings.json)",
+ "missingBaseUrl": "当前配置缺少 base_url,无法写入 VS Code",
+ "saveFailed": "保存失败:{{error}}",
+ "saveFailedGeneric": "保存失败,请重试",
+ "syncVSCodeFailed": "同步 VS Code 失败"
+ },
+ "confirm": {
+ "deleteProvider": "删除供应商",
+ "deleteProviderMessage": "确定要删除供应商 \"{{name}}\" 吗?此操作无法撤销。"
+ },
+ "settings": {
+ "title": "设置",
+ "windowBehavior": "窗口行为",
+ "minimizeToTray": "关闭时最小化到托盘",
+ "minimizeToTrayDescription": "勾选后点击关闭按钮会隐藏到系统托盘,取消则直接退出应用。",
+ "configFileLocation": "配置文件位置",
+ "openFolder": "打开文件夹",
+ "configDirectoryOverride": "配置目录覆盖(高级)",
+ "configDirectoryDescription": "在 WSL 等环境使用 Claude Code 或 Codex 的时候,可手动指定 WSL 里的配置目录,供应商数据与主环境保持一致。",
+ "claudeConfigDir": "Claude Code 配置目录",
+ "codexConfigDir": "Codex 配置目录",
+ "browsePlaceholderClaude": "例如:/home/<你的用户名>/.claude",
+ "browsePlaceholderCodex": "例如:/home/<你的用户名>/.codex",
+ "browseDirectory": "浏览目录",
+ "resetDefault": "恢复默认目录(需保存后生效)",
+ "checkForUpdates": "检查更新",
+ "updateTo": "更新到 v{{version}}",
+ "updating": "更新中...",
+ "checking": "检查中...",
+ "upToDate": "已是最新",
+ "releaseNotes": "更新日志",
+ "viewReleaseNotes": "查看该版本更新日志",
+ "viewCurrentReleaseNotes": "查看当前版本更新日志"
+ },
+ "apps": {
+ "claude": "Claude Code",
+ "codex": "Codex"
+ },
+ "console": {
+ "providerSwitchReceived": "收到供应商切换事件:",
+ "setupListenerFailed": "设置供应商切换监听器失败:",
+ "updateProviderFailed": "更新供应商失败:",
+ "syncToVSCodeFailed": "同步到VS Code失败:",
+ "autoImportFailed": "自动导入默认配置失败:",
+ "openLinkFailed": "打开链接失败:",
+ "getVersionFailed": "获取版本信息失败:",
+ "loadSettingsFailed": "加载设置失败:",
+ "getConfigPathFailed": "获取配置路径失败:",
+ "getConfigDirFailed": "获取配置目录失败:",
+ "detectPortableFailed": "检测便携模式失败:",
+ "saveSettingsFailed": "保存设置失败:",
+ "updateFailed": "更新失败:",
+ "checkUpdateFailed": "检查更新失败:",
+ "openConfigFolderFailed": "打开配置文件夹失败:",
+ "selectConfigDirFailed": "选择配置目录失败:",
+ "getDefaultConfigDirFailed": "获取默认配置目录失败:",
+ "openReleaseNotesFailed": "打开更新日志失败:"
+ }
+}
diff --git a/src/main.tsx b/src/main.tsx
index 5d77b49..8bdc674 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -5,6 +5,8 @@ import { UpdateProvider } from "./contexts/UpdateContext";
import "./index.css";
// 导入 Tauri API(自动绑定到 window.api)
import "./lib/tauri-api";
+// 导入国际化配置
+import "./i18n";
// 根据平台添加 body class,便于平台特定样式
try {
@@ -23,5 +25,5 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
- ,
+
);