refactor(i18n): remove pages.* namespace and migrate route texts under module-level page keys
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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={{
|
||||
|
||||
@@ -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={() => {
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 } }}
|
||||
/>
|
||||
|
||||
@@ -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")
|
||||
: ""
|
||||
}
|
||||
>
|
||||
|
||||
@@ -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}`}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }}
|
||||
>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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" }}
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -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")}
|
||||
/>
|
||||
}
|
||||
>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
|
||||
|
||||
@@ -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")}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user