service-mode.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import useSWR, { useSWRConfig } from "swr";
  2. import { useLockFn } from "ahooks";
  3. import { useTranslation } from "react-i18next";
  4. import {
  5. Button,
  6. Dialog,
  7. DialogContent,
  8. DialogTitle,
  9. Stack,
  10. Typography,
  11. } from "@mui/material";
  12. import {
  13. checkService,
  14. installService,
  15. uninstallService,
  16. patchVergeConfig,
  17. } from "../../services/cmds";
  18. import Notice from "../base/base-notice";
  19. import noop from "../../utils/noop";
  20. interface Props {
  21. open: boolean;
  22. enable: boolean;
  23. onClose: () => void;
  24. onError?: (err: Error) => void;
  25. }
  26. const ServiceMode = (props: Props) => {
  27. const { open, enable, onClose, onError = noop } = props;
  28. const { t } = useTranslation();
  29. const { mutate } = useSWRConfig();
  30. const { data: status } = useSWR("checkService", checkService, {
  31. revalidateIfStale: true,
  32. shouldRetryOnError: false,
  33. });
  34. const state = status != null ? status : "pending";
  35. const onInstall = useLockFn(async () => {
  36. try {
  37. await installService();
  38. mutate("checkService");
  39. onClose();
  40. Notice.success("Service installed successfully");
  41. } catch (err: any) {
  42. mutate("checkService");
  43. onError(err);
  44. }
  45. });
  46. const onUninstall = useLockFn(async () => {
  47. try {
  48. if (state === "active" && enable) {
  49. await patchVergeConfig({ enable_service_mode: false });
  50. }
  51. await uninstallService();
  52. mutate("checkService");
  53. onClose();
  54. Notice.success("Service uninstalled successfully");
  55. } catch (err: any) {
  56. mutate("checkService");
  57. onError(err);
  58. }
  59. });
  60. return (
  61. <Dialog open={open} onClose={onClose}>
  62. <DialogTitle>{t("Service Mode")}</DialogTitle>
  63. <DialogContent sx={{ width: 360, userSelect: "text" }}>
  64. <Typography>Current State: {state}</Typography>
  65. {(state === "unknown" || state === "uninstall") && (
  66. <Typography>
  67. Infomation: Please make sure the Clash Verge Service is installed
  68. and enabled
  69. </Typography>
  70. )}
  71. <Stack
  72. direction="row"
  73. spacing={1}
  74. sx={{ mt: 4, justifyContent: "flex-end" }}
  75. >
  76. {state === "uninstall" && (
  77. <Button variant="contained" onClick={onInstall}>
  78. Install
  79. </Button>
  80. )}
  81. {(state === "active" || state === "installed") && (
  82. <Button variant="outlined" onClick={onUninstall}>
  83. Uninstall
  84. </Button>
  85. )}
  86. </Stack>
  87. </DialogContent>
  88. </Dialog>
  89. );
  90. };
  91. export default ServiceMode;