mirror of
				https://github.com/AdrianKuta/KahootQuiz.git
				synced 2025-10-31 00:43:40 +01:00 
			
		
		
		
	fix: Correct timer behavior and display
This commit addresses issues with the question timer in `QuizScreen`.
Key changes:
- **QuizScreenViewModel:**
    - Initialize `_remainingTimeSeconds` to `0` instead of `-1` to prevent premature timer display.
    - Start timer only if `timerJob` is `null` (not already running) and it's the first question.
    - Set `timerJob` to `null` when it's cancelled (on choice selection, moving to next question, or finishing the quiz).
    - If a question has no time limit (null or <= 0 seconds), set `_remainingTimeSeconds` to `0` and do not start the `timerJob`.
    - When the timer finishes and no choice was selected, set `_selectedChoiceIndex` to `-1` (indicating time ran out) and ensure `timerJob` is nullified.
- **QuizScreen:**
    - Conditionally display the `TimerBar` only if `selectedChoiceIndex` is `null` (no choice made yet) AND `timerState.totalTimeSeconds` is greater than `0` (meaning there's a valid timer for the current question). This prevents showing a timer when a question has no time limit.
			
			
This commit is contained in:
		| @@ -129,7 +129,7 @@ private fun QuizScreen( | ||||
|                 } | ||||
|  | ||||
|                 // Timer below choices | ||||
|                 if (uiState.selectedChoiceIndex == null) { | ||||
|                 if (uiState.selectedChoiceIndex == null && uiState.timerState.totalTimeSeconds > 0) { | ||||
|                     item { | ||||
|                         TimerBar( | ||||
|                             totalSeconds = uiState.timerState.totalTimeSeconds, | ||||
|   | ||||
| @@ -12,10 +12,7 @@ import kotlinx.coroutines.flow.MutableStateFlow | ||||
| import kotlinx.coroutines.flow.SharingStarted | ||||
| import kotlinx.coroutines.flow.StateFlow | ||||
| import kotlinx.coroutines.flow.combine | ||||
| import kotlinx.coroutines.flow.filterIsInstance | ||||
| import kotlinx.coroutines.flow.first | ||||
| import kotlinx.coroutines.flow.flow | ||||
| import kotlinx.coroutines.flow.onEach | ||||
| import kotlinx.coroutines.flow.stateIn | ||||
| import kotlinx.coroutines.launch | ||||
| import javax.inject.Inject | ||||
| @@ -34,7 +31,7 @@ class QuizScreenViewModel @Inject constructor( | ||||
|             initialValue = QuizUiState.Loading, | ||||
|         ) | ||||
|     private val _selectedChoiceIndex = MutableStateFlow<Int?>(null) | ||||
|     private val _remainingTimeSeconds = MutableStateFlow(-1) | ||||
|     private val _remainingTimeSeconds = MutableStateFlow(0) | ||||
|     private val _currentQuestionIndex = MutableStateFlow(0) | ||||
|     private var timerJob: Job? = null | ||||
|  | ||||
| @@ -44,7 +41,7 @@ class QuizScreenViewModel @Inject constructor( | ||||
|             quiz.collect { quizState -> | ||||
|                 if (quizState is QuizUiState.Success) { | ||||
|                     // Start only if timer hasn't been started yet and we are on the first question | ||||
|                     if (_remainingTimeSeconds.value == -1 && _currentQuestionIndex.value == 0) { | ||||
|                     if (timerJob == null && _currentQuestionIndex.value == 0) { | ||||
|                         val firstQuestionTime = quizState.quiz.questions.getOrNull(0)?.time?.inWholeSeconds?.toInt() | ||||
|                         startCountdown(firstQuestionTime) | ||||
|                     } | ||||
| @@ -86,6 +83,7 @@ class QuizScreenViewModel @Inject constructor( | ||||
|  | ||||
|     fun onChoiceSelected(index: Int) { | ||||
|         timerJob?.cancel() | ||||
|         timerJob = null | ||||
|         _selectedChoiceIndex.value = index | ||||
|     } | ||||
|  | ||||
| @@ -103,13 +101,19 @@ class QuizScreenViewModel @Inject constructor( | ||||
|             } else { | ||||
|                 // Last question reached: stop timer and keep state (could navigate to results in the future) | ||||
|                 timerJob?.cancel() | ||||
|                 timerJob = null | ||||
|                 _remainingTimeSeconds.value = 0 | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun startCountdown(totalSeconds: Int?) { | ||||
|         timerJob?.cancel() | ||||
|         if (totalSeconds == null || totalSeconds <= 0) return | ||||
|         if (totalSeconds == null || totalSeconds <= 0) { | ||||
|             _remainingTimeSeconds.value = 0 | ||||
|             timerJob = null | ||||
|             return | ||||
|         } | ||||
|         _remainingTimeSeconds.value = totalSeconds | ||||
|         timerJob = viewModelScope.launch { | ||||
|             var remaining = totalSeconds | ||||
| @@ -122,6 +126,7 @@ class QuizScreenViewModel @Inject constructor( | ||||
|             if (_selectedChoiceIndex.value == null) { | ||||
|                 _selectedChoiceIndex.value = -1 | ||||
|             } | ||||
|             timerJob = null | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user