import * as React from 'react'; import { LogOut } from 'react-feather'; import { useTranslation } from 'react-i18next'; import * as logsApi from 'src/api/logs'; import Select from 'src/components/shared/Select'; import { ClashGeneralConfig, DispatchFn, State } from 'src/store/types'; import { ClashAPIConfig } from 'src/types'; import { getClashAPIConfig, getLatencyTestUrl, getSelectedChartStyleIndex, } from '../store/app'; import { fetchConfigs, getConfigs, updateConfigs } from '../store/configs'; import { openModal } from '../store/modals'; import Button from './Button'; import s0 from './Config.module.scss'; import ContentHeader from './ContentHeader'; import Input, { SelfControlledInput } from './Input'; import { Selection2 } from './Selection'; import { connect, useStoreActions } from './StateProvider'; import Switch from './SwitchThemed'; import TrafficChartSample from './TrafficChartSample'; // import ToggleSwitch from './ToggleSwitch'; const { useEffect, useState, useCallback, useRef, useMemo } = React; const propsList = [{ id: 0 }, { id: 1 }, { id: 2 }, { id: 3 }]; const logLeveOptions = [ ['debug', 'Debug'], ['warning', 'Warning'], ['info', 'Info'], ['error', 'Error'], ['silent', 'Silent'], ]; const portFields = [ { key: 'port', label: 'HTTP Proxy Port' }, { key: 'socks-port', label: 'SOCKS5 Proxy Port' }, { key: 'mixed-port', label: 'Mixed Port' }, { key: 'redir-port', label: 'Redir Port' }, ]; const langOptions = [ ['zh', '中文'], ['en', 'English'], ]; const modeOptions = [ ['Global', 'Global'], ['Rule', 'Rule'], ['Direct', 'Direct'], ]; const mapState = (s: State) => ({ configs: getConfigs(s), apiConfig: getClashAPIConfig(s), }); const mapState2 = (s: State) => ({ selectedChartStyleIndex: getSelectedChartStyleIndex(s), latencyTestUrl: getLatencyTestUrl(s), apiConfig: getClashAPIConfig(s), }); const Config = connect(mapState2)(ConfigImpl); export default connect(mapState)(ConfigContainer); function ConfigContainer({ dispatch, configs, apiConfig }) { useEffect(() => { dispatch(fetchConfigs(apiConfig)); }, [dispatch, apiConfig]); return ; } type ConfigImplProps = { dispatch: DispatchFn; configs: ClashGeneralConfig; selectedChartStyleIndex: number; latencyTestUrl: string; apiConfig: ClashAPIConfig; }; function ConfigImpl({ dispatch, configs, selectedChartStyleIndex, latencyTestUrl, apiConfig, }: ConfigImplProps) { const [configState, setConfigStateInternal] = useState(configs); const refConfigs = useRef(configs); useEffect(() => { if (refConfigs.current !== configs) { setConfigStateInternal(configs); } refConfigs.current = configs; }, [configs]); const openAPIConfigModal = useCallback(() => { dispatch(openModal('apiConfig')); }, [dispatch]); const setConfigState = useCallback( (name, val) => { setConfigStateInternal({ ...configState, [name]: val }); }, [configState] ); const handleSwitchOnChange = useCallback( (checked: boolean) => { const name = 'allow-lan'; const value = checked; setConfigState(name, value); dispatch(updateConfigs(apiConfig, { 'allow-lan': value })); }, [apiConfig, dispatch, setConfigState] ); const handleChangeValue = useCallback( ({ name, value }) => { switch (name) { case 'mode': case 'log-level': setConfigState(name, value); dispatch(updateConfigs(apiConfig, { [name]: value })); if (name === 'log-level') { logsApi.reconnect({ ...apiConfig, logLevel: value }); } break; case 'redir-port': case 'socks-port': case 'mixed-port': case 'port': if (value !== '') { const num = parseInt(value, 10); if (num < 0 || num > 65535) return; } setConfigState(name, value); break; default: return; } }, [apiConfig, dispatch, setConfigState] ); const handleInputOnChange = useCallback( (e) => handleChangeValue(e.target), [handleChangeValue] ); const { selectChartStyleIndex, updateAppConfig } = useStoreActions(); const handleInputOnBlur = useCallback( (e) => { const target = e.target; const { name, value } = target; switch (name) { case 'port': case 'socks-port': case 'mixed-port': case 'redir-port': { const num = parseInt(value, 10); if (num < 0 || num > 65535) return; dispatch(updateConfigs(apiConfig, { [name]: num })); break; } case 'latencyTestUrl': { updateAppConfig(name, value); break; } default: throw new Error(`unknown input name ${name}`); } }, [apiConfig, dispatch, updateAppConfig] ); const mode = useMemo(() => { const m = configState.mode; return typeof m === 'string' && m[0].toUpperCase() + m.slice(1); }, [configState.mode]); const { t, i18n } = useTranslation(); return (
{portFields.map((f) => configState[f.key] !== undefined ? (
{f.label}
) : null )}
Mode
handleChangeValue({ name: 'log-level', value: e.target.value }) } />
Allow LAN
{t('latency_test_url')}
{t('lang')}