From e66a89208d1041a9a3eebc62cabe891a92dba4dc Mon Sep 17 00:00:00 2001 From: GyDi Date: Sun, 6 Nov 2022 23:23:26 +0800 Subject: [PATCH] feat: support to change external controller --- src-tauri/src/core/mod.rs | 17 +-- .../setting/mods/controller-viewer.tsx | 101 ++++++++++++++++++ src/components/setting/setting-clash.tsx | 16 ++- src/locales/zh.json | 1 + src/services/types.d.ts | 6 +- 5 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 src/components/setting/mods/controller-viewer.tsx diff --git a/src-tauri/src/core/mod.rs b/src-tauri/src/core/mod.rs index e0133b4..0a419bd 100644 --- a/src-tauri/src/core/mod.rs +++ b/src-tauri/src/core/mod.rs @@ -112,18 +112,21 @@ impl Core { /// Patch Clash /// handle the clash config changed pub fn patch_clash(&self, patch: Mapping) -> Result<()> { - let has_port = patch.contains_key(&Value::from("mixed-port")); - let has_mode = patch.contains_key(&Value::from("mode")); + let patch_cloned = patch.clone(); + let clash_mode = patch.get("mode"); + let mixed_port = patch.get("mixed-port"); + let external = patch.get("external-controller"); + let secret = patch.get("secret"); - let port = { + let valid_port = { let global = Data::global(); let mut clash = global.clash.lock(); - clash.patch_config(patch)?; - clash.info.port.clone() + clash.patch_config(patch_cloned)?; + clash.info.port.is_some() }; // todo: port check - if has_port && port.is_some() { + if (mixed_port.is_some() && valid_port) || external.is_some() || secret.is_some() { let mut service = self.service.lock(); service.restart()?; drop(service); @@ -134,7 +137,7 @@ impl Core { sysopt.init_sysproxy()?; } - if has_mode { + if clash_mode.is_some() { let handle = self.handle.lock(); handle.update_systray_part()?; } diff --git a/src/components/setting/mods/controller-viewer.tsx b/src/components/setting/mods/controller-viewer.tsx new file mode 100644 index 0000000..ec4c58a --- /dev/null +++ b/src/components/setting/mods/controller-viewer.tsx @@ -0,0 +1,101 @@ +import useSWR from "swr"; +import { useState } from "react"; +import { useLockFn } from "ahooks"; +import { useTranslation } from "react-i18next"; +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + List, + ListItem, + ListItemText, + TextField, +} from "@mui/material"; +import { getClashInfo, patchClashConfig } from "@/services/cmds"; +import { ModalHandler } from "@/hooks/use-modal-handler"; +import { getAxios } from "@/services/api"; +import Notice from "@/components/base/base-notice"; + +interface Props { + handler: ModalHandler; +} + +const ControllerViewer = ({ handler }: Props) => { + const { t } = useTranslation(); + const [open, setOpen] = useState(false); + + const { data: clashInfo, mutate } = useSWR("getClashInfo", getClashInfo); + const [controller, setController] = useState(clashInfo?.server || ""); + const [secret, setSecret] = useState(clashInfo?.secret || ""); + + if (handler) { + handler.current = { + open: () => { + setOpen(true); + setController(clashInfo?.server || ""); + setSecret(clashInfo?.secret || ""); + }, + close: () => setOpen(false), + }; + } + + const onSave = useLockFn(async () => { + try { + await patchClashConfig({ "external-controller": controller, secret }); + mutate(); + // 刷新接口 + getAxios(true); + Notice.success("Change Clash Config successfully!", 1000); + setOpen(false); + } catch (err) { + console.log(err); + } + }); + + return ( + setOpen(false)}> + {t("Clash Port")} + + + + + + setController(e.target.value)} + /> + + + + + setSecret(e.target.value)} + /> + + + + + + + + + + ); +}; + +export default ControllerViewer; diff --git a/src/components/setting/setting-clash.tsx b/src/components/setting/setting-clash.tsx index 3ba8cd1..8ddad18 100644 --- a/src/components/setting/setting-clash.tsx +++ b/src/components/setting/setting-clash.tsx @@ -18,6 +18,7 @@ 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"; +import ControllerViewer from "./mods/controller-viewer"; interface Props { onError: (err: Error) => void; @@ -42,6 +43,7 @@ const SettingClash = ({ onError }: Props) => { const webUIHandler = useModalHandler(); const fieldHandler = useModalHandler(); const portHandler = useModalHandler(); + const controllerHandler = useModalHandler(); const onSwitchFormat = (_e: any, value: boolean) => value; const onChangeData = (patch: Partial) => { @@ -62,6 +64,7 @@ const SettingClash = ({ onError }: Props) => { + { autoComplete="off" size="small" value={mixedPort ?? 0} - sx={{ width: 100, input: { py: "7.5px" } }} + sx={{ width: 100, input: { py: "7.5px", cursor: "pointer" } }} onClick={(e) => { portHandler.current.open(); (e.target as any).blur(); @@ -121,6 +124,17 @@ const SettingClash = ({ onError }: Props) => { /> + + controllerHandler.current.open()} + > + + + +