Skip to content

Commit

Permalink
proxy delay
Browse files Browse the repository at this point in the history
  • Loading branch information
Pompurin404 committed Aug 3, 2024
1 parent 8361a73 commit db1766b
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 23 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"electron-updater": "^6.2.1",
"framer-motion": "^11.3.19",
"next-themes": "^0.3.0",
"pubsub-js": "^1.9.4",
"react-icons": "^5.2.1",
"react-monaco-editor": "^0.55.0",
"react-router-dom": "^6.25.1",
Expand All @@ -40,6 +41,7 @@
"@electron-toolkit/eslint-config-ts": "^2.0.0",
"@electron-toolkit/tsconfig": "^1.0.1",
"@types/node": "^22.0.0",
"@types/pubsub-js": "^1.8.6",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/ws": "^8.5.12",
Expand Down
16 changes: 16 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion src/main/core/mihomoApi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import axios, { AxiosInstance } from 'axios'
import { getControledMihomoConfig } from '../config'
import { getAppConfig, getControledMihomoConfig } from '../config'
import WebSocket from 'ws'
import { window } from '..'

Expand Down Expand Up @@ -59,6 +59,19 @@ export const mihomoChangeProxy = async (group: string, proxy: string): Promise<I
return instance.put(`/proxies/${encodeURIComponent(group)}`, { name: proxy })
}

export const mihomoProxyDelay = async (proxy: string, url?: string): Promise<IMihomoDelay> => {
const appConfig = getAppConfig()
const { delayTestUrl, delayTestTimeout } = appConfig
const instance = await getAxios()
return instance.get(`/proxies/${encodeURIComponent(proxy)}/delay`, {
params: {
url: url || delayTestUrl || 'https://www.gstatic.com/generate_204',
timeout: delayTestTimeout || 5000
},
timeout: delayTestTimeout || 5000
})
}

