From 3027e2b87f7083ecf50bfb527f0d78c59b33a6bf Mon Sep 17 00:00:00 2001 From: Tunglies <77394545+Tunglies@users.noreply.github.com> Date: Mon, 2 Nov 2026 22:23:26 +0800 Subject: [PATCH] fix(proxies): restore GLOBAL selection in global mode Show the GLOBAL group before configured groups so the global exit can be selected without changing a shared policy group. Use the displayed groups for delay subscriptions and verify row identity before reusing the list. Close #8516 --- Changelog.md | 4 ++++ src/components/proxy/use-render-list.ts | 28 ++++++++++++------------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Changelog.md b/Changelog.md index ddedcb2f4..3187e4fa9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -24,14 +24,18 @@
🐞 修复问题 +- 修复全局模式缺少 `GLOBAL` 策略组,无法单独选择全局出口 +
✨ 新增功能 +
🚀 优化改进 +
diff --git a/src/components/proxy/use-render-list.ts b/src/components/proxy/use-render-list.ts index b819b8ac5..d62ffdab6 100644 --- a/src/components/proxy/use-render-list.ts +++ b/src/components/proxy/use-render-list.ts @@ -206,17 +206,20 @@ export const useRenderList = ( verge?.default_latency_timeout, ]) + const renderGroups = useMemo(() => { + if (!proxyView) return [] + if (mode === 'rule') return proxyView.groups + const global = proxyView.global ? [proxyView.global] : [] + return mode === 'global' ? [...global, ...proxyView.groups] : global + }, [mode, proxyView]) + // Every group this list draws, so a test settling in any of them re-sorts that group. const renderedGroupNames = useMemo(() => { if (!proxyView) return [] if (isChainMode) return selectedGroup ? [selectedGroup] : [CHAIN_DELAY_GROUP] - return mode === 'rule' || mode === 'global' - ? proxyView.groups.map(({ name }) => name) - : proxyView.global - ? [proxyView.global.name] - : [] - }, [isChainMode, mode, proxyView, selectedGroup]) + return renderGroups.map(({ name }) => name) + }, [isChainMode, proxyView, renderGroups, selectedGroup]) const groupDelays = useGroupsDelays(renderedGroupNames) const groupCacheRef = useRef>(new Map()) @@ -258,13 +261,7 @@ export const useRenderList = ( } const useRule = mode === 'rule' || mode === 'global' - const renderGroups = useRule - ? proxyView.groups - : proxyView.global === null - ? [] - : [proxyView.global] const cache = groupCacheRef.current - let anyChanged = false const retList = renderGroups.flatMap((group) => { const headState = headStates[group.name] || DEFAULT_STATE @@ -281,7 +278,6 @@ export const useRenderList = ( return cached.items } - anyChanged = true const ret: IRenderItem[] = [ { type: 0, @@ -350,7 +346,10 @@ export const useRenderList = ( const filtered = !useRule ? retList.slice(1) : retList.filter((item) => !item.group.hidden) - if (!anyChanged && prevListRef.current.length === filtered.length) { + if ( + prevListRef.current.length === filtered.length && + filtered.every((item, index) => item === prevListRef.current[index]) + ) { return prevListRef.current } prevListRef.current = filtered @@ -364,6 +363,7 @@ export const useRenderList = ( latencyTimeout, mode, proxyView, + renderGroups, selectedGroup, ])