feat(config): reload config file, flush fake-ip data

This commit is contained in:
kunish 2023-09-16 02:50:21 +08:00
parent 3bc8b525d6
commit 6ffd1a8605
No known key found for this signature in database
GPG Key ID: 647A12B4F782C430
6 changed files with 101 additions and 35 deletions

View File

@ -1,6 +1,6 @@
import { createSignal } from 'solid-js' import { createSignal, ResourceActions } from 'solid-js'
import { toast } from 'solid-toast' import { toast } from 'solid-toast'
import { setBackendConfig, useRequest } from '~/signals' import { useRequest } from '~/signals'
import { import {
BackendVersion, BackendVersion,
Config, Config,
@ -22,11 +22,34 @@ export const closeSingleConnectionAPI = (id: string) => {
return request.delete(`connections/${id}`) return request.delete(`connections/${id}`)
} }
export const [reloadingConfigFile, setReloadingConfigFile] = createSignal(false)
export const [updatingGEODatabases, setUpdatingGEODatabases] = export const [updatingGEODatabases, setUpdatingGEODatabases] =
createSignal(false) createSignal(false)
export const [flushingFakeIPData, setFlushingFakeIPData] = createSignal(false)
export const [upgradingBackend, setUpgradingBackend] = createSignal(false) export const [upgradingBackend, setUpgradingBackend] = createSignal(false)
export const [restartingBackend, setRestartingBackend] = createSignal(false) export const [restartingBackend, setRestartingBackend] = createSignal(false)
export const reloadConfigFileAPI = async () => {
const request = useRequest()
setReloadingConfigFile(true)
try {
await request.put('configs', {
searchParams: { force: true },
json: { path: '', payload: '' },
})
} catch {}
setReloadingConfigFile(false)
}
export const flushFakeIPDataAPI = async () => {
const request = useRequest()
setFlushingFakeIPData(true)
try {
await request.post('cache/fakeip/flush')
} catch {}
setFlushingFakeIPData(false)
}
export const updateGEODatabasesAPI = async () => { export const updateGEODatabasesAPI = async () => {
const request = useRequest() const request = useRequest()
setUpdatingGEODatabases(true) setUpdatingGEODatabases(true)
@ -63,21 +86,14 @@ export const fetchBackendConfigAPI = () => {
export const updateBackendConfigAPI = async ( export const updateBackendConfigAPI = async (
key: keyof Config, key: keyof Config,
value: Config[keyof Config], value: Config[keyof Config],
refetch: ResourceActions<Config | undefined>['refetch'],
) => { ) => {
try { try {
const request = useRequest() const request = useRequest()
await request await request.patch('configs', { json: { [key]: value } }).json<Config>()
.patch('configs', {
body: JSON.stringify({
[key]: value,
}),
})
.json<Config>()
const updatedConfig = await fetchBackendConfigAPI() await refetch()
setBackendConfig(updatedConfig)
} catch (err) { } catch (err) {
toast.error((err as Error).message) toast.error((err as Error).message)
} }

View File

@ -87,4 +87,6 @@ export default {
closed: 'Closed', closed: 'Closed',
sort: 'Sort', sort: 'Sort',
hideUnAvailableProxies: 'Hide UnAvailable Proxies', hideUnAvailableProxies: 'Hide UnAvailable Proxies',
reloadConfigFile: 'Reload Config File',
flushFakeIPData: 'Flush Fake-IP Data',
} }

View File

@ -87,4 +87,6 @@ export default {
closed: '已关闭', closed: '已关闭',
sort: '排序', sort: '排序',
hideUnAvailableProxies: '隐藏不可用节点', hideUnAvailableProxies: '隐藏不可用节点',
reloadConfigFile: '重新加载配置文件',
flushFakeIPData: '清空 Fake-IP 数据',
} }

View File

@ -2,11 +2,22 @@ import { createForm } from '@felte/solid'
import { validator } from '@felte/validator-zod' import { validator } from '@felte/validator-zod'
import { useI18n } from '@solid-primitives/i18n' import { useI18n } from '@solid-primitives/i18n'
import { useNavigate } from '@solidjs/router' import { useNavigate } from '@solidjs/router'
import { For, Show, createSignal, onMount } from 'solid-js' import {
For,
Show,
createEffect,
createResource,
createSignal,
onMount,
} from 'solid-js'
import { z } from 'zod' import { z } from 'zod'
import { import {
fetchBackendConfigAPI, fetchBackendConfigAPI,
fetchBackendVersionAPI, fetchBackendVersionAPI,
flushFakeIPDataAPI,
flushingFakeIPData,
reloadConfigFileAPI,
reloadingConfigFile,
restartBackendAPI, restartBackendAPI,
restartingBackend, restartingBackend,
updateBackendConfigAPI, updateBackendConfigAPI,
@ -19,11 +30,9 @@ import { Button, ConfigTitle } from '~/components'
import { LANG, MODE_OPTIONS, ROUTES, themes } from '~/constants' import { LANG, MODE_OPTIONS, ROUTES, themes } from '~/constants'
import { import {
autoSwitchTheme, autoSwitchTheme,
backendConfig,
favDayTheme, favDayTheme,
favNightTheme, favNightTheme,
setAutoSwitchTheme, setAutoSwitchTheme,
setBackendConfig,
setFavDayTheme, setFavDayTheme,
setFavNightTheme, setFavNightTheme,
setSelectedEndpoint, setSelectedEndpoint,
@ -103,27 +112,54 @@ const configFormSchema = z.object({
const ConfigForm = () => { const ConfigForm = () => {
const [t] = useI18n() const [t] = useI18n()
const navigate = useNavigate()
const portsList = [ const portsList = [
{ {
label: 'HTTP Port', label: 'HTTP Port',
key: 'port', key: 'port',
onChange: (e: Event & { target: HTMLInputElement }) =>
void updateBackendConfigAPI('port', Number(e.target.value), refetch),
}, },
{ {
label: 'Socks Port', label: 'Socks Port',
key: 'socks-port', key: 'socks-port',
onChange: (e: Event & { target: HTMLInputElement }) =>
void updateBackendConfigAPI(
'socks-port',
Number(e.target.value),
refetch,
),
}, },
{ {
label: 'Redir Port', label: 'Redir Port',
key: 'redir-port', key: 'redir-port',
onChange: (e: Event & { target: HTMLInputElement }) =>
void updateBackendConfigAPI(
'redir-port',
Number(e.target.value),
refetch,
),
}, },
{ {
label: 'TProxy Port', label: 'TProxy Port',
key: 'tproxy-port', key: 'tproxy-port',
onChange: (e: Event & { target: HTMLInputElement }) =>
void updateBackendConfigAPI(
'tproxy-port',
Number(e.target.value),
refetch,
),
}, },
{ {
label: 'Mixed Port', label: 'Mixed Port',
key: 'mixed-port', key: 'mixed-port',
onChange: (e: Event & { target: HTMLInputElement }) =>
void updateBackendConfigAPI(
'mixed-port',
Number(e.target.value),
refetch,
),
}, },
] ]
@ -131,19 +167,30 @@ const ConfigForm = () => {
z.infer<typeof configFormSchema> z.infer<typeof configFormSchema>
>({ extend: validator({ schema: configFormSchema }) }) >({ extend: validator({ schema: configFormSchema }) })
onMount(async () => { const [configsData, { refetch }] = createResource(fetchBackendConfigAPI)
const configs = await fetchBackendConfigAPI()
setBackendConfig(configs) createEffect(() => {
setInitialValues(configs) const configs = configsData()
reset()
if (configs) {
setInitialValues(configs)
reset()
}
}) })
const onSwitchEndpointClick = () => {
setSelectedEndpoint('')
navigate(ROUTES.Setup)
}
return ( return (
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<select <select
class="select select-bordered" class="select select-bordered"
value={backendConfig()?.mode} value={configsData()?.mode}
onChange={(e) => updateBackendConfigAPI('mode', e.target.value)} onChange={(e) =>
void updateBackendConfigAPI('mode', e.target.value, refetch)
}
> >
<option value={MODE_OPTIONS.Global}>{t('global')}</option> <option value={MODE_OPTIONS.Global}>{t('global')}</option>
<option value={MODE_OPTIONS.Rule}>{t('rule')}</option> <option value={MODE_OPTIONS.Rule}>{t('rule')}</option>
@ -163,6 +210,7 @@ const ConfigForm = () => {
type="number" type="number"
class="input input-bordered" class="input input-bordered"
placeholder={item.label} placeholder={item.label}
onChange={item.onChange}
/> />
</div> </div>
)} )}
@ -170,6 +218,14 @@ const ConfigForm = () => {
</form> </form>
<div class="flex flex-wrap items-center gap-2"> <div class="flex flex-wrap items-center gap-2">
<Button loading={reloadingConfigFile()} onClick={reloadConfigFileAPI}>
{t('reloadConfigFile')}
</Button>
<Button loading={flushingFakeIPData()} onClick={flushFakeIPDataAPI}>
{t('flushFakeIPData')}
</Button>
<Button <Button
loading={updatingGEODatabases()} loading={updatingGEODatabases()}
onClick={updateGEODatabasesAPI} onClick={updateGEODatabasesAPI}
@ -184,6 +240,8 @@ const ConfigForm = () => {
<Button loading={restartingBackend()} onClick={restartBackendAPI}> <Button loading={restartingBackend()} onClick={restartBackendAPI}>
{t('restartCore')} {t('restartCore')}
</Button> </Button>
<Button onClick={onSwitchEndpointClick}>{t('switchEndpoint')}</Button>
</div> </div>
</div> </div>
) )
@ -191,12 +249,6 @@ const ConfigForm = () => {
const ConfigForXd = () => { const ConfigForXd = () => {
const [t, { locale }] = useI18n() const [t, { locale }] = useI18n()
const navigate = useNavigate()
const onSwitchEndpointClick = () => {
setSelectedEndpoint('')
navigate(ROUTES.Setup)
}
const autoSwitchThemeSubChild = () => ( const autoSwitchThemeSubChild = () => (
<Show when={autoSwitchTheme()}> <Show when={autoSwitchTheme()}>
@ -284,10 +336,6 @@ const ConfigForXd = () => {
{t('switchLanguage')} {t('switchLanguage')}
</Button> </Button>
</div> </div>
<div>
<Button onClick={onSwitchEndpointClick}>{t('switchEndpoint')}</Button>
</div>
</div> </div>
) )
} }

View File

@ -10,7 +10,6 @@ import {
TAILWINDCSS_SIZE, TAILWINDCSS_SIZE,
} from '~/constants' } from '~/constants'
import { setCurTheme } from '~/signals' import { setCurTheme } from '~/signals'
import { Config } from '~/types'
export const [proxiesPreviewType, setProxiesPreviewType] = makePersisted( export const [proxiesPreviewType, setProxiesPreviewType] = makePersisted(
createSignal(PROXIES_PREVIEW_TYPE.Auto), createSignal(PROXIES_PREVIEW_TYPE.Auto),
@ -112,5 +111,3 @@ export const useAutoSwitchTheme = () => {
} }
}) })
} }
export const [backendConfig, setBackendConfig] = createSignal<Config>()

View File

@ -25,6 +25,7 @@ type ProxyInfo = {
xudp: boolean xudp: boolean
type: string type: string
} }
// these signals should be global state // these signals should be global state
const [proxies, setProxies] = createSignal<Proxy[]>([]) const [proxies, setProxies] = createSignal<Proxy[]>([])
const [proxyProviders, setProxyProviders] = createSignal<ProxyProvider[]>([]) const [proxyProviders, setProxyProviders] = createSignal<ProxyProvider[]>([])