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');
}
});