From c4a716378635bcdf84a96a68de9838f02b3316f6 Mon Sep 17 00:00:00 2001 From: Zephyruso <127948745+Zephyruso@users.noreply.github.com> Date: Tue, 5 Sep 2023 15:38:42 +0800 Subject: [PATCH] refactor: use a map for update state --- src/components/IconButton.tsx | 0 src/helpers/proxies.ts | 40 ++++++++++++++--------- src/pages/Proxies.tsx | 35 ++++++++++---------- src/pages/ProxyProvider.tsx | 61 ++++++++++++++++++++++------------- src/pages/Rules.tsx | 35 +++++++++++++------- src/signals/rules.ts | 14 ++++---- 6 files changed, 108 insertions(+), 77 deletions(-) delete mode 100644 src/components/IconButton.tsx diff --git a/src/components/IconButton.tsx b/src/components/IconButton.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/helpers/proxies.ts b/src/helpers/proxies.ts index f2d2680..0a575fc 100644 --- a/src/helpers/proxies.ts +++ b/src/helpers/proxies.ts @@ -1,27 +1,35 @@ import dayjs from 'dayjs' +import { createSignal } from 'solid-js' import { PROXIES_ORDERING_TYPE } from '~/constants' export const formatTimeFromNow = (time: number | string) => { return dayjs(time).fromNow() } - -export const handleAnimatedBtnClickWithCallback = async ( - event: MouseEvent, - callback: () => Promise, - className = 'animate-spin', -) => { - let el = event.target as HTMLElement - event.stopPropagation() - - while (el && !el.classList.contains('btn')) { - el = el.parentElement! +export const useStringBooleanMap = () => { + const [map, setMap] = createSignal>({}) + const set = (name: string, value: boolean) => { + setMap({ + ...map(), + [name]: value, + }) } - el.classList.add(className) - try { - await callback() - } catch {} - el.classList.remove(className) + const setWithCallback = async ( + name: string, + callback: () => Promise, + ) => { + set(name, true) + try { + await callback() + } catch {} + set(name, false) + } + + return { + map, + set, + setWithCallback, + } } export const formatProxyType = (type = '') => { diff --git a/src/pages/Proxies.tsx b/src/pages/Proxies.tsx index 0b7e069..0538636 100644 --- a/src/pages/Proxies.tsx +++ b/src/pages/Proxies.tsx @@ -1,6 +1,7 @@ import { useI18n } from '@solid-primitives/i18n' import { IconBrandSpeedtest } from '@tabler/icons-solidjs' -import { createSignal, Show } from 'solid-js' +import { Show } from 'solid-js' +import { twMerge } from 'tailwind-merge' import { Button, Collapse, @@ -8,10 +9,7 @@ import { ProxyCardGroups, ProxyNodePreview, } from '~/components' -import { - handleAnimatedBtnClickWithCallback, - sortProxiesByOrderingType, -} from '~/helpers' +import { sortProxiesByOrderingType, useStringBooleanMap } from '~/helpers' import { proxiesOrderingType, renderProxiesInSamePage, @@ -29,19 +27,19 @@ export default () => { latencyMap, } = useProxies() - const [collapsedMap, setCollapsedMap] = createSignal>( - {}, - ) + const { map: collapsedMap, set: setCollapsedMap } = useStringBooleanMap() + const { map: speedTestingMap, setWithCallback: setSpeedTestingMap } = + useStringBooleanMap() const onProxyNodeClick = async (proxy: Proxy, proxyName: string) => { void setProxyGroupByProxyName(proxy, proxyName) } - const onSpeedTestClick = (e: MouseEvent, name: string) => { - handleAnimatedBtnClickWithCallback( - e, - latencyTestByProxyGroupName.bind(null, name), - 'animate-pulse', + const onSpeedTestClick = async (e: MouseEvent, name: string) => { + e.stopPropagation() + setSpeedTestingMap( + name, + async () => await latencyTestByProxyGroupName(name), ) } @@ -67,7 +65,11 @@ export default () => { class="btn-circle btn-sm" onClick={(e) => onSpeedTestClick(e, proxy.name)} > - +
@@ -98,10 +100,7 @@ export default () => { title={title} content={content} onCollapse={(val) => - setCollapsedMap({ - ...collapsedMap(), - [`group-${proxy.name}`]: val, - }) + setCollapsedMap(`group-${proxy.name}`, val) } /> ) diff --git a/src/pages/ProxyProvider.tsx b/src/pages/ProxyProvider.tsx index a59bbb7..2660a1e 100644 --- a/src/pages/ProxyProvider.tsx +++ b/src/pages/ProxyProvider.tsx @@ -1,6 +1,7 @@ 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, @@ -11,8 +12,8 @@ import { } from '~/components' import { formatTimeFromNow, - handleAnimatedBtnClickWithCallback, sortProxiesByOrderingType, + useStringBooleanMap, } from '~/helpers' import { proxiesOrderingType, useProxies } from '~/signals' @@ -26,27 +27,33 @@ export default () => { latencyMap, } = useProxies() - const [collapsedMap, setCollapsedMap] = createSignal>( - {}, - ) + 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) => { - handleAnimatedBtnClickWithCallback( - e, - healthCheckByProviderName.bind(null, name), - 'animate-pulse', + const onHealthCheckClick = async (e: MouseEvent, name: string) => { + e.stopPropagation() + setHealthCheckingMap( + name, + async () => await healthCheckByProviderName(name), ) } - const onUpdateProviderClick = (e: MouseEvent, name: string) => { - handleAnimatedBtnClickWithCallback( - e, - updateProviderByProviderName.bind(null, name), - ) + const onUpdateProviderClick = async (e: MouseEvent, name: string) => { + e.stopPropagation() + setUpdateingMap(name, async () => await updateProviderByProviderName(name)) } - const onUpdateAllProviderClick = (e: MouseEvent) => { - handleAnimatedBtnClickWithCallback(e, updateAllProvider) + const onUpdateAllProviderClick = async (e: MouseEvent) => { + e.stopPropagation() + setAllProviderIsUpdating(true) + try { + await updateAllProvider() + } catch {} + setAllProviderIsUpdating(false) } return ( @@ -58,7 +65,9 @@ export default () => { class="btn-circle btn-ghost btn-sm ml-2" onClick={(e) => onUpdateAllProviderClick(e)} > - + { onUpdateProviderClick(e, proxyProvider.name) } > - +
@@ -112,10 +130,7 @@ export default () => { title={title} content={content} onCollapse={(val) => - setCollapsedMap({ - ...collapsedMap(), - [`provider-${proxyProvider.name}`]: val, - }) + setCollapsedMap(`provider-${proxyProvider.name}`, val) } /> ) diff --git a/src/pages/Rules.tsx b/src/pages/Rules.tsx index 4f2385f..66467a6 100644 --- a/src/pages/Rules.tsx +++ b/src/pages/Rules.tsx @@ -2,11 +2,9 @@ import { useI18n } from '@solid-primitives/i18n' import { IconReload } from '@tabler/icons-solidjs' import InfiniteScroll from 'solid-infinite-scroll' import { For, Show, createMemo, createSignal, onMount } from 'solid-js' +import { twMerge } from 'tailwind-merge' import { Button } from '~/components' -import { - formatTimeFromNow, - handleAnimatedBtnClickWithCallback, -} from '~/helpers' +import { formatTimeFromNow, useStringBooleanMap } from '~/helpers' import { useRules } from '~/signals' export default () => { @@ -23,15 +21,22 @@ export default () => { onMount(updateRules) + const { map: updateingMap, setWithCallback: setUpdateingMap } = + useStringBooleanMap() + const [allProviderIsUpdating, setAllProviderIsUpdating] = createSignal(false) + const onUpdateProviderClick = (e: MouseEvent, name: string) => { - handleAnimatedBtnClickWithCallback( - e, - updateRuleProviderByName.bind(null, name), - ) + e.stopPropagation() + setUpdateingMap(name, async () => await updateRuleProviderByName(name)) } - const onUpdateAllProviderClick = (e: MouseEvent) => { - handleAnimatedBtnClickWithCallback(e, updateAllRuleProvider) + const onUpdateAllProviderClick = async (e: MouseEvent) => { + e.stopPropagation() + setAllProviderIsUpdating(true) + try { + await updateAllRuleProvider() + } catch {} + setAllProviderIsUpdating(false) } return ( @@ -68,7 +73,9 @@ export default () => { class="btn-circle btn-ghost btn-sm ml-2" onClick={(e) => onUpdateAllProviderClick(e)} > - + @@ -86,7 +93,11 @@ export default () => { onUpdateProviderClick(e, rulesProvider.name) } > - + diff --git a/src/signals/rules.ts b/src/signals/rules.ts index 426dc6f..0bc4384 100644 --- a/src/signals/rules.ts +++ b/src/signals/rules.ts @@ -9,16 +9,14 @@ export const useRules = () => { const [rulesProviders, setRulesProviders] = createSignal([]) const updateRules = async () => { - const { rules } = await request - .get('rules') - .json<{ rules: Record }>() + const [{ rules }, { providers }] = await Promise.all([ + request.get('rules').json<{ rules: Record }>(), + request + .get('providers/rules') + .json<{ providers: Record }>(), + ]) setRules(Object.values(rules)) - - const { providers } = await request - .get('providers/rules') - .json<{ providers: Record }>() - setRulesProviders(Object.values(providers)) }