diff --git a/display.html b/display.html index bfd8e79..1ad6acb 100644 --- a/display.html +++ b/display.html @@ -56,6 +56,7 @@
+ diff --git a/display.js b/display.js index 117fb7d..28c79bf 100644 --- a/display.js +++ b/display.js @@ -15,10 +15,13 @@ const markCorrectBtn = document.getElementById('markCorrect'); const markIncorrectBtn = document.getElementById('markIncorrect'); const showAnswerBtn = document.getElementById('showAnswer'); const resetGameBtn = document.getElementById('resetGame'); +const readQuestionBtn = document.getElementById('readQuestion'); let currentQuestion = null; let currentQuestionNumber = 1; let currentBuzzedPlayer = null; +let speechSynthesis = window.speechSynthesis; +let currentUtterance = null; // Initialize game state database.ref('gameState').set({ @@ -30,7 +33,8 @@ database.ref('gameState').set({ player3: 0, player4: 0 }, - questionNumber: 1 + questionNumber: 1, + isReading: false }); // Listen for game state changes @@ -55,6 +59,11 @@ database.ref('gameState').on('value', (snapshot) => { buzzedPlayer.textContent = `Player ${playerNum} buzzed in!`; + // Stop reading when someone buzzes + if (currentUtterance) { + speechSynthesis.cancel(); + } + // Show grading buttons markCorrectBtn.style.display = 'inline-block'; markIncorrectBtn.style.display = 'inline-block'; @@ -80,6 +89,10 @@ newQuestionBtn.addEventListener('click', async () => { body: JSON.stringify({ categories }) }); + if (!response.ok) { + throw new Error('API request failed'); + } + const data = await response.json(); currentQuestion = data; @@ -89,12 +102,13 @@ newQuestionBtn.addEventListener('click', async () => { questionNum.textContent = currentQuestionNumber; // Update Firebase - database.ref('gameState').update({ + await database.ref('gameState').update({ currentQuestion: currentQuestion, buzzerActive: false, buzzer: null, playerAnswer: null, - questionNumber: currentQuestionNumber + questionNumber: currentQuestionNumber, + isReading: false }); // Reset UI @@ -106,14 +120,51 @@ newQuestionBtn.addEventListener('click', async () => { showAnswerBtn.style.display = 'none'; activateBuzzerBtn.disabled = false; + readQuestionBtn.disabled = false; currentQuestionNumber++; + console.log('Question loaded successfully:', currentQuestion); + } catch (error) { console.error('Error fetching question:', error); - alert('Error loading question. Check console.'); + alert('Error loading question. Check console for details. The API might be down or CORS is blocking it.'); } }); +// Read question aloud +readQuestionBtn.addEventListener('click', () => { + if (!currentQuestion) { + alert('Load a question first!'); + return; + } + + // Stop any current speech + speechSynthesis.cancel(); + + // Create utterance + currentUtterance = new SpeechSynthesisUtterance(currentQuestion.tossup_question); + currentUtterance.rate = 0.9; // Slightly slower for clarity + currentUtterance.pitch = 1; + currentUtterance.volume = 1; + + // Update Firebase that we're reading + database.ref('gameState/isReading').set(true); + + currentUtterance.onend = () => { + database.ref('gameState/isReading').set(false); + console.log('Finished reading question'); + }; + + speechSynthesis.speak(currentUtterance); + readQuestionBtn.textContent = '🔊 Reading...'; + readQuestionBtn.disabled = true; + + setTimeout(() => { + readQuestionBtn.textContent = '🔊 Read Question'; + readQuestionBtn.disabled = false; + }, 2000); +}); + // Activate buzzers activateBuzzerBtn.addEventListener('click', () => { database.ref('gameState').update({ @@ -166,6 +217,7 @@ showAnswerBtn.addEventListener('click', () => { resetGameBtn.addEventListener('click', () => { if (confirm('Reset all scores and start over?')) { currentQuestionNumber = 1; + speechSynthesis.cancel(); database.ref('gameState').set({ buzzerActive: false, currentQuestion: null, @@ -175,7 +227,8 @@ resetGameBtn.addEventListener('click', () => { player3: 0, player4: 0 }, - questionNumber: 1 + questionNumber: 1, + isReading: false }); questionText.textContent = 'Click "New Question" to start'; answerSection.style.display = 'none'; @@ -183,10 +236,12 @@ resetGameBtn.addEventListener('click', () => { }); function resetForNextQuestion() { + speechSynthesis.cancel(); database.ref('gameState').update({ buzzerActive: false, buzzer: null, - playerAnswer: null + playerAnswer: null, + isReading: false }); buzzedPlayer.textContent = ''; diff --git a/player.js b/player.js index 0f05527..7c2f4d4 100644 --- a/player.js +++ b/player.js @@ -33,9 +33,15 @@ database.ref('gameState').on('value', (snapshot) => { playerScore.textContent = state.scores[`player${playerId}`]; } - // Update question - if (state.currentQuestion) { - questionDisplay.textContent = state.currentQuestion.tossup_question; + // Hide question text - players only hear it + if (state.isReading) { + questionDisplay.textContent = '🔊 Listen to the question...'; + questionDisplay.style.display = 'block'; + } else if (state.currentQuestion) { + questionDisplay.textContent = 'Question loaded. Waiting for moderator to read...'; + questionDisplay.style.display = 'block'; + } else { + questionDisplay.style.display = 'none'; } // Update buzzer state @@ -58,7 +64,8 @@ database.ref('gameState').on('value', (snapshot) => { answerContainer.style.display = 'block'; answerInput.focus(); } else if (state.buzzer && state.buzzer.playerId) { - statusMessage.textContent = `${state.buzzer.playerId} buzzed in`; + const buzzedPlayerNum = state.buzzer.playerId.replace('player', ''); + statusMessage.textContent = `Player ${buzzedPlayerNum} buzzed in`; buzzer.classList.add('locked'); } });