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>
)
}