From 57f9d2fd1e546481aa3a21102df392622121bfba Mon Sep 17 00:00:00 2001 From: haishan Date: Tue, 3 Oct 2023 13:09:03 +0800 Subject: [PATCH] ProxyGroup ProxyProvider app index --- src/components/proxies/ProxyGroup.tsx | 20 ++++++++++---------- src/components/proxies/ProxyProvider.tsx | 22 +++++++++++----------- src/store/app.ts | 14 +------------- src/store/index.ts | 3 --- 4 files changed, 22 insertions(+), 37 deletions(-) diff --git a/src/components/proxies/ProxyGroup.tsx b/src/components/proxies/ProxyGroup.tsx index 0cf57b812..0a0a808d7 100644 --- a/src/components/proxies/ProxyGroup.tsx +++ b/src/components/proxies/ProxyGroup.tsx @@ -1,4 +1,5 @@ import { Tooltip } from '@reach/tooltip'; +import { useAtom } from 'jotai'; import * as React from 'react'; import Button from '$src/components/Button'; @@ -6,7 +7,7 @@ import CollapsibleSectionHeader from '$src/components/CollapsibleSectionHeader'; import { ZapAnimated } from '$src/components/shared/ZapAnimated'; import { connect, useStoreActions } from '$src/components/StateProvider'; import { useState2 } from '$src/hooks/basic'; -import { getCollapsibleIsOpen, getHideUnavailableProxies, getProxySortBy } from '$src/store/app'; +import { collapsibleIsOpenAtom, getHideUnavailableProxies, getProxySortBy } from '$src/store/app'; import { getProxies, switchProxy } from '$src/store/proxies'; import { DelayMapping, DispatchFn, ProxiesMapping, State } from '$src/store/types'; import { ClashAPIConfig } from '$src/types'; @@ -26,7 +27,6 @@ type ProxyGroupImplProps = { proxies: ProxiesMapping; type: string; now: string; - isOpen: boolean; apiConfig: ClashAPIConfig; dispatch: DispatchFn; }; @@ -40,19 +40,22 @@ function ProxyGroupImpl({ proxies, type, now, - isOpen, apiConfig, dispatch, }: ProxyGroupImplProps) { + const [collapsibleIsOpen, setCollapsibleIsOpen] = useAtom(collapsibleIsOpenAtom); + const isOpen = collapsibleIsOpen[`proxyGroup:${name}`]; const all = useFilteredAndSorted(allItems, delay, hideUnavailableProxies, proxySortBy, proxies); - const isSelectable = useMemo(() => type === 'Selector', [type]); - const { - app: { updateCollapsibleIsOpen }, proxies: { requestDelayForProxies }, } = useStoreActions(); - + const updateCollapsibleIsOpen = useCallback( + (prefix: string, name: string, v: boolean) => { + setCollapsibleIsOpen((s) => ({ ...s, [`${prefix}:${name}`]: v })); + }, + [setCollapsibleIsOpen], + ); const toggle = useCallback(() => { updateCollapsibleIsOpen('proxyGroup', name, !isOpen); }, [isOpen, updateCollapsibleIsOpen, name]); @@ -105,10 +108,8 @@ function ProxyGroupImpl({ export const ProxyGroup = connect((s: State, { name, delay }) => { const proxies = getProxies(s); - const collapsibleIsOpen = getCollapsibleIsOpen(s); const proxySortBy = getProxySortBy(s); const hideUnavailableProxies = getHideUnavailableProxies(s); - const group = proxies[name]; const { all, type, now } = group; return { @@ -119,6 +120,5 @@ export const ProxyGroup = connect((s: State, { name, delay }) => { proxies, type, now, - isOpen: collapsibleIsOpen[`proxyGroup:${name}`], }; })(ProxyGroupImpl); diff --git a/src/components/proxies/ProxyProvider.tsx b/src/components/proxies/ProxyProvider.tsx index 6b3f20cb9..40f415318 100644 --- a/src/components/proxies/ProxyProvider.tsx +++ b/src/components/proxies/ProxyProvider.tsx @@ -1,5 +1,6 @@ import { Tooltip } from '@reach/tooltip'; import { formatDistance } from 'date-fns'; +import { useAtom } from 'jotai'; import * as React from 'react'; import { RotateCw } from 'react-feather'; import Button from 'src/components/Button'; @@ -8,7 +9,7 @@ import { useUpdateProviderItem } from 'src/components/proxies/proxies.hooks'; import { connect, useStoreActions } from 'src/components/StateProvider'; import { framerMotionResource } from 'src/misc/motion'; import { - getCollapsibleIsOpen, + collapsibleIsOpenAtom, getHideUnavailableProxies, getProxySortBy, useApiConfig, @@ -35,7 +36,6 @@ type Props = { vehicleType: 'HTTP' | 'File' | 'Compatible'; updatedAt?: string; dispatch: (x: any) => Promise; - isOpen: boolean; }; function ProxyProviderImpl({ @@ -46,9 +46,10 @@ function ProxyProviderImpl({ proxySortBy, vehicleType, updatedAt, - isOpen, dispatch, }: Props) { + const [collapsibleIsOpen, setCollapsibleIsOpen] = useAtom(collapsibleIsOpenAtom); + const isOpen = collapsibleIsOpen[`proxyProvider:${name}`]; const apiConfig = useApiConfig(); const proxies = useFilteredAndSorted(all, delay, hideUnavailableProxies, proxySortBy); const checkingHealth = useState2(false); @@ -61,11 +62,12 @@ function ProxyProviderImpl({ const stop = () => checkingHealth.set(false); dispatch(healthcheckProviderByName(apiConfig, name)).then(stop, stop); }, [apiConfig, dispatch, name, checkingHealth]); - - const { - app: { updateCollapsibleIsOpen }, - } = useStoreActions(); - + const updateCollapsibleIsOpen = useCallback( + (prefix: string, name: string, v: boolean) => { + setCollapsibleIsOpen((s) => ({ ...s, [`${prefix}:${name}`]: v })); + }, + [setCollapsibleIsOpen], + ); const toggle = useCallback(() => { updateCollapsibleIsOpen('proxyProvider', name, !isOpen); }, [isOpen, updateCollapsibleIsOpen, name]); @@ -129,17 +131,15 @@ function Refresh() { ); } -const mapState = (s: State, { proxies, name }) => { +const mapState = (s: State, { proxies }) => { const hideUnavailableProxies = getHideUnavailableProxies(s); const delay = getDelay(s); - const collapsibleIsOpen = getCollapsibleIsOpen(s); const proxySortBy = getProxySortBy(s); return { proxies, delay, hideUnavailableProxies, proxySortBy, - isOpen: collapsibleIsOpen[`proxyProvider:${name}`], }; }; diff --git a/src/store/app.ts b/src/store/app.ts index 9da270868..3a456034d 100644 --- a/src/store/app.ts +++ b/src/store/app.ts @@ -56,6 +56,7 @@ export const selectedClashAPIConfigIndexAtom = atom(initialState().selec export const clashAPIConfigsAtom = atom(initialState().clashAPIConfigs); export const selectedChartStyleIndexAtom = atom(initialState().selectedChartStyleIndex); export const latencyTestUrlAtom = atom(initialState().latencyTestUrl); +export const collapsibleIsOpenAtom = atom(initialState().collapsibleIsOpen); // hooks @@ -66,14 +67,11 @@ export function useApiConfig() { } export const getTheme = (s: State) => s.app.theme; -export const getCollapsibleIsOpen = (s: State) => s.app.collapsibleIsOpen; export const getProxySortBy = (s: State) => s.app.proxySortBy; export const getHideUnavailableProxies = (s: State) => s.app.hideUnavailableProxies; export const getAutoCloseOldConns = (s: State) => s.app.autoCloseOldConns; export const getLogStreamingPaused = (s: State) => s.app.logStreamingPaused; -const saveStateDebounced = debounce(saveState, 600); - export function findClashAPIConfigIndexTmp( arr: ClashAPIConfigWithAddedAt[], { baseURL, secret, metaLabel }: ClashAPIConfig, @@ -172,16 +170,6 @@ export function updateAppConfig(name: string, value: unknown) { }; } -export function updateCollapsibleIsOpen(prefix: string, name: string, v: boolean) { - return (dispatch: DispatchFn, getState: GetStateFn) => { - dispatch('updateCollapsibleIsOpen', (s: State) => { - s.app.collapsibleIsOpen[`${prefix}:${name}`] = v; - }); - // side effect - saveStateDebounced(getState().app); - }; -} - function parseConfigQueryString() { const { search } = window.location; const collector: Record = {}; diff --git a/src/store/index.ts b/src/store/index.ts index ff5ed9010..743858a0f 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,7 +1,6 @@ import { initialState as app, updateAppConfig, - updateCollapsibleIsOpen, } from './app'; import { initialState as configs } from './configs'; import { initialState as logs } from './logs'; @@ -18,9 +17,7 @@ export const initialState = { export const actions = { updateAppConfig, - app: { - updateCollapsibleIsOpen, updateAppConfig, }, proxies: proxiesActions,