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)",