proxies.tsx 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import useSWR, { useSWRConfig } from "swr";
  2. import { useEffect } from "react";
  3. import { useLockFn } from "ahooks";
  4. import { Button, ButtonGroup, List, Paper } from "@mui/material";
  5. import { getClashConfig, updateConfigs } from "../services/api";
  6. import { patchClashConfig } from "../services/cmds";
  7. import { getProxies } from "../services/api";
  8. import BasePage from "../components/base/base-page";
  9. import ProxyGroup from "../components/proxy/proxy-group";
  10. import ProxyGlobal from "../components/proxy/proxy-global";
  11. const ProxyPage = () => {
  12. const { mutate } = useSWRConfig();
  13. const { data: proxiesData } = useSWR("getProxies", getProxies);
  14. const { data: clashConfig } = useSWR("getClashConfig", getClashConfig);
  15. const modeList = ["rule", "global", "direct"];
  16. const curMode = clashConfig?.mode.toLowerCase() ?? "direct";
  17. const { groups = [], proxies = [] } = proxiesData ?? {};
  18. // make sure that fetch the proxies successfully
  19. useEffect(() => {
  20. if (
  21. (curMode === "rule" && !groups.length) ||
  22. (curMode === "global" && proxies.length < 2)
  23. ) {
  24. setTimeout(() => mutate("getProxies"), 500);
  25. }
  26. }, [groups, proxies, curMode]);
  27. const onChangeMode = useLockFn(async (mode: string) => {
  28. // switch rapidly
  29. await updateConfigs({ mode });
  30. await patchClashConfig({ mode });
  31. mutate("getClashConfig");
  32. });
  33. // difference style
  34. const showGroup = curMode === "rule" && !!groups.length;
  35. const pageStyle = showGroup ? {} : { height: "100%" };
  36. const paperStyle: any = showGroup
  37. ? { mb: 0.5 }
  38. : { py: 1, height: "100%", boxSizing: "border-box" };
  39. return (
  40. <BasePage
  41. contentStyle={pageStyle}
  42. title={showGroup ? "Proxy Groups" : "Proxies"}
  43. header={
  44. <ButtonGroup size="small">
  45. {modeList.map((mode) => (
  46. <Button
  47. key={mode}
  48. variant={mode === curMode ? "contained" : "outlined"}
  49. onClick={() => onChangeMode(mode)}
  50. sx={{ textTransform: "capitalize" }}
  51. >
  52. {mode}
  53. </Button>
  54. ))}
  55. </ButtonGroup>
  56. }
  57. >
  58. <Paper sx={{ borderRadius: 1, boxShadow: 2, ...paperStyle }}>
  59. {curMode === "rule" && !!groups.length && (
  60. <List>
  61. {groups.map((group) => (
  62. <ProxyGroup key={group.name} group={group} />
  63. ))}
  64. </List>
  65. )}
  66. {((curMode === "rule" && !groups.length) || curMode === "global") && (
  67. <ProxyGlobal
  68. groupName="GLOBAL"
  69. curProxy={proxiesData?.global?.now}
  70. proxies={proxies}
  71. />
  72. )}
  73. {curMode === "direct" && (
  74. <ProxyGlobal
  75. groupName="DIRECT"
  76. curProxy="DIRECT"
  77. proxies={[proxiesData?.direct!].filter(Boolean)}
  78. />
  79. )}
  80. </Paper>
  81. </BasePage>
  82. );
  83. };
  84. export default ProxyPage;