fix: remaining localization gaps (#156)

Co-authored-by: Lê Trung Hiếu <[email protected]>
This commit is contained in:
Lê Trung HiếuandLê Trung Hiếu authored and GitHub committed 2026-04-14 12:59:57 +08:00
1 parent 440a934280
commit 7093c982ba
13 files changed
+838 -208

No files matched your search

+119 -1
View File
@@ -1,6 +1,7 @@
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import vi from './vi';
i18n
.use(LanguageDetector)
@@ -12,12 +13,19 @@ i18n
caches: ['localStorage'],
lookupLocalStorage: 'lang',
},
supportedLngs: ['en', 'zh-CN', 'ru'],
supportedLngs: ['en', 'zh-CN', 'ru', 'vi'],
load: 'currentOnly', // Only load the exact language code, not variants
resources: {
en: {
translation: {
appName: 'Antigravity Manager',
common: {
loading: 'Loading...',
error: 'Error',
unknown: 'Unknown',
notAvailable: 'N/A',
openMenu: 'Open menu',
},
status: {
checking: 'Checking status...',
running: 'Antigravity is running in background',
@@ -84,6 +92,7 @@ i18n
english: 'English',
chinese: 'Chinese (Simplified)',
russian: 'Russian',
vietnamese: 'Vietnamese',
},
about: {
title: 'About',
@@ -93,6 +102,15 @@ i18n
platform: 'Platform',
license: 'License',
openLogDir: 'Open',
toast: {
saved: {
title: 'Settings saved',
description: 'Your configuration has been updated.',
},
saveFailed: {
title: 'Error saving settings',
},
},
account: {
title: 'Account Settings',
description: 'Configure automatic account refresh and sync.',
@@ -125,6 +143,8 @@ i18n
quotaAlertDesc: 'Get notified when a model quota drops below the set threshold',
quotaThreshold: 'Alert Threshold',
quotaThresholdDesc: 'Percentage below which to trigger an alert',
saveFailed: 'Failed to save notification settings',
thresholdSaveFailed: 'Failed to save threshold setting',
},
proxy: {
title: 'Upstream Proxy',
@@ -369,6 +389,20 @@ i18n
autoSwitchOn: 'Auto-Switch Enabled',
autoSwitchOff: 'Auto-Switch Disabled',
updateSettingsFailed: 'Failed to update settings',
actionFailed: 'Action failed',
startAuthFailed: 'Failed to start sign-in flow',
refreshCreditsAvailable: 'AI credits: ${{amount}}',
refreshCreditsUnavailable: 'AI credits not available for this refresh.',
batchRefreshSuccess: 'Successfully refreshed {{count}} accounts.',
batchRefreshPartial: {
title: 'Refresh completed with issues',
description: 'Refreshed {{successful}} accounts, {{failed}} failed.',
},
batchDeleteSuccess: 'Successfully deleted {{count}} accounts.',
batchDeletePartial: {
title: 'Deletion completed with issues',
description: 'Deleted {{successful}} accounts, {{failed}} failed.',
},
},
batch: {
selected: 'Selected {{count}}',
@@ -403,6 +437,9 @@ i18n
importErrors: 'Import completed with {{count}} error(s)',
selectFile: 'Select File',
importing: 'Importing...',
fileTooLarge: 'File size exceeds 5MB limit',
invalidJson: 'Invalid JSON file format',
readFileFailed: 'Failed to read file',
},
},
proxy: {
@@ -410,6 +447,7 @@ i18n
description: 'Manage the local API proxy service.',
save: 'Save Settings',
copy: 'Copy',
copied: 'Copied!',
regenerate: 'Regenerate',
regenerateConfirm: {
title: 'Regenerate API Key?',
@@ -433,6 +471,7 @@ i18n
auto_start: 'Auto Start with App',
auto_start_desc: 'Start proxy service when application launches',
local_access: 'Local network access:',
select_ip: 'Select IP',
no_token_warning: '⚠️ API key is not set. Access is open to everyone!',
show_key: 'Show',
hide_key: 'Hide',
@@ -450,9 +489,19 @@ i18n
},
},
},
vi: {
translation: vi,
},
'zh-CN': {
translation: {
appName: 'Antigravity 管理器',
common: {
loading: '加载中...',
error: '错误',
unknown: '未知',
notAvailable: '不适用',
openMenu: '打开菜单',
},
status: {
checking: '正在检查状态...',
running: 'Antigravity 正在后台运行',
@@ -519,6 +568,7 @@ i18n
english: '英语',
chinese: '中文 (简体)',
russian: '俄语',
vietnamese: '越南语',
},
about: {
title: '关于',
@@ -528,6 +578,15 @@ i18n
platform: '平台',
license: '许可证',
openLogDir: '打开',
toast: {
saved: {
title: '设置已保存',
description: '配置已更新。',
},
saveFailed: {
title: '保存设置失败',
},
},
account: {
title: '账号设置',
description: '配置自动刷新和同步账号。',
@@ -558,6 +617,8 @@ i18n
quotaAlertDesc: '当模型配额低于设定阈值时收到提醒',
quotaThreshold: '提醒阈值',
quotaThresholdDesc: '触发提醒的百分比阈值',
saveFailed: '保存通知设置失败',
thresholdSaveFailed: '保存阈值设置失败',
},
proxy: {
title: '上游代理',
@@ -799,6 +860,20 @@ i18n
autoSwitchOn: '自动切换已启用',
autoSwitchOff: '自动切换已禁用',
updateSettingsFailed: '更新设置失败',
actionFailed: '操作失败',
startAuthFailed: '启动登录流程失败',
refreshCreditsAvailable: 'AI 积分:${{amount}}',
refreshCreditsUnavailable: '本次刷新没有可用的 AI 积分信息。',
batchRefreshSuccess: '成功刷新 {{count}} 个账号。',
batchRefreshPartial: {
title: '刷新已完成,但存在问题',
description: '已刷新 {{successful}} 个账号,{{failed}} 个失败。',
},
batchDeleteSuccess: '成功删除 {{count}} 个账号。',
batchDeletePartial: {
title: '删除已完成,但存在问题',
description: '已删除 {{successful}} 个账号,{{failed}} 个失败。',
},
},
batch: {
selected: '已选 {{count}} 项',
@@ -833,6 +908,9 @@ i18n
importErrors: '导入完成,但有 {{count}} 个错误',
selectFile: '选择文件',
importing: '导入中...',
fileTooLarge: '文件大小超过 5MB 限制',
invalidJson: 'JSON 文件格式无效',
readFileFailed: '读取文件失败',
},
},
proxy: {
@@ -840,6 +918,7 @@ i18n
description: '管理本地 API 代理服务。',
save: '保存设置',
copy: '复制',
copied: '已复制!',
regenerate: '重新生成',
regenerateConfirm: {
title: '重新生成 API 密钥?',
@@ -862,6 +941,7 @@ i18n
auto_start: '随应用启动',
auto_start_desc: '应用启动时自动启动代理服务',
local_access: '局域网访问:',
select_ip: '选择 IP',
no_token_warning: '⚠️ 未设置 API 密钥。服务对公网开放!',
show_key: '显示密钥',
hide_key: '隐藏密钥',
@@ -882,6 +962,13 @@ i18n
ru: {
translation: {
appName: 'Antigravity Manager',
common: {
loading: 'Загрузка...',
error: 'Ошибка',
unknown: 'Неизвестно',
notAvailable: 'Н/Д',
openMenu: 'Открыть меню',
},
status: {
checking: 'Проверка статуса...',
running: 'Antigravity работает в фоне',
@@ -949,6 +1036,7 @@ i18n
english: 'English',
chinese: '中文 (简体)',
russian: 'Русский',
vietnamese: 'Вьетнамский',
},
about: {
title: 'О программе',
@@ -958,6 +1046,15 @@ i18n
platform: 'Платформа',
license: 'Лицензия',
openLogDir: 'Открыть',
toast: {
saved: {
title: 'Настройки сохранены',
description: 'Конфигурация обновлена.',
},
saveFailed: {
title: 'Ошибка сохранения настроек',
},
},
account: {
title: 'Настройки аккаунта',
description: 'Настройка автоматического обновления и синхронизации.',
@@ -991,6 +1088,8 @@ i18n
'Получайте уведомления, когда квота модели падает ниже установленного порога',
quotaThreshold: 'Порог уведомления',
quotaThresholdDesc: 'Процент, ниже которого срабатывает уведомление',
saveFailed: 'Не удалось сохранить настройки уведомлений',
thresholdSaveFailed: 'Не удалось сохранить порог уведомления',
},
proxy: {
title: 'Верхнеуровневый прокси',
@@ -1234,6 +1333,20 @@ i18n
autoSwitchOn: 'Авто-переключение включено',
autoSwitchOff: 'Авто-переключение выключено',
updateSettingsFailed: 'Не удалось обновить настройки',
actionFailed: 'Не удалось выполнить действие',
startAuthFailed: 'Не удалось запустить процесс входа',
refreshCreditsAvailable: 'AI кредиты: ${{amount}}',
refreshCreditsUnavailable: 'AI кредиты недоступны для этого обновления.',
batchRefreshSuccess: 'Успешно обновлено {{count}} аккаунтов.',
batchRefreshPartial: {
title: 'Обновление завершено с проблемами',
description: 'Обновлено {{successful}} аккаунтов, {{failed}} с ошибкой.',
},
batchDeleteSuccess: 'Успешно удалено {{count}} аккаунтов.',
batchDeletePartial: {
title: 'Удаление завершено с проблемами',
description: 'Удалено {{successful}} аккаунтов, {{failed}} с ошибкой.',
},
},
batch: {
selected: 'Выбрано {{count}}',
@@ -1269,6 +1382,9 @@ i18n
importErrors: 'Импорт завершён с {{count}} ошибкой(ами)',
selectFile: 'Выбрать файл',
importing: 'Импорт...',
fileTooLarge: 'Размер файла превышает лимит в 5 МБ',
invalidJson: 'Некорректный формат JSON-файла',
readFileFailed: 'Не удалось прочитать файл',
},
},
proxy: {
@@ -1276,6 +1392,7 @@ i18n
description: 'Управление локальным прокси-сервером API.',
save: 'Сохранить',
copy: 'Копировать',
copied: 'Скопировано!',
regenerate: 'Перегенерировать',
regenerateConfirm: {
title: 'Перегенерировать API ключ?',
@@ -1299,6 +1416,7 @@ i18n
auto_start: 'Автозапуск',
auto_start_desc: 'Запускать прокси при старте приложения',
local_access: 'Доступ из локальной сети:',
select_ip: 'Выбрать IP',
no_token_warning: '⚠️ API ключ не установлен. Доступ открыт всем!',
show_key: 'Показать',
hide_key: 'Скрыть',
+471
View File
@@ -0,0 +1,471 @@
const vi = {
appName: 'Antigravity Manager',
common: {
loading: 'Đang tải...',
error: 'Lỗi',
unknown: 'Không rõ',
notAvailable: 'Không có',
openMenu: 'Mở menu',
},
status: {
checking: 'Đang kiểm tra trạng thái...',
running: 'Antigravity đang chạy nền',
stopped: 'Dịch vụ Antigravity đã dừng',
},
action: {
stop: 'Dừng',
start: 'Bắt đầu',
switch: 'Chuyển',
deleteBackup: 'Xóa bản sao lưu',
backupCurrent: 'Sao lưu tài khoản hiện tại',
retry: 'Thử lại',
openLogs: 'Mở thư mục log',
},
error: {
generic: 'Đã xảy ra lỗi không mong đợi.',
keychainUnavailable: 'Keychain không khả dụng.',
keychainHint: {
translocation:
'Đã phát hiện macOS App Translocation. Hãy chuyển ứng dụng vào /Applications rồi mở lại.',
keychainDenied:
'Quyền truy cập Keychain đã bị từ chối. Ứng dụng có thể chưa được ký; hãy xem README để biết cách tự ký.',
signNotarize: 'Hãy ưu tiên dùng bản dựng đã được ký và công chứng khi có thể.',
},
dataMigrationFailed: 'Không thể giải mã dữ liệu tài khoản cũ.',
dataMigrationHint: {
relogin: 'Hãy đăng nhập lại hoặc thêm lại tài khoản của bạn.',
clearData: 'Nếu lỗi vẫn tiếp diễn, hãy xóa dữ liệu tài khoản cục bộ rồi đăng nhập lại.',
},
},
nav: {
accounts: 'Tài khoản',
proxy: 'API Proxy',
settings: 'Cài đặt',
},
account: {
current: 'Hiện tại',
lastUsed: 'Đã dùng {{time}}',
},
home: {
title: 'Tài khoản',
description: 'Quản lý các tài khoản Antigravity Google Gemini.',
noBackups: {
title: 'Chưa tìm thấy bản sao lưu',
description: 'Hãy tạo bản sao lưu cho tài khoản Antigravity hiện tại để bắt đầu.',
action: 'Sao lưu tài khoản hiện tại',
},
},
settings: {
title: 'Cài đặt',
description: 'Quản lý tùy chọn ứng dụng.',
general: 'Chung',
connection: 'Kết nối',
models: 'Mô hình',
appearance: {
title: 'Giao diện',
description: 'Tùy chỉnh giao diện Antigravity Manager trên thiết bị của bạn.',
},
darkMode: 'Chế độ tối',
darkModeDescription: 'Bật chế độ tối để dễ nhìn hơn vào ban đêm.',
language: {
title: 'Ngôn ngữ',
description: 'Chọn ngôn ngữ bạn muốn sử dụng.',
english: 'Tiếng Anh',
chinese: 'Tiếng Trung Giản thể',
russian: 'Tiếng Nga',
vietnamese: 'Tiếng Việt',
},
about: {
title: 'Thông tin',
description: 'Thông tin ứng dụng.',
},
version: 'Phiên bản',
platform: 'Nền tảng',
license: 'Giấy phép',
openLogDir: 'Mở',
toast: {
saved: {
title: 'Đã lưu cài đặt',
description: 'Cấu hình của bạn đã được cập nhật.',
},
saveFailed: {
title: 'Không thể lưu cài đặt',
},
},
account: {
title: 'Cài đặt tài khoản',
description: 'Cấu hình tự động làm mới quota và đồng bộ.',
auto_refresh: 'Tự động làm mới quota',
auto_refresh_desc: 'Định kỳ cập nhật thông tin quota cho tất cả tài khoản',
auto_sync: 'Tự động đồng bộ tài khoản hiện tại',
auto_sync_desc: 'Định kỳ đồng bộ thông tin tài khoản đang hoạt động',
},
startup: {
title: 'Khởi động',
description: 'Điều khiển hành vi khởi động cùng hệ thống.',
auto_startup: 'Khởi động cùng hệ thống',
auto_startup_desc: 'Chạy khi đăng nhập và ẩn vào khay hệ thống',
macos_hint:
'macOS cần bản ký ứng dụng để Login Items hoạt động. Nếu tự động khởi động thất bại, hãy ký ứng dụng hoặc bật thủ công trong System Settings.',
},
privacy: {
title: 'Quyền riêng tư',
description: 'Quản lý cách dữ liệu được sử dụng để cải thiện ứng dụng.',
error_reporting: 'Báo cáo lỗi',
error_reporting_desc:
'Gửi báo cáo lỗi ẩn danh để giúp cải thiện ứng dụng. Không thu thập dữ liệu cá nhân.',
restart_note: 'Thay đổi báo cáo lỗi sẽ có hiệu lực sau khi khởi động lại ứng dụng.',
},
notifications: {
title: 'Thông báo',
description: 'Cấu hình cảnh báo trên desktop cho các sự kiện tài khoản.',
quotaAlert: 'Cảnh báo quota thấp',
quotaAlertDesc: 'Nhận thông báo khi quota của model giảm xuống dưới ngưỡng đã đặt',
quotaThreshold: 'Ngưỡng cảnh báo',
quotaThresholdDesc: 'Phần trăm dùng để kích hoạt cảnh báo',
saveFailed: 'Không thể lưu cài đặt thông báo',
thresholdSaveFailed: 'Không thể lưu ngưỡng cảnh báo',
},
proxy: {
title: 'Proxy trung gian',
description: 'Cấu hình proxy cho các request đi ra Google/Gemini APIs.',
enable: 'Bật proxy trung gian',
url: 'Địa chỉ proxy',
timeout: 'Thời gian chờ request (giây)',
},
modelMapping: {
title: 'Ánh xạ mô hình',
description:
'Ánh xạ các model Claude Code sang model Antigravity để tối ưu chi phí và tốc độ.',
claudeKeyword: 'Từ khóa model Claude',
targetGemini: 'Model Gemini đích',
addPlaceholderKey: 'ví dụ: op-3',
addPlaceholderValue: 'ví dụ: gemini-3-flash',
noMappings: 'Chưa có ánh xạ tùy chỉnh.',
mapsTo: 'Ánh xạ tới',
default: 'Mặc định',
restoreDefaults: 'Khôi phục mặc định',
},
modelVisibility: {
title: 'Hiển thị mô hình',
description:
'Điều khiển model nào được hiện trong thẻ tài khoản. Model bị ẩn sẽ không xuất hiện ở phần quota.',
searchPlaceholder: 'Tìm mô hình...',
showAll: 'Hiện tất cả',
hideAll: 'Ẩn tất cả',
reset: 'Đặt lại mặc định',
save: 'Lưu thay đổi',
noModels: 'Không tìm thấy mô hình',
modelsShown: 'Đang hiện {{visible}} / {{total}} mô hình',
quotaManagement: 'Quản lý quota',
hidden: 'Đã ẩn',
noModelsFound: 'Không tìm thấy mô hình',
totalModels: 'Tổng',
visibleModels: 'Đang hiện',
hiddenModels: 'Đã ẩn',
saving: 'Đang lưu...',
},
providerGroupings: {
title: 'Nhóm theo nhà cung cấp',
description: 'Nhóm model theo nhà cung cấp để dễ quản lý hơn',
enabled: 'Bật nhóm theo nhà cung cấp',
models: '{{count}} mô hình',
avgLabel: 'tb',
resetLabel: 'reset',
overall: 'Tổng thể',
healthy: 'Tốt',
degraded: 'Giảm',
limited: 'Giới hạn',
critical: 'Nghiêm trọng',
},
examples: {
title: 'Ví dụ sử dụng',
description: 'Ví dụ lệnh để gọi local API proxy.',
curl: 'cURL',
python: 'Python',
copy: 'Sao chép',
copied: 'Đã sao chép!',
openai_protocol: 'Giao thức OpenAI',
anthropic_protocol: 'Giao thức Anthropic',
openai_tools: 'Cursor, Windsurf, NextChat',
anthropic_tools: 'Claude Code CLI',
flash: 'Nhanh',
pro: 'Pro',
flash_preview: 'Xem trước',
pro_high: 'Tốt nhất',
sonnet: 'Thinking',
opus: 'Opus',
},
gateway: {
title: 'Dịch vụ API Proxy',
description: 'Điều khiển local API proxy server.',
status_running: 'Đang chạy',
status_stopped: 'Đã dừng',
action_start: 'Bắt đầu dịch vụ',
action_stop: 'Dừng dịch vụ',
accounts_info: '{{count}} tài khoản khả dụng',
port: 'Cổng lắng nghe',
port_hint: 'Mặc định 8045, cần khởi động lại để áp dụng',
timeout: 'Thời gian chờ request',
timeout_hint: 'Mặc định 120 giây, khoảng 30-600 giây',
api_key: 'API Key',
regenerate_key: 'Tạo lại',
regenerateConfirm: {
title: 'Tạo lại API Key?',
description:
'API key hiện tại sẽ hết hiệu lực ngay lập tức. Các ứng dụng đang dùng key cũ sẽ ngừng hoạt động.',
cancel: 'Hủy',
confirm: 'Tạo lại',
},
key_warning: 'Hãy giữ kín API key của bạn. Không chia sẻ với người khác.',
auto_start: 'Tự động chạy cùng app',
auto_start_desc: 'Khởi động proxy khi ứng dụng mở lên',
},
proxy_tab: 'Proxy',
save: 'Lưu cài đặt',
},
toast: {
backupSuccess: {
title: 'Thành công',
description: 'Đã tạo bản sao lưu tài khoản.',
},
backupError: {
title: 'Lỗi',
description: 'Không thể tạo bản sao lưu: {{error}}',
},
switchSuccess: {
title: 'Thành công',
description: 'Chuyển tài khoản thành công.',
},
switchError: {
title: 'Lỗi',
description: 'Không thể chuyển tài khoản: {{error}}',
},
deleteSuccess: {
title: 'Thành công',
description: 'Đã xóa bản sao lưu tài khoản.',
},
deleteError: {
title: 'Lỗi',
description: 'Không thể xóa bản sao lưu: {{error}}',
},
},
cloud: {
title: 'Tài khoản',
description: 'Quản lý pool tài khoản Google Gemini của bạn.',
autoSwitch: 'Tự động chuyển',
providerGroupings: 'Nhóm theo nhà cung cấp',
addAccount: 'Thêm tài khoản',
syncFromIDE: 'Đồng bộ từ IDE',
checkQuota: 'Kiểm tra quota ngay',
polling: 'Đã kích hoạt polling',
globalQuota: 'Quota tổng',
layout: {
auto: 'Tự động',
twoCol: '2 cột',
threeCol: '3 cột',
list: 'Danh sách',
compact: 'Thu gọn',
},
authDialog: {
title: 'Thêm tài khoản Google',
description: 'Bạn cần cấp quyền ứng dụng để thêm tài khoản.',
oauthClient: 'OAuth Client',
oauthClientPlaceholder: 'Chọn OAuth client',
openLogin: 'Mở trang đăng nhập',
authCode: 'Mã ủy quyền',
placeholder: 'Dán mã bắt đầu bằng 4/...',
instruction:
'Ứng dụng sẽ mở trình duyệt mặc định để đăng nhập Google. Sao chép mã từ trang localhost và dán vào đây.',
verify: 'Xác thực và thêm',
},
card: {
active: 'Đang hoạt động',
use: 'Sử dụng',
rateLimited: 'Bị giới hạn tốc độ',
validationRiskControlled: 'Rủi ro / Bị giới hạn',
validationOAuthReauthRequired: 'Cần xác thực lại OAuth',
validationRequired: 'Cần xác minh',
left: 'còn lại',
used: 'Đã dùng',
unknown: 'Người dùng không rõ',
actions: 'Hành động',
useAccount: 'Dùng tài khoản này',
identityProfile: 'Hồ sơ định danh',
refresh: 'Làm mới quota',
delete: 'Xóa tài khoản',
noQuota: 'Chưa có dữ liệu quota',
rateLimitedQuota: 'Bị giới hạn',
resetPrefix: 'reset',
resetTime: 'Thời điểm reset',
resetUnknown: 'Không rõ',
gemini3Ready: 'Sẵn sàng cho Gemini 3',
groupGoogleGemini: 'Google Gemini',
groupAnthropicClaude: 'Anthropic Claude',
proxy: 'Proxy',
proxyPlaceholder: 'ví dụ: http://127.0.0.1:7890',
proxySaved: 'Đã lưu proxy',
noProxy: 'Không dùng proxy',
aiCredits: 'AI Credits',
creditsExpiry: 'hết hạn {{date}}',
modelVisibility: 'Hiển thị model',
},
identity: {
title: 'Hồ sơ định danh',
loading: 'Đang tải...',
generateAndBind: 'Tạo và gán',
captureAndBind: 'Lấy và gán hồ sơ hiện tại',
restoreOriginal: 'Khôi phục baseline',
openFolder: 'Mở thư mục lưu hồ sơ',
previewTitle: 'Xem trước hồ sơ đã tạo',
confirm: 'Xác nhận',
cancel: 'Hủy',
close: 'Đóng',
currentStorage: 'Hồ sơ runtime hiện tại',
accountBinding: 'Hồ sơ đang gán với tài khoản',
history: 'Lịch sử hồ sơ',
noHistory: 'Chưa có lịch sử hồ sơ',
current: 'Đang dùng',
restore: 'Khôi phục',
generateSuccess: 'Đã tạo và gán hồ sơ',
captureSuccess: 'Đã lấy và gán hồ sơ hiện tại',
restoreOriginalSuccess: 'Đã khôi phục baseline',
restoreVersionSuccess: 'Đã khôi phục bản lịch sử',
deleteVersionSuccess: 'Đã xóa bản lịch sử',
openFolderSuccess: 'Đã mở thư mục lưu hồ sơ',
baseline: 'Hồ sơ baseline',
},
list: {
noAccounts: 'Chưa có tài khoản cloud nào được thêm.',
},
error: {
loadFailed: 'Không thể tải danh sách tài khoản cloud.',
},
toast: {
syncSuccess: {
title: 'Đồng bộ thành công',
description: 'Đã nhập {{email}} từ IDE.',
},
syncFailed: {
title: 'Đồng bộ thất bại',
description: 'Không tìm thấy tài khoản đang hoạt động trong database của IDE.',
},
addSuccess: 'Đã thêm tài khoản thành công!',
addFailed: {
title: 'Không thể thêm tài khoản',
},
quotaRefreshed: 'Đã làm mới quota',
refreshFailed: 'Không thể làm mới quota',
pollFailed: 'Không thể polling quota của tất cả tài khoản',
switched: {
title: 'Đã chuyển tài khoản!',
description: 'Đang khởi động lại Antigravity...',
},
switchFailed: 'Không thể chuyển tài khoản',
deleted: 'Đã xóa tài khoản',
deleteFailed: 'Không thể xóa tài khoản',
deleteConfirm: 'Bạn có chắc chắn muốn xóa tài khoản này không?',
autoSwitchOn: 'Đã bật tự động chuyển',
autoSwitchOff: 'Đã tắt tự động chuyển',
updateSettingsFailed: 'Không thể cập nhật cài đặt',
actionFailed: 'Không thể thực hiện thao tác',
startAuthFailed: 'Không thể bắt đầu luồng đăng nhập',
refreshCreditsAvailable: 'AI credits: ${{amount}}',
refreshCreditsUnavailable: 'Không có thông tin AI credits cho lần làm mới này.',
batchRefreshSuccess: 'Đã làm mới thành công {{count}} tài khoản.',
batchRefreshPartial: {
title: 'Làm mới hoàn tất nhưng có lỗi',
description: 'Đã làm mới {{successful}} tài khoản, {{failed}} tài khoản thất bại.',
},
batchDeleteSuccess: 'Đã xóa thành công {{count}} tài khoản.',
batchDeletePartial: {
title: 'Xóa hoàn tất nhưng có lỗi',
description: 'Đã xóa {{successful}} tài khoản, {{failed}} tài khoản thất bại.',
},
},
batch: {
selected: 'Đã chọn {{count}}',
delete: 'Xóa mục đã chọn',
refresh: 'Làm mới mục đã chọn',
selectAll: 'Chọn tất cả',
clear: 'Bỏ chọn',
confirmDelete: 'Bạn có chắc chắn muốn xóa {{count}} tài khoản không?',
},
sort: {
recentlyUsed: 'Dùng gần đây',
quotaOverall: 'Quota tổng',
quotaClaude: 'Quota Claude',
quotaPro3: 'Quota Pro3',
quotaFlash: 'Quota Flash',
},
exportImport: {
export: 'Xuất',
import: 'Nhập',
exportTitle: 'Xuất tài khoản',
exportDesc: 'Chọn có bao gồm token xác thực trong tệp xuất hay không.',
includeTokens: 'Bao gồm token (kém an toàn hơn)',
stripTokens: 'Loại bỏ token (an toàn hơn khi chia sẻ)',
exportSuccess: 'Đã xuất tài khoản thành công',
importTitle: 'Nhập tài khoản',
importDesc: 'Chọn tệp JSON đã được xuất trước đó.',
importStrategy: 'Chiến lược nhập',
strategyMerge: 'Gộp - Cập nhật tài khoản cũ, thêm tài khoản mới',
strategyOverwrite: 'Ghi đè - Thay thế toàn bộ dữ liệu hiện có',
strategySkip: 'Bỏ qua - Chỉ thêm tài khoản mới',
importSuccess: 'Đã nhập {{imported}}, cập nhật {{updated}}, bỏ qua {{skipped}}',
importErrors: 'Đã nhập xong với {{count}} lỗi',
selectFile: 'Chọn tệp',
importing: 'Đang nhập...',
fileTooLarge: 'Kích thước tệp vượt quá giới hạn 5MB',
invalidJson: 'Định dạng tệp JSON không hợp lệ',
readFileFailed: 'Không thể đọc tệp',
},
},
proxy: {
title: 'API Proxy',
description: 'Quản lý local API proxy service.',
save: 'Lưu cài đặt',
copy: 'Sao chép',
copied: 'Đã sao chép!',
regenerate: 'Tạo lại',
regenerateConfirm: {
title: 'Tạo lại API Key?',
description:
'API key hiện tại sẽ hết hiệu lực ngay lập tức. Các ứng dụng đang dùng key cũ sẽ ngừng hoạt động.',
cancel: 'Hủy',
confirm: 'Tạo lại',
},
service: {
title: 'Trạng thái dịch vụ',
description: 'Điều khiển local API proxy server.',
running: 'Đang chạy',
stopped: 'Đã dừng',
start: 'Bắt đầu dịch vụ',
stop: 'Dừng dịch vụ',
},
config: {
port: 'Cổng lắng nghe',
timeout: 'Thời gian chờ request',
api_key: 'API Key',
auto_start: 'Tự động chạy cùng app',
auto_start_desc: 'Khởi động proxy khi ứng dụng mở lên',
local_access: 'Truy cập trong mạng nội bộ:',
select_ip: 'Chọn IP',
no_token_warning: 'API key chưa được đặt. Bất kỳ ai trong mạng đều có thể truy cập!',
show_key: 'Hiện',
hide_key: 'Ẩn',
},
mapping: {
title: 'Ánh xạ mô hình',
description: 'Ánh xạ model Claude sang Gemini để định tuyến.',
maps_to: 'Ánh xạ tới',
restore: 'Khôi phục mặc định',
},
examples: {
title: 'Ví dụ sử dụng',
description: 'Ví dụ lệnh để gọi local API proxy.',
},
},
};
export default vi;