import { useCallback, useEffect, useState } from "react"; import socket from "@/lib/socket.io"; type RoomUpdatePayload = { roomId: string; payloads: T[]; }; type RoomErrorPayload = { roomId?: string; message?: string; }; export function useSocketRoom( roomId: string, enabled = true, getKey?: (item: T) => string | number, ) { const [data, setData] = useState([]); const [info, setInfo] = useState( "No data yet — join the room to start receiving", ); const clearRoom = useCallback( (id?: string | number) => { if (id !== undefined && getKey) { setData((prev) => prev.filter((item) => getKey(item) !== id)); setInfo(`Removed item ${id}`); return; } setData([]); setInfo("Room data cleared"); }, [getKey], ); useEffect(() => { if (!roomId || !enabled) return; function handleConnect() { socket.emit("join-room", roomId); setInfo(`Joined room: ${roomId}`); } function handleUpdate(payload: RoomUpdatePayload) { // protects against other room updates hitting this hook if (payload.roomId !== roomId) return; setData((prev) => [...payload.payloads, ...prev]); setInfo(""); } function handleError(err: RoomErrorPayload) { if (err.roomId && err.roomId !== roomId) return; setInfo(err.message ?? "Room error"); } if (!socket.connected) { socket.connect(); } socket.on("connect", handleConnect); socket.on("room-update", handleUpdate); socket.on("room-error", handleError); // If already connected, join immediately if (socket.connected) { socket.emit("join-room", roomId); setInfo(`Joined room: ${roomId}`); } return () => { socket.emit("leave-room", roomId); socket.off("connect", handleConnect); socket.off("room-update", handleUpdate); socket.off("room-error", handleError); }; }, [roomId, enabled]); return { data, info, clearRoom }; } /* const isDockDoorPage = location.pathname.startsWith("/dockdoor"); useSocketRoom( dockId ? `dockdoor:${dockId}` : null, isDockDoorPage, ); */