import { createContext, useContext, useEffect, useRef } from "react"; import { Constants, myFetch } 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); 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(); const connect = () => { ws.current = new WebSocket(`${Constants.WS_ADDRESS}?auth=${userSession}`); ws.current.onopen = () => { console.log("connected"); sideBarContext.setConnectionBadgeStatus("success"); setIsWebSocketReady(true); 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 ( {children} ); }