Fix host disconnect
This commit is contained in:
parent
2b3be6569f
commit
5d3c6320d9
2 changed files with 27 additions and 15 deletions
|
|
@ -129,6 +129,7 @@ export const useGame = (defaultGameConfig?: GameConfig) => {
|
|||
const [hostSecret, setHostSecret] = useState<string | null>(null);
|
||||
const [isReconnecting, setIsReconnecting] = useState(false);
|
||||
const [presenterId, setPresenterId] = useState<string | null>(null);
|
||||
const [connectedPlayerIds, setConnectedPlayerIds] = useState<string[]>([]);
|
||||
|
||||
const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||
const syncTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||
|
|
@ -213,11 +214,19 @@ export const useGame = (defaultGameConfig?: GameConfig) => {
|
|||
return null;
|
||||
}
|
||||
|
||||
// Don't redirect away from game URLs during initial load - let initializeFromUrl handle it
|
||||
const isGameUrl = /^\/host\/[A-Z0-9]+$/i.test(location.pathname) ||
|
||||
/^\/play\/[A-Z0-9]+$/i.test(location.pathname);
|
||||
|
||||
switch (gameState) {
|
||||
case 'LANDING':
|
||||
if (gamePin && location.pathname.startsWith('/play/')) {
|
||||
return `/play/${gamePin}`;
|
||||
}
|
||||
// Don't navigate away from game URLs if we're in LANDING state (might be reconnecting)
|
||||
if (isGameUrl) {
|
||||
return null;
|
||||
}
|
||||
return '/';
|
||||
case 'CREATING':
|
||||
case 'GENERATING':
|
||||
|
|
@ -236,6 +245,10 @@ export const useGame = (defaultGameConfig?: GameConfig) => {
|
|||
}
|
||||
return '/';
|
||||
case 'DISCONNECTED':
|
||||
if (gamePin) {
|
||||
return role === 'HOST' ? `/host/${gamePin}` : `/play/${gamePin}`;
|
||||
}
|
||||
return '/';
|
||||
case 'WAITING_TO_REJOIN':
|
||||
if (gamePin) {
|
||||
return `/play/${gamePin}`;
|
||||
|
|
@ -411,6 +424,7 @@ export const useGame = (defaultGameConfig?: GameConfig) => {
|
|||
});
|
||||
conn.on('close', () => {
|
||||
connectionsRef.current.delete(conn.peer);
|
||||
setConnectedPlayerIds(prev => prev.filter(id => id !== conn.peer));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -504,6 +518,7 @@ export const useGame = (defaultGameConfig?: GameConfig) => {
|
|||
setGamePin(session.pin);
|
||||
setGameState('DISCONNECTED'); // Show loading state on disconnected screen
|
||||
setCurrentPlayerName("Host");
|
||||
setConnectedPlayerIds([]); // Reset connected players - they will reconnect
|
||||
|
||||
const hostData = await fetchHostSession(session.pin, session.hostSecret);
|
||||
|
||||
|
|
@ -546,24 +561,15 @@ export const useGame = (defaultGameConfig?: GameConfig) => {
|
|||
|
||||
// Determine which state to restore to
|
||||
const savedState = hostData.gameState;
|
||||
const restoredPlayers = hostData.players || [];
|
||||
const allAnswered = restoredPlayers.length > 0 && restoredPlayers.every((p: Player) => p.lastAnswerCorrect !== null);
|
||||
|
||||
if (savedState === 'LOBBY') {
|
||||
setGameState('LOBBY');
|
||||
} else if (savedState === 'PODIUM') {
|
||||
setGameState('PODIUM');
|
||||
} else if (savedState === 'REVEAL') {
|
||||
// Go directly to reveal screen - players may have already seen their results
|
||||
setGameState('REVEAL');
|
||||
} else if (savedState === 'SCOREBOARD') {
|
||||
// Go directly to scoreboard
|
||||
setGameState('SCOREBOARD');
|
||||
} else if (savedState === 'QUESTION' && allAnswered) {
|
||||
// All players answered while host was disconnected - go directly to reveal
|
||||
setGameState('REVEAL');
|
||||
} else {
|
||||
// For QUESTION or COUNTDOWN states where not everyone answered, show HOST_RECONNECTED to let them resume
|
||||
// For all mid-game states (QUESTION, COUNTDOWN, REVEAL, SCOREBOARD),
|
||||
// show HOST_RECONNECTED first so host can wait for players to reconnect
|
||||
// and then choose when to resume
|
||||
setGameState('HOST_RECONNECTED');
|
||||
}
|
||||
|
||||
|
|
@ -853,6 +859,7 @@ export const useGame = (defaultGameConfig?: GameConfig) => {
|
|||
const payload = data.payload as { name: string; reconnect?: boolean; previousId?: string };
|
||||
|
||||
connectionsRef.current.set(conn.peer, conn);
|
||||
setConnectedPlayerIds(prev => prev.includes(conn.peer) ? prev : [...prev, conn.peer]);
|
||||
|
||||
const existingByPreviousId = payload.previousId ? playersRef.current.find(p => p.id === payload.previousId) : null;
|
||||
const existingByName = playersRef.current.find(p => p.name === payload.name && p.id !== 'host');
|
||||
|
|
@ -899,6 +906,8 @@ export const useGame = (defaultGameConfig?: GameConfig) => {
|
|||
updatedPlayers = playersRef.current.map(p => p.id === reconnectedPlayer.id ? { ...p, id: conn.peer } : p);
|
||||
setPlayers(updatedPlayers);
|
||||
assignedName = reconnectedPlayer.name;
|
||||
// Update connected player IDs - remove old ID, new ID already added above
|
||||
setConnectedPlayerIds(prev => prev.filter(id => id !== reconnectedPlayer.id));
|
||||
if (presenterIdRef.current === reconnectedPlayer.id) {
|
||||
setPresenterId(conn.peer);
|
||||
}
|
||||
|
|
@ -1052,6 +1061,7 @@ export const useGame = (defaultGameConfig?: GameConfig) => {
|
|||
playersRef.current = updatedPlayers;
|
||||
setPlayers(updatedPlayers);
|
||||
connectionsRef.current.delete(playerId);
|
||||
setConnectedPlayerIds(prev => prev.filter(id => id !== playerId));
|
||||
|
||||
if (presenterIdRef.current === playerId) {
|
||||
const realPlayers = updatedPlayers.filter(p => p.id !== 'host');
|
||||
|
|
@ -1718,7 +1728,7 @@ export const useGame = (defaultGameConfig?: GameConfig) => {
|
|||
|
||||
return {
|
||||
role, gameState, quiz, players, currentQuestionIndex, timeLeft, error, gamePin, hasAnswered, lastPointsEarned, lastAnswerCorrect, currentCorrectShape, selectedOption, currentPlayerScore, currentStreak, currentPlayerId, gameConfig,
|
||||
pendingQuizToSave, dismissSavePrompt, sourceQuizId, isReconnecting, currentPlayerName, presenterId,
|
||||
pendingQuizToSave, dismissSavePrompt, sourceQuizId, isReconnecting, currentPlayerName, presenterId, connectedPlayerIds,
|
||||
startQuizGen, startManualCreation, cancelCreation, finalizeManualQuiz, loadSavedQuiz, joinGame, startGame: startHostGame, handleAnswer, nextQuestion, showScoreboard,
|
||||
updateQuizFromEditor, startGameFromEditor, backFromEditor, endGame, attemptReconnect, goHomeFromDisconnected, resumeGame, setPresenterPlayer, sendAdvance, kickPlayer, leaveGame
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue