Files
Tarokka/hooks/useSocket.ts
2025-06-23 15:33:04 -04:00

124 lines
3.0 KiB
TypeScript

import { useEffect, useRef, useState } from 'react';
import { socket } from '@/socket';
import type { GameUpdate } from '@/types';
export interface UseSocketProps {
gameID: string;
setGameData: (gameUpdate: GameUpdate) => void;
setNoGame: (noGame: boolean) => void;
}
export interface UseSocket {
ready: boolean;
flipCard: (cardIndex: number) => void;
handleSettings: (cardData: GameUpdate) => void;
redraw: (cardIndex: number) => void;
rtcAnswer: (answer: RTCSessionDescriptionInit) => void;
registerAnsweredReceiver: (receiver: (answer: RTCSessionDescriptionInit) => void) => void;
rtcOffer: (offer: RTCSessionDescriptionInit) => void;
registerOfferredReceiver: (receiver: (offer: RTCSessionDescriptionInit) => void) => void;
select: (cardIndex: number, cardID: string) => void;
}
export default function useSocket({ gameID, setGameData, setNoGame }: UseSocketProps): UseSocket {
const [ready, setReady] = useState(false);
const answerRef = useRef<(answer: RTCSessionDescriptionInit) => void>(null);
const offerRef = useRef<(offer: RTCSessionDescriptionInit) => void>(null);
useEffect(() => {
if (gameID) {
socket.emit('join', gameID);
socket.on('init', (data: GameUpdate) => {
setReady(true);
setGameData(data);
});
socket.on('game-update', (data: GameUpdate) => {
setGameData(data);
});
socket.on('join-error', (error) => {
console.error('Error:', error);
setNoGame(true);
});
socket.on('flip-error', (error) => {
console.error('Error:', error);
});
socket.on('rtc-answered', (answered: RTCSessionDescriptionInit) => {
if (answerRef.current) answerRef.current(answered);
});
socket.on('rtc-offered', (offered: RTCSessionDescriptionInit) => {
if (offerRef.current) {
offerRef.current(offered);
}
});
}
return () => {
socket.removeAllListeners();
};
}, [gameID]);
const flipCard = (cardIndex: number) => {
console.log('flip-card', {
gameID,
cardIndex,
});
socket.emit('flip-card', {
gameID,
cardIndex,
});
};
const handleSettings = (gameData: GameUpdate) => {
socket.emit('settings', {
gameID,
gameData,
});
};
const redraw = (cardIndex: number) => {
socket.emit('redraw', {
gameID,
cardIndex,
});
};
const rtcAnswer = (answer: RTCSessionDescriptionInit) => {
console.log('rtc-answer', { gameID, answer });
socket.emit('rtc-answer', { gameID, answer });
};
const rtcOffer = (offer: RTCSessionDescriptionInit) => {
console.log('rtc-offer', { gameID, offer });
socket.emit('rtc-offer', { gameID, offer });
};
const select = (cardIndex: number, cardID: string) => {
socket.emit('select', {
gameID,
cardIndex,
cardID,
});
};
return {
ready,
flipCard,
handleSettings,
redraw,
rtcAnswer,
registerAnsweredReceiver: (receiver: (obj: RTCSessionDescriptionInit) => void[]) =>
(answerRef.current = receiver),
rtcOffer,
registerOfferredReceiver: (receiver: (obj: RTCSessionDescriptionInit) => void[]) =>
(offerRef.current = receiver),
select,
};
}