diff --git a/src/components/proxy/use-filter-sort.ts b/src/components/proxy/use-filter-sort.ts index accec284..79bf8634 100644 --- a/src/components/proxy/use-filter-sort.ts +++ b/src/components/proxy/use-filter-sort.ts @@ -1,5 +1,6 @@ import { useEffect, useMemo, useReducer } from "react"; +import { useVerge } from "@/hooks/use-verge"; import delayManager from "@/services/delay"; // default | delay | alphabet @@ -11,6 +12,7 @@ export default function useFilterSort( filterText: string, sortType: ProxySortType, ) { + const { verge } = useVerge(); const [_, bumpRefresh] = useReducer((count: number) => count + 1, 0); useEffect(() => { @@ -32,9 +34,20 @@ export default function useFilterSort( return useMemo(() => { const fp = filterProxies(proxies, groupName, filterText); - const sp = sortProxies(fp, groupName, sortType); + const sp = sortProxies( + fp, + groupName, + sortType, + verge?.default_latency_timeout, + ); return sp; - }, [proxies, groupName, filterText, sortType]); + }, [ + proxies, + groupName, + filterText, + sortType, + verge?.default_latency_timeout, + ]); } export function filterSort( @@ -42,9 +55,10 @@ export function filterSort( groupName: string, filterText: string, sortType: ProxySortType, + latencyTimeout?: number, ) { const fp = filterProxies(proxies, groupName, filterText); - const sp = sortProxies(fp, groupName, sortType); + const sp = sortProxies(fp, groupName, sortType, latencyTimeout); return sp; } @@ -102,23 +116,36 @@ function sortProxies( proxies: IProxyItem[], groupName: string, sortType: ProxySortType, + latencyTimeout?: number, ) { if (!proxies) return []; if (sortType === 0) return proxies; const list = proxies.slice(); + const effectiveTimeout = + typeof latencyTimeout === "number" && latencyTimeout > 0 + ? latencyTimeout + : 10000; if (sortType === 1) { - const toSortableValue = (delay: number) => { - if (!Number.isFinite(delay) || delay <= 0) return Number.MAX_SAFE_INTEGER; - return delay; + const categorizeDelay = (delay: number): [number, number] => { + if (!Number.isFinite(delay)) return [3, Number.MAX_SAFE_INTEGER]; + if (delay > 1e5) return [4, delay]; + if (delay < 0) return [2, Math.abs(delay)]; + if (delay === 0 || (delay >= effectiveTimeout && delay <= 1e5)) { + return [3, delay || effectiveTimeout]; + } + return [0, delay]; }; list.sort((a, b) => { - const ad = toSortableValue(delayManager.getDelayFix(a, groupName)); - const bd = toSortableValue(delayManager.getDelayFix(b, groupName)); + const ad = delayManager.getDelayFix(a, groupName); + const bd = delayManager.getDelayFix(b, groupName); + const [ar, av] = categorizeDelay(ad); + const [br, bv] = categorizeDelay(bd); - return ad - bd; + if (ar !== br) return ar - br; + return av - bv; }); } else { list.sort((a, b) => a.name.localeCompare(b.name)); diff --git a/src/components/proxy/use-render-list.ts b/src/components/proxy/use-render-list.ts index 172d2915..7a5949ae 100644 --- a/src/components/proxy/use-render-list.ts +++ b/src/components/proxy/use-render-list.ts @@ -103,6 +103,7 @@ export const useRenderList = ( const { verge } = useVerge(); const { width } = useWindowWidth(); const [headStates, setHeadState] = useHeadStateNew(); + const latencyTimeout = verge?.default_latency_timeout; // 获取运行时配置用于链式代理模式 const { data: runtimeConfig } = useSWR( @@ -197,7 +198,13 @@ export const useRenderList = ( (g: any) => g.name === selectedGroup, ); if (targetGroup) { - const proxies = filterSort(targetGroup.all, targetGroup.name, "", 0); + const proxies = filterSort( + targetGroup.all, + targetGroup.name, + "", + 0, + latencyTimeout, + ); if (col > 1) { return groupProxies(proxies, col).map((proxyCol, colIndex) => ({ @@ -226,7 +233,13 @@ export const useRenderList = ( // 如果没有选择特定组,显示第一个组的节点(如果有组的话) if (allGroups.length > 0) { const firstGroup = allGroups[0]; - const proxies = filterSort(firstGroup.all, firstGroup.name, "", 0); + const proxies = filterSort( + firstGroup.all, + firstGroup.name, + "", + 0, + latencyTimeout, + ); if (col > 1) { return groupProxies(proxies, col).map((proxyCol, colIndex) => ({ @@ -391,6 +404,7 @@ export const useRenderList = ( group.name, headState.filterText, headState.sortType, + latencyTimeout, ); ret.push({ @@ -445,6 +459,7 @@ export const useRenderList = ( isChainMode, runtimeConfig, selectedGroup, + latencyTimeout, ]); return {