From ff2c1bf8ed23405e0a97098024311efd91a744cc Mon Sep 17 00:00:00 2001 From: GyDi Date: Mon, 5 Sep 2022 02:12:25 +0800 Subject: [PATCH] feat: change clash port in dialog --- .../setting/mods/clash-port-viewer.tsx | 103 ++++++++++++++++++ src/components/setting/setting-clash.tsx | 49 +++------ 2 files changed, 117 insertions(+), 35 deletions(-) create mode 100644 src/components/setting/mods/clash-port-viewer.tsx diff --git a/src/components/setting/mods/clash-port-viewer.tsx b/src/components/setting/mods/clash-port-viewer.tsx new file mode 100644 index 0000000..53de768 --- /dev/null +++ b/src/components/setting/mods/clash-port-viewer.tsx @@ -0,0 +1,103 @@ +import useSWR from "swr"; +import { useEffect, useState } from "react"; +import { useSetRecoilState } from "recoil"; +import { useTranslation } from "react-i18next"; +import { useLockFn } from "ahooks"; +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + List, + ListItem, + ListItemText, + TextField, +} from "@mui/material"; +import { atomClashPort } from "@/services/states"; +import { getClashConfig } from "@/services/api"; +import { patchClashConfig } from "@/services/cmds"; +import { ModalHandler } from "@/hooks/use-modal-handler"; +import Notice from "@/components/base/base-notice"; + +interface Props { + handler: ModalHandler; +} + +const ClashPortViewer = ({ handler }: Props) => { + const { t } = useTranslation(); + + const { data: config, mutate: mutateClash } = useSWR( + "getClashConfig", + getClashConfig + ); + + const [open, setOpen] = useState(false); + const [port, setPort] = useState(config?.["mixed-port"] ?? 9090); + + const setGlobalClashPort = useSetRecoilState(atomClashPort); + + if (handler) { + handler.current = { + open: () => setOpen(true), + close: () => setOpen(false), + }; + } + + useEffect(() => { + if (open && config?.["mixed-port"]) { + setPort(config["mixed-port"]); + } + }, [open, config?.["mixed-port"]]); + + const onSave = useLockFn(async () => { + if (port < 1000) { + return Notice.error("The port should not < 1000"); + } + if (port > 65536) { + return Notice.error("The port should not > 65536"); + } + + setOpen(false); + if (port === config?.["mixed-port"]) return; + + await patchClashConfig({ "mixed-port": port }); + setGlobalClashPort(port); + Notice.success("Change Clash port successfully!", 1000); + mutateClash(); + }); + + return ( + setOpen(false)}> + {t("Clash Port")} + + + + + + + setPort(+e.target.value?.replace(/\D+/, "").slice(0, 5)) + } + /> + + + + + + + + + + ); +}; + +export default ClashPortViewer; diff --git a/src/components/setting/setting-clash.tsx b/src/components/setting/setting-clash.tsx index 78d0ea3..5e13d6b 100644 --- a/src/components/setting/setting-clash.tsx +++ b/src/components/setting/setting-clash.tsx @@ -1,5 +1,4 @@ import useSWR from "swr"; -import { useSetRecoilState } from "recoil"; import { useTranslation } from "react-i18next"; import { TextField, @@ -9,17 +8,16 @@ import { Typography, IconButton, } from "@mui/material"; -import { atomClashPort } from "@/services/states"; import { ArrowForward } from "@mui/icons-material"; import { patchClashConfig } from "@/services/cmds"; import { SettingList, SettingItem } from "./setting"; import { getClashConfig, getVersion, updateConfigs } from "@/services/api"; import useModalHandler from "@/hooks/use-modal-handler"; -import Notice from "../base/base-notice"; import GuardState from "./mods/guard-state"; import CoreSwitch from "./mods/core-switch"; import WebUIViewer from "./mods/web-ui-viewer"; import ClashFieldViewer from "./mods/clash-field-viewer"; +import ClashPortViewer from "./mods/clash-port-viewer"; interface Props { onError: (err: Error) => void; @@ -41,10 +39,9 @@ const SettingClash = ({ onError }: Props) => { "mixed-port": mixedPort, } = clashConfig ?? {}; - const setGlobalClashPort = useSetRecoilState(atomClashPort); - const webUIHandler = useModalHandler(); const fieldHandler = useModalHandler(); + const portHandler = useModalHandler(); const onSwitchFormat = (_e: any, value: boolean) => value; const onChangeData = (patch: Partial) => { @@ -55,21 +52,6 @@ const SettingClash = ({ onError }: Props) => { await patchClashConfig(patch); }; - const onUpdatePort = async (port: number) => { - 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 }); - setGlobalClashPort(port); - Notice.success("Change Clash port successfully!", 1000); - - // update the config - mutateClash(); - }; - // get clash core version const clashVer = versionData?.premium ? `${versionData.version} Premium` @@ -79,6 +61,7 @@ const SettingClash = ({ onError }: Props) => { + { onChange={(e) => onChangeData({ "log-level": e })} onGuard={(e) => onUpdateData({ "log-level": e })} > - div": { py: "7.5px" } }}> Debug Info - Warning + Warn Error Silent @@ -125,20 +108,16 @@ const SettingClash = ({ onError }: Props) => { - +e.target.value?.replace(/\D+/, "")} - onChange={(e) => onChangeData({ "mixed-port": e })} - onGuard={onUpdatePort} - waitTime={1000} - > - - + sx={{ width: 100, input: { py: "7.5px" } }} + onClick={(e) => { + portHandler.current.open(); + (e.target as any).blur(); + }} + />