misc-viewer.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import { forwardRef, useImperativeHandle, useState } from "react";
  2. import { useLockFn } from "ahooks";
  3. import { useTranslation } from "react-i18next";
  4. import {
  5. List,
  6. ListItem,
  7. ListItemText,
  8. MenuItem,
  9. Select,
  10. Switch,
  11. TextField,
  12. } from "@mui/material";
  13. import { useVerge } from "@/hooks/use-verge";
  14. import { BaseDialog, DialogRef, Notice } from "@/components/base";
  15. export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
  16. const { t } = useTranslation();
  17. const { verge, patchVerge } = useVerge();
  18. const [open, setOpen] = useState(false);
  19. const [values, setValues] = useState({
  20. appLogLevel: "info",
  21. autoCloseConnection: false,
  22. enableClashFields: true,
  23. enableBuiltinEnhanced: true,
  24. proxyLayoutColumn: 6,
  25. defaultLatencyTest: "",
  26. });
  27. useImperativeHandle(ref, () => ({
  28. open: () => {
  29. setOpen(true);
  30. setValues({
  31. appLogLevel: verge?.app_log_level ?? "info",
  32. autoCloseConnection: verge?.auto_close_connection ?? false,
  33. enableClashFields: verge?.enable_clash_fields ?? true,
  34. enableBuiltinEnhanced: verge?.enable_builtin_enhanced ?? true,
  35. proxyLayoutColumn: verge?.proxy_layout_column || 6,
  36. defaultLatencyTest: verge?.default_latency_test || "",
  37. });
  38. },
  39. close: () => setOpen(false),
  40. }));
  41. const onSave = useLockFn(async () => {
  42. try {
  43. await patchVerge({
  44. app_log_level: values.appLogLevel,
  45. auto_close_connection: values.autoCloseConnection,
  46. enable_clash_fields: values.enableClashFields,
  47. enable_builtin_enhanced: values.enableBuiltinEnhanced,
  48. proxy_layout_column: values.proxyLayoutColumn,
  49. default_latency_test: values.defaultLatencyTest,
  50. });
  51. setOpen(false);
  52. } catch (err: any) {
  53. Notice.error(err.message || err.toString());
  54. }
  55. });
  56. return (
  57. <BaseDialog
  58. open={open}
  59. title={t("Miscellaneous")}
  60. contentSx={{ width: 450 }}
  61. okBtn={t("Save")}
  62. cancelBtn={t("Cancel")}
  63. onClose={() => setOpen(false)}
  64. onCancel={() => setOpen(false)}
  65. onOk={onSave}
  66. >
  67. <List>
  68. <ListItem sx={{ padding: "5px 2px" }}>
  69. <ListItemText primary="App Log Level" />
  70. <Select
  71. size="small"
  72. sx={{ width: 100, "> div": { py: "7.5px" } }}
  73. value={values.appLogLevel}
  74. onChange={(e) => {
  75. setValues((v) => ({
  76. ...v,
  77. appLogLevel: e.target.value as string,
  78. }));
  79. }}
  80. >
  81. {["trace", "debug", "info", "warn", "error", "silent"].map((i) => (
  82. <MenuItem value={i} key={i}>
  83. {i[0].toUpperCase() + i.slice(1).toLowerCase()}
  84. </MenuItem>
  85. ))}
  86. </Select>
  87. </ListItem>
  88. <ListItem sx={{ padding: "5px 2px" }}>
  89. <ListItemText primary="Auto Close Connections" />
  90. <Switch
  91. edge="end"
  92. checked={values.autoCloseConnection}
  93. onChange={(_, c) =>
  94. setValues((v) => ({ ...v, autoCloseConnection: c }))
  95. }
  96. />
  97. </ListItem>
  98. <ListItem sx={{ padding: "5px 2px" }}>
  99. <ListItemText primary="Clash Fields Filter" />
  100. <Switch
  101. edge="end"
  102. checked={values.enableClashFields}
  103. onChange={(_, c) =>
  104. setValues((v) => ({ ...v, enableClashFields: c }))
  105. }
  106. />
  107. </ListItem>
  108. <ListItem sx={{ padding: "5px 2px" }}>
  109. <ListItemText primary="Enable Builtin Enhanced" />
  110. <Switch
  111. edge="end"
  112. checked={values.enableBuiltinEnhanced}
  113. onChange={(_, c) =>
  114. setValues((v) => ({ ...v, enableBuiltinEnhanced: c }))
  115. }
  116. />
  117. </ListItem>
  118. <ListItem sx={{ padding: "5px 2px" }}>
  119. <ListItemText primary="Proxy Layout Column" />
  120. <Select
  121. size="small"
  122. sx={{ width: 100, "> div": { py: "7.5px" } }}
  123. value={values.proxyLayoutColumn}
  124. onChange={(e) => {
  125. setValues((v) => ({
  126. ...v,
  127. proxyLayoutColumn: e.target.value as number,
  128. }));
  129. }}
  130. >
  131. <MenuItem value={6} key={6}>
  132. Auto
  133. </MenuItem>
  134. {[1, 2, 3, 4, 5].map((i) => (
  135. <MenuItem value={i} key={i}>
  136. {i}
  137. </MenuItem>
  138. ))}
  139. </Select>
  140. </ListItem>
  141. <ListItem sx={{ padding: "5px 2px" }}>
  142. <ListItemText primary="Default Latency Test" />
  143. <TextField
  144. size="small"
  145. autoComplete="off"
  146. autoCorrect="off"
  147. autoCapitalize="off"
  148. spellCheck="false"
  149. sx={{ width: 250 }}
  150. value={values.defaultLatencyTest}
  151. placeholder="http://www.gstatic.com/generate_204"
  152. onChange={(e) =>
  153. setValues((v) => ({ ...v, defaultLatencyTest: e.target.value }))
  154. }
  155. />
  156. </ListItem>
  157. </List>
  158. </BaseDialog>
  159. );
  160. });