feat(i18n): add multi-language support (ja/ko/vi/ru/zh-TW) with system auto-detection

- Extend AppLanguage to 7 locales: zh-CN, zh-TW, en, ja, ko, vi, ru
- Auto-detect system language via navigator.languages; fallback to English
- Add BCP47 locale mapping for date formatting and sorting
- Create 50 translation JSON files (5 languages × 10 namespaces, 1137 keys each)
- Update language selector with native language names
- Extend locale key parity test to cover all 7 languages (70 assertions)
- Add VNC/RDP desktop, serial terminal, AI agent, port forwarding, and SFTP features
- Add credential encryption, host metrics, session backup crypto, and zmodem bridge
- Update Rust backend: desktop services, host metrics, SSH/SFTP enhancements
This commit is contained in:
Logan.Li committed 2026-08-12 00:07:48 +08:00
1 parent fea6d8db04
commit b0d0e3a5f3
301 files changed
+28002 -2705

No files matched your search

+174
View File
@@ -0,0 +1,174 @@
{
"nav": {
"general": "Рабочее пространство",
"generalDesc": "Макет и ресурсы",
"appearance": "Внешний вид",
"appearanceDesc": "Тема и язык",
"terminal": "Терминал",
"terminalDesc": "Шрифт и цвета",
"shortcuts": "Горячие клавиши",
"shortcutsDesc": "Назначение клавиш",
"ssh": "SSH",
"sshDesc": "Подключение и пул",
"security": "Безопасность",
"securityDesc": "Учётные данные и ключи хостов",
"ai": "AI-модели",
"aiDesc": "AI-провайдеры",
"about": "О приложении",
"aboutDesc": "Версия и данные"
},
"title": "Настройки",
"search": {
"placeholder": "Поиск по настройкам..."
},
"language": {
"label": "Язык",
"description": "Применяется сразу",
"zhCN": "简体中文",
"zhTW": "繁體中文",
"en": "English",
"ja": "日本語",
"ko": "한국어",
"vi": "Tiếng Việt",
"ru": "Русский"
},
"general": {
"layout": "Макет рабочего пространства",
"sidebarWidth": "Ширина боковой панели",
"sidebarWidthDesc": "Ширина панели сеансов по умолчанию",
"collapseSidebar": "Сворачивать боковую панель",
"collapseSidebarDesc": "Скрывать дерево сеансов, чтобы сосредоточиться на терминале; переключайте через Ctrl/Cmd+B"
},
"appearance": {
"themeGroup": "Тема",
"theme": "Тема",
"themeDesc": "Цвета интерфейса приложения (независимо от цветов терминала)",
"dark": "Тёмная",
"light": "Светлая",
"system": "Системная"
},
"terminal": {
"fontGroup": "Шрифт и размер",
"fontFamily": "Шрифт",
"fontFamilyDesc": "Используйте Nerd Font для значков в приглашении Zsh",
"fontSize": "Размер",
"fontSizeDesc": "Размер текста терминала",
"scrollback": "Буфер прокрутки",
"scrollbackDesc": "Количество сохраняемых строк истории на терминал",
"keywordHighlight": "Подсветка ключевых слов",
"keywordHighlightDesc": "Подсвечивать ошибки, предупреждения и состояния успеха",
"colorTheme": "Цветовая тема"
},
"shortcuts": {
"resetAll": "Сбросить все по умолчанию",
"custom": "Свои",
"pressKeys": "Нажмите клавиши...",
"resetDefault": "Сбросить по умолчанию",
"conflict": "Конфликтует с «{{label}}»",
"setTo": "Установлено: {{keys}}",
"hint": "Нажмите на горячую клавишу, чтобы переназначить · Esc для отмены",
"category": {
"tabs": "Вкладки",
"view": "Вид",
"session": "Сеанс",
"tools": "Инструменты"
},
"actions": {
"tabNext": "Следующая вкладка",
"tabPrev": "Предыдущая вкладка",
"tabGotoN": "Перейти к вкладке N",
"tabClose": "Закрыть текущую вкладку",
"tabNew": "Новая вкладка",
"viewFullscreen": "Полноэкранный режим",
"viewToggleSidebar": "Показать/скрыть боковую панель",
"sessionNew": "Новый сеанс",
"sessionQuickConnect": "Быстрое подключение",
"toolsCommandPalette": "Палитра команд"
}
},
"ssh": {
"connection": "Подключение",
"keepAlive": "Keep-alive",
"keepAliveDesc": "Отправлять keep-alive при простое для уменьшения разрывов",
"autoReconnect": "Авто-переподключение",
"autoReconnectDesc": "Автоматически повторять после неожиданного разрыва",
"timeout": "Тайм-аут подключения",
"timeoutDesc": "Максимальное время ожидания при установке SSH (секунды)",
"maxReconnect": "Попытки переподключения",
"maxReconnectDesc": "Максимум повторов после неожиданного разрыва",
"pool": "Пул подключений",
"maxConnections": "Максимум подключений",
"maxConnectionsDesc": "Общий лимит для SSH, SFTP и пакетных подключений",
"maxBackground": "Лимит фоновых подключений",
"maxBackgroundDesc": "Вытеснять давно не использованные подключения при превышении лимита",
"suspend": "Фоновая приостановка",
"suspendDesc": "Минуты до освобождения активных каналов, когда вкладка в фоне"
},
"security": {
"credentials": "Защита учётных данных",
"sessionPassword": "Пароли сеансов и парольные фразы ключей",
"sessionPasswordDesc": "Шифруются AES-256-GCM в Rust перед сохранением; отключить нельзя",
"enabled": "Включено",
"masterKey": "Локальный мастер-ключ",
"masterKeyDesc": "Доступен только текущему системному пользователю; путь ~/.opsxshell/master.key (устаревший ~/.opsxshsell мигрируется автоматически)",
"knownHosts": "Известные хосты",
"knownHostsHint": "При первом подключении запрашивается отпечаток хоста. Если переустановка или клон изменяют ключ, выберите «Доверять и обновить» в запросе, чтобы заменить старую запись. Здесь можно удалить отдельную запись или очистить все.",
"clearAll": "Очистить все",
"removeHost": "Удалить запись этого хоста",
"empty": "Записей нет",
"clearConfirm": "Очистить все известные ключи хостов? При следующем подключении запрос появится снова."
},
"about": {
"tagline": "Лёгкий нативный терминал эксплуатации SSH / SFTP",
"appVersion": "Приложение v{{version}}",
"copyVersion": "Копировать сведения о версии",
"runtime": "Среда выполнения",
"system": "Система",
"localData": "Локальные данные",
"sessionsSettings": "Сеансы и настройки",
"masterKeyPath": "Мастер-ключ",
"privacyNote": "Пароли и парольные фразы ключей шифруются AES-256-GCM в Rust. OpsXShell не сохраняет историю команд терминала.",
"license": "Лицензия MIT · Rust · XTerm.js"
},
"ai": {
"presets": "Пресеты провайдеров",
"add": "Добавить",
"configured": "Настроено",
"configuredHint": "Выберите провайдера и нажмите «Добавить»",
"emptyHint": "Добавьте провайдера, чтобы начать",
"noModel": "Модель не выбрана",
"name": "Название",
"model": "Модель",
"protocol": "Протокол",
"auth": "Аутентификация",
"authNone": "Нет",
"test": "Проверить",
"testing": "Проверка",
"testingMessage": "Проверка...",
"saved": "Сохранено",
"retest": "Пожалуйста, перепроверьте",
"testFailed": "Сбой проверки подключения",
"available": "OK · {{latency}} мс",
"savedKeepBlank": "Сохранено — оставьте пустым, чтобы сохранить",
"notRequired": "Не требуется",
"otherModels": "Другие модели…",
"customModel": "Своя модель",
"backToList": "Назад к списку",
"apiKeyOptional": "API Key (не требуется)",
"advanced": "Дополнительно",
"allowHttp": "Разрешить HTTP (localhost/LAN)",
"setActive": "Сделать активным",
"deleteTitle": "Удалить",
"apiKeySaveFailed": "Не удалось сохранить API-ключ",
"providerNotFound": "Провайдер не найден",
"modelCatalogReadFailed": "Не удалось прочитать каталог моделей",
"catalogUnavailable": "models.dev недоступен"
},
"family": {
"openai_compatible": "Совместимый с OpenAI",
"standalone": "────────",
"plan": "План",
"local": "Self-hosted",
"custom": "Своё"
}
}