summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/configs.ts6
-rw-r--r--src/components/Config.tsx100
-rw-r--r--src/store/configs.ts28
-rw-r--r--src/store/types.ts16
4 files changed, 109 insertions, 41 deletions
diff --git a/src/api/configs.ts b/src/api/configs.ts
index e084261..ed2b1e9 100644
--- a/src/api/configs.ts
+++ b/src/api/configs.ts
@@ -1,5 +1,5 @@
import { getURLAndInit } from 'src/misc/request-helper';
-import { ClashGeneralConfig } from 'src/store/types';
+import { ClashGeneralConfig, TunPartial } from 'src/store/types';
import { ClashAPIConfig } from 'src/types';
const endpoint = '/configs';
@@ -14,7 +14,7 @@ export async function fetchConfigs(apiConfig: ClashAPIConfig) {
// req body
// { Path: string }
-type ClashConfigPartial = Partial<ClashGeneralConfig>;
+type ClashConfigPartial = TunPartial<ClashGeneralConfig>;
function configsPatchWorkaround(o: ClashConfigPartial) {
// backward compatibility for older clash using `socket-port`
if ('socks-port' in o) {
@@ -32,7 +32,7 @@ export async function updateConfigs(
return await fetch(url + endpoint, { ...init, body, method: 'PATCH' });
}
-export async function reloadConfigs(
+export async function reloadConfigFile(
apiConfig: ClashAPIConfig
) {
const { url, init } = getURLAndInit(apiConfig);
diff --git a/src/components/Config.tsx b/src/components/Config.tsx
index 3d9e36e..808ffd9 100644
--- a/src/components/Config.tsx
+++ b/src/components/Config.tsx
@@ -11,7 +11,13 @@ import {
getLatencyTestUrl,
getSelectedChartStyleIndex,
} from '../store/app';
-import { fetchConfigs, getConfigs, updateConfigs, reloadConfigs, flushFakeIPPool } from '../store/configs';
+import {
+ fetchConfigs,
+ flushFakeIPPool,
+ getConfigs,
+ reloadConfigFile,
+ updateConfigs,
+} from '../store/configs';
import { openModal } from '../store/modals';
import Button from './Button';
import s0 from './Config.module.scss';
@@ -40,7 +46,7 @@ const portFields = [
{ key: 'socks-port', label: 'SOCKS5 Proxy Port' },
{ key: 'mixed-port', label: 'Mixed Port' },
{ key: 'redir-port', label: 'Redir Port' },
- { key: 'tproxy-port', label: 'tProxy Port' },
+ { key: 'tproxy-port', label: 'TProxy Port' },
{ key: 'mitm-port', label: 'MITM Port' },
];
@@ -50,10 +56,15 @@ const langOptions = [
];
const modeOptions = [
- ['Global', 'Global'],
- ['Rule', 'Rule'],
- ['Script', 'Script'],
- ['Direct', 'Direct'],
+ ['rule', 'Rule'],
+ ['script', 'Script'],
+ ['direct', 'Direct'],
+ ['global', 'Global'],
+];
+
+const tunStackOptions = [
+ ['gVisor', 'gVisor'],
+ ['System', 'System'],
];
const mapState = (s: State) => ({
@@ -112,6 +123,14 @@ function ConfigImpl({
[configState]
);
+ const setTunConfigState = useCallback(
+ (name, val) => {
+ const tun = {...configState.tun, [name]: val }
+ setConfigStateInternal({ ...configState, tun: {...tun}});
+ },
+ [configState]
+ );
+
const handleSwitchOnChange = useCallback(
(checked: boolean) => {
const name = 'allow-lan';
@@ -145,11 +164,15 @@ function ConfigImpl({
}
setConfigState(name, value);
break;
+ case 'stack':
+ setTunConfigState(name, value);
+ dispatch(updateConfigs(apiConfig, { 'tun': {[name]: value }}));
+ break;
default:
return;
}
},
- [apiConfig, dispatch, setConfigState]
+ [apiConfig, dispatch, setConfigState, setTunConfigState]
);
const handleInputOnChange = useCallback(
@@ -186,8 +209,8 @@ function ConfigImpl({
[apiConfig, dispatch, updateAppConfig]
);
- const handleReloadConfigs = useCallback(() => {
- dispatch(reloadConfigs(apiConfig));
+ const handleReloadConfigFile = useCallback(() => {
+ dispatch(reloadConfigFile(apiConfig));
},[apiConfig, dispatch]);
const handleFlushFakeIPPool = useCallback(() => {
@@ -243,6 +266,17 @@ function ConfigImpl({
</div>
<div>
+ <div className={s0.label}>TUN Stack</div>
+ <Select
+ options={tunStackOptions}
+ selected={configState['tun']['stack']}
+ onChange={(e) =>
+ handleChangeValue({ name: 'stack', value: e.target.value })
+ }
+ />
+ </div>
+
+ <div>
<div className={s0.label}>Allow LAN</div>
<div className={s0.wrapSwitch}>
<Switch
@@ -260,6 +294,30 @@ function ConfigImpl({
<div className={s0.section}>
<div>
+ <div className={s0.label}>Reload</div>
+ <Button
+ start={<RotateCw size={16} />}
+ label={t('reload_config_file')}
+ onClick={handleReloadConfigFile}
+ />
+ </div>
+
+ <div>
+ <div className={s0.label}>FakeIP</div>
+ <Button
+ start={<Trash2 size={16} />}
+ label={t('flush_fake_ip_pool')}
+ onClick={handleFlushFakeIPPool}
+ />
+ </div>
+ </div>
+
+ <div className={s0.sep}>
+ <div />
+ </div>
+
+ <div className={s0.section}>
+ <div>
<div className={s0.label}>{t('latency_test_url')}</div>
<SelfControlledInput
name="latencyTestUrl"
@@ -298,30 +356,6 @@ function ConfigImpl({
/>
</div>
</div>
-
- <div className={s0.sep}>
- <div />
- </div>
-
- <div className={s0.section}>
- <div>
- <div className={s0.label}>Reload</div>
- <Button
- start={<RotateCw size={16} />}
- label={t('reload_config_file')}
- onClick={handleReloadConfigs}
- />
- </div>
-
- <div>
- <div className={s0.label}>FakeIP</div>
- <Button
- start={<Trash2 size={16} />}
- label={t('flush_fake_ip_pool')}
- onClick={handleFlushFakeIPPool}
- />
- </div>
- </div>
</div>
);
}
diff --git a/src/store/configs.ts b/src/store/configs.ts
index b0ae2a7..c4b95de 100644
--- a/src/store/configs.ts
+++ b/src/store/configs.ts
@@ -4,6 +4,7 @@ import {
GetStateFn,
State,
StateConfigs,
+ TunPartial,
} from 'src/store/types';
import { ClashAPIConfig } from 'src/types';
@@ -59,9 +60,11 @@ function markHaveFetchedConfig() {
};
}
+type generalConfig = Omit<ClashGeneralConfig, 'tun'>
+
export function updateConfigs(
apiConfig: ClashAPIConfig,
- partialConfg: Partial<ClashGeneralConfig>
+ partialConfg: TunPartial<ClashGeneralConfig>
) {
return async (dispatch: DispatchFn) => {
configsAPI
@@ -84,15 +87,20 @@ export function updateConfigs(
});
dispatch('storeConfigsOptimisticUpdateConfigs', (s) => {
- s.configs.configs = { ...s.configs.configs, ...partialConfg };
+ if (partialConfg.tun != null) {
+ s.configs.configs.tun = { ...s.configs.configs.tun, ...partialConfg.tun };
+ } else {
+ const config: generalConfig = {...s.configs.configs, ...partialConfg};
+ s.configs.configs = config
+ }
});
};
}
-export function reloadConfigs(apiConfig: ClashAPIConfig) {
+export function reloadConfigFile(apiConfig: ClashAPIConfig) {
return async (dispatch: DispatchFn) => {
configsAPI
- .reloadConfigs(apiConfig)
+ .reloadConfigFile(apiConfig)
.then(
(res) => {
if (res.ok === false) {
@@ -139,10 +147,20 @@ export const initialState: StateConfigs = {
configs: {
port: 7890,
'socks-port': 7891,
+ 'mixed-port': 0,
'redir-port': 0,
+ 'tproxy-port': 0,
+ 'mitm-port': 0,
'allow-lan': false,
- mode: 'Rule',
+ mode: 'rule',
'log-level': 'uninit',
+ tun: {
+ enable: false,
+ device: '',
+ stack: '',
+ 'dns-hijack': [],
+ 'auto-route': false,
+ },
},
haveFetchedConfig: false,
};
diff --git a/src/store/types.ts b/src/store/types.ts
index b9141ac..16402ae 100644
--- a/src/store/types.ts
+++ b/src/store/types.ts
@@ -16,15 +16,31 @@ export type StateApp = {
logStreamingPaused: boolean;
};
+export type ClashTunConfig = {
+ enable: boolean;
+ device?: string;
+ stack: string;
+ 'dns-hijack': string[];
+ 'auto-route': boolean;
+}
+
export type ClashGeneralConfig = {
port: number;
'socks-port': number;
+ 'mixed-port': number;
'redir-port': number;
+ 'tproxy-port': number;
+ 'mitm-port'?: number;
'allow-lan': boolean;
mode: string;
'log-level': string;
+ tun?: ClashTunConfig;
};
+export type TunPartial<T> = {
+ [P in keyof T]?: T[P] extends ClashTunConfig ? TunPartial<T[P]> : T[P];
+}
+
///// store.proxies
type LatencyHistory = Array<{ time: string; delay: number }>;