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 (
+
+ );
+};
+
+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 })}
>
-
- +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();
+ }}
+ />