feat: Implement Answer Feedback Banner

This commit introduces an `AnswerFeedbackBanner` composable that displays whether a selected answer is correct or wrong. It's integrated into the `Toolbar` section of the `QuizScreen`.

Key changes:

- **UI Layer (`ui:quiz` module):**
    - Created `AnswerFeedbackBanner.kt` composable:
        - Displays "Correct" or "Wrong" text with a green or red background respectively.
        - Uses `Surface` for elevation and `zIndex` to appear above other elements.
    - In `QuizScreen.kt`:
        - Modified the `toolbar` item to include a `Box` that layers the `Toolbar` and the new `AnswerFeedbackBanner`.
        - The `AnswerFeedbackBanner` is shown when `uiState.isAnswerCorrect` is not null.
    - In `QuizScreenViewModel.kt`:
        - Added `isAnswerCorrect: Boolean?` to `ScreenUiState.Success`.
        - Calculated `isAnswerCorrect` based on the selected choice and the correct answer for the current question.
- **Resources (`ui:quiz` module):**
    - Added new string resources for "Correct" and "Wrong" in `strings.xml`.
This commit is contained in:
2025-09-04 22:04:40 +02:00
parent 12638f33d8
commit 99f1c49713
4 changed files with 66 additions and 8 deletions

View File

@@ -32,6 +32,7 @@ import dev.adriankuta.kahootquiz.core.designsystem.KahootQuizTheme
import dev.adriankuta.kahootquiz.domain.models.Choice
import dev.adriankuta.kahootquiz.domain.models.Question
import dev.adriankuta.kahootquiz.ui.quiz.components.Choices
import dev.adriankuta.kahootquiz.ui.quiz.components.AnswerFeedbackBanner
import dev.adriankuta.kahootquiz.ui.quiz.components.QuestionContent
import dev.adriankuta.kahootquiz.ui.quiz.components.TimerBar
import dev.adriankuta.kahootquiz.ui.quiz.components.Toolbar
@@ -115,16 +116,26 @@ private fun QuizScreenSuccess(
private fun LazyListScope.toolbar(
uiState: ScreenUiState.Success,
modifier: Modifier = Modifier,
) {
item(key = "toolbar") {
Box(
modifier = modifier
.height(72.dp),
) {
Toolbar(
modifier = Modifier
.fillMaxWidth()
.height(72.dp)
.fillMaxSize()
.padding(8.dp),
currentQuestionIndex = uiState.currentQuestionIndex,
totalQuestions = uiState.totalQuestions,
)
uiState.isAnswerCorrect?.let { isCorrect ->
AnswerFeedbackBanner(
isCorrect = isCorrect,
)
}
}
}
}

View File

@@ -61,6 +61,9 @@ class QuizScreenViewModel @Inject constructor(
QuizUiState.Loading -> ScreenUiState.Loading
is QuizUiState.Success -> {
val currentQuestion = quizState.quiz.questions.getOrNull(currentQuestionIndex)
val isAnswerCorrect = selectedChoiceIndex?.let { idx ->
currentQuestion?.choices?.getOrNull(idx)?.correct == true
}
ScreenUiState.Success(
currentQuestion = currentQuestion,
@@ -71,6 +74,7 @@ class QuizScreenViewModel @Inject constructor(
remainingTimeSeconds = remainingTimeSeconds,
totalTimeSeconds = currentQuestion?.time?.inWholeSeconds?.toInt() ?: 0,
),
isAnswerCorrect = isAnswerCorrect,
)
}
}
@@ -148,6 +152,7 @@ sealed interface ScreenUiState {
val currentQuestionIndex: Int = 0,
val totalQuestions: Int = 0,
val timerState: TimerState = TimerState(),
val isAnswerCorrect: Boolean? = null,
) : ScreenUiState
}

View File

@@ -0,0 +1,40 @@
package dev.adriankuta.kahootquiz.ui.quiz.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import dev.adriankuta.kahootquiz.core.designsystem.Green
import dev.adriankuta.kahootquiz.core.designsystem.Red
import dev.adriankuta.kahootquiz.ui.quiz.R
@Composable
fun AnswerFeedbackBanner(
isCorrect: Boolean,
modifier: Modifier = Modifier,
) {
Surface(
modifier = modifier
.fillMaxSize()
.zIndex(10f),
shadowElevation = 8.dp,
color = if (isCorrect) Green else Red,
contentColor = Color.White,
) {
Box {
Text(
text = stringResource(if (isCorrect) R.string.correct else R.string.wrong),
textAlign = TextAlign.Center,
modifier = Modifier.align(Alignment.Center),
)
}
}
}

View File

@@ -2,4 +2,6 @@
<resources>
<string name="quiz">Quiz</string>
<string name="continue_text">Continue</string>
<string name="correct">Correct</string>
<string name="wrong">Wrong</string>
</resources>