Display WS state in favicon
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import Favicon from "react-favicon";
|
import Favicon from "react-favicon";
|
||||||
|
import { WSState } from "./MatrixWS";
|
||||||
|
|
||||||
// Taken from https://github.com/element-hq/element-web/blob/0577e245dac944bd85eea07b93a9762a93062f62/src/favicon.ts
|
// Taken from https://github.com/element-hq/element-web/blob/0577e245dac944bd85eea07b93a9762a93062f62/src/favicon.ts
|
||||||
function getInitialFavicon(): HTMLLinkElement[] {
|
function getInitialFavicon(): HTMLLinkElement[] {
|
||||||
@@ -21,6 +22,14 @@ let iconPath = getInitialFavicon()[0].getAttribute("href")!;
|
|||||||
|
|
||||||
export function AppIconModifier(p: {
|
export function AppIconModifier(p: {
|
||||||
numberUnread: number;
|
numberUnread: number;
|
||||||
|
state: string;
|
||||||
}): React.ReactElement {
|
}): React.ReactElement {
|
||||||
return <Favicon url={iconPath} alertCount={p.numberUnread} />;
|
const isError = p.state === WSState.Error || p.state === WSState.Closed;
|
||||||
|
return (
|
||||||
|
<Favicon
|
||||||
|
url={iconPath}
|
||||||
|
alertFillColor={isError ? "orange" : undefined}
|
||||||
|
alertCount={isError ? "x" : p.numberUnread}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ function _MainMessageWidget(p: {
|
|||||||
setRoomMgr(mgr);
|
setRoomMgr(mgr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [wsState, setWsState] = React.useState("");
|
||||||
const handleWsEvent = (m: WsMessage) => {
|
const handleWsEvent = (m: WsMessage) => {
|
||||||
// Process messages for current room
|
// Process messages for current room
|
||||||
if (roomMgr?.processWsMessage(m)) {
|
if (roomMgr?.processWsMessage(m)) {
|
||||||
@@ -120,11 +121,11 @@ function _MainMessageWidget(p: {
|
|||||||
<div style={{ display: "flex", height: "100%" }}>
|
<div style={{ display: "flex", height: "100%" }}>
|
||||||
{/* Websocket */}
|
{/* Websocket */}
|
||||||
<div style={{ position: "absolute", right: "0px", padding: "10px" }}>
|
<div style={{ position: "absolute", right: "0px", padding: "10px" }}>
|
||||||
<MatrixWS onMessage={handleWsEvent} />
|
<MatrixWS onMessage={handleWsEvent} onStateChange={setWsState} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/** Application icon modifier */}
|
{/** Application icon modifier */}
|
||||||
<AppIconModifier numberUnread={unreadRooms} />
|
<AppIconModifier numberUnread={unreadRooms} state={wsState} />
|
||||||
|
|
||||||
{/* Space selector */}
|
{/* Space selector */}
|
||||||
<SpaceSelector {...p} selectedSpace={space} onChange={setSpace} />
|
<SpaceSelector {...p} selectedSpace={space} onChange={setSpace} />
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useSnackbar } from "../../hooks/contexts_provider/SnackbarProvider";
|
|||||||
import CircleIcon from "@mui/icons-material/Circle";
|
import CircleIcon from "@mui/icons-material/Circle";
|
||||||
import { Tooltip } from "@mui/material";
|
import { Tooltip } from "@mui/material";
|
||||||
|
|
||||||
const State = {
|
export const WSState = {
|
||||||
Closed: "Closed",
|
Closed: "Closed",
|
||||||
Connected: "Connected",
|
Connected: "Connected",
|
||||||
Error: "Error",
|
Error: "Error",
|
||||||
@@ -12,6 +12,7 @@ const State = {
|
|||||||
|
|
||||||
export function MatrixWS(p: {
|
export function MatrixWS(p: {
|
||||||
onMessage: (msg: WsMessage) => void;
|
onMessage: (msg: WsMessage) => void;
|
||||||
|
onStateChange?: (state: string) => void;
|
||||||
}): React.ReactElement {
|
}): React.ReactElement {
|
||||||
const snackbar = useSnackbar();
|
const snackbar = useSnackbar();
|
||||||
|
|
||||||
@@ -21,7 +22,13 @@ export function MatrixWS(p: {
|
|||||||
cbRef.current = p.onMessage;
|
cbRef.current = p.onMessage;
|
||||||
}, [p.onMessage]);
|
}, [p.onMessage]);
|
||||||
|
|
||||||
const [state, setState] = React.useState<string>(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<string>(WSState.Closed);
|
||||||
const wsId = React.useRef<number | undefined>(undefined);
|
const wsId = React.useRef<number | undefined>(undefined);
|
||||||
const [connCount, setConnCount] = React.useState(0);
|
const [connCount, setConnCount] = React.useState(0);
|
||||||
|
|
||||||
@@ -30,23 +37,35 @@ export function MatrixWS(p: {
|
|||||||
const ws = new WebSocket(WsApi.WsURL);
|
const ws = new WebSocket(WsApi.WsURL);
|
||||||
wsId.current = id;
|
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) => {
|
ws.onerror = (e) => {
|
||||||
if (wsId.current != id) return;
|
if (wsId.current != id) return;
|
||||||
|
|
||||||
console.error(`WS Debug error!`, e);
|
console.error(`WS Debug error!`, e);
|
||||||
snackbar(`WebSocket error!`);
|
snackbar(`WebSocket error!`);
|
||||||
setState(State.Error);
|
setState(WSState.Error);
|
||||||
|
stateCbRef.current?.(WSState.Error);
|
||||||
|
|
||||||
setTimeout(() => setConnCount(connCount + 1), 500);
|
setTimeout(() => setConnCount(connCount + 1), 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Close
|
||||||
ws.onclose = () => {
|
ws.onclose = () => {
|
||||||
if (wsId.current !== id) return;
|
if (wsId.current !== id) return;
|
||||||
setState(State.Closed);
|
setState(WSState.Closed);
|
||||||
|
stateCbRef.current?.(WSState.Closed);
|
||||||
wsId.current = undefined;
|
wsId.current = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Message
|
||||||
ws.onmessage = (msg) => {
|
ws.onmessage = (msg) => {
|
||||||
if (wsId.current !== id) return;
|
if (wsId.current !== id) return;
|
||||||
|
|
||||||
@@ -62,9 +81,9 @@ export function MatrixWS(p: {
|
|||||||
<Tooltip title={state}>
|
<Tooltip title={state}>
|
||||||
<CircleIcon
|
<CircleIcon
|
||||||
color={
|
color={
|
||||||
state === State.Connected
|
state === WSState.Connected
|
||||||
? "success"
|
? "success"
|
||||||
: state === State.Error
|
: state === WSState.Error
|
||||||
? "error"
|
? "error"
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user