fix: Picker WebSocket auth, event handling, and status display

- Authenticate with JWT before subscribing to session events
- Use message.type instead of message.event (matches server format)
- Handle all new shard monitor events (room.connected, lobby.*,
  game.started, game.ended, room.disconnected)
- Replace never-set 'waiting' status with 'monitoring'
- Show monitoring indicator with live player count

Made-with: Cursor
This commit is contained in:
cottongin
2026-03-20 11:47:19 -04:00
parent 336ba0e608
commit 65036a4e1b

View File

@@ -8,7 +8,7 @@ import { formatLocalTime } from '../utils/dateUtils';
import PopularityBadge from '../components/PopularityBadge';
function Picker() {
const { isAuthenticated, loading: authLoading } = useAuth();
const { isAuthenticated, loading: authLoading, token } = useAuth();
const navigate = useNavigate();
const [activeSession, setActiveSession] = useState(null);
@@ -977,8 +977,10 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame })
return () => clearInterval(interval);
}, [loadGames]);
// Setup WebSocket connection for real-time player count updates
// Setup WebSocket connection for real-time session updates
useEffect(() => {
if (!token) return;
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsUrl = `${protocol}//${window.location.hostname}:${window.location.port || (window.location.protocol === 'https:' ? 443 : 80)}/api/sessions/live`;
@@ -986,22 +988,33 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame })
const ws = new WebSocket(wsUrl);
ws.onopen = () => {
console.log('[WebSocket] Connected for player count updates');
// Subscribe to session events
ws.send(JSON.stringify({
type: 'subscribe',
sessionId: parseInt(sessionId)
}));
console.log('[WebSocket] Connected, authenticating...');
ws.send(JSON.stringify({ type: 'auth', token }));
};
ws.onmessage = (event) => {
try {
const message = JSON.parse(event.data);
// Handle player count updates
if (message.event === 'player-count.updated') {
console.log('[WebSocket] Player count updated:', message.data);
// Reload games to get updated player counts
if (message.type === 'auth_success') {
console.log('[WebSocket] Authenticated, subscribing to session', sessionId);
ws.send(JSON.stringify({ type: 'subscribe', sessionId: parseInt(sessionId) }));
return;
}
const reloadEvents = [
'room.connected',
'lobby.player-joined',
'lobby.updated',
'game.started',
'game.ended',
'room.disconnected',
'player-count.updated',
'game.added',
];
if (reloadEvents.includes(message.type)) {
console.log(`[WebSocket] ${message.type}:`, message.data);
loadGames();
}
} catch (error) {
@@ -1027,7 +1040,7 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame })
} catch (error) {
console.error('[WebSocket] Failed to connect:', error);
}
}, [sessionId, loadGames]);
}, [sessionId, token, loadGames]);
const handleUpdateStatus = async (gameId, newStatus) => {
try {
@@ -1303,14 +1316,14 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame })
{/* Player Count Display */}
{game.player_count_check_status && game.player_count_check_status !== 'not_started' && (
<div className="flex items-center gap-1">
{game.player_count_check_status === 'waiting' && (
{game.player_count_check_status === 'monitoring' && !game.player_count && (
<span className="inline-flex items-center gap-1 text-xs bg-yellow-100 dark:bg-yellow-900 text-yellow-800 dark:text-yellow-200 px-2 py-1 rounded">
Waiting...
📡 Monitoring...
</span>
)}
{game.player_count_check_status === 'checking' && (
{(game.player_count_check_status === 'checking' || (game.player_count_check_status === 'monitoring' && game.player_count)) && (
<span className="inline-flex items-center gap-1 text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded">
🔍 {game.player_count ? `${game.player_count} players (checking...)` : 'Checking...'}
📡 {game.player_count ? `${game.player_count} players` : 'Monitoring...'}
</span>
)}
{game.player_count_check_status === 'completed' && game.player_count && (
@@ -1406,7 +1419,7 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame })
</>
)}
{/* Stop button for active checks */}
{isAuthenticated && (game.player_count_check_status === 'waiting' || game.player_count_check_status === 'checking') && (
{isAuthenticated && (game.player_count_check_status === 'monitoring' || game.player_count_check_status === 'checking') && (
<button
onClick={() => handleStopPlayerCountCheck(game.id)}
className="text-xs text-gray-500 dark:text-gray-400 hover:text-red-600 dark:hover:text-red-400"