sysproxy-viewer.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import { forwardRef, useImperativeHandle, useState } from "react";
  2. import { useLockFn } from "ahooks";
  3. import { useTranslation } from "react-i18next";
  4. import {
  5. Box,
  6. InputAdornment,
  7. List,
  8. ListItem,
  9. ListItemText,
  10. styled,
  11. TextField,
  12. Typography,
  13. } from "@mui/material";
  14. import { useVerge } from "@/hooks/use-verge";
  15. import { getSystemProxy } from "@/services/cmds";
  16. import { BaseDialog, DialogRef, Notice, Switch } from "@/components/base";
  17. export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
  18. const { t } = useTranslation();
  19. const [open, setOpen] = useState(false);
  20. const { verge, patchVerge } = useVerge();
  21. type SysProxy = Awaited<ReturnType<typeof getSystemProxy>>;
  22. const [sysproxy, setSysproxy] = useState<SysProxy>();
  23. const {
  24. enable_system_proxy: enabled,
  25. enable_proxy_guard,
  26. system_proxy_bypass,
  27. proxy_guard_duration,
  28. } = verge ?? {};
  29. const [value, setValue] = useState({
  30. guard: enable_proxy_guard,
  31. bypass: system_proxy_bypass,
  32. duration: proxy_guard_duration ?? 10,
  33. });
  34. useImperativeHandle(ref, () => ({
  35. open: () => {
  36. setOpen(true);
  37. setValue({
  38. guard: enable_proxy_guard,
  39. bypass: system_proxy_bypass,
  40. duration: proxy_guard_duration ?? 10,
  41. });
  42. getSystemProxy().then((p) => setSysproxy(p));
  43. },
  44. close: () => setOpen(false),
  45. }));
  46. const onSave = useLockFn(async () => {
  47. if (value.duration < 1) {
  48. Notice.error(t("Proxy Daemon Duration Cannot be Less than 1 Second"));
  49. return;
  50. }
  51. const patch: Partial<IVergeConfig> = {};
  52. if (value.guard !== enable_proxy_guard) {
  53. patch.enable_proxy_guard = value.guard;
  54. }
  55. if (value.duration !== proxy_guard_duration) {
  56. patch.proxy_guard_duration = value.duration;
  57. }
  58. if (value.bypass !== system_proxy_bypass) {
  59. patch.system_proxy_bypass = value.bypass;
  60. }
  61. try {
  62. await patchVerge(patch);
  63. setOpen(false);
  64. } catch (err: any) {
  65. Notice.error(err.message || err.toString());
  66. }
  67. });
  68. return (
  69. <BaseDialog
  70. open={open}
  71. title={t("System Proxy Setting")}
  72. contentSx={{ width: 450, maxHeight: 300 }}
  73. okBtn={t("Save")}
  74. cancelBtn={t("Cancel")}
  75. onClose={() => setOpen(false)}
  76. onCancel={() => setOpen(false)}
  77. onOk={onSave}
  78. >
  79. <List>
  80. <ListItem sx={{ padding: "5px 2px" }}>
  81. <ListItemText primary={t("Proxy Guard")} />
  82. <Switch
  83. edge="end"
  84. disabled={!enabled}
  85. checked={value.guard}
  86. onChange={(_, e) => setValue((v) => ({ ...v, guard: e }))}
  87. />
  88. </ListItem>
  89. <ListItem sx={{ padding: "5px 2px" }}>
  90. <ListItemText primary={t("Guard Duration")} />
  91. <TextField
  92. disabled={!enabled}
  93. size="small"
  94. value={value.duration}
  95. sx={{ width: 100 }}
  96. InputProps={{
  97. endAdornment: <InputAdornment position="end">s</InputAdornment>,
  98. }}
  99. onChange={(e) => {
  100. setValue((v) => ({
  101. ...v,
  102. duration: +e.target.value.replace(/\D/, ""),
  103. }));
  104. }}
  105. />
  106. </ListItem>
  107. <ListItem sx={{ padding: "5px 2px", alignItems: "start" }}>
  108. <ListItemText primary={t("Proxy Bypass")} sx={{ padding: "3px 0" }} />
  109. <TextField
  110. disabled={!enabled}
  111. size="small"
  112. autoComplete="off"
  113. multiline
  114. rows={3}
  115. sx={{ width: 280 }}
  116. value={value.bypass}
  117. placeholder={sysproxy?.bypass || `-`}
  118. onChange={(e) =>
  119. setValue((v) => ({ ...v, bypass: e.target.value }))
  120. }
  121. />
  122. </ListItem>
  123. </List>
  124. <Box sx={{ mt: 2.5 }}>
  125. <Typography variant="body1" sx={{ fontSize: "18px", mb: 1 }}>
  126. {t("Current System Proxy")}
  127. </Typography>
  128. <FlexBox>
  129. <Typography className="label">{t("Enable status")}</Typography>
  130. <Typography className="value">
  131. {(!!sysproxy?.enable).toString()}
  132. </Typography>
  133. </FlexBox>
  134. <FlexBox>
  135. <Typography className="label">{t("Server Addr")}</Typography>
  136. <Typography className="value">{sysproxy?.server || "-"}</Typography>
  137. </FlexBox>
  138. <FlexBox>
  139. <Typography className="label">{t("Bypass")}</Typography>
  140. <Typography className="value" style={{ overflowWrap: "anywhere" }}>
  141. {sysproxy?.bypass || "-"}
  142. </Typography>
  143. </FlexBox>
  144. </Box>
  145. </BaseDialog>
  146. );
  147. });
  148. const FlexBox = styled("div")`
  149. display: flex;
  150. margin-top: 4px;
  151. .label {
  152. flex: none;
  153. width: 85px;
  154. }
  155. `;