diff --git a/src/components/setting/setting-system.tsx b/src/components/setting/setting-system.tsx index 1bfae0b..fad66a2 100644 --- a/src/components/setting/setting-system.tsx +++ b/src/components/setting/setting-system.tsx @@ -1,16 +1,22 @@ import useSWR from "swr"; -import { useRef } from "react"; +import { useRef, useState } from "react"; import { useTranslation } from "react-i18next"; -import { PrivacyTipRounded, SettingsRounded } from "@mui/icons-material"; -import { checkService } from "@/services/cmds"; +import { SettingsRounded } from "@mui/icons-material"; +import { + checkService, + installService, + uninstallService, +} from "@/services/cmds"; import { useVerge } from "@/hooks/use-verge"; -import { DialogRef, Switch } from "@/components/base"; +import { DialogRef, Notice, Switch } from "@/components/base"; import { SettingList, SettingItem } from "./mods/setting-comp"; import { GuardState } from "./mods/guard-state"; import { ServiceViewer } from "./mods/service-viewer"; import { SysproxyViewer } from "./mods/sysproxy-viewer"; import { TunViewer } from "./mods/tun-viewer"; import { TooltipIcon } from "@/components/base/base-tooltip-icon"; +import { LoadingButton } from "@mui/lab"; +import { useLockFn } from "ahooks"; interface Props { onError?: (err: Error) => void; @@ -20,13 +26,18 @@ const SettingSystem = ({ onError }: Props) => { const { t } = useTranslation(); const { verge, mutateVerge, patchVerge } = useVerge(); - + const [serviceLoading, setServiceLoading] = useState(false); + const [uninstallServiceLoaing, setUninstallServiceLoading] = useState(false); // service mode - const { data: serviceStatus } = useSWR("checkService", checkService, { - revalidateIfStale: false, - shouldRetryOnError: false, - focusThrottleInterval: 36e5, // 1 hour - }); + const { data: serviceStatus, mutate: mutateServiceStatus } = useSWR( + "checkService", + checkService, + { + revalidateIfStale: false, + shouldRetryOnError: false, + focusThrottleInterval: 36e5, // 1 hour + } + ); const serviceRef = useRef(null); const sysproxyRef = useRef(null); @@ -45,6 +56,53 @@ const SettingSystem = ({ onError }: Props) => { mutateVerge({ ...verge, ...patch }, false); }; + const onInstallOrEnableService = useLockFn(async () => { + setServiceLoading(true); + try { + if (serviceStatus === "uninstall" || serviceStatus === "unknown") { + // install service + await installService(); + await mutateServiceStatus(); + setTimeout(() => { + mutateServiceStatus(); + }, 2000); + Notice.success(t("Service Installed Successfully")); + setServiceLoading(false); + } else { + // enable or disable service + const enable = serviceStatus === "active"; + await patchVerge({ enable_service_mode: !enable }); + onChangeData({ enable_service_mode: !enable }); + await mutateServiceStatus(); + setTimeout(() => { + mutateServiceStatus(); + }, 2000); + setServiceLoading(false); + } + } catch (err: any) { + await mutateServiceStatus(); + Notice.error(err.message || err.toString()); + setServiceLoading(false); + } + }); + + const onUninstallService = useLockFn(async () => { + setUninstallServiceLoading(true); + try { + await uninstallService(); + await mutateServiceStatus(); + setTimeout(() => { + mutateServiceStatus(); + }, 2000); + Notice.success(t("Service Uninstalled Successfully")); + setUninstallServiceLoading(false); + } catch (err: any) { + await mutateServiceStatus(); + Notice.error(err.message || err.toString()); + setUninstallServiceLoading(false); + } + }); + return ( @@ -66,38 +124,52 @@ const SettingSystem = ({ onError }: Props) => { valueProps="checked" onCatch={onError} onFormat={onSwitchFormat} - onChange={(e) => onChangeData({ enable_tun_mode: e })} - onGuard={(e) => patchVerge({ enable_tun_mode: e })} + onChange={(e) => { + if (serviceStatus !== "active") { + onChangeData({ enable_tun_mode: false }); + } else { + onChangeData({ enable_tun_mode: e }); + } + }} + onGuard={(e) => { + if (serviceStatus !== "active" && e) { + Notice.error(t("Please enable service mode first")); + return Promise.resolve(); + } else { + return patchVerge({ enable_tun_mode: e }); + } + }} > - serviceRef.current?.open()} - /> - } - > - onChangeData({ enable_service_mode: e })} - onGuard={(e) => patchVerge({ enable_service_mode: e })} + + - - + {serviceStatus === "active" + ? t("Disable") + : serviceStatus === "installed" + ? t("Enable") + : t("Install")} + + {serviceStatus === "installed" && ( + + {t("Uninstall")} + + )}