From 5566c671900028f56fcce3e86c11895aa95b2e03 Mon Sep 17 00:00:00 2001
From: Sebastian Mohr <sebastian@mohrenclan.de>
Date: Thu, 16 Jan 2025 18:23:11 +0100
Subject: [PATCH] Refactored client side useSocketHook and split online user
 and manager connect functions.

---
 .../components/context/useSocketContext.tsx   | 80 +++++++++++--------
 1 file changed, 46 insertions(+), 34 deletions(-)

diff --git a/apps/fullstack/components/context/useSocketContext.tsx b/apps/fullstack/components/context/useSocketContext.tsx
index 75c57401..04ed8db4 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>
     );
-- 
GitLab