mirror of
https://github.com/woodchen-ink/clash-and-dashboard.git
synced 2025-07-18 14:01:56 +08:00
77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
import React, { useMemo, useLayoutEffect, useCallback } from 'react'
|
|
import { ResultAsync } from 'neverthrow'
|
|
import type{ AxiosError } from 'axios'
|
|
import classnames from 'classnames'
|
|
import { BaseComponentProps } from '@models'
|
|
import { useProxy } from '@stores'
|
|
import { getProxyDelay, Proxy as IProxy } from '@lib/request'
|
|
import EE, { Action } from '@lib/event'
|
|
import { isClashX, jsBridge } from '@lib/jsBridge'
|
|
|
|
import './style.scss'
|
|
|
|
interface ProxyProps extends BaseComponentProps {
|
|
config: IProxy
|
|
}
|
|
|
|
const TagColors = {
|
|
'#909399': 0,
|
|
'#00c520': 260,
|
|
'#ff9a28': 600,
|
|
'#ff3e5e': Infinity
|
|
}
|
|
|
|
async function getDelay (name: string) {
|
|
if (isClashX()) {
|
|
const delay = await jsBridge?.getProxyDelay(name) ?? 0
|
|
return delay
|
|
}
|
|
|
|
const { data: { delay } } = await getProxyDelay(name)
|
|
return delay
|
|
}
|
|
|
|
export function Proxy (props: ProxyProps) {
|
|
const { config, className } = props
|
|
const { set } = useProxy()
|
|
|
|
const speedTest = useCallback(async function () {
|
|
const result = await ResultAsync.fromPromise(getDelay(config.name), e => e as AxiosError)
|
|
|
|
const validDelay = result.isErr() ? 0 : result.value
|
|
set(draft => {
|
|
const proxy = draft.proxies.find(p => p.name === config.name)
|
|
if (proxy) {
|
|
proxy.history.push({ time: Date.now().toString(), delay: validDelay })
|
|
}
|
|
})
|
|
}, [config.name, set])
|
|
|
|
const delay = useMemo(
|
|
() => config.history?.length ? config.history.slice(-1)[0].delay : 0,
|
|
[config]
|
|
)
|
|
|
|
useLayoutEffect(() => {
|
|
EE.subscribe(Action.SPEED_NOTIFY, speedTest)
|
|
return () => EE.unsubscribe(Action.SPEED_NOTIFY, speedTest)
|
|
}, [speedTest])
|
|
|
|
const hasError = useMemo(() => delay === 0, [delay])
|
|
const color = useMemo(() =>
|
|
Object.keys(TagColors).find(
|
|
threshold => delay <= TagColors[threshold as keyof typeof TagColors]
|
|
),
|
|
[delay]
|
|
)
|
|
|
|
const backgroundColor = hasError ? undefined : color
|
|
return (
|
|
<div className={classnames('proxy-item', { 'proxy-error': hasError }, className)}>
|
|
<span className="proxy-type" style={{ backgroundColor }}>{config.type}</span>
|
|
<p className="proxy-name">{config.name}</p>
|
|
<p className="proxy-delay">{delay === 0 ? '-' : `${delay}ms`}</p>
|
|
</div>
|
|
)
|
|
}
|