From 69423bdfff89e6c00db4406319189a8852c05aa7 Mon Sep 17 00:00:00 2001 From: Haishan Date: Sun, 12 Jun 2022 09:30:45 +0800 Subject: [PATCH] Always show update and health check buttons for proxy provider ref #649 --- src/components/StyleGuide.tsx | 4 ++ src/components/proxies/ProxyGroup.module.scss | 13 ++--- src/components/proxies/ProxyGroup.tsx | 39 ++++++-------- src/components/proxies/ProxyList.module.scss | 3 +- .../proxies/ProxyProvider.module.scss | 20 ++++--- src/components/proxies/ProxyProvider.tsx | 53 ++++++++++--------- src/components/shared/ZapAnimated.module.scss | 12 +++++ src/components/shared/ZapAnimated.tsx | 25 +++++++++ 8 files changed, 102 insertions(+), 67 deletions(-) create mode 100644 src/components/shared/ZapAnimated.module.scss create mode 100644 src/components/shared/ZapAnimated.tsx diff --git a/src/components/StyleGuide.tsx b/src/components/StyleGuide.tsx index 1f5f3be..910c538 100644 --- a/src/components/StyleGuide.tsx +++ b/src/components/StyleGuide.tsx @@ -4,6 +4,7 @@ import Loading from 'src/components/Loading'; import Button from './Button'; import Input from './Input'; +import { ZapAnimated } from './shared/ZapAnimated'; import SwitchThemed from './SwitchThemed'; import ToggleSwitch from './ToggleSwitch'; @@ -42,6 +43,9 @@ class StyleGuide extends PureComponent { render() { return (
+ + + diff --git a/src/components/proxies/ProxyGroup.module.scss b/src/components/proxies/ProxyGroup.module.scss index 6e9d91f..85b68b6 100644 --- a/src/components/proxies/ProxyGroup.module.scss +++ b/src/components/proxies/ProxyGroup.module.scss @@ -4,17 +4,10 @@ .groupHead { display: flex; + flex-wrap: wrap; align-items: center; } -.latencyButton { - margin-left: 5px; -} - -.zapWrapper { - width: 20px; - height: 20px; - display: flex; - align-items: center; - justify-content: center; +.action { + margin: 0 5px; } diff --git a/src/components/proxies/ProxyGroup.tsx b/src/components/proxies/ProxyGroup.tsx index d6a4e99..6d6c59e 100644 --- a/src/components/proxies/ProxyGroup.tsx +++ b/src/components/proxies/ProxyGroup.tsx @@ -1,26 +1,20 @@ +import Tooltip from '@reach/tooltip'; import * as React from 'react'; -import { Zap } from 'react-feather'; +import { useState2 } from '$src/hooks/basic'; import { State } from '$src/store/types'; import { getCollapsibleIsOpen, getHideUnavailableProxies, getProxySortBy } from '../../store/app'; import { getProxies, switchProxy } from '../../store/proxies'; import Button from '../Button'; import CollapsibleSectionHeader from '../CollapsibleSectionHeader'; +import { ZapAnimated } from '../shared/ZapAnimated'; import { connect, useStoreActions } from '../StateProvider'; import { useFilteredAndSorted } from './hooks'; import s0 from './ProxyGroup.module.scss'; import { ProxyList, ProxyListSummaryView } from './ProxyList'; -const { createElement, useCallback, useMemo, useState } = React; - -function ZapWrapper() { - return ( -
- -
- ); -} +const { createElement, useCallback, useMemo } = React; function ProxyGroupImpl({ name, @@ -56,14 +50,15 @@ function ProxyGroupImpl({ [apiConfig, dispatch, name, isSelectable] ); - const [isTestingLatency, setIsTestingLatency] = useState(false); + const testingLatency = useState2(false); const testLatency = useCallback(async () => { - setIsTestingLatency(true); + if (testingLatency.value) return; + testingLatency.set(true); try { await requestDelayForProxies(apiConfig, all); } catch (err) {} - setIsTestingLatency(false); - }, [all, apiConfig, requestDelayForProxies]); + testingLatency.set(false); + }, [all, apiConfig, requestDelayForProxies, testingLatency]); return (
@@ -75,15 +70,13 @@ function ProxyGroupImpl({ qty={all.length} isOpen={isOpen} /> - +
+ + + +
{createElement(isOpen ? ProxyList : ProxyListSummaryView, { all, diff --git a/src/components/proxies/ProxyList.module.scss b/src/components/proxies/ProxyList.module.scss index d548572..12fea7e 100644 --- a/src/components/proxies/ProxyList.module.scss +++ b/src/components/proxies/ProxyList.module.scss @@ -6,9 +6,10 @@ } .listSummaryView { - margin: 8px 0; + margin: 14px 0; display: grid; grid-template-columns: repeat(auto-fill, 13px); grid-gap: 10px; place-items: center; + max-width: 900px; } diff --git a/src/components/proxies/ProxyProvider.module.scss b/src/components/proxies/ProxyProvider.module.scss index 534305b..bc66bca 100644 --- a/src/components/proxies/ProxyProvider.module.scss +++ b/src/components/proxies/ProxyProvider.module.scss @@ -5,21 +5,25 @@ } } -.body { +.main { padding: 10px 15px; @media (--breakpoint-not-small) { padding: 10px 40px; } } -.actionFooter { +.head { display: flex; - button { - margin: 0 5px; - &:first-child { - margin-left: 0; - } - } + align-items: center; + flex-wrap: wrap; +} + +.action { + margin: 0 5px; + display: grid; + grid-template-columns: auto auto; + gap: 10px; + place-items: center; } .refresh { diff --git a/src/components/proxies/ProxyProvider.tsx b/src/components/proxies/ProxyProvider.tsx index 972a735..7939190 100644 --- a/src/components/proxies/ProxyProvider.tsx +++ b/src/components/proxies/ProxyProvider.tsx @@ -1,8 +1,8 @@ +import Tooltip from '@reach/tooltip'; import { formatDistance } from 'date-fns'; import * as React from 'react'; -import { RotateCw, Zap } from 'react-feather'; +import { RotateCw } from 'react-feather'; import Button from 'src/components/Button'; -import Collapsible from 'src/components/Collapsible'; import CollapsibleSectionHeader from 'src/components/CollapsibleSectionHeader'; import { useUpdateProviderItem } from 'src/components/proxies/proxies.hooks'; import { connect, useStoreActions } from 'src/components/StateProvider'; @@ -18,6 +18,7 @@ import { DelayMapping, State } from 'src/store/types'; import { useState2 } from '$src/hooks/basic'; +import { ZapAnimated } from '../shared/ZapAnimated'; import { useFilteredAndSorted } from './hooks'; import { ProxyList, ProxyListSummaryView } from './ProxyList'; import s from './ProxyProvider.module.scss'; @@ -56,6 +57,7 @@ function ProxyProviderImpl({ const updateProvider = useUpdateProviderItem({ dispatch, apiConfig, name }); const healthcheckProvider = useCallback(() => { + if (checkingHealth.value) return; checkingHealth.set(true); const stop = () => checkingHealth.set(false); dispatch(healthcheckProviderByName(apiConfig, name)).then(stop, stop); @@ -71,32 +73,33 @@ function ProxyProviderImpl({ const timeAgo = formatDistance(new Date(updatedAt), new Date()); return ( -
- +
+
+ + +
+ + + + + + +
+
Updated {timeAgo} ago
- - -
-
-
- - - + {isOpen ? : }
); } diff --git a/src/components/shared/ZapAnimated.module.scss b/src/components/shared/ZapAnimated.module.scss new file mode 100644 index 0000000..e4cb37b --- /dev/null +++ b/src/components/shared/ZapAnimated.module.scss @@ -0,0 +1,12 @@ +.animate { + --saturation: 70%; + stroke: hsl(46deg var(--saturation) 45%); + animation: zap-pulse 0.7s 0s ease-in-out none normal infinite; +} + +// prettier-ignore +@keyframes zap-pulse { + 0% { stroke: hsl(46deg var(--saturation) 45%); } + 50% { stroke: hsl(46deg var(--saturation) 95%); } + 100% { stroke: hsl(46deg var(--saturation) 45%); } +} diff --git a/src/components/shared/ZapAnimated.tsx b/src/components/shared/ZapAnimated.tsx new file mode 100644 index 0000000..e3b153a --- /dev/null +++ b/src/components/shared/ZapAnimated.tsx @@ -0,0 +1,25 @@ +import cx from 'clsx'; +import * as React from 'react'; + +import s from './ZapAnimated.module.scss'; + +export function ZapAnimated(props: { size?: number; animate?: boolean }) { + const size = props.size || 24; + const cls = cx({ [s.animate]: props.animate }); + return ( + + + + ); +}