diff --git a/src/containers/Proxies/index.tsx b/src/containers/Proxies/index.tsx index a3ae11f..63663af 100644 --- a/src/containers/Proxies/index.tsx +++ b/src/containers/Proxies/index.tsx @@ -1,5 +1,4 @@ import React, { useMemo } from 'react' -import useSWR from 'swr' import EE from '@lib/event' import { useRound } from '@lib/hook' import { Card, Header, Icon, Checkbox } from '@components' @@ -68,12 +67,10 @@ function ProxyGroups () { } function ProxyProviders () { - const { providers, update } = useProxyProviders() + const { providers } = useProxyProviders() const { useTranslation } = useI18n() const { t } = useTranslation('Proxies') - useSWR('providers', update) - return <> { providers.length !== 0 && @@ -95,12 +92,9 @@ function ProxyProviders () { function Proxies () { const { proxies } = useProxy() - const { update: updateGeneral } = useGeneral() const { useTranslation } = useI18n() const { t } = useTranslation('Proxies') - useSWR('general', updateGeneral) - function handleNotitySpeedTest () { EE.notifySpeedTest() } @@ -144,9 +138,6 @@ function Proxies () { } export default function ProxyContainer () { - const { update: updateProxy } = useProxy() - useSWR('proxies', updateProxy) - return (
diff --git a/src/containers/Rules/index.tsx b/src/containers/Rules/index.tsx index dc50f6b..e6b8146 100644 --- a/src/containers/Rules/index.tsx +++ b/src/containers/Rules/index.tsx @@ -1,6 +1,6 @@ -import React, { useLayoutEffect } from 'react' +import React from 'react' import { Header, Card, Row, Col } from '@components' -import { useI18n, useRule, useRuleProviders, useVersion } from '@stores' +import { useI18n, useRule, useRuleProviders } from '@stores' import { FixedSizeList as List } from 'react-window' import AutoSizer from 'react-virtualized-auto-sizer' import useSWR from 'swr' @@ -8,17 +8,10 @@ import { Provider } from './Provider' import './style.scss' function RuleProviders () { - const { providers, update } = useRuleProviders() - const { premium } = useVersion() + const { providers } = useRuleProviders() const { useTranslation } = useI18n() const { t } = useTranslation('Rules') - useLayoutEffect(() => { - if (premium) { - update() - } - }, [premium]) - return <> { providers.length !== 0 && diff --git a/src/containers/Settings/index.tsx b/src/containers/Settings/index.tsx index aa09e17..d4681d2 100644 --- a/src/containers/Settings/index.tsx +++ b/src/containers/Settings/index.tsx @@ -25,11 +25,6 @@ export default function Settings () { mixedProxyPort: 0 }) - useEffect(() => { - fetchGeneral() - fetchClashXData() - }, []) - useEffect(() => { set('socks5ProxyPort', general?.socksPort ?? 0) set('httpProxyPort', general?.port ?? 0) @@ -81,10 +76,10 @@ export default function Settings () { } = apiInfo const { allowLan, mode } = general - const { - startAtLogin, - systemProxy - } = clashXData + + const startAtLogin = clashXData?.startAtLogin ?? false + const systemProxy = clashXData?.systemProxy ?? false + const isClashX = clashXData?.isClashX ?? false const proxyModeOptions = useMemo(() => { const options = [ @@ -108,7 +103,7 @@ export default function Settings () { {t('labels.startAtLogin')} - + @@ -127,7 +122,7 @@ export default function Settings () { @@ -167,7 +162,7 @@ export default function Settings () { set('socks5ProxyPort', +socks5ProxyPort)} onBlur={handleSocksPortSave} @@ -182,7 +177,7 @@ export default function Settings () { set('httpProxyPort', +httpProxyPort)} onBlur={handleHttpPortSave} @@ -195,7 +190,7 @@ export default function Settings () { set('mixedProxyPort', +mixedProxyPort)} onBlur={handleMixedPortSave} @@ -210,8 +205,8 @@ export default function Settings () { !clashXData.isClashX && setIdentity(false)}> + className={classnames({ 'modify-btn': !isClashX })} + onClick={() => !isClashX && setIdentity(false)}> {`${externalControllerHost}:${externalControllerPort}`} diff --git a/src/containers/Sidebar/index.tsx b/src/containers/Sidebar/index.tsx index bac28f0..183d91e 100644 --- a/src/containers/Sidebar/index.tsx +++ b/src/containers/Sidebar/index.tsx @@ -20,11 +20,10 @@ export default function Sidebar (props: SidebarProps) { const { routes } = props const { useTranslation } = useI18n() const { version, premium, update } = useVersion() - const { data: { isClashX }, update: updateClashXData } = useClashXData() + const { data } = useClashXData() const { t } = useTranslation('SideBar') useSWR('version', update) - useSWR('clashx', updateClashXData) const navlinks = routes.map( ({ path, name, exact, noMobile }) => ( @@ -41,7 +40,7 @@ export default function Sidebar (props: SidebarProps) { { navlinks }
- Clash{ isClashX && 'X' } { t('Version') } + Clash{ data?.isClashX && 'X' } { t('Version') } { version } { premium && Premium }
diff --git a/src/stores/recoil.ts b/src/stores/recoil.ts index a078c5d..4766b9e 100644 --- a/src/stores/recoil.ts +++ b/src/stores/recoil.ts @@ -1,8 +1,8 @@ import { atom, useRecoilState, selector } from 'recoil' import get from 'lodash/get' -import throttle from 'lodash/throttle' -import { useCallback } from 'react' +import { useCallback, useEffect } from 'react' import { AxiosError } from 'axios' +import swr from 'swr' import { getLanguage, setLanguage, Lang, locales, Language } from '@i18n' import { useRecoilObjectWithImmer } from '@lib/recoil' @@ -108,59 +108,43 @@ export const proxyProvider = atom({ }) export function useProxyProviders () { - const [data, set] = useRecoilState(proxyProvider) + const [providers, set] = useRecoilState(proxyProvider) - async function update () { + const { data, mutate } = swr('/providers/proxy', async () => { const proxyProviders = await API.getProxyProviders() - const providers = Object.keys(proxyProviders.data.providers) + return Object.keys(proxyProviders.data.providers) .map(name => proxyProviders.data.providers[name]) .filter(pd => pd.name !== 'default') .filter(pd => pd.vehicleType !== 'Compatible') + }) - set(providers) - } - - return { providers: data, update } + useEffect(() => set(data ?? []), [data, set]) + return { providers, update: mutate } } -export const ruleProvider = atom({ - key: 'ruleProvider', - default: [] as API.RuleProvider[] -}) - export function useRuleProviders () { - const [data, set] = useRecoilState(ruleProvider) const [{ premium }] = useRecoilState(version) - async function update () { + const { data, mutate } = swr('/providers/rule', async () => { if (!premium) { - return + return [] } const ruleProviders = await API.getRuleProviders() - const providers = Object.keys(ruleProviders.data.providers) + return Object.keys(ruleProviders.data.providers) .map(name => ruleProviders.data.providers[name]) + }) - set(providers) - } - - return { providers: data, update } + return { providers: data ?? [], update: mutate } } -export const general = atom({ - key: 'general', - default: {} as Models.Data['general'] -}) - export function useGeneral () { - const [data, set] = useRecoilState(general) - - async function update () { + const { data, mutate } = swr('/config', async () => { const resp = await API.getConfig() const data = resp.data - set({ + return { port: data.port, socksPort: data['socks-port'], mixedPort: data['mixed-port'] ?? 0, @@ -168,10 +152,10 @@ export function useGeneral () { mode: data.mode.toLowerCase() as Models.Data['general']['mode'], logLevel: data['log-level'], allowLan: data['allow-lan'] - }) - } + } as Models.Data['general'] + }) - return { general: data, update: throttle(update, 50) } + return { general: data ?? {} as Models.Data['general'], update: mutate } } export const proxies = atom({ @@ -184,9 +168,9 @@ export const proxies = atom({ }) export function useProxy () { - const [data, set] = useRecoilObjectWithImmer(proxies) + const [allProxy, set] = useRecoilObjectWithImmer(proxies) - async function update () { + const { data, mutate } = swr('/proxies', async () => { const allProxies = await API.getProxies() const global = allProxies.data.proxies.GLOBAL as API.Group @@ -199,15 +183,15 @@ export function useProxy () { .filter(key => !unUsedProxy.has(key)) .map(key => ({ ...allProxies.data.proxies[key], name: key })) const [proxy, groups] = partition(proxies, proxy => !policyGroup.has(proxy.type)) - - set({ proxies: proxy as API.Proxy[], groups: groups as API.Group[], global: global }) - } + return { proxies: proxy as API.Proxy[], groups: groups as API.Group[], global: global } + }) + useEffect(() => data && set(data), [data, set]) return { - proxies: data.proxies, - groups: data.groups, - global: data.global, - update, + proxies: allProxy.proxies, + groups: allProxy.groups, + global: allProxy.global, + update: mutate, set } } @@ -232,30 +216,23 @@ export const proxyMapping = selector({ } }) -export const clashxData = atom({ - key: 'clashxData', - default: { - isClashX: false, - startAtLogin: false, - systemProxy: false - } -}) - export function useClashXData () { - const [data, set] = useRecoilState(clashxData) - - async function update () { + const { data, mutate } = swr('/clashx', async () => { if (!isClashX()) { - return + return { + isClashX: false, + startAtLogin: false, + systemProxy: false + } } const startAtLogin = await jsBridge?.getStartAtLogin() ?? false const systemProxy = await jsBridge?.isSystemProxySet() ?? false - set({ startAtLogin, systemProxy, isClashX: true }) - } + return { startAtLogin, systemProxy, isClashX: true } + }) - return { data, update } + return { data, update: mutate } } export const apiData = atom({