Add kick player and leave game functionality
- Host can kick players from lobby (removes from game, clears presenter if needed) - Client can voluntarily leave game - Fix browser-compatible base64 decoding for document upload (atob vs Buffer)
This commit is contained in:
parent
3122748bae
commit
79820f5298
7 changed files with 1640 additions and 10 deletions
|
|
@ -1446,6 +1446,31 @@ export const useGame = () => {
|
|||
if (data.type === 'PRESENTER_CHANGED') {
|
||||
setPresenterId(data.payload.presenterId);
|
||||
}
|
||||
|
||||
if (data.type === 'KICKED') {
|
||||
if (hostConnectionRef.current) {
|
||||
hostConnectionRef.current.close();
|
||||
hostConnectionRef.current = null;
|
||||
}
|
||||
if (peerRef.current) {
|
||||
peerRef.current.destroy();
|
||||
peerRef.current = null;
|
||||
}
|
||||
clearStoredSession();
|
||||
if (timerRef.current) clearInterval(timerRef.current);
|
||||
setError(data.payload.reason || 'You were kicked from the game');
|
||||
setGamePin(null);
|
||||
setQuiz(null);
|
||||
setPlayers([]);
|
||||
setCurrentPlayerId(null);
|
||||
setCurrentPlayerName(null);
|
||||
setGameState('LANDING');
|
||||
navigate('/', { replace: true });
|
||||
}
|
||||
|
||||
if (data.type === 'PLAYER_LEFT') {
|
||||
setPlayers(prev => prev.filter(p => p.id !== data.payload.playerId));
|
||||
}
|
||||
};
|
||||
|
||||
const handleAnswer = (arg: boolean | AnswerOption) => {
|
||||
|
|
@ -1535,6 +1560,54 @@ export const useGame = () => {
|
|||
broadcast({ type: 'PRESENTER_CHANGED', payload: { presenterId: playerId } });
|
||||
};
|
||||
|
||||
const kickPlayer = (playerId: string) => {
|
||||
if (role !== 'HOST') return;
|
||||
if (playerId === 'host') return;
|
||||
|
||||
const conn = connectionsRef.current.get(playerId);
|
||||
if (conn?.open) {
|
||||
conn.send({ type: 'KICKED', payload: { reason: 'You were kicked by the host' } });
|
||||
conn.close();
|
||||
}
|
||||
connectionsRef.current.delete(playerId);
|
||||
|
||||
const updatedPlayers = playersRef.current.filter(p => p.id !== playerId);
|
||||
playersRef.current = updatedPlayers;
|
||||
setPlayers(updatedPlayers);
|
||||
|
||||
if (presenterIdRef.current === playerId) {
|
||||
setPresenterId(null);
|
||||
broadcast({ type: 'PRESENTER_CHANGED', payload: { presenterId: null } });
|
||||
}
|
||||
|
||||
broadcast({ type: 'PLAYER_LEFT', payload: { playerId } });
|
||||
};
|
||||
|
||||
const leaveGame = () => {
|
||||
if (role !== 'CLIENT') return;
|
||||
|
||||
if (hostConnectionRef.current?.open) {
|
||||
hostConnectionRef.current.close();
|
||||
}
|
||||
hostConnectionRef.current = null;
|
||||
|
||||
if (peerRef.current) {
|
||||
peerRef.current.destroy();
|
||||
peerRef.current = null;
|
||||
}
|
||||
|
||||
clearStoredSession();
|
||||
if (timerRef.current) clearInterval(timerRef.current);
|
||||
|
||||
setGamePin(null);
|
||||
setQuiz(null);
|
||||
setPlayers([]);
|
||||
setCurrentPlayerId(null);
|
||||
setCurrentPlayerName(null);
|
||||
setGameState('LANDING');
|
||||
navigate('/', { replace: true });
|
||||
};
|
||||
|
||||
const sendAdvance = (action: 'START' | 'NEXT' | 'SCOREBOARD') => {
|
||||
if (role !== 'CLIENT' || !hostConnectionRef.current) return;
|
||||
hostConnectionRef.current.send({ type: 'ADVANCE', payload: { action } });
|
||||
|
|
@ -1544,6 +1617,6 @@ export const useGame = () => {
|
|||
role, gameState, quiz, players, currentQuestionIndex, timeLeft, error, gamePin, hasAnswered, lastPointsEarned, lastAnswerCorrect, currentCorrectShape, selectedOption, currentPlayerScore, currentStreak, currentPlayerId, gameConfig,
|
||||
pendingQuizToSave, dismissSavePrompt, sourceQuizId, isReconnecting, currentPlayerName, presenterId,
|
||||
startQuizGen, startManualCreation, cancelCreation, finalizeManualQuiz, loadSavedQuiz, joinGame, startGame: startHostGame, handleAnswer, nextQuestion, showScoreboard,
|
||||
updateQuizFromEditor, startGameFromEditor, backFromEditor, endGame, attemptReconnect, goHomeFromDisconnected, resumeGame, setPresenterPlayer, sendAdvance
|
||||
updateQuizFromEditor, startGameFromEditor, backFromEditor, endGame, attemptReconnect, goHomeFromDisconnected, resumeGame, setPresenterPlayer, sendAdvance, kickPlayer, leaveGame
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue