admin-dashboard-web/src/Contexts/WebSocketContext.js

153 lines
4.4 KiB
JavaScript

import { createContext, useContext, useEffect, useRef } from "react";
import {
BrowserTabSession,
Constants,
myFetch,
wsConnectionCustomEventName,
} from "../utils";
import { useSideBarContext } from "./SideBarContext";
import { useAppContext } from "./AppContext";
import { handleWebSocketMessage } from "../Handlers/WebSocketMessageHandler";
import { useGroupTasksContext } from "./GroupTasksContext";
import { useNavigate } from "react-router-dom";
import { useUserProfileContext } from "./UserProfileContext";
import { useAdminAreaRolesContext } from "./AdminAreaRolesContext";
import { useUsersContext } from "./UsersContext";
import { useHeaderContext } from "./HeaderContext";
import { useConsolesContext } from "./ConsolesContext";
const WebSocketContext = createContext(null);
export const useWebSocketContext = () => useContext(WebSocketContext);
let wsConnectionEvent = null;
export default function WebSocketProvider({
children,
userSession,
setUserSession,
isWebSocketReady,
setIsWebSocketReady,
notificationApi,
}) {
const ws = useRef(null);
const wsMessageCache = useRef([]);
const navigate = useNavigate();
const appContext = useAppContext();
const headerContext = useHeaderContext();
const sideBarContext = useSideBarContext();
const groupTasksContext = useGroupTasksContext();
const userProfileContext = useUserProfileContext();
const adminAreaRolesContext = useAdminAreaRolesContext();
const usersContext = useUsersContext();
const consolesContext = useConsolesContext();
if (wsConnectionEvent === null) {
wsConnectionEvent = new CustomEvent(wsConnectionCustomEventName, {
detail: "wsReconnect",
});
}
const connect = () => {
ws.current = new WebSocket(
`${Constants.WS_ADDRESS}?auth=${userSession}&bts=${BrowserTabSession}`
);
ws.current.onopen = () => {
console.log("connected");
sideBarContext.setConnectionBadgeStatus("success");
setIsWebSocketReady(true);
console.log("dispatchEvent");
document.dispatchEvent(wsConnectionEvent);
myFetch("/user/", "GET").then((data) => {
appContext.userId.current = data.UserId;
appContext.setUserPermissions(
data.Permissions === null ? [] : data.Permissions
);
appContext.setUsers(data.Users);
headerContext.setTotalNotifications(data.TotalNotifications);
sideBarContext.setUsername(data.Username);
sideBarContext.setAvatar(data.Avatar);
sideBarContext.setAvailableCategories(
data.AvailableCategories === null ? [] : data.AvailableCategories
);
});
if (wsMessageCache.current.length > 0) {
// send cached messages
wsMessageCache.current.forEach((message) => {
ws.current.send(JSON.stringify(message));
});
wsMessageCache.current = [];
}
};
ws.current.onmessage = (event) => {
handleWebSocketMessage(
event,
navigate,
notificationApi,
sideBarContext,
appContext,
headerContext,
groupTasksContext,
userProfileContext,
adminAreaRolesContext,
usersContext,
consolesContext
);
};
ws.current.onclose = (event) => {
setIsWebSocketReady(false);
sideBarContext.setConnectionBadgeStatus("error");
console.warn("closed", event);
// custom code defined by the backend server
if (event.code === 4001 || event.code === 4002) {
//Unauthorized || SessionClosed
setUserSession();
window.location.href = "/";
return;
}
if (event.reason.code === 1005) return;
console.warn("reconnecting...");
setTimeout(() => connect(), 1000);
};
};
const SendSocketMessage = (cmd, body) => {
if (isWebSocketReady && ws.current !== null) {
ws.current.send(JSON.stringify({ Cmd: cmd, Body: body }));
} else {
/*notificationApi["error"]({
message: `Websocket is not ready`,
description: `Please check your internet connection`,
}); */
wsMessageCache.current.push({ Cmd: cmd, Body: body });
// message.error(`Websocket is not ready`);
}
};
useEffect(() => {
connect();
return () => ws.current.close();
}, []);
return (
<WebSocketContext.Provider value={{ SendSocketMessage: SendSocketMessage }}>
{children}
</WebSocketContext.Provider>
);
}