Phase 2: async play-by-turn — the games ledger and turn signals
The lobby is now the front door to all your games. A "your games" ledger lists every seat this browser holds — room code, whose turn it is (including counteraction/discard/interrupt waits, which count as your turn), the round, and how long since the last move — with one-click resume, a forget control, and a green highlight when a game waits on you. The server answers a token-validated myGames query with per-seat summaries; the client polls every 45 seconds, so turns in other rooms reach you wherever you are. Turn signals travel three ways: the tab title flips to "● Your turn", the favicon grows a green dot, and — opt-in via "notify me on my turn" — a browser notification fires when a turn becomes yours anywhere. Landing in the app now shows the ledger rather than teleporting into the last game; mid-game socket drops still walk straight back to the table. Verified live: two seeded games, ledger showing "gandalf's turn" and YOUR TURN, one-click resume into the correct game with history. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
7cfffb8ab5
commit
bc8013863b
@@ -21,6 +21,7 @@ import {
|
||||
redactFor,
|
||||
runCommand,
|
||||
startGame,
|
||||
summarize,
|
||||
viewForPlayer,
|
||||
type Room,
|
||||
} from "./rooms";
|
||||
@@ -130,6 +131,20 @@ wss.on("connection", (socket) => {
|
||||
broadcast(room, (playerId) => ({ type: "state", view: viewForPlayer(room, playerId) }));
|
||||
break;
|
||||
}
|
||||
case "myGames": {
|
||||
// {seats: [{roomId, name, token}]} -> summaries for valid seats.
|
||||
const seats = Array.isArray(msg.seats) ? msg.seats : [];
|
||||
const games = [];
|
||||
for (const seat of seats) {
|
||||
const room = getRoom(String(seat.roomId ?? ""));
|
||||
if (!room) continue;
|
||||
const name = String(seat.name ?? "");
|
||||
if (room.tokens.get(name) !== seat.token) continue;
|
||||
games.push(summarize(room, name));
|
||||
}
|
||||
send(socket, { type: "games", games });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
send(socket, { type: "error", message: `unknown message type: ${String(msg.type)}` });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user