diff --git a/src/App.tsx b/src/App.tsx index 8d1e2fa..0bffc02 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,7 +6,6 @@ import { ROUTES } from '~/constants' import { curTheme, endpoint, - renderProxiesInSamePage, selectedEndpoint, useAutoSwitchTheme, useProxies, @@ -18,7 +17,6 @@ const Overview = lazy(() => import('~/pages/Overview')) const Connections = lazy(() => import('~/pages/Connections')) const Logs = lazy(() => import('~/pages/Logs')) const Proxies = lazy(() => import('~/pages/Proxies')) -const ProxyProvider = lazy(() => import('~/pages/ProxyProvider')) const Rules = lazy(() => import('~/pages/Rules')) const Config = lazy(() => import('~/pages/Config')) @@ -54,9 +52,6 @@ export const App = () => { - - - diff --git a/src/components/Header.tsx b/src/components/Header.tsx index b446bb1..5433aec 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -3,7 +3,6 @@ import { A, useLocation } from '@solidjs/router' import { IconFileStack, IconGlobe, - IconGlobeFilled, IconHome, IconMenu, IconNetwork, @@ -11,10 +10,10 @@ import { IconRuler, IconSettings, } from '@tabler/icons-solidjs' -import { For, ParentComponent, Show, createMemo, createSignal } from 'solid-js' +import { For, ParentComponent, Show, createSignal } from 'solid-js' import { twMerge } from 'tailwind-merge' import { ROUTES, themes } from '~/constants' -import { renderProxiesInSamePage, setCurTheme, useProxies } from '~/signals' +import { setCurTheme } from '~/signals' const Nav: ParentComponent<{ href: string; tooltip: string }> = ({ href, @@ -74,51 +73,38 @@ const LogoText = () => ( export const Header = () => { const [t] = useI18n() - const { proxyProviders } = useProxies() - const navs = createMemo(() => { - const list = [ - { - href: ROUTES.Overview, - name: t('overview'), - icon: , - }, - { - href: ROUTES.Proxies, - name: t('proxies'), - icon: , - }, - { - href: ROUTES.Rules, - name: t('rules'), - icon: , - }, - { - href: ROUTES.Conns, - name: t('connections'), - icon: , - }, - { - href: ROUTES.Log, - name: t('logs'), - icon: , - }, - { - href: ROUTES.Config, - name: t('config'), - icon: , - }, - ] - - if (proxyProviders().length > 0 && !renderProxiesInSamePage()) { - list.splice(2, 0, { - href: ROUTES.ProxyProvider, - name: t('proxyProviders'), - icon: , - }) - } - - return list - }) + const navs = () => [ + { + href: ROUTES.Overview, + name: t('overview'), + icon: , + }, + { + href: ROUTES.Proxies, + name: t('proxies'), + icon: , + }, + { + href: ROUTES.Rules, + name: t('rules'), + icon: , + }, + { + href: ROUTES.Conns, + name: t('connections'), + icon: , + }, + { + href: ROUTES.Log, + name: t('logs'), + icon: , + }, + { + href: ROUTES.Config, + name: t('config'), + icon: , + }, + ] const location = useLocation() diff --git a/src/i18n/en.ts b/src/i18n/en.ts index b033ac0..3bc74e0 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -71,4 +71,5 @@ export default { switchLanguage: 'Switch Language', latencyTestTimeoutDuration: 'Latency Test Timeout Duration', closedConnections: 'Closed Connections', + all: 'All', } diff --git a/src/i18n/zh.ts b/src/i18n/zh.ts index dc35694..db49aff 100644 --- a/src/i18n/zh.ts +++ b/src/i18n/zh.ts @@ -70,4 +70,5 @@ export default { switchLanguage: '切换语言', latencyTestTimeoutDuration: '测速超时时间', closedConnections: '已关闭连接', + all: '全部', } diff --git a/src/pages/Config.tsx b/src/pages/Config.tsx index 792e6bd..2018a3a 100644 --- a/src/pages/Config.tsx +++ b/src/pages/Config.tsx @@ -30,7 +30,6 @@ import { proxiesOrderingType, proxiesPreviewType, renderInTwoColumns, - renderProxiesInSamePage, renderRulesAndProviderInTwoColumns, setAutoCloseConns, setAutoSwitchTheme, @@ -40,7 +39,6 @@ import { setProxiesOrderingType, setProxiesPreviewType, setRenderInTwoColumns, - setRenderProxiesInSamePage, setRenderRulesAndProviderInTwoColumns, setSelectedEndpoint, setTableSize, @@ -326,11 +324,6 @@ const ConfigForXd = () => { value: renderRulesAndProviderInTwoColumns, onChange: setRenderRulesAndProviderInTwoColumns, }, - { - label: 'renderProxiesInSamePage', - value: renderProxiesInSamePage, - onChange: setRenderProxiesInSamePage, - }, { label: 'autoSwitchTheme', value: autoSwitchTheme, diff --git a/src/pages/Connections.tsx b/src/pages/Connections.tsx index 9f646cb..c7055db 100644 --- a/src/pages/Connections.tsx +++ b/src/pages/Connections.tsx @@ -113,7 +113,7 @@ export default () => { ) setClosedConnectionsWithSpeed((prev) => - [...prev, ...closedConnections].slice(-100), + [...prev, ...closedConnections].slice(-1000), ) return connections.slice(-100) @@ -157,7 +157,7 @@ export default () => { }, ) - const columns: ColumnDef[] = [ + const columns = createMemo[]>(() => [ { header: () => t('close'), enableGrouping: false, @@ -265,7 +265,7 @@ export default () => { row.metadata.destinationIP || row.metadata.host, }, - ] + ]) const [grouping, setGrouping] = createSignal([]) const [sorting, setSorting] = createSignal([ @@ -297,7 +297,7 @@ export default () => { }, sortDescFirst: true, enableHiding: true, - columns, + columns: columns(), onGlobalFilterChange: setSearch, onGroupingChange: setGrouping, onSortingChange: setSorting, @@ -327,10 +327,14 @@ export default () => { {(tab) => ( )} diff --git a/src/pages/Proxies.tsx b/src/pages/Proxies.tsx index dc85816..4672d29 100644 --- a/src/pages/Proxies.tsx +++ b/src/pages/Proxies.tsx @@ -1,6 +1,6 @@ import { useI18n } from '@solid-primitives/i18n' -import { IconBrandSpeedtest } from '@tabler/icons-solidjs' -import { Show } from 'solid-js' +import { IconBrandSpeedtest, IconReload } from '@tabler/icons-solidjs' +import { For, Show, createSignal } from 'solid-js' import { twMerge } from 'tailwind-merge' import { Button, @@ -8,15 +8,21 @@ import { ForTwoColumns, ProxyCardGroups, ProxyNodePreview, + SubscriptionInfo, } from '~/components' -import { sortProxiesByOrderingType, useStringBooleanMap } from '~/helpers' import { - proxiesOrderingType, - renderProxiesInSamePage, - useProxies, -} from '~/signals' + formatTimeFromNow, + sortProxiesByOrderingType, + useStringBooleanMap, +} from '~/helpers' +import { proxiesOrderingType, useProxies } from '~/signals' import type { Proxy } from '~/types' -import ProxyProvider from './ProxyProvider' + +enum ActiveTab { + all = 'all', + proxyProviders = 'proxyProviders', + proxies = 'proxies', +} export default () => { const [t] = useI18n() @@ -25,27 +31,184 @@ export default () => { setProxyGroupByProxyName, latencyTestByProxyGroupName, latencyMap, + proxyProviders, + updateProviderByProviderName, + updateAllProvider, + healthCheckByProviderName, } = useProxies() const { map: collapsedMap, set: setCollapsedMap } = useStringBooleanMap() - const { map: speedTestingMap, setWithCallback: setSpeedTestingMap } = + const { map: latencyTestingMap, setWithCallback: setLatencyTestingMap } = useStringBooleanMap() const onProxyNodeClick = async (proxy: Proxy, proxyName: string) => { void setProxyGroupByProxyName(proxy, proxyName) } - const onSpeedTestClick = async (e: MouseEvent, name: string) => { + const onLatencyTestClick = async (e: MouseEvent, name: string) => { e.stopPropagation() - setSpeedTestingMap(name, () => latencyTestByProxyGroupName(name)) + void setLatencyTestingMap(name, () => latencyTestByProxyGroupName(name)) } + const { map: healthCheckingMap, setWithCallback: setHealthCheckingMap } = + useStringBooleanMap() + const { map: updatingMap, setWithCallback: setUpdatingMap } = + useStringBooleanMap() + const [isAllProviderUpdating, setIsAllProviderUpdating] = createSignal(false) + + const onHealthCheckClick = (e: MouseEvent, name: string) => { + e.stopPropagation() + void setHealthCheckingMap(name, () => healthCheckByProviderName(name)) + } + + const onUpdateProviderClick = (e: MouseEvent, name: string) => { + e.stopPropagation() + void setUpdatingMap(name, () => updateProviderByProviderName(name)) + } + + const onUpdateAllProviderClick = async (e: MouseEvent) => { + e.stopPropagation() + setIsAllProviderUpdating(true) + try { + await updateAllProvider() + } catch {} + setIsAllProviderUpdating(false) + } + + const [activeTab, setActiveTab] = createSignal(ActiveTab.all) + + const tabs = () => [ + { + type: ActiveTab.all, + name: t('all'), + count: proxyProviders().length + proxies().length, + }, + { + type: ActiveTab.proxyProviders, + name: t('proxyProviders'), + count: proxyProviders().length, + }, + { + type: ActiveTab.proxies, + name: t('proxies'), + count: proxies().length, + }, + ] + return ( - <> -
-

- {t('proxies')} -

+
+
+
+ + {(tab) => ( + + )} + +
+ + +
+ + + { + const sortedProxyNames = sortProxiesByOrderingType( + proxyProvider.proxies.map((i) => i.name) ?? [], + latencyMap(), + proxiesOrderingType(), + ) + + const title = ( + <> +
+ {proxyProvider.name} +
+ + + +
+
+ +
+ {proxyProvider.vehicleType} :: {t('updated')}{' '} + {formatTimeFromNow(proxyProvider.updatedAt)} +
+ + + + + ) + + const content = + + return ( + setCollapsedMap(proxyProvider.name, val)} + /> + ) + })} + /> +
+ + +
+ + + { const sortedProxyNames = sortProxiesByOrderingType( @@ -60,19 +223,21 @@ export default () => { {proxy.name}
+
{proxy.type} {proxy.now?.length > 0 && ` :: ${proxy.now}`}
+ { ) })} /> -
- -
-
- +
) } diff --git a/src/pages/ProxyProvider.tsx b/src/pages/ProxyProvider.tsx deleted file mode 100644 index b4c3303..0000000 --- a/src/pages/ProxyProvider.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import { useI18n } from '@solid-primitives/i18n' -import { IconBrandSpeedtest, IconReload } from '@tabler/icons-solidjs' -import { Show, createSignal } from 'solid-js' -import { twMerge } from 'tailwind-merge' -import { - Button, - Collapse, - ForTwoColumns, - ProxyCardGroups, - ProxyNodePreview, - SubscriptionInfo, -} from '~/components' -import { - formatTimeFromNow, - sortProxiesByOrderingType, - useStringBooleanMap, -} from '~/helpers' -import { proxiesOrderingType, useProxies } from '~/signals' - -export default () => { - const [t] = useI18n() - const { - proxyProviders, - updateProviderByProviderName, - updateAllProvider, - healthCheckByProviderName, - latencyMap, - } = useProxies() - - const { map: collapsedMap, set: setCollapsedMap } = useStringBooleanMap() - const { map: healthCheckingMap, setWithCallback: setHealthCheckingMap } = - useStringBooleanMap() - const { map: updateingMap, setWithCallback: setUpdateingMap } = - useStringBooleanMap() - const [allProviderIsUpdating, setAllProviderIsUpdating] = createSignal(false) - - const onHealthCheckClick = (e: MouseEvent, name: string) => { - e.stopPropagation() - setHealthCheckingMap(name, () => healthCheckByProviderName(name)) - } - - const onUpdateProviderClick = (e: MouseEvent, name: string) => { - e.stopPropagation() - setUpdateingMap(name, () => updateProviderByProviderName(name)) - } - - const onUpdateAllProviderClick = async (e: MouseEvent) => { - e.stopPropagation() - setAllProviderIsUpdating(true) - try { - await updateAllProvider() - } catch {} - setAllProviderIsUpdating(false) - } - - return ( -
-

- {t('proxyProviders')} - - -

- { - const sortedProxyNames = sortProxiesByOrderingType( - proxyProvider.proxies.map((i) => i.name) ?? [], - latencyMap(), - proxiesOrderingType(), - ) - - const title = ( - <> -
- {proxyProvider.name} -
- - - -
-
- -
- {proxyProvider.vehicleType} :: {t('updated')}{' '} - {formatTimeFromNow(proxyProvider.updatedAt)} -
- - - - - ) - - const content = - - return ( - setCollapsedMap(proxyProvider.name, val)} - /> - ) - })} - /> -
- ) -} diff --git a/src/signals/config.ts b/src/signals/config.ts index ea71b9c..876b2a9 100644 --- a/src/signals/config.ts +++ b/src/signals/config.ts @@ -45,11 +45,6 @@ export const [renderInTwoColumns, setRenderInTwoColumns] = makePersisted( createSignal(true), { name: 'renderInTwoColumn', storage: localStorage }, ) -export const [renderProxiesInSamePage, setRenderProxiesInSamePage] = - makePersisted(createSignal(false), { - name: 'renderProxiesInSamePage', - storage: localStorage, - }) export const [ renderRulesAndProviderInTwoColumns, setRenderRulesAndProviderInTwoColumns,