clash-verge-rev/src/hooks/use-system-proxy-state.ts
Tunglies a73fafaf9f
refactor: migrate SWR to TanStack Query v5 (#6713)
Replace swr with @tanstack/react-query v5 across all hooks, providers,
and components. Introduce singleton QueryClient, WS subscription pattern
via useQuery+useEffect, and enforce component-layer cache access contract.
2026-04-03 08:15:51 +00:00

87 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useQuery } from '@tanstack/react-query'
import { useRef } from 'react'
import { closeAllConnections } from 'tauri-plugin-mihomo-api'
import { useVerge } from '@/hooks/use-verge'
import { useAppData } from '@/providers/app-data-context'
import { getAutotemProxy } from '@/services/cmds'
import { queryClient } from '@/services/query-client'
// 系统代理状态检测统一逻辑
export const useSystemProxyState = () => {
const { verge, mutateVerge, patchVerge } = useVerge()
const { sysproxy, clashConfig } = useAppData()
const { data: autoproxy } = useQuery({
queryKey: ['getAutotemProxy'],
queryFn: getAutotemProxy,
refetchOnWindowFocus: true,
refetchOnReconnect: true,
})
const {
enable_system_proxy,
proxy_auto_config,
proxy_host,
verge_mixed_port,
} = verge ?? {}
// OS 实际状态enable + 地址匹配本应用
const indicator = (() => {
const host = proxy_host || '127.0.0.1'
if (proxy_auto_config) {
if (!autoproxy?.enable) return false
const pacPort = import.meta.env.DEV ? 11233 : 33331
return autoproxy.url === `http://${host}:${pacPort}/commands/pac`
} else {
if (!sysproxy?.enable) return false
const port = verge_mixed_port || clashConfig?.mixedPort || 7897
return sysproxy.server === `${host}:${port}`
}
})()
// "最后一次生效"模式:快速连续点击时,只执行最终状态
const pendingRef = useRef<boolean | null>(null)
const busyRef = useRef(false)
const toggleSystemProxy = async (enabled: boolean) => {
mutateVerge(
(prev) => (prev ? { ...prev, enable_system_proxy: enabled } : prev),
false,
)
pendingRef.current = enabled
if (busyRef.current) return
busyRef.current = true
try {
while (pendingRef.current !== null) {
const target = pendingRef.current
pendingRef.current = null
if (!target && verge?.auto_close_connection) {
await closeAllConnections().catch(() => {})
}
await patchVerge({ enable_system_proxy: target })
}
} finally {
busyRef.current = false
await Promise.all([
queryClient.invalidateQueries({ queryKey: ['getSystemProxy'] }),
queryClient.invalidateQueries({ queryKey: ['getAutotemProxy'] }),
])
}
}
const invalidateProxyState = () =>
Promise.all([
queryClient.invalidateQueries({ queryKey: ['getSystemProxy'] }),
queryClient.invalidateQueries({ queryKey: ['getAutotemProxy'] }),
])
return {
indicator,
configState: enable_system_proxy ?? false,
toggleSystemProxy,
invalidateProxyState,
}
}