diff --git a/src/main/core/mihomoApi.ts b/src/main/core/mihomoApi.ts index 942f7fa..39cd5e6 100644 --- a/src/main/core/mihomoApi.ts +++ b/src/main/core/mihomoApi.ts @@ -4,6 +4,7 @@ import { mainWindow } from '..' import WebSocket from 'ws' import { tray } from '../resolve/tray' import { calcTraffic } from '../utils/calc' +import { getRuntimeConfig } from './factory' let axiosIns: AxiosInstance = null! let mihomoTrafficWs: WebSocket | null = null @@ -75,6 +76,28 @@ export const mihomoProxies = async (): Promise => { return await instance.get('/proxies') } +export const mihomoGroups = async (): Promise => { + const proxies = await mihomoProxies() + const runtime = await getRuntimeConfig() + const groups: IMihomoMixedGroup[] = [] + runtime?.['proxy-groups']?.forEach((group: { name: string; url?: string }) => { + group = Object.assign(group, group['<<']) + const { name, url } = group + if (proxies.proxies[name] && 'all' in proxies.proxies[name] && !proxies.proxies[name].hidden) { + const newGroup = proxies.proxies[name] + newGroup.testUrl = url + const newAll = newGroup.all.map((name) => proxies.proxies[name]) + groups.push({ ...newGroup, all: newAll }) + } + }) + if (!groups.find((group) => group.name === 'GLOBAL')) { + const newGlobal = proxies.proxies['GLOBAL'] as IMihomoGroup + const newAll = newGlobal.all.map((name) => proxies.proxies[name]) + groups.push({ ...newGlobal, all: newAll }) + } + return groups +} + export const mihomoProxyProviders = async (): Promise => { const instance = await getAxios() return await instance.get('/providers/proxies') diff --git a/src/main/utils/ipc.ts b/src/main/utils/ipc.ts index 9721497..0fc6870 100644 --- a/src/main/utils/ipc.ts +++ b/src/main/utils/ipc.ts @@ -4,6 +4,7 @@ import { mihomoCloseAllConnections, mihomoCloseConnection, mihomoGroupDelay, + mihomoGroups, mihomoProxies, mihomoProxyDelay, mihomoProxyProviders, @@ -71,6 +72,7 @@ export function registerIpcMainHandlers(): void { ipcMain.handle('mihomoCloseAllConnections', ipcErrorWrapper(mihomoCloseAllConnections)) ipcMain.handle('mihomoRules', ipcErrorWrapper(mihomoRules)) ipcMain.handle('mihomoProxies', ipcErrorWrapper(mihomoProxies)) + ipcMain.handle('mihomoGroups', ipcErrorWrapper(mihomoGroups)) ipcMain.handle('mihomoProxyProviders', ipcErrorWrapper(mihomoProxyProviders)) ipcMain.handle('mihomoUpdateProxyProviders', (_e, name) => ipcErrorWrapper(mihomoUpdateProxyProviders)(name) diff --git a/src/renderer/src/components/proxies/proxy-item.tsx b/src/renderer/src/components/proxies/proxy-item.tsx index 629c13a..dd0fdb1 100644 --- a/src/renderer/src/components/proxies/proxy-item.tsx +++ b/src/renderer/src/components/proxies/proxy-item.tsx @@ -7,7 +7,7 @@ interface Props { onProxyDelay: (proxy: string, url?: string) => Promise proxyDisplayMode: 'simple' | 'full' proxy: IMihomoProxy | IMihomoGroup - group: IMihomoGroup + group: IMihomoMixedGroup onSelect: (group: string, proxy: string) => void selected: boolean } diff --git a/src/renderer/src/components/sider/proxy-card.tsx b/src/renderer/src/components/sider/proxy-card.tsx index 0c5caba..3357ada 100644 --- a/src/renderer/src/components/sider/proxy-card.tsx +++ b/src/renderer/src/components/sider/proxy-card.tsx @@ -1,17 +1,16 @@ import { Button, Card, CardBody, CardFooter, Chip } from '@nextui-org/react' -import { mihomoProxies } from '@renderer/utils/ipc' -import { useMemo } from 'react' import { useSortable } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { LuGroup } from 'react-icons/lu' import { useLocation, useNavigate } from 'react-router-dom' import useSWR from 'swr' +import { mihomoGroups } from '@renderer/utils/ipc' const ProxyCard: React.FC = () => { const navigate = useNavigate() const location = useLocation() const match = location.pathname.includes('/proxies') - const { data: proxies } = useSWR('mihomoProxies', mihomoProxies) + const { data: groups = [] } = useSWR('mihomoGroups', mihomoGroups) const { attributes, listeners, @@ -23,11 +22,6 @@ const ProxyCard: React.FC = () => { id: 'proxy' }) const transform = tf ? { x: tf.x, y: tf.y, scaleX: 1, scaleY: 1 } : null - const filtered = useMemo(() => { - if (!proxies) return [] - if (!proxies.proxies) return [] - return Object.keys(proxies.proxies).filter((key) => 'all' in proxies.proxies[key]) - }, [proxies]) return (
{ variant="bordered" className="mr-2 mt-2" > - {filtered.length} + {groups.length}
diff --git a/src/renderer/src/pages/proxies.tsx b/src/renderer/src/pages/proxies.tsx index 92724a4..cef658e 100644 --- a/src/renderer/src/pages/proxies.tsx +++ b/src/renderer/src/pages/proxies.tsx @@ -2,11 +2,10 @@ import { Avatar, Button, Card, CardBody, Chip } from '@nextui-org/react' import BasePage from '@renderer/components/base/base-page' import { useAppConfig } from '@renderer/hooks/use-app-config' import { - getRuntimeConfig, mihomoChangeProxy, mihomoCloseAllConnections, mihomoGroupDelay, - mihomoProxies, + mihomoGroups, mihomoProxyDelay } from '@renderer/utils/ipc' import { CgDetailsLess, CgDetailsMore } from 'react-icons/cg' @@ -22,38 +21,13 @@ import { IoIosArrowBack } from 'react-icons/io' import { MdOutlineSpeed } from 'react-icons/md' const Proxies: React.FC = () => { - const { data: proxies, mutate } = useSWR('mihomoProxies', mihomoProxies) - const { data: runtime } = useSWR('getRuntimeConfig', getRuntimeConfig) + const { data: groups = [], mutate } = useSWR('mihomoGroups', mihomoGroups) const { appConfig, patchAppConfig } = useAppConfig() const { proxyDisplayMode = 'simple', proxyDisplayOrder = 'default', autoCloseConnection = true } = appConfig || {} - - const groups = useMemo(() => { - if (!proxies) return [] - if (!proxies.proxies) return [] - const groups: IMihomoGroup[] = [] - runtime?.['proxy-groups']?.forEach((group: { name: string; url?: string }) => { - group = Object.assign(group, group['<<']) - const { name, url } = group - if ( - proxies.proxies[name] && - isGroup(proxies.proxies[name]) && - !proxies.proxies[name].hidden - ) { - const newGroup = proxies.proxies[name] - newGroup.testUrl = url - groups.push(newGroup as IMihomoGroup) - } - }) - if (!groups.find((group) => group.name === 'GLOBAL')) { - groups.push(proxies.proxies['GLOBAL'] as IMihomoGroup) - } - return groups - }, [proxies, runtime]) - const [isOpen, setIsOpen] = useState(Array(groups.length).fill(false)) const virtuosoRef = useRef(null) const { groupCounts, allProxies } = useMemo(() => { @@ -62,8 +36,8 @@ const Proxies: React.FC = () => { }) const allProxies: (IMihomoProxy | IMihomoGroup)[] = [] groups.forEach((group, index) => { - if (isOpen[index] && proxies) { - let groupProxies = group.all.map((name) => proxies.proxies[name]) + if (isOpen[index]) { + let groupProxies = group.all if (proxyDisplayOrder === 'delay') { groupProxies = groupProxies.sort((a, b) => { if (a.history.length === 0) return -1 @@ -267,8 +241,4 @@ const Proxies: React.FC = () => { ) } -function isGroup(proxy: IMihomoProxy | IMihomoGroup): proxy is IMihomoGroup { - return 'all' in proxy -} - export default Proxies diff --git a/src/renderer/src/utils/ipc.ts b/src/renderer/src/utils/ipc.ts index 0803ce9..e8abc7c 100644 --- a/src/renderer/src/utils/ipc.ts +++ b/src/renderer/src/utils/ipc.ts @@ -27,6 +27,10 @@ export async function mihomoProxies(): Promise { return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('mihomoProxies')) } +export async function mihomoGroups(): Promise { + return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('mihomoGroups')) +} + export async function mihomoProxyProviders(): Promise { return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('mihomoProxyProviders')) } diff --git a/src/shared/types.d.ts b/src/shared/types.d.ts index 0417dcd..ad9109f 100644 --- a/src/shared/types.d.ts +++ b/src/shared/types.d.ts @@ -162,6 +162,10 @@ interface IMihomoProxies { proxies: Record } +interface IMihomoMixedGroup extends IMihomoGroup { + all: (IMihomoProxy | IMihomoGroup)[] +} + interface IMihomoRuleProviders { providers: Record }