Skip to content

Commit 77d2517

Browse files
author
pompurin404
committed
proxy order
1 parent 3730d09 commit 77d2517

File tree

5 files changed

+105
-39
lines changed

5 files changed

+105
-39
lines changed

src/main/utils/template.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export const defaultConfig: IAppConfig = {
22
core: 'mihomo',
33
silentStart: false,
44
proxyDisplayMode: 'simple',
5+
proxyDisplayOrder: 'default',
56
sysProxy: { enable: false, mode: 'manual' }
67
}
78

src/renderer/src/components/proxies/proxy-item.tsx

+17-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Button, Card, CardBody } from '@nextui-org/react'
2-
import React, { useEffect, useState } from 'react'
2+
import React, { useEffect, useMemo, useState } from 'react'
33
import PubSub from 'pubsub-js'
44

55
interface Props {
@@ -14,12 +14,14 @@ interface Props {
1414

1515
const ProxyItem: React.FC<Props> = (props) => {
1616
const { mutateProxies, proxyDisplayMode, group, proxy, selected, onSelect, onProxyDelay } = props
17-
const [delay, setDelay] = useState(() => {
17+
18+
const delay = useMemo(() => {
1819
if (proxy.history.length > 0) {
1920
return proxy.history[proxy.history.length - 1].delay
2021
}
2122
return -1
22-
})
23+
}, [proxy])
24+
2325
const [loading, setLoading] = useState(false)
2426

2527
function delayColor(delay: number): 'primary' | 'success' | 'warning' | 'danger' {
@@ -37,19 +39,11 @@ const ProxyItem: React.FC<Props> = (props) => {
3739

3840
const onDelay = (): void => {
3941
setLoading(true)
40-
onProxyDelay(proxy.name, group.testUrl).then(
41-
(delay) => {
42-
setDelay(delay.delay || 0)
43-
mutateProxies()
44-
setLoading(false)
45-
},
46-
() => {
47-
setDelay(0)
48-
setLoading(false)
49-
}
50-
)
42+
onProxyDelay(proxy.name, group.testUrl).finally(() => {
43+
mutateProxies()
44+
setLoading(false)
45+
})
5146
}
52-
console.log(delay)
5347

5448
useEffect(() => {
5549
const token = PubSub.subscribe(`${group.name}-delay`, onDelay)
@@ -58,6 +52,7 @@ const ProxyItem: React.FC<Props> = (props) => {
5852
PubSub.unsubscribe(token)
5953
}
6054
}, [])
55+
6156
return (
6257
<Card
6358
onPress={() => onSelect(group.name, proxy.name)}
@@ -66,12 +61,16 @@ const ProxyItem: React.FC<Props> = (props) => {
6661
className={`${selected ? 'bg-primary/30' : ''}`}
6762
radius="sm"
6863
>
69-
<CardBody className="p-1">
64+
<CardBody className="p-2">
7065
<div className="flex justify-between items-center">
7166
<div>
72-
<div className="inline">{proxy.name}</div>
67+
<div className="inline text-ellipsis whitespace-nowrap overflow-hidden">
68+
{proxy.name}
69+
</div>
7370
{proxyDisplayMode === 'full' && (
74-
<div className="inline ml-2 text-default-500">{proxy.type}</div>
71+
<div className="inline ml-2 text-ellipsis whitespace-nowrap overflow-hidden text-default-500">
72+
{proxy.type}
73+
</div>
7574
)}
7675
</div>
7776
<Button

src/renderer/src/pages/proxies.tsx

+86-20
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@ import BasePage from '@renderer/components/base/base-page'
33
import { useAppConfig } from '@renderer/hooks/use-app-config'
44
import { mihomoChangeProxy, mihomoProxies, mihomoProxyDelay } from '@renderer/utils/ipc'
55
import { CgDetailsLess, CgDetailsMore } from 'react-icons/cg'
6-
import { useMemo, useState } from 'react'
6+
import { FaBoltLightning } from 'react-icons/fa6'
7+
import { TbCircleLetterD } from 'react-icons/tb'
8+
import { FaLocationCrosshairs } from 'react-icons/fa6'
9+
import { RxLetterCaseCapitalize } from 'react-icons/rx'
10+
import { useMemo, useRef, useState } from 'react'
711
import useSWR from 'swr'
8-
import { GroupedVirtuoso } from 'react-virtuoso'
12+
import { GroupedVirtuoso, GroupedVirtuosoHandle } from 'react-virtuoso'
913
import ProxyItem from '@renderer/components/proxies/proxy-item'
1014
import { IoIosArrowBack } from 'react-icons/io'
1115
import { MdOutlineSpeed } from 'react-icons/md'
1216

1317
const Proxies: React.FC = () => {
1418
const { data: proxies, mutate } = useSWR('mihomoProxies', mihomoProxies)
1519
const { appConfig, patchAppConfig } = useAppConfig()
16-
const { proxyDisplayMode = 'simple' } = appConfig || {}
20+
const { proxyDisplayMode = 'simple', proxyDisplayOrder = 'default' } = appConfig || {}
1721

1822
const groups = useMemo(() => {
1923
const groups: IMihomoGroup[] = []
@@ -36,20 +40,31 @@ const Proxies: React.FC = () => {
3640
}, [proxies])
3741

3842
const [isOpen, setIsOpen] = useState(Array(groups.length).fill(false))
39-
43+
const virtuosoRef = useRef<GroupedVirtuosoHandle>(null)
4044
const { groupCounts, allProxies } = useMemo(() => {
4145
const groupCounts = groups.map((group, index) => {
4246
return isOpen[index] ? group.all.length : 0
4347
})
4448
const allProxies: (IMihomoProxy | IMihomoGroup)[] = []
4549
groups.forEach((group, index) => {
4650
if (isOpen[index] && proxies) {
47-
allProxies.push(...group.all.map((name) => proxies.proxies[name]))
51+
let groupProxies = group.all.map((name) => proxies.proxies[name])
52+
if (proxyDisplayOrder === 'delay') {
53+
groupProxies = groupProxies.sort((a, b) => {
54+
if (a.history.length === 0) return 1
55+
if (b.history.length === 0) return -1
56+
return a.history[a.history.length - 1].delay - b.history[b.history.length - 1].delay
57+
})
58+
}
59+
if (proxyDisplayOrder === 'name') {
60+
groupProxies = groupProxies.sort((a, b) => a.name.localeCompare(b.name))
61+
}
62+
allProxies.push(...groupProxies)
4863
}
4964
})
5065

5166
return { groupCounts, allProxies }
52-
}, [groups, isOpen])
67+
}, [groups, isOpen, proxyDisplayOrder])
5368

5469
const onChangeProxy = (group: string, proxy: string): void => {
5570
mihomoChangeProxy(group, proxy).then(() => {
@@ -69,22 +84,50 @@ const Proxies: React.FC = () => {
6984
<BasePage
7085
title="代理组"
7186
header={
72-
<Button
73-
size="sm"
74-
isIconOnly
75-
onPress={() => {
76-
patchAppConfig({ proxyDisplayMode: proxyDisplayMode === 'simple' ? 'full' : 'simple' })
77-
}}
78-
>
79-
{proxyDisplayMode === 'simple' ? (
80-
<CgDetailsMore size={20} />
81-
) : (
82-
<CgDetailsLess size={20} />
83-
)}
84-
</Button>
87+
<div>
88+
<Button
89+
size="sm"
90+
isIconOnly
91+
onPress={() => {
92+
patchAppConfig({
93+
proxyDisplayOrder:
94+
proxyDisplayOrder === 'default'
95+
? 'delay'
96+
: proxyDisplayOrder === 'delay'
97+
? 'name'
98+
: 'default'
99+
})
100+
}}
101+
>
102+
{proxyDisplayOrder === 'default' ? (
103+
<TbCircleLetterD size={20} title="默认" />
104+
) : proxyDisplayOrder === 'delay' ? (
105+
<FaBoltLightning size={16} title="延迟" />
106+
) : (
107+
<RxLetterCaseCapitalize size={22} title="名称" />
108+
)}
109+
</Button>
110+
<Button
111+
size="sm"
112+
isIconOnly
113+
className="ml-2"
114+
onPress={() => {
115+
patchAppConfig({
116+
proxyDisplayMode: proxyDisplayMode === 'simple' ? 'full' : 'simple'
117+
})
118+
}}
119+
>
120+
{proxyDisplayMode === 'simple' ? (
121+
<CgDetailsMore size={20} title="详细信息" />
122+
) : (
123+
<CgDetailsLess size={20} title="简洁信息" />
124+
)}
125+
</Button>
126+
</div>
85127
}
86128
>
87129
<GroupedVirtuoso
130+
ref={virtuosoRef}
88131
style={{ height: 'calc(100vh - 50px)' }}
89132
groupCounts={groupCounts}
90133
groupContent={(index) => {
@@ -112,7 +155,7 @@ const Proxies: React.FC = () => {
112155
src={groups[index].icon}
113156
/>
114157
) : null}
115-
<div className="h-[32px] text-md leading-[32px]">
158+
<div className="h-[32px] text-ellipsis whitespace-nowrap overflow-hidden text-md leading-[32px]">
116159
{groups[index].name}
117160
{proxyDisplayMode === 'full' && (
118161
<>
@@ -128,6 +171,29 @@ const Proxies: React.FC = () => {
128171
</div>
129172
<div className="flex">
130173
<Button
174+
title="定位到当前节点"
175+
variant="light"
176+
size="sm"
177+
isIconOnly
178+
onPress={() => {
179+
if (!isOpen[index]) return
180+
let i = 0
181+
for (let j = 0; j < index; j++) {
182+
i += groupCounts[j]
183+
}
184+
for (let j = 0; j < groupCounts[index]; j++) {
185+
if (allProxies[i + j].name === groups[index].now) {
186+
i += j
187+
break
188+
}
189+
}
190+
virtuosoRef.current?.scrollToIndex({ index: i, align: 'start' })
191+
}}
192+
>
193+
<FaLocationCrosshairs className="text-lg text-default-500" />
194+
</Button>
195+
<Button
196+
title="延迟测试"
131197
variant="light"
132198
size="sm"
133199
isIconOnly

src/renderer/src/utils/ipc.ts

-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ export async function mihomoChangeProxy(group: string, proxy: string): Promise<I
3232

3333
export async function mihomoProxyDelay(proxy: string, url?: string): Promise<IMihomoDelay> {
3434
const res = await window.electron.ipcRenderer.invoke('mihomoProxyDelay', proxy, url)
35-
console.log(res)
3635
return res
3736
}
3837

src/shared/types.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ interface ISysProxyConfig {
131131
interface IAppConfig {
132132
core: 'mihomo' | 'mihomo-alpha'
133133
proxyDisplayMode: 'simple' | 'full'
134+
proxyDisplayOrder: 'default' | 'delay' | 'name'
134135
silentStart: boolean
135136
sysProxy: ISysProxyConfig
136137
userAgent?: string

0 commit comments

Comments
 (0)