From 062510b6c6ecd5bd2a66dd4a4bac46a23721e525 Mon Sep 17 00:00:00 2001 From: Jan Willem Mannaerts Date: Tue, 3 Mar 2026 14:08:37 +0100 Subject: [PATCH] Fix poker:leave regression: move leave emit from PokerRoom to Room level poker:leave was firing on every issue advance (PokerRoom unmount), causing a race condition where participants were briefly removed and revealIfComplete triggered after just 1 vote. Now poker:leave only emits when the user truly leaves the room (Room component unmounts). Co-Authored-By: Claude Opus 4.6 --- frontend/src/components/PokerRoom.jsx | 1 - frontend/src/components/Room.jsx | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/PokerRoom.jsx b/frontend/src/components/PokerRoom.jsx index c3d7070..c3586a2 100644 --- a/frontend/src/components/PokerRoom.jsx +++ b/frontend/src/components/PokerRoom.jsx @@ -80,7 +80,6 @@ export default function PokerRoom({ session, issue, user, onSaved }) { } return () => { - socket.emit('poker:leave', { sessionId: session.id }); socket.off('poker:participants', onParticipants); socket.off('poker:vote-update', onVoteUpdate); socket.off('poker:revealed', onRevealed); diff --git a/frontend/src/components/Room.jsx b/frontend/src/components/Room.jsx index 5c38303..15bcc9f 100644 --- a/frontend/src/components/Room.jsx +++ b/frontend/src/components/Room.jsx @@ -1,5 +1,6 @@ -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { api } from '../services/api'; +import { getSocket } from '../services/socket'; import PokerRoom from './PokerRoom'; import DarkModeToggle from './DarkModeToggle'; import AdfRenderer from './AdfRenderer'; @@ -13,6 +14,18 @@ export default function Room({ room, user, dark, toggleDark, onBack }) { const issuesRef = useRef([]); const pokerUser = { key: user.jiraAccountId, name: user.displayName }; + const socket = useMemo(() => getSocket(), []); + const activeSessionIdRef = useRef(null); + + // Emit poker:leave when the Room unmounts (user truly leaves the room) + useEffect(() => { + return () => { + const sessionId = activeSessionIdRef.current; + if (sessionId) { + socket.emit('poker:leave', { sessionId }); + } + }; + }, [socket]); useEffect(() => { loadIssues(); @@ -69,6 +82,7 @@ export default function Room({ room, user, dark, toggleDark, onBack }) { const activeSessionRef = useRef(null); activeSessionRef.current = activeSession; + activeSessionIdRef.current = activeSession?.session?.id || null; const advanceToNext = useCallback((estimate) => { if (!activeSessionRef.current) return;