Skip to content

Commit 55ffcbb

Browse files
committed
fix(i18n): replace hardcoded Chinese messages with i18n keys and extract AppError
1 parent 5be20c1 commit 55ffcbb

7 files changed

Lines changed: 138 additions & 335 deletions

File tree

src-tauri/locales/en.json

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,37 @@
708708
"confirm_import": "Confirm Import",
709709
"export_import_config_description": "Export current configuration or restore configuration from file",
710710
"confirm_import_description": "Importing configuration will overwrite all current settings and automatically restart the software. Continue?",
711-
"password_obscured_hint": "Password is obscured by rclone and cannot be displayed. Please re-enter to modify"
711+
"password_obscured_hint": "Password is obscured by rclone and cannot be displayed. Please re-enter to modify",
712+
713+
"error_boundary_title": "An error occurred",
714+
"error_boundary_subtitle": "The application encountered a problem, but your data is safe",
715+
"reload": "Reload",
716+
"validation_storage_name_empty": "Storage name cannot be empty",
717+
"validation_storage_name_too_long": "Storage name length cannot exceed 128 characters",
718+
"validation_storage_name_invalid_chars": "Storage name contains invalid characters",
719+
"validation_storage_type_empty": "Storage type cannot be empty",
720+
"validation_storage_params_empty": "Storage parameters cannot be empty",
721+
"validation_input_invalid": "Invalid input parameters",
722+
"error_unsupported_storage_type": "Unsupported storage type",
723+
"error_storage_params_serialization": "Storage parameter serialization failed",
724+
"error_storage_id_not_found": "Cannot get storage ID",
725+
"error_operation_failed": "Operation failed",
726+
"error_unsupported_framework": "Unsupported storage framework",
727+
"error_storage_network_failure": "Storage operation failed, please check network connection",
728+
"error_network": "Network connection failed, please check network settings",
729+
"error_api": "Server request failed, please try again later",
730+
"error_validation": "Invalid input data, please check and try again",
731+
"error_auth": "Login expired, please login again",
732+
"error_forbidden": "No permission to perform this operation",
733+
"error_not_found": "Requested resource not found",
734+
"error_timeout": "Request timeout, please try again later",
735+
"error_file_system": "File operation failed",
736+
"error_config": "Configuration error",
737+
"error_unknown": "An unknown error occurred, please try again later",
738+
"error_auth_failed": "Authentication failed",
739+
"error_no_permission": "No permission",
740+
"error_resource_not_found": "{{resource}} not found",
741+
"error_operation_timeout": "{{operation}} operation timeout",
742+
"no_logs": "No logs"
712743
}
713744

src-tauri/locales/zh-cn.json

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,5 +718,36 @@
718718
"proxy_range": "Proxy Range",
719719
"app_id": "App ID",
720720
"sign_key": "Sign Key",
721-
"password_obscured_hint": "密码已被rclone混淆存储,无法显示原始值,如需修改请重新输入"
721+
"password_obscured_hint": "密码已被rclone混淆存储,无法显示原始值,如需修改请重新输入",
722+
723+
"error_boundary_title": "出现错误",
724+
"error_boundary_subtitle": "应用遇到了问题,但别担心,数据是安全的",
725+
"reload": "重新加载",
726+
"validation_storage_name_empty": "存储名称不能为空",
727+
"validation_storage_name_too_long": "存储名称长度不能超过128字符",
728+
"validation_storage_name_invalid_chars": "存储名称包含非法字符",
729+
"validation_storage_type_empty": "存储类型不能为空",
730+
"validation_storage_params_empty": "存储参数不能为空",
731+
"validation_input_invalid": "输入参数无效",
732+
"error_unsupported_storage_type": "不支持的存储类型",
733+
"error_storage_params_serialization": "存储参数序列化失败",
734+
"error_storage_id_not_found": "无法获取存储 ID",
735+
"error_operation_failed": "操作失败",
736+
"error_unsupported_framework": "不支持的存储框架",
737+
"error_storage_network_failure": "存储操作失败,请检查网络连接",
738+
"error_network": "网络连接失败,请检查网络设置",
739+
"error_api": "服务器请求失败,请稍后重试",
740+
"error_validation": "输入数据有误,请检查后重试",
741+
"error_auth": "登录已过期,请重新登录",
742+
"error_forbidden": "没有权限执行此操作",
743+
"error_not_found": "请求的资源不存在",
744+
"error_timeout": "请求超时,请稍后重试",
745+
"error_file_system": "文件操作失败",
746+
"error_config": "配置错误",
747+
"error_unknown": "发生未知错误,请稍后重试",
748+
"error_auth_failed": "认证失败",
749+
"error_no_permission": "没有权限",
750+
"error_resource_not_found": "{{resource}} 不存在",
751+
"error_operation_timeout": "{{operation}} 操作超时",
752+
"no_logs": "暂无日志"
722753
}

