From 70bc5100b0e326d13599bebffba4cd2e34673a50 Mon Sep 17 00:00:00 2001 From: Slinetrac Date: Wed, 5 Nov 2025 17:08:51 +0800 Subject: [PATCH] refactor(i18n): restructure feedback and profile namespaces for better organization --- .../common/traffic-error-boundary.tsx | 4 +- src/components/home/home-profile-card.tsx | 14 +- src/components/profile/editor-viewer.tsx | 6 +- src/components/profile/file-input.tsx | 2 +- .../profile/groups-editor-viewer.tsx | 76 ++-- src/components/profile/log-viewer.tsx | 2 +- src/components/profile/profile-item.tsx | 54 +-- src/components/profile/profile-more.tsx | 16 +- src/components/profile/profile-viewer.tsx | 36 +- .../profile/proxies-editor-viewer.tsx | 10 +- .../profile/rules-editor-viewer.tsx | 2 +- src/locales/ar.json | 344 +++++++++--------- src/locales/de.json | 344 +++++++++--------- src/locales/en.json | 344 +++++++++--------- src/locales/es.json | 344 +++++++++--------- src/locales/fa.json | 344 +++++++++--------- src/locales/id.json | 344 +++++++++--------- src/locales/jp.json | 344 +++++++++--------- src/locales/ko.json | 344 +++++++++--------- src/locales/ru.json | 344 +++++++++--------- src/locales/tr.json | 344 +++++++++--------- src/locales/tt.json | 344 +++++++++--------- src/locales/zh.json | 344 +++++++++--------- src/locales/zhtw.json | 344 +++++++++--------- src/pages/_layout/notificationHandlers.ts | 4 +- src/pages/profiles.tsx | 59 +-- src/services/noticeService.ts | 8 +- 27 files changed, 2535 insertions(+), 2230 deletions(-) diff --git a/src/components/common/traffic-error-boundary.tsx b/src/components/common/traffic-error-boundary.tsx index c32f6b30..763dcbbe 100644 --- a/src/components/common/traffic-error-boundary.tsx +++ b/src/components/common/traffic-error-boundary.tsx @@ -177,7 +177,7 @@ const TrafficErrorFallback: React.FC = ({ - {t("shared.messages.errors.trafficStats")} + {t("shared.feedback.errors.trafficStats")} = ({ textAlign="center" sx={{ mb: 2 }} > - {t("shared.messages.errors.trafficStatsDescription")} + {t("shared.feedback.errors.trafficStatsDescription")} diff --git a/src/components/home/home-profile-card.tsx b/src/components/home/home-profile-card.tsx index 4bd12500..5e8fbc0f 100644 --- a/src/components/home/home-profile-card.tsx +++ b/src/components/home/home-profile-card.tsx @@ -112,7 +112,7 @@ const ProfileDetails = ({ sx={{ display: "flex", alignItems: "center" }} > - {t("profiles.card.labels.from")}:{" "} + {t("profiles.components.card.labels.from")}:{" "} {current.home ? ( - {t("profiles.card.labels.updateTime")}:{" "} + {t("profiles.components.card.labels.updateTime")}:{" "} {dayjs(current.updated * 1000).format("YYYY-MM-DD HH:mm")} @@ -201,7 +201,7 @@ const ProfileDetails = ({ - {t("profiles.card.labels.usedTotal")}:{" "} + {t("profiles.components.card.labels.usedTotal")}:{" "} {parseTraffic(usedTraffic)} /{" "} {parseTraffic(current.extra.total)} @@ -213,7 +213,7 @@ const ProfileDetails = ({ - {t("profiles.card.labels.expireTime")}:{" "} + {t("profiles.components.card.labels.expireTime")}:{" "} {parseExpire(current.extra.expire)} @@ -268,10 +268,10 @@ const EmptyProfile = ({ onClick }: { onClick: () => void }) => { sx={{ fontSize: 60, color: "primary.main", mb: 2 }} /> - {t("profiles.page.actions.import")} {t("profiles.page.title")} + {t("profiles.page.actions.import")} {t("profiles.page.header.title")} - {t("profiles.card.labels.clickToImport")} + {t("profiles.components.card.labels.clickToImport")} ); @@ -312,7 +312,7 @@ export const HomeProfileCard = ({ // 卡片标题 const cardTitle = useMemo(() => { - if (!current) return t("profiles.page.title"); + if (!current) return t("profiles.page.header.title"); if (!current.home) return current.name; diff --git a/src/components/profile/editor-viewer.tsx b/src/components/profile/editor-viewer.tsx index ce2e8025..fdbf4fc1 100644 --- a/src/components/profile/editor-viewer.tsx +++ b/src/components/profile/editor-viewer.tsx @@ -97,7 +97,7 @@ export const EditorViewer = (props: Props) => { onClose, } = props; - const resolvedTitle = title ?? t("profiles.menu.editFile"); + const resolvedTitle = title ?? t("profiles.components.menu.editFile"); const resolvedInitialData = useMemo( () => initialData ?? Promise.resolve(""), [initialData], @@ -203,7 +203,7 @@ export const EditorViewer = (props: Props) => { mouseWheelZoom: true, // 按住Ctrl滚轮调节缩放比例 readOnly: readOnly, // 只读模式 readOnlyMessage: { - value: t("profiles.editor.readOnlyMessage"), + value: t("profiles.modals.editor.messages.readOnly"), }, // 只读模式尝试编辑时的提示信息 renderValidationDecorations: "on", // 只读模式下显示校验信息 quickSuggestions: { @@ -233,7 +233,7 @@ export const EditorViewer = (props: Props) => { size="medium" color="inherit" sx={{ display: readOnly ? "none" : "" }} - title={t("profiles.editor.format")} + title={t("profiles.modals.editor.actions.format")} onClick={() => editorRef.current ?.getAction("editor.action.formatDocument") diff --git a/src/components/profile/file-input.tsx b/src/components/profile/file-input.tsx index 2b6de501..20b4ad20 100644 --- a/src/components/profile/file-input.tsx +++ b/src/components/profile/file-input.tsx @@ -42,7 +42,7 @@ export const FileInput = (props: Props) => { sx={{ flex: "none" }} onClick={() => inputRef.current?.click()} > - {t("profiles.fileInput.chooseFile")} + {t("profiles.components.fileInput.chooseFile")} { const validateGroup = () => { const group = formIns.getValues(); if (group.name === "") { - throw new Error(t("profiles.groupsEditor.errors.nameRequired")); + throw new Error(t("profiles.modals.groupsEditor.errors.nameRequired")); } }; @@ -415,7 +415,7 @@ export const GroupsEditorViewer = (props: Props) => { } await saveProfileFile(property, nextData); - showNotice.success("profiles.notifications.saved"); + showNotice.success("shared.feedback.notifications.saved"); setPrevData(nextData); onSave?.(prevData, nextData); onClose(); @@ -429,7 +429,7 @@ export const GroupsEditorViewer = (props: Props) => { { - {t("profiles.groupsEditor.title")} + {t("profiles.modals.groupsEditor.title")} @@ -941,7 +961,7 @@ export const GroupsEditorViewer = (props: Props) => { for (const item of [...appendSeq, ...groupList]) { if (item.name === formIns.getValues().name) { throw new Error( - t("profiles.groupsEditor.errors.nameExists"), + t("profiles.modals.groupsEditor.errors.nameExists"), ); } } @@ -951,7 +971,7 @@ export const GroupsEditorViewer = (props: Props) => { } }} > - {t("profiles.groupsEditor.actions.append")} + {t("profiles.modals.groupsEditor.actions.append")} diff --git a/src/components/profile/log-viewer.tsx b/src/components/profile/log-viewer.tsx index 9c4d2028..90349ccc 100644 --- a/src/components/profile/log-viewer.tsx +++ b/src/components/profile/log-viewer.tsx @@ -26,7 +26,7 @@ export const LogViewer = (props: Props) => { return ( - {t("profiles.logViewer.title")} + {t("profiles.modals.logViewer.title")} { // 如果已经过期,显示"更新失败" if (nextUpdateDate.isBefore(now)) { - setNextUpdateTime(t("profiles.item.status.lastUpdateFailed")); + setNextUpdateTime( + t("profiles.components.profileItem.status.lastUpdateFailed"), + ); } else { // 否则显示剩余时间 const diffMinutes = nextUpdateDate.diff(now, "minute"); if (diffMinutes < 60) { if (diffMinutes <= 0) { - setNextUpdateTime(`${t("profiles.item.status.nextUp")} <1m`); + setNextUpdateTime( + `${t("profiles.components.profileItem.status.nextUp")} <1m`, + ); } else { setNextUpdateTime( - `${t("profiles.item.status.nextUp")} ${diffMinutes}m`, + `${t("profiles.components.profileItem.status.nextUp")} ${diffMinutes}m`, ); } } else { const hours = Math.floor(diffMinutes / 60); const mins = diffMinutes % 60; setNextUpdateTime( - `${t("profiles.item.status.nextUp")} ${hours}h ${mins}m`, + `${t("profiles.components.profileItem.status.nextUp")} ${hours}h ${mins}m`, ); } } } else { console.log(`返回的下次更新时间为空`); - setNextUpdateTime(t("profiles.item.status.noSchedule")); + setNextUpdateTime( + t("profiles.components.profileItem.status.noSchedule"), + ); } } catch (err) { console.error(`获取下次更新时间出错:`, err); - setNextUpdateTime(t("profiles.item.status.unknown")); + setNextUpdateTime(t("profiles.components.profileItem.status.unknown")); } } else { console.log(`该配置未设置更新间隔或间隔为0`); - setNextUpdateTime(t("profiles.item.status.autoUpdateDisabled")); + setNextUpdateTime( + t("profiles.components.profileItem.status.autoUpdateDisabled"), + ); } }); @@ -365,18 +373,18 @@ export const ProfileItem = (props: Props) => { }; const menuLabels = { - home: "profiles.menu.home", - select: "profiles.menu.select", - editInfo: "profiles.menu.editInfo", - editFile: "profiles.menu.editFile", - editRules: "profiles.menu.editRules", - editProxies: "profiles.menu.editProxies", - editGroups: "profiles.menu.editGroups", - extendConfig: "profiles.menu.extendConfig", - extendScript: "profiles.menu.extendScript", - openFile: "profiles.menu.openFile", - update: "profiles.menu.update", - updateViaProxy: "profiles.menu.updateViaProxy", + home: "profiles.components.menu.home", + select: "profiles.components.menu.select", + editInfo: "profiles.components.menu.editInfo", + editFile: "profiles.components.menu.editFile", + editRules: "profiles.components.menu.editRules", + editProxies: "profiles.components.menu.editProxies", + editGroups: "profiles.components.menu.editGroups", + extendConfig: "profiles.components.menu.extendConfig", + extendScript: "profiles.components.menu.extendScript", + openFile: "profiles.components.menu.openFile", + update: "profiles.components.menu.update", + updateViaProxy: "profiles.components.menu.updateViaProxy", delete: "shared.actions.delete", } as const; @@ -733,8 +741,8 @@ export const ProfileItem = (props: Props) => { textAlign="right" title={ showNextUpdate - ? t("profiles.item.tooltips.showLast") - : `${t("shared.labels.updateTime")}: ${parseExpire(updated)}\n${t("profiles.item.tooltips.showNext")}` + ? t("profiles.components.profileItem.tooltips.showLast") + : `${t("shared.labels.updateTime")}: ${parseExpire(updated)}\n${t("profiles.components.profileItem.tooltips.showNext")}` } sx={{ cursor: "pointer", @@ -891,8 +899,8 @@ export const ProfileItem = (props: Props) => { )} setConfirmOpen(false)} onConfirm={() => { diff --git a/src/components/profile/profile-more.tsx b/src/components/profile/profile-more.tsx index 97c57308..bcc7acd3 100644 --- a/src/components/profile/profile-more.tsx +++ b/src/components/profile/profile-more.tsx @@ -55,18 +55,18 @@ export const ProfileMore = (props: Props) => { const hasError = entries.some(([level]) => level === "exception"); const globalTitles: Record = { - Merge: "profiles.more.global.merge", - Script: "profiles.more.global.script", + Merge: "profiles.components.more.global.merge", + Script: "profiles.components.more.global.script", }; const chipLabels: Record = { - Merge: "profiles.more.chips.merge", - Script: "profiles.more.chips.script", + Merge: "profiles.components.more.chips.merge", + Script: "profiles.components.more.chips.script", }; const itemMenu = [ - { label: "profiles.menu.editFile", handler: onEditFile }, - { label: "profiles.menu.openFile", handler: onOpenFile }, + { label: "profiles.components.menu.editFile", handler: onEditFile }, + { label: "profiles.components.menu.openFile", handler: onOpenFile }, ]; const boxStyle = { @@ -121,7 +121,7 @@ export const ProfileMore = (props: Props) => { size="small" edge="start" color="error" - title={t("profiles.logViewer.title")} + title={t("profiles.modals.logViewer.title")} onClick={() => setLogOpen(true)} > @@ -132,7 +132,7 @@ export const ProfileMore = (props: Props) => { size="small" edge="start" color="inherit" - title={t("profiles.logViewer.title")} + title={t("profiles.modals.logViewer.title")} onClick={() => setLogOpen(true)} > diff --git a/src/components/profile/profile-viewer.tsx b/src/components/profile/profile-viewer.tsx index 962a6aac..380895a2 100644 --- a/src/components/profile/profile-viewer.tsx +++ b/src/components/profile/profile-viewer.tsx @@ -144,7 +144,9 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) { } } catch { // 首次创建/更新失败,尝试使用自身代理 - showNotice.info("profiles.viewer.notifications.creationRetry"); + showNotice.info( + "profiles.modals.profileForm.feedback.notifications.creationRetry", + ); // 使用自身代理的配置 const retryItem = { @@ -167,7 +169,9 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) { await patchProfile(form.uid, { option: originalOptions }); } - showNotice.success("profiles.viewer.notifications.creationSuccess"); + showNotice.success( + "profiles.modals.profileForm.feedback.notifications.creationSuccess", + ); } } @@ -216,8 +220,8 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) { open={open} title={ openType === "new" - ? t("profiles.viewer.title.create") - : t("profiles.viewer.title.edit") + ? t("profiles.modals.profileForm.title.create") + : t("profiles.modals.profileForm.title.edit") } contentSx={{ width: 375, pb: 0, maxHeight: "80%" }} okBtn={t("shared.actions.save")} @@ -232,11 +236,13 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) { control={control} render={({ field }) => ( - {t("profiles.viewer.fields.type")} + + {t("profiles.modals.profileForm.fields.type")} +