mirror of
https://github.com/AdrianKuta/KahootQuiz.git
synced 2025-09-14 09:15:59 +02: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