mirror of
				https://github.com/AdrianKuta/KahootQuiz.git
				synced 2025-10-31 00:43:40 +01:00 
			
		
		
		
	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:
		| @@ -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") { | ||||
|         Toolbar( | ||||
|             modifier = Modifier | ||||
|                 .fillMaxWidth() | ||||
|                 .height(72.dp) | ||||
|                 .padding(8.dp), | ||||
|             currentQuestionIndex = uiState.currentQuestionIndex, | ||||
|             totalQuestions = uiState.totalQuestions, | ||||
|         ) | ||||
|         Box( | ||||
|             modifier = modifier | ||||
|                 .height(72.dp), | ||||
|         ) { | ||||
|             Toolbar( | ||||
|                 modifier = Modifier | ||||
|                     .fillMaxSize() | ||||
|                     .padding(8.dp), | ||||
|                 currentQuestionIndex = uiState.currentQuestionIndex, | ||||
|                 totalQuestions = uiState.totalQuestions, | ||||
|             ) | ||||
|             uiState.isAnswerCorrect?.let { isCorrect -> | ||||
|                 AnswerFeedbackBanner( | ||||
|                     isCorrect = isCorrect, | ||||
|                 ) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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), | ||||
|             ) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -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> | ||||
		Reference in New Issue
	
	Block a user