layout-viewer.tsx 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
  2. import { useTranslation } from "react-i18next";
  3. import { List, Button, Select, MenuItem } from "@mui/material";
  4. import { useVerge } from "@/hooks/use-verge";
  5. import { BaseDialog, DialogRef, Notice, Switch } from "@/components/base";
  6. import { SettingItem } from "./setting-comp";
  7. import { GuardState } from "./guard-state";
  8. import { open as openDialog } from "@tauri-apps/api/dialog";
  9. import { convertFileSrc } from "@tauri-apps/api/tauri";
  10. import { copyIconFile, getAppDir } from "@/services/cmds";
  11. import { join } from "@tauri-apps/api/path";
  12. export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
  13. const { t } = useTranslation();
  14. const { verge, patchVerge, mutateVerge } = useVerge();
  15. const [open, setOpen] = useState(false);
  16. const [commonIcon, setCommonIcon] = useState("");
  17. const [sysproxyIcon, setSysproxyIcon] = useState("");
  18. const [tunIcon, setTunIcon] = useState("");
  19. // const { menu_icon } = verge ?? {};
  20. useEffect(() => {
  21. initIconPath();
  22. }, []);
  23. async function initIconPath() {
  24. const appDir = await getAppDir();
  25. const icon_dir = await join(appDir, "icons");
  26. const common_icon = await join(icon_dir, "common.png");
  27. const sysproxy_icon = await join(icon_dir, "sysproxy.png");
  28. const tun_icon = await join(icon_dir, "tun.png");
  29. setCommonIcon(common_icon);
  30. setSysproxyIcon(sysproxy_icon);
  31. setTunIcon(tun_icon);
  32. }
  33. useImperativeHandle(ref, () => ({
  34. open: () => setOpen(true),
  35. close: () => setOpen(false),
  36. }));
  37. const onSwitchFormat = (_e: any, value: boolean) => value;
  38. const onError = (err: any) => {
  39. Notice.error(err.message || err.toString());
  40. };
  41. const onChangeData = (patch: Partial<IVergeConfig>) => {
  42. mutateVerge({ ...verge, ...patch }, false);
  43. };
  44. return (
  45. <BaseDialog
  46. open={open}
  47. title={t("Layout Setting")}
  48. contentSx={{ width: 450 }}
  49. disableOk
  50. cancelBtn={t("Cancel")}
  51. onClose={() => setOpen(false)}
  52. onCancel={() => setOpen(false)}
  53. >
  54. <List>
  55. <SettingItem label={t("Traffic Graph")}>
  56. <GuardState
  57. value={verge?.traffic_graph ?? true}
  58. valueProps="checked"
  59. onCatch={onError}
  60. onFormat={onSwitchFormat}
  61. onChange={(e) => onChangeData({ traffic_graph: e })}
  62. onGuard={(e) => patchVerge({ traffic_graph: e })}
  63. >
  64. <Switch edge="end" />
  65. </GuardState>
  66. </SettingItem>
  67. <SettingItem label={t("Memory Usage")}>
  68. <GuardState
  69. value={verge?.enable_memory_usage ?? true}
  70. valueProps="checked"
  71. onCatch={onError}
  72. onFormat={onSwitchFormat}
  73. onChange={(e) => onChangeData({ enable_memory_usage: e })}
  74. onGuard={(e) => patchVerge({ enable_memory_usage: e })}
  75. >
  76. <Switch edge="end" />
  77. </GuardState>
  78. </SettingItem>
  79. <SettingItem label={t("Proxy Group Icon")}>
  80. <GuardState
  81. value={verge?.enable_group_icon ?? true}
  82. valueProps="checked"
  83. onCatch={onError}
  84. onFormat={onSwitchFormat}
  85. onChange={(e) => onChangeData({ enable_group_icon: e })}
  86. onGuard={(e) => patchVerge({ enable_group_icon: e })}
  87. >
  88. <Switch edge="end" />
  89. </GuardState>
  90. </SettingItem>
  91. <SettingItem label={t("Menu Icon")}>
  92. <GuardState
  93. value={verge?.menu_icon ?? "monochrome"}
  94. onCatch={onError}
  95. onFormat={(e: any) => e.target.value}
  96. onChange={(e) => onChangeData({ menu_icon: e })}
  97. onGuard={(e) => patchVerge({ menu_icon: e })}
  98. >
  99. <Select size="small" sx={{ width: 140, "> div": { py: "7.5px" } }}>
  100. <MenuItem value="monochrome">{t("Monochrome")}</MenuItem>
  101. <MenuItem value="colorful">{t("Colorful")}</MenuItem>
  102. <MenuItem value="disable">{t("Disable")}</MenuItem>
  103. </Select>
  104. </GuardState>
  105. </SettingItem>
  106. <SettingItem label={t("Common Tray Icon")}>
  107. <GuardState
  108. value={verge?.common_tray_icon}
  109. onCatch={onError}
  110. onChange={(e) => onChangeData({ common_tray_icon: e })}
  111. onGuard={(e) => patchVerge({ common_tray_icon: e })}
  112. >
  113. <Button
  114. variant="outlined"
  115. size="small"
  116. startIcon={
  117. verge?.common_tray_icon &&
  118. commonIcon && (
  119. <img height="20px" src={convertFileSrc(commonIcon)} />
  120. )
  121. }
  122. onClick={async () => {
  123. if (verge?.common_tray_icon) {
  124. onChangeData({ common_tray_icon: false });
  125. patchVerge({ common_tray_icon: false });
  126. } else {
  127. const path = await openDialog({
  128. directory: false,
  129. multiple: false,
  130. filters: [
  131. {
  132. name: "Tray Icon Image",
  133. extensions: ["png"],
  134. },
  135. ],
  136. });
  137. if (path?.length) {
  138. await copyIconFile(`${path}`, "common.png");
  139. onChangeData({ common_tray_icon: true });
  140. patchVerge({ common_tray_icon: true });
  141. }
  142. }
  143. }}
  144. >
  145. {verge?.common_tray_icon ? t("Clear") : t("Browse")}
  146. </Button>
  147. </GuardState>
  148. </SettingItem>
  149. <SettingItem label={t("System Proxy Tray Icon")}>
  150. <GuardState
  151. value={verge?.sysproxy_tray_icon}
  152. onCatch={onError}
  153. onChange={(e) => onChangeData({ sysproxy_tray_icon: e })}
  154. onGuard={(e) => patchVerge({ sysproxy_tray_icon: e })}
  155. >
  156. <Button
  157. variant="outlined"
  158. size="small"
  159. startIcon={
  160. verge?.sysproxy_tray_icon &&
  161. sysproxyIcon && (
  162. <img height="20px" src={convertFileSrc(sysproxyIcon)} />
  163. )
  164. }
  165. onClick={async () => {
  166. if (verge?.sysproxy_tray_icon) {
  167. onChangeData({ sysproxy_tray_icon: false });
  168. patchVerge({ sysproxy_tray_icon: false });
  169. } else {
  170. const path = await openDialog({
  171. directory: false,
  172. multiple: false,
  173. filters: [
  174. {
  175. name: "Tray Icon Image",
  176. extensions: ["png"],
  177. },
  178. ],
  179. });
  180. if (path?.length) {
  181. await copyIconFile(`${path}`, "sysproxy.png");
  182. onChangeData({ sysproxy_tray_icon: true });
  183. patchVerge({ sysproxy_tray_icon: true });
  184. }
  185. }
  186. }}
  187. >
  188. {verge?.sysproxy_tray_icon ? t("Clear") : t("Browse")}
  189. </Button>
  190. </GuardState>
  191. </SettingItem>
  192. <SettingItem label={t("Tun Tray Icon")}>
  193. <GuardState
  194. value={verge?.tun_tray_icon}
  195. onCatch={onError}
  196. onChange={(e) => onChangeData({ tun_tray_icon: e })}
  197. onGuard={(e) => patchVerge({ tun_tray_icon: e })}
  198. >
  199. <Button
  200. variant="outlined"
  201. size="small"
  202. startIcon={
  203. verge?.tun_tray_icon &&
  204. tunIcon && <img height="20px" src={convertFileSrc(tunIcon)} />
  205. }
  206. onClick={async () => {
  207. if (verge?.tun_tray_icon) {
  208. onChangeData({ tun_tray_icon: false });
  209. patchVerge({ tun_tray_icon: false });
  210. } else {
  211. const path = await openDialog({
  212. directory: false,
  213. multiple: false,
  214. filters: [
  215. {
  216. name: "Tray Icon Image",
  217. extensions: ["png"],
  218. },
  219. ],
  220. });
  221. if (path?.length) {
  222. await copyIconFile(`${path}`, "tun.png");
  223. onChangeData({ tun_tray_icon: true });
  224. patchVerge({ tun_tray_icon: true });
  225. }
  226. }
  227. }}
  228. >
  229. {verge?.tun_tray_icon ? t("Clear") : t("Browse")}
  230. </Button>
  231. </GuardState>
  232. </SettingItem>
  233. </List>
  234. </BaseDialog>
  235. );
  236. });