From 4cd7ccda570ee54e0ae50eb6677fcde8b8cdc0f3 Mon Sep 17 00:00:00 2001 From: MystiPanda Date: Mon, 15 Jul 2024 20:29:56 +0800 Subject: [PATCH] fix: unified switch style --- src/components/base/base-switch.tsx | 1 + .../setting/mods/service-switcher.tsx | 97 +++++++++++++ .../setting/mods/service-viewer.tsx | 129 ------------------ src/components/setting/setting-system.tsx | 97 ++----------- src/locales/en.json | 2 +- src/locales/fa.json | 2 +- src/locales/ru.json | 2 +- src/locales/zh.json | 2 +- 8 files changed, 112 insertions(+), 220 deletions(-) create mode 100644 src/components/setting/mods/service-switcher.tsx delete mode 100644 src/components/setting/mods/service-viewer.tsx diff --git a/src/components/base/base-switch.tsx b/src/components/base/base-switch.tsx index c05c091..747affc 100644 --- a/src/components/base/base-switch.tsx +++ b/src/components/base/base-switch.tsx @@ -11,6 +11,7 @@ export const Switch = styled((props: SwitchProps) => ( width: 42, height: 26, padding: 0, + marginRight: 1, "& .MuiSwitch-switchBase": { padding: 0, margin: 2, diff --git a/src/components/setting/mods/service-switcher.tsx b/src/components/setting/mods/service-switcher.tsx new file mode 100644 index 0000000..e86aa1e --- /dev/null +++ b/src/components/setting/mods/service-switcher.tsx @@ -0,0 +1,97 @@ +import { KeyedMutator } from "swr"; +import { useState } from "react"; +import { useLockFn } from "ahooks"; +import { useTranslation } from "react-i18next"; +import { installService, uninstallService } from "@/services/cmds"; +import { Notice } from "@/components/base"; +import { LoadingButton } from "@mui/lab"; + +interface Props { + status: "active" | "installed" | "unknown" | "uninstall"; + mutate: KeyedMutator<"active" | "installed" | "unknown" | "uninstall">; + patchVerge: (value: Partial) => Promise; + onChangeData: (patch: Partial) => void; +} + +export const ServiceSwitcher = (props: Props) => { + const { status, mutate, patchVerge, onChangeData } = props; + + const isActive = status === "active"; + const isInstalled = status === "installed"; + const isUninstall = status === "uninstall" || status === "unknown"; + + const { t } = useTranslation(); + const [serviceLoading, setServiceLoading] = useState(false); + const [uninstallServiceLoaing, setUninstallServiceLoading] = useState(false); + + const onInstallOrEnableService = useLockFn(async () => { + setServiceLoading(true); + try { + if (isUninstall) { + // install service + await installService(); + await mutate(); + setTimeout(() => { + mutate(); + }, 2000); + Notice.success(t("Service Installed Successfully")); + setServiceLoading(false); + } else { + // enable or disable service + await patchVerge({ enable_service_mode: !isActive }); + onChangeData({ enable_service_mode: !isActive }); + await mutate(); + setTimeout(() => { + mutate(); + }, 2000); + setServiceLoading(false); + } + } catch (err: any) { + await mutate(); + Notice.error(err.message || err.toString()); + setServiceLoading(false); + } + }); + + const onUninstallService = useLockFn(async () => { + setUninstallServiceLoading(true); + try { + await uninstallService(); + await mutate(); + setTimeout(() => { + mutate(); + }, 2000); + Notice.success(t("Service Uninstalled Successfully")); + setUninstallServiceLoading(false); + } catch (err: any) { + await mutate(); + Notice.error(err.message || err.toString()); + setUninstallServiceLoading(false); + } + }); + + return ( + <> + + {isActive ? t("Disable") : isInstalled ? t("Enable") : t("Install")} + + {isInstalled && ( + + {t("Uninstall")} + + )} + + ); +}; diff --git a/src/components/setting/mods/service-viewer.tsx b/src/components/setting/mods/service-viewer.tsx deleted file mode 100644 index 5c4e97f..0000000 --- a/src/components/setting/mods/service-viewer.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import useSWR from "swr"; -import { forwardRef, useImperativeHandle, useState } from "react"; -import { useLockFn } from "ahooks"; -import { useTranslation } from "react-i18next"; -import { Button, Stack, Typography } from "@mui/material"; -import { - checkService, - installService, - uninstallService, - patchVergeConfig, -} from "@/services/cmds"; -import { BaseDialog, DialogRef, Notice } from "@/components/base"; - -interface Props { - enable: boolean; -} - -export const ServiceViewer = forwardRef((props, ref) => { - const { enable } = props; - - const { t } = useTranslation(); - const [open, setOpen] = useState(false); - - const { data: status, mutate: mutateCheck } = useSWR( - "checkService", - checkService, - { - revalidateIfStale: false, - shouldRetryOnError: false, - focusThrottleInterval: 36e5, // 1 hour - } - ); - - useImperativeHandle(ref, () => ({ - open: () => setOpen(true), - close: () => setOpen(false), - })); - - const state = status != null ? status : "pending"; - - const onInstall = useLockFn(async () => { - try { - await installService(); - await mutateCheck(); - setOpen(false); - setTimeout(() => { - mutateCheck(); - }, 2000); - Notice.success(t("Service Installed Successfully")); - } catch (err: any) { - mutateCheck(); - Notice.error(err.message || err.toString()); - } - }); - - const onUninstall = useLockFn(async () => { - try { - if (enable) { - await patchVergeConfig({ enable_service_mode: false }); - } - - await uninstallService(); - mutateCheck(); - setOpen(false); - Notice.success(t("Service Uninstalled Successfully")); - } catch (err: any) { - mutateCheck(); - Notice.error(err.message || err.toString()); - } - }); - - // fix unhandled error of the service mode - const onDisable = useLockFn(async () => { - try { - await patchVergeConfig({ enable_service_mode: false }); - mutateCheck(); - setOpen(false); - } catch (err: any) { - mutateCheck(); - Notice.error(err.message || err.toString()); - } - }); - - return ( - setOpen(false)} - > - - {t("Current State")}: {t(state)} - - - {(state === "unknown" || state === "uninstall") && ( - - {t( - "Information: Please make sure that the Clash Verge Service is installed and enabled" - )} - - )} - - - {state === "uninstall" && enable && ( - - )} - - {state === "uninstall" && ( - - )} - - {(state === "active" || state === "installed") && ( - - )} - - - ); -}); diff --git a/src/components/setting/setting-system.tsx b/src/components/setting/setting-system.tsx index fad66a2..7686c8f 100644 --- a/src/components/setting/setting-system.tsx +++ b/src/components/setting/setting-system.tsx @@ -1,22 +1,16 @@ import useSWR from "swr"; -import { useRef, useState } from "react"; +import { useRef } from "react"; import { useTranslation } from "react-i18next"; import { SettingsRounded } from "@mui/icons-material"; -import { - checkService, - installService, - uninstallService, -} from "@/services/cmds"; +import { checkService } from "@/services/cmds"; import { useVerge } from "@/hooks/use-verge"; 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 { ServiceSwitcher } from "./mods/service-switcher"; 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; @@ -26,8 +20,6 @@ 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, mutate: mutateServiceStatus } = useSWR( "checkService", @@ -39,14 +31,12 @@ const SettingSystem = ({ onError }: Props) => { } ); - const serviceRef = useRef(null); const sysproxyRef = useRef(null); const tunRef = useRef(null); const { enable_tun_mode, enable_auto_launch, - enable_service_mode, enable_silent_start, enable_system_proxy, } = verge ?? {}; @@ -56,58 +46,10 @@ 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 ( - { }} onGuard={(e) => { if (serviceStatus !== "active" && e) { - Notice.error(t("Please enable service mode first")); + Notice.error(t("Please Enable Service Mode")); return Promise.resolve(); } else { return patchVerge({ enable_tun_mode: e }); @@ -145,31 +87,12 @@ const SettingSystem = ({ onError }: Props) => { - - {serviceStatus === "active" - ? t("Disable") - : serviceStatus === "installed" - ? t("Enable") - : t("Install")} - - {serviceStatus === "installed" && ( - - {t("Uninstall")} - - )} +