refactor(i18n): remove pages.* namespace and migrate route texts under module-level page keys

This commit is contained in:
Slinetrac
2025-11-02 21:18:33 +08:00
Unverified
parent e6df315bb0
commit 3512caebae
72 changed files with 13589 additions and 13755 deletions

View File

@@ -68,50 +68,50 @@ const InnerConnectionDetail = ({ data, onClose }: InnerProps) => {
: metadata.remoteDestination;
const information = [
{ label: t("components.connection.fields.host"), value: host },
{ label: t("connection.fields.host"), value: host },
{
label: t("components.connection.fields.downloaded"),
label: t("connection.fields.downloaded"),
value: parseTraffic(data.download).join(" "),
},
{
label: t("components.connection.fields.uploaded"),
label: t("connection.fields.uploaded"),
value: parseTraffic(data.upload).join(" "),
},
{
label: t("components.connection.fields.dlSpeed"),
label: t("connection.fields.dlSpeed"),
value: parseTraffic(data.curDownload ?? -1).join(" ") + "/s",
},
{
label: t("components.connection.fields.ulSpeed"),
label: t("connection.fields.ulSpeed"),
value: parseTraffic(data.curUpload ?? -1).join(" ") + "/s",
},
{
label: t("components.connection.fields.chains"),
label: t("connection.fields.chains"),
value: chains,
},
{ label: t("components.connection.fields.rule"), value: rule },
{ label: t("connection.fields.rule"), value: rule },
{
label: t("components.connection.fields.process"),
label: t("connection.fields.process"),
value: `${metadata.process}${metadata.processPath ? `(${metadata.processPath})` : ""}`,
},
{
label: t("components.connection.fields.time"),
label: t("connection.fields.time"),
value: dayjs(data.start).fromNow(),
},
{
label: t("components.connection.fields.source"),
label: t("connection.fields.source"),
value: `${metadata.sourceIP}:${metadata.sourcePort}`,
},
{
label: t("components.connection.fields.destination"),
label: t("connection.fields.destination"),
value: Destination,
},
{
label: t("components.connection.fields.destinationPort"),
label: t("connection.fields.destinationPort"),
value: `${metadata.destinationPort}`,
},
{
label: t("components.connection.fields.type"),
label: t("connection.fields.type"),
value: `${metadata.type}(${metadata.network})`,
},
];
@@ -137,13 +137,13 @@ const InnerConnectionDetail = ({ data, onClose }: InnerProps) => {
<Box sx={{ textAlign: "right" }}>
<Button
variant="contained"
title={t("components.connection.actions.closeConnection")}
title={t("connection.actions.closeConnection")}
onClick={() => {
onDelete();
onClose?.();
}}
>
{t("components.connection.actions.closeConnection")}
{t("connection.actions.closeConnection")}
</Button>
</Box>
</Box>

View File

@@ -48,8 +48,8 @@ export const ConnectionItem = (props: Props) => {
edge="end"
color="inherit"
onClick={onDelete}
title={t("components.connection.actions.closeConnection")}
aria-label={t("components.connection.actions.closeConnection")}
title={t("connection.actions.closeConnection")}
aria-label={t("connection.actions.closeConnection")}
>
<CloseRounded />
</IconButton>

View File

@@ -162,13 +162,13 @@ export const ConnectionTable = (props: Props) => {
return [
{
field: "host",
headerName: t("components.connection.fields.host"),
headerName: t("connection.fields.host"),
width: columnWidths["host"] || 220,
minWidth: 180,
},
{
field: "download",
headerName: t("components.connection.fields.downloaded"),
headerName: t("connection.fields.downloaded"),
width: columnWidths["download"] || 88,
align: "right",
headerAlign: "right",
@@ -176,7 +176,7 @@ export const ConnectionTable = (props: Props) => {
},
{
field: "upload",
headerName: t("components.connection.fields.uploaded"),
headerName: t("connection.fields.uploaded"),
width: columnWidths["upload"] || 88,
align: "right",
headerAlign: "right",
@@ -184,7 +184,7 @@ export const ConnectionTable = (props: Props) => {
},
{
field: "dlSpeed",
headerName: t("components.connection.fields.dlSpeed"),
headerName: t("connection.fields.dlSpeed"),
width: columnWidths["dlSpeed"] || 88,
align: "right",
headerAlign: "right",
@@ -192,7 +192,7 @@ export const ConnectionTable = (props: Props) => {
},
{
field: "ulSpeed",
headerName: t("components.connection.fields.ulSpeed"),
headerName: t("connection.fields.ulSpeed"),
width: columnWidths["ulSpeed"] || 88,
align: "right",
headerAlign: "right",
@@ -200,25 +200,25 @@ export const ConnectionTable = (props: Props) => {
},
{
field: "chains",
headerName: t("components.connection.fields.chains"),
headerName: t("connection.fields.chains"),
width: columnWidths["chains"] || 340,
minWidth: 180,
},
{
field: "rule",
headerName: t("components.connection.fields.rule"),
headerName: t("connection.fields.rule"),
width: columnWidths["rule"] || 280,
minWidth: 180,
},
{
field: "process",
headerName: t("components.connection.fields.process"),
headerName: t("connection.fields.process"),
width: columnWidths["process"] || 220,
minWidth: 180,
},
{
field: "time",
headerName: t("components.connection.fields.time"),
headerName: t("connection.fields.time"),
width: columnWidths["time"] || 120,
minWidth: 100,
align: "right",
@@ -229,19 +229,19 @@ export const ConnectionTable = (props: Props) => {
},
{
field: "source",
headerName: t("components.connection.fields.source"),
headerName: t("connection.fields.source"),
width: columnWidths["source"] || 200,
minWidth: 130,
},
{
field: "remoteDestination",
headerName: t("components.connection.fields.destination"),
headerName: t("connection.fields.destination"),
width: columnWidths["remoteDestination"] || 200,
minWidth: 130,
},
{
field: "type",
headerName: t("components.connection.fields.type"),
headerName: t("connection.fields.type"),
width: columnWidths["type"] || 160,
minWidth: 100,
},

View File

@@ -32,7 +32,7 @@ export const ClashInfoCard = () => {
<Stack spacing={1.5}>
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("components.home.clashInfo.fields.coreVersion")}
{t("home.clashInfo.fields.coreVersion")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{clashVersion || "-"}
@@ -41,7 +41,7 @@ export const ClashInfoCard = () => {
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("components.home.clashInfo.fields.systemProxyAddress")}
{t("home.clashInfo.fields.systemProxyAddress")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{systemProxyAddress}
@@ -50,7 +50,7 @@ export const ClashInfoCard = () => {
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("components.home.clashInfo.fields.mixedPort")}
{t("home.clashInfo.fields.mixedPort")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{clashConfig.mixedPort || "-"}
@@ -59,7 +59,7 @@ export const ClashInfoCard = () => {
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("components.home.clashInfo.fields.uptime")}
{t("home.clashInfo.fields.uptime")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{formattedUptime}
@@ -68,7 +68,7 @@ export const ClashInfoCard = () => {
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("components.home.clashInfo.fields.rulesCount")}
{t("home.clashInfo.fields.rulesCount")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{rules.length}
@@ -87,7 +87,7 @@ export const ClashInfoCard = () => {
return (
<EnhancedCard
title={t("components.home.clashInfo.title")}
title={t("home.clashInfo.title")}
icon={<DeveloperBoardOutlined />}
iconColor="warning"
action={null}

View File

@@ -823,7 +823,7 @@ export const CurrentProxyCard = () => {
return (
<EnhancedCard
title={t("components.home.currentProxy.title")}
title={t("home.currentProxy.title")}
icon={
<Tooltip
title={
@@ -840,9 +840,7 @@ export const CurrentProxyCard = () => {
iconColor={currentProxy ? "primary" : undefined}
action={
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<Tooltip
title={t("components.home.currentProxy.actions.refreshDelay")}
>
<Tooltip title={t("home.currentProxy.actions.refreshDelay")}>
<span>
<IconButton
size="small"
@@ -908,7 +906,7 @@ export const CurrentProxyCard = () => {
{isGlobalMode && (
<Chip
size="small"
label={t("components.home.currentProxy.labels.globalMode")}
label={t("home.currentProxy.labels.globalMode")}
color="primary"
sx={{ mr: 0.5 }}
/>
@@ -916,7 +914,7 @@ export const CurrentProxyCard = () => {
{isDirectMode && (
<Chip
size="small"
label={t("components.home.currentProxy.labels.directMode")}
label={t("home.currentProxy.labels.directMode")}
color="success"
sx={{ mr: 0.5 }}
/>
@@ -957,13 +955,13 @@ export const CurrentProxyCard = () => {
sx={{ mb: 1.5 }}
>
<InputLabel id="proxy-group-select-label">
{t("components.home.currentProxy.labels.group")}
{t("home.currentProxy.labels.group")}
</InputLabel>
<Select
labelId="proxy-group-select-label"
value={state.selection.group}
onChange={handleGroupChange}
label={t("components.home.currentProxy.labels.group")}
label={t("home.currentProxy.labels.group")}
disabled={isGlobalMode || isDirectMode}
>
{state.proxyData.groups.map((group) => (
@@ -977,13 +975,13 @@ export const CurrentProxyCard = () => {
{/* 代理节点选择器 */}
<FormControl fullWidth variant="outlined" size="small" sx={{ mb: 0 }}>
<InputLabel id="proxy-select-label">
{t("components.home.currentProxy.labels.proxy")}
{t("home.currentProxy.labels.proxy")}
</InputLabel>
<Select
labelId="proxy-select-label"
value={state.selection.proxy}
onChange={handleProxyChange}
label={t("components.home.currentProxy.labels.proxy")}
label={t("home.currentProxy.labels.proxy")}
disabled={isDirectMode}
renderValue={renderProxyValue}
MenuProps={{
@@ -1039,7 +1037,7 @@ export const CurrentProxyCard = () => {
) : (
<Box sx={{ textAlign: "center", py: 4 }}>
<Typography variant="body1" color="text.secondary">
{t("components.home.currentProxy.labels.noActiveNode")}
{t("home.currentProxy.labels.noActiveNode")}
</Typography>
</Box>
)}

View File

@@ -851,7 +851,7 @@ export const EnhancedCanvasTrafficGraph = memo(
// 获取时间范围文本
const getTimeRangeText = useCallback(() => {
return t("components.home.traffic.patterns.minutes", { time: timeRange });
return t("home.traffic.patterns.minutes", { time: timeRange });
}, [timeRange, t]);
return (
@@ -934,7 +934,7 @@ export const EnhancedCanvasTrafficGraph = memo(
textAlign: "right",
}}
>
{t("components.home.traffic.legends.upload")}
{t("home.traffic.legends.upload")}
</Box>
<Box
sx={{
@@ -944,7 +944,7 @@ export const EnhancedCanvasTrafficGraph = memo(
textAlign: "right",
}}
>
{t("components.home.traffic.legends.download")}
{t("home.traffic.legends.download")}
</Box>
</Box>

View File

@@ -219,42 +219,42 @@ export const EnhancedTrafficStats = () => {
() => [
{
icon: <ArrowUpwardRounded fontSize="small" />,
title: t("components.home.traffic.metrics.uploadSpeed"),
title: t("home.traffic.metrics.uploadSpeed"),
value: parsedData.up,
unit: `${parsedData.upUnit}/s`,
color: "secondary" as const,
},
{
icon: <ArrowDownwardRounded fontSize="small" />,
title: t("components.home.traffic.metrics.downloadSpeed"),
title: t("home.traffic.metrics.downloadSpeed"),
value: parsedData.down,
unit: `${parsedData.downUnit}/s`,
color: "primary" as const,
},
{
icon: <LinkRounded fontSize="small" />,
title: t("components.home.traffic.metrics.activeConnections"),
title: t("home.traffic.metrics.activeConnections"),
value: parsedData.connectionsCount,
unit: "",
color: "success" as const,
},
{
icon: <CloudUploadRounded fontSize="small" />,
title: t("components.home.traffic.metrics.uploaded"),
title: t("home.traffic.metrics.uploaded"),
value: parsedData.uploadTotal,
unit: parsedData.uploadTotalUnit,
color: "secondary" as const,
},
{
icon: <CloudDownloadRounded fontSize="small" />,
title: t("components.home.traffic.metrics.downloaded"),
title: t("home.traffic.metrics.downloaded"),
value: parsedData.downloadTotal,
unit: parsedData.downloadTotalUnit,
color: "primary" as const,
},
{
icon: <MemoryRounded fontSize="small" />,
title: t("components.home.traffic.metrics.memoryUsage"),
title: t("home.traffic.metrics.memoryUsage"),
value: parsedData.inuse,
unit: parsedData.inuseUnit,
color: "error" as const,

View File

@@ -112,7 +112,7 @@ const ProfileDetails = ({
sx={{ display: "flex", alignItems: "center" }}
>
<span style={{ flexShrink: 0 }}>
{t("components.home.profile.labels.from")}:{" "}
{t("home.profile.labels.from")}:{" "}
</span>
{current.home ? (
<Link
@@ -188,7 +188,7 @@ const ProfileDetails = ({
sx={{ cursor: "pointer" }}
onClick={onUpdateProfile}
>
{t("components.home.profile.labels.updateTime")}:{" "}
{t("home.profile.labels.updateTime")}:{" "}
<Box component="span" fontWeight="medium">
{dayjs(current.updated * 1000).format("YYYY-MM-DD HH:mm")}
</Box>
@@ -201,7 +201,7 @@ const ProfileDetails = ({
<Stack direction="row" alignItems="center" spacing={1}>
<SpeedOutlined fontSize="small" color="action" />
<Typography variant="body2" color="text.secondary">
{t("components.home.profile.labels.usedTotal")}:{" "}
{t("home.profile.labels.usedTotal")}:{" "}
<Box component="span" fontWeight="medium">
{parseTraffic(usedTraffic)} /{" "}
{parseTraffic(current.extra.total)}
@@ -213,7 +213,7 @@ const ProfileDetails = ({
<Stack direction="row" alignItems="center" spacing={1}>
<EventOutlined fontSize="small" color="action" />
<Typography variant="body2" color="text.secondary">
{t("components.home.profile.labels.expireTime")}:{" "}
{t("home.profile.labels.expireTime")}:{" "}
<Box component="span" fontWeight="medium">
{parseExpire(current.extra.expire)}
</Box>
@@ -268,11 +268,10 @@ const EmptyProfile = ({ onClick }: { onClick: () => void }) => {
sx={{ fontSize: 60, color: "primary.main", mb: 2 }}
/>
<Typography variant="h6" gutterBottom>
{t("components.home.profile.actions.import")}{" "}
{t("components.home.profile.title")}
{t("home.profile.actions.import")} {t("home.profile.title")}
</Typography>
<Typography variant="body2" color="text.secondary">
{t("components.home.profile.labels.clickToImport")}
{t("home.profile.labels.clickToImport")}
</Typography>
</Box>
);
@@ -313,7 +312,7 @@ export const HomeProfileCard = ({
// 卡片标题
const cardTitle = useMemo(() => {
if (!current) return t("components.home.profile.title");
if (!current) return t("home.profile.title");
if (!current.home) return current.name;

View File

@@ -70,9 +70,7 @@ export const IpInfoCard = () => {
setCountdown(IP_REFRESH_SECONDS);
} catch (err) {
setError(
err instanceof Error
? err.message
: t("components.home.ipInfo.errors.load"),
err instanceof Error ? err.message : t("home.ipInfo.errors.load"),
);
} finally {
setLoading(false);
@@ -118,7 +116,7 @@ export const IpInfoCard = () => {
if (loading) {
return (
<EnhancedCard
title={t("components.home.ipInfo.title")}
title={t("home.ipInfo.title")}
icon={<LocationOnOutlined />}
iconColor="info"
action={
@@ -141,7 +139,7 @@ export const IpInfoCard = () => {
if (error) {
return (
<EnhancedCard
title={t("components.home.ipInfo.title")}
title={t("home.ipInfo.title")}
icon={<LocationOnOutlined />}
iconColor="info"
action={
@@ -164,7 +162,7 @@ export const IpInfoCard = () => {
{error}
</Typography>
<Button onClick={fetchIpInfo} sx={{ mt: 2 }}>
{t("components.home.ipInfo.labels.retry")}
{t("home.ipInfo.labels.retry")}
</Button>
</Box>
</EnhancedCard>
@@ -174,7 +172,7 @@ export const IpInfoCard = () => {
// 渲染正常数据
return (
<EnhancedCard
title={t("components.home.ipInfo.title")}
title={t("home.ipInfo.title")}
icon={<LocationOnOutlined />}
iconColor="info"
action={
@@ -226,7 +224,7 @@ export const IpInfoCard = () => {
maxWidth: "100%",
}}
>
{ipInfo?.country || t("components.home.ipInfo.labels.unknown")}
{ipInfo?.country || t("home.ipInfo.labels.unknown")}
</Typography>
</Box>
@@ -236,7 +234,7 @@ export const IpInfoCard = () => {
color="text.secondary"
sx={{ flexShrink: 0 }}
>
{t("components.home.ipInfo.labels.ip")}:
{t("home.ipInfo.labels.ip")}:
</Typography>
<Box
sx={{
@@ -270,27 +268,24 @@ export const IpInfoCard = () => {
</Box>
<InfoItem
label={t("components.home.ipInfo.labels.asn")}
label={t("home.ipInfo.labels.asn")}
value={ipInfo?.asn ? `AS${ipInfo.asn}` : "N/A"}
/>
</Box>
{/* 右侧组织、ISP和位置信息 */}
<Box sx={{ width: "60%", overflow: "auto" }}>
<InfoItem label={t("home.ipInfo.labels.isp")} value={ipInfo?.isp} />
<InfoItem
label={t("components.home.ipInfo.labels.isp")}
value={ipInfo?.isp}
/>
<InfoItem
label={t("components.home.ipInfo.labels.org")}
label={t("home.ipInfo.labels.org")}
value={ipInfo?.asn_organization}
/>
<InfoItem
label={t("components.home.ipInfo.labels.location")}
label={t("home.ipInfo.labels.location")}
value={[ipInfo?.city, ipInfo?.region].filter(Boolean).join(", ")}
/>
<InfoItem
label={t("components.home.ipInfo.labels.timezone")}
label={t("home.ipInfo.labels.timezone")}
value={ipInfo?.timezone}
/>
</Box>
@@ -310,7 +305,7 @@ export const IpInfoCard = () => {
}}
>
<Typography variant="caption">
{t("components.home.ipInfo.labels.autoRefresh")}: {countdown}s
{t("home.ipInfo.labels.autoRefresh")}: {countdown}s
</Typography>
<Typography
variant="caption"

View File

@@ -160,18 +160,18 @@ export const ProxyTunCard: FC = () => {
if (activeTab === "system") {
return {
text: systemProxyActualState
? t("components.home.proxyTunCard.status.systemProxyEnabled")
: t("components.home.proxyTunCard.status.systemProxyDisabled"),
tooltip: t("components.home.proxyTunCard.tooltips.systemProxy"),
? t("home.proxyTunCard.status.systemProxyEnabled")
: t("home.proxyTunCard.status.systemProxyDisabled"),
tooltip: t("home.proxyTunCard.tooltips.systemProxy"),
};
} else {
return {
text: !isTunModeAvailable
? t("components.home.proxyTunCard.status.tunModeServiceRequired")
? t("home.proxyTunCard.status.tunModeServiceRequired")
: enable_tun_mode
? t("components.home.proxyTunCard.status.tunModeEnabled")
: t("components.home.proxyTunCard.status.tunModeDisabled"),
tooltip: t("components.home.proxyTunCard.tooltips.tunMode"),
? t("home.proxyTunCard.status.tunModeEnabled")
: t("home.proxyTunCard.status.tunModeDisabled"),
tooltip: t("home.proxyTunCard.tooltips.tunMode"),
};
}
}, [
@@ -198,14 +198,14 @@ export const ProxyTunCard: FC = () => {
isActive={activeTab === "system"}
onClick={() => handleTabChange("system")}
icon={ComputerRounded}
label={t("components.settings.system.toggles.systemProxy")}
label={t("settings.system.toggles.systemProxy")}
hasIndicator={systemProxyActualState}
/>
<TabButton
isActive={activeTab === "tun"}
onClick={() => handleTabChange("tun")}
icon={TroubleshootRounded}
label={t("components.settings.system.toggles.tunMode")}
label={t("settings.system.toggles.tunMode")}
hasIndicator={enable_tun_mode && isTunModeAvailable}
/>
</Stack>
@@ -238,8 +238,8 @@ export const ProxyTunCard: FC = () => {
onError={handleError}
label={
activeTab === "system"
? t("components.settings.system.toggles.systemProxy")
: t("components.settings.system.toggles.tunMode")
? t("settings.system.toggles.systemProxy")
: t("settings.system.toggles.tunMode")
}
noRightPadding={true}
/>

View File

@@ -217,11 +217,11 @@ export const SystemInfoCard = () => {
<>
<AdminPanelSettingsOutlined
sx={{ color: "primary.main", fontSize: 16 }}
titleAccess={t("components.home.systemInfo.badges.adminMode")}
titleAccess={t("home.systemInfo.badges.adminMode")}
/>
<DnsOutlined
sx={{ color: "success.main", fontSize: 16, ml: 0.5 }}
titleAccess={t("components.home.systemInfo.badges.serviceMode")}
titleAccess={t("home.systemInfo.badges.serviceMode")}
/>
</>
);
@@ -229,21 +229,21 @@ export const SystemInfoCard = () => {
return (
<AdminPanelSettingsOutlined
sx={{ color: "primary.main", fontSize: 16 }}
titleAccess={t("components.home.systemInfo.badges.adminMode")}
titleAccess={t("home.systemInfo.badges.adminMode")}
/>
);
} else if (isSidecarMode) {
return (
<ExtensionOutlined
sx={{ color: "info.main", fontSize: 16 }}
titleAccess={t("components.home.systemInfo.badges.sidecarMode")}
titleAccess={t("home.systemInfo.badges.sidecarMode")}
/>
);
} else {
return (
<DnsOutlined
sx={{ color: "success.main", fontSize: 16 }}
titleAccess={t("components.home.systemInfo.badges.serviceMode")}
titleAccess={t("home.systemInfo.badges.serviceMode")}
/>
);
}
@@ -254,13 +254,13 @@ export const SystemInfoCard = () => {
if (isAdminMode) {
// 判断是否同时处于服务模式
if (!isSidecarMode) {
return t("components.home.systemInfo.badges.adminServiceMode");
return t("home.systemInfo.badges.adminServiceMode");
}
return t("components.home.systemInfo.badges.adminMode");
return t("home.systemInfo.badges.adminMode");
} else if (isSidecarMode) {
return t("components.home.systemInfo.badges.sidecarMode");
return t("home.systemInfo.badges.sidecarMode");
} else {
return t("components.home.systemInfo.badges.serviceMode");
return t("home.systemInfo.badges.serviceMode");
}
};
@@ -269,14 +269,14 @@ export const SystemInfoCard = () => {
return (
<EnhancedCard
title={t("components.home.systemInfo.title")}
title={t("home.systemInfo.title")}
icon={<InfoOutlined />}
iconColor="error"
action={
<IconButton
size="small"
onClick={goToSettings}
title={t("components.home.systemInfo.actions.settings")}
title={t("home.systemInfo.actions.settings")}
>
<SettingsOutlined fontSize="small" />
</IconButton>
@@ -285,7 +285,7 @@ export const SystemInfoCard = () => {
<Stack spacing={1.5}>
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("components.home.systemInfo.fields.osInfo")}
{t("home.systemInfo.fields.osInfo")}
</Typography>
<Typography variant="body2" fontWeight="medium">
{systemState.osInfo}
@@ -298,13 +298,11 @@ export const SystemInfoCard = () => {
alignItems="center"
>
<Typography variant="body2" color="text.secondary">
{t("components.home.systemInfo.fields.autoLaunch")}
{t("home.systemInfo.fields.autoLaunch")}
</Typography>
<Stack direction="row" spacing={1} alignItems="center">
{isAdminMode && (
<Tooltip
title={t("components.home.systemInfo.tooltips.autoLaunchAdmin")}
>
<Tooltip title={t("home.systemInfo.tooltips.autoLaunchAdmin")}>
<WarningOutlined sx={{ color: "warning.main", fontSize: 20 }} />
</Tooltip>
)}
@@ -312,8 +310,8 @@ export const SystemInfoCard = () => {
size="small"
label={
autoLaunchEnabled
? t("components.home.systemInfo.labels.enabled")
: t("components.home.systemInfo.labels.disabled")
? t("home.systemInfo.labels.enabled")
: t("home.systemInfo.labels.disabled")
}
color={autoLaunchEnabled ? "success" : "default"}
variant={autoLaunchEnabled ? "filled" : "outlined"}
@@ -329,7 +327,7 @@ export const SystemInfoCard = () => {
alignItems="center"
>
<Typography variant="body2" color="text.secondary">
{t("components.home.systemInfo.fields.runningMode")}
{t("home.systemInfo.fields.runningMode")}
</Typography>
<Typography
variant="body2"
@@ -344,7 +342,7 @@ export const SystemInfoCard = () => {
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("components.home.systemInfo.fields.lastCheckUpdate")}
{t("home.systemInfo.fields.lastCheckUpdate")}
</Typography>
<Typography
variant="body2"
@@ -362,7 +360,7 @@ export const SystemInfoCard = () => {
<Divider />
<Stack direction="row" justifyContent="space-between">
<Typography variant="body2" color="text.secondary">
{t("components.home.systemInfo.fields.vergeVersion")}
{t("home.systemInfo.fields.vergeVersion")}
</Typography>
<Typography variant="body2" fontWeight="medium">
v{appVersion}

View File

@@ -177,12 +177,12 @@ export const TestCard = () => {
icon={<NetworkCheck />}
action={
<Box sx={{ display: "flex", gap: 1 }}>
<Tooltip title={t("pages.test.actions.testAll")} arrow>
<Tooltip title={t("test.page.actions.testAll")} arrow>
<IconButton size="small" onClick={handleTestAll}>
<NetworkCheck fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title={t("components.test.viewer.title.create")} arrow>
<Tooltip title={t("test.viewer.title.create")} arrow>
<IconButton size="small" onClick={handleCreateTest}>
<Add fontSize="small" />
</IconButton>

View File

@@ -97,7 +97,7 @@ export const EditorViewer = <T extends Language>(props: Props<T>) => {
onClose,
} = props;
const resolvedTitle = title ?? t("components.profile.menu.editFile");
const resolvedTitle = title ?? t("profile.menu.editFile");
const resolvedInitialData = useMemo(
() => initialData ?? Promise.resolve(""),
[initialData],
@@ -203,7 +203,7 @@ export const EditorViewer = <T extends Language>(props: Props<T>) => {
mouseWheelZoom: true, // 按住Ctrl滚轮调节缩放比例
readOnly: readOnly, // 只读模式
readOnlyMessage: {
value: t("components.profile.editor.readOnlyMessage"),
value: t("profile.editor.readOnlyMessage"),
}, // 只读模式尝试编辑时的提示信息
renderValidationDecorations: "on", // 只读模式下显示校验信息
quickSuggestions: {
@@ -233,7 +233,7 @@ export const EditorViewer = <T extends Language>(props: Props<T>) => {
size="medium"
color="inherit"
sx={{ display: readOnly ? "none" : "" }}
title={t("components.profile.editor.format")}
title={t("profile.editor.format")}
onClick={() =>
editorRef.current
?.getAction("editor.action.formatDocument")

View File

@@ -42,7 +42,7 @@ export const FileInput = (props: Props) => {
sx={{ flex: "none" }}
onClick={() => inputRef.current?.click()}
>
{t("components.profile.fileInput.chooseFile")}
{t("profile.fileInput.chooseFile")}
</Button>
<input

View File

@@ -369,7 +369,7 @@ export const GroupsEditorViewer = (props: Props) => {
const validateGroup = () => {
const group = formIns.getValues();
if (group.name === "") {
throw new Error(t("components.profile.groupsEditor.errors.nameRequired"));
throw new Error(t("profile.groupsEditor.errors.nameRequired"));
}
};
@@ -384,7 +384,7 @@ export const GroupsEditorViewer = (props: Props) => {
}
await saveProfileFile(property, nextData);
showNotice.success("components.profile.notifications.saved");
showNotice.success("profile.notifications.saved");
setPrevData(nextData);
onSave?.(prevData, nextData);
onClose();
@@ -398,7 +398,7 @@ export const GroupsEditorViewer = (props: Props) => {
<DialogTitle>
{
<Box display="flex" justifyContent="space-between">
{t("components.profile.groupsEditor.title")}
{t("profile.groupsEditor.title")}
<Box>
<Button
variant="contained"
@@ -439,9 +439,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.type",
)}
primary={t("profile.groupsEditor.fields.type")}
/>
<Autocomplete
size="small"
@@ -471,9 +469,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.name",
)}
primary={t("profile.groupsEditor.fields.name")}
/>
<TextField
autoComplete="new-password"
@@ -492,9 +488,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.icon",
)}
primary={t("profile.groupsEditor.fields.icon")}
/>
<TextField
autoComplete="new-password"
@@ -511,9 +505,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.proxies",
)}
primary={t("profile.groupsEditor.fields.proxies")}
/>
<Autocomplete
size="small"
@@ -540,9 +532,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.provider",
)}
primary={t("profile.groupsEditor.fields.provider")}
/>
<Autocomplete
size="small"
@@ -563,7 +553,7 @@ export const GroupsEditorViewer = (props: Props) => {
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.healthCheckUrl",
"profile.groupsEditor.fields.healthCheckUrl",
)}
/>
<TextField
@@ -583,7 +573,7 @@ export const GroupsEditorViewer = (props: Props) => {
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.expectedStatus",
"profile.groupsEditor.fields.expectedStatus",
)}
/>
<TextField
@@ -604,9 +594,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.interval",
)}
primary={t("profile.groupsEditor.fields.interval")}
/>
<TextField
autoComplete="new-password"
@@ -636,9 +624,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.timeout",
)}
primary={t("profile.groupsEditor.fields.timeout")}
/>
<TextField
autoComplete="new-password"
@@ -669,7 +655,7 @@ export const GroupsEditorViewer = (props: Props) => {
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.maxFailedTimes",
"profile.groupsEditor.fields.maxFailedTimes",
)}
/>
<TextField
@@ -691,9 +677,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.interfaceName",
)}
primary={t("profile.groupsEditor.fields.interfaceName")}
/>
<Autocomplete
size="small"
@@ -712,9 +696,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.routingMark",
)}
primary={t("profile.groupsEditor.fields.routingMark")}
/>
<TextField
autoComplete="new-password"
@@ -734,9 +716,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.filter",
)}
primary={t("profile.groupsEditor.fields.filter")}
/>
<TextField
autoComplete="new-password"
@@ -753,9 +733,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.excludeFilter",
)}
primary={t("profile.groupsEditor.fields.excludeFilter")}
/>
<TextField
autoComplete="new-password"
@@ -772,9 +750,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.excludeType",
)}
primary={t("profile.groupsEditor.fields.excludeType")}
/>
<Autocomplete
multiple
@@ -822,9 +798,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.includeAll",
)}
primary={t("profile.groupsEditor.fields.includeAll")}
/>
<Switch checked={field.value} {...field} />
</Item>
@@ -837,7 +811,7 @@ export const GroupsEditorViewer = (props: Props) => {
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.includeAllProxies",
"profile.groupsEditor.fields.includeAllProxies",
)}
/>
<Switch checked={field.value} {...field} />
@@ -851,7 +825,7 @@ export const GroupsEditorViewer = (props: Props) => {
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.fields.includeAllProviders",
"profile.groupsEditor.fields.includeAllProviders",
)}
/>
<Switch checked={field.value} {...field} />
@@ -864,9 +838,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.toggles.lazy",
)}
primary={t("profile.groupsEditor.toggles.lazy")}
/>
<Switch checked={field.value} {...field} />
</Item>
@@ -878,9 +850,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.toggles.disableUdp",
)}
primary={t("profile.groupsEditor.toggles.disableUdp")}
/>
<Switch checked={field.value} {...field} />
</Item>
@@ -892,9 +862,7 @@ export const GroupsEditorViewer = (props: Props) => {
render={({ field }) => (
<Item>
<ListItemText
primary={t(
"components.profile.groupsEditor.toggles.hidden",
)}
primary={t("profile.groupsEditor.toggles.hidden")}
/>
<Switch checked={field.value} {...field} />
</Item>
@@ -912,9 +880,7 @@ export const GroupsEditorViewer = (props: Props) => {
for (const item of [...prependSeq, ...groupList]) {
if (item.name === formIns.getValues().name) {
throw new Error(
t(
"components.profile.groupsEditor.errors.nameExists",
),
t("profile.groupsEditor.errors.nameExists"),
);
}
}
@@ -924,7 +890,7 @@ export const GroupsEditorViewer = (props: Props) => {
}
}}
>
{t("components.profile.groupsEditor.actions.prepend")}
{t("profile.groupsEditor.actions.prepend")}
</Button>
</Item>
<Item>
@@ -938,9 +904,7 @@ export const GroupsEditorViewer = (props: Props) => {
for (const item of [...appendSeq, ...groupList]) {
if (item.name === formIns.getValues().name) {
throw new Error(
t(
"components.profile.groupsEditor.errors.nameExists",
),
t("profile.groupsEditor.errors.nameExists"),
);
}
}
@@ -950,7 +914,7 @@ export const GroupsEditorViewer = (props: Props) => {
}
}}
>
{t("components.profile.groupsEditor.actions.append")}
{t("profile.groupsEditor.actions.append")}
</Button>
</Item>
</List>

View File

@@ -26,7 +26,7 @@ export const LogViewer = (props: Props) => {
return (
<Dialog open={open} onClose={onClose}>
<DialogTitle>{t("components.profile.logViewer.title")}</DialogTitle>
<DialogTitle>{t("profile.logViewer.title")}</DialogTitle>
<DialogContent
sx={{

View File

@@ -120,42 +120,38 @@ export const ProfileItem = (props: Props) => {
// 如果已经过期,显示"更新失败"
if (nextUpdateDate.isBefore(now)) {
setNextUpdateTime(
t("components.profile.item.status.lastUpdateFailed"),
);
setNextUpdateTime(t("profile.item.status.lastUpdateFailed"));
} else {
// 否则显示剩余时间
const diffMinutes = nextUpdateDate.diff(now, "minute");
if (diffMinutes < 60) {
if (diffMinutes <= 0) {
setNextUpdateTime(
`${t("components.profile.item.status.nextUp")} <1m`,
);
setNextUpdateTime(`${t("profile.item.status.nextUp")} <1m`);
} else {
setNextUpdateTime(
`${t("components.profile.item.status.nextUp")} ${diffMinutes}m`,
`${t("profile.item.status.nextUp")} ${diffMinutes}m`,
);
}
} else {
const hours = Math.floor(diffMinutes / 60);
const mins = diffMinutes % 60;
setNextUpdateTime(
`${t("components.profile.item.status.nextUp")} ${hours}h ${mins}m`,
`${t("profile.item.status.nextUp")} ${hours}h ${mins}m`,
);
}
}
} else {
console.log(`返回的下次更新时间为空`);
setNextUpdateTime(t("components.profile.item.status.noSchedule"));
setNextUpdateTime(t("profile.item.status.noSchedule"));
}
} catch (err) {
console.error(`获取下次更新时间出错:`, err);
setNextUpdateTime(t("components.profile.item.status.unknown"));
setNextUpdateTime(t("profile.item.status.unknown"));
}
} else {
console.log(`该配置未设置更新间隔或间隔为0`);
setNextUpdateTime(t("components.profile.item.status.autoUpdateDisabled"));
setNextUpdateTime(t("profile.item.status.autoUpdateDisabled"));
}
});
@@ -369,19 +365,19 @@ export const ProfileItem = (props: Props) => {
};
const menuLabels = {
home: "components.profile.menu.home",
select: "components.profile.menu.select",
editInfo: "components.profile.menu.editInfo",
editFile: "components.profile.menu.editFile",
editRules: "components.profile.menu.editRules",
editProxies: "components.profile.menu.editProxies",
editGroups: "components.profile.menu.editGroups",
extendConfig: "components.profile.menu.extendConfig",
extendScript: "components.profile.menu.extendScript",
openFile: "components.profile.menu.openFile",
update: "components.profile.menu.update",
updateViaProxy: "components.profile.menu.updateViaProxy",
delete: "components.profile.menu.delete",
home: "profile.menu.home",
select: "profile.menu.select",
editInfo: "profile.menu.editInfo",
editFile: "profile.menu.editFile",
editRules: "profile.menu.editRules",
editProxies: "profile.menu.editProxies",
editGroups: "profile.menu.editGroups",
extendConfig: "profile.menu.extendConfig",
extendScript: "profile.menu.extendScript",
openFile: "profile.menu.openFile",
update: "profile.menu.update",
updateViaProxy: "profile.menu.updateViaProxy",
delete: "profile.menu.delete",
} as const;
const urlModeMenu: ContextMenuItem[] = [
@@ -734,8 +730,8 @@ export const ProfileItem = (props: Props) => {
textAlign="right"
title={
showNextUpdate
? t("components.profile.item.tooltips.showLast")
: `${t("Update Time")}: ${parseExpire(updated)}\n${t("components.profile.item.tooltips.showNext")}`
? t("profile.item.tooltips.showLast")
: `${t("Update Time")}: ${parseExpire(updated)}\n${t("profile.item.tooltips.showNext")}`
}
sx={{
cursor: "pointer",
@@ -890,8 +886,8 @@ export const ProfileItem = (props: Props) => {
)}
<ConfirmViewer
title={t("components.profile.confirm.delete.title")}
message={t("components.profile.confirm.delete.message")}
title={t("profile.confirm.delete.title")}
message={t("profile.confirm.delete.message")}
open={confirmOpen}
onClose={() => setConfirmOpen(false)}
onConfirm={() => {

View File

@@ -55,18 +55,18 @@ export const ProfileMore = (props: Props) => {
const hasError = entries.some(([level]) => level === "exception");
const globalTitles: Record<Props["id"], string> = {
Merge: "components.profile.more.global.merge",
Script: "components.profile.more.global.script",
Merge: "profile.more.global.merge",
Script: "profile.more.global.script",
};
const chipLabels: Record<Props["id"], string> = {
Merge: "components.profile.more.chips.merge",
Script: "components.profile.more.chips.script",
Merge: "profile.more.chips.merge",
Script: "profile.more.chips.script",
};
const itemMenu = [
{ label: "components.profile.menu.editFile", handler: onEditFile },
{ label: "components.profile.menu.openFile", handler: onOpenFile },
{ label: "profile.menu.editFile", handler: onEditFile },
{ label: "profile.menu.openFile", handler: onOpenFile },
];
const boxStyle = {
@@ -121,7 +121,7 @@ export const ProfileMore = (props: Props) => {
size="small"
edge="start"
color="error"
title={t("components.profile.logViewer.title")}
title={t("profile.logViewer.title")}
onClick={() => setLogOpen(true)}
>
<FeaturedPlayListRounded fontSize="inherit" />
@@ -132,7 +132,7 @@ export const ProfileMore = (props: Props) => {
size="small"
edge="start"
color="inherit"
title={t("components.profile.logViewer.title")}
title={t("profile.logViewer.title")}
onClick={() => setLogOpen(true)}
>
<FeaturedPlayListRounded fontSize="inherit" />

View File

@@ -144,9 +144,7 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
}
} catch {
// 首次创建/更新失败,尝试使用自身代理
showNotice.info(
"components.profile.viewer.notifications.creationRetry",
);
showNotice.info("profile.viewer.notifications.creationRetry");
// 使用自身代理的配置
const retryItem = {
@@ -169,9 +167,7 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
await patchProfile(form.uid, { option: originalOptions });
}
showNotice.success(
"components.profile.viewer.notifications.creationSuccess",
);
showNotice.success("profile.viewer.notifications.creationSuccess");
}
}
@@ -220,12 +216,12 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
open={open}
title={
openType === "new"
? t("components.profile.viewer.title.create")
: t("components.profile.viewer.title.edit")
? t("profile.viewer.title.create")
: t("profile.viewer.title.edit")
}
contentSx={{ width: 375, pb: 0, maxHeight: "80%" }}
okBtn={t("components.profile.viewer.buttons.save")}
cancelBtn={t("components.profile.viewer.buttons.cancel")}
okBtn={t("profile.viewer.buttons.save")}
cancelBtn={t("profile.viewer.buttons.cancel")}
onClose={handleClose}
onCancel={handleClose}
onOk={handleOk}
@@ -236,13 +232,11 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
control={control}
render={({ field }) => (
<FormControl size="small" fullWidth sx={{ mt: 1, mb: 1 }}>
<InputLabel>
{t("components.profile.viewer.fields.type")}
</InputLabel>
<InputLabel>{t("profile.viewer.fields.type")}</InputLabel>
<Select
{...field}
autoFocus
label={t("components.profile.viewer.fields.type")}
label={t("profile.viewer.fields.type")}
>
<MenuItem value="remote">Remote</MenuItem>
<MenuItem value="local">Local</MenuItem>
@@ -258,7 +252,7 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
<TextField
{...text}
{...field}
label={t("components.profile.viewer.fields.name")}
label={t("profile.viewer.fields.name")}
/>
)}
/>
@@ -270,7 +264,7 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
<TextField
{...text}
{...field}
label={t("components.profile.viewer.fields.description")}
label={t("profile.viewer.fields.description")}
/>
)}
/>
@@ -285,7 +279,7 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
{...text}
{...field}
multiline
label={t("components.profile.viewer.fields.subscriptionUrl")}
label={t("profile.viewer.fields.subscriptionUrl")}
/>
)}
/>
@@ -312,7 +306,7 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
{...field}
type="number"
placeholder="60"
label={t("components.profile.viewer.fields.httpTimeout")}
label={t("profile.viewer.fields.httpTimeout")}
slotProps={{
input: {
endAdornment: (
@@ -337,7 +331,7 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
{...text}
{...field}
type="number"
label={t("components.profile.viewer.fields.updateInterval")}
label={t("profile.viewer.fields.updateInterval")}
slotProps={{
input: {
endAdornment: (
@@ -367,7 +361,7 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
render={({ field }) => (
<StyledBox>
<InputLabel>
{t("components.profile.viewer.fields.useSystemProxy")}
{t("profile.viewer.fields.useSystemProxy")}
</InputLabel>
<Switch checked={field.value} {...field} color="primary" />
</StyledBox>
@@ -380,7 +374,7 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
render={({ field }) => (
<StyledBox>
<InputLabel>
{t("components.profile.viewer.fields.useClashProxy")}
{t("profile.viewer.fields.useClashProxy")}
</InputLabel>
<Switch checked={field.value} {...field} color="primary" />
</StyledBox>
@@ -393,7 +387,7 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
render={({ field }) => (
<StyledBox>
<InputLabel>
{t("components.profile.viewer.fields.acceptInvalidCerts")}
{t("profile.viewer.fields.acceptInvalidCerts")}
</InputLabel>
<Switch checked={field.value} {...field} color="primary" />
</StyledBox>
@@ -406,7 +400,7 @@ export function ProfileViewer({ onChange, ref }: ProfileViewerProps) {
render={({ field }) => (
<StyledBox>
<InputLabel>
{t("components.profile.viewer.fields.allowAutoUpdate")}
{t("profile.viewer.fields.allowAutoUpdate")}
</InputLabel>
<Switch checked={field.value} {...field} color="primary" />
</StyledBox>

View File

@@ -263,7 +263,7 @@ export const ProxiesEditorViewer = (props: Props) => {
const handleSave = useLockFn(async () => {
try {
await saveProfileFile(property, currData);
showNotice.success("components.profile.notifications.saved");
showNotice.success("profile.notifications.saved");
onSave?.(prevData, currData);
onClose();
} catch (err) {
@@ -276,7 +276,7 @@ export const ProxiesEditorViewer = (props: Props) => {
<DialogTitle>
{
<Box display="flex" justifyContent="space-between">
{t("components.profile.proxiesEditor.title")}
{t("profile.proxiesEditor.title")}
<Box>
<Button
variant="contained"
@@ -315,7 +315,7 @@ export const ProxiesEditorViewer = (props: Props) => {
<TextField
autoComplete="new-password"
placeholder={t(
"components.profile.proxiesEditor.placeholders.multiUri",
"profile.proxiesEditor.placeholders.multiUri",
)}
fullWidth
rows={9}
@@ -336,7 +336,7 @@ export const ProxiesEditorViewer = (props: Props) => {
});
}}
>
{t("components.profile.proxiesEditor.actions.prepend")}
{t("profile.proxiesEditor.actions.prepend")}
</Button>
</Item>
<Item>
@@ -350,7 +350,7 @@ export const ProxiesEditorViewer = (props: Props) => {
});
}}
>
{t("components.profile.proxiesEditor.actions.append")}
{t("profile.proxiesEditor.actions.append")}
</Button>
</Item>
</List>

View File

@@ -462,12 +462,10 @@ export const RulesEditorViewer = (props: Props) => {
const validateRule = () => {
if ((ruleType.required ?? true) && !ruleContent) {
throw new Error(
t("components.ruleEditor.form.validation.conditionRequired"),
);
throw new Error(t("ruleEditor.form.validation.conditionRequired"));
}
if (ruleType.validator && !ruleType.validator(ruleContent)) {
throw new Error(t("components.ruleEditor.form.validation.invalidRule"));
throw new Error(t("ruleEditor.form.validation.invalidRule"));
}
const condition = (ruleType.required ?? true) ? ruleContent : "";
@@ -479,7 +477,7 @@ export const RulesEditorViewer = (props: Props) => {
const handleSave = useLockFn(async () => {
try {
await saveProfileFile(property, currData);
showNotice.success("components.profile.notifications.saved");
showNotice.success("profile.notifications.saved");
onSave?.(prevData, currData);
onClose();
} catch (err: any) {
@@ -492,7 +490,7 @@ export const RulesEditorViewer = (props: Props) => {
<DialogTitle>
{
<Box display="flex" justifyContent="space-between">
{t("components.ruleEditor.title")}
{t("ruleEditor.title")}
<Box>
<Button
variant="contained"
@@ -522,9 +520,7 @@ export const RulesEditorViewer = (props: Props) => {
}}
>
<Item>
<ListItemText
primary={t("components.ruleEditor.form.labels.type")}
/>
<ListItemText primary={t("ruleEditor.form.labels.type")} />
<Autocomplete
size="small"
sx={{ minWidth: "240px" }}
@@ -535,9 +531,7 @@ export const RulesEditorViewer = (props: Props) => {
renderOption={(props, option) => (
<li
{...props}
title={t(
`components.ruleEditor.ruleTypes.${option.name}`,
)}
title={t(`ruleEditor.ruleTypes.${option.name}`)}
>
{option.name}
</li>
@@ -548,9 +542,7 @@ export const RulesEditorViewer = (props: Props) => {
<Item
sx={{ display: !(ruleType.required ?? true) ? "none" : "" }}
>
<ListItemText
primary={t("components.ruleEditor.form.labels.content")}
/>
<ListItemText primary={t("ruleEditor.form.labels.content")} />
{ruleType.name === "RULE-SET" && (
<Autocomplete
@@ -588,7 +580,7 @@ export const RulesEditorViewer = (props: Props) => {
</Item>
<Item>
<ListItemText
primary={t("components.ruleEditor.form.labels.proxyPolicy")}
primary={t("ruleEditor.form.labels.proxyPolicy")}
/>
<Autocomplete
size="small"
@@ -607,7 +599,7 @@ export const RulesEditorViewer = (props: Props) => {
{ruleType.noResolve && (
<Item>
<ListItemText
primary={t("components.ruleEditor.form.toggles.noResolve")}
primary={t("ruleEditor.form.toggles.noResolve")}
/>
<Switch
checked={noResolve}
@@ -630,7 +622,7 @@ export const RulesEditorViewer = (props: Props) => {
}
}}
>
{t("components.ruleEditor.form.actions.prependRule")}
{t("ruleEditor.form.actions.prependRule")}
</Button>
</Item>
<Item>
@@ -648,7 +640,7 @@ export const RulesEditorViewer = (props: Props) => {
}
}}
>
{t("components.ruleEditor.form.actions.appendRule")}
{t("ruleEditor.form.actions.appendRule")}
</Button>
</Item>
</List>

View File

@@ -66,11 +66,11 @@ export const ProviderButton = () => {
await refreshProxy();
await refreshProxyProviders();
showNotice.success("components.providers.notices.updateSuccess", {
showNotice.success("providers.notices.updateSuccess", {
name,
});
} catch (err) {
showNotice.error("components.providers.notices.updateFailed", {
showNotice.error("providers.notices.updateFailed", {
name,
message: String(err),
});
@@ -86,7 +86,7 @@ export const ProviderButton = () => {
// 获取所有provider的名称
const allProviders = Object.keys(proxyProviders || {});
if (allProviders.length === 0) {
showNotice.info("components.providers.notices.none");
showNotice.info("providers.notices.none");
return;
}
@@ -116,9 +116,9 @@ export const ProviderButton = () => {
await refreshProxy();
await refreshProxyProviders();
showNotice.success("components.providers.notices.allUpdated");
showNotice.success("providers.notices.allUpdated");
} catch (err) {
showNotice.error("components.providers.notices.genericError", {
showNotice.error("providers.notices.genericError", {
message: String(err),
});
} finally {
@@ -142,7 +142,7 @@ export const ProviderButton = () => {
onClick={() => setOpen(true)}
sx={{ mr: 1 }}
>
{t("pages.proxies.provider.title")}
{t("proxies.page.provider.title")}
</Button>
<Dialog open={open} onClose={handleClose} maxWidth="sm" fullWidth>
@@ -153,16 +153,16 @@ export const ProviderButton = () => {
alignItems="center"
>
<Typography variant="h6">
{t("pages.proxies.provider.title")}
{t("proxies.page.provider.title")}
</Typography>
<Box>
<Button
variant="contained"
size="small"
onClick={updateAllProviders}
aria-label={t("pages.proxies.provider.actions.updateAll")}
aria-label={t("proxies.page.provider.actions.updateAll")}
>
{t("pages.proxies.provider.actions.updateAll")}
{t("proxies.page.provider.actions.updateAll")}
</Button>
</Box>
</Box>
@@ -320,8 +320,8 @@ export const ProviderButton = () => {
"100%": { transform: "rotate(360deg)" },
},
}}
title={t("pages.proxies.provider.actions.update")}
aria-label={t("pages.proxies.provider.actions.update")}
title={t("proxies.page.provider.actions.update")}
aria-label={t("proxies.page.provider.actions.update")}
>
<RefreshRounded />
</IconButton>

View File

@@ -299,7 +299,7 @@ export const ProxyChain = ({
// onUpdateChain([]);
} catch (error) {
console.error("Failed to disconnect from proxy chain:", error);
alert(t("pages.proxies.chain.disconnectFailed") || "断开链式代理失败");
alert(t("proxies.page.chain.disconnectFailed") || "断开链式代理失败");
} finally {
setIsConnecting(false);
}
@@ -307,7 +307,7 @@ export const ProxyChain = ({
}
if (proxyChain.length < 2) {
alert(t("pages.proxies.chain.minimumNodes") || "链式代理至少需要2个节点");
alert(t("proxies.page.chain.minimumNodes") || "链式代理至少需要2个节点");
return;
}
@@ -339,7 +339,7 @@ export const ProxyChain = ({
console.log("Successfully connected to proxy chain");
} catch (error) {
console.error("Failed to connect to proxy chain:", error);
alert(t("pages.proxies.chain.connectFailed") || "连接链式代理失败");
alert(t("proxies.page.chain.connectFailed") || "连接链式代理失败");
} finally {
setIsConnecting(false);
}
@@ -469,7 +469,7 @@ export const ProxyChain = ({
mb: 2,
}}
>
<Typography variant="h6">{t("pages.proxies.chain.header")}</Typography>
<Typography variant="h6">{t("proxies.page.chain.header")}</Typography>
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
{proxyChain.length > 0 && (
<IconButton
@@ -485,7 +485,7 @@ export const ProxyChain = ({
},
}}
title={
t("pages.proxies.actions.clearChainConfig") || "删除链式配置"
t("proxies.page.actions.clearChainConfig") || "删除链式配置"
}
>
<DeleteIcon fontSize="small" />
@@ -507,16 +507,16 @@ export const ProxyChain = ({
}}
title={
proxyChain.length < 2
? t("pages.proxies.chain.minimumNodes") ||
? t("proxies.page.chain.minimumNodes") ||
"链式代理至少需要2个节点"
: undefined
}
>
{isConnecting
? t("pages.proxies.actions.connecting") || "连接中..."
? t("proxies.page.actions.connecting") || "连接中..."
: isConnected
? t("pages.proxies.actions.disconnect") || "断开"
: t("pages.proxies.actions.connect") || "连接"}
? t("proxies.page.actions.disconnect") || "断开"
: t("proxies.page.actions.connect") || "连接"}
</Button>
</Box>
</Box>
@@ -526,9 +526,9 @@ export const ProxyChain = ({
sx={{ mb: 2 }}
>
{proxyChain.length === 1
? t("pages.proxies.chain.minimumNodesHint") ||
? t("proxies.page.chain.minimumNodesHint") ||
"链式代理至少需要2个节点请再添加一个节点。"
: t("pages.proxies.chain.instruction") ||
: t("proxies.page.chain.instruction") ||
"按顺序点击节点添加到代理链中"}
</Alert>
@@ -543,7 +543,7 @@ export const ProxyChain = ({
color: theme.palette.text.secondary,
}}
>
<Typography>{t("pages.proxies.chain.empty")}</Typography>
<Typography>{t("proxies.page.chain.empty")}</Typography>
</Box>
) : (
<DndContext

View File

@@ -239,7 +239,7 @@ export const ProxyGroups = (props: Props) => {
setProxyChain((prev) => {
// 检查是否已经存在相同名称的代理,防止重复添加
if (prev.some((item) => item.name === proxy.name)) {
const warningMessage = t("pages.proxies.chain.duplicateNode");
const warningMessage = t("proxies.page.chain.duplicateNode");
setDuplicateWarning({
open: true,
message: warningMessage,
@@ -403,7 +403,7 @@ export const ProxyGroups = (props: Props) => {
variant="h6"
sx={{ fontWeight: 600, fontSize: "16px" }}
>
{t("pages.proxies.rules.title")}
{t("proxies.page.rules.title")}
</Typography>
{currentGroup && (
<Box
@@ -442,7 +442,7 @@ export const ProxyGroups = (props: Props) => {
variant="body2"
sx={{ mr: 0.5, fontSize: "12px" }}
>
{t("pages.proxies.rules.select")}
{t("proxies.page.rules.select")}
</Typography>
<ExpandMoreRounded fontSize="small" />
</IconButton>

View File

@@ -67,7 +67,7 @@ export const ProxyHead = ({
<IconButton
size="small"
color="inherit"
title={t("pages.proxies.tooltips.locate")}
title={t("proxies.page.tooltips.locate")}
onClick={onLocation}
>
<MyLocationRounded />
@@ -76,7 +76,7 @@ export const ProxyHead = ({
<IconButton
size="small"
color="inherit"
title={t("pages.proxies.tooltips.delayCheck")}
title={t("proxies.page.tooltips.delayCheck")}
onClick={() => {
console.log(`[ProxyHead] 点击延迟测试按钮,组: ${groupName}`);
// Remind the user that it is custom test url
@@ -95,9 +95,9 @@ export const ProxyHead = ({
color="inherit"
title={
[
t("pages.proxies.tooltips.sortDefault"),
t("pages.proxies.tooltips.sortDelay"),
t("pages.proxies.tooltips.sortName"),
t("proxies.page.tooltips.sortDefault"),
t("proxies.page.tooltips.sortDelay"),
t("proxies.page.tooltips.sortName"),
][sortType]
}
onClick={() =>
@@ -112,7 +112,7 @@ export const ProxyHead = ({
<IconButton
size="small"
color="inherit"
title={t("pages.proxies.tooltips.delayCheckUrl")}
title={t("proxies.page.tooltips.delayCheckUrl")}
onClick={() =>
onHeadState({ textState: textState === "url" ? null : "url" })
}
@@ -129,8 +129,8 @@ export const ProxyHead = ({
color="inherit"
title={
showType
? t("pages.proxies.tooltips.showBasic")
: t("pages.proxies.tooltips.showDetail")
? t("proxies.page.tooltips.showBasic")
: t("proxies.page.tooltips.showDetail")
}
onClick={() => onHeadState({ showType: !showType })}
>
@@ -140,7 +140,7 @@ export const ProxyHead = ({
<IconButton
size="small"
color="inherit"
title={t("pages.proxies.tooltips.filter")}
title={t("proxies.page.tooltips.filter")}
onClick={() =>
onHeadState({ textState: textState === "filter" ? null : "filter" })
}
@@ -160,7 +160,7 @@ export const ProxyHead = ({
value={filterText}
size="small"
variant="outlined"
placeholder={t("pages.proxies.placeholders.filter")}
placeholder={t("proxies.page.placeholders.filter")}
onChange={(e) => onHeadState({ filterText: e.target.value })}
sx={{ ml: 0.5, flex: "1 1 auto", input: { py: 0.65, px: 1 } }}
/>
@@ -175,7 +175,7 @@ export const ProxyHead = ({
value={testUrl}
size="small"
variant="outlined"
placeholder={t("pages.proxies.placeholders.delayCheckUrl")}
placeholder={t("proxies.page.placeholders.delayCheckUrl")}
onChange={(e) => onHeadState({ testUrl: e.target.value })}
sx={{ ml: 0.5, flex: "1 1 auto", input: { py: 0.65, px: 1 } }}
/>

View File

@@ -272,7 +272,7 @@ export const ProxyItemMini = (props: Props) => {
className={proxy.name === group.now ? "the-pin" : "the-unpin"}
title={
group.type === "URLTest"
? t("pages.proxies.labels.delayCheckReset")
? t("proxies.page.labels.delayCheckReset")
: ""
}
>

View File

@@ -160,7 +160,7 @@ export const ProxyRender = (props: RenderProps) => {
}}
/>
<Box sx={{ display: "flex", alignItems: "center" }}>
<Tooltip title={t("pages.proxies.labels.proxyCount")} arrow>
<Tooltip title={t("proxies.page.labels.proxyCount")} arrow>
<Chip
size="small"
label={`${group.all.length}`}

View File

@@ -58,11 +58,11 @@ export const ProviderButton = () => {
await refreshRules();
await refreshRuleProviders();
showNotice.success("components.notices.providers.updateSuccess", {
showNotice.success("notices.providers.updateSuccess", {
name,
});
} catch (err) {
showNotice.error("components.notices.providers.updateFailed", {
showNotice.error("notices.providers.updateFailed", {
name,
message: String(err),
});
@@ -78,7 +78,7 @@ export const ProviderButton = () => {
// 获取所有provider的名称
const allProviders = Object.keys(ruleProviders || {});
if (allProviders.length === 0) {
showNotice.info("components.notices.providers.none");
showNotice.info("notices.providers.none");
return;
}
@@ -108,9 +108,9 @@ export const ProviderButton = () => {
await refreshRules();
await refreshRuleProviders();
showNotice.success("components.notices.providers.allUpdated");
showNotice.success("notices.providers.allUpdated");
} catch (err) {
showNotice.error("components.notices.providers.genericError", {
showNotice.error("notices.providers.genericError", {
message: String(err),
});
} finally {
@@ -133,7 +133,7 @@ export const ProviderButton = () => {
startIcon={<StorageOutlined />}
onClick={() => setOpen(true)}
>
{t("pages.rules.provider.trigger")}
{t("rules.page.provider.trigger")}
</Button>
<Dialog open={open} onClose={handleClose} maxWidth="sm" fullWidth>
@@ -144,14 +144,14 @@ export const ProviderButton = () => {
alignItems="center"
>
<Typography variant="h6">
{t("pages.rules.provider.dialogTitle")}
{t("rules.page.provider.dialogTitle")}
</Typography>
<Button
variant="contained"
size="small"
onClick={updateAllProviders}
>
{t("pages.rules.provider.actions.updateAll")}
{t("rules.page.provider.actions.updateAll")}
</Button>
</Box>
</DialogTitle>
@@ -252,7 +252,7 @@ export const ProviderButton = () => {
color="primary"
onClick={() => updateProvider(key)}
disabled={isUpdating}
aria-label={t("pages.rules.provider.actions.update")}
aria-label={t("rules.page.provider.actions.update")}
sx={{
animation: isUpdating
? "spin 1s linear infinite"
@@ -262,7 +262,7 @@ export const ProviderButton = () => {
"100%": { transform: "rotate(360deg)" },
},
}}
title={t("pages.rules.provider.actions.update")}
title={t("rules.page.provider.actions.update")}
>
<RefreshRounded />
</IconButton>

View File

@@ -84,38 +84,22 @@ export const BackupConfigViewer = memo(
if (!url) {
urlRef.current?.focus();
showNotice.error(
"components.settings.backup.messages.webdavUrlRequired",
);
throw new Error(
t("components.settings.backup.messages.webdavUrlRequired"),
);
showNotice.error("settings.backup.messages.webdavUrlRequired");
throw new Error(t("settings.backup.messages.webdavUrlRequired"));
} else if (!isValidUrl(url)) {
urlRef.current?.focus();
showNotice.error(
"components.settings.backup.messages.invalidWebdavUrl",
);
throw new Error(
t("components.settings.backup.messages.invalidWebdavUrl"),
);
showNotice.error("settings.backup.messages.invalidWebdavUrl");
throw new Error(t("settings.backup.messages.invalidWebdavUrl"));
}
if (!username) {
usernameRef.current?.focus();
showNotice.error(
"components.settings.backup.messages.usernameRequired",
);
throw new Error(
t("components.settings.backup.messages.usernameRequired"),
);
showNotice.error("settings.backup.messages.usernameRequired");
throw new Error(t("settings.backup.messages.usernameRequired"));
}
if (!password) {
passwordRef.current?.focus();
showNotice.error(
"components.settings.backup.messages.passwordRequired",
);
throw new Error(
t("components.settings.backup.messages.passwordRequired"),
);
showNotice.error("settings.backup.messages.passwordRequired");
throw new Error(t("settings.backup.messages.passwordRequired"));
}
};
@@ -128,14 +112,12 @@ export const BackupConfigViewer = memo(
data.username.trim(),
data.password,
).then(() => {
showNotice.success(
"components.settings.backup.messages.webdavConfigSaved",
);
showNotice.success("settings.backup.messages.webdavConfigSaved");
onSaveSuccess();
});
} catch (error) {
showNotice.error(
"components.settings.backup.messages.webdavConfigSaveFailed",
"settings.backup.messages.webdavConfigSaveFailed",
{ error },
3000,
);
@@ -149,13 +131,11 @@ export const BackupConfigViewer = memo(
try {
setLoading(true);
await createWebdavBackup().then(async () => {
showNotice.success(
"components.settings.backup.messages.backupCreated",
);
showNotice.success("settings.backup.messages.backupCreated");
await onBackupSuccess();
});
} catch (error) {
showNotice.error("components.settings.backup.messages.backupFailed", {
showNotice.error("settings.backup.messages.backupFailed", {
error,
});
} finally {
@@ -171,7 +151,7 @@ export const BackupConfigViewer = memo(
<Grid size={{ xs: 12 }}>
<TextField
fullWidth
label={t("components.settings.backup.fields.webdavUrl")}
label={t("settings.backup.fields.webdavUrl")}
variant="outlined"
size="small"
{...register("url")}
@@ -183,7 +163,7 @@ export const BackupConfigViewer = memo(
</Grid>
<Grid size={{ xs: 6 }}>
<TextField
label={t("components.settings.backup.fields.username")}
label={t("settings.backup.fields.username")}
variant="outlined"
size="small"
{...register("username")}
@@ -195,7 +175,7 @@ export const BackupConfigViewer = memo(
</Grid>
<Grid size={{ xs: 6 }}>
<TextField
label={t("components.settings.backup.fields.password")}
label={t("settings.backup.fields.password")}
type={showPassword ? "text" : "password"}
variant="outlined"
size="small"
@@ -240,7 +220,7 @@ export const BackupConfigViewer = memo(
type="button"
onClick={handleSubmit(save)}
>
{t("components.settings.backup.actions.save")}
{t("settings.backup.actions.save")}
</Button>
) : (
<>
@@ -251,7 +231,7 @@ export const BackupConfigViewer = memo(
type="button"
size="large"
>
{t("components.settings.backup.actions.backup")}
{t("settings.backup.actions.backup")}
</Button>
<Button
variant="outlined"
@@ -259,7 +239,7 @@ export const BackupConfigViewer = memo(
type="button"
size="large"
>
{t("components.settings.backup.actions.refresh")}
{t("settings.backup.actions.refresh")}
</Button>
</>
)}

View File

@@ -75,9 +75,7 @@ export const BackupTableViewer = memo(
const handleRestore = useLockFn(async (filename: string) => {
await onRestore(filename).then(() => {
showNotice.success(
"components.settings.backup.messages.restoreSuccess",
);
showNotice.success("settings.backup.messages.restoreSuccess");
});
await restartApp();
});
@@ -94,14 +92,10 @@ export const BackupTableViewer = memo(
return;
}
await onExport(filename, savePath);
showNotice.success(
"components.settings.backup.messages.localBackupExported",
);
showNotice.success("settings.backup.messages.localBackupExported");
} catch (error) {
console.error(error);
showNotice.error(
"components.settings.backup.messages.localBackupExportFailed",
);
showNotice.error("settings.backup.messages.localBackupExportFailed");
}
});
@@ -110,14 +104,10 @@ export const BackupTableViewer = memo(
<Table>
<TableHead>
<TableRow>
<TableCell>
{t("components.settings.backup.table.filename")}
</TableCell>
<TableCell>
{t("components.settings.backup.table.backupTime")}
</TableCell>
<TableCell>{t("settings.backup.table.filename")}</TableCell>
<TableCell>{t("settings.backup.table.backupTime")}</TableCell>
<TableCell align="right">
{t("components.settings.backup.table.actions")}
{t("settings.backup.table.actions")}
</TableCell>
</TableRow>
</TableHead>
@@ -152,13 +142,9 @@ export const BackupTableViewer = memo(
<>
<IconButton
color="primary"
aria-label={t(
"components.settings.backup.actions.export",
)}
aria-label={t("settings.backup.actions.export")}
size="small"
title={t(
"components.settings.backup.actions.exportBackup",
)}
title={t("settings.backup.actions.exportBackup")}
onClick={async (e: React.MouseEvent) => {
e.preventDefault();
await handleExport(file.filename);
@@ -175,19 +161,13 @@ export const BackupTableViewer = memo(
)}
<IconButton
color="secondary"
aria-label={t(
"components.settings.backup.actions.delete",
)}
aria-label={t("settings.backup.actions.delete")}
size="small"
title={t(
"components.settings.backup.actions.deleteBackup",
)}
title={t("settings.backup.actions.deleteBackup")}
onClick={async (e: React.MouseEvent) => {
e.preventDefault();
const confirmed = await confirmAsync(
t(
"components.settings.backup.messages.confirmDelete",
),
t("settings.backup.messages.confirmDelete"),
);
if (confirmed) {
await handleDelete(file.filename);
@@ -203,20 +183,14 @@ export const BackupTableViewer = memo(
/>
<IconButton
color="primary"
aria-label={t(
"components.settings.backup.actions.restore",
)}
aria-label={t("settings.backup.actions.restore")}
size="small"
title={t(
"components.settings.backup.actions.restoreBackup",
)}
title={t("settings.backup.actions.restoreBackup")}
disabled={!file.allow_apply}
onClick={async (e: React.MouseEvent) => {
e.preventDefault();
const confirmed = await confirmAsync(
t(
"components.settings.backup.messages.confirmRestore",
),
t("settings.backup.messages.confirmRestore"),
);
if (confirmed) {
await handleRestore(file.filename);
@@ -247,7 +221,7 @@ export const BackupTableViewer = memo(
color="textSecondary"
align="center"
>
{t("components.settings.backup.table.noBackups")}
{t("settings.backup.table.noBackups")}
</Typography>
</Box>
</TableCell>
@@ -262,7 +236,7 @@ export const BackupTableViewer = memo(
rowsPerPage={DEFAULT_ROWS_PER_PAGE}
page={page}
onPageChange={onPageChange}
labelRowsPerPage={t("components.settings.backup.table.rowsPerPage")}
labelRowsPerPage={t("settings.backup.table.rowsPerPage")}
/>
</TableContainer>
);

View File

@@ -247,7 +247,7 @@ export function BackupViewer({ ref }: { ref?: Ref<DialogRef> }) {
return (
<BaseDialog
open={open}
title={t("components.settings.backup.title")}
title={t("settings.backup.title")}
contentSx={{
minWidth: { xs: 320, sm: 620 },
maxWidth: "unset",
@@ -278,17 +278,11 @@ export function BackupViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Tabs
value={source}
onChange={handleChangeSource}
aria-label={t("components.settings.backup.actions.selectTarget")}
aria-label={t("settings.backup.actions.selectTarget")}
sx={{ mb: 2 }}
>
<Tab
value="local"
label={t("components.settings.backup.tabs.local")}
/>
<Tab
value="webdav"
label={t("components.settings.backup.tabs.webdav")}
/>
<Tab value="local" label={t("settings.backup.tabs.local")} />
<Tab value="webdav" label={t("settings.backup.tabs.webdav")} />
</Tabs>
{source === "local" ? (
<LocalBackupActions

View File

@@ -69,10 +69,10 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
manual: true,
onSuccess: () => {
setOpen(false);
showNotice.success("components.settings.clash.port.messages.saved");
showNotice.success("settings.clash.port.messages.saved");
},
onError: () => {
showNotice.error("components.settings.clash.port.messages.saveFailed");
showNotice.error("settings.clash.port.messages.saveFailed");
},
},
);
@@ -149,7 +149,7 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
return (
<BaseDialog
open={open}
title={t("components.settings.clash.port.title")}
title={t("settings.clash.port.title")}
contentSx={{
width: 400,
}}
@@ -171,7 +171,7 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
<List sx={{ width: "100%" }}>
<ListItem sx={{ padding: "4px 0", minHeight: 36 }}>
<ListItemText
primary={t("components.settings.clash.port.fields.mixed")}
primary={t("settings.clash.port.fields.mixed")}
slotProps={{ primary: { sx: { fontSize: 12 } } }}
/>
<div style={{ display: "flex", alignItems: "center" }}>
@@ -187,7 +187,7 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
<IconButton
size="small"
onClick={() => setMixedPort(generateRandomPort())}
title={t("components.settings.clash.port.actions.random")}
title={t("settings.clash.port.actions.random")}
sx={{ mr: 0.5 }}
>
<Shuffle fontSize="small" />
@@ -203,7 +203,7 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
<ListItem sx={{ padding: "4px 0", minHeight: 36 }}>
<ListItemText
primary={t("components.settings.clash.port.fields.socks")}
primary={t("settings.clash.port.fields.socks")}
slotProps={{ primary: { sx: { fontSize: 12 } } }}
/>
<div style={{ display: "flex", alignItems: "center" }}>
@@ -220,7 +220,7 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
<IconButton
size="small"
onClick={() => setSocksPort(generateRandomPort())}
title={t("components.settings.clash.port.actions.random")}
title={t("settings.clash.port.actions.random")}
disabled={!socksEnabled}
sx={{ mr: 0.5 }}
>
@@ -237,7 +237,7 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
<ListItem sx={{ padding: "4px 0", minHeight: 36 }}>
<ListItemText
primary={t("components.settings.clash.port.fields.http")}
primary={t("settings.clash.port.fields.http")}
slotProps={{ primary: { sx: { fontSize: 12 } } }}
/>
<div style={{ display: "flex", alignItems: "center" }}>
@@ -254,7 +254,7 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
<IconButton
size="small"
onClick={() => setHttpPort(generateRandomPort())}
title={t("components.settings.clash.port.actions.random")}
title={t("settings.clash.port.actions.random")}
disabled={!httpEnabled}
sx={{ mr: 0.5 }}
>
@@ -272,7 +272,7 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
{OS !== "windows" && (
<ListItem sx={{ padding: "4px 0", minHeight: 36 }}>
<ListItemText
primary={t("components.settings.clash.port.fields.redir")}
primary={t("settings.clash.port.fields.redir")}
slotProps={{ primary: { sx: { fontSize: 12 } } }}
/>
<div style={{ display: "flex", alignItems: "center" }}>
@@ -289,7 +289,7 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
<IconButton
size="small"
onClick={() => setRedirPort(generateRandomPort())}
title={t("components.settings.clash.port.actions.random")}
title={t("settings.clash.port.actions.random")}
disabled={!redirEnabled}
sx={{ mr: 0.5 }}
>
@@ -308,7 +308,7 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
{OS === "linux" && (
<ListItem sx={{ padding: "4px 0", minHeight: 36 }}>
<ListItemText
primary={t("components.settings.clash.port.fields.tproxy")}
primary={t("settings.clash.port.fields.tproxy")}
slotProps={{ primary: { sx: { fontSize: 12 } } }}
/>
<div style={{ display: "flex", alignItems: "center" }}>
@@ -325,7 +325,7 @@ export const ClashPortViewer = forwardRef<ClashPortViewerRef>((_, ref) => {
<IconButton
size="small"
onClick={() => setTproxyPort(generateRandomPort())}
title={t("components.settings.clash.port.actions.random")}
title={t("settings.clash.port.actions.random")}
disabled={!tproxyEnabled}
sx={{ mr: 0.5 }}
>

View File

@@ -57,14 +57,14 @@ export function ControllerViewer({ ref }: { ref?: Ref<DialogRef> }) {
if (enableController) {
if (!controller.trim()) {
showNotice.error(
"components.settings.externalController.messages.addressRequired",
"settings.externalController.messages.addressRequired",
);
return;
}
if (!secret.trim()) {
showNotice.error(
"components.settings.externalController.messages.secretRequired",
"settings.externalController.messages.secretRequired",
);
return;
}
@@ -93,9 +93,7 @@ export function ControllerViewer({ ref }: { ref?: Ref<DialogRef> }) {
setTimeout(() => setCopySuccess(null));
} catch (err) {
console.warn("[ControllerViewer] copy to clipboard failed:", err);
showNotice.error(
"components.settings.externalController.messages.copyFailed",
);
showNotice.error("settings.externalController.messages.copyFailed");
}
},
);
@@ -103,7 +101,7 @@ export function ControllerViewer({ ref }: { ref?: Ref<DialogRef> }) {
return (
<BaseDialog
open={open}
title={t("components.settings.externalController.title")}
title={t("settings.externalController.title")}
contentSx={{ width: 400 }}
okBtn={
isSaving ? (
@@ -129,7 +127,7 @@ export function ControllerViewer({ ref }: { ref?: Ref<DialogRef> }) {
}}
>
<ListItemText
primary={t("components.settings.externalController.fields.enable")}
primary={t("settings.externalController.fields.enable")}
/>
<Switch
edge="end"
@@ -147,7 +145,7 @@ export function ControllerViewer({ ref }: { ref?: Ref<DialogRef> }) {
}}
>
<ListItemText
primary={t("components.settings.externalController.fields.address")}
primary={t("settings.externalController.fields.address")}
/>
<Box display="flex" alignItems="center" gap={1}>
<TextField
@@ -159,14 +157,12 @@ export function ControllerViewer({ ref }: { ref?: Ref<DialogRef> }) {
}}
value={controller}
placeholder={t(
"components.settings.externalController.placeholders.address",
"settings.externalController.placeholders.address",
)}
onChange={(e) => setController(e.target.value)}
disabled={isSaving || !enableController}
/>
<Tooltip
title={t("components.settings.externalController.tooltips.copy")}
>
<Tooltip title={t("settings.externalController.tooltips.copy")}>
<IconButton
size="small"
onClick={() => handleCopyToClipboard(controller, "controller")}
@@ -187,7 +183,7 @@ export function ControllerViewer({ ref }: { ref?: Ref<DialogRef> }) {
}}
>
<ListItemText
primary={t("components.settings.externalController.fields.secret")}
primary={t("settings.externalController.fields.secret")}
/>
<Box display="flex" alignItems="center" gap={1}>
<TextField
@@ -198,15 +194,11 @@ export function ControllerViewer({ ref }: { ref?: Ref<DialogRef> }) {
pointerEvents: enableController ? "auto" : "none",
}}
value={secret}
placeholder={t(
"components.settings.externalController.placeholders.secret",
)}
placeholder={t("settings.externalController.placeholders.secret")}
onChange={(e) => setSecret(e.target.value)}
disabled={isSaving || !enableController}
/>
<Tooltip
title={t("components.settings.externalController.tooltips.copy")}
>
<Tooltip title={t("settings.externalController.tooltips.copy")}>
<IconButton
size="small"
onClick={() => handleCopyToClipboard(secret, "secret")}
@@ -227,10 +219,8 @@ export function ControllerViewer({ ref }: { ref?: Ref<DialogRef> }) {
>
<Alert severity="success">
{copySuccess === "controller"
? t(
"components.settings.externalController.messages.controllerCopied",
)
: t("components.settings.externalController.messages.secretCopied")}
? t("settings.externalController.messages.controllerCopied")
: t("settings.externalController.messages.secretCopied")}
</Alert>
</Snackbar>
</BaseDialog>

View File

@@ -509,7 +509,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
// 使用YAML编辑器的值
const parsedConfig = yaml.load(yamlContent);
if (typeof parsedConfig !== "object" || parsedConfig === null) {
throw new Error(t("components.settings.dns.errors.invalid"));
throw new Error(t("settings.dns.errors.invalid"));
}
config = parsedConfig as Record<string, any>;
}
@@ -547,10 +547,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
}
}
showNotice.error(
"components.settings.dns.messages.configError",
cleanErrorMsg,
);
showNotice.error("settings.dns.messages.configError", cleanErrorMsg);
return;
}
@@ -561,7 +558,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
}
setOpen(false);
showNotice.success("components.settings.dns.messages.saved");
showNotice.success("settings.dns.messages.saved");
} catch (err) {
showNotice.error(err);
}
@@ -613,7 +610,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
open={open}
title={
<Box display="flex" justifyContent="space-between" alignItems="center">
{t("components.settings.dns.dialog.title")}
{t("settings.dns.dialog.title")}
<Box display="flex" alignItems="center" gap={1}>
<Button
variant="outlined"
@@ -657,7 +654,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
color="warning.main"
sx={{ mb: 2, mt: 0, fontStyle: "italic" }}
>
{t("components.settings.dns.dialog.warning")}
{t("settings.dns.dialog.warning")}
</Typography>
{visualization ? (
@@ -666,13 +663,11 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
variant="subtitle1"
sx={{ mt: 1, mb: 1, fontWeight: "bold" }}
>
{t("components.settings.dns.sections.general")}
{t("settings.dns.sections.general")}
</Typography>
<Item>
<ListItemText
primary={t("components.settings.dns.fields.enable")}
/>
<ListItemText primary={t("settings.dns.fields.enable")} />
<Switch
edge="end"
checked={values.enable}
@@ -681,9 +676,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
</Item>
<Item>
<ListItemText
primary={t("components.settings.dns.fields.listen")}
/>
<ListItemText primary={t("settings.dns.fields.listen")} />
<TextField
size="small"
autoComplete="off"
@@ -695,9 +688,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
</Item>
<Item>
<ListItemText
primary={t("components.settings.dns.fields.enhancedMode")}
/>
<ListItemText primary={t("settings.dns.fields.enhancedMode")} />
<FormControl size="small" sx={{ width: 150 }}>
<Select
value={values.enhancedMode}
@@ -710,9 +701,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
</Item>
<Item>
<ListItemText
primary={t("components.settings.dns.fields.fakeIpRange")}
/>
<ListItemText primary={t("settings.dns.fields.fakeIpRange")} />
<TextField
size="small"
autoComplete="off"
@@ -724,9 +713,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
</Item>
<Item>
<ListItemText
primary={t("components.settings.dns.fields.fakeIpFilterMode")}
/>
<ListItemText primary={t("settings.dns.fields.fakeIpFilterMode")} />
<FormControl size="small" sx={{ width: 150 }}>
<Select
value={values.fakeIpFilterMode}
@@ -740,8 +727,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item>
<ListItemText
primary={t("components.settings.dns.fields.ipv6.label")}
secondary={t("components.settings.dns.fields.ipv6.description")}
primary={t("settings.dns.fields.ipv6.label")}
secondary={t("settings.dns.fields.ipv6.description")}
/>
<Switch
edge="end"
@@ -752,10 +739,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item>
<ListItemText
primary={t("components.settings.dns.fields.preferH3.label")}
secondary={t(
"components.settings.dns.fields.preferH3.description",
)}
primary={t("settings.dns.fields.preferH3.label")}
secondary={t("settings.dns.fields.preferH3.description")}
/>
<Switch
edge="end"
@@ -766,10 +751,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item>
<ListItemText
primary={t("components.settings.dns.fields.respectRules.label")}
secondary={t(
"components.settings.dns.fields.respectRules.description",
)}
primary={t("settings.dns.fields.respectRules.label")}
secondary={t("settings.dns.fields.respectRules.description")}
/>
<Switch
edge="end"
@@ -780,10 +763,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item>
<ListItemText
primary={t("components.settings.dns.fields.useHosts.label")}
secondary={t(
"components.settings.dns.fields.useHosts.description",
)}
primary={t("settings.dns.fields.useHosts.label")}
secondary={t("settings.dns.fields.useHosts.description")}
/>
<Switch
edge="end"
@@ -794,10 +775,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item>
<ListItemText
primary={t("components.settings.dns.fields.useSystemHosts.label")}
secondary={t(
"components.settings.dns.fields.useSystemHosts.description",
)}
primary={t("settings.dns.fields.useSystemHosts.label")}
secondary={t("settings.dns.fields.useSystemHosts.description")}
/>
<Switch
edge="end"
@@ -808,10 +787,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item>
<ListItemText
primary={t("components.settings.dns.fields.directPolicy.label")}
secondary={t(
"components.settings.dns.fields.directPolicy.description",
)}
primary={t("settings.dns.fields.directPolicy.label")}
secondary={t("settings.dns.fields.directPolicy.description")}
/>
<Switch
edge="end"
@@ -822,12 +799,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item sx={{ flexDirection: "column", alignItems: "flex-start" }}>
<ListItemText
primary={t(
"components.settings.dns.fields.defaultNameserver.label",
)}
secondary={t(
"components.settings.dns.fields.defaultNameserver.description",
)}
primary={t("settings.dns.fields.defaultNameserver.label")}
secondary={t("settings.dns.fields.defaultNameserver.description")}
/>
<TextField
fullWidth
@@ -843,10 +816,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item sx={{ flexDirection: "column", alignItems: "flex-start" }}>
<ListItemText
primary={t("components.settings.dns.fields.nameserver.label")}
secondary={t(
"components.settings.dns.fields.nameserver.description",
)}
primary={t("settings.dns.fields.nameserver.label")}
secondary={t("settings.dns.fields.nameserver.description")}
/>
<TextField
fullWidth
@@ -862,10 +833,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item sx={{ flexDirection: "column", alignItems: "flex-start" }}>
<ListItemText
primary={t("components.settings.dns.fields.fallback.label")}
secondary={t(
"components.settings.dns.fields.fallback.description",
)}
primary={t("settings.dns.fields.fallback.label")}
secondary={t("settings.dns.fields.fallback.description")}
/>
<TextField
fullWidth
@@ -881,8 +850,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item sx={{ flexDirection: "column", alignItems: "flex-start" }}>
<ListItemText
primary={t("components.settings.dns.fields.proxy.label")}
secondary={t("components.settings.dns.fields.proxy.description")}
primary={t("settings.dns.fields.proxy.label")}
secondary={t("settings.dns.fields.proxy.description")}
/>
<TextField
fullWidth
@@ -898,12 +867,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item sx={{ flexDirection: "column", alignItems: "flex-start" }}>
<ListItemText
primary={t(
"components.settings.dns.fields.directNameserver.label",
)}
secondary={t(
"components.settings.dns.fields.directNameserver.description",
)}
primary={t("settings.dns.fields.directNameserver.label")}
secondary={t("settings.dns.fields.directNameserver.description")}
/>
<TextField
fullWidth
@@ -919,10 +884,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item sx={{ flexDirection: "column", alignItems: "flex-start" }}>
<ListItemText
primary={t("components.settings.dns.fields.fakeIpFilter.label")}
secondary={t(
"components.settings.dns.fields.fakeIpFilter.description",
)}
primary={t("settings.dns.fields.fakeIpFilter.label")}
secondary={t("settings.dns.fields.fakeIpFilter.description")}
/>
<TextField
fullWidth
@@ -938,12 +901,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item sx={{ flexDirection: "column", alignItems: "flex-start" }}>
<ListItemText
primary={t(
"components.settings.dns.fields.nameserverPolicy.label",
)}
secondary={t(
"components.settings.dns.fields.nameserverPolicy.description",
)}
primary={t("settings.dns.fields.nameserverPolicy.label")}
secondary={t("settings.dns.fields.nameserverPolicy.description")}
/>
<TextField
fullWidth
@@ -961,15 +920,13 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
variant="subtitle2"
sx={{ mt: 2, mb: 1, fontWeight: "bold" }}
>
{t("components.settings.dns.sections.fallbackFilter")}
{t("settings.dns.sections.fallbackFilter")}
</Typography>
<Item>
<ListItemText
primary={t("components.settings.dns.fields.geoipFiltering.label")}
secondary={t(
"components.settings.dns.fields.geoipFiltering.description",
)}
primary={t("settings.dns.fields.geoipFiltering.label")}
secondary={t("settings.dns.fields.geoipFiltering.description")}
/>
<Switch
edge="end"
@@ -979,9 +936,7 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
</Item>
<Item>
<ListItemText
primary={t("components.settings.dns.fields.geoipCode")}
/>
<ListItemText primary={t("settings.dns.fields.geoipCode")} />
<TextField
size="small"
autoComplete="off"
@@ -994,10 +949,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item sx={{ flexDirection: "column", alignItems: "flex-start" }}>
<ListItemText
primary={t("components.settings.dns.fields.fallbackIpCidr.label")}
secondary={t(
"components.settings.dns.fields.fallbackIpCidr.description",
)}
primary={t("settings.dns.fields.fallbackIpCidr.label")}
secondary={t("settings.dns.fields.fallbackIpCidr.description")}
/>
<TextField
fullWidth
@@ -1013,10 +966,8 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
<Item sx={{ flexDirection: "column", alignItems: "flex-start" }}>
<ListItemText
primary={t("components.settings.dns.fields.fallbackDomain.label")}
secondary={t(
"components.settings.dns.fields.fallbackDomain.description",
)}
primary={t("settings.dns.fields.fallbackDomain.label")}
secondary={t("settings.dns.fields.fallbackDomain.description")}
/>
<TextField
fullWidth
@@ -1035,13 +986,13 @@ export function DnsViewer({ ref }: { ref?: Ref<DialogRef> }) {
variant="subtitle1"
sx={{ mt: 3, mb: 0, fontWeight: "bold" }}
>
{t("components.settings.dns.sections.hosts")}
{t("settings.dns.sections.hosts")}
</Typography>
<Item sx={{ flexDirection: "column", alignItems: "flex-start" }}>
<ListItemText
primary={t("components.settings.dns.fields.hosts.label")}
secondary={t("components.settings.dns.fields.hosts.description")}
primary={t("settings.dns.fields.hosts.label")}
secondary={t("settings.dns.fields.hosts.description")}
/>
<TextField
fullWidth

View File

@@ -181,7 +181,7 @@ export const HeaderConfiguration = forwardRef<ClashHeaderConfigingRef>(
return (
<BaseDialog
open={open}
title={t("components.settings.externalCors.title")}
title={t("settings.externalCors.title")}
contentSx={{ width: 500 }}
okBtn={loading ? t("Saving...") : t("Save")}
cancelBtn={t("Cancel")}
@@ -198,9 +198,7 @@ export const HeaderConfiguration = forwardRef<ClashHeaderConfigingRef>(
width="100%"
>
<span style={{ fontWeight: "normal" }}>
{t(
"components.settings.externalCors.fields.allowPrivateNetwork",
)}
{t("settings.externalCors.fields.allowPrivateNetwork")}
</span>
<Switch
edge="end"
@@ -220,7 +218,7 @@ export const HeaderConfiguration = forwardRef<ClashHeaderConfigingRef>(
<ListItem sx={{ padding: "8px 0" }}>
<div style={{ width: "100%" }}>
<div style={{ marginBottom: 8, fontWeight: "bold" }}>
{t("components.settings.externalCors.fields.allowedOrigins")}
{t("settings.externalCors.fields.allowedOrigins")}
</div>
{originEntries.map(({ origin, index, key }) => (
<div
@@ -237,9 +235,7 @@ export const HeaderConfiguration = forwardRef<ClashHeaderConfigingRef>(
sx={{ fontSize: 14, marginRight: 2 }}
value={origin}
onChange={(e) => handleUpdateOrigin(index, e.target.value)}
placeholder={t(
"components.settings.externalCors.placeholders.origin",
)}
placeholder={t("settings.externalCors.placeholders.origin")}
inputProps={{ style: { fontSize: 14 } }}
/>
<Button
@@ -260,7 +256,7 @@ export const HeaderConfiguration = forwardRef<ClashHeaderConfigingRef>(
onClick={handleAddOrigin}
sx={addButtonStyle}
>
{t("components.settings.externalCors.actions.add")}
{t("settings.externalCors.actions.add")}
</Button>
<div
@@ -274,12 +270,9 @@ export const HeaderConfiguration = forwardRef<ClashHeaderConfigingRef>(
<div
style={{ color: "#666", fontSize: 12, fontStyle: "italic" }}
>
{t(
"components.settings.externalCors.messages.alwaysIncluded",
{
urls: DEV_URLS.join(", "),
},
)}
{t("settings.externalCors.messages.alwaysIncluded", {
urls: DEV_URLS.join(", "),
})}
</div>
</div>
</div>

View File

@@ -113,7 +113,7 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
return (
<BaseDialog
open={open}
title={t("components.settings.verge.layout.title")}
title={t("settings.verge.layout.title")}
contentSx={{ width: 450 }}
disableOk
cancelBtn={t("Close")}
@@ -123,9 +123,7 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
<List>
<Item>
<ListItemText
primary={t(
"components.settings.verge.layout.fields.preferSystemTitlebar",
)}
primary={t("settings.verge.layout.fields.preferSystemTitlebar")}
/>
<GuardState
value={decorated}
@@ -142,7 +140,7 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
<Item>
<ListItemText
primary={t("components.settings.verge.layout.fields.trafficGraph")}
primary={t("settings.verge.layout.fields.trafficGraph")}
/>
<GuardState
value={verge?.traffic_graph ?? true}
@@ -158,7 +156,7 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
<Item>
<ListItemText
primary={t("components.settings.verge.layout.fields.memoryUsage")}
primary={t("settings.verge.layout.fields.memoryUsage")}
/>
<GuardState
value={verge?.enable_memory_usage ?? true}
@@ -174,9 +172,7 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
<Item>
<ListItemText
primary={t(
"components.settings.verge.layout.fields.proxyGroupIcon",
)}
primary={t("settings.verge.layout.fields.proxyGroupIcon")}
/>
<GuardState
value={verge?.enable_group_icon ?? true}
@@ -194,13 +190,9 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
<ListItemText
primary={
<Box sx={{ display: "flex", alignItems: "center", gap: 0.5 }}>
<span>
{t("components.settings.verge.layout.fields.hoverNavigator")}
</span>
<span>{t("settings.verge.layout.fields.hoverNavigator")}</span>
<TooltipIcon
title={t(
"components.settings.verge.layout.tooltips.hoverNavigator",
)}
title={t("settings.verge.layout.tooltips.hoverNavigator")}
sx={{ opacity: "0.7" }}
/>
</Box>
@@ -223,13 +215,11 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
primary={
<Box sx={{ display: "flex", alignItems: "center", gap: 0.5 }}>
<span>
{t(
"components.settings.verge.layout.fields.hoverNavigatorDelay",
)}
{t("settings.verge.layout.fields.hoverNavigatorDelay")}
</span>
<TooltipIcon
title={t(
"components.settings.verge.layout.tooltips.hoverNavigatorDelay",
"settings.verge.layout.tooltips.hoverNavigatorDelay",
)}
sx={{ opacity: "0.7" }}
/>
@@ -278,9 +268,7 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
</Item>
<Item>
<ListItemText
primary={t("components.settings.verge.layout.fields.navIcon")}
/>
<ListItemText primary={t("settings.verge.layout.fields.navIcon")} />
<GuardState
value={verge?.menu_icon ?? "monochrome"}
onCatch={onError}
@@ -290,13 +278,13 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
>
<Select size="small" sx={{ width: 140, "> div": { py: "7.5px" } }}>
<MenuItem value="monochrome">
{t("components.settings.verge.layout.options.icon.monochrome")}
{t("settings.verge.layout.options.icon.monochrome")}
</MenuItem>
<MenuItem value="colorful">
{t("components.settings.verge.layout.options.icon.colorful")}
{t("settings.verge.layout.options.icon.colorful")}
</MenuItem>
<MenuItem value="disable">
{t("components.settings.verge.layout.options.icon.disable")}
{t("settings.verge.layout.options.icon.disable")}
</MenuItem>
</Select>
</GuardState>
@@ -305,7 +293,7 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
{OS === "macos" && (
<Item>
<ListItemText
primary={t("components.settings.verge.layout.fields.trayIcon")}
primary={t("settings.verge.layout.fields.trayIcon")}
/>
<GuardState
value={verge?.tray_icon ?? "monochrome"}
@@ -319,12 +307,10 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
sx={{ width: 140, "> div": { py: "7.5px" } }}
>
<MenuItem value="monochrome">
{t(
"components.settings.verge.layout.options.icon.monochrome",
)}
{t("settings.verge.layout.options.icon.monochrome")}
</MenuItem>
<MenuItem value="colorful">
{t("components.settings.verge.layout.options.icon.colorful")}
{t("settings.verge.layout.options.icon.colorful")}
</MenuItem>
</Select>
</GuardState>
@@ -367,9 +353,7 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
)} */}
<Item>
<ListItemText
primary={t(
"components.settings.verge.layout.fields.showProxyGroupsInline",
)}
primary={t("settings.verge.layout.fields.showProxyGroupsInline")}
/>
<GuardState
value={verge?.tray_inline_proxy_groups ?? false}
@@ -385,9 +369,7 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
<Item>
<ListItemText
primary={t(
"components.settings.verge.layout.fields.commonTrayIcon",
)}
primary={t("settings.verge.layout.fields.commonTrayIcon")}
/>
<GuardState
value={verge?.common_tray_icon}
@@ -431,17 +413,15 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
}}
>
{verge?.common_tray_icon
? t("components.settings.verge.basic.actions.clear")
: t("components.settings.verge.basic.actions.browse")}
? t("settings.verge.basic.actions.clear")
: t("settings.verge.basic.actions.browse")}
</Button>
</GuardState>
</Item>
<Item>
<ListItemText
primary={t(
"components.settings.verge.layout.fields.systemProxyTrayIcon",
)}
primary={t("settings.verge.layout.fields.systemProxyTrayIcon")}
/>
<GuardState
value={verge?.sysproxy_tray_icon}
@@ -483,15 +463,15 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
}}
>
{verge?.sysproxy_tray_icon
? t("components.settings.verge.basic.actions.clear")
: t("components.settings.verge.basic.actions.browse")}
? t("settings.verge.basic.actions.clear")
: t("settings.verge.basic.actions.browse")}
</Button>
</GuardState>
</Item>
<Item>
<ListItemText
primary={t("components.settings.verge.layout.fields.tunTrayIcon")}
primary={t("settings.verge.layout.fields.tunTrayIcon")}
/>
<GuardState
value={verge?.tun_tray_icon}
@@ -531,8 +511,8 @@ export const LayoutViewer = forwardRef<DialogRef>((_, ref) => {
}}
>
{verge?.tun_tray_icon
? t("components.settings.verge.basic.actions.clear")
: t("components.settings.verge.basic.actions.browse")}
? t("settings.verge.basic.actions.clear")
: t("settings.verge.basic.actions.browse")}
</Button>
</GuardState>
</Item>

View File

@@ -53,7 +53,7 @@ export function LiteModeViewer({ ref }: { ref?: Ref<DialogRef> }) {
return (
<BaseDialog
open={open}
title={t("components.settings.liteMode.title")}
title={t("settings.liteMode.title")}
contentSx={{ width: 450 }}
okBtn={t("Save")}
cancelBtn={t("Cancel")}
@@ -63,9 +63,7 @@ export function LiteModeViewer({ ref }: { ref?: Ref<DialogRef> }) {
>
<List>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.liteMode.actions.enterNow")}
/>
<ListItemText primary={t("settings.liteMode.actions.enterNow")} />
<Typography
variant="button"
sx={{
@@ -81,11 +79,11 @@ export function LiteModeViewer({ ref }: { ref?: Ref<DialogRef> }) {
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.liteMode.toggles.autoEnter")}
primary={t("settings.liteMode.toggles.autoEnter")}
sx={{ maxWidth: "fit-content" }}
/>
<TooltipIcon
title={t("components.settings.liteMode.tooltips.autoEnter")}
title={t("settings.liteMode.tooltips.autoEnter")}
sx={{ opacity: "0.7" }}
/>
<Switch
@@ -101,9 +99,7 @@ export function LiteModeViewer({ ref }: { ref?: Ref<DialogRef> }) {
{values.autoEnterLiteMode && (
<>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.liteMode.fields.delay")}
/>
<ListItemText primary={t("settings.liteMode.fields.delay")} />
<TextField
autoComplete="off"
size="small"
@@ -137,7 +133,7 @@ export function LiteModeViewer({ ref }: { ref?: Ref<DialogRef> }) {
color="text.secondary"
sx={{ fontStyle: "italic" }}
>
{t("components.settings.liteMode.messages.autoEnterHint", {
{t("settings.liteMode.messages.autoEnterHint", {
n: values.autoEnterLiteModeDelay,
})}
</Typography>

View File

@@ -20,15 +20,11 @@ export const LocalBackupActions = memo(
try {
setLoading(true);
await createLocalBackup();
showNotice.success(
"components.settings.backup.messages.localBackupCreated",
);
showNotice.success("settings.backup.messages.localBackupCreated");
await onBackupSuccess();
} catch (error) {
console.error(error);
showNotice.error(
"components.settings.backup.messages.localBackupFailed",
);
showNotice.error("settings.backup.messages.localBackupFailed");
} finally {
setLoading(false);
}
@@ -47,7 +43,7 @@ export const LocalBackupActions = memo(
<Grid container spacing={2}>
<Grid size={{ xs: 12, sm: 9 }}>
<Typography variant="body2" color="text.secondary">
{t("components.settings.backup.fields.info")}
{t("settings.backup.fields.info")}
</Typography>
</Grid>
<Grid size={{ xs: 12, sm: 3 }}>
@@ -64,7 +60,7 @@ export const LocalBackupActions = memo(
type="button"
size="large"
>
{t("components.settings.backup.actions.backup")}
{t("settings.backup.actions.backup")}
</Button>
<Button
variant="outlined"
@@ -72,7 +68,7 @@ export const LocalBackupActions = memo(
type="button"
size="large"
>
{t("components.settings.backup.actions.refresh")}
{t("settings.backup.actions.refresh")}
</Button>
</Stack>
</Grid>

View File

@@ -77,7 +77,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
return (
<BaseDialog
open={open}
title={t("components.settings.misc.title")}
title={t("settings.misc.title")}
contentSx={{ width: 450 }}
okBtn={t("Save")}
cancelBtn={t("Cancel")}
@@ -87,9 +87,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
>
<List>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.misc.fields.appLogLevel")}
/>
<ListItemText primary={t("settings.misc.fields.appLogLevel")} />
<Select
size="small"
sx={{ width: 100, "> div": { py: "7.5px" } }}
@@ -111,7 +109,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.misc.fields.appLogMaxSize")}
primary={t("settings.misc.fields.appLogMaxSize")}
sx={{ maxWidth: "fit-content" }}
/>
<TextField
@@ -141,7 +139,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.misc.fields.appLogMaxCount")}
primary={t("settings.misc.fields.appLogMaxCount")}
sx={{ maxWidth: "fit-content" }}
/>
<TextField
@@ -171,11 +169,11 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.misc.fields.autoCloseConnections")}
primary={t("settings.misc.fields.autoCloseConnections")}
sx={{ maxWidth: "fit-content" }}
/>
<TooltipIcon
title={t("components.settings.misc.tooltips.autoCloseConnections")}
title={t("settings.misc.tooltips.autoCloseConnections")}
sx={{ opacity: "0.7" }}
/>
<Switch
@@ -189,9 +187,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.misc.fields.autoCheckUpdate")}
/>
<ListItemText primary={t("settings.misc.fields.autoCheckUpdate")} />
<Switch
edge="end"
checked={values.autoCheckUpdate}
@@ -203,11 +199,11 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.misc.fields.enableBuiltinEnhanced")}
primary={t("settings.misc.fields.enableBuiltinEnhanced")}
sx={{ maxWidth: "fit-content" }}
/>
<TooltipIcon
title={t("components.settings.misc.tooltips.enableBuiltinEnhanced")}
title={t("settings.misc.tooltips.enableBuiltinEnhanced")}
sx={{ opacity: "0.7" }}
/>
<Switch
@@ -222,7 +218,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.misc.fields.proxyLayoutColumns")}
primary={t("settings.misc.fields.proxyLayoutColumns")}
/>
<Select
size="small"
@@ -236,7 +232,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
}
>
<MenuItem value={6} key={6}>
{t("components.settings.misc.options.proxyLayoutColumns.auto")}
{t("settings.misc.options.proxyLayoutColumns.auto")}
</MenuItem>
{[1, 2, 3, 4, 5].map((i) => (
<MenuItem value={i} key={i}>
@@ -247,9 +243,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.misc.fields.autoLogClean")}
/>
<ListItemText primary={t("settings.misc.fields.autoLogClean")} />
<Select
size="small"
sx={{ width: 160, "> div": { py: "7.5px" } }}
@@ -264,35 +258,31 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
{/* 1: 1天, 2: 7天, 3: 30天, 4: 90天*/}
{[
{
key: t("components.settings.misc.options.autoLogClean.never"),
key: t("settings.misc.options.autoLogClean.never"),
value: 0,
},
{
key: t(
"components.settings.misc.options.autoLogClean.retainDays",
{ n: 1 },
),
key: t("settings.misc.options.autoLogClean.retainDays", {
n: 1,
}),
value: 1,
},
{
key: t(
"components.settings.misc.options.autoLogClean.retainDays",
{ n: 7 },
),
key: t("settings.misc.options.autoLogClean.retainDays", {
n: 7,
}),
value: 2,
},
{
key: t(
"components.settings.misc.options.autoLogClean.retainDays",
{ n: 30 },
),
key: t("settings.misc.options.autoLogClean.retainDays", {
n: 30,
}),
value: 3,
},
{
key: t(
"components.settings.misc.options.autoLogClean.retainDays",
{ n: 90 },
),
key: t("settings.misc.options.autoLogClean.retainDays", {
n: 90,
}),
value: 4,
},
].map((i) => (
@@ -305,11 +295,11 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.misc.fields.autoDelayDetection")}
primary={t("settings.misc.fields.autoDelayDetection")}
sx={{ maxWidth: "fit-content" }}
/>
<TooltipIcon
title={t("components.settings.misc.tooltips.autoDelayDetection")}
title={t("settings.misc.tooltips.autoDelayDetection")}
sx={{ opacity: "0.7" }}
/>
<Switch
@@ -324,11 +314,11 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.misc.fields.defaultLatencyTest")}
primary={t("settings.misc.fields.defaultLatencyTest")}
sx={{ maxWidth: "fit-content" }}
/>
<TooltipIcon
title={t("components.settings.misc.tooltips.defaultLatencyTest")}
title={t("settings.misc.tooltips.defaultLatencyTest")}
sx={{ opacity: "0.7" }}
/>
<TextField
@@ -348,7 +338,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.misc.fields.defaultLatencyTimeout")}
primary={t("settings.misc.fields.defaultLatencyTimeout")}
/>
<TextField
autoComplete="new-password"

View File

@@ -277,13 +277,11 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
const onSave = useLockFn(async () => {
if (value.duration < 1) {
showNotice.error(
"components.settings.sysproxy.messages.durationTooShort",
);
showNotice.error("settings.sysproxy.messages.durationTooShort");
return;
}
if (value.bypass && !validReg.test(value.bypass)) {
showNotice.error("components.settings.sysproxy.messages.invalidBypass");
showNotice.error("settings.sysproxy.messages.invalidBypass");
return;
}
@@ -300,9 +298,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
!ipv6Regex.test(value.proxy_host) &&
!hostnameRegex.test(value.proxy_host)
) {
showNotice.error(
"components.settings.sysproxy.messages.invalidProxyHost",
);
showNotice.error("settings.sysproxy.messages.invalidProxyHost");
return;
}
@@ -414,7 +410,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
return (
<BaseDialog
open={open}
title={t("components.settings.sysproxy.title")}
title={t("settings.sysproxy.title")}
contentSx={{ width: 450, maxHeight: 565 }}
okBtn={t("Save")}
cancelBtn={t("Cancel")}
@@ -426,12 +422,12 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
>
<List>
<BaseFieldset
label={t("components.settings.sysproxy.fieldsets.currentStatus")}
label={t("settings.sysproxy.fieldsets.currentStatus")}
padding="15px 10px"
>
<FlexBox>
<Typography className="label">
{t("components.settings.sysproxy.fields.enableStatus")}
{t("settings.sysproxy.fields.enableStatus")}
</Typography>
<Typography className="value">
{value.pac
@@ -446,7 +442,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
{!value.pac && (
<FlexBox>
<Typography className="label">
{t("components.settings.sysproxy.fields.serverAddr")}
{t("settings.sysproxy.fields.serverAddr")}
</Typography>
<Typography className="value">{getSystemProxyAddress}</Typography>
</FlexBox>
@@ -454,7 +450,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
{value.pac && (
<FlexBox>
<Typography className="label">
{t("components.settings.sysproxy.fields.pacUrl")}
{t("settings.sysproxy.fields.pacUrl")}
</Typography>
<Typography className="value">
{getCurrentPacUrl || "-"}
@@ -463,9 +459,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
)}
</BaseFieldset>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.sysproxy.fields.proxyHost")}
/>
<ListItemText primary={t("settings.sysproxy.fields.proxyHost")} />
<Autocomplete
size="small"
sx={{ width: 150 }}
@@ -490,9 +484,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
/>
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.sysproxy.fields.usePacMode")}
/>
<ListItemText primary={t("settings.sysproxy.fields.usePacMode")} />
<Switch
edge="end"
disabled={!enabled}
@@ -503,11 +495,11 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.sysproxy.fields.proxyGuard")}
primary={t("settings.sysproxy.fields.proxyGuard")}
sx={{ maxWidth: "fit-content" }}
/>
<TooltipIcon
title={t("components.settings.sysproxy.tooltips.proxyGuard")}
title={t("settings.sysproxy.tooltips.proxyGuard")}
sx={{ opacity: "0.7" }}
/>
<Switch
@@ -520,9 +512,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.sysproxy.fields.guardDuration")}
/>
<ListItemText primary={t("settings.sysproxy.fields.guardDuration")} />
<TextField
disabled={!enabled}
size="small"
@@ -544,9 +534,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
{!value.pac && (
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t(
"components.settings.sysproxy.fields.alwaysUseDefaultBypass",
)}
primary={t("settings.sysproxy.fields.alwaysUseDefaultBypass")}
/>
<Switch
edge="end"
@@ -566,9 +554,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
{!value.pac && !value.use_default && (
<>
<ListItemText
primary={t("components.settings.sysproxy.fields.proxyBypass")}
/>
<ListItemText primary={t("settings.sysproxy.fields.proxyBypass")} />
<TextField
error={value.bypass ? !validReg.test(value.bypass) : false}
disabled={!enabled}
@@ -586,9 +572,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
{!value.pac && value.use_default && (
<>
<ListItemText
primary={t("components.settings.sysproxy.fields.bypass")}
/>
<ListItemText primary={t("settings.sysproxy.fields.bypass")} />
<FlexBox>
<TextField
disabled={true}
@@ -605,9 +589,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
{value.pac && (
<ListItem sx={{ padding: "5px 2px", alignItems: "start" }}>
<ListItemText
primary={t(
"components.settings.sysproxy.fields.pacScriptContent",
)}
primary={t("settings.sysproxy.fields.pacScriptContent")}
sx={{ padding: "3px 0" }}
/>
<Button
@@ -617,12 +599,12 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
setEditorOpen(true);
}}
>
{t("components.settings.sysproxy.actions.editPac")}
{t("settings.sysproxy.actions.editPac")}
</Button>
{editorOpen && (
<EditorViewer
open={true}
title={t("components.settings.sysproxy.actions.editPac")}
title={t("settings.sysproxy.actions.editPac")}
initialData={Promise.resolve(value.pac_content ?? "")}
language="javascript"
onSave={(_prev, curr) => {

View File

@@ -65,35 +65,35 @@ export function ThemeViewer(props: { ref?: React.Ref<DialogRef> }) {
const fieldDefinitions: Array<{ labelKey: string; key: ThemeKey }> = useMemo(
() => [
{
labelKey: "components.settings.verge.theme.fields.primaryColor",
labelKey: "settings.verge.theme.fields.primaryColor",
key: "primary_color",
},
{
labelKey: "components.settings.verge.theme.fields.secondaryColor",
labelKey: "settings.verge.theme.fields.secondaryColor",
key: "secondary_color",
},
{
labelKey: "components.settings.verge.theme.fields.primaryText",
labelKey: "settings.verge.theme.fields.primaryText",
key: "primary_text",
},
{
labelKey: "components.settings.verge.theme.fields.secondaryText",
labelKey: "settings.verge.theme.fields.secondaryText",
key: "secondary_text",
},
{
labelKey: "components.settings.verge.theme.fields.infoColor",
labelKey: "settings.verge.theme.fields.infoColor",
key: "info_color",
},
{
labelKey: "components.settings.verge.theme.fields.warningColor",
labelKey: "settings.verge.theme.fields.warningColor",
key: "warning_color",
},
{
labelKey: "components.settings.verge.theme.fields.errorColor",
labelKey: "settings.verge.theme.fields.errorColor",
key: "error_color",
},
{
labelKey: "components.settings.verge.theme.fields.successColor",
labelKey: "settings.verge.theme.fields.successColor",
key: "success_color",
},
],
@@ -120,7 +120,7 @@ export function ThemeViewer(props: { ref?: React.Ref<DialogRef> }) {
return (
<BaseDialog
open={open}
title={t("components.settings.verge.theme.title")}
title={t("settings.verge.theme.title")}
okBtn={t("Save")}
cancelBtn={t("Cancel")}
contentSx={{ width: 400, maxHeight: 505, overflow: "auto", pb: 0 }}
@@ -132,9 +132,7 @@ export function ThemeViewer(props: { ref?: React.Ref<DialogRef> }) {
{fieldDefinitions.map((field) => renderItem(field.labelKey, field.key))}
<Item>
<ListItemText
primary={t("components.settings.verge.theme.fields.fontFamily")}
/>
<ListItemText primary={t("settings.verge.theme.fields.fontFamily")} />
<TextField
{...textProps}
value={theme.font_family ?? ""}
@@ -144,7 +142,7 @@ export function ThemeViewer(props: { ref?: React.Ref<DialogRef> }) {
</Item>
<Item>
<ListItemText
primary={t("components.settings.verge.theme.fields.cssInjection")}
primary={t("settings.verge.theme.fields.cssInjection")}
/>
<Button
startIcon={<EditRounded />}
@@ -153,12 +151,12 @@ export function ThemeViewer(props: { ref?: React.Ref<DialogRef> }) {
setEditorOpen(true);
}}
>
{t("components.settings.verge.theme.actions.editCss")}
{t("settings.verge.theme.actions.editCss")}
</Button>
{editorOpen && (
<EditorViewer
open={true}
title={t("components.settings.verge.theme.dialogs.editCssTitle")}
title={t("settings.verge.theme.dialogs.editCssTitle")}
initialData={Promise.resolve(theme.css_injection ?? "")}
language="css"
onSave={(_prev, curr) => {

View File

@@ -80,7 +80,7 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
);
try {
await enhanceProfiles();
showNotice.success("components.settings.tun.messages.applied");
showNotice.success("settings.tun.messages.applied");
} catch (err: any) {
showNotice.error(err);
}
@@ -95,9 +95,7 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
open={open}
title={
<Box display="flex" justifyContent="space-between" gap={1}>
<Typography variant="h6">
{t("components.settings.tun.title")}
</Typography>
<Typography variant="h6">{t("settings.tun.title")}</Typography>
<Button
variant="outlined"
size="small"
@@ -130,7 +128,7 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
);
}}
>
{t("components.settings.tun.actions.reset")}
{t("settings.tun.actions.reset")}
</Button>
</Box>
}
@@ -143,7 +141,7 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
>
<List>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText primary={t("components.settings.tun.fields.stack")} />
<ListItemText primary={t("settings.tun.fields.stack")} />
<StackModeSwitch
value={values.stack}
onChange={(value) => {
@@ -156,7 +154,7 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText primary={t("components.settings.tun.fields.device")} />
<ListItemText primary={t("settings.tun.fields.device")} />
<TextField
autoComplete="new-password"
size="small"
@@ -173,9 +171,7 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.tun.fields.autoRoute")}
/>
<ListItemText primary={t("settings.tun.fields.autoRoute")} />
<Switch
edge="end"
checked={values.autoRoute}
@@ -184,9 +180,7 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.tun.fields.strictRoute")}
/>
<ListItemText primary={t("settings.tun.fields.strictRoute")} />
<Switch
edge="end"
checked={values.strictRoute}
@@ -196,7 +190,7 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.tun.fields.autoDetectInterface")}
primary={t("settings.tun.fields.autoDetectInterface")}
/>
<Switch
edge="end"
@@ -208,9 +202,7 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText
primary={t("components.settings.tun.fields.dnsHijack")}
/>
<ListItemText primary={t("settings.tun.fields.dnsHijack")} />
<TextField
autoComplete="new-password"
size="small"
@@ -219,7 +211,7 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
spellCheck="false"
sx={{ width: 250 }}
value={values.dnsHijack.join(",")}
placeholder={t("components.settings.tun.tooltips.dnsHijack")}
placeholder={t("settings.tun.tooltips.dnsHijack")}
onChange={(e) =>
setValues((v) => ({ ...v, dnsHijack: e.target.value.split(",") }))
}
@@ -227,7 +219,7 @@ export function TunViewer({ ref }: { ref?: Ref<DialogRef> }) {
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText primary={t("components.settings.tun.fields.mtu")} />
<ListItemText primary={t("settings.tun.fields.mtu")} />
<TextField
autoComplete="new-password"
size="small"

View File

@@ -58,12 +58,12 @@ export function UpdateViewer({ ref }: { ref?: Ref<DialogRef> }) {
const onUpdate = useLockFn(async () => {
if (portableFlag) {
showNotice.error("components.settings.update.messages.portableError");
showNotice.error("settings.update.messages.portableError");
return;
}
if (!updateInfo?.body) return;
if (breakChangeFlag) {
showNotice.error("components.settings.update.messages.breakChangeError");
showNotice.error("settings.update.messages.breakChangeError");
return;
}
if (updateState) return;
@@ -113,7 +113,7 @@ export function UpdateViewer({ ref }: { ref?: Ref<DialogRef> }) {
open={open}
title={
<Box display="flex" justifyContent="space-between">
{t("components.settings.update.title", {
{t("settings.update.title", {
version: updateInfo?.version ?? "",
})}
<Box>
@@ -126,13 +126,13 @@ export function UpdateViewer({ ref }: { ref?: Ref<DialogRef> }) {
);
}}
>
{t("components.settings.update.actions.goToRelease")}
{t("settings.update.actions.goToRelease")}
</Button>
</Box>
</Box>
}
contentSx={{ minWidth: 360, maxWidth: 400, height: "50vh" }}
okBtn={t("components.settings.update.actions.update")}
okBtn={t("settings.update.actions.update")}
cancelBtn={t("Cancel")}
onClose={() => setOpen(false)}
onCancel={() => setOpen(false)}

View File

@@ -67,7 +67,7 @@ const SettingClash = ({ onError }: Props) => {
const onUpdateGeo = async () => {
try {
await updateGeo();
showNotice.success("components.settings.clash.messages.geoDataUpdated");
showNotice.success("settings.clash.messages.geoDataUpdated");
} catch (err: any) {
showNotice.error(err);
}
@@ -93,7 +93,7 @@ const SettingClash = ({ onError }: Props) => {
});
return (
<SettingList title={t("components.settings.clash.title")}>
<SettingList title={t("settings.clash.title")}>
<WebUIViewer ref={webRef} />
<ClashPortViewer ref={portRef} />
<ControllerViewer ref={ctrlRef} />
@@ -103,10 +103,10 @@ const SettingClash = ({ onError }: Props) => {
<HeaderConfiguration ref={corsRef} />
<SettingItem
label={t("components.settings.clash.items.allowLan")}
label={t("settings.clash.items.allowLan")}
extra={
<TooltipIcon
title={t("components.settings.clash.tooltips.networkInterface")}
title={t("settings.clash.tooltips.networkInterface")}
color={"inherit"}
icon={LanRounded}
onClick={() => {
@@ -128,7 +128,7 @@ const SettingClash = ({ onError }: Props) => {
</SettingItem>
<SettingItem
label={t("components.settings.clash.items.dnsOverwrite")}
label={t("settings.clash.items.dnsOverwrite")}
extra={
<TooltipIcon
icon={SettingsRounded}
@@ -143,7 +143,7 @@ const SettingClash = ({ onError }: Props) => {
/>
</SettingItem>
<SettingItem label={t("components.settings.clash.items.ipv6")}>
<SettingItem label={t("settings.clash.items.ipv6")}>
<GuardState
value={ipv6 ?? false}
valueProps="checked"
@@ -157,10 +157,10 @@ const SettingClash = ({ onError }: Props) => {
</SettingItem>
<SettingItem
label={t("components.settings.clash.items.unifiedDelay")}
label={t("settings.clash.items.unifiedDelay")}
extra={
<TooltipIcon
title={t("components.settings.clash.tooltips.unifiedDelay")}
title={t("settings.clash.tooltips.unifiedDelay")}
sx={{ opacity: "0.7" }}
/>
}
@@ -178,10 +178,10 @@ const SettingClash = ({ onError }: Props) => {
</SettingItem>
<SettingItem
label={t("components.settings.clash.items.logLevel")}
label={t("settings.clash.items.logLevel")}
extra={
<TooltipIcon
title={t("components.settings.clash.tooltips.logLevel")}
title={t("settings.clash.tooltips.logLevel")}
sx={{ opacity: "0.7" }}
/>
}
@@ -198,25 +198,25 @@ const SettingClash = ({ onError }: Props) => {
>
<Select size="small" sx={{ width: 100, "> div": { py: "7.5px" } }}>
<MenuItem value="debug">
{t("components.settings.clash.options.logLevel.debug")}
{t("settings.clash.options.logLevel.debug")}
</MenuItem>
<MenuItem value="info">
{t("components.settings.clash.options.logLevel.info")}
{t("settings.clash.options.logLevel.info")}
</MenuItem>
<MenuItem value="warning">
{t("components.settings.clash.options.logLevel.warning")}
{t("settings.clash.options.logLevel.warning")}
</MenuItem>
<MenuItem value="error">
{t("components.settings.clash.options.logLevel.error")}
{t("settings.clash.options.logLevel.error")}
</MenuItem>
<MenuItem value="silent">
{t("components.settings.clash.options.logLevel.silent")}
{t("settings.clash.options.logLevel.silent")}
</MenuItem>
</Select>
</GuardState>
</SettingItem>
<SettingItem label={t("components.settings.clash.items.portConfig")}>
<SettingItem label={t("settings.clash.items.portConfig")}>
<TextField
autoComplete="new-password"
disabled={false}
@@ -231,10 +231,10 @@ const SettingClash = ({ onError }: Props) => {
</SettingItem>
<SettingItem
label={t("components.settings.clash.items.external")}
label={t("settings.clash.items.external")}
extra={
<TooltipIcon
title={t("components.settings.externalCors.tooltips.open")}
title={t("settings.externalCors.tooltips.open")}
icon={SettingsRounded}
onClick={(e) => {
e.stopPropagation();
@@ -249,11 +249,11 @@ const SettingClash = ({ onError }: Props) => {
<SettingItem
onClick={() => webRef.current?.open()}
label={t("components.settings.clash.items.webUI")}
label={t("settings.clash.items.webUI")}
/>
<SettingItem
label={t("components.settings.clash.items.clashCore")}
label={t("settings.clash.items.clashCore")}
extra={
<TooltipIcon
icon={SettingsRounded}
@@ -267,10 +267,10 @@ const SettingClash = ({ onError }: Props) => {
{isWIN && (
<SettingItem
onClick={invoke_uwp_tool}
label={t("components.settings.clash.items.openUwpTool")}
label={t("settings.clash.items.openUwpTool")}
extra={
<TooltipIcon
title={t("components.settings.clash.tooltips.openUwpTool")}
title={t("settings.clash.tooltips.openUwpTool")}
sx={{ opacity: "0.7" }}
/>
}
@@ -279,7 +279,7 @@ const SettingClash = ({ onError }: Props) => {
<SettingItem
onClick={onUpdateGeo}
label={t("components.settings.clash.items.updateGeoData")}
label={t("settings.clash.items.updateGeoData")}
/>
</SettingList>
);

View File

@@ -41,27 +41,25 @@ const SettingSystem = ({ onError }: Props) => {
};
return (
<SettingList title={t("components.settings.system.title")}>
<SettingList title={t("settings.system.title")}>
<SysproxyViewer ref={sysproxyRef} />
<TunViewer ref={tunRef} />
<ProxyControlSwitches
label={t("components.settings.system.toggles.tunMode")}
label={t("settings.system.toggles.tunMode")}
onError={onError}
/>
<ProxyControlSwitches
label={t("components.settings.system.toggles.systemProxy")}
label={t("settings.system.toggles.systemProxy")}
onError={onError}
/>
<SettingItem
label={t("components.settings.system.labels.autoLaunch")}
label={t("settings.system.labels.autoLaunch")}
extra={
isAdminMode && (
<Tooltip
title={t("components.settings.system.tooltips.autoLaunchAdmin")}
>
<Tooltip title={t("settings.system.tooltips.autoLaunchAdmin")}>
<WarningRounded sx={{ color: "warning.main", mr: 1 }} />
</Tooltip>
)
@@ -78,9 +76,7 @@ const SettingSystem = ({ onError }: Props) => {
}}
onGuard={async (e) => {
if (isAdminMode) {
showNotice.info(
"components.settings.system.tooltips.autoLaunchAdmin",
);
showNotice.info("settings.system.tooltips.autoLaunchAdmin");
}
try {
@@ -101,10 +97,10 @@ const SettingSystem = ({ onError }: Props) => {
</SettingItem>
<SettingItem
label={t("components.settings.system.labels.silentStart")}
label={t("settings.system.labels.silentStart")}
extra={
<TooltipIcon
title={t("components.settings.system.tooltips.silentStart")}
title={t("settings.system.tooltips.silentStart")}
sx={{ opacity: "0.7" }}
/>
}

View File

@@ -48,7 +48,7 @@ const SettingVergeAdvanced = ({ onError: _ }: Props) => {
const info = await checkUpdate();
if (!info?.available) {
showNotice.success(
"components.settings.verge.advanced.notifications.latestVersion",
"settings.verge.advanced.notifications.latestVersion",
);
} else {
updateRef.current?.open();
@@ -60,23 +60,20 @@ const SettingVergeAdvanced = ({ onError: _ }: Props) => {
const onExportDiagnosticInfo = useCallback(async () => {
await exportDiagnosticInfo();
showNotice.success(
"components.settings.common.notifications.copySuccess",
1000,
);
showNotice.success("settings.common.notifications.copySuccess", 1000);
}, []);
const copyVersion = useCallback(() => {
navigator.clipboard.writeText(`v${version}`).then(() => {
showNotice.success(
"components.settings.verge.advanced.notifications.versionCopied",
"settings.verge.advanced.notifications.versionCopied",
1000,
);
});
}, []);
return (
<SettingList title={t("components.settings.verge.advanced.title")}>
<SettingList title={t("settings.verge.advanced.title")}>
<ThemeViewer ref={themeRef} />
<ConfigViewer ref={configRef} />
<HotkeyViewer ref={hotkeyRef} />
@@ -88,10 +85,10 @@ const SettingVergeAdvanced = ({ onError: _ }: Props) => {
<SettingItem
onClick={() => backupRef.current?.open()}
label={t("components.settings.verge.advanced.items.backupSetting")}
label={t("settings.verge.advanced.items.backupSetting")}
extra={
<TooltipIcon
title={t("components.settings.verge.advanced.tooltips.backupInfo")}
title={t("settings.verge.advanced.tooltips.backupInfo")}
sx={{ opacity: "0.7" }}
/>
}
@@ -99,15 +96,15 @@ const SettingVergeAdvanced = ({ onError: _ }: Props) => {
<SettingItem
onClick={() => configRef.current?.open()}
label={t("components.settings.verge.advanced.items.runtimeConfig")}
label={t("settings.verge.advanced.items.runtimeConfig")}
/>
<SettingItem
onClick={openAppDir}
label={t("components.settings.verge.advanced.items.openConfDir")}
label={t("settings.verge.advanced.items.openConfDir")}
extra={
<TooltipIcon
title={t("components.settings.verge.advanced.tooltips.openConfDir")}
title={t("settings.verge.advanced.tooltips.openConfDir")}
sx={{ opacity: "0.7" }}
/>
}
@@ -115,29 +112,29 @@ const SettingVergeAdvanced = ({ onError: _ }: Props) => {
<SettingItem
onClick={openCoreDir}
label={t("components.settings.verge.advanced.items.openCoreDir")}
label={t("settings.verge.advanced.items.openCoreDir")}
/>
<SettingItem
onClick={openLogsDir}
label={t("components.settings.verge.advanced.items.openLogsDir")}
label={t("settings.verge.advanced.items.openLogsDir")}
/>
<SettingItem
onClick={onCheckUpdate}
label={t("components.settings.verge.advanced.items.checkUpdates")}
label={t("settings.verge.advanced.items.checkUpdates")}
/>
<SettingItem
onClick={openDevTools}
label={t("components.settings.verge.advanced.items.openDevTools")}
label={t("settings.verge.advanced.items.openDevTools")}
/>
<SettingItem
label={t("components.settings.verge.advanced.items.liteModeSettings")}
label={t("settings.verge.advanced.items.liteModeSettings")}
extra={
<TooltipIcon
title={t("components.settings.verge.advanced.tooltips.liteMode")}
title={t("settings.verge.advanced.tooltips.liteMode")}
sx={{ opacity: "0.7" }}
/>
}
@@ -148,11 +145,11 @@ const SettingVergeAdvanced = ({ onError: _ }: Props) => {
onClick={() => {
exitApp();
}}
label={t("components.settings.verge.advanced.items.exit")}
label={t("settings.verge.advanced.items.exit")}
/>
<SettingItem
label={t("components.settings.verge.advanced.items.exportDiagnostics")}
label={t("settings.verge.advanced.items.exportDiagnostics")}
extra={
<TooltipIcon
icon={ContentCopyRounded}
@@ -162,12 +159,12 @@ const SettingVergeAdvanced = ({ onError: _ }: Props) => {
></SettingItem>
<SettingItem
label={t("components.settings.verge.advanced.items.vergeVersion")}
label={t("settings.verge.advanced.items.vergeVersion")}
extra={
<TooltipIcon
icon={ContentCopyRounded}
onClick={copyVersion}
title={t("components.settings.verge.advanced.actions.copyVersion")}
title={t("settings.verge.advanced.actions.copyVersion")}
/>
}
>

View File

@@ -76,14 +76,11 @@ const SettingVergeBasic = ({ onError }: Props) => {
const onCopyClashEnv = useCallback(async () => {
await copyClashEnv();
showNotice.success(
"components.settings.common.notifications.copySuccess",
1000,
);
showNotice.success("settings.common.notifications.copySuccess", 1000);
}, []);
return (
<SettingList title={t("components.settings.verge.basic.title")}>
<SettingList title={t("settings.verge.basic.title")}>
<ThemeViewer ref={themeRef} />
<ConfigViewer ref={configRef} />
<HotkeyViewer ref={hotkeyRef} />
@@ -92,7 +89,7 @@ const SettingVergeBasic = ({ onError }: Props) => {
<UpdateViewer ref={updateRef} />
<BackupViewer ref={backupRef} />
<SettingItem label={t("components.settings.verge.basic.items.language")}>
<SettingItem label={t("settings.verge.basic.items.language")}>
<GuardState
value={language ?? "en"}
onCatch={onError}
@@ -110,7 +107,7 @@ const SettingVergeBasic = ({ onError }: Props) => {
</GuardState>
</SettingItem>
<SettingItem label={t("components.settings.verge.basic.items.themeMode")}>
<SettingItem label={t("settings.verge.basic.items.themeMode")}>
<GuardState
value={theme_mode}
onCatch={onError}
@@ -122,9 +119,7 @@ const SettingVergeBasic = ({ onError }: Props) => {
</SettingItem>
{OS !== "linux" && (
<SettingItem
label={t("components.settings.verge.basic.items.trayClickEvent")}
>
<SettingItem label={t("settings.verge.basic.items.trayClickEvent")}>
<GuardState
value={tray_event ?? "main_window"}
onCatch={onError}
@@ -134,21 +129,19 @@ const SettingVergeBasic = ({ onError }: Props) => {
>
<Select size="small" sx={{ width: 140, "> div": { py: "7.5px" } }}>
<MenuItem value="main_window">
{t(
"components.settings.verge.basic.trayOptions.showMainWindow",
)}
{t("settings.verge.basic.trayOptions.showMainWindow")}
</MenuItem>
<MenuItem value="tray_menu">
{t("components.settings.verge.basic.trayOptions.showTrayMenu")}
{t("settings.verge.basic.trayOptions.showTrayMenu")}
</MenuItem>
<MenuItem value="system_proxy">
{t("components.settings.system.toggles.systemProxy")}
{t("settings.system.toggles.systemProxy")}
</MenuItem>
<MenuItem value="tun_mode">
{t("components.settings.system.toggles.tunMode")}
{t("settings.system.toggles.tunMode")}
</MenuItem>
<MenuItem value="disable">
{t("components.settings.verge.basic.trayOptions.disable")}
{t("settings.verge.basic.trayOptions.disable")}
</MenuItem>
</Select>
</GuardState>
@@ -156,7 +149,7 @@ const SettingVergeBasic = ({ onError }: Props) => {
)}
<SettingItem
label={t("components.settings.verge.basic.items.copyEnvType")}
label={t("settings.verge.basic.items.copyEnvType")}
extra={
<TooltipIcon icon={ContentCopyRounded} onClick={onCopyClashEnv} />
}
@@ -178,7 +171,7 @@ const SettingVergeBasic = ({ onError }: Props) => {
</GuardState>
</SettingItem>
<SettingItem label={t("components.settings.verge.basic.items.startPage")}>
<SettingItem label={t("settings.verge.basic.items.startPage")}>
<GuardState
value={start_page ?? "/"}
onCatch={onError}
@@ -198,9 +191,7 @@ const SettingVergeBasic = ({ onError }: Props) => {
</GuardState>
</SettingItem>
<SettingItem
label={t("components.settings.verge.basic.items.startupScript")}
>
<SettingItem label={t("settings.verge.basic.items.startupScript")}>
<GuardState
value={startup_script ?? ""}
onCatch={onError}
@@ -233,7 +224,7 @@ const SettingVergeBasic = ({ onError }: Props) => {
}
}}
>
{t("components.settings.verge.basic.actions.browse")}
{t("settings.verge.basic.actions.browse")}
</Button>
{startup_script && (
<Button
@@ -242,7 +233,7 @@ const SettingVergeBasic = ({ onError }: Props) => {
patchVerge({ startup_script: "" });
}}
>
{t("components.settings.verge.basic.actions.clear")}
{t("settings.verge.basic.actions.clear")}
</Button>
)}
</>
@@ -253,22 +244,22 @@ const SettingVergeBasic = ({ onError }: Props) => {
<SettingItem
onClick={() => themeRef.current?.open()}
label={t("components.settings.verge.basic.items.themeSetting")}
label={t("settings.verge.basic.items.themeSetting")}
/>
<SettingItem
onClick={() => layoutRef.current?.open()}
label={t("components.settings.verge.basic.items.layoutSetting")}
label={t("settings.verge.basic.items.layoutSetting")}
/>
<SettingItem
onClick={() => miscRef.current?.open()}
label={t("components.settings.verge.basic.items.misc")}
label={t("settings.verge.basic.items.misc")}
/>
<SettingItem
onClick={() => hotkeyRef.current?.open()}
label={t("components.settings.verge.basic.items.hotkeySetting")}
label={t("settings.verge.basic.items.hotkeySetting")}
/>
</SettingList>
);

View File

@@ -132,7 +132,7 @@ const ProxyControlSwitches = ({
const handleTunToggle = async (value: boolean) => {
if (!isTunModeAvailable) {
const msgKey = "components.settings.proxyControl.tooltips.tunUnavailable";
const msgKey = "settings.proxyControl.tooltips.tunUnavailable";
showErrorNotice(msgKey);
throw new Error(t(msgKey));
}
@@ -162,16 +162,16 @@ const ProxyControlSwitches = ({
});
const isSystemProxyMode =
label === t("components.settings.system.toggles.systemProxy") || !label;
const isTunMode = label === t("components.settings.system.toggles.tunMode");
label === t("settings.system.toggles.systemProxy") || !label;
const isTunMode = label === t("settings.system.toggles.tunMode");
return (
<Box sx={{ width: "100%", pr: noRightPadding ? 1 : 2 }}>
{isSystemProxyMode && (
<SwitchRow
label={t("components.settings.proxyControl.labels.systemProxy")}
label={t("settings.proxyControl.labels.systemProxy")}
active={systemProxyActualState}
infoTitle={t("components.settings.proxyControl.tooltips.systemProxy")}
infoTitle={t("settings.proxyControl.tooltips.systemProxy")}
onInfoClick={() => sysproxyRef.current?.open()}
onToggle={(value) => toggleSystemProxy(value)}
onError={onError}
@@ -181,9 +181,9 @@ const ProxyControlSwitches = ({
{isTunMode && (
<SwitchRow
label={t("components.settings.proxyControl.labels.tunMode")}
label={t("settings.proxyControl.labels.tunMode")}
active={enable_tun_mode || false}
infoTitle={t("components.settings.proxyControl.tooltips.tunMode")}
infoTitle={t("settings.proxyControl.tooltips.tunMode")}
onInfoClick={() => tunRef.current?.open()}
onToggle={handleTunToggle}
onError={onError}
@@ -194,16 +194,12 @@ const ProxyControlSwitches = ({
{!isTunModeAvailable && (
<>
<TooltipIcon
title={t(
"components.settings.proxyControl.tooltips.tunUnavailable",
)}
title={t("settings.proxyControl.tooltips.tunUnavailable")}
icon={WarningRounded}
sx={{ color: "warning.main", ml: 1 }}
/>
<TooltipIcon
title={t(
"components.settings.proxyControl.actions.installService",
)}
title={t("settings.proxyControl.actions.installService")}
icon={BuildRounded}
color="primary"
onClick={onInstallService}
@@ -213,9 +209,7 @@ const ProxyControlSwitches = ({
)}
{isServiceOk && (
<TooltipIcon
title={t(
"components.settings.proxyControl.actions.uninstallService",
)}
title={t("settings.proxyControl.actions.uninstallService")}
icon={DeleteForeverRounded}
color="secondary"
onClick={onUninstallService}

View File

@@ -192,7 +192,7 @@ export const TestItem = ({
":hover": { bgcolor: alpha(palette.primary.main, 0.15) },
})}
>
{t("components.test.item.actions.test")}
{t("test.item.actions.test")}
</Widget>
)}

View File

@@ -126,8 +126,8 @@ export const TestViewer = forwardRef<TestViewerRef, Props>((props, ref) => {
open={open}
title={
openType === "new"
? t("components.test.viewer.title.create")
: t("components.test.viewer.title.edit")
? t("test.viewer.title.create")
: t("test.viewer.title.edit")
}
contentSx={{ width: 375, pb: 0, maxHeight: "80%" }}
okBtn={t("Save")}
@@ -166,7 +166,7 @@ export const TestViewer = forwardRef<TestViewerRef, Props>((props, ref) => {
{...field}
multiline
maxRows={3}
label={t("components.test.viewer.fields.url")}
label={t("test.viewer.fields.url")}
/>
)}
/>