Skip to content

Commit

Permalink
proxy order
Browse files Browse the repository at this point in the history
  • Loading branch information
pompurin404 committed Aug 4, 2024
1 parent 3730d09 commit 77d2517
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 39 deletions.
1 change: 1 addition & 0 deletions src/main/utils/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export const defaultConfig: IAppConfig = {
core: 'mihomo',
silentStart: false,
proxyDisplayMode: 'simple',
proxyDisplayOrder: 'default',
sysProxy: { enable: false, mode: 'manual' }
}

Expand Down
35 changes: 17 additions & 18 deletions src/renderer/src/components/proxies/proxy-item.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Button, Card, CardBody } from '@nextui-org/react'
import React, { useEffect, useState } from 'react'
import React, { useEffect, useMemo, useState } from 'react'
import PubSub from 'pubsub-js'

interface Props {
Expand All @@ -14,12 +14,14 @@ interface Props {

const ProxyItem: React.FC<Props> = (props) => {
const { mutateProxies, proxyDisplayMode, group, proxy, selected, onSelect, onProxyDelay } = props
const [delay, setDelay] = useState(() => {

const delay = useMemo(() => {
if (proxy.history.length > 0) {
return proxy.history[proxy.history.length - 1].delay
}
return -1
})
}, [proxy])

const [loading, setLoading] = useState(false)

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

const onDelay = (): void => {
setLoading(true)
onProxyDelay(proxy.name, group.testUrl).then(
(delay) => {
setDelay(delay.delay || 0)
mutateProxies()
setLoading(false)
},
() => {
setDelay(0)
setLoading(false)
}
)
onProxyDelay(proxy.name, group.testUrl).finally(() => {
mutateProxies()
setLoading(false)
})
}
console.log(delay)

useEffect(() => {
const token = PubSub.subscribe(`${group.name}-delay`, onDelay)
Expand All @@ -58,6 +52,7 @@ const ProxyItem: React.FC<Props> = (props) => {
PubSub.unsubscribe(token)
}
}, [])

return (
<Card
onPress={() => onSelect(group.name, proxy.name)}
Expand All @@ -66,12 +61,16 @@ const ProxyItem: React.FC<Props> = (props) => {
className={`${selected ? 'bg-primary/30' : ''}`}
radius="sm"
>
<CardBody className="p-1">
<CardBody className="p-2">
<div className="flex justify-between items-center">
<div>
<div className="inline">{proxy.name}</div>
<div className="inline text-ellipsis whitespace-nowrap overflow-hidden">
{proxy.name}
</div>
{proxyDisplayMode === 'full' && (
<div className="inline ml-2 text-default-500">{proxy.type}</div>
<div className="inline ml-2 text-ellipsis whitespace-nowrap overflow-hidden text-default-500">
{proxy.type}
</div>
)}
</div>
<Button
Expand Down
106 changes: 86 additions & 20 deletions src/renderer/src/pages/proxies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@ import BasePage from '@renderer/components/base/base-page'
import { useAppConfig } from '@renderer/hooks/use-app-config'
import { mihomoChangeProxy, mihomoProxies, mihomoProxyDelay } from '@renderer/utils/ipc'
import { CgDetailsLess, CgDetailsMore } from 'react-icons/cg'
import { useMemo, useState } from 'react'
import { FaBoltLightning } from 'react-icons/fa6'
import { TbCircleLetterD } from 'react-icons/tb'
import { FaLocationCrosshairs } from 'react-icons/fa6'
import { RxLetterCaseCapitalize } from 'react-icons/rx'
import { useMemo, useRef, useState } from 'react'
import useSWR from 'swr'
import { GroupedVirtuoso } from 'react-virtuoso'
import { GroupedVirtuoso, GroupedVirtuosoHandle } from 'react-virtuoso'
import ProxyItem from '@renderer/components/proxies/proxy-item'
import { IoIosArrowBack } from 'react-icons/io'
import { MdOutlineSpeed } from 'react-icons/md'

const Proxies: React.FC = () => {
const { data: proxies, mutate } = useSWR('mihomoProxies', mihomoProxies)
const { appConfig, patchAppConfig } = useAppConfig()
const { proxyDisplayMode = 'simple' } = appConfig || {}
const { proxyDisplayMode = 'simple', proxyDisplayOrder = 'default' } = appConfig || {}

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

const [isOpen, setIsOpen] = useState(Array(groups.length).fill(false))

const virtuosoRef = useRef<GroupedVirtuosoHandle>(null)
const { groupCounts, allProxies } = useMemo(() => {
const groupCounts = groups.map((group, index) => {
return isOpen[index] ? group.all.length : 0
})
const allProxies: (IMihomoProxy | IMihomoGroup)[] = []
groups.forEach((group, index) => {
if (isOpen[index] && proxies) {
allProxies.push(...group.all.map((name) => proxies.proxies[name]))
let groupProxies = group.all.map((name) => proxies.proxies[name])
if (proxyDisplayOrder === 'delay') {
groupProxies = groupProxies.sort((a, b) => {
if (a.history.length === 0) return 1
if (b.history.length === 0) return -1
return a.history[a.history.length - 1].delay - b.history[b.history.length - 1].delay
})
}
if (proxyDisplayOrder === 'name') {
groupProxies = groupProxies.sort((a, b) => a.name.localeCompare(b.name))
}
allProxies.push(...groupProxies)
}
})

return { groupCounts, allProxies }
}, [groups, isOpen])
}, [groups, isOpen, proxyDisplayOrder])

const onChangeProxy = (group: string, proxy: string): void => {
mihomoChangeProxy(group, proxy).then(() => {
Expand All @@ -69,22 +84,50 @@ const Proxies: React.FC = () => {
<BasePage
title="代理组"
header={
<Button
size="sm"
isIconOnly
onPress={() => {
patchAppConfig({ proxyDisplayMode: proxyDisplayMode === 'simple' ? 'full' : 'simple' })
}}
>
{proxyDisplayMode === 'simple' ? (
<CgDetailsMore size={20} />
) : (
<CgDetailsLess size={20} />
)}
</Button>
<div>
<Button
size="sm"
isIconOnly
onPress={() => {
patchAppConfig({
proxyDisplayOrder:
proxyDisplayOrder === 'default'
? 'delay'
: proxyDisplayOrder === 'delay'
? 'name'
: 'default'
})
}}
>
{proxyDisplayOrder === 'default' ? (
<TbCircleLetterD size={20} title="默认" />
) : proxyDisplayOrder === 'delay' ? (
<FaBoltLightning size={16} title="延迟" />
) : (
<RxLetterCaseCapitalize size={22} title="名称" />
)}
</Button>
<Button
size="sm"
isIconOnly
className="ml-2"
onPress={() => {
patchAppConfig({
proxyDisplayMode: proxyDisplayMode === 'simple' ? 'full' : 'simple'
})
}}
>
{proxyDisplayMode === 'simple' ? (
<CgDetailsMore size={20} title="详细信息" />
) : (
<CgDetailsLess size={20} title="简洁信息" />
)}
</Button>
</div>
}
>
<GroupedVirtuoso
ref={virtuosoRef}
style={{ height: 'calc(100vh - 50px)' }}
groupCounts={groupCounts}
groupContent={(index) => {
Expand Down Expand Up @@ -112,7 +155,7 @@ const Proxies: React.FC = () => {
src={groups[index].icon}
/>
) : null}
<div className="h-[32px] text-md leading-[32px]">
<div className="h-[32px] text-ellipsis whitespace-nowrap overflow-hidden text-md leading-[32px]">
{groups[index].name}
{proxyDisplayMode === 'full' && (
<>
Expand All @@ -128,6 +171,29 @@ const Proxies: React.FC = () => {
</div>
<div className="flex">
<Button
title="定位到当前节点"
variant="light"
size="sm"
isIconOnly
onPress={() => {
if (!isOpen[index]) return
let i = 0
for (let j = 0; j < index; j++) {
i += groupCounts[j]
}
for (let j = 0; j < groupCounts[index]; j++) {
if (allProxies[i + j].name === groups[index].now) {
i += j
break
}
}
virtuosoRef.current?.scrollToIndex({ index: i, align: 'start' })
}}
>
<FaLocationCrosshairs className="text-lg text-default-500" />
</Button>
<Button
title="延迟测试"
variant="light"
size="sm"
isIconOnly
Expand Down
1 change: 0 additions & 1 deletion src/renderer/src/utils/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export async function mihomoChangeProxy(group: string, proxy: string): Promise<I

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

Expand Down
1 change: 1 addition & 0 deletions src/shared/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ interface ISysProxyConfig {
interface IAppConfig {
core: 'mihomo' | 'mihomo-alpha'
proxyDisplayMode: 'simple' | 'full'
proxyDisplayOrder: 'default' | 'delay' | 'name'
silentStart: boolean
sysProxy: ISysProxyConfig
userAgent?: string
Expand Down

0 comments on commit 77d2517

Please sign in to comment.