mirror of
https://github.com/woodchen-ink/clash-and-dashboard.git
synced 2025-07-18 14:01:56 +08:00
Chore: improve swr use
This commit is contained in:
parent
6265c5adb1
commit
1c45cc16e6
@ -1,5 +1,4 @@
|
|||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
import useSWR from 'swr'
|
|
||||||
import EE from '@lib/event'
|
import EE from '@lib/event'
|
||||||
import { useRound } from '@lib/hook'
|
import { useRound } from '@lib/hook'
|
||||||
import { Card, Header, Icon, Checkbox } from '@components'
|
import { Card, Header, Icon, Checkbox } from '@components'
|
||||||
@ -68,12 +67,10 @@ function ProxyGroups () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ProxyProviders () {
|
function ProxyProviders () {
|
||||||
const { providers, update } = useProxyProviders()
|
const { providers } = useProxyProviders()
|
||||||
const { useTranslation } = useI18n()
|
const { useTranslation } = useI18n()
|
||||||
const { t } = useTranslation('Proxies')
|
const { t } = useTranslation('Proxies')
|
||||||
|
|
||||||
useSWR('providers', update)
|
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
{
|
{
|
||||||
providers.length !== 0 &&
|
providers.length !== 0 &&
|
||||||
@ -95,12 +92,9 @@ function ProxyProviders () {
|
|||||||
|
|
||||||
function Proxies () {
|
function Proxies () {
|
||||||
const { proxies } = useProxy()
|
const { proxies } = useProxy()
|
||||||
const { update: updateGeneral } = useGeneral()
|
|
||||||
const { useTranslation } = useI18n()
|
const { useTranslation } = useI18n()
|
||||||
const { t } = useTranslation('Proxies')
|
const { t } = useTranslation('Proxies')
|
||||||
|
|
||||||
useSWR('general', updateGeneral)
|
|
||||||
|
|
||||||
function handleNotitySpeedTest () {
|
function handleNotitySpeedTest () {
|
||||||
EE.notifySpeedTest()
|
EE.notifySpeedTest()
|
||||||
}
|
}
|
||||||
@ -144,9 +138,6 @@ function Proxies () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ProxyContainer () {
|
export default function ProxyContainer () {
|
||||||
const { update: updateProxy } = useProxy()
|
|
||||||
useSWR('proxies', updateProxy)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="page">
|
<div className="page">
|
||||||
<ProxyGroups />
|
<ProxyGroups />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { useLayoutEffect } from 'react'
|
import React from 'react'
|
||||||
import { Header, Card, Row, Col } from '@components'
|
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 { FixedSizeList as List } from 'react-window'
|
||||||
import AutoSizer from 'react-virtualized-auto-sizer'
|
import AutoSizer from 'react-virtualized-auto-sizer'
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
@ -8,17 +8,10 @@ import { Provider } from './Provider'
|
|||||||
import './style.scss'
|
import './style.scss'
|
||||||
|
|
||||||
function RuleProviders () {
|
function RuleProviders () {
|
||||||
const { providers, update } = useRuleProviders()
|
const { providers } = useRuleProviders()
|
||||||
const { premium } = useVersion()
|
|
||||||
const { useTranslation } = useI18n()
|
const { useTranslation } = useI18n()
|
||||||
const { t } = useTranslation('Rules')
|
const { t } = useTranslation('Rules')
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
if (premium) {
|
|
||||||
update()
|
|
||||||
}
|
|
||||||
}, [premium])
|
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
{
|
{
|
||||||
providers.length !== 0 &&
|
providers.length !== 0 &&
|
||||||
|
@ -25,11 +25,6 @@ export default function Settings () {
|
|||||||
mixedProxyPort: 0
|
mixedProxyPort: 0
|
||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchGeneral()
|
|
||||||
fetchClashXData()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
set('socks5ProxyPort', general?.socksPort ?? 0)
|
set('socks5ProxyPort', general?.socksPort ?? 0)
|
||||||
set('httpProxyPort', general?.port ?? 0)
|
set('httpProxyPort', general?.port ?? 0)
|
||||||
@ -81,10 +76,10 @@ export default function Settings () {
|
|||||||
} = apiInfo
|
} = apiInfo
|
||||||
|
|
||||||
const { allowLan, mode } = general
|
const { allowLan, mode } = general
|
||||||
const {
|
|
||||||
startAtLogin,
|
const startAtLogin = clashXData?.startAtLogin ?? false
|
||||||
systemProxy
|
const systemProxy = clashXData?.systemProxy ?? false
|
||||||
} = clashXData
|
const isClashX = clashXData?.isClashX ?? false
|
||||||
|
|
||||||
const proxyModeOptions = useMemo(() => {
|
const proxyModeOptions = useMemo(() => {
|
||||||
const options = [
|
const options = [
|
||||||
@ -108,7 +103,7 @@ export default function Settings () {
|
|||||||
<span className="label">{t('labels.startAtLogin')}</span>
|
<span className="label">{t('labels.startAtLogin')}</span>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={8} className="value-column">
|
<Col span={8} className="value-column">
|
||||||
<Switch disabled={!clashXData.isClashX} checked={startAtLogin} onChange={handleStartAtLoginChange} />
|
<Switch disabled={!clashXData?.isClashX} checked={startAtLogin} onChange={handleStartAtLoginChange} />
|
||||||
</Col>
|
</Col>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
@ -127,7 +122,7 @@ export default function Settings () {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={8} className="value-column">
|
<Col span={8} className="value-column">
|
||||||
<Switch
|
<Switch
|
||||||
disabled={!clashXData.isClashX}
|
disabled={!isClashX}
|
||||||
checked={systemProxy}
|
checked={systemProxy}
|
||||||
onChange={handleSetSystemProxy}
|
onChange={handleSetSystemProxy}
|
||||||
/>
|
/>
|
||||||
@ -167,7 +162,7 @@ export default function Settings () {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<Input
|
<Input
|
||||||
disabled={clashXData.isClashX}
|
disabled={isClashX}
|
||||||
value={info.socks5ProxyPort}
|
value={info.socks5ProxyPort}
|
||||||
onChange={socks5ProxyPort => set('socks5ProxyPort', +socks5ProxyPort)}
|
onChange={socks5ProxyPort => set('socks5ProxyPort', +socks5ProxyPort)}
|
||||||
onBlur={handleSocksPortSave}
|
onBlur={handleSocksPortSave}
|
||||||
@ -182,7 +177,7 @@ export default function Settings () {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<Input
|
<Input
|
||||||
disabled={clashXData.isClashX}
|
disabled={isClashX}
|
||||||
value={info.httpProxyPort}
|
value={info.httpProxyPort}
|
||||||
onChange={httpProxyPort => set('httpProxyPort', +httpProxyPort)}
|
onChange={httpProxyPort => set('httpProxyPort', +httpProxyPort)}
|
||||||
onBlur={handleHttpPortSave}
|
onBlur={handleHttpPortSave}
|
||||||
@ -195,7 +190,7 @@ export default function Settings () {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<Input
|
<Input
|
||||||
disabled={clashXData.isClashX}
|
disabled={isClashX}
|
||||||
value={info.mixedProxyPort}
|
value={info.mixedProxyPort}
|
||||||
onChange={mixedProxyPort => set('mixedProxyPort', +mixedProxyPort)}
|
onChange={mixedProxyPort => set('mixedProxyPort', +mixedProxyPort)}
|
||||||
onBlur={handleMixedPortSave}
|
onBlur={handleMixedPortSave}
|
||||||
@ -210,8 +205,8 @@ export default function Settings () {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col className="external-controller" span={10}>
|
<Col className="external-controller" span={10}>
|
||||||
<span
|
<span
|
||||||
className={classnames({ 'modify-btn': !clashXData.isClashX })}
|
className={classnames({ 'modify-btn': !isClashX })}
|
||||||
onClick={() => !clashXData.isClashX && setIdentity(false)}>
|
onClick={() => !isClashX && setIdentity(false)}>
|
||||||
{`${externalControllerHost}:${externalControllerPort}`}
|
{`${externalControllerHost}:${externalControllerPort}`}
|
||||||
</span>
|
</span>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -20,11 +20,10 @@ export default function Sidebar (props: SidebarProps) {
|
|||||||
const { routes } = props
|
const { routes } = props
|
||||||
const { useTranslation } = useI18n()
|
const { useTranslation } = useI18n()
|
||||||
const { version, premium, update } = useVersion()
|
const { version, premium, update } = useVersion()
|
||||||
const { data: { isClashX }, update: updateClashXData } = useClashXData()
|
const { data } = useClashXData()
|
||||||
const { t } = useTranslation('SideBar')
|
const { t } = useTranslation('SideBar')
|
||||||
|
|
||||||
useSWR('version', update)
|
useSWR('version', update)
|
||||||
useSWR('clashx', updateClashXData)
|
|
||||||
|
|
||||||
const navlinks = routes.map(
|
const navlinks = routes.map(
|
||||||
({ path, name, exact, noMobile }) => (
|
({ path, name, exact, noMobile }) => (
|
||||||
@ -41,7 +40,7 @@ export default function Sidebar (props: SidebarProps) {
|
|||||||
{ navlinks }
|
{ navlinks }
|
||||||
</ul>
|
</ul>
|
||||||
<div className="sidebar-version">
|
<div className="sidebar-version">
|
||||||
<span className="sidebar-version-label">Clash{ isClashX && 'X' } { t('Version') }</span>
|
<span className="sidebar-version-label">Clash{ data?.isClashX && 'X' } { t('Version') }</span>
|
||||||
<span className="sidebar-version-text">{ version }</span>
|
<span className="sidebar-version-text">{ version }</span>
|
||||||
{ premium && <span className="sidebar-version-label">Premium</span> }
|
{ premium && <span className="sidebar-version-label">Premium</span> }
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { atom, useRecoilState, selector } from 'recoil'
|
import { atom, useRecoilState, selector } from 'recoil'
|
||||||
import get from 'lodash/get'
|
import get from 'lodash/get'
|
||||||
import throttle from 'lodash/throttle'
|
import { useCallback, useEffect } from 'react'
|
||||||
import { useCallback } from 'react'
|
|
||||||
import { AxiosError } from 'axios'
|
import { AxiosError } from 'axios'
|
||||||
|
import swr from 'swr'
|
||||||
|
|
||||||
import { getLanguage, setLanguage, Lang, locales, Language } from '@i18n'
|
import { getLanguage, setLanguage, Lang, locales, Language } from '@i18n'
|
||||||
import { useRecoilObjectWithImmer } from '@lib/recoil'
|
import { useRecoilObjectWithImmer } from '@lib/recoil'
|
||||||
@ -108,59 +108,43 @@ export const proxyProvider = atom({
|
|||||||
})
|
})
|
||||||
|
|
||||||
export function useProxyProviders () {
|
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 proxyProviders = await API.getProxyProviders()
|
||||||
|
|
||||||
const providers = Object.keys(proxyProviders.data.providers)
|
return Object.keys(proxyProviders.data.providers)
|
||||||
.map<API.Provider>(name => proxyProviders.data.providers[name])
|
.map<API.Provider>(name => proxyProviders.data.providers[name])
|
||||||
.filter(pd => pd.name !== 'default')
|
.filter(pd => pd.name !== 'default')
|
||||||
.filter(pd => pd.vehicleType !== 'Compatible')
|
.filter(pd => pd.vehicleType !== 'Compatible')
|
||||||
|
|
||||||
set(providers)
|
|
||||||
}
|
|
||||||
|
|
||||||
return { providers: data, update }
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ruleProvider = atom({
|
|
||||||
key: 'ruleProvider',
|
|
||||||
default: [] as API.RuleProvider[]
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
useEffect(() => set(data ?? []), [data, set])
|
||||||
|
return { providers, update: mutate }
|
||||||
|
}
|
||||||
|
|
||||||
export function useRuleProviders () {
|
export function useRuleProviders () {
|
||||||
const [data, set] = useRecoilState(ruleProvider)
|
|
||||||
const [{ premium }] = useRecoilState(version)
|
const [{ premium }] = useRecoilState(version)
|
||||||
|
|
||||||
async function update () {
|
const { data, mutate } = swr('/providers/rule', async () => {
|
||||||
if (!premium) {
|
if (!premium) {
|
||||||
return
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
const ruleProviders = await API.getRuleProviders()
|
const ruleProviders = await API.getRuleProviders()
|
||||||
|
|
||||||
const providers = Object.keys(ruleProviders.data.providers)
|
return Object.keys(ruleProviders.data.providers)
|
||||||
.map<API.RuleProvider>(name => ruleProviders.data.providers[name])
|
.map<API.RuleProvider>(name => ruleProviders.data.providers[name])
|
||||||
|
|
||||||
set(providers)
|
|
||||||
}
|
|
||||||
|
|
||||||
return { providers: data, update }
|
|
||||||
}
|
|
||||||
|
|
||||||
export const general = atom({
|
|
||||||
key: 'general',
|
|
||||||
default: {} as Models.Data['general']
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export function useGeneral () {
|
return { providers: data ?? [], update: mutate }
|
||||||
const [data, set] = useRecoilState(general)
|
}
|
||||||
|
|
||||||
async function update () {
|
export function useGeneral () {
|
||||||
|
const { data, mutate } = swr('/config', async () => {
|
||||||
const resp = await API.getConfig()
|
const resp = await API.getConfig()
|
||||||
const data = resp.data
|
const data = resp.data
|
||||||
set({
|
return {
|
||||||
port: data.port,
|
port: data.port,
|
||||||
socksPort: data['socks-port'],
|
socksPort: data['socks-port'],
|
||||||
mixedPort: data['mixed-port'] ?? 0,
|
mixedPort: data['mixed-port'] ?? 0,
|
||||||
@ -168,10 +152,10 @@ export function useGeneral () {
|
|||||||
mode: data.mode.toLowerCase() as Models.Data['general']['mode'],
|
mode: data.mode.toLowerCase() as Models.Data['general']['mode'],
|
||||||
logLevel: data['log-level'],
|
logLevel: data['log-level'],
|
||||||
allowLan: data['allow-lan']
|
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({
|
export const proxies = atom({
|
||||||
@ -184,9 +168,9 @@ export const proxies = atom({
|
|||||||
})
|
})
|
||||||
|
|
||||||
export function useProxy () {
|
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 allProxies = await API.getProxies()
|
||||||
|
|
||||||
const global = allProxies.data.proxies.GLOBAL as API.Group
|
const global = allProxies.data.proxies.GLOBAL as API.Group
|
||||||
@ -199,15 +183,15 @@ export function useProxy () {
|
|||||||
.filter(key => !unUsedProxy.has(key))
|
.filter(key => !unUsedProxy.has(key))
|
||||||
.map(key => ({ ...allProxies.data.proxies[key], name: key }))
|
.map(key => ({ ...allProxies.data.proxies[key], name: key }))
|
||||||
const [proxy, groups] = partition(proxies, proxy => !policyGroup.has(proxy.type))
|
const [proxy, groups] = partition(proxies, proxy => !policyGroup.has(proxy.type))
|
||||||
|
return { proxies: proxy as API.Proxy[], groups: groups as API.Group[], global: global }
|
||||||
set({ proxies: proxy as API.Proxy[], groups: groups as API.Group[], global: global })
|
})
|
||||||
}
|
useEffect(() => data && set(data), [data, set])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
proxies: data.proxies,
|
proxies: allProxy.proxies,
|
||||||
groups: data.groups,
|
groups: allProxy.groups,
|
||||||
global: data.global,
|
global: allProxy.global,
|
||||||
update,
|
update: mutate,
|
||||||
set
|
set
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,30 +216,23 @@ export const proxyMapping = selector({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const clashxData = atom({
|
export function useClashXData () {
|
||||||
key: 'clashxData',
|
const { data, mutate } = swr('/clashx', async () => {
|
||||||
default: {
|
if (!isClashX()) {
|
||||||
|
return {
|
||||||
isClashX: false,
|
isClashX: false,
|
||||||
startAtLogin: false,
|
startAtLogin: false,
|
||||||
systemProxy: false
|
systemProxy: false
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
export function useClashXData () {
|
|
||||||
const [data, set] = useRecoilState(clashxData)
|
|
||||||
|
|
||||||
async function update () {
|
|
||||||
if (!isClashX()) {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const startAtLogin = await jsBridge?.getStartAtLogin() ?? false
|
const startAtLogin = await jsBridge?.getStartAtLogin() ?? false
|
||||||
const systemProxy = await jsBridge?.isSystemProxySet() ?? 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({
|
export const apiData = atom({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user