diff --git a/public/js/render.js b/public/js/render.js index 654d65d..72374c1 100644 --- a/public/js/render.js +++ b/public/js/render.js @@ -107,8 +107,9 @@ export function renderRoom(room) { const isHost = state.playerId === room.hostId; const activePlayers = room.players.filter((p) => !p.spectator && p.connected); const allReady = activePlayers.length > 0 && activePlayers.every((p) => p.ready); + const hasPlaylist = !!room.state.playlist; - const canStart = room.state.status === 'lobby' && isHost && allReady; + const canStart = room.state.status === 'lobby' && isHost && allReady && hasPlaylist; if ($startGame) $startGame.classList.toggle('hidden', !canStart); @@ -121,18 +122,52 @@ export function renderRoom(room) { $playlistSection.classList.toggle('hidden', room.state.status !== 'lobby' || !isHost); } if ($playlistSelect && state.playlists && state.playlists.length > 0) { - // Populate playlist dropdown if not already populated - if ($playlistSelect.options.length === 1 && $playlistSelect.options[0].value === 'default') { + // Populate playlist dropdown if not already populated with actual playlists + const needsPopulation = + $playlistSelect.options.length === 0 || + ($playlistSelect.options.length === 1 && $playlistSelect.options[0].value === 'default'); + + if (needsPopulation) { $playlistSelect.innerHTML = ''; + // Add a placeholder option + const placeholderOption = document.createElement('option'); + placeholderOption.value = ''; + placeholderOption.textContent = '-- Bitte Playlist auswählen --'; + placeholderOption.disabled = true; + placeholderOption.selected = true; // Make it selected by default + $playlistSelect.appendChild(placeholderOption); + state.playlists.forEach((playlist) => { const option = document.createElement('option'); option.value = playlist.id; option.textContent = `${playlist.name} (${playlist.trackCount} Tracks)`; $playlistSelect.appendChild(option); }); + + // Mark that we've populated the dropdown + state.playlistsPopulated = true; + + // Auto-select first playlist if host and in lobby (only on first population) + if ( + !room.state.playlist && + isHost && + room.state.status === 'lobby' && + state.playlists.length > 0 + ) { + // Use setTimeout to ensure the change event is properly triggered after render + setTimeout(() => { + const firstPlaylistId = state.playlists[0].id; + $playlistSelect.value = firstPlaylistId; + // Trigger the change event to send to server + $playlistSelect.dispatchEvent(new Event('change')); + }, 100); + } + } + + // Set selected playlist based on room state + if (room.state.playlist) { + $playlistSelect.value = room.state.playlist; } - // Set selected playlist - $playlistSelect.value = room.state.playlist || 'default'; } if ($currentPlaylist) { $currentPlaylist.textContent = room.state.playlist || 'default'; diff --git a/public/js/ui.js b/public/js/ui.js index fb2b253..7bff281 100644 --- a/public/js/ui.js +++ b/public/js/ui.js @@ -121,7 +121,14 @@ export function wireUi() { $room.classList.add('hidden'); }); - wire($startGame, 'click', () => sendMsg({ type: 'start_game' })); + wire($startGame, 'click', () => { + // Validate playlist selection before starting + if (!state.room?.state?.playlist) { + showToast('⚠️ Bitte wähle zuerst eine Playlist aus!'); + return; + } + sendMsg({ type: 'start_game' }); + }); wire($readyChk, 'change', (e) => { const val = !!e.target.checked; diff --git a/src/server/game.js b/src/server/game.js index 06eeb7d..98f1c79 100644 --- a/src/server/game.js +++ b/src/server/game.js @@ -298,6 +298,8 @@ export function setupWebSocket(server) { const room = rooms.get(player.roomId); if (!room) return; if (room.hostId !== player.id) return send('error', { message: 'Only host can start' }); + if (!room.state.playlist) + return send('error', { message: 'Please select a playlist first' }); const active = [...room.players.values()].filter( (p) => !room.state.spectators?.[p.id] && p.connected ); diff --git a/src/server/game/deck.js b/src/server/game/deck.js index 0a2d008..2abea24 100644 --- a/src/server/game/deck.js +++ b/src/server/game/deck.js @@ -108,13 +108,6 @@ export async function loadDeck(playlistId = 'default') { }) ); tracks.push(...batchTracks); - - // Optional: Log progress for large playlists - if (files.length > 100 && (i + BATCH_SIZE) % 100 === 0) { - console.log( - `Loading playlist ${playlistId}: ${Math.min(i + BATCH_SIZE, files.length)}/${files.length} tracks processed` - ); - } } console.log(`Loaded ${tracks.length} tracks from playlist: ${playlistId}`); diff --git a/src/server/game/state.js b/src/server/game/state.js index f571c59..b90f5c9 100644 --- a/src/server/game/state.js +++ b/src/server/game/state.js @@ -42,7 +42,7 @@ export function createRoom(name, host) { paused: false, pausedPosSec: 0, goal: 10, - playlist: 'default', // Selected playlist for this room + playlist: null, // Selected playlist for this room (must be chosen by host) }, }; rooms.set(id, room);