/**
* useSocketSubscriptions
* アプリ共通で必要なソケット購読を登録するフック
* 接続,ルーム更新,ゲーム開始の購読と解除を一元化する
*/
import { useEffect } from "react";
import { socketManager } from "@client/network/SocketManager";
import { domain } from "@repo/shared";
import type { GameResultPayload } from "@repo/shared";
import type { AppFlowAction } from "./types/appFlowState";
type UseSocketSubscriptionsParams = {
completeJoinRequest: () => void;
dispatchAppFlow: (action: AppFlowAction) => void;
};
type AppSocketHandlers = {
handleConnect: (id: string) => void;
handleRoomUpdate: (updatedRoom: domain.room.Room) => void;
handleGameStart: () => void;
handleGameResult: (payload: GameResultPayload) => void;
};
const registerConnectionSubscriptions = ({
handleConnect,
}: AppSocketHandlers): void => {
socketManager.common.onConnect(handleConnect);
};
const unregisterConnectionSubscriptions = ({
handleConnect,
}: AppSocketHandlers): void => {
socketManager.common.offConnect(handleConnect);
};
const registerRoomSubscriptions = ({
handleRoomUpdate,
}: AppSocketHandlers): void => {
socketManager.lobby.onRoomUpdate(handleRoomUpdate);
};
const unregisterRoomSubscriptions = ({
handleRoomUpdate,
}: AppSocketHandlers): void => {
socketManager.lobby.offRoomUpdate(handleRoomUpdate);
};
const registerGameSubscriptions = ({
handleGameStart,
handleGameResult,
}: AppSocketHandlers): void => {
socketManager.game.onGameStart(handleGameStart);
socketManager.game.onGameResult(handleGameResult);
};
const unregisterGameSubscriptions = ({
handleGameStart,
handleGameResult,
}: AppSocketHandlers): void => {
socketManager.game.offGameStart(handleGameStart);
socketManager.game.offGameResult(handleGameResult);
};
/** アプリ共通のソケット購読を登録しクリーンアップするフック */
export const useSocketSubscriptions = ({
completeJoinRequest,
dispatchAppFlow,
}: UseSocketSubscriptionsParams): void => {
useEffect(() => {
const handlers: AppSocketHandlers = {
handleConnect: (id: string) => {
dispatchAppFlow({ type: "setMyId", myId: id });
},
handleRoomUpdate: (updatedRoom: domain.room.Room) => {
completeJoinRequest();
dispatchAppFlow({ type: "setRoomAndLobby", room: updatedRoom });
},
handleGameStart: () => {
dispatchAppFlow({ type: "setPlaying" });
},
handleGameResult: (payload: GameResultPayload) => {
dispatchAppFlow({ type: "setResult", result: payload });
},
};
registerConnectionSubscriptions(handlers);
registerRoomSubscriptions(handlers);
registerGameSubscriptions(handlers);
return () => {
completeJoinRequest();
unregisterConnectionSubscriptions(handlers);
unregisterRoomSubscriptions(handlers);
unregisterGameSubscriptions(handlers);
};
}, [completeJoinRequest, dispatchAppFlow]);
};