11// Global variables
2+ const MAX_HISTORY = 30 ;
3+ const PAUSE_SECONDS_FROM_END = 5 ;
4+
25let questions = { } ;
36let currentQuestionId = null ;
47let askedQuestions = [ ] ;
58let userAnswers = [ ] ;
6- const MAX_HISTORY = 30 ;
9+ let hasHeardAnswer = false ;
710
811// Initialize the application
912document . addEventListener ( 'DOMContentLoaded' , async ( ) => {
@@ -48,6 +51,9 @@ function nextQuestion() {
4851 btn . disabled = false ;
4952 } ) ;
5053
54+ // Reset the hasHeardAnswer flag
55+ hasHeardAnswer = false ;
56+
5157 // Select a new question
5258 currentQuestionId = selectNewQuestion ( ) ;
5359
@@ -74,12 +80,17 @@ function nextQuestion() {
7480 const audioElement = document . getElementById ( 'question-audio' ) ;
7581 audioElement . src = `audio/KNS ${ currentQuestionId . padStart ( 3 , '0' ) } .mp3` ;
7682
77- // Remove any existing timeupdate event listeners
83+ // Remove any existing time-related event listeners
7884 audioElement . removeEventListener ( 'timeupdate' , pauseBeforeEnd ) ;
85+ audioElement . removeEventListener ( 'timeupdate' , checkIfPastPausePoint ) ;
7986
80- // Add event listener to pause 5 seconds before the end
87+ // Add an event listener to pause before the answer is told.
8188 audioElement . addEventListener ( 'timeupdate' , pauseBeforeEnd ) ;
8289
90+ // Add an event listener to detect if past the pause point
91+ audioElement . addEventListener ( 'timeupdate' , checkIfPastPausePoint ) ;
92+
93+
8394 audioElement . load ( ) ;
8495 audioElement . play ( ) . catch ( error => {
8596 console . error ( 'Error playing audio:' , error ) ;
@@ -91,7 +102,11 @@ function checkAnswer(selectedOption) {
91102 if ( ! currentQuestionId ) return ;
92103
93104 const question = questions [ currentQuestionId ] ;
94- const isCorrect = selectedOption === question . answer ;
105+ const selectedCorrectOption = selectedOption === question . answer ;
106+
107+ // Determine if the answer should be counted as correct
108+ // If the user has heard the answer, don't count it as correct even if they selected the right option
109+ const isCorrect = selectedCorrectOption && ! hasHeardAnswer ;
95110
96111 // Record the answer
97112 userAnswers . push ( {
@@ -104,14 +119,22 @@ function checkAnswer(selectedOption) {
104119 userAnswers . shift ( ) ;
105120 }
106121
107- // Update the UI to show correct/incorrect
122+ // Update the UI to show correct/incorrect/neutral
108123 const selectedButton = document . getElementById ( `option-${ selectedOption } ` ) ;
109124
110- if ( isCorrect ) {
125+ if ( hasHeardAnswer ) {
126+ // User has heard the answer - neutral outcome
127+ selectedButton . classList . add ( 'neutral' ) ;
128+ document . getElementById ( `option-${ question . answer } ` ) . classList . add ( 'correct' ) ;
129+ document . getElementById ( 'feedback' ) . textContent = 'You heard the answer - not counting this one!' ;
130+ document . getElementById ( 'feedback' ) . className = 'feedback neutral' ;
131+ } else if ( selectedCorrectOption ) {
132+ // User selected the correct answer without hearing the answer
111133 selectedButton . classList . add ( 'correct' ) ;
112134 document . getElementById ( 'feedback' ) . textContent = 'Correct!' ;
113135 document . getElementById ( 'feedback' ) . className = 'feedback correct' ;
114136 } else {
137+ // User selected the wrong answer
115138 selectedButton . classList . add ( 'incorrect' ) ;
116139 document . getElementById ( `option-${ question . answer } ` ) . classList . add ( 'correct' ) ;
117140 document . getElementById ( 'feedback' ) . textContent = 'Incorrect!' ;
@@ -163,18 +186,28 @@ function handleImageError() {
163186// Add error handler to image
164187document . getElementById ( 'question-image' ) . addEventListener ( 'error' , handleImageError ) ;
165188
166- // Function to pause audio 5 seconds before the end
189+ // Function to pause before the answer is told.
167190function pauseBeforeEnd ( ) {
168191 const audioElement = document . getElementById ( 'question-audio' ) ;
169192
170- // Check if the audio is 5 seconds from the end
171- if ( audioElement . duration > 0 && audioElement . currentTime > 0 &&
172- ( audioElement . duration - audioElement . currentTime ) <= 5 ) {
193+ // margin is needed because the duration and currentTime are floats.
194+ const margin = 0.5
173195
174- // Pause the audio
175- audioElement . pause ( ) ;
196+ if ( audioElement . duration > 0 && audioElement . currentTime > 0 &&
197+ ( audioElement . duration - audioElement . currentTime ) < PAUSE_SECONDS_FROM_END + margin ) {
176198
177- // Remove the event listener to prevent multiple pauses
199+ audioElement . pause ( ) ;
178200 audioElement . removeEventListener ( 'timeupdate' , pauseBeforeEnd ) ;
179201 }
180202}
203+
204+ function checkIfPastPausePoint ( ) {
205+ const audioElement = document . getElementById ( 'question-audio' ) ;
206+ if ( audioElement . duration > 0 && audioElement . currentTime > 0 &&
207+ ( audioElement . duration - audioElement . currentTime ) < PAUSE_SECONDS_FROM_END ) {
208+
209+ hasHeardAnswer = true ;
210+ audioElement . removeEventListener ( 'timeupdate' , checkIfPastPausePoint ) ;
211+ }
212+ }
213+
0 commit comments