102 lines
2.5 KiB
TypeScript
102 lines
2.5 KiB
TypeScript
|
|
import { useEffect, useState, useCallback } from "react";
|
||
|
|
import { io, Socket } from "socket.io-client";
|
||
|
|
|
||
|
|
const SOCKET_URL = typeof window !== "undefined"
|
||
|
|
? window.location.origin
|
||
|
|
: "http://localhost:3000";
|
||
|
|
|
||
|
|
export interface DraftSocketEvents {
|
||
|
|
// Events emitted by server
|
||
|
|
"pick-made": (data: any) => void;
|
||
|
|
"timer-update": (data: any) => void;
|
||
|
|
"current-pick-changed": (data: any) => void;
|
||
|
|
"draft-started": (data: any) => void;
|
||
|
|
"draft-paused": (data: any) => void;
|
||
|
|
"draft-completed": (data: any) => void;
|
||
|
|
"queue-updated": (data: any) => void;
|
||
|
|
"user-joined": (data: any) => void;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useDraftSocket(seasonId: string | null) {
|
||
|
|
const [socket, setSocket] = useState<Socket | null>(null);
|
||
|
|
const [isConnected, setIsConnected] = useState(false);
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
if (!seasonId) return;
|
||
|
|
|
||
|
|
// Create socket connection
|
||
|
|
const newSocket = io(SOCKET_URL, {
|
||
|
|
transports: ["websocket", "polling"],
|
||
|
|
});
|
||
|
|
|
||
|
|
newSocket.on("connect", () => {
|
||
|
|
console.log("Socket connected:", newSocket.id);
|
||
|
|
setIsConnected(true);
|
||
|
|
|
||
|
|
// Join the draft room
|
||
|
|
newSocket.emit("join-draft", seasonId);
|
||
|
|
});
|
||
|
|
|
||
|
|
newSocket.on("disconnect", () => {
|
||
|
|
console.log("Socket disconnected");
|
||
|
|
setIsConnected(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
newSocket.on("connect_error", (error) => {
|
||
|
|
console.error("Socket connection error:", error);
|
||
|
|
setIsConnected(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
setSocket(newSocket);
|
||
|
|
|
||
|
|
// Cleanup on unmount
|
||
|
|
return () => {
|
||
|
|
if (newSocket) {
|
||
|
|
newSocket.emit("leave-draft", seasonId);
|
||
|
|
newSocket.close();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}, [seasonId]);
|
||
|
|
|
||
|
|
// Helper to emit events
|
||
|
|
const emit = useCallback((event: string, data?: any) => {
|
||
|
|
if (socket && isConnected) {
|
||
|
|
socket.emit(event, data);
|
||
|
|
} else {
|
||
|
|
console.warn(`Cannot emit ${event}: socket not connected`);
|
||
|
|
}
|
||
|
|
}, [socket, isConnected]);
|
||
|
|
|
||
|
|
// Helper to listen to events
|
||
|
|
const on = useCallback(<K extends keyof DraftSocketEvents>(
|
||
|
|
event: K,
|
||
|
|
handler: DraftSocketEvents[K]
|
||
|
|
) => {
|
||
|
|
if (socket) {
|
||
|
|
socket.on(event as string, handler as any);
|
||
|
|
}
|
||
|
|
}, [socket]);
|
||
|
|
|
||
|
|
// Helper to remove event listeners
|
||
|
|
const off = useCallback(<K extends keyof DraftSocketEvents>(
|
||
|
|
event: K,
|
||
|
|
handler?: DraftSocketEvents[K]
|
||
|
|
) => {
|
||
|
|
if (socket) {
|
||
|
|
if (handler) {
|
||
|
|
socket.off(event as string, handler as any);
|
||
|
|
} else {
|
||
|
|
socket.off(event as string);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}, [socket]);
|
||
|
|
|
||
|
|
return {
|
||
|
|
socket,
|
||
|
|
isConnected,
|
||
|
|
emit,
|
||
|
|
on,
|
||
|
|
off,
|
||
|
|
};
|
||
|
|
}
|