diff --git a/src/components/profile/enhanced.tsx b/src/components/profile/enhanced.tsx index ea3dfd238e5ce3682035682d70b9d4ffde2e19b8..b226fd0ad9ec7d38b61b3e212957b2301cc99807 100644 --- a/src/components/profile/enhanced.tsx +++ b/src/components/profile/enhanced.tsx @@ -1,5 +1,6 @@ import useSWR from "swr"; import { useLockFn } from "ahooks"; +import { useTranslation } from "react-i18next"; import { Box, Grid, IconButton, Stack } from "@mui/material"; import { RestartAltRounded } from "@mui/icons-material"; import { @@ -20,6 +21,7 @@ interface Props { const EnhancedMode = (props: Props) => { const { items, chain } = props; + const { t } = useTranslation(); const { mutate: mutateProfiles } = useSWR("getProfiles", getProfiles); const { data: chainLogs = {}, mutate: mutateLogs } = useSWR( "getRuntimeLogs", @@ -96,7 +98,7 @@ const EnhancedMode = (props: Props) => { <IconButton size="small" color="inherit" - title="refresh enhanced profiles" + title={t("Refresh profiles")} onClick={onEnhance} > <RestartAltRounded /> diff --git a/src/components/profile/info-editor.tsx b/src/components/profile/info-editor.tsx index f34644de3ccf70adb2ea64eba7933de17e470866..2bb2c1d6d4d92ac8c687dc8726f011d7fb6443d9 100644 --- a/src/components/profile/info-editor.tsx +++ b/src/components/profile/info-editor.tsx @@ -82,7 +82,7 @@ const InfoEditor = (props: Props) => { <TextField {...textFieldProps} disabled - label="Type" + label={t("Type")} value={type} sx={{ input: { textTransform: "capitalize" } }} /> @@ -90,7 +90,7 @@ const InfoEditor = (props: Props) => { <TextField {...textFieldProps} autoFocus - label="Name" + label={t("Name")} value={form.name} onChange={(e) => setForm({ name: e.target.value })} onKeyDown={(e) => e.key === "Enter" && onUpdate()} @@ -98,7 +98,7 @@ const InfoEditor = (props: Props) => { <TextField {...textFieldProps} - label="Descriptions" + label={t("Descriptions")} value={form.desc} onChange={(e) => setForm({ desc: e.target.value })} onKeyDown={(e) => e.key === "Enter" && onUpdate()} @@ -107,7 +107,7 @@ const InfoEditor = (props: Props) => { {type === "remote" && ( <TextField {...textFieldProps} - label="Subscription URL" + label={t("Subscription URL")} value={form.url} onChange={(e) => setForm({ url: e.target.value })} onKeyDown={(e) => e.key === "Enter" && onUpdate()} @@ -128,7 +128,7 @@ const InfoEditor = (props: Props) => { {((type === "remote" && showOpt) || type === "local") && ( <TextField {...textFieldProps} - label="Update Interval (mins)" + label={t("Update Interval(mins)")} value={option.update_interval} onChange={(e) => { const str = e.target.value?.replace(/\D/, ""); diff --git a/src/components/profile/profile-new.tsx b/src/components/profile/profile-new.tsx index fdd9f10ee305401cfa4a63f391265f6ab9f2e7af..dfe24bba535f5b355f72105ac110cbb8a963d88e 100644 --- a/src/components/profile/profile-new.tsx +++ b/src/components/profile/profile-new.tsx @@ -91,7 +91,7 @@ const ProfileNew = (props: Props) => { <InputLabel>Type</InputLabel> <Select autoFocus - label="Type" + label={t("Type")} value={form.type} onChange={(e) => setForm({ type: e.target.value })} > @@ -104,7 +104,7 @@ const ProfileNew = (props: Props) => { <TextField {...textFieldProps} - label="Name" + label={t("Name")} autoComplete="off" value={form.name} onChange={(e) => setForm({ name: e.target.value })} @@ -112,7 +112,7 @@ const ProfileNew = (props: Props) => { <TextField {...textFieldProps} - label="Descriptions" + label={t("Descriptions")} autoComplete="off" value={form.desc} onChange={(e) => setForm({ desc: e.target.value })} @@ -121,7 +121,7 @@ const ProfileNew = (props: Props) => { {form.type === "remote" && ( <TextField {...textFieldProps} - label="Subscription URL" + label={t("Subscription URL")} autoComplete="off" value={form.url} onChange={(e) => setForm({ url: e.target.value })} diff --git a/src/components/proxy/proxy-head.tsx b/src/components/proxy/proxy-head.tsx index 1e87310799f2fd59cb45f72aee01445119f59988..f906b15e50c09a4dd5fdd6f8f0407657d1d4554a 100644 --- a/src/components/proxy/proxy-head.tsx +++ b/src/components/proxy/proxy-head.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; import { Box, IconButton, TextField, SxProps } from "@mui/material"; import { AccessTimeRounded, @@ -31,11 +32,13 @@ const ProxyHead = (props: Props) => { const { showType, sortType, filterText, textState, testUrl } = headState; + const { t } = useTranslation(); const [autoFocus, setAutoFocus] = useState(false); useEffect(() => { // fix the focus conflict - setTimeout(() => setAutoFocus(true), 100); + const timer = setTimeout(() => setAutoFocus(true), 100); + return () => clearTimeout(timer); }, []); useEffect(() => { @@ -46,8 +49,8 @@ const ProxyHead = (props: Props) => { <Box sx={{ display: "flex", alignItems: "center", ...sx }}> <IconButton size="small" - title="location" color="inherit" + title={t("Location")} onClick={props.onLocation} > <MyLocationRounded /> @@ -56,7 +59,7 @@ const ProxyHead = (props: Props) => { <IconButton size="small" color="inherit" - title="delay check" + title={t("Delay check")} onClick={() => { // Remind the user that it is custom test url if (testUrl?.trim() && textState !== "filter") { @@ -71,7 +74,11 @@ const ProxyHead = (props: Props) => { <IconButton size="small" color="inherit" - title={["sort by default", "sort by delay", "sort by name"][sortType]} + title={ + [t("Sort by default"), t("Sort by delay"), t("Sort by name")][ + sortType + ] + } onClick={() => onHeadState({ sortType: ((sortType + 1) % 3) as ProxySortType }) } @@ -84,7 +91,7 @@ const ProxyHead = (props: Props) => { <IconButton size="small" color="inherit" - title="edit test url" + title={t("Delay check URL")} onClick={() => onHeadState({ textState: textState === "url" ? null : "url" }) } @@ -99,7 +106,7 @@ const ProxyHead = (props: Props) => { <IconButton size="small" color="inherit" - title="proxy detail" + title={t("Proxy detail")} onClick={() => onHeadState({ showType: !showType })} > {showType ? <VisibilityRounded /> : <VisibilityOffRounded />} @@ -108,7 +115,7 @@ const ProxyHead = (props: Props) => { <IconButton size="small" color="inherit" - title="filter" + title={t("Filter")} onClick={() => onHeadState({ textState: textState === "filter" ? null : "filter" }) } @@ -127,7 +134,7 @@ const ProxyHead = (props: Props) => { value={filterText} size="small" variant="outlined" - placeholder="Filter conditions" + placeholder={t("Filter conditions")} onChange={(e) => onHeadState({ filterText: e.target.value })} sx={{ ml: 0.5, flex: "1 1 auto", input: { py: 0.65, px: 1 } }} /> @@ -142,7 +149,7 @@ const ProxyHead = (props: Props) => { value={testUrl} size="small" variant="outlined" - placeholder="Test url" + placeholder={t("Delay check URL")} onChange={(e) => onHeadState({ testUrl: e.target.value })} sx={{ ml: 0.5, flex: "1 1 auto", input: { py: 0.65, px: 1 } }} /> diff --git a/src/locales/en.json b/src/locales/en.json index 014c634eca32ec951ac655d45a8b92cdbb326b92..037e1b9ea4108c7ec25efbb754e3174dd8ff5704 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -34,6 +34,23 @@ "To Top": "To Top", "To End": "To End", + "Location": "Location", + "Delay check": "Delay check", + "Sort by default": "Sort by default", + "Sort by delay": "Sort by delay", + "Sort by name": "Sort by name", + "Delay check URL": "Delay check URL", + "Proxy detail": "Proxy detail", + "Filter": "Filter", + "Filter conditions": "Filter conditions", + "Refresh profiles": "Refresh profiles", + + "Type": "Type", + "Name": "Name", + "Descriptions": "Descriptions", + "Subscription URL": "Subscription URL", + "Update Interval(mins)": "Update Interval(mins)", + "Settings": "Settings", "Clash Setting": "Clash Setting", "System Setting": "System Setting", diff --git a/src/locales/zh.json b/src/locales/zh.json index f60789ce0169d46f5db1c2971e89d22ee0348ea6..30f67f44a887583196eabefd71c9461327ce16ac 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -34,6 +34,23 @@ "To Top": "移到最å‰", "To End": "移到末尾", + "Location": "当å‰èŠ‚点", + "Delay check": "延迟测试", + "Sort by default": "默认排åº", + "Sort by delay": "按延迟排åº", + "Sort by name": "按å称排åº", + "Delay check URL": "延迟测试链接", + "Proxy detail": "展示节点细节", + "Filter": "过滤节点", + "Filter conditions": "过滤æ¡ä»¶", + "Refresh profiles": "刷新é…ç½®", + + "Type": "类型", + "Name": "å称", + "Descriptions": "æè¿°", + "Subscription URL": "订阅链接", + "Update Interval(mins)": "æ›´æ–°é—´éš”(分钟)", + "Settings": "设置", "Clash Setting": "Clash 设置", "System Setting": "系统设置", diff --git a/src/pages/connections.tsx b/src/pages/connections.tsx index a5fdad233c2ca9605a40de5c48a71511e4c4009a..ce59c2a4031f3de527c55934bb1b017dc50b1fb9 100644 --- a/src/pages/connections.tsx +++ b/src/pages/connections.tsx @@ -114,7 +114,7 @@ const ConnectionsPage = () => { size="small" autoComplete="off" variant="outlined" - placeholder="Filter conditions" + placeholder={t("Filter conditions")} value={filterText} onChange={(e) => setFilterText(e.target.value)} sx={{ input: { py: 0.65, px: 1.25 } }} diff --git a/src/pages/logs.tsx b/src/pages/logs.tsx index c0c13967776ce1543a66dc42bba6be6328ca5e4c..f4566bd5920848320d9876869ad9bc15345c3e78 100644 --- a/src/pages/logs.tsx +++ b/src/pages/logs.tsx @@ -67,7 +67,7 @@ const LogPage = () => { size="small" autoComplete="off" variant="outlined" - placeholder="Filter conditions" + placeholder={t("Filter conditions")} value={filterText} onChange={(e) => setFilterText(e.target.value)} sx={{ input: { py: 0.65, px: 1.25 } }}