diff --git a/src/renderer/src/components/base/base-page.tsx b/src/renderer/src/components/base/base-page.tsx index eb79897..f726076 100644 --- a/src/renderer/src/components/base/base-page.tsx +++ b/src/renderer/src/components/base/base-page.tsx @@ -1,3 +1,4 @@ +import { Divider } from '@nextui-org/react' import React from 'react' interface Props { title?: React.ReactNode @@ -14,6 +15,7 @@ const BasePage: React.FC = (props) => {
{props.title}
{props.header}
+
{props.children}
diff --git a/src/renderer/src/components/proxies/proxy-item.tsx b/src/renderer/src/components/proxies/proxy-item.tsx index 42a7348..722e586 100644 --- a/src/renderer/src/components/proxies/proxy-item.tsx +++ b/src/renderer/src/components/proxies/proxy-item.tsx @@ -1,14 +1,14 @@ -import { Button, Card, CardBody, Divider } from '@nextui-org/react' +import { Button, Card, CardBody } from '@nextui-org/react' import { useAppConfig } from '@renderer/hooks/use-app-config' import PubSub from 'pubsub-js' import React, { useEffect, useState } from 'react' interface Props { - onProxyDelay: (proxy: string) => Promise + onProxyDelay: (proxy: string, url?: string) => Promise proxyDisplayMode: 'simple' | 'full' proxy: IMihomoProxy | IMihomoGroup group: string - onSelect: (proxy: string) => void + onSelect: (group: string, proxy: string) => void selected: boolean } @@ -61,36 +61,33 @@ const ProxyItem: React.FC = (props) => { } }, []) return ( - <> - - onSelect(proxy.name)} - isPressable - fullWidth - className={`my-1 ${selected ? 'bg-primary/30' : ''}`} - radius="sm" - > - -
-
-
{proxy.name}
- {proxyDisplayMode === 'full' && ( -
{proxy.type}
- )} -
- + onSelect(group, proxy.name)} + isPressable + fullWidth + className={`${selected ? 'bg-primary/30' : ''}`} + radius="sm" + > + +
+
+
{proxy.name}
+ {proxyDisplayMode === 'full' && ( +
{proxy.type}
+ )}
- - - + +
+
+
) } diff --git a/src/renderer/src/components/proxies/proxy-list.tsx b/src/renderer/src/components/proxies/proxy-list.tsx deleted file mode 100644 index 59e97c5..0000000 --- a/src/renderer/src/components/proxies/proxy-list.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' -import { Virtuoso } from 'react-virtuoso' -import ProxyItem from './proxy-item' - -interface Props { - onProxyDelay: (proxy: string) => Promise - onChangeProxy: (proxy: string) => void - proxyDisplayMode: 'simple' | 'full' - proxies: (IMihomoProxy | IMihomoGroup)[] - group: string - now: string -} - -const ProxyList: React.FC = (props) => { - const { proxyDisplayMode, onProxyDelay, onChangeProxy, proxies, group, now } = props - - return ( - ( - - )} - /> - ) -} - -export default ProxyList diff --git a/src/renderer/src/pages/proxies.tsx b/src/renderer/src/pages/proxies.tsx index 9fdf37e..7eca643 100644 --- a/src/renderer/src/pages/proxies.tsx +++ b/src/renderer/src/pages/proxies.tsx @@ -1,13 +1,14 @@ -import { Accordion, AccordionItem, Avatar, Button } from '@nextui-org/react' +import { Avatar, Button, Card, CardBody } from '@nextui-org/react' import BasePage from '@renderer/components/base/base-page' -import ProxyList from '@renderer/components/proxies/proxy-list' import { useAppConfig } from '@renderer/hooks/use-app-config' -import { MdOutlineSpeed } from 'react-icons/md' import { mihomoChangeProxy, mihomoProxies, mihomoProxyDelay } from '@renderer/utils/ipc' import { CgDetailsLess, CgDetailsMore } from 'react-icons/cg' -import { useEffect, useMemo } from 'react' -import PubSub from 'pubsub-js' +import { useMemo, useState } from 'react' import useSWR from 'swr' +import { GroupedVirtuoso } 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) @@ -34,15 +35,21 @@ const Proxies: React.FC = () => { return groups }, [proxies]) - const groupProxies = useMemo(() => { - const groupProxies: Record = {} - if (proxies) { - for (const group of groups) { - groupProxies[group.name] = group.all.map((name) => proxies.proxies[name]) + const [isOpen, setIsOpen] = useState(Array(groups.length).fill(false)) + + 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])) } - } - return groupProxies - }, [proxies]) + }) + + return { groupCounts, allProxies } + }, [groups, isOpen]) const onChangeProxy = (group: string, proxy: string): void => { mihomoChangeProxy(group, proxy).then(() => { @@ -54,7 +61,6 @@ const Proxies: React.FC = () => { return await mihomoProxyDelay(proxy, url) } - useEffect(() => {}, []) return ( { } > - - {groups.map((group) => { + { return ( - -
-
{group.name}
- {proxyDisplayMode === 'full' && ( - <> -
{group.type}
-
{group.now}
- - )} +
+ { + setIsOpen((prev) => { + const newOpen = [...prev] + newOpen[index] = !prev[index] + return newOpen + }) + }} + > + +
+
+ {groups[index].icon.length > 0 ? ( + + ) : null} +
+ {groups[index].name} + {proxyDisplayMode === 'full' && ( + <> +
+ {groups[index].type} +
+
+ {groups[index].now} +
+ + )} +
+
+
+ + +
- -
- } - classNames={{ title: 'select-none', base: 'px-2', content: 'pt-2', trigger: 'py-2' }} - startContent={ - group.icon.length > 0 ? ( - - ) : null - } - > - onProxyDelay(proxy, group.testUrl)} - onChangeProxy={(proxy) => onChangeProxy(group.name, proxy)} - proxyDisplayMode={proxyDisplayMode} - proxies={groupProxies[group.name]} - group={group.name} - now={group.now} - /> - + + +
) - })} -
+ }} + itemContent={(index, groupIndex) => { + return allProxies[index] ? ( +
+ +
+ ) : ( +
Never See This
+ ) + }} + />
) }