diff --git a/apps/client/src/app.tsx b/apps/client/src/app.tsx index 8b37e31..b3d47a2 100644 --- a/apps/client/src/app.tsx +++ b/apps/client/src/app.tsx @@ -16,8 +16,10 @@ room, myId, gameResult, + playerName, joinErrorMessage, isJoining, + setPlayerName, requestJoin, returnToTitle, } = useAppFlow(); @@ -29,6 +31,8 @@ scene = ( diff --git a/apps/client/src/hooks/application/appFlowReducer.ts b/apps/client/src/hooks/application/appFlowReducer.ts index d9e4478..9d2f46b 100644 --- a/apps/client/src/hooks/application/appFlowReducer.ts +++ b/apps/client/src/hooks/application/appFlowReducer.ts @@ -12,6 +12,7 @@ room: null, myId: null, gameResult: null, + playerName: "", }; /** アプリフロー状態をアクションに応じて更新する */ @@ -26,6 +27,13 @@ }; } + if (action.type === "setPlayerName") { + return { + ...state, + playerName: action.playerName, + }; + } + if (action.type === "setRoomAndLobby") { return { ...state, @@ -56,6 +64,7 @@ room: null, myId: action.clearMyId ? null : state.myId, gameResult: null, + playerName: state.playerName, }; } diff --git a/apps/client/src/hooks/types/appFlowState.ts b/apps/client/src/hooks/types/appFlowState.ts index 16d3356..1901239 100644 --- a/apps/client/src/hooks/types/appFlowState.ts +++ b/apps/client/src/hooks/types/appFlowState.ts @@ -12,11 +12,13 @@ room: domain.room.Room | null; myId: string | null; gameResult: GameResultPayload | null; + playerName: string; }; /** アプリフローを更新するアクション型 */ export type AppFlowAction = | { type: "setMyId"; myId: string | null } + | { type: "setPlayerName"; playerName: string } | { type: "setRoomAndLobby"; room: domain.room.Room } | { type: "setPlaying" } | { type: "setResult"; result: GameResultPayload } diff --git a/apps/client/src/hooks/useAppFlow.ts b/apps/client/src/hooks/useAppFlow.ts index b90b523..cc81f24 100644 --- a/apps/client/src/hooks/useAppFlow.ts +++ b/apps/client/src/hooks/useAppFlow.ts @@ -20,8 +20,10 @@ room: domain.room.Room | null; myId: string | null; gameResult: GameResultPayload | null; + playerName: string; joinErrorMessage: string | null; isJoining: boolean; + setPlayerName: (name: string) => void; requestJoin: (payload: domain.room.JoinRoomPayload) => void; returnToTitle: (options?: { leaveRoom?: boolean }) => void; }; @@ -38,6 +40,7 @@ type JoinFailure = { reason: JoinFailureReason; roomId?: string; + playerName?: string; }; type JoinAction = @@ -144,6 +147,7 @@ completeJoinRequest({ reason: payload.reason, roomId: payload.roomId, + playerName: payload.playerName, }); }; @@ -155,10 +159,21 @@ }, config.GAME_CONFIG.JOIN_REQUEST_TIMEOUT_MS); socketManager.title.joinRoom(payload); + + if (payload.playerName.trim() !== "") { + dispatchAppFlow({ + type: "setPlayerName", + playerName: payload.playerName, + }); + } }, [completeJoinRequest, joinState.isJoining], ); + const setPlayerName = useCallback((name: string) => { + dispatchAppFlow({ type: "setPlayerName", playerName: name }); + }, []); + const returnToTitle = useCallback( (options?: { leaveRoom?: boolean }) => { completeJoinRequest(); @@ -187,8 +202,10 @@ room: appFlow.room, myId: appFlow.myId, gameResult: appFlow.gameResult, + playerName: appFlow.playerName, joinErrorMessage: getJoinErrorMessage(joinState.joinFailure), isJoining: joinState.isJoining, + setPlayerName, requestJoin, returnToTitle, }; diff --git a/apps/client/src/scenes/title/TitleScene.tsx b/apps/client/src/scenes/title/TitleScene.tsx index ac9c199..53f2cce 100644 --- a/apps/client/src/scenes/title/TitleScene.tsx +++ b/apps/client/src/scenes/title/TitleScene.tsx @@ -5,18 +5,26 @@ type Props = { // 入室実行時呼び出しコールバック onJoin: (payload: domain.room.JoinRoomPayload) => void; + // プレイヤー名の入力値 + playerName: string; + // プレイヤー名の更新コールバック + onPlayerNameChange: (value: string) => void; // 入室失敗時の表示メッセージ joinErrorMessage: string | null; // 入室リクエスト送信中フラグ isJoining: boolean; }; -export const TitleScene = ({ onJoin, joinErrorMessage, isJoining }: Props) => { +export const TitleScene = ({ + onJoin, + playerName, + onPlayerNameChange, + joinErrorMessage, + isJoining, +}: Props) => { // 🌟 追加:「TAP TO START」が押されてフォームを表示する状態かどうか const [showForm, setShowForm] = useState(false); - // プレイヤー名入力値 - const [playerName, setPlayerName] = useState(""); // ルームID入力値 const [roomIdInput, setRoomIdInput] = useState(""); @@ -112,7 +120,7 @@ setPlayerName(e.target.value)} + onChange={(e) => onPlayerNameChange(e.target.value)} style={{ padding: "12px", fontSize: "clamp(1rem, 3vw, 1.2rem)",