fix: per-socket state with drawer-only wordChoices to prevent race on lobby→play nav
This commit is contained in:
+15
-1
@@ -59,7 +59,8 @@ function makeRoom({ code, hostId, mode, settings }) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function publicRoomState(room) {
|
function publicRoomState(room, viewerId) {
|
||||||
|
const isViewerDrawer = !!(viewerId && room.skribbl && room.skribbl.drawerId === viewerId);
|
||||||
return {
|
return {
|
||||||
code: room.code,
|
code: room.code,
|
||||||
hostId: room.hostId,
|
hostId: room.hostId,
|
||||||
@@ -84,6 +85,19 @@ function publicRoomState(room) {
|
|||||||
phase: room.skribbl.phase, // 'choosing' | 'drawing' | 'between'
|
phase: room.skribbl.phase, // 'choosing' | 'drawing' | 'between'
|
||||||
endsAt: room.skribbl.endsAt,
|
endsAt: room.skribbl.endsAt,
|
||||||
solvedIds: [...(room.skribbl.solvedIds || [])],
|
solvedIds: [...(room.skribbl.solvedIds || [])],
|
||||||
|
// Drawer-only: surface current word choices in the snapshot so a
|
||||||
|
// late-mounted play page (after lobby→/play navigation) can render
|
||||||
|
// the pick modal even if the original skribbl:wordChoices event
|
||||||
|
// was emitted before the listener was attached.
|
||||||
|
wordChoices:
|
||||||
|
isViewerDrawer && room.skribbl.phase === "choosing"
|
||||||
|
? room.skribbl.wordChoices
|
||||||
|
: null,
|
||||||
|
// Drawer-only: reveal the actual word so they know what to draw.
|
||||||
|
word:
|
||||||
|
isViewerDrawer && room.skribbl.phase === "drawing"
|
||||||
|
? room.skribbl.word
|
||||||
|
: null,
|
||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
gartic: room.gartic
|
gartic: room.gartic
|
||||||
|
|||||||
@@ -10,7 +10,15 @@ function escape(text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function broadcastState(io, room) {
|
function broadcastState(io, room) {
|
||||||
io.to(room.code).emit("room:state", G.publicRoomState(room));
|
// Per-socket emission so we can include drawer-only data
|
||||||
|
// (wordChoices during choosing, secret word during drawing) in the
|
||||||
|
// snapshot of the right viewer without leaking it to others.
|
||||||
|
for (const player of room.players) {
|
||||||
|
if (!player.socketId) continue;
|
||||||
|
const sock = io.sockets.sockets.get(player.socketId);
|
||||||
|
if (!sock) continue;
|
||||||
|
sock.emit("room:state", G.publicRoomState(room, player.id));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function chatSystem(io, room, text) {
|
function chatSystem(io, room, text) {
|
||||||
|
|||||||
Reference in New Issue
Block a user