diff --git a/src/components/setting/guard-state.tsx b/src/components/setting/guard-state.tsx index b2cff75..9b15aa9 100644 --- a/src/components/setting/guard-state.tsx +++ b/src/components/setting/guard-state.tsx @@ -7,7 +7,7 @@ interface Props { onChangeProps?: string; onChange?: (value: Value) => void; onFormat?: (...args: any[]) => Value; - onGuard?: (value: Value) => Promise; + onGuard?: (value: Value, oldValue: Value) => Promise; onCatch?: (error: Error) => void; children: ReactNode; } @@ -41,7 +41,7 @@ function GuardState(props: Props) { const newValue = (onFormat as any)(...args); // 先在ui上响应操作 onChange(newValue); - await onGuard(newValue); + await onGuard(newValue, oldValue!); } catch (err: any) { // 状态回退 onChange(oldValue!); diff --git a/src/components/setting/setting-clash.tsx b/src/components/setting/setting-clash.tsx index 766d3e3..eee2e11 100644 --- a/src/components/setting/setting-clash.tsx +++ b/src/components/setting/setting-clash.tsx @@ -1,3 +1,6 @@ +import { useEffect, useState } from "react"; +import { useDebounceFn } from "ahooks"; +import { useSetRecoilState } from "recoil"; import useSWR, { useSWRConfig } from "swr"; import { ListItemText, @@ -9,11 +12,13 @@ import { import { getClashConfig, updateConfigs } from "../../services/api"; import { SettingList, SettingItem } from "./setting"; import { patchClashConfig } from "../../services/cmds"; +import { atomClashPort } from "../../states/setting"; import { ApiType } from "../../services/types"; import GuardState from "./guard-state"; +import Notice from "../notice"; interface Props { - onError?: (err: Error) => void; + onError: (err: Error) => void; } const SettingClash = ({ onError }: Props) => { @@ -24,9 +29,14 @@ const SettingClash = ({ onError }: Props) => { ipv6 = false, "allow-lan": allowLan = false, "log-level": logLevel = "silent", - "mixed-port": mixedPort = 7890, + "mixed-port": thePort = 0, } = clashConfig ?? {}; + const setPort = useSetRecoilState(atomClashPort); + const [mixedPort, setMixedPort] = useState(thePort); + + useEffect(() => setMixedPort(thePort), [thePort]); + const onSwitchFormat = (_e: any, value: boolean) => value; const onChangeData = (patch: Partial) => { mutate("getClashConfig", { ...clashConfig, ...patch }, false); @@ -36,6 +46,28 @@ const SettingClash = ({ onError }: Props) => { await patchClashConfig(patch); }; + // restart clash when port is changed + const { run: onUpdatePort } = useDebounceFn( + async (port: number) => { + (async () => { + if (port < 1000) { + throw new Error("The port should not < 1000"); + } + if (port > 65536) { + throw new Error("The port should not > 65536"); + } + await patchClashConfig({ "mixed-port": port }); + onChangeData({ "mixed-port": port }); + setPort(port); + Notice.success("Change Clash port successfully!"); + })().catch((err: any) => { + setMixedPort(thePort); // back to old port value + Notice.error(err.message ?? err.toString()); + }); + }, + { wait: 1000 } + ); + return ( @@ -87,12 +119,14 @@ const SettingClash = ({ onError }: Props) => { - + onFormat={(e: any) => +e.target.value?.replace(/\D+/, "")} + onChange={setMixedPort} + onGuard={onUpdatePort} + > + + ); diff --git a/src/components/traffic.tsx b/src/components/traffic.tsx index e0e7d91..52d5f61 100644 --- a/src/components/traffic.tsx +++ b/src/components/traffic.tsx @@ -1,11 +1,14 @@ import { useEffect, useState } from "react"; +import { useRecoilValue } from "recoil"; import { Box, Typography } from "@mui/material"; import { ArrowDownward, ArrowUpward } from "@mui/icons-material"; import { getInfomation } from "../services/api"; import { ApiType } from "../services/types"; +import { atomClashPort } from "../states/setting"; import parseTraffic from "../utils/parse-traffic"; const Traffic = () => { + const portValue = useRecoilValue(atomClashPort); const [traffic, setTraffic] = useState({ up: 0, down: 0 }); useEffect(() => { @@ -21,7 +24,7 @@ const Traffic = () => { }); return () => ws?.close(); - }, []); + }, [portValue]); const [up, upUnit] = parseTraffic(traffic.up); const [down, downUnit] = parseTraffic(traffic.down); diff --git a/src/states/setting.ts b/src/states/setting.ts index e425e6e..65095e5 100644 --- a/src/states/setting.ts +++ b/src/states/setting.ts @@ -9,3 +9,8 @@ export const atomThemeBlur = atom({ key: "atomThemeBlur", default: false, }); + +export const atomClashPort = atom({ + key: "atomClashPort", + default: 0, +});