Files
clash-verge-rev/src/hooks/use-proxy-delay-state.ts
T
wonfen 5e6a696087 revert(tray): revert per-group latency testing (#8173)
This reverts commit cb751052a4.

Remove the tray latency test and its dashboard URL persistence and cache
changes because the two entry points have diverging behavior.

Preserve the subsequent IPC binding migration and remove generated fields,
input projections, and locale entries that depended on the reverted feature.
2026-10-21 05:37:18 +08:00

100 lines
2.6 KiB
TypeScript

import { useLockFn } from 'ahooks'
import { useCallback, useEffect, useReducer } from 'react'
import { useVerge } from '@/hooks/use-verge'
import delayManager, { type DelayUpdate } from '@/services/delay'
import {
isInteractableMember,
memberDetails,
type ResolvedProxyMember,
} from '@/types/proxy-view'
const PRESET_PROXY_NAMES = [
'DIRECT',
'REJECT',
'REJECT-DROP',
'PASS',
'COMPATIBLE',
]
const identity = (_: DelayUpdate, next: DelayUpdate): DelayUpdate => next
const INITIAL_DELAY: DelayUpdate = { delay: -1, updatedAt: 0 }
export interface UseProxyDelayState {
delayState: DelayUpdate
delayValue: number
isPreset: boolean
timeout: number
onDelay: () => Promise<void>
}
export function useProxyDelayState(
member: ResolvedProxyMember,
groupName: string,
): UseProxyDelayState {
const name = member.ref.name
const details = memberDetails(member)
const unresolved = member.kind === 'unresolved'
const isPreset = unresolved || PRESET_PROXY_NAMES.includes(name)
const [delayState, setDelayState] = useReducer(identity, INITIAL_DELAY)
const { verge } = useVerge()
const timeout = verge?.default_latency_timeout || 10000
useEffect(() => {
if (isPreset) return
delayManager.setListener(name, groupName, setDelayState)
return () => {
delayManager.removeListener(name, groupName)
}
}, [name, groupName, isPreset])
const updateDelay = useCallback(() => {
if (unresolved) {
setDelayState(INITIAL_DELAY)
return
}
const cachedUpdate = delayManager.getDelayUpdate(name, groupName)
if (cachedUpdate) {
setDelayState({ ...cachedUpdate })
return
}
const fallbackDelay = delayManager.getDelayFix(member, groupName)
if (fallbackDelay === -1) {
setDelayState({ delay: -1, updatedAt: 0 })
return
}
let updatedAt = 0
const history = details?.history
if (history && history.length > 0) {
const lastRecord = history[history.length - 1]
const parsed = Date.parse(lastRecord.time)
if (!Number.isNaN(parsed)) {
updatedAt = parsed
}
}
setDelayState({ delay: fallbackDelay, updatedAt })
}, [details?.history, groupName, member, name, unresolved])
useEffect(() => {
updateDelay()
}, [updateDelay])
const onDelay = useLockFn(async () => {
if (!isInteractableMember(member)) return
setDelayState({ delay: -2, updatedAt: Date.now() })
setDelayState(await delayManager.checkDelay(member, groupName, timeout))
})
return {
delayState,
delayValue: delayState.delay,
isPreset,
timeout,
onDelay,
}
}