mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-25 21:22:20 +08:00
- Extract shared delay state logic from ProxyItem and ProxyItemMini into `useProxyDelayState` hook (src/hooks/use-proxy-delay-state.ts); JSX display thresholds preserved per-component. - Deduplicate rAF/setTimeout/Promise scheduling in DelayManager via a private `scheduleOnNextFrame` helper. - Drop no-op `useMemo(() => MODES, [])` in proxies page. - Replace `any` on `setClashLog` prev params and layout-traffic sx objects with proper types (`pre!`, `Pick<BoxProps|...>`).
88 lines
2.2 KiB
TypeScript
88 lines
2.2 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'
|
|
|
|
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(
|
|
proxy: IProxyItem,
|
|
groupName: string,
|
|
): UseProxyDelayState {
|
|
const isPreset = PRESET_PROXY_NAMES.includes(proxy.name)
|
|
const [delayState, setDelayState] = useReducer(identity, INITIAL_DELAY)
|
|
const { verge } = useVerge()
|
|
const timeout = verge?.default_latency_timeout || 10000
|
|
|
|
useEffect(() => {
|
|
if (isPreset) return
|
|
delayManager.setListener(proxy.name, groupName, setDelayState)
|
|
return () => {
|
|
delayManager.removeListener(proxy.name, groupName)
|
|
}
|
|
}, [proxy.name, groupName, isPreset])
|
|
|
|
const updateDelay = useCallback(() => {
|
|
if (!proxy) return
|
|
const cachedUpdate = delayManager.getDelayUpdate(proxy.name, groupName)
|
|
if (cachedUpdate) {
|
|
setDelayState({ ...cachedUpdate })
|
|
return
|
|
}
|
|
|
|
const fallbackDelay = delayManager.getDelayFix(proxy, groupName)
|
|
if (fallbackDelay === -1) {
|
|
setDelayState({ delay: -1, updatedAt: 0 })
|
|
return
|
|
}
|
|
|
|
let updatedAt = 0
|
|
const history = proxy.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 })
|
|
}, [proxy, groupName])
|
|
|
|
useEffect(() => {
|
|
updateDelay()
|
|
}, [updateDelay])
|
|
|
|
const onDelay = useLockFn(async () => {
|
|
setDelayState({ delay: -2, updatedAt: Date.now() })
|
|
setDelayState(await delayManager.checkDelay(proxy.name, groupName, timeout))
|
|
})
|
|
|
|
return {
|
|
delayState,
|
|
delayValue: delayState.delay,
|
|
isPreset,
|
|
timeout,
|
|
onDelay,
|
|
}
|
|
}
|