- Moved all login, session UI, mode selection, and matchmaking logic from TicTacToe.tsx into Player.tsx. - Added onMatchDataCallback prop support for Player component. - Cleaned up TicTacToe.tsx by removing duplicated login/matchmaking UI and connect logic. - Improved auto-connect on mount via Player.tsx.
96 lines
2.2 KiB
TypeScript
96 lines
2.2 KiB
TypeScript
import { useState, useEffect } from "react";
|
|
import { useNakama } from "./providers/NakamaProvider";
|
|
import Board from "./Board";
|
|
import Player from "./Player";
|
|
// import { Match } from "@heroiclabs/nakama-js";
|
|
// import MatchList from "./MatchList";
|
|
|
|
export default function TicTacToe() {
|
|
const [board, setBoard] = useState<string[][]>([
|
|
["", "", ""],
|
|
["", "", ""],
|
|
["", "", ""]
|
|
]);
|
|
const [turn, setTurn] = useState<number>(0);
|
|
const [winner, setWinner] = useState<string | null>(null);
|
|
// const [openMatches, setOpenMatches] = useState<Match[]>([]);
|
|
const [players, setPlayers] = useState<string[]>([]);
|
|
|
|
function onMatchDataCallback(msg: { opCode: number; data: any }) {
|
|
console.log("[Match Data]", msg);
|
|
|
|
if (msg.opCode === 2) {
|
|
const state = msg.data;
|
|
console.log("Match state:", state);
|
|
|
|
setBoard(state.board);
|
|
setTurn(state.turn);
|
|
setWinner(state.winner || null);
|
|
|
|
// new:
|
|
setPlayers(state.players || []);
|
|
}
|
|
}
|
|
|
|
const {
|
|
onMatchData,
|
|
sendMatchData,
|
|
// listOpenMatches,
|
|
matchId,
|
|
session,
|
|
} = useNakama();
|
|
|
|
useEffect(() => {
|
|
onMatchData(onMatchDataCallback);
|
|
}, [onMatchData]);
|
|
|
|
// useEffect(() => {
|
|
// let active = true;
|
|
//
|
|
// async function refreshLoop() {
|
|
// while (active) {
|
|
// const matches = await listOpenMatches();
|
|
// setOpenMatches(matches);
|
|
//
|
|
// await new Promise(res => setTimeout(res, 500)); // 0.5s refresh
|
|
// }
|
|
// }
|
|
//
|
|
// refreshLoop();
|
|
//
|
|
// return () => {
|
|
// active = false;
|
|
// };
|
|
// }, [listOpenMatches]);
|
|
|
|
// ------------------------------------------
|
|
// SEND A MOVE
|
|
// ------------------------------------------
|
|
function handleCellClick(row: number, col: number) {
|
|
if (!matchId) return;
|
|
|
|
sendMatchData(matchId, 1, { row, col }); // OpMove=1
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<h1>Tic Tac Toe Multiplayer</h1>
|
|
|
|
<Player
|
|
onMatchDataCallback={onMatchDataCallback}
|
|
/>
|
|
|
|
{matchId && (
|
|
<Board
|
|
board={board}
|
|
turn={turn}
|
|
winner={winner}
|
|
players={players}
|
|
myUserId={session?.user_id ?? null}
|
|
onCellClick={handleCellClick}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|