2019-07-03 22:59:14 +08:00

208 lines
8.0 KiB
TypeScript

import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import i18next from 'i18next'
import { Header, Card, Row, Col, Switch, ButtonSelect, ButtonSelectOptions, Input, Icon } from '@components'
import { APIInfo, Data, ClashXData } from '@stores'
import { updateConfig } from '@lib/request'
import { useObject } from '@lib/hook'
import { to } from '@lib/helper'
import { isClashX, jsBridge } from '@lib/jsBridge'
import './style.scss'
const languageOptions: ButtonSelectOptions[] = [{ label: '中文', value: 'zh' }, { label: 'English', value: 'en' }]
function changeLanguage (language: string) {
i18next.changeLanguage(language)
}
async function handleStartAtLoginChange (state: boolean) {
await jsBridge.setStartAtLogin(state)
}
async function handleSetSystemProxy (state: boolean) {
await jsBridge.setSystemProxy(state)
}
export default function Settings () {
const { data: clashXData, fetch: fetchClashXData } = ClashXData.useContainer()
const { data, fetch, unauthorized: { show } } = Data.useContainer()
const { data: apiInfo } = APIInfo.useContainer()
const { t, i18n } = useTranslation(['Settings'])
const { value: info, change } = useObject({
socks5ProxyPort: 7891,
httpProxyPort: 7890,
isClashX: false
})
useEffect(() => {
fetch()
if (isClashX()) {
fetchClashXData().then(() => change('isClashX', true))
}
}, [])
useEffect(() => {
change('socks5ProxyPort', data.general.socksPort)
change('httpProxyPort', data.general.port)
}, [data])
async function handleProxyModeChange (mode: string) {
const [, err] = await to(updateConfig({ mode }))
if (!err) {
fetch()
}
}
async function handleHttpPortSave () {
const [, err] = await to(updateConfig({ 'port': info.httpProxyPort }))
if (!err) {
await fetch()
change('httpProxyPort', data.general.port)
}
}
async function handleSocksPortSave () {
const [, err] = await to(updateConfig({ 'socks-port': info.socks5ProxyPort }))
if (!err) {
await fetch()
change('socks5ProxyPort', data.general.socksPort)
}
}
async function handleAllowLanChange (state: boolean) {
const [, err] = await to(updateConfig({ 'allow-lan': state }))
if (!err) {
await fetch()
}
}
const {
hostname: externalControllerHost,
port: externalControllerPort
} = apiInfo
const { allowLan, mode } = data.general
const {
startAtLogin,
systemProxy
} = clashXData
const proxyModeOptions: ButtonSelectOptions[] = [
{ label: t('values.global'), value: 'Global' },
{ label: t('values.rules'), value: 'Rule' },
{ label: t('values.direct'), value: 'Direct' }
]
return (
<div className="page">
<Header title={t('title')} />
<Card className="settings-card">
<Row gutter={24} align="middle">
<Col span={12}>
<Col span={14} offset={1}>
<span className="label">{t('labels.startAtLogin')}</span>
</Col>
<Col span={8} className="value-column">
<Switch disabled={!isClashX} checked={startAtLogin} onChange={handleStartAtLoginChange} />
</Col>
</Col>
<Col span={12}>
<Col span={8} offset={1}>
<span className="label">{t('labels.language')}</span>
</Col>
<Col span={14} className="value-column">
<ButtonSelect options={languageOptions} value={i18n.language.replace(/-.+$/, '')} onSelect={changeLanguage} />
</Col>
</Col>
</Row>
<Row gutter={24} align="middle">
<Col span={12}>
<Col span={14} offset={1}>
<span className="label">{t('labels.setAsSystemProxy')}</span>
</Col>
<Col span={8} className="value-column">
<Switch
disabled={!isClashX}
checked={systemProxy}
onChange={handleSetSystemProxy}
/>
</Col>
</Col>
<Col span={12}>
<Col span={14} offset={1}>
<span className="label">{t('labels.allowConnectFromLan')}</span>
</Col>
<Col span={8} className="value-column">
<Switch
checked={allowLan}
onChange={handleAllowLanChange}
/>
</Col>
</Col>
</Row>
</Card>
<Card className="settings-card">
<Row gutter={24} align="middle">
<Col span={12}>
<Col span={8} offset={1}>
<span className="label">{t('labels.proxyMode')}</span>
</Col>
<Col span={14} className="value-column">
<ButtonSelect
options={proxyModeOptions}
value={mode}
onSelect={handleProxyModeChange}
/>
</Col>
</Col>
<Col span={12}>
<Col span={14} offset={1}>
<span className="label">{t('labels.socks5ProxyPort')}</span>
</Col>
<Col span={8}>
<Input
value={info.socks5ProxyPort}
onChange={socks5ProxyPort => change('socks5ProxyPort', parseInt(socks5ProxyPort, 10))}
onBlur={handleSocksPortSave}
/>
</Col>
</Col>
</Row>
<Row gutter={24} align="middle">
<Col span={12}>
<Col span={14} offset={1}>
<span className="label">{t('labels.httpProxyPort')}</span>
</Col>
<Col span={8}>
<Input
value={info.httpProxyPort}
onChange={httpProxyPort => change('httpProxyPort', parseInt(httpProxyPort, 10))}
onBlur={handleHttpPortSave}
/>
</Col>
</Col>
<Col span={12}>
<Col span={12} offset={1}>
<span className="label">{t('labels.externalController')}</span>
</Col>
<Col className="external-controller" span={10}>
<span className="modify-btn" onClick={show}>
{`${externalControllerHost}:${externalControllerPort}`}
</span>
</Col>
</Col>
</Row>
</Card>
<Card className="clash-version" style={{ display: 'none' }}>
<span className="check-icon">
<Icon type="check" size={20} />
</span>
<p className="version-info">{t('versionString', { version: 'unknown' })}</p>
<span className="check-update-btn">{t('checkUpdate')}</span>
</Card>
</div>
)
}