diff options
| author | Haishan <[email protected]> | 2022-06-06 23:39:56 +0800 |
|---|---|---|
| committer | Haishan <[email protected]> | 2022-06-06 23:39:56 +0800 |
| commit | 78f3434cb52f53c66936de278f0828c19ef63666 (patch) | |
| tree | e7f9685cc0f3d8eaa6a94ad330e8876752ecb276 /src | |
| parent | 23e734aa548354bb7ceff5ad8d85de95cd860a55 (diff) | |
Run prettier
Diffstat (limited to 'src')
52 files changed, 127 insertions, 355 deletions
diff --git a/src/api/configs.ts b/src/api/configs.ts index 69b02d4..3646f1a 100644 --- a/src/api/configs.ts +++ b/src/api/configs.ts @@ -22,10 +22,7 @@ function configsPatchWorkaround(o: ClashConfigPartial) { return o; } -export async function updateConfigs( - apiConfig: ClashAPIConfig, - o: ClashConfigPartial -) { +export async function updateConfigs(apiConfig: ClashAPIConfig, o: ClashConfigPartial) { const { url, init } = getURLAndInit(apiConfig); const body = JSON.stringify(configsPatchWorkaround(o)); return await fetch(url + endpoint, { ...init, body, method: 'PATCH' }); diff --git a/src/api/connections.ts b/src/api/connections.ts index 9c94d31..60fd4c5 100644 --- a/src/api/connections.ts +++ b/src/api/connections.ts @@ -51,10 +51,7 @@ function appendData(s: string) { type UnsubscribeFn = () => void; let wsState: number; -export function fetchData( - apiConfig: ClashAPIConfig, - listener: unknown -): UnsubscribeFn | void { +export function fetchData(apiConfig: ClashAPIConfig, listener: unknown): UnsubscribeFn | void { if (fetched || wsState === 1) { if (listener) return subscribe(listener); } diff --git a/src/api/proxies.ts b/src/api/proxies.ts index 6b3e28e..e11fd9e 100644 --- a/src/api/proxies.ts +++ b/src/api/proxies.ts @@ -59,8 +59,5 @@ export async function updateProviderByName(config, name) { export async function healthcheckProviderByName(config, name) { const { url, init } = getURLAndInit(config); const options = { ...init, method: 'GET' }; - return await fetch( - url + '/providers/proxies/' + name + '/healthcheck', - options - ); + return await fetch(url + '/providers/proxies/' + name + '/healthcheck', options); } diff --git a/src/api/rule-provider.ts b/src/api/rule-provider.ts index ec9fa7b..5ecd61e 100644 --- a/src/api/rule-provider.ts +++ b/src/api/rule-provider.ts @@ -31,10 +31,7 @@ function normalizeAPIResponse(data: RuleProviderAPIData) { return { byName, names }; } -export async function fetchRuleProviders( - endpoint: string, - apiConfig: ClashAPIConfig -) { +export async function fetchRuleProviders(endpoint: string, apiConfig: ClashAPIConfig) { const { url, init } = getURLAndInit(apiConfig); let data = { providers: {} }; diff --git a/src/api/rules.ts b/src/api/rules.ts index b57b0e3..4d18c23 100644 --- a/src/api/rules.ts +++ b/src/api/rules.ts @@ -12,9 +12,7 @@ type RuleAPIItem = { proxy: string; }; -function normalizeAPIResponse(json: { - rules: Array<RuleAPIItem>; -}): Array<RuleItem> { +function normalizeAPIResponse(json: { rules: Array<RuleAPIItem> }): Array<RuleItem> { invariant( json.rules && json.rules.length >= 0, 'there is no valid rules list in the rules API response' diff --git a/src/api/traffic.ts b/src/api/traffic.ts index cd18aac..aa9143c 100644 --- a/src/api/traffic.ts +++ b/src/api/traffic.ts @@ -27,7 +27,7 @@ const traffic = { this.subscribers.forEach((f) => f(o)); }, - subscribe(listener: (x:any) => void) { + subscribe(listener: (x: any) => void) { this.subscribers.push(listener); return () => { const idx = this.subscribers.indexOf(listener); diff --git a/src/components/APIConfig.tsx b/src/components/APIConfig.tsx index 6e11bc4..4a11c92 100644 --- a/src/components/APIConfig.tsx +++ b/src/components/APIConfig.tsx @@ -72,9 +72,9 @@ function APIConfig({ dispatch }) { const detectApiServer = async () => { // if there is already a clash API server at `/`, just use it as default value const res = await fetch('/'); - res.json().then(data => { + res.json().then((data) => { if (data['hello'] === 'clash') { - setBaseURL(window.location.origin) + setBaseURL(window.location.origin); } }); }; @@ -82,7 +82,6 @@ function APIConfig({ dispatch }) { detectApiServer(); }, []); - return ( // eslint-disable-next-line jsx-a11y/no-static-element-interactions <div className={s0.root} ref={contentEl} onKeyDown={handleContentOnKeyDown}> diff --git a/src/components/BackendList.tsx b/src/components/BackendList.tsx index 8e0d906..e4f4d80 100644 --- a/src/components/BackendList.tsx +++ b/src/components/BackendList.tsx @@ -2,10 +2,7 @@ import cx from 'clsx'; import * as React from 'react'; import { Eye, EyeOff, X as Close } from 'react-feather'; import { useToggle } from 'src/hooks/basic'; -import { - getClashAPIConfigs, - getSelectedClashAPIConfigIndex, -} from 'src/store/app'; +import { getClashAPIConfigs, getSelectedClashAPIConfigIndex } from 'src/store/app'; import { ClashAPIConfig } from 'src/types'; import s from './BackendList.module.scss'; @@ -137,11 +134,7 @@ function Button({ disabled?: boolean; }) { return ( - <button - disabled={disabled} - className={cx(className, s.btn)} - onClick={onClick} - > + <button disabled={disabled} className={cx(className, s.btn)} onClick={onClick}> {children} </button> ); diff --git a/src/components/Collapsible.tsx b/src/components/Collapsible.tsx index e9a1ee8..819bc7c 100644 --- a/src/components/Collapsible.tsx +++ b/src/components/Collapsible.tsx @@ -60,20 +60,11 @@ const Collapsible = memo(({ children, isOpen }) => { return ( <div> <motion.div - animate={ - isOpen && previous === isOpen - ? 'initialOpen' - : isOpen - ? 'open' - : 'closed' - } + animate={isOpen && previous === isOpen ? 'initialOpen' : isOpen ? 'open' : 'closed'} custom={height} variants={variantsCollpapsibleWrap} > - <motion.div - variants={variantsCollpapsibleChildContainer} - ref={refToMeature} - > + <motion.div variants={variantsCollpapsibleChildContainer} ref={refToMeature}> {children} </motion.div> </motion.div> diff --git a/src/components/CollapsibleSectionHeader.tsx b/src/components/CollapsibleSectionHeader.tsx index 2d5ecd1..8b701e1 100644 --- a/src/components/CollapsibleSectionHeader.tsx +++ b/src/components/CollapsibleSectionHeader.tsx @@ -39,12 +39,7 @@ export default function Header({ name, type, toggle, isOpen, qty }: Props) { {typeof qty === 'number' ? <span className={s.qty}>{qty}</span> : null} - <Button - kind="minimal" - onClick={toggle} - className={s.btn} - title="Toggle collapsible section" - > + <Button kind="minimal" onClick={toggle} className={s.btn} title="Toggle collapsible section"> <span className={cx(s.arrow, { [s.isOpen]: isOpen })}> <ChevronDown size={20} /> </span> diff --git a/src/components/ConnectionTable.tsx b/src/components/ConnectionTable.tsx index 2323e2e..15261a3 100644 --- a/src/components/ConnectionTable.tsx +++ b/src/components/ConnectionTable.tsx @@ -64,10 +64,7 @@ function Table({ data }) { return ( <div {...headerGroup.getHeaderGroupProps()} className={s.tr}> {headerGroup.headers.map((column) => ( - <div - {...column.getHeaderProps(column.getSortByToggleProps())} - className={s.th} - > + <div {...column.getHeaderProps(column.getSortByToggleProps())} className={s.th}> <span>{column.render('Header')}</span> <span className={s.sortIconContainer}> {column.isSorted ? ( diff --git a/src/components/Logs.tsx b/src/components/Logs.tsx index d9c53d7..5930634 100644 --- a/src/components/Logs.tsx +++ b/src/components/Logs.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { Pause, Play } from 'react-feather'; import { useTranslation } from 'react-i18next'; import { areEqual, FixedSizeList as List, ListChildComponentProps } from 'react-window'; -import { fetchLogs, reconnect as reconnectLogs,stop as stopLogs } from 'src/api/logs'; +import { fetchLogs, reconnect as reconnectLogs, stop as stopLogs } from 'src/api/logs'; import ContentHeader from 'src/components/ContentHeader'; import LogSearch from 'src/components/LogSearch'; import { connect, useStoreActions } from 'src/components/StateProvider'; diff --git a/src/components/Rules.tsx b/src/components/Rules.tsx index 47644e7..e6e1422 100644 --- a/src/components/Rules.tsx +++ b/src/components/Rules.tsx @@ -41,7 +41,7 @@ function getItemSizeFactory({ provider }) { const providerQty = provider.names.length; if (idx < providerQty) { // provider - return 90; + return 110; } // rule return 80; diff --git a/src/components/Search.tsx b/src/components/Search.tsx index 6edc4a5..9762d8f 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -25,12 +25,7 @@ function RuleSearch({ dispatch, searchText, updateSearchText }) { <div className={s0.RuleSearch}> <div className={s0.RuleSearchContainer}> <div className={s0.inputWrapper}> - <input - type="text" - value={text} - onChange={onChange} - className={s0.input} - /> + <input type="text" value={text} onChange={onChange} className={s0.input} /> </div> <div className={s0.iconWrapper}> <SearchIcon size={20} /> diff --git a/src/components/SideBar.tsx b/src/components/SideBar.tsx index dbe7f0d..2c5ba0c 100644 --- a/src/components/SideBar.tsx +++ b/src/components/SideBar.tsx @@ -3,14 +3,7 @@ import cx from 'clsx'; import * as React from 'react'; import { Info } from 'react-feather'; import { useTranslation } from 'react-i18next'; -import { - FcAreaChart, - FcDocument, - FcGlobe, - FcLink, - FcRuler, - FcSettings, -} from 'react-icons/fc'; +import { FcAreaChart, FcDocument, FcGlobe, FcLink, FcRuler, FcSettings } from 'react-icons/fc'; import { Link, useLocation } from 'react-router-dom'; import { ThemeSwitcher } from 'src/components/shared/ThemeSwitcher'; diff --git a/src/components/SvgYacd.tsx b/src/components/SvgYacd.tsx index 63c0bd5..499456d 100644 --- a/src/components/SvgYacd.tsx +++ b/src/components/SvgYacd.tsx @@ -25,12 +25,7 @@ function SvgYacd({ }: Props) { const faceClasName = cx({ [s.path]: animate }); return ( - <svg - width={width} - height={height} - viewBox="0 0 320 320" - xmlns="http://www.w3.org/2000/svg" - > + <svg width={width} height={height} viewBox="0 0 320 320" xmlns="http://www.w3.org/2000/svg"> <g fill="none" fillRule="evenodd"> {/* face */} <path diff --git a/src/components/ToggleSwitch.tsx b/src/components/ToggleSwitch.tsx index 9eb1019..58400c9 100644 --- a/src/components/ToggleSwitch.tsx +++ b/src/components/ToggleSwitch.tsx @@ -10,10 +10,7 @@ type Props = { }; function ToggleSwitch({ options, value, name, onChange }: Props) { - const idxSelected = useMemo( - () => options.map((o) => o.value).indexOf(value), - [options, value] - ); + const idxSelected = useMemo(() => options.map((o) => o.value).indexOf(value), [options, value]); const getPortionPercentage = useCallback( (idx: number) => { diff --git a/src/components/TrafficChart.tsx b/src/components/TrafficChart.tsx index 367166a..c6bf8ff 100644 --- a/src/components/TrafficChart.tsx +++ b/src/components/TrafficChart.tsx @@ -1,15 +1,11 @@ import * as React from 'react'; import { useTranslation } from 'react-i18next'; -import { State } from '$src/store/types'; +import { State } from '$src/store/types'; import { fetchData } from '../api/traffic'; import useLineChart from '../hooks/useLineChart'; -import { - chartJSResource, - chartStyles, - commonDataSetProps, -} from '../misc/chart'; +import { chartJSResource, chartStyles, commonDataSetProps } from '../misc/chart'; import { getClashAPIConfig, getSelectedChartStyleIndex } from '../store/app'; import { connect } from './StateProvider'; @@ -50,7 +46,7 @@ function TrafficChart({ apiConfig, selectedChartStyleIndex }) { }, ], }), - [ traffic, selectedChartStyleIndex, t] + [traffic, selectedChartStyleIndex, t] ); useLineChart(ChartMod.Chart, 'trafficChart', data, traffic); diff --git a/src/components/about/About.tsx b/src/components/about/About.tsx index 6ed01ad..f59ce20 100644 --- a/src/components/about/About.tsx +++ b/src/components/about/About.tsx @@ -11,15 +11,7 @@ import s from './About.module.scss'; type Props = { apiConfig: ClashAPIConfig }; -function Version({ - name, - link, - version, -}: { - name: string; - link: string; - version: string; -}) { +function Version({ name, link, version }: { name: string; link: string; version: string }) { return ( <div className={s.root}> <h2>{name}</h2> @@ -28,12 +20,7 @@ function Version({ <span className={s.mono}>{version}</span> </p> <p> - <a - className={s.link} - href={link} - target="_blank" - rel="noopener noreferrer" - > + <a className={s.link} href={link} target="_blank" rel="noopener noreferrer"> <GitHub size={20} /> <span>Source</span> </a> @@ -50,17 +37,9 @@ function AboutImpl(props: Props) { <> <ContentHeader title="About" /> {version && version.version ? ( - <Version - name="Clash" - version={version.version} - link="https://github.com/Dreamacro/clash" - /> + <Version name="Clash" version={version.version} link="https://github.com/Dreamacro/clash" /> ) : null} - <Version - name="Yacd" - version={__VERSION__} - link="https://github.com/haishanh/yacd" - /> + <Version name="Yacd" version={__VERSION__} link="https://github.com/haishanh/yacd" /> </> ); } diff --git a/src/components/proxies/ClosePrevConns.tsx b/src/components/proxies/ClosePrevConns.tsx index 5617efe..f26a5e9 100644 --- a/src/components/proxies/ClosePrevConns.tsx +++ b/src/components/proxies/ClosePrevConns.tsx @@ -10,10 +10,7 @@ type Props = { onClickSecondaryButton?: () => void; }; -export function ClosePrevConns({ - onClickPrimaryButton, - onClickSecondaryButton, -}: Props) { +export function ClosePrevConns({ onClickPrimaryButton, onClickSecondaryButton }: Props) { const primaryButtonRef = useRef<HTMLButtonElement>(null); const secondaryButtonRef = useRef<HTMLButtonElement>(null); useEffect(() => { @@ -33,8 +30,8 @@ export function ClosePrevConns({ <div onKeyDown={handleKeyDown}> <h2>Close Connections?</h2> <p> - Click "Yes" to close those connections that are still using the old - selected proxy in this group + Click "Yes" to close those connections that are still using the old selected proxy in this + group </p> <div style={{ height: 30 }} /> <FlexCenter> diff --git a/src/components/proxies/Proxies.tsx b/src/components/proxies/Proxies.tsx index c1606dd..12d3cb2 100644 --- a/src/components/proxies/Proxies.tsx +++ b/src/components/proxies/Proxies.tsx @@ -35,9 +35,7 @@ function Proxies({ apiConfig, showModalClosePrevConns, }) { - const refFetchedTimestamp = useRef<{ startAt?: number; completeAt?: number }>( - {} - ); + const refFetchedTimestamp = useRef<{ startAt?: number; completeAt?: number }>({}); const fetchProxiesHooked = useCallback(() => { refFetchedTimestamp.current.startAt = Date.now(); @@ -75,10 +73,7 @@ function Proxies({ return ( <> - <BaseModal - isOpen={isSettingsModalOpen} - onRequestClose={closeSettingsModal} - > + <BaseModal isOpen={isSettingsModalOpen} onRequestClose={closeSettingsModal}> <Settings /> </BaseModal> <div className={s0.topBar}> @@ -110,15 +105,8 @@ function Proxies({ </div> <ProxyProviderList items={proxyProviders} /> <div style={{ height: 60 }} /> - <ProxyPageFab - dispatch={dispatch} - apiConfig={apiConfig} - proxyProviders={proxyProviders} - /> - <BaseModal - isOpen={showModalClosePrevConns} - onRequestClose={closeModalClosePrevConns} - > + <ProxyPageFab dispatch={dispatch} apiConfig={apiConfig} proxyProviders={proxyProviders} /> + <BaseModal isOpen={showModalClosePrevConns} onRequestClose={closeModalClosePrevConns}> <ClosePrevConns onClickPrimaryButton={() => closePrevConnsAndTheModal(apiConfig)} onClickSecondaryButton={closeModalClosePrevConns} diff --git a/src/components/proxies/Proxy.module.scss b/src/components/proxies/Proxy.module.scss index b25948b..044722f 100644 --- a/src/components/proxies/Proxy.module.scss +++ b/src/components/proxies/Proxy.module.scss @@ -58,9 +58,6 @@ width: 100%; margin-bottom: 5px; font-size: 0.85em; - @media (--breakpoint-not-small) { - font-size: 1em; - } } .proxySmall { diff --git a/src/components/proxies/Proxy.tsx b/src/components/proxies/Proxy.tsx index 424d320..8dc8caa 100644 --- a/src/components/proxies/Proxy.tsx +++ b/src/components/proxies/Proxy.tsx @@ -58,18 +58,8 @@ type ProxyProps = { onClick?: (proxyName: string) => unknown; }; -function ProxySmallImpl({ - now, - name, - proxy, - latency, - isSelectable, - onClick, -}: ProxyProps) { - const color = useMemo(() => getProxyDotBackgroundColor(latency, proxy.type), [ - latency, - proxy, - ]); +function ProxySmallImpl({ now, name, proxy, latency, isSelectable, onClick }: ProxyProps) { + const color = useMemo(() => getProxyDotBackgroundColor(latency, proxy.type), [latency, proxy]); const title = useMemo(() => { let ret = name; if (latency && typeof latency.number === 'number') { @@ -115,14 +105,7 @@ function formatProxyType(t: string) { return t; } -function ProxyImpl({ - now, - name, - proxy, - latency, - isSelectable, - onClick, -}: ProxyProps) { +function ProxyImpl({ now, name, proxy, latency, isSelectable, onClick }: ProxyProps) { const color = useMemo(() => getLabelColor(latency), [latency]); const doSelect = React.useCallback(() => { isSelectable && onClick && onClick(name); @@ -156,9 +139,7 @@ function ProxyImpl({ <span className={s0.proxyType} style={{ opacity: now ? 0.6 : 0.2 }}> {formatProxyType(proxy.type)} </span> - {latency && latency.number ? ( - <ProxyLatency number={latency.number} color={color} /> - ) : null} + {latency && latency.number ? <ProxyLatency number={latency.number} color={color} /> : null} </div> </div> ); diff --git a/src/components/proxies/ProxyGroup.module.scss b/src/components/proxies/ProxyGroup.module.scss index 5409ea8..6e9d91f 100644 --- a/src/components/proxies/ProxyGroup.module.scss +++ b/src/components/proxies/ProxyGroup.module.scss @@ -2,6 +2,15 @@ margin-bottom: 12px; } +.groupHead { + display: flex; + align-items: center; +} + +.latencyButton { + margin-left: 5px; +} + .zapWrapper { width: 20px; height: 20px; diff --git a/src/components/proxies/ProxyGroup.tsx b/src/components/proxies/ProxyGroup.tsx index 32705c1..d6a4e99 100644 --- a/src/components/proxies/ProxyGroup.tsx +++ b/src/components/proxies/ProxyGroup.tsx @@ -1,11 +1,9 @@ import * as React from 'react'; import { Zap } from 'react-feather'; -import { - getCollapsibleIsOpen, - getHideUnavailableProxies, - getProxySortBy, -} from '../../store/app'; +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'; @@ -37,13 +35,7 @@ function ProxyGroupImpl({ apiConfig, dispatch, }) { - const all = useFilteredAndSorted( - allItems, - delay, - hideUnavailableProxies, - proxySortBy, - proxies - ); + const all = useFilteredAndSorted(allItems, delay, hideUnavailableProxies, proxySortBy, proxies); const isSelectable = useMemo(() => type === 'Selector', [type]); @@ -57,7 +49,7 @@ function ProxyGroupImpl({ }, [isOpen, updateCollapsibleIsOpen, name]); const itemOnTapCallback = useCallback( - (proxyName) => { + (proxyName: string) => { if (!isSelectable) return; dispatch(switchProxy(apiConfig, name, proxyName)); }, @@ -75,7 +67,7 @@ function ProxyGroupImpl({ return ( <div className={s0.group}> - <div style={{ display: 'flex', alignItems: 'center' }}> + <div className={s0.groupHead}> <CollapsibleSectionHeader name={name} type={type} @@ -84,6 +76,7 @@ function ProxyGroupImpl({ isOpen={isOpen} /> <Button + className={s0.latencyButton} title="Test latency" kind="minimal" onClick={testLatency} @@ -102,7 +95,7 @@ function ProxyGroupImpl({ ); } -export const ProxyGroup = connect((s, { name, delay }) => { +export const ProxyGroup = connect((s: State, { name, delay }) => { const proxies = getProxies(s); const collapsibleIsOpen = getCollapsibleIsOpen(s); const proxySortBy = getProxySortBy(s); diff --git a/src/components/proxies/ProxyList.tsx b/src/components/proxies/ProxyList.tsx index a86bb88..3856c68 100644 --- a/src/components/proxies/ProxyList.tsx +++ b/src/components/proxies/ProxyList.tsx @@ -11,12 +11,7 @@ type ProxyListProps = { show?: boolean; }; -export function ProxyList({ - all, - now, - isSelectable, - itemOnTapCallback, -}: ProxyListProps) { +export function ProxyList({ all, now, isSelectable, itemOnTapCallback }: ProxyListProps) { const proxies = all; return ( diff --git a/src/components/proxies/ProxyPageFab.tsx b/src/components/proxies/ProxyPageFab.tsx index 7cc6d03..44e446f 100644 --- a/src/components/proxies/ProxyPageFab.tsx +++ b/src/components/proxies/ProxyPageFab.tsx @@ -2,12 +2,7 @@ import * as React from 'react'; import { Zap } from 'react-feather'; import { useTranslation } from 'react-i18next'; import { useUpdateProviderItems } from 'src/components/proxies/proxies.hooks'; -import { - Action, - Fab, - IsFetching, - position as fabPosition, -} from 'src/components/shared/Fab'; +import { Action, Fab, IsFetching, position as fabPosition } from 'src/components/shared/Fab'; import { RotateIcon } from 'src/components/shared/RotateIcon'; import { requestDelayAll } from 'src/store/proxies'; import { DispatchFn, FormattedProxyProvider } from 'src/store/types'; diff --git a/src/components/proxies/ProxyProvider.tsx b/src/components/proxies/ProxyProvider.tsx index 055a572..af5be18 100644 --- a/src/components/proxies/ProxyProvider.tsx +++ b/src/components/proxies/ProxyProvider.tsx @@ -48,12 +48,7 @@ function ProxyProviderImpl({ dispatch, apiConfig, }: Props) { - const proxies = useFilteredAndSorted( - all, - delay, - hideUnavailableProxies, - proxySortBy - ); + const proxies = useFilteredAndSorted(all, delay, hideUnavailableProxies, proxySortBy); const [isHealthcheckLoading, setIsHealthcheckLoading] = useState(false); const updateProvider = useUpdateProviderItem({ dispatch, apiConfig, name }); diff --git a/src/components/proxies/ProxyProviderList.tsx b/src/components/proxies/ProxyProviderList.tsx index 1528f37..754eeac 100644 --- a/src/components/proxies/ProxyProviderList.tsx +++ b/src/components/proxies/ProxyProviderList.tsx @@ -3,11 +3,7 @@ import ContentHeader from 'src/components/ContentHeader'; import { ProxyProvider } from 'src/components/proxies/ProxyProvider'; import { FormattedProxyProvider } from 'src/store/types'; -export function ProxyProviderList({ - items, -}: { - items: FormattedProxyProvider[]; -}) { +export function ProxyProviderList({ items }: { items: FormattedProxyProvider[] }) { if (items.length === 0) return null; return ( diff --git a/src/components/proxies/Settings.tsx b/src/components/proxies/Settings.tsx index 5e1ff98..55e18fe 100644 --- a/src/components/proxies/Settings.tsx +++ b/src/components/proxies/Settings.tsx @@ -2,11 +2,7 @@ import * as React from 'react'; import { useTranslation } from 'react-i18next'; import Select from 'src/components/shared/Select'; -import { - getAutoCloseOldConns, - getHideUnavailableProxies, - getProxySortBy, -} from '../../store/app'; +import { getAutoCloseOldConns, getHideUnavailableProxies, getProxySortBy } from '../../store/app'; import { connect, useStoreActions } from '../StateProvider'; import Switch from '../SwitchThemed'; import s from './Settings.module.scss'; diff --git a/src/components/proxies/hooks.tsx b/src/components/proxies/hooks.tsx index 861c0e5..a43dc0e 100644 --- a/src/components/proxies/hooks.tsx +++ b/src/components/proxies/hooks.tsx @@ -45,22 +45,14 @@ const getSortDelay = ( const ProxySortingFns = { Natural: (proxies: string[]) => proxies, - LatencyAsc: ( - proxies: string[], - delay: DelayMapping, - proxyMapping?: ProxiesMapping - ) => { + LatencyAsc: (proxies: string[], delay: DelayMapping, proxyMapping?: ProxiesMapping) => { return proxies.sort((a, b) => { const d1 = getSortDelay(delay[a], proxyMapping && proxyMapping[a]); const d2 = getSortDelay(delay[b], proxyMapping && proxyMapping[b]); return d1 - d2; }); }, - LatencyDesc: ( - proxies: string[], - delay: DelayMapping, - proxyMapping?: ProxiesMapping - ) => { + LatencyDesc: (proxies: string[], delay: DelayMapping, proxyMapping?: ProxiesMapping) => { return proxies.sort((a, b) => { const d1 = getSortDelay(delay[a], proxyMapping && proxyMapping[a]); const d2 = getSortDelay(delay[b], proxyMapping && proxyMapping[b]); diff --git a/src/components/proxies/proxies.hooks.tsx b/src/components/proxies/proxies.hooks.tsx index ec51c9b..20695ac 100644 --- a/src/components/proxies/proxies.hooks.tsx +++ b/src/components/proxies/proxies.hooks.tsx @@ -14,11 +14,10 @@ export function useUpdateProviderItem({ apiConfig: ClashAPIConfig; name: string; }) { - return useCallback(() => dispatch(updateProviderByName(apiConfig, name)), [ - apiConfig, - dispatch, - name, - ]); + return useCallback( + () => dispatch(updateProviderByName(apiConfig, name)), + [apiConfig, dispatch, name] + ); } export function useUpdateProviderItems({ diff --git a/src/components/rules/RuleProviderItem.module.scss b/src/components/rules/RuleProviderItem.module.scss index 532ec8a..c3e1f07 100644 --- a/src/components/rules/RuleProviderItem.module.scss +++ b/src/components/rules/RuleProviderItem.module.scss @@ -13,6 +13,7 @@ .middle { display: grid; + gap: 6px; grid-template-rows: 1fr auto auto; align-items: center; } @@ -21,13 +22,13 @@ color: #777; } -.refreshButtonWrapper { +.action { display: grid; - place-items: center; - opacity: 0; - transition: opacity 0.2s; + gap: 4px; + grid-template-columns: auto 1fr; + align-items: center; } -.RuleProviderItem:hover .refreshButtonWrapper { - opacity: 1; +.refreshBtn { + padding: 5px; } diff --git a/src/components/rules/RuleProviderItem.tsx b/src/components/rules/RuleProviderItem.tsx index fc88ae1..c27e464 100644 --- a/src/components/rules/RuleProviderItem.tsx +++ b/src/components/rules/RuleProviderItem.tsx @@ -24,14 +24,14 @@ export function RuleProviderItem({ <div className={s.middle}> <SectionNameType name={name} type={`${vehicleType} / ${behavior}`} /> <div className={s.gray}>{ruleCount < 2 ? `${ruleCount} rule` : `${ruleCount} rules`}</div> - <small className={s.gray}>Updated {timeAgo} ago</small> + <div className={s.action}> + <Button onClick={onClickRefreshButton} disabled={isRefreshing} className={s.refreshBtn}> + <RotateIcon isRotating={isRefreshing} size={13} /> + <span className="visually-hidden">Refresh</span> + </Button> + <small className={s.gray}>Updated {timeAgo} ago</small> + </div> </div> - <span className={s.refreshButtonWrapper}> - <Button onClick={onClickRefreshButton} disabled={isRefreshing} kind="circular"> - <RotateIcon isRotating={isRefreshing} /> - <span className="visually-hidden">Refresh</span> - </Button> - </span> </div> ); } diff --git a/src/components/shared/Fab.tsx b/src/components/shared/Fab.tsx index 832306e..8e72432 100644 --- a/src/components/shared/Fab.tsx +++ b/src/components/shared/Fab.tsx @@ -28,8 +28,7 @@ const AB: React.FC<ABProps> = ({ children, ...p }) => ( </button> ); -interface MBProps - extends Omit<React.HTMLAttributes<HTMLButtonElement>, 'tabIndex'> { +interface MBProps extends Omit<React.HTMLAttributes<HTMLButtonElement>, 'tabIndex'> { tabIndex?: number; } @@ -77,10 +76,7 @@ const Fab: React.FC<FabProps> = ({ return event === 'click' ? (isOpen ? close() : open()) : null; }; - const actionOnClick = ( - e: React.FormEvent, - userFunc: (e: React.FormEvent) => void - ) => { + const actionOnClick = (e: React.FormEvent, userFunc: (e: React.FormEvent) => void) => { e.persist(); setIsOpen(false); setTimeout(() => { @@ -141,9 +137,7 @@ const Fab: React.FC<FabProps> = ({ </MB> {text && ( <span - className={`${'right' in style ? 'right' : ''} ${ - alwaysShowTitle ? 'always-show' : '' - }`} + className={`${'right' in style ? 'right' : ''} ${alwaysShowTitle ? 'always-show' : ''}`} aria-hidden={ariaHidden} > {text} diff --git a/src/components/shared/RotateIcon.tsx b/src/components/shared/RotateIcon.tsx index d9dcbd9..d291ece 100644 --- a/src/components/shared/RotateIcon.tsx +++ b/src/components/shared/RotateIcon.tsx @@ -4,13 +4,12 @@ import { RotateCw } from 'react-feather'; import s from './RotateIcon.module.scss'; -export function RotateIcon({ isRotating }: { isRotating: boolean }) { - const cls = cx(s.rotate, { - [s.isRotating]: isRotating, - }); +export function RotateIcon(props: { isRotating: boolean; size?: number }) { + const size = props.size || 16; + const cls = cx(s.rotate, { [s.isRotating]: props.isRotating }); return ( <span className={cls}> - <RotateCw size={16} /> + <RotateCw size={size} /> </span> ); } diff --git a/src/components/shared/TextFitler.tsx b/src/components/shared/TextFitler.tsx index e4a4a88..7af61ac 100644 --- a/src/components/shared/TextFitler.tsx +++ b/src/components/shared/TextFitler.tsx @@ -4,10 +4,7 @@ import { useTextInut } from 'src/hooks/useTextInput'; import s from './TextFitler.module.scss'; -export function TextFilter(props: { - textAtom: RecoilState<string>; - placeholder?: string; -}) { +export function TextFilter(props: { textAtom: RecoilState<string>; placeholder?: string }) { const [onChange, text] = useTextInut(props.textAtom); return ( <input diff --git a/src/components/svg/Equalizer.tsx b/src/components/svg/Equalizer.tsx index 274720f..ae3c858 100644 --- a/src/components/svg/Equalizer.tsx +++ b/src/components/svg/Equalizer.tsx @@ -5,10 +5,7 @@ type Props = { color?: string; }; -export default function Equalizer({ - color = 'currentColor', - size = 24, -}: Props) { +export default function Equalizer({ color = 'currentColor', size = 24 }: Props) { return ( <svg fill="none" diff --git a/src/hooks/useRemainingViewPortHeight.ts b/src/hooks/useRemainingViewPortHeight.ts index 9f3470d..2c920c2 100644 --- a/src/hooks/useRemainingViewPortHeight.ts +++ b/src/hooks/useRemainingViewPortHeight.ts @@ -9,9 +9,10 @@ const { useState, useRef, useCallback, useLayoutEffect } = React; * to the bottom of the view port * */ -export default function useRemainingViewPortHeight< - ElementType extends HTMLDivElement ->(): [React.MutableRefObject<ElementType>, number] { +export default function useRemainingViewPortHeight<ElementType extends HTMLDivElement>(): [ + React.MutableRefObject<ElementType>, + number +] { const ref = useRef<ElementType>(null); const [containerHeight, setContainerHeight] = useState(200); const updateContainerHeight = useCallback(() => { diff --git a/src/hooks/useTextInput.ts b/src/hooks/useTextInput.ts index 1fa19f7..853044c 100644 --- a/src/hooks/useTextInput.ts +++ b/src/hooks/useTextInput.ts @@ -9,9 +9,7 @@ export function useTextInut( ): [(e: React.ChangeEvent<HTMLInputElement>) => void, string] { const [, setTextGlobal] = useRecoilState(x); const [text, setText] = useState(''); - const setTextDebounced = useMemo(() => debounce(setTextGlobal, 300), [ - setTextGlobal, - ]); + const setTextDebounced = useMemo(() => debounce(setTextGlobal, 300), [setTextGlobal]); const onChange = useCallback( (e: React.ChangeEvent<HTMLInputElement>) => { setText(e.target.value); diff --git a/src/misc/chart.ts b/src/misc/chart.ts index c62fa06..56e05a2 100644 --- a/src/misc/chart.ts +++ b/src/misc/chart.ts @@ -1,4 +1,4 @@ -import { createAsset } from "use-asset" +import { createAsset } from 'use-asset'; import prettyBytes from './pretty-bytes'; export const chartJSResource = createAsset(() => { @@ -11,7 +11,7 @@ export const commonChartOptions: import('chart.js').ChartOptions<'line'> = { responsive: true, maintainAspectRatio: true, plugins: { - legend: { labels: { boxWidth: 20 } } + legend: { labels: { boxWidth: 20 } }, }, scales: { x: { display: false, type: 'category' }, diff --git a/src/misc/i18n.ts b/src/misc/i18n.ts index cf1a4f2..eecd72a 100644 --- a/src/misc/i18n.ts +++ b/src/misc/i18n.ts @@ -8,10 +8,7 @@ const allLocales = { en: import('src/i18n/en'), }; -type BackendRequestCallback = ( - err: null, - result: { status: number; data: any } -) => void; +type BackendRequestCallback = (err: null, result: { status: number; data: any }) => void; i18next .use(HttpBackend) diff --git a/src/misc/motion.ts b/src/misc/motion.ts index 5f2fe50..7fac864 100644 --- a/src/misc/motion.ts +++ b/src/misc/motion.ts @@ -1,5 +1,3 @@ import { createResource } from './createResource'; -export const framerMotionResouce = createResource( - () => import('framer-motion') -); +export const framerMotionResouce = createResource(() => import('framer-motion')); diff --git a/src/misc/request-helper.ts b/src/misc/request-helper.ts index 3bc8476..c01b994 100644 --- a/src/misc/request-helper.ts +++ b/src/misc/request-helper.ts @@ -12,7 +12,7 @@ function genCommonHeaders({ secret }: { secret?: string }) { return h; } function buildWebSocketURLBase(baseURL: string, params: URLSearchParams, endpoint: string) { - const qs = '?' + params.toString() + const qs = '?' + params.toString(); const url = new URL(baseURL); url.protocol === 'https:' ? (url.protocol = 'wss:') : (url.protocol = 'ws:'); return `${trimTrailingSlash(url.href)}${endpoint}${qs}`; @@ -32,7 +32,7 @@ export function buildWebSocketURL(apiConfig: ClashAPIConfig, endpoint: string) { token: secret, }); - return buildWebSocketURLBase(baseURL, params, endpoint) + return buildWebSocketURLBase(baseURL, params, endpoint); } export function buildLogsWebSocketURL(apiConfig: LogsAPIConfig, endpoint: string) { @@ -42,5 +42,5 @@ export function buildLogsWebSocketURL(apiConfig: LogsAPIConfig, endpoint: string level: logLevel, }); - return buildWebSocketURLBase(baseURL, params, endpoint) + return buildWebSocketURLBase(baseURL, params, endpoint); } diff --git a/src/misc/shallowEqual.ts b/src/misc/shallowEqual.ts index 241b725..937bc27 100644 --- a/src/misc/shallowEqual.ts +++ b/src/misc/shallowEqual.ts @@ -12,12 +12,7 @@ function is(x, y) { export default function shallowEqual(objA, objB) { if (is(objA, objB)) return true; - if ( - typeof objA !== 'object' || - objA === null || - typeof objB !== 'object' || - objB === null - ) { + if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { return false; } diff --git a/src/misc/utils.ts b/src/misc/utils.ts index d3a7bfc..9497026 100644 --- a/src/misc/utils.ts +++ b/src/misc/utils.ts @@ -1,7 +1,4 @@ -export function throttle<T extends any[]>( - fn: (...args: T) => unknown, - timeout: number -) { +export function throttle<T extends any[]>(fn: (...args: T) => unknown, timeout: number) { let pending = false; return (...args: T) => { @@ -15,10 +12,7 @@ export function throttle<T extends any[]>( }; } -export function debounce<T extends any[]>( - fn: (...args: T) => unknown, - timeout: number -) { +export function debounce<T extends any[]>(fn: (...args: T) => unknown, timeout: number) { let timeoutId: ReturnType<typeof setTimeout>; return (...args: T) => { if (timeoutId) clearTimeout(timeoutId); diff --git a/src/store/app.ts b/src/store/app.ts index 7262b32..2789981 100644 --- a/src/store/app.ts +++ b/src/store/app.ts @@ -152,7 +152,7 @@ export function updateCollapsibleIsOpen(prefix: string, name: string, v: boolean const defaultClashAPIConfig = { baseURL: document.getElementById('app')?.getAttribute('data-base-url') ?? 'http://127.0.0.1:9090', secret: '', - addedAt: 0 + addedAt: 0, }; // type Theme = 'light' | 'dark'; const defaultState: StateApp = { @@ -169,7 +169,7 @@ const defaultState: StateApp = { proxySortBy: 'Natural', hideUnavailableProxies: false, autoCloseOldConns: false, - logStreamingPaused: false + logStreamingPaused: false, }; function parseConfigQueryString() { diff --git a/src/store/configs.ts b/src/store/configs.ts index c533508..7571b4e 100644 --- a/src/store/configs.ts +++ b/src/store/configs.ts @@ -1,10 +1,4 @@ -import { - ClashGeneralConfig, - DispatchFn, - GetStateFn, - State, - StateConfigs, -} from 'src/store/types'; +import { ClashGeneralConfig, DispatchFn, GetStateFn, State, StateConfigs } from 'src/store/types'; import { ClashAPIConfig } from 'src/types'; import * as configsAPI from '../api/configs'; diff --git a/src/store/proxies.tsx b/src/store/proxies.tsx index 25200cd..0505fce 100644 --- a/src/store/proxies.tsx +++ b/src/store/proxies.tsx @@ -48,8 +48,7 @@ export const getDelay = (s: State) => s.proxies.delay; export const getProxyGroupNames = (s: State) => s.proxies.groupNames; export const getProxyProviders = (s: State) => s.proxies.proxyProviders || []; export const getDangleProxyNames = (s: State) => s.proxies.dangleProxyNames; -export const getShowModalClosePrevConns = (s: State) => - s.proxies.showModalClosePrevConns; +export const getShowModalClosePrevConns = (s: State) => s.proxies.showModalClosePrevConns; export function fetchProxies(apiConfig: ClashAPIConfig) { return async (dispatch: any, getState: any) => { @@ -58,10 +57,9 @@ export function fetchProxies(apiConfig: ClashAPIConfig) { proxiesAPI.fetchProviderProxies(apiConfig), ]); - const { - providers: proxyProviders, - proxies: providerProxies, - } = formatProxyProviders(providersData.providers); + const { providers: proxyProviders, proxies: providerProxies } = formatProxyProviders( + providersData.providers + ); const proxies = { ...providerProxies, ...proxiesData.proxies }; const [groupNames, proxyNames] = retrieveGroupNamesFrom(proxies); @@ -121,10 +119,7 @@ export function updateProviders(apiConfig: ClashAPIConfig, names: string[]) { }; } -async function healthcheckProviderByNameInternal( - apiConfig: ClashAPIConfig, - name: string -) { +async function healthcheckProviderByNameInternal(apiConfig: ClashAPIConfig, name: string) { try { await proxiesAPI.healthcheckProviderByName(apiConfig, name); } catch (x) { @@ -132,10 +127,7 @@ async function healthcheckProviderByNameInternal( } } -export function healthcheckProviderByName( - apiConfig: ClashAPIConfig, - name: string -) { +export function healthcheckProviderByName(apiConfig: ClashAPIConfig, name: string) { return async (dispatch: DispatchFn) => { await healthcheckProviderByNameInternal(apiConfig, name); // should be optimized @@ -168,16 +160,10 @@ async function closeGroupConns( } } - await Promise.all( - idsToClose.map((id) => connAPI.closeConnById(apiConfig, id).catch(noop)) - ); + await Promise.all(idsToClose.map((id) => connAPI.closeConnById(apiConfig, id).catch(noop))); } -function resolveChain( - proxies: ProxiesMapping, - groupName: string, - itemName: string -) { +function resolveChain(proxies: ProxiesMapping, groupName: string, itemName: string) { const chain = [itemName, groupName]; let child: ProxyItem; @@ -197,11 +183,7 @@ async function switchProxyImpl( itemName: string ) { try { - const res = await proxiesAPI.requestToSwitchProxy( - apiConfig, - groupName, - itemName - ); + const res = await proxiesAPI.requestToSwitchProxy(apiConfig, groupName, itemName); if (res.ok === false) { throw new Error(`failed to switch proxy: res.statusText`); } @@ -267,16 +249,10 @@ function closePrevConnsAndTheModal(apiConfig: ClashAPIConfig) { }; } -export function switchProxy( - apiConfig: ClashAPIConfig, - groupName: string, - itemName: string -) { +export function switchProxy(apiConfig: ClashAPIConfig, groupName: string, itemName: string) { return async (dispatch: DispatchFn, getState: GetStateFn) => { // switch proxy asynchronously - switchProxyImpl(dispatch, getState, apiConfig, groupName, itemName).catch( - noop - ); + switchProxyImpl(dispatch, getState, apiConfig, groupName, itemName).catch(noop); // optimistic UI update dispatch('store/proxies#switchProxy', (s) => { @@ -291,11 +267,7 @@ export function switchProxy( function requestDelayForProxyOnce(apiConfig: ClashAPIConfig, name: string) { return async (dispatch: DispatchFn, getState: GetStateFn) => { const latencyTestUrl = getLatencyTestUrl(getState()); - const res = await proxiesAPI.requestDelayForProxy( - apiConfig, - name, - latencyTestUrl - ); + const res = await proxiesAPI.requestDelayForProxy(apiConfig, name, latencyTestUrl); let error = ''; if (res.ok === false) { error = res.statusText; @@ -323,10 +295,7 @@ export function requestDelayForProxy(apiConfig: ClashAPIConfig, name: string) { }; } -export function requestDelayForProxies( - apiConfig: ClashAPIConfig, - names: string[] -) { +export function requestDelayForProxies(apiConfig: ClashAPIConfig, names: string[]) { return async (dispatch: DispatchFn, getState: GetStateFn) => { const proxyNames = getDangleProxyNames(getState()); @@ -342,9 +311,7 @@ export function requestDelayForProxies( export function requestDelayAll(apiConfig: ClashAPIConfig) { return async (dispatch: DispatchFn, getState: GetStateFn) => { const proxyNames = getDangleProxyNames(getState()); - await Promise.all( - proxyNames.map((p) => dispatch(requestDelayForProxy(apiConfig, p))) - ); + await Promise.all(proxyNames.map((p) => dispatch(requestDelayForProxy(apiConfig, p)))); const proxyProviders = getProxyProviders(getState()); // one by one for (const p of proxyProviders) { @@ -385,9 +352,7 @@ type ProvidersRaw = { [key: string]: ProxyProvider; }; -function formatProxyProviders( - providersInput: ProvidersRaw -): { +function formatProxyProviders(providersInput: ProvidersRaw): { providers: Array<FormattedProxyProvider>; proxies: { [key: string]: ProxyItem }; } { @@ -53,8 +53,7 @@ registerRoute( // precache, in this case same-origin .png requests like those from in public/ registerRoute( // Add in any other file extensions or routing criteria as needed. - ({ url }) => - url.origin === self.location.origin && url.pathname.endsWith('.png'), + ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst. new StaleWhileRevalidate({ cacheName: 'images', diff --git a/src/swRegistration.ts b/src/swRegistration.ts index 55ceb0b..0a684a8 100644 --- a/src/swRegistration.ts +++ b/src/swRegistration.ts @@ -3,9 +3,7 @@ const isLocalhost = Boolean( // [::1] is the IPv6 localhost address. window.location.hostname === '[::1]' || // 127.0.0.0/8 are considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) + window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/) ); type Config = { @@ -34,9 +32,7 @@ export function register(config?: Config) { // Add some additional logging to localhost, pointing developers to the // service worker/PWA documentation. navigator.serviceWorker.ready.then(() => { - console.log( - 'This web app is being served cache-first by a service worker' - ); + console.log('This web app is being served cache-first by a service worker'); }); } else { // Is not localhost. Just register service worker @@ -114,9 +110,7 @@ function checkValidServiceWorker(swUrl: string, config?: Config) { } }) .catch(() => { - console.log( - 'No internet connection found. App is running in offline mode.' - ); + console.log('No internet connection found. App is running in offline mode.'); }); } diff --git a/src/types.ts b/src/types.ts index 694289b..8446dfc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -3,4 +3,4 @@ export type ClashAPIConfig = { secret?: string; }; -export type LogsAPIConfig = ClashAPIConfig & { logLevel: string };
\ No newline at end of file +export type LogsAPIConfig = ClashAPIConfig & { logLevel: string }; |
