import { useMemo, useState } from "react"; import { Box, Button, IconButton, MenuItem } from "@mui/material"; import { Virtuoso } from "react-virtuoso"; import { useTranslation } from "react-i18next"; import { useLocalStorage } from "foxact/use-local-storage"; import { PlayCircleOutlineRounded, PauseCircleOutlineRounded, } from "@mui/icons-material"; import { LogLevel } from "@/hooks/use-log-data"; import { useClashInfo } from "@/hooks/use-clash"; import { useEnableLog } from "@/services/states"; import { BaseEmpty, BasePage } from "@/components/base"; import LogItem from "@/components/log/log-item"; import { useTheme } from "@mui/material/styles"; import { BaseSearchBox } from "@/components/base/base-search-box"; import { BaseStyledSelect } from "@/components/base/base-styled-select"; import { SearchState } from "@/components/base/base-search-box"; import { useGlobalLogData, clearGlobalLogs, changeLogLevel, toggleLogEnabled, } from "@/services/global-log-service"; // 后端通过 /logs?level={level} 进行筛选,前端不再需要手动筛选日志级别 const LogPage = () => { const { t } = useTranslation(); const [enableLog, setEnableLog] = useEnableLog(); const { clashInfo } = useClashInfo(); const theme = useTheme(); const isDark = theme.palette.mode === "dark"; const [logLevel, setLogLevel] = useLocalStorage( "log:log-level", "info", ); const [match, setMatch] = useState(() => (_: string) => true); const logData = useGlobalLogData("all"); const [searchState, setSearchState] = useState(); const filterLogs = useMemo(() => { if (!logData || logData.length === 0) { return []; } // Server-side filtering handles level filtering via query parameters // We only need to apply search filtering here return logData.filter((data) => { // 构建完整的搜索文本,包含时间、类型和内容 const searchText = `${data.time || ""} ${data.type} ${data.payload}`.toLowerCase(); const matchesSearch = match(searchText); return matchesSearch; }); }, [logData, match]); const handleLogLevelChange = (newLevel: LogLevel) => { setLogLevel(newLevel); changeLogLevel(newLevel); }; const handleToggleLog = async () => { await toggleLogEnabled(); setEnableLog(!enableLog); }; return ( {enableLog ? ( ) : ( )} } > handleLogLevelChange(e.target.value as LogLevel)} > ALL DEBUG INFO WARNING ERROR { setMatch(() => matcher); setSearchState(state); }} /> {filterLogs.length > 0 ? ( ( )} followOutput={"smooth"} /> ) : ( )} ); }; export default LogPage;