diff --git a/matrixgw_frontend/src/widgets/messages/AppIconModifier.tsx b/matrixgw_frontend/src/widgets/messages/AppIconModifier.tsx index 4d10089..5cce966 100644 --- a/matrixgw_frontend/src/widgets/messages/AppIconModifier.tsx +++ b/matrixgw_frontend/src/widgets/messages/AppIconModifier.tsx @@ -1,4 +1,5 @@ import Favicon from "react-favicon"; +import { WSState } from "./MatrixWS"; // Taken from https://github.com/element-hq/element-web/blob/0577e245dac944bd85eea07b93a9762a93062f62/src/favicon.ts function getInitialFavicon(): HTMLLinkElement[] { @@ -21,6 +22,14 @@ let iconPath = getInitialFavicon()[0].getAttribute("href")!; export function AppIconModifier(p: { numberUnread: number; + state: string; }): React.ReactElement { - return ; + const isError = p.state === WSState.Error || p.state === WSState.Closed; + return ( + + ); } diff --git a/matrixgw_frontend/src/widgets/messages/MainMessagesWidget.tsx b/matrixgw_frontend/src/widgets/messages/MainMessagesWidget.tsx index 8d87f46..1980e8f 100644 --- a/matrixgw_frontend/src/widgets/messages/MainMessagesWidget.tsx +++ b/matrixgw_frontend/src/widgets/messages/MainMessagesWidget.tsx @@ -90,6 +90,7 @@ function _MainMessageWidget(p: { setRoomMgr(mgr); }; + const [wsState, setWsState] = React.useState(""); const handleWsEvent = (m: WsMessage) => { // Process messages for current room if (roomMgr?.processWsMessage(m)) { @@ -120,11 +121,11 @@ function _MainMessageWidget(p: {
{/* Websocket */}
- +
{/** Application icon modifier */} - + {/* Space selector */} diff --git a/matrixgw_frontend/src/widgets/messages/MatrixWS.tsx b/matrixgw_frontend/src/widgets/messages/MatrixWS.tsx index f4d4833..8e376cb 100644 --- a/matrixgw_frontend/src/widgets/messages/MatrixWS.tsx +++ b/matrixgw_frontend/src/widgets/messages/MatrixWS.tsx @@ -4,7 +4,7 @@ import { useSnackbar } from "../../hooks/contexts_provider/SnackbarProvider"; import CircleIcon from "@mui/icons-material/Circle"; import { Tooltip } from "@mui/material"; -const State = { +export const WSState = { Closed: "Closed", Connected: "Connected", Error: "Error", @@ -12,6 +12,7 @@ const State = { export function MatrixWS(p: { onMessage: (msg: WsMessage) => void; + onStateChange?: (state: string) => void; }): React.ReactElement { const snackbar = useSnackbar(); @@ -21,7 +22,13 @@ export function MatrixWS(p: { cbRef.current = p.onMessage; }, [p.onMessage]); - const [state, setState] = React.useState(State.Closed); + // Keep only the latest version of onStateChange + const stateCbRef = React.useRef(p.onStateChange); + React.useEffect(() => { + stateCbRef.current = p.onStateChange; + }, [p.onStateChange]); + + const [state, setState] = React.useState(WSState.Closed); const wsId = React.useRef(undefined); const [connCount, setConnCount] = React.useState(0); @@ -30,23 +37,35 @@ export function MatrixWS(p: { const ws = new WebSocket(WsApi.WsURL); wsId.current = id; - ws.onopen = () => setState(State.Connected); + // Open + ws.onopen = () => { + if (wsId.current != id) return; + + setState(WSState.Connected); + stateCbRef.current?.(WSState.Connected); + }; + + // Error ws.onerror = (e) => { if (wsId.current != id) return; console.error(`WS Debug error!`, e); snackbar(`WebSocket error!`); - setState(State.Error); + setState(WSState.Error); + stateCbRef.current?.(WSState.Error); setTimeout(() => setConnCount(connCount + 1), 500); }; + // Close ws.onclose = () => { if (wsId.current !== id) return; - setState(State.Closed); + setState(WSState.Closed); + stateCbRef.current?.(WSState.Closed); wsId.current = undefined; }; + // Message ws.onmessage = (msg) => { if (wsId.current !== id) return; @@ -62,9 +81,9 @@ export function MatrixWS(p: {