src-tauri/locales/zh-hant.json

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,37 @@
708708
"confirm_import": "確認導入",
709709
"export_import_config_description": "導出當前配置或者從文件恢復配置",
710710
"confirm_import_description": "導入配置將覆蓋當前所有配置並自動重啓軟件,是否繼續?",
711-
"password_obscured_hint": "密碼已被rclone混淆存儲,無法顯示原始值,如需修改請重新輸入"
711+
"password_obscured_hint": "密碼已被rclone混淆存儲,無法顯示原始值,如需修改請重新輸入",
712+
713+
"error_boundary_title": "出現錯誤",
714+
"error_boundary_subtitle": "應用遇到了問題,但不用擔心,數據是安全的",
715+
"reload": "重新載入",
716+
"validation_storage_name_empty": "存儲名稱不能為空",
717+
"validation_storage_name_too_long": "存儲名稱長度不能超過128字符",
718+
"validation_storage_name_invalid_chars": "存儲名稱包含非法字符",
719+
"validation_storage_type_empty": "存儲類型不能為空",
720+
"validation_storage_params_empty": "存儲參數不能為空",
721+
"validation_input_invalid": "輸入參數無效",
722+
"error_unsupported_storage_type": "不支持的存儲類型",
723+
"error_storage_params_serialization": "存儲參數序列化失敗",
724+
"error_storage_id_not_found": "無法獲取存儲 ID",
725+
"error_operation_failed": "操作失敗",
726+
"error_unsupported_framework": "不支持的存儲框架",
727+
"error_storage_network_failure": "存儲操作失敗,請檢查網絡連接",
728+
"error_network": "網絡連接失敗,請檢查網絡設置",
729+
"error_api": "服務器請求失敗,請稍後重試",
730+
"error_validation": "輸入數據有誤,請檢查後重試",
731+
"error_auth": "登錄已過期,請重新登錄",
732+
"error_forbidden": "沒有權限執行此操作",
733+
"error_not_found": "請求的資源不存在",
734+
"error_timeout": "請求超時,請稍後重試",
735+
"error_file_system": "文件操作失敗",
736+
"error_config": "配置錯誤",
737+
"error_unknown": "發生未知錯誤,請稍後重試",
738+
"error_auth_failed": "認證失敗",
739+
"error_no_permission": "沒有權限",
740+
"error_resource_not_found": "{{resource}} 不存在",
741+
"error_operation_timeout": "{{operation}} 操作超時",
742+
"no_logs": "暫無日誌"
712743
}
713744

src/components/ErrorBoundary.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
import { Component, ErrorInfo, ReactNode, JSX } from 'react'
20+
import { useTranslation } from 'react-i18next'
2021
import { Button, Card, Result, Space, Typography } from '@arco-design/web-react'
2122
import { IconRefresh, IconBug } from '@arco-design/web-react/icon'
2223
import { logger } from '../services/LoggerService'
@@ -54,6 +55,7 @@ interface DefaultErrorFallbackProps {
5455
}
5556

5657
function DefaultErrorFallback({ error, onReset }: DefaultErrorFallbackProps): JSX.Element {
58+
const { t } = useTranslation()
5759
return (
5860
<div
5961
style={{
@@ -70,8 +72,8 @@ function DefaultErrorFallback({ error, onReset }: DefaultErrorFallbackProps): JS
7072
<Result
7173
status="error"
7274
icon={<IconBug style={{ fontSize: '3rem', color: 'var(--color-danger)' }} />}
73-
title="出现错误"
74-
subTitle="应用遇到了问题,但别担心,数据是安全的"
75+
title={t('error_boundary_title')}
76+
subTitle={t('error_boundary_subtitle')}
7577
>
7678
<Space direction="vertical" style={{ width: '100%' }}>
7779
<div
@@ -94,7 +96,7 @@ function DefaultErrorFallback({ error, onReset }: DefaultErrorFallbackProps): JS
9496
</div>
9597
<Space style={{ justifyContent: 'center', width: '100%', marginTop: '1rem' }}>
9698
<Button type="primary" icon={<IconRefresh />} onClick={onReset}>
97-
重新加载
99+
{t('reload')}
98100
</Button>
99101
</Space>
100102
</Space>

src/controller/storage/create.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Message } from '@arco-design/web-react'
2+
import { t } from 'i18next'
23
import { ParametersType } from '../../type/defaults'
34
import { openlist_api_post } from '../../utils/openlist/request'
45
import { rclone_api_post } from '../../utils/rclone/request'
@@ -12,17 +13,16 @@ import { logger } from '../../services/LoggerService'
1213
*/
1314
function validateStorageName(name: string): string | null {
1415
if (!name || typeof name !== 'string') {
15-
return '存储名称不能为空'
16+
return t('validation_storage_name_empty')
1617
}
1718
if (name.trim().length === 0) {
18-
return '存储名称不能为空'
19+
return t('validation_storage_name_empty')
1920
}
2021
if (name.length > 128) {
21-
return '存储名称长度不能超过128字符'
22+
return t('validation_storage_name_too_long')
2223
}
23-
// 检查非法字符
2424
if (/[<>:"|?*/\\]/.test(name)) {
25-
return '存储名称包含非法字符'
25+
return t('validation_storage_name_invalid_chars')
2626
}
2727
return null
2828
}
@@ -32,7 +32,7 @@ function validateStorageName(name: string): string | null {
3232
*/
3333
function validateStorageType(type: string): string | null {
3434
if (!type || typeof type !== 'string') {
35-
return '存储类型不能为空'
35+
return t('validation_storage_type_empty')
3636
}
3737
return null
3838
}
@@ -42,7 +42,7 @@ function validateStorageType(type: string): string | null {
4242
*/
4343
function validateParameters(parameters: ParametersType): string | null {
4444
if (!parameters || typeof parameters !== 'object') {
45-
return '存储参数不能为空'
45+
return t('validation_storage_params_empty')
4646
}
4747
return null
4848
}
@@ -77,14 +77,14 @@ async function createStorage(
7777
// 输入验证
7878
const validation = validateStorageInput(name, type, parameters)
7979
if (!validation.valid) {
80-
Message.error(validation.error || '输入参数无效')
80+
Message.error(validation.error || t('validation_input_invalid'))
8181
logger.error('Storage validation failed', undefined, 'StorageCreate', { error: validation.error })
8282
return false
8383
}
8484

8585
const storageInfo = searchStorageInfo(type)
8686
if (!storageInfo) {
87-
Message.error('不支持的存储类型: ' + type)
87+
Message.error(t('error_unsupported_storage_type') + ': ' + type)
8888
logger.error('Storage type not found', undefined, 'StorageCreate', { type })
8989
return false
9090
}
@@ -117,7 +117,7 @@ async function createStorage(
117117
serializedAddition = JSON.stringify(parameters.addition)
118118
} catch (e) {
119119
logger.error('Failed to serialize addition', e as Error, 'StorageCreate')
120-
Message.error('存储参数序列化失败')
120+
Message.error(t('error_storage_params_serialization'))
121121
return false
122122
}
123123

@@ -135,7 +135,7 @@ async function createStorage(
135135
// 更新现有存储
136136
const storageId = storage.other?.openlist?.id
137137
if (!storageId) {
138-
Message.error('无法获取存储 ID')
138+
Message.error(t('error_storage_id_not_found'))
139139
return false
140140
}
141141
backData = await openlist_api_post('/api/admin/storage/update', {
@@ -145,7 +145,7 @@ async function createStorage(
145145
}
146146

147147
if (backData.code !== 200) {
148-
Message.error(backData.message || '操作失败')
148+
Message.error(backData.message || t('error_operation_failed'))
149149
return false
150150
}
151151

@@ -154,12 +154,12 @@ async function createStorage(
154154
}
155155

156156
default:
157-
Message.error('不支持的存储框架: ' + storageInfo.framework)
157+
Message.error(t('error_unsupported_framework') + ': ' + storageInfo.framework)
158158
return false
159159
}
160160
} catch (error) {
161161
logger.error('Storage operation failed', error as Error, 'StorageCreate')
162-
Message.error('存储操作失败,请检查网络连接')
162+
Message.error(t('error_storage_network_failure'))
163163
return false
164164
}
165165
}

src/page/setting/setting.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export default function Setting_page() {
2323
const showLogFromFileTail = async (path: string) => {
2424
try {
2525
const content = await readTextFileTail(path, { maxBytes: 256 * 1024, allowMissing: true })
26-
showLog(modal, (content || '').trim() ? content : '暂无日志')
26+
showLog(modal, (content || '').trim() ? content : t('no_logs'))
2727
} catch (e) {
2828
const msg = e instanceof Error ? e.message : String(e)
2929
Message.error(msg)

0 commit comments

Comments
 (0)