import React from 'react'; import PropTypes from 'prop-types'; import { connect, useStoreActions } from './StateProvider'; import { getConfigs, fetchConfigs, updateConfigs } from '../store/configs'; import { getClashAPIConfig, getSelectedChartStyleIndex, getLatencyTestUrl, clearStorage, } from '../store/app'; import ContentHeader from './ContentHeader'; import Switch from './SwitchThemed'; import ToggleSwitch from './ToggleSwitch'; import Input, { SelfControlledInput } from './Input'; import Button from './Button'; import Selection from './Selection'; import TrafficChartSample from './TrafficChartSample'; import s0 from './Config.module.css'; const { useEffect, useState, useCallback, useRef } = React; const propsList = [{ id: 0 }, { id: 1 }, { id: 2 }, { id: 3 }]; const optionsRule = [ { label: 'Global', value: 'Global', }, { label: 'Rule', value: 'Rule', }, { label: 'Direct', value: 'Direct', }, ]; const optionsLogLevel = [ { label: 'info', value: 'info', }, { label: 'warning', value: 'warning', }, { label: 'error', value: 'error', }, { label: 'debug', value: 'debug', }, { label: 'silent', value: 'silent', }, ]; const mapState = (s) => ({ configs: getConfigs(s), apiConfig: getClashAPIConfig(s), }); const mapState2 = (s) => ({ 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 ; } function ConfigImpl({ dispatch, configs, selectedChartStyleIndex, latencyTestUrl, apiConfig, }) { const [configState, setConfigStateInternal] = useState(configs); const refConfigs = useRef(configs); useEffect(() => { if (refConfigs.current !== configs) { setConfigStateInternal(configs); } refConfigs.current = configs; }, [configs]); const setConfigState = useCallback( (name, val) => { setConfigStateInternal({ ...configState, [name]: val, }); }, [configState] ); const handleSwitchOnChange = useCallback( (checked) => { const name = 'allow-lan'; const value = checked; setConfigState(name, value); dispatch(updateConfigs(apiConfig, { [name]: value })); }, [apiConfig, dispatch, setConfigState] ); const handleInputOnChange = useCallback( (e) => { const target = e.target; const { name } = target; const { value } = target; switch (target.name) { case 'mode': case 'log-level': setConfigState(name, value); dispatch(updateConfigs(apiConfig, { [name]: value })); break; case 'redir-port': case 'socks-port': case 'port': if (target.value !== '') { const num = parseInt(target.value, 10); if (num < 0 || num > 65535) return; } setConfigState(name, value); break; default: return; } }, [apiConfig, dispatch, setConfigState] ); const { selectChartStyleIndex, updateAppConfig } = useStoreActions(); const handleInputOnBlur = useCallback( (e) => { const target = e.target; const { name, value } = target; switch (name) { case 'port': case 'socks-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] ); return (
HTTP Proxy Port
SOCKS5 Proxy Port
Redir Port
Allow LAN
Mode
Log Level
Chart Style
Latency Test URL
Action
); } Config.propTypes = { configs: PropTypes.object, };