import { createContext, useEffect, useState } from "react"; /** * constants */ export const Constants = { API_ADDRESS: "http://localhost:8080/v1", WS_ADDRESS: "ws://localhost:8080/ws", }; /** * user session */ export function UseUserSession() { const getUserSession = () => { return JSON.parse(localStorage.getItem("session")); }; const [userSession, setUserSession] = useState(getUserSession()); const saveUserSession = (session) => { setUserSession(session); if (session === undefined) { localStorage.removeItem("session"); } else { localStorage.setItem("session", JSON.stringify(session)); } }; return { setUserSession: saveUserSession, userSession, }; } /** * websocket */ let l = "loading..."; let webSocketContextPreview = { User: { Username: l, Email: l, }, ConnectionBadgeStatus: "error", ConnectedWebSocketUsersCount: 0, CategoryGroups: [], }; export const WebSocketContext = createContext(webSocketContextPreview); // commands received from the backend server const ReceivedMessagesCommands = { InitUserSocketConnection: 1, UpdateConnectedUsers: 2, }; export function WebSocketProvider({ children, userSession, setUserSession }) { const [isReady, setIsReady] = useState(false); const [connectionBadgeStatus, setConnectionBadgeStatus] = useState( webSocketContextPreview.ConnectionBadgeStatus ); const [connectedWebSocketUsersCount, setConnectedWebSocketUsersCount] = useState(0); const [user, setUser] = useState(webSocketContextPreview.User); const [categoryGroups, setCategoryGroups] = useState( webSocketContextPreview.CategoryGroups ); let socket = null; const connect = () => { socket = new WebSocket(Constants.WS_ADDRESS + "?auth=" + userSession); socket.onopen = () => { console.log("connected"); setConnectionBadgeStatus("success"); setIsReady(true); }; socket.onmessage = (event) => { const data = JSON.parse(event.data); console.log("received message", data); const cmd = data.Cmd; const body = data.Body; switch (cmd) { case ReceivedMessagesCommands.InitUserSocketConnection: setUser(body.User); setCategoryGroups(body.CategoryGroups); break; case ReceivedMessagesCommands.UpdateConnectedUsers: setConnectedWebSocketUsersCount(body); break; } }; socket.onclose = (event) => { setIsReady(false); setConnectionBadgeStatus("error"); console.log("closed", event); // custom code defined by the backend server if (event.code === 4001) { setUserSession(); window.location.href = "/"; return; } if (event.reason.code === 1005) return; console.log("reconnecting..."); setTimeout(() => connect(), 1000); }; }; useEffect(() => { connect(); return () => socket.close(); }, []); return ( {children} ); }