export const startMihomoTraffic = (): void => {
mihomoTraffic()
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/utils/cmds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
mihomoConfig,
mihomoConnections,
mihomoProxies,
mihomoProxyDelay,
mihomoRules,
mihomoVersion,
patchMihomoConfig,
Expand Down Expand Up @@ -33,6 +34,7 @@ export function registerIpcMainHandlers(): void {
ipcMain.handle('mihomoRules', mihomoRules)
ipcMain.handle('mihomoProxies', () => mihomoProxies())
ipcMain.handle('mihomoChangeProxy', (_e, group, proxy) => mihomoChangeProxy(group, proxy))
ipcMain.handle('mihomoProxyDelay', (_e, proxy, url) => mihomoProxyDelay(proxy, url))
ipcMain.handle('startMihomoLogs', startMihomoLogs)
ipcMain.handle('stopMihomoLogs', () => stopMihomoLogs())
ipcMain.handle('patchMihomoConfig', async (_e, patch) => await patchMihomoConfig(patch))
Expand Down
76 changes: 70 additions & 6 deletions src/renderer/src/components/proxies/proxy-item.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,92 @@
import { Card, CardBody, Divider } from '@nextui-org/react'
import React from 'react'
import { Button, Card, CardBody, Divider } from '@nextui-org/react'
import { useAppConfig } from '@renderer/hooks/use-config'
import PubSub from 'pubsub-js'
import React, { useEffect, useState } from 'react'

interface Props {
onProxyDelay: (proxy: string) => Promise<IMihomoDelay>
proxyDisplayMode: 'simple' | 'full'
proxy: IMihomoProxy | IMihomoGroup
group: string
onSelect: (proxy: string) => void
selected: boolean
}

const ProxyItem: React.FC<Props> = (props) => {
const { proxy, selected, onSelect } = props
const { proxyDisplayMode, group, proxy, selected, onSelect, onProxyDelay } = props
const { appConfig } = useAppConfig()
const { delayTestTimeout = 5000 } = appConfig || {}
const [delay, setDelay] = useState(() => {
if (proxy.history.length > 0) {
return proxy.history[0].delay
}
return 0
})
const [loading, setLoading] = useState(false)

function delayColor(delay: number): 'primary' | 'success' | 'warning' | 'danger' {
if (delay < 0) return 'danger'
if (delay === 0) return 'primary'
if (delay < 500) return 'success'
if (delay < delayTestTimeout) return 'warning'
return 'danger'
}

function delayText(delay: number): string {
if (delay < 0) return 'Error'
if (delay === 0) return 'Delay'
if (delay < delayTestTimeout) return delay.toString()
return 'Timeout'
}

const onDelay = (): void => {
setLoading(true)
onProxyDelay(proxy.name).then(
(delay) => {
setDelay(delay.delay || delayTestTimeout + 1)
setLoading(false)
},
() => {
setDelay(-1)
setLoading(false)
}
)
}

useEffect(() => {
const token = PubSub.subscribe(`${group}-delay`, onDelay)

return (): void => {
PubSub.unsubscribe(token)
}
}, [])
return (
<>
<Divider />
<Card
onPress={() => onSelect(proxy.name)}
isPressable
fullWidth
className={`my-1 ${selected ? 'bg-primary' : ''}`}
className={`my-1 ${selected ? 'bg-primary/30' : ''}`}
radius="sm"
>
<CardBody className="p-1">
<div className="flex justify-between items-center">
<div>{proxy.name}</div>
<div className="mx-2 text-sm">{proxy.history.length > 0 && proxy.history[0].delay}</div>
<div>
<div className="inline">{proxy.name}</div>
{proxyDisplayMode === 'full' && (
<div className="inline ml-2 text-default-500">{proxy.type}</div>
)}
</div>
<Button
isLoading={loading}
color={delayColor(delay)}
onPress={onDelay}
variant="light"
className="h-full min-w-[50px] p-0 mx-2 text-sm hover:bg-content"
>
{delayText(delay)}
</Button>
</div>
</CardBody>
</Card>
Expand Down
8 changes: 7 additions & 1 deletion src/renderer/src/components/proxies/proxy-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import { Virtuoso } from 'react-virtuoso'
import ProxyItem from './proxy-item'

interface Props {
onProxyDelay: (proxy: string) => Promise<IMihomoDelay>
onChangeProxy: (proxy: string) => void
proxyDisplayMode: 'simple' | 'full'
proxies: (IMihomoProxy | IMihomoGroup)[]
group: string
now: string
}

const ProxyList: React.FC<Props> = (props) => {
const { onChangeProxy, proxies, now } = props
const { proxyDisplayMode, onProxyDelay, onChangeProxy, proxies, group, now } = props

return (
<Virtuoso
Expand All @@ -18,8 +21,11 @@ const ProxyList: React.FC<Props> = (props) => {
increaseViewportBy={100}
itemContent={(index) => (
<ProxyItem
onProxyDelay={onProxyDelay}
onSelect={onChangeProxy}
proxy={proxies[index]}
group={group}
proxyDisplayMode={proxyDisplayMode}
selected={proxies[index].name === now}
/>
)}
Expand Down
41 changes: 33 additions & 8 deletions src/renderer/src/components/sider/proxy-card.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,53 @@
import { Button, Card, CardBody, CardFooter } from '@nextui-org/react'
import { SiSpeedtest } from 'react-icons/si'
import { Button, Card, CardBody, CardFooter, Chip } from '@nextui-org/react'
import { mihomoProxies } from '@renderer/utils/ipc'
import { SiNginxproxymanager } from 'react-icons/si'
import { useLocation, useNavigate } from 'react-router-dom'
import useSWR from 'swr'

const ProxyCard: React.FC = () => {
const navigate = useNavigate()
const location = useLocation()
const match = location.pathname.includes('/proxies')
const { data: proxies = { proxies: {} } } = useSWR('mihomoProxies', mihomoProxies)
return (
<Card
fullWidth
className={`mb-2 ${match ? 'bg-primary' : ''}`}
isPressable
onPress={() => navigate('/proxies')}
>
<CardBody>
<div className="flex justify-between h-[32px]">
<h3 className="select-none text-md font-bold leading-[32px]">节点名称</h3>
<Button isIconOnly size="sm" variant="light" color="default">
<SiSpeedtest color="default" className="text-[20px]" />
<CardBody className="pb-1 pt-0 px-0">
<div className="flex justify-between">
<Button
isIconOnly
className="bg-transparent pointer-events-none"
variant="flat"
color="default"
>
<SiNginxproxymanager color="default" className="text-[20px]" />
</Button>
<Chip
classNames={
match
? {
base: 'border-foreground',
content: 'text-foreground'
}
: {
base: 'border-primary',
content: 'text-primary'
}
}
size="sm"
variant="bordered"
className="mr-3 mt-2"
>
{Object.keys(proxies.proxies).length ?? 0}
</Chip>
</div>
</CardBody>
<CardFooter className="pt-1">
<small>二级节点</small>
<h3 className="select-none text-md font-bold">代理组</h3>
</CardFooter>
</Card>
)
Expand Down
Loading

0 comments on commit db1766b

Please sign in to comment.