diff --git a/backend/src/index.js b/backend/src/index.js index 3736d98..c17429d 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -343,6 +343,28 @@ io.on('connection', (socket) => { } }); + throttled('poker:kick', async ({ sessionId, userKey }) => { + try { + if (!sessionId || !userKey) { + socket.emit('poker:error', { error: 'sessionId and userKey are required.' }); + return; + } + if (!await canAccessSession(sessionId, socket.user.jiraCloudId)) { + socket.emit('poker:error', { error: 'Session not found.' }); + return; + } + await leaveSession({ + sessionId, + tenantCloudId: socket.user.jiraCloudId, + userKey + }); + await emitSessionState(sessionId, socket.user.jiraCloudId); + } catch (error) { + console.error('[socket] poker:kick failed:', error); + socket.emit('poker:error', { error: safeError(error) }); + } + }); + throttled('poker:leave', async ({ sessionId }) => { try { if (!sessionId) return; diff --git a/frontend/src/components/PokerRoom.jsx b/frontend/src/components/PokerRoom.jsx index ea095c5..c3d7070 100644 --- a/frontend/src/components/PokerRoom.jsx +++ b/frontend/src/components/PokerRoom.jsx @@ -80,6 +80,7 @@ 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); @@ -98,6 +99,10 @@ export default function PokerRoom({ session, issue, user, onSaved }) { }); } + function handleKick(userKey) { + socket.emit('poker:kick', { sessionId: session.id, userKey }); + } + function handleSave() { const estimate = Number(manualEstimate || suggestedEstimate); if (!Number.isFinite(estimate)) { @@ -229,13 +234,24 @@ export default function PokerRoom({ session, issue, user, onSaved }) { {isCurrentUser && (you)} -
- {revealed && vote !== null && vote !== undefined ? ( - {vote} - ) : hasVoted ? ( - - ) : ( - ... +
+ + {revealed && vote !== null && vote !== undefined ? ( + {vote} + ) : hasVoted ? ( + + ) : ( + ... + )} + + {!isCurrentUser && ( + )}