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 ? (
) : null
)}
Mode
Log Level
{t('lang')}
Action
}
label="Switch backend"
onClick={openAPIConfigModal}
/>
);
}