diff --git a/apps/fullstack/components/context/useSocketContext.tsx b/apps/fullstack/components/context/useSocketContext.tsx index 75c574011dbb55e0f66055356e2fd69445c38106..04ed8db4af8154154b4a232049df62364d8692cb 100644 --- a/apps/fullstack/components/context/useSocketContext.tsx +++ b/apps/fullstack/components/context/useSocketContext.tsx @@ -43,16 +43,9 @@ const SocketContext = createContext<SocketContext | null>(null); * any pages i.e. rooms. This is intentional * as only the worker(s) should join the pages * directly. - * @param children - The children to wrap * @param book_id - The ID of the book to connect to */ -export function SocketContextProvider({ - children, - book_id, -}: { - children: React.ReactNode; - book_id: ID; -}) { +export function useSocket(book_id: ID) { /** Socket variables * normally they are not used but * they are here mainly for debugging purposes @@ -61,30 +54,6 @@ export function SocketContextProvider({ useState<Socket<ServerToClientEvents, ClientToServerEvents>>(); const [isConnected, setIsConnected] = useState(false); - /** Other users currently online and viewing pages - * of the book - */ - const [onlineUsers, setOnlineUsers] = useState<Map<ID, OnlineUser>>( - new Map(), - ); - - const pageToOnlineUsers = new Map<ID, OnlineUser[]>(); - onlineUsers?.forEach((user) => { - user?.page_ids?.forEach((page_id) => { - let new_users = pageToOnlineUsers.get(page_id) || []; - new_users.push(user); - - // filter out duplicates - new_users = new_users.filter( - (user, index, self) => - index === self.findIndex((u) => u.id === user.id), - ); - - pageToOnlineUsers.set(page_id, new_users); - }); - }); - - // Create the socket useEffect(() => { // Create the socket getSocket(book_id).then((newSocket) => { @@ -136,6 +105,20 @@ export function SocketContextProvider({ }; }, [book_id, socket]); + return { socket, isConnected }; +} + +export function useOnlineUsers( + isConnected: boolean, + socket?: Socket<ServerToClientEvents, ClientToServerEvents>, +) { + /** Other users currently online and viewing pages + * of the book + */ + const [onlineUsers, setOnlineUsers] = useState<Map<ID, OnlineUser>>( + new Map(), + ); + //Register online users after connection useEffect(() => { if (!isConnected || !socket) return; @@ -190,18 +173,47 @@ export function SocketContextProvider({ }; }, [socket, isConnected]); + return { onlineUsers }; +} + +export function SocketContextProvider({ + children, + book_id, +}: { + children: React.ReactNode; + book_id: ID; +}) { + const { socket, isConnected } = useSocket(book_id); + const { onlineUsers } = useOnlineUsers(isConnected, socket); + + // Map page ids to online users + const pageToOnlineUsers = new Map<ID, OnlineUser[]>(); + onlineUsers?.forEach((user) => { + user?.page_ids?.forEach((page_id) => { + let new_users = pageToOnlineUsers.get(page_id) || []; + new_users.push(user); + + // filter out duplicates + new_users = new_users.filter( + (user, index, self) => + index === self.findIndex((u) => u.id === user.id), + ); + + pageToOnlineUsers.set(page_id, new_users); + }); + }); + return ( <SocketContext.Provider value={{ socket, isConnected, - onlineUsers, book_id, + onlineUsers, pageToOnlineUsers, }} > <LatencyProblemsModal /> - {children} </SocketContext.Provider> );