diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs index 594abd04..91e3a26e 100644 --- a/src-tauri/src/cmds.rs +++ b/src-tauri/src/cmds.rs @@ -249,8 +249,9 @@ pub mod uwp { pub async fn clash_api_get_proxy_delay( name: String, url: Option, + timeout: i32, ) -> CmdResult { - match clash_api::get_proxy_delay(name, url).await { + match clash_api::get_proxy_delay(name, url, timeout).await { Ok(res) => Ok(res), Err(err) => Err(err.to_string()), } diff --git a/src-tauri/src/config/verge.rs b/src-tauri/src/config/verge.rs index 765cd82b..0cdf6784 100644 --- a/src-tauri/src/config/verge.rs +++ b/src-tauri/src/config/verge.rs @@ -81,6 +81,9 @@ pub struct IVerge { /// 默认的延迟测试连接 pub default_latency_test: Option, + /// 默认的延迟测试超时时间 + pub default_latency_timeout: Option, + /// 是否使用内部的脚本支持,默认为真 pub enable_builtin_enhanced: Option, @@ -222,6 +225,7 @@ impl IVerge { patch!(auto_close_connection); patch!(default_latency_test); + patch!(default_latency_timeout); patch!(enable_builtin_enhanced); patch!(proxy_layout_column); patch!(test_list); diff --git a/src-tauri/src/core/clash_api.rs b/src-tauri/src/core/clash_api.rs index 6d4668e3..79a5e55e 100644 --- a/src-tauri/src/core/clash_api.rs +++ b/src-tauri/src/core/clash_api.rs @@ -44,7 +44,11 @@ pub struct DelayRes { /// GET /proxies/{name}/delay /// 获取代理延迟 -pub async fn get_proxy_delay(name: String, test_url: Option) -> Result { +pub async fn get_proxy_delay( + name: String, + test_url: Option, + timeout: i32, +) -> Result { let (url, headers) = clash_client_info()?; let url = format!("{url}/proxies/{name}/delay"); @@ -57,7 +61,7 @@ pub async fn get_proxy_delay(name: String, test_url: Option) -> Result().await?) diff --git a/src/components/proxy/proxy-groups.tsx b/src/components/proxy/proxy-groups.tsx index 4637cb4b..2db4d7b5 100644 --- a/src/components/proxy/proxy-groups.tsx +++ b/src/components/proxy/proxy-groups.tsx @@ -25,6 +25,7 @@ export const ProxyGroups = (props: Props) => { const { verge } = useVerge(); const { current, patchCurrent } = useProfiles(); + const timeout = verge?.default_latency_timeout || 10000; const virtuosoRef = useRef(null); @@ -83,7 +84,7 @@ export const ProxyGroups = (props: Props) => { } const names = proxies.filter((p) => !p!.provider).map((p) => p!.name); - await delayManager.checkListDelay(names, groupName); + await delayManager.checkListDelay(names, groupName, timeout); onProxies(); }); diff --git a/src/components/proxy/proxy-item-mini.tsx b/src/components/proxy/proxy-item-mini.tsx index 61d6f21a..6f7e5e18 100644 --- a/src/components/proxy/proxy-item-mini.tsx +++ b/src/components/proxy/proxy-item-mini.tsx @@ -4,6 +4,7 @@ import { CheckCircleOutlineRounded } from "@mui/icons-material"; import { alpha, Box, ListItemButton, styled, Typography } from "@mui/material"; import { BaseLoading } from "@/components/base"; import delayManager from "@/services/delay"; +import { useVerge } from "@/hooks/use-verge"; interface Props { groupName: string; @@ -20,6 +21,8 @@ export const ProxyItemMini = (props: Props) => { // -1/<=0 为 不显示 // -2 为 loading const [delay, setDelay] = useState(-1); + const { verge } = useVerge(); + const timeout = verge?.default_latency_timeout || 10000; useEffect(() => { delayManager.setListener(proxy.name, groupName, setDelay); @@ -36,7 +39,7 @@ export const ProxyItemMini = (props: Props) => { const onDelay = useLockFn(async () => { setDelay(-2); - setDelay(await delayManager.checkDelay(proxy.name, groupName)); + setDelay(await delayManager.checkDelay(proxy.name, groupName, timeout)); }); return ( @@ -139,14 +142,14 @@ export const ProxyItemMini = (props: Props) => { e.stopPropagation(); onDelay(); }} - color={delayManager.formatDelayColor(delay)} + color={delayManager.formatDelayColor(delay, timeout)} sx={({ palette }) => !proxy.provider ? { ":hover": { bgcolor: alpha(palette.primary.main, 0.15) } } : {} } > - {delayManager.formatDelay(delay)} + {delayManager.formatDelay(delay, timeout)} )} diff --git a/src/components/proxy/proxy-item.tsx b/src/components/proxy/proxy-item.tsx index ff3bc0b8..48609174 100644 --- a/src/components/proxy/proxy-item.tsx +++ b/src/components/proxy/proxy-item.tsx @@ -14,6 +14,7 @@ import { } from "@mui/material"; import { BaseLoading } from "@/components/base"; import delayManager from "@/services/delay"; +import { useVerge } from "@/hooks/use-verge"; interface Props { groupName: string; @@ -48,7 +49,8 @@ export const ProxyItem = (props: Props) => { // -1/<=0 为 不显示 // -2 为 loading const [delay, setDelay] = useState(-1); - + const { verge } = useVerge(); + const timeout = verge?.default_latency_timeout || 10000; useEffect(() => { delayManager.setListener(proxy.name, groupName, setDelay); @@ -64,7 +66,7 @@ export const ProxyItem = (props: Props) => { const onDelay = useLockFn(async () => { setDelay(-2); - setDelay(await delayManager.checkDelay(proxy.name, groupName)); + setDelay(await delayManager.checkDelay(proxy.name, groupName, timeout)); }); return ( @@ -149,14 +151,14 @@ export const ProxyItem = (props: Props) => { e.stopPropagation(); onDelay(); }} - color={delayManager.formatDelayColor(delay)} + color={delayManager.formatDelayColor(delay, timeout)} sx={({ palette }) => !proxy.provider ? { ":hover": { bgcolor: alpha(palette.primary.main, 0.15) } } : {} } > - {delayManager.formatDelay(delay)} + {delayManager.formatDelay(delay, timeout)} )} diff --git a/src/components/setting/mods/misc-viewer.tsx b/src/components/setting/mods/misc-viewer.tsx index 71461e79..ed9ce1f1 100644 --- a/src/components/setting/mods/misc-viewer.tsx +++ b/src/components/setting/mods/misc-viewer.tsx @@ -25,6 +25,7 @@ export const MiscViewer = forwardRef((props, ref) => { proxyLayoutColumn: 6, defaultLatencyTest: "", autoLogClean: 0, + defaultLatencyTimeout: 10000, }); useImperativeHandle(ref, () => ({ @@ -37,6 +38,7 @@ export const MiscViewer = forwardRef((props, ref) => { proxyLayoutColumn: verge?.proxy_layout_column || 6, defaultLatencyTest: verge?.default_latency_test || "", autoLogClean: verge?.auto_log_clean || 0, + defaultLatencyTimeout: verge?.default_latency_timeout || 10000, }); }, close: () => setOpen(false), @@ -50,6 +52,7 @@ export const MiscViewer = forwardRef((props, ref) => { enable_builtin_enhanced: values.enableBuiltinEnhanced, proxy_layout_column: values.proxyLayoutColumn, default_latency_test: values.defaultLatencyTest, + default_latency_timeout: values.defaultLatencyTimeout, auto_log_clean: values.autoLogClean as any, }); setOpen(false); @@ -179,6 +182,27 @@ export const MiscViewer = forwardRef((props, ref) => { } /> + + + + + setValues((v) => ({ + ...v, + defaultLatencyTimeout: parseInt(e.target.value), + })) + } + /> + ); diff --git a/src/locales/en.json b/src/locales/en.json index ba0c8ba7..3518dcd6 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -152,6 +152,7 @@ "Enable Builtin Enhanced": "Enable Builtin Enhanced", "Proxy Layout Column": "Proxy Layout Column", "Default Latency Test": "Default Latency Test", + "Defaule Latency Timeout": "Defaule Latency Timeout", "Auto Log Clean": "Auto Log Clean", "Never Clean": "Never Clean", diff --git a/src/locales/zh.json b/src/locales/zh.json index eb810bd7..e0f634f6 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -152,6 +152,7 @@ "Enable Builtin Enhanced": "开启内建增强功能", "Proxy Layout Column": "代理页布局列数", "Default Latency Test": "默认测试链接", + "Default Latency Timeout": "测试超时时间", "Auto Log Clean": "自动清理日志", "Never Clean": "不清理", diff --git a/src/services/cmds.ts b/src/services/cmds.ts index f46a11d4..3c5e80ed 100644 --- a/src/services/cmds.ts +++ b/src/services/cmds.ts @@ -160,9 +160,17 @@ export async function openWebUrl(url: string) { return invoke("open_web_url", { url }); } -export async function cmdGetProxyDelay(name: string, url?: string) { +export async function cmdGetProxyDelay( + name: string, + timeout: number, + url?: string +) { name = encodeURIComponent(name); - return invoke<{ delay: number }>("clash_api_get_proxy_delay", { name, url }); + return invoke<{ delay: number }>("clash_api_get_proxy_delay", { + name, + url, + timeout, + }); } export async function cmdTestDelay(url: string) { diff --git a/src/services/delay.ts b/src/services/delay.ts index 88e2b283..3c572a9a 100644 --- a/src/services/delay.ts +++ b/src/services/delay.ts @@ -69,12 +69,12 @@ class DelayManager { return -1; } - async checkDelay(name: string, group: string) { + async checkDelay(name: string, group: string, timeout: number) { let delay = -1; try { const url = this.getUrl(group); - const result = await cmdGetProxyDelay(name, url); + const result = await cmdGetProxyDelay(name, timeout, url); delay = result.delay; } catch { delay = 1e6; // error @@ -84,7 +84,12 @@ class DelayManager { return delay; } - async checkListDelay(nameList: string[], group: string, concurrency = 36) { + async checkListDelay( + nameList: string[], + group: string, + timeout: number, + concurrency = 36 + ) { const names = nameList.filter(Boolean); // 设置正在延迟测试中 names.forEach((name) => this.setDelay(name, group, -2)); @@ -98,7 +103,7 @@ class DelayManager { const task = names.shift(); if (!task) return; current += 1; - await this.checkDelay(task, group); + await this.checkDelay(task, group, timeout); current -= 1; total -= 1; if (total <= 0) resolve(null); @@ -108,15 +113,15 @@ class DelayManager { }); } - formatDelay(delay: number) { + formatDelay(delay: number, timeout = 10000) { if (delay <= 0) return "Error"; if (delay > 1e5) return "Error"; - if (delay >= 10000) return "Timeout"; // 10s + if (delay >= timeout) return "Timeout"; // 10s return `${delay}`; } - formatDelayColor(delay: number) { - if (delay >= 10000) return "error.main"; + formatDelayColor(delay: number, timeout = 10000) { + if (delay >= timeout) return "error.main"; if (delay <= 0) return "error.main"; if (delay > 500) return "warning.main"; return "success.main"; diff --git a/src/services/types.d.ts b/src/services/types.d.ts index 626461b7..bfea5789 100644 --- a/src/services/types.d.ts +++ b/src/services/types.d.ts @@ -219,6 +219,7 @@ interface IVergeConfig { }; auto_close_connection?: boolean; default_latency_test?: string; + default_latency_timeout?: number; enable_builtin_enhanced?: boolean; auto_log_clean?: 0 | 1 | 2 | 3; proxy_layout_column?: number;