import { useEffect, useMemo, useState } from "react"; import { useLockFn } from "ahooks"; import { Box, Button, Paper, TextField } from "@mui/material"; import { Virtuoso } from "react-virtuoso"; import { useTranslation } from "react-i18next"; import { ApiType } from "../services/types"; import { closeAllConnections, getInformation } from "../services/api"; import BasePage from "../components/base/base-page"; import ConnectionItem from "../components/connection/connection-item"; const initConn = { uploadTotal: 0, downloadTotal: 0, connections: [] }; const ConnectionsPage = () => { const { t } = useTranslation(); const [filterText, setFilterText] = useState(""); const [connData, setConnData] = useState(initConn); const filterConn = useMemo(() => { return connData.connections.filter((conn) => (conn.metadata.host || conn.metadata.destinationIP)?.includes(filterText) ); }, [connData, filterText]); useEffect(() => { let ws: WebSocket | null = null; getInformation().then((result) => { const { server = "", secret = "" } = result; ws = new WebSocket(`ws://${server}/connections?token=${secret}`); ws.addEventListener("message", (event) => { const data = JSON.parse(event.data) as ApiType.Connections; // 与前一次connections的展示顺序尽量保持一致 setConnData((old) => { const oldConn = old.connections; const maxLen = data.connections.length; const connections: typeof oldConn = []; const rest = data.connections.filter((each) => { const index = oldConn.findIndex((o) => o.id === each.id); if (index >= 0 && index < maxLen) { const old = oldConn[index]; each.curUpload = each.upload - old.upload; each.curDownload = each.download - old.download; connections[index] = each; return false; } return true; }); for (let i = 0; i < maxLen; ++i) { if (!connections[i] && rest.length > 0) { connections[i] = rest.shift()!; connections[i].curUpload = 0; connections[i].curDownload = 0; } } return { ...data, connections }; }); }); }); return () => ws?.close(); }, []); const onCloseAll = useLockFn(closeAllConnections); return ( {t("Close All")} } > {/* */} setFilterText(e.target.value)} sx={{ input: { py: 0.65, px: 1.25 } }} /> } /> ); }; export default ConnectionsPage;