diff --git a/src/components/layout/use-log-setup.ts b/src/components/layout/use-log-setup.ts index 2d05477061180171877241099634b337793c4ad1..75885a47356f1238e48df36a5732f2b6ba4ba438 100644 --- a/src/components/layout/use-log-setup.ts +++ b/src/components/layout/use-log-setup.ts @@ -5,15 +5,20 @@ import { listen } from "@tauri-apps/api/event"; import { getInformation } from "@/services/api"; import { getClashLogs } from "@/services/cmds"; import { atomLogData } from "@/services/states"; +import useLogToggle from "./use-log-toggle"; const MAX_LOG_NUM = 1000; // setup the log websocket export default function useLogSetup() { const [refresh, setRefresh] = useState({}); + + const [enableLog] = useLogToggle(); const setLogData = useSetRecoilState(atomLogData); useEffect(() => { + if (!enableLog) return; + getClashLogs().then(setLogData); let ws: WebSocket = null!; @@ -41,5 +46,5 @@ export default function useLogSetup() { ws?.close(); unlisten?.then((fn) => fn()); }; - }, [refresh]); + }, [refresh, enableLog]); } diff --git a/src/components/layout/use-log-toggle.ts b/src/components/layout/use-log-toggle.ts new file mode 100644 index 0000000000000000000000000000000000000000..36e1f80a3e28fa098d1a2596eb598af52ae76f6d --- /dev/null +++ b/src/components/layout/use-log-toggle.ts @@ -0,0 +1,24 @@ +import { useEffect } from "react"; +import { useRecoilState } from "recoil"; +import { atomEnableLog } from "@/services/states"; + +const LOG_KEY = "enable-log"; + +export default function useLogToggle() { + const [enableLog, setEnableLog] = useRecoilState(atomEnableLog); + + useEffect(() => { + try { + setEnableLog(localStorage.getItem(LOG_KEY) !== "false"); + } catch {} + }, []); + + const setter = (enable: boolean) => { + try { + localStorage.setItem(LOG_KEY, enable.toString()); + } catch {} + setEnableLog(enable); + }; + + return [enableLog, setter]; +} diff --git a/src/pages/logs.tsx b/src/pages/logs.tsx index b749291deeedda09e273a3e60022b1ada0c4e3b3..54dd2b2efea178bcbe977a447804a5e1bd78b1ee 100644 --- a/src/pages/logs.tsx +++ b/src/pages/logs.tsx @@ -1,16 +1,29 @@ import { useMemo, useState } from "react"; import { useRecoilState } from "recoil"; -import { Box, Button, MenuItem, Paper, Select, TextField } from "@mui/material"; +import { + Box, + Button, + IconButton, + MenuItem, + Paper, + Select, + TextField, +} from "@mui/material"; import { Virtuoso } from "react-virtuoso"; import { useTranslation } from "react-i18next"; -import { atomLogData } from "@/services/states"; +import { + PlayCircleOutlineRounded, + PauseCircleOutlineRounded, +} from "@mui/icons-material"; +import { atomEnableLog, atomLogData } from "@/services/states"; import BasePage from "@/components/base/base-page"; -import LogItem from "@/components/log/log-item"; import BaseEmpty from "@/components/base/base-empty"; +import LogItem from "@/components/log/log-item"; const LogPage = () => { const { t } = useTranslation(); const [logData, setLogData] = useRecoilState(atomLogData); + const [enableLog, setEnableLog] = useRecoilState(atomEnableLog); const [logState, setLogState] = useState("all"); const [filterText, setFilterText] = useState(""); @@ -29,14 +42,27 @@ const LogPage = () => { title={t("Logs")} contentStyle={{ height: "100%" }} header={ - <Button - size="small" - sx={{ mt: 1 }} - variant="contained" - onClick={() => setLogData([])} - > - {t("Clear")} - </Button> + <Box sx={{ mt: 1, display: "flex", alignItems: "center" }}> + <IconButton + size="small" + sx={{ mr: 2 }} + onClick={() => setEnableLog((e) => !e)} + > + {enableLog ? ( + <PauseCircleOutlineRounded /> + ) : ( + <PlayCircleOutlineRounded /> + )} + </IconButton> + + <Button + size="small" + variant="contained" + onClick={() => setLogData([])} + > + {t("Clear")} + </Button> + </Box> } > <Paper sx={{ boxSizing: "border-box", boxShadow: 2, height: "100%" }}> diff --git a/src/services/states.ts b/src/services/states.ts index c283d0b52d7db0515f9a900f2ccd5c45c709740b..3f322e388d4ecc65e9e7759a409486b6b55e2d0b 100644 --- a/src/services/states.ts +++ b/src/services/states.ts @@ -15,6 +15,11 @@ export const atomLogData = atom<ApiType.LogItem[]>({ default: [], }); +export const atomEnableLog = atom<boolean>({ + key: "atomEnableLog", + default: true, +}); + // save the state of each profile item loading export const atomLoadingCache = atom<Record<string, boolean>>({ key: "atomLoadingCache",