From 86dcf0bdcf642f85be27a5de8013e069ae064b71 Mon Sep 17 00:00:00 2001 From: Slinetrac Date: Thu, 11 Dec 2025 16:23:43 +0800 Subject: [PATCH] fix: proxy chain #5776 Closes #5776 --- src/components/proxy/proxy-chain.tsx | 61 ++++++++++++++++++--------- src/components/proxy/proxy-groups.tsx | 25 +++++++++-- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/components/proxy/proxy-chain.tsx b/src/components/proxy/proxy-chain.tsx index 9e47a289e..b93cb579b 100644 --- a/src/components/proxy/proxy-chain.tsx +++ b/src/components/proxy/proxy-chain.tsx @@ -285,23 +285,37 @@ export const ProxyChain = ({ const handleConnect = useCallback(async () => { if (isConnected) { - // 如果已连接,则断开连接 setIsConnecting(true); try { - // 清空链式代理配置 await updateProxyChainConfigInRuntime(null); - // 切换到 DIRECT 模式断开代理连接 - // await updateProxyAndSync("GLOBAL", "DIRECT"); + const targetGroup = + mode === "global" + ? "GLOBAL" + : selectedGroup || localStorage.getItem("proxy-chain-group"); + + if (targetGroup) { + try { + await selectNodeForGroup(targetGroup, "DIRECT"); + } catch { + if (proxyChain.length >= 1) { + try { + await selectNodeForGroup(targetGroup, proxyChain[0].name); + } catch { + // ignore + } + } + } + } + + localStorage.removeItem("proxy-chain-group"); + localStorage.removeItem("proxy-chain-exit-node"); + localStorage.removeItem("proxy-chain-items"); - // 关闭所有连接 await closeAllConnections(); + await mutateProxies(); - // 刷新代理信息以更新连接状态 - mutateProxies(); - - // 清空链式代理配置UI - // onUpdateChain([]); + onUpdateChain([]); } catch (error) { console.error("Failed to disconnect from proxy chain:", error); alert(t("proxies.page.chain.disconnectFailed") || "断开链式代理失败"); @@ -348,7 +362,15 @@ export const ProxyChain = ({ } finally { setIsConnecting(false); } - }, [proxyChain, isConnected, t, mutateProxies, mode, selectedGroup]); + }, [ + proxyChain, + isConnected, + t, + mutateProxies, + mode, + selectedGroup, + onUpdateChain, + ]); const proxyChainRef = useRef(proxyChain); const onUpdateChainRef = useRef(onUpdateChain); @@ -376,10 +398,11 @@ export const ProxyChain = ({ type: proxy.type, delay: undefined, })) || []; - onUpdateChain(chainItems); + if (chainItems.length > 0) { + onUpdateChain(chainItems); + } } catch (parseError) { console.error("Failed to parse YAML:", parseError); - onUpdateChain([]); } }) .catch((importError) => { @@ -399,19 +422,16 @@ export const ProxyChain = ({ type: proxy.type, delay: undefined, })) || []; - onUpdateChain(chainItems); + if (chainItems.length > 0) { + onUpdateChain(chainItems); + } } catch (jsonError) { console.error("Failed to parse as JSON either:", jsonError); - onUpdateChain([]); } }); } catch (error) { console.error("Failed to process chain config data:", error); - onUpdateChain([]); } - } else if (chainConfigData === "") { - // Empty string means no proxies available, show empty state - onUpdateChain([]); } }, [chainConfigData, onUpdateChain]); @@ -481,6 +501,9 @@ export const ProxyChain = ({ size="small" onClick={() => { updateProxyChainConfigInRuntime(null); + localStorage.removeItem("proxy-chain-group"); + localStorage.removeItem("proxy-chain-exit-node"); + localStorage.removeItem("proxy-chain-items"); onUpdateChain([]); }} sx={{ diff --git a/src/components/proxy/proxy-groups.tsx b/src/components/proxy/proxy-groups.tsx index 19b93b7ee..88d7012d8 100644 --- a/src/components/proxy/proxy-groups.tsx +++ b/src/components/proxy/proxy-groups.tsx @@ -51,8 +51,26 @@ const VirtuosoFooter = () =>
; export const ProxyGroups = (props: Props) => { const { t } = useTranslation(); const { mode, isChainMode = false, chainConfigData } = props; - const [proxyChain, setProxyChain] = useState([]); + const [proxyChain, setProxyChain] = useState(() => { + try { + const saved = localStorage.getItem("proxy-chain-items"); + if (saved) { + return JSON.parse(saved); + } + } catch { + // ignore + } + return []; + }); const [selectedGroup, setSelectedGroup] = useState(null); + + useEffect(() => { + if (proxyChain.length > 0) { + localStorage.setItem("proxy-chain-items", JSON.stringify(proxyChain)); + } else { + localStorage.removeItem("proxy-chain-items"); + } + }, [proxyChain]); const [ruleMenuAnchor, setRuleMenuAnchor] = useState( null, ); @@ -231,10 +249,11 @@ export const ProxyGroups = (props: Props) => { setSelectedGroup(groupName); handleGroupMenuClose(); - // 在链式代理模式的规则模式下,切换代理组时清空链式代理配置 if (isChainMode && mode === "rule") { updateProxyChainConfigInRuntime(null); - // 同时清空右侧链式代理配置 + localStorage.removeItem("proxy-chain-group"); + localStorage.removeItem("proxy-chain-exit-node"); + localStorage.removeItem("proxy-chain-items"); setProxyChain([]); } };