mirror of
https://github.com/woodchen-ink/clash-and-dashboard.git
synced 2025-07-18 14:01:56 +08:00
Chore: code improvement
This commit is contained in:
parent
8199612bc7
commit
d66cf8f9fa
730
package-lock.json
generated
730
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
38
package.json
38
package.json
@ -28,17 +28,17 @@
|
|||||||
"contributors:generate": "all-contributors generate"
|
"contributors:generate": "all-contributors generate"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.6.0",
|
"@babel/cli": "^7.6.2",
|
||||||
"@babel/core": "^7.6.0",
|
"@babel/core": "^7.6.2",
|
||||||
"@babel/preset-env": "^7.6.0",
|
"@babel/preset-env": "^7.6.2",
|
||||||
"@babel/preset-react": "^7.0.0",
|
"@babel/preset-react": "^7.0.0",
|
||||||
"@hot-loader/react-dom": "^16.9.0",
|
"@hot-loader/react-dom": "^16.9.0",
|
||||||
"@types/classnames": "^2.2.8",
|
"@types/classnames": "^2.2.8",
|
||||||
"@types/lodash-es": "^4.17.3",
|
"@types/lodash-es": "^4.17.3",
|
||||||
"@types/node": "^12.7.5",
|
"@types/node": "^12.7.8",
|
||||||
"@types/react": "^16.9.2",
|
"@types/react": "^16.9.3",
|
||||||
"@types/react-dom": "^16.9.0",
|
"@types/react-dom": "^16.9.1",
|
||||||
"@types/react-router-dom": "^4.3.5",
|
"@types/react-router-dom": "^5.1.0",
|
||||||
"@types/react-virtualized-auto-sizer": "^1.0.0",
|
"@types/react-virtualized-auto-sizer": "^1.0.0",
|
||||||
"@types/react-window": "^1.8.1",
|
"@types/react-window": "^1.8.1",
|
||||||
"autoprefixer": "^9.6.1",
|
"autoprefixer": "^9.6.1",
|
||||||
@ -52,22 +52,22 @@
|
|||||||
"mini-css-extract-plugin": "^0.8.0",
|
"mini-css-extract-plugin": "^0.8.0",
|
||||||
"offline-plugin": "^5.0.7",
|
"offline-plugin": "^5.0.7",
|
||||||
"postcss-loader": "^3.0.0",
|
"postcss-loader": "^3.0.0",
|
||||||
"react-hot-loader": "^4.12.13",
|
"react-hot-loader": "^4.12.14",
|
||||||
"sass": "^1.22.12",
|
"sass": "^1.22.12",
|
||||||
"sass-loader": "^8.0.0",
|
"sass-loader": "^8.0.0",
|
||||||
"style-loader": "^1.0.0",
|
"style-loader": "^1.0.0",
|
||||||
"stylelint": "^10.1.0",
|
"stylelint": "^11.0.0",
|
||||||
"stylelint-config-standard": "^18.3.0",
|
"stylelint-config-standard": "^19.0.0",
|
||||||
"stylelint-webpack-plugin": "^0.10.5",
|
"stylelint-webpack-plugin": "^0.10.5",
|
||||||
"terser-webpack-plugin": "^2.0.1",
|
"terser-webpack-plugin": "^2.1.2",
|
||||||
"tslint": "^5.20.0",
|
"tslint": "^5.20.0",
|
||||||
"tslint-config-standard": "^8.0.1",
|
"tslint-config-standard": "^8.0.1",
|
||||||
"tslint-loader": "^3.6.0",
|
"tslint-loader": "^3.6.0",
|
||||||
"typescript": "^3.6.3",
|
"typescript": "^3.6.3",
|
||||||
"webpack": "^4.40.1",
|
"webpack": "^4.41.0",
|
||||||
"webpack-cli": "^3.3.8",
|
"webpack-cli": "^3.3.9",
|
||||||
"webpack-dev-middleware": "^3.7.1",
|
"webpack-dev-middleware": "^3.7.2",
|
||||||
"webpack-dev-server": "^3.8.0",
|
"webpack-dev-server": "^3.8.1",
|
||||||
"webpack-merge": "^4.2.2",
|
"webpack-merge": "^4.2.2",
|
||||||
"webpack-pwa-manifest": "^4.0.0"
|
"webpack-pwa-manifest": "^4.0.0"
|
||||||
},
|
},
|
||||||
@ -78,12 +78,12 @@
|
|||||||
"eventemitter3": "^4.0.0",
|
"eventemitter3": "^4.0.0",
|
||||||
"immer": "^4.0.0",
|
"immer": "^4.0.0",
|
||||||
"lodash-es": "^4.17.15",
|
"lodash-es": "^4.17.15",
|
||||||
"react": "^16.9.0",
|
"react": "^16.10.1",
|
||||||
"react-dom": "^16.9.0",
|
"react-dom": "^16.10.1",
|
||||||
"react-router-dom": "^5.0.1",
|
"react-router-dom": "^5.1.1",
|
||||||
"react-virtualized-auto-sizer": "^1.0.2",
|
"react-virtualized-auto-sizer": "^1.0.2",
|
||||||
"react-window": "^1.8.5",
|
"react-window": "^1.8.5",
|
||||||
"unstated-next": "^1.1.0",
|
"unstated-next": "^1.1.0",
|
||||||
"use-immer": "^0.3.3"
|
"use-immer": "^0.3.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ export default function ExternalController () {
|
|||||||
const { t } = useTranslation('Settings')
|
const { t } = useTranslation('Settings')
|
||||||
const { data: info, update, fetch } = containers.useAPIInfo()
|
const { data: info, update, fetch } = containers.useAPIInfo()
|
||||||
const { unauthorized: { hidden, visible } } = containers.useData()
|
const { unauthorized: { hidden, visible } } = containers.useData()
|
||||||
const { value, setMulti, setSingle } = useObject({
|
const [value, set] = useObject({
|
||||||
hostname: '',
|
hostname: '',
|
||||||
port: '',
|
port: '',
|
||||||
secret: ''
|
secret: ''
|
||||||
@ -20,7 +20,7 @@ export default function ExternalController () {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMulti({ hostname: info.hostname, port: info.port, secret: info.secret })
|
set({ hostname: info.hostname, port: info.port, secret: info.secret })
|
||||||
}, [info])
|
}, [info])
|
||||||
|
|
||||||
function handleOk () {
|
function handleOk () {
|
||||||
@ -46,7 +46,7 @@ export default function ExternalController () {
|
|||||||
align="left"
|
align="left"
|
||||||
inside={true}
|
inside={true}
|
||||||
value={value.hostname}
|
value={value.hostname}
|
||||||
onChange={hostname => setSingle('hostname', hostname)}
|
onChange={hostname => set('hostname', hostname)}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
@ -57,7 +57,7 @@ export default function ExternalController () {
|
|||||||
align="left"
|
align="left"
|
||||||
inside={true}
|
inside={true}
|
||||||
value={value.port}
|
value={value.port}
|
||||||
onChange={port => setSingle('port', port)}
|
onChange={port => set('port', port)}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
@ -68,7 +68,7 @@ export default function ExternalController () {
|
|||||||
align="left"
|
align="left"
|
||||||
inside={true}
|
inside={true}
|
||||||
value={value.secret}
|
value={value.secret}
|
||||||
onChange={secret => setSingle('secret', secret)}
|
onChange={secret => set('secret', secret)}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -15,7 +15,7 @@ export default function Settings () {
|
|||||||
const { data: apiInfo } = containers.useAPIInfo()
|
const { data: apiInfo } = containers.useAPIInfo()
|
||||||
const { useTranslation, setLang, lang } = containers.useI18n()
|
const { useTranslation, setLang, lang } = containers.useI18n()
|
||||||
const { t } = useTranslation('Settings')
|
const { t } = useTranslation('Settings')
|
||||||
const { value: info, setSingle } = useObject({
|
const [info, set] = useObject({
|
||||||
socks5ProxyPort: 7891,
|
socks5ProxyPort: 7891,
|
||||||
httpProxyPort: 7890,
|
httpProxyPort: 7890,
|
||||||
isClashX: false
|
isClashX: false
|
||||||
@ -24,13 +24,13 @@ export default function Settings () {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch()
|
fetch()
|
||||||
if (isClashX()) {
|
if (isClashX()) {
|
||||||
fetchClashXData().then(() => setSingle('isClashX', true))
|
fetchClashXData().then(() => set('isClashX', true))
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSingle('socks5ProxyPort', data.general.socksPort)
|
set('socks5ProxyPort', data.general.socksPort)
|
||||||
setSingle('httpProxyPort', data.general.port)
|
set('httpProxyPort', data.general.port)
|
||||||
}, [data])
|
}, [data])
|
||||||
|
|
||||||
async function handleProxyModeChange (mode: string) {
|
async function handleProxyModeChange (mode: string) {
|
||||||
@ -58,7 +58,7 @@ export default function Settings () {
|
|||||||
const [, err] = await to(updateConfig({ 'port': info.httpProxyPort }))
|
const [, err] = await to(updateConfig({ 'port': info.httpProxyPort }))
|
||||||
if (!err) {
|
if (!err) {
|
||||||
await fetch()
|
await fetch()
|
||||||
setSingle('httpProxyPort', data.general.port)
|
set('httpProxyPort', data.general.port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ export default function Settings () {
|
|||||||
const [, err] = await to(updateConfig({ 'socks-port': info.socks5ProxyPort }))
|
const [, err] = await to(updateConfig({ 'socks-port': info.socks5ProxyPort }))
|
||||||
if (!err) {
|
if (!err) {
|
||||||
await fetch()
|
await fetch()
|
||||||
setSingle('socks5ProxyPort', data.general.socksPort)
|
set('socks5ProxyPort', data.general.socksPort)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ export default function Settings () {
|
|||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<Input
|
<Input
|
||||||
value={info.socks5ProxyPort}
|
value={info.socks5ProxyPort}
|
||||||
onChange={socks5ProxyPort => setSingle('socks5ProxyPort', parseInt(socks5ProxyPort, 10))}
|
onChange={socks5ProxyPort => set('socks5ProxyPort', parseInt(socks5ProxyPort, 10))}
|
||||||
onBlur={handleSocksPortSave}
|
onBlur={handleSocksPortSave}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
@ -178,7 +178,7 @@ export default function Settings () {
|
|||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
<Input
|
<Input
|
||||||
value={info.httpProxyPort}
|
value={info.httpProxyPort}
|
||||||
onChange={httpProxyPort => setSingle('httpProxyPort', parseInt(httpProxyPort, 10))}
|
onChange={httpProxyPort => set('httpProxyPort', parseInt(httpProxyPort, 10))}
|
||||||
onBlur={handleHttpPortSave}
|
onBlur={handleHttpPortSave}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -3,43 +3,50 @@ import { useImmer } from 'use-immer'
|
|||||||
import { createContainer } from 'unstated-next'
|
import { createContainer } from 'unstated-next'
|
||||||
|
|
||||||
export function useObject<T extends object> (initialValue: T) {
|
export function useObject<T extends object> (initialValue: T) {
|
||||||
let [copy, set] = useImmer(initialValue)
|
const [copy, rawSet] = useImmer(initialValue)
|
||||||
|
|
||||||
function setSingle<K extends keyof Draft<T>> (key: K, value: Draft<T>[K]) {
|
function set<K extends keyof Draft<T>> (key: K, value: Draft<T>[K]): void
|
||||||
set(draft => {
|
function set<K extends keyof Draft<T>> (data: Partial<T>): void
|
||||||
draft[key] = value
|
function set<K extends keyof Draft<T>> (f: (draft: Draft<T>) => void | T): void
|
||||||
})
|
function set<K extends keyof Draft<T>> (data: any, value?: Draft<T>[K]): void {
|
||||||
|
if (typeof data === 'string') {
|
||||||
|
rawSet(draft => {
|
||||||
|
const key = data as K
|
||||||
|
const v = value
|
||||||
|
draft[key] = v
|
||||||
|
})
|
||||||
|
} else if (typeof data === 'function') {
|
||||||
|
rawSet(data)
|
||||||
|
} else if (typeof data === 'object') {
|
||||||
|
rawSet((draft: Draft<T>) => {
|
||||||
|
const obj = data as Draft<T>
|
||||||
|
for (const key of Object.keys(obj)) {
|
||||||
|
const k = key as keyof Draft<T>
|
||||||
|
draft[k] = obj[k]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setMulti<K extends keyof Draft<T>, U extends keyof T> (newValue: Partial<T>) {
|
return [copy, set] as [T, typeof set]
|
||||||
set((draft: Draft<T>) => {
|
|
||||||
for (const key of Object.keys(newValue)) {
|
|
||||||
draft[key as K] = newValue[key as U] as any
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return { value: copy, setSingle, setMulti, set }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type containerFn<Value, State = void> = (initialState?: State) => Value
|
type containerFn<Value, State = void> = (initialState?: State) => Value
|
||||||
|
|
||||||
export function composeContainer<T, C = containerFn<T>, U = { [key: string]: C }> (mapping: U) {
|
export function composeContainer<T, C extends containerFn<T>, U extends { [key: string]: C }, K extends keyof U> (mapping: U) {
|
||||||
function Global () {
|
function Global () {
|
||||||
return Object.keys(mapping).reduce((obj, key) => {
|
return Object.keys(mapping).reduce((obj, key) => {
|
||||||
obj[key] = mapping[key]()
|
obj[key as K] = mapping[key]()
|
||||||
return obj
|
return obj
|
||||||
}, {}) as { [K in keyof U]: T }
|
}, {} as { [K in keyof U]: T })
|
||||||
}
|
}
|
||||||
|
|
||||||
const allContainer = createContainer(Global)
|
const allContainer = createContainer(Global)
|
||||||
return {
|
return {
|
||||||
Provider: allContainer.Provider,
|
Provider: allContainer.Provider,
|
||||||
containers: Object.keys(mapping).reduce((obj, key) => {
|
containers: Object.keys(mapping).reduce((obj, key) => {
|
||||||
obj[key] = function () {
|
obj[key as K] = (() => allContainer.useContainer()[key]) as U[K]
|
||||||
return allContainer.useContainer()[key]
|
|
||||||
}
|
|
||||||
return obj
|
return obj
|
||||||
}, {}) as { [K in keyof U]: U[K] }
|
}, {} as { [K in keyof U]: U[K] })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import { setLocalStorageItem, partition, to } from '@lib/helper'
|
|||||||
import { useI18n } from '@i18n'
|
import { useI18n } from '@i18n'
|
||||||
|
|
||||||
function useData () {
|
function useData () {
|
||||||
const { value: data, setSingle, setMulti, set } = useObject<Models.Data>({
|
const [data, set] = useObject<Models.Data>({
|
||||||
general: {},
|
general: {},
|
||||||
proxy: [],
|
proxy: [],
|
||||||
proxyGroup: [],
|
proxyGroup: [],
|
||||||
@ -32,7 +32,7 @@ function useData () {
|
|||||||
|
|
||||||
const [{ data: general }, rawProxies, rules] = resp
|
const [{ data: general }, rawProxies, rules] = resp
|
||||||
|
|
||||||
setSingle('general', {
|
set('general', {
|
||||||
port: general.port,
|
port: general.port,
|
||||||
socksPort: general['socks-port'],
|
socksPort: general['socks-port'],
|
||||||
redirPort: general['redir-port'],
|
redirPort: general['redir-port'],
|
||||||
@ -51,7 +51,7 @@ function useData () {
|
|||||||
.map(key => ({ ...rawProxies.data.proxies[key], name: key }))
|
.map(key => ({ ...rawProxies.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))
|
||||||
|
|
||||||
setMulti({
|
set({
|
||||||
proxy: proxy as API.Proxy[],
|
proxy: proxy as API.Proxy[],
|
||||||
proxyGroup: general.mode === 'Global' ? [proxyList] : groups as API.Group[],
|
proxyGroup: general.mode === 'Global' ? [proxyList] : groups as API.Group[],
|
||||||
rules: rules.data.rules
|
rules: rules.data.rules
|
||||||
@ -71,7 +71,7 @@ function useData () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function useAPIInfo () {
|
function useAPIInfo () {
|
||||||
const { value: data, setMulti } = useObject<Models.APIInfo>({
|
const [data, set] = useObject<Models.APIInfo>({
|
||||||
hostname: '127.0.0.1',
|
hostname: '127.0.0.1',
|
||||||
port: '9090',
|
port: '9090',
|
||||||
secret: ''
|
secret: ''
|
||||||
@ -79,7 +79,7 @@ function useAPIInfo () {
|
|||||||
|
|
||||||
async function fetch () {
|
async function fetch () {
|
||||||
const info = await API.getExternalControllerConfig()
|
const info = await API.getExternalControllerConfig()
|
||||||
setMulti({ ...info })
|
set({ ...info })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function update (info: Models.APIInfo) {
|
async function update (info: Models.APIInfo) {
|
||||||
@ -94,7 +94,7 @@ function useAPIInfo () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function useClashXData () {
|
function useClashXData () {
|
||||||
const { value: data, setMulti } = useObject<Models.ClashXData>({
|
const [data, set] = useObject<Models.ClashXData>({
|
||||||
startAtLogin: false,
|
startAtLogin: false,
|
||||||
systemProxy: false
|
systemProxy: false
|
||||||
})
|
})
|
||||||
@ -103,7 +103,7 @@ function useClashXData () {
|
|||||||
const startAtLogin = await jsBridge.getStartAtLogin()
|
const startAtLogin = await jsBridge.getStartAtLogin()
|
||||||
const systemProxy = await jsBridge.isSystemProxySet()
|
const systemProxy = await jsBridge.isSystemProxySet()
|
||||||
|
|
||||||
setMulti({ startAtLogin, systemProxy })
|
set({ startAtLogin, systemProxy })
|
||||||
}
|
}
|
||||||
|
|
||||||
return { data, fetch }
|
return { data, fetch }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user