Refactor: Move background image to main App composable and cleanup

This commit refactors the placement of the background image, moving it from `QuizScreen` to the main `KahootQuizApp` composable. This ensures the background is consistently applied across the app.

Additionally, this commit includes:
- Removal of unused Detekt configuration file (`ui/quiz/config/detekt/detekt.yml`).
- Minor code cleanup:
    - Removed commented-out code in `Theme.kt` and `Type.kt`.
    - Removed trailing blank lines in various domain model files.
    - Added `@file:Suppress("TooManyFunctions")` to `QuizMapper.kt`.
    - Added `@file:Suppress("MatchingDeclarationName")` to `QuizNavigation.kt`.
    - Used `1.seconds` instead of `1000` (Long) for delay in `QuizScreenViewModel`.
This commit is contained in:
2025-09-04 22:17:57 +02:00
parent 99f1c49713
commit 77a3dd9eeb
30 changed files with 47 additions and 79 deletions

View File

@@ -1,11 +1,16 @@
package dev.adriankuta.kahootquiz package dev.adriankuta.kahootquiz
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import dev.adriankuta.kahootquiz.core.designsystem.R as DesignR
@Composable @Composable
fun KahootQuizApp( fun KahootQuizApp(
@@ -15,6 +20,12 @@ fun KahootQuizApp(
contentWindowInsets = WindowInsets.safeDrawing, contentWindowInsets = WindowInsets.safeDrawing,
modifier = modifier, modifier = modifier,
) { paddingValues -> ) { paddingValues ->
KahootQuizNavGraph(modifier = modifier.padding(paddingValues)) Image(
painter = painterResource(id = DesignR.drawable.bg_image),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize(),
)
KahootQuizNavGraph(modifier = Modifier.padding(paddingValues))
} }
} }

View File

@@ -20,4 +20,4 @@ fun KahootQuizNavGraph(
) { ) {
quizScreen() quizScreen()
} }
} }

View File

@@ -13,4 +13,4 @@ class ExampleUnitTest {
fun addition_isCorrect() { fun addition_isCorrect() {
assertEquals(4, 2 + 2) assertEquals(4, 2 + 2)
} }
} }

View File

@@ -28,7 +28,8 @@ fun Spanned.toAnnotatedString(): AnnotatedString = buildAnnotatedString {
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
fontStyle = FontStyle.Italic, fontStyle = FontStyle.Italic,
), ),
start, end, start,
end,
) )
} }
@@ -45,4 +46,4 @@ fun Spanned.toAnnotatedString(): AnnotatedString = buildAnnotatedString {
) )
} }
} }
} }

View File

@@ -20,16 +20,6 @@ private val LightColorScheme = lightColorScheme(
primary = Purple40, primary = Purple40,
secondary = PurpleGrey40, secondary = PurpleGrey40,
tertiary = Pink40, tertiary = Pink40,
/* Other default colors to override
background = Color(0xFFFFFBFE),
surface = Color(0xFFFFFBFE),
onPrimary = Color.White,
onSecondary = Color.White,
onTertiary = Color.White,
onBackground = Color(0xFF1C1B1F),
onSurface = Color(0xFF1C1B1F),
*/
) )
@Composable @Composable
@@ -54,4 +44,4 @@ fun KahootQuizTheme(
typography = Typography, typography = Typography,
content = content, content = content,
) )
} }

View File

@@ -15,20 +15,4 @@ val Typography = Typography(
lineHeight = 24.sp, lineHeight = 24.sp,
letterSpacing = 0.5.sp, letterSpacing = 0.5.sp,
), ),
/* Other default text styles to override )
titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
),
labelSmall = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Medium,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
*/
)

View File

@@ -6,4 +6,4 @@ data class Access(
val groupRead: List<String>?, val groupRead: List<String>?,
val folderGroupIds: List<String>?, val folderGroupIds: List<String>?,
val features: List<String>?, val features: List<String>?,
) )

View File

@@ -2,4 +2,4 @@ package dev.adriankuta.kahootquiz.domain.models
// Minimal channel info // Minimal channel info
data class Channel(val id: String?) data class Channel(val id: String?)

View File

@@ -4,4 +4,4 @@ data class Choice(
val answer: String?, val answer: String?,
val correct: Boolean, val correct: Boolean,
val languageInfo: LanguageInfo? = null, val languageInfo: LanguageInfo? = null,
) )

View File

@@ -8,4 +8,4 @@ data class ChoiceRange(
val step: Int?, val step: Int?,
val correct: Int?, val correct: Int?,
val tolerance: Int?, val tolerance: Int?,
) )

View File

@@ -5,4 +5,4 @@ package dev.adriankuta.kahootquiz.domain.models
data class ContentTags( data class ContentTags(
val curriculumCodes: List<String>?, val curriculumCodes: List<String>?,
val generatedCurriculumCodes: List<String>?, val generatedCurriculumCodes: List<String>?,
) )

View File

@@ -14,4 +14,4 @@ data class CoverMetadata(
val extractedColors: List<ExtractedColor>?, val extractedColors: List<ExtractedColor>?,
val blurhash: String?, val blurhash: String?,
val crop: Crop?, val crop: Crop?,
) )

View File

@@ -6,4 +6,4 @@ data class Crop(
val origin: Point?, val origin: Point?,
val target: Point?, val target: Point?,
val circular: Boolean?, val circular: Boolean?,
) )

View File

@@ -5,4 +5,4 @@ package dev.adriankuta.kahootquiz.domain.models
data class ExtractedColor( data class ExtractedColor(
val swatch: String?, val swatch: String?,
val rgbHex: String?, val rgbHex: String?,
) )

View File

@@ -5,4 +5,4 @@ package dev.adriankuta.kahootquiz.domain.models
data class FeaturedListMembership( data class FeaturedListMembership(
val list: String?, val list: String?,
val addedAt: Long?, val addedAt: Long?,
) )

View File

@@ -13,4 +13,4 @@ data class ImageMetadata(
val height: Int? = null, val height: Int? = null,
val effects: List<String>? = null, val effects: List<String>? = null,
val crop: Crop? = null, val crop: Crop? = null,
) )

View File

@@ -6,4 +6,4 @@ data class LanguageInfo(
val language: String?, val language: String?,
val lastUpdatedOn: Long?, val lastUpdatedOn: Long?,
val readAloudSupported: Boolean?, val readAloudSupported: Boolean?,
) )

View File

@@ -6,4 +6,4 @@ data class LastEdit(
val editorUserId: String?, val editorUserId: String?,
val editorUsername: String?, val editorUsername: String?,
val editTimestamp: Long?, val editTimestamp: Long?,
) )

View File

@@ -15,4 +15,4 @@ data class MediaItem(
val width: Int? = null, val width: Int? = null,
val height: Int? = null, val height: Int? = null,
val crop: Crop? = null, val crop: Crop? = null,
) )

View File

@@ -8,4 +8,4 @@ data class Metadata(
val featuredListMemberships: List<FeaturedListMembership>?, val featuredListMemberships: List<FeaturedListMembership>?,
val lastEdit: LastEdit?, val lastEdit: LastEdit?,
val versionMetadata: VersionMetadata?, val versionMetadata: VersionMetadata?,
) )

View File

@@ -5,4 +5,4 @@ package dev.adriankuta.kahootquiz.domain.models
data class Point( data class Point(
val x: Int?, val x: Int?,
val y: Int?, val y: Int?,
) )

View File

@@ -20,4 +20,4 @@ data class Question(
val languageInfo: LanguageInfo? = null, val languageInfo: LanguageInfo? = null,
val media: List<MediaItem>? = null, val media: List<MediaItem>? = null,
val choiceRange: ChoiceRange? = null, val choiceRange: ChoiceRange? = null,
) )

View File

@@ -32,4 +32,4 @@ data class Quiz(
val type: String?, val type: String?,
val created: Long?, val created: Long?,
val modified: Long?, val modified: Long?,
) )

View File

@@ -6,4 +6,4 @@ data class VersionMetadata(
val version: Int?, val version: Int?,
val created: Long?, val created: Long?,
val creator: String?, val creator: String?,
) )

View File

@@ -6,4 +6,4 @@ data class Video(
val endTime: Int?, val endTime: Int?,
val service: String?, val service: String?,
val fullUrl: String?, val fullUrl: String?,
) )

View File

@@ -1,3 +1,5 @@
@file:Suppress("TooManyFunctions")
package dev.adriankuta.kahootquiz.model.data.mappers package dev.adriankuta.kahootquiz.model.data.mappers
import dev.adriankuta.kahootquiz.core.network.models.AccessDto import dev.adriankuta.kahootquiz.core.network.models.AccessDto

View File

@@ -1,10 +0,0 @@
# Deviations from defaults
formatting:
TrailingCommaOnCallSite:
active: true
autoCorrect: true
useTrailingCommaOnCallSite: true
TrailingCommaOnDeclarationSite:
active: true
autoCorrect: true
useTrailingCommaOnDeclarationSite: true

View File

@@ -1,7 +1,6 @@
package dev.adriankuta.kahootquiz.ui.quiz package dev.adriankuta.kahootquiz.ui.quiz
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@@ -20,8 +19,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@@ -31,20 +28,18 @@ import dev.adriankuta.kahootquiz.core.designsystem.Grey
import dev.adriankuta.kahootquiz.core.designsystem.KahootQuizTheme import dev.adriankuta.kahootquiz.core.designsystem.KahootQuizTheme
import dev.adriankuta.kahootquiz.domain.models.Choice import dev.adriankuta.kahootquiz.domain.models.Choice
import dev.adriankuta.kahootquiz.domain.models.Question 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.AnswerFeedbackBanner
import dev.adriankuta.kahootquiz.ui.quiz.components.Choices
import dev.adriankuta.kahootquiz.ui.quiz.components.QuestionContent import dev.adriankuta.kahootquiz.ui.quiz.components.QuestionContent
import dev.adriankuta.kahootquiz.ui.quiz.components.TimerBar import dev.adriankuta.kahootquiz.ui.quiz.components.TimerBar
import dev.adriankuta.kahootquiz.ui.quiz.components.Toolbar import dev.adriankuta.kahootquiz.ui.quiz.components.Toolbar
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
import dev.adriankuta.kahootquiz.core.designsystem.R as DesignR
@Composable @Composable
fun QuizScreen( fun QuizScreen(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
viewModel: QuizScreenViewModel = hiltViewModel(), viewModel: QuizScreenViewModel = hiltViewModel(),
) { ) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle() val uiState by viewModel.uiState.collectAsStateWithLifecycle()
QuizScreen( QuizScreen(
@@ -63,12 +58,6 @@ private fun QuizScreen(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Box(modifier.fillMaxSize()) { Box(modifier.fillMaxSize()) {
Image(
painter = painterResource(id = DesignR.drawable.bg_image),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize(),
)
when (uiState) { when (uiState) {
ScreenUiState.Loading -> QuizScreenLoading() ScreenUiState.Loading -> QuizScreenLoading()
is ScreenUiState.Success -> QuizScreenSuccess( is ScreenUiState.Success -> QuizScreenSuccess(
@@ -76,7 +65,6 @@ private fun QuizScreen(
onSelect = onSelect, onSelect = onSelect,
onContinue = onContinue, onContinue = onContinue,
) )
} }
} }
} }

View File

@@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
@HiltViewModel @HiltViewModel
class QuizScreenViewModel @Inject constructor( class QuizScreenViewModel @Inject constructor(
@@ -78,7 +79,6 @@ class QuizScreenViewModel @Inject constructor(
) )
} }
} }
} }
.stateIn( .stateIn(
scope = viewModelScope, scope = viewModelScope,
@@ -124,7 +124,7 @@ class QuizScreenViewModel @Inject constructor(
timerJob = viewModelScope.launch { timerJob = viewModelScope.launch {
var remaining = totalSeconds var remaining = totalSeconds
while (remaining > 0) { while (remaining > 0) {
delay(1000) delay(1.seconds)
remaining -= 1 remaining -= 1
_remainingTimeSeconds.value = remaining _remainingTimeSeconds.value = remaining
} }

View File

@@ -1,3 +1,5 @@
@file:Suppress("MatchingDeclarationName")
package dev.adriankuta.kahootquiz.ui.quiz.navigation package dev.adriankuta.kahootquiz.ui.quiz.navigation
import androidx.navigation.NavGraphBuilder import androidx.navigation.NavGraphBuilder
@@ -12,4 +14,4 @@ fun NavGraphBuilder.quizScreen() {
composable<QuizRoute> { composable<QuizRoute> {
QuizScreen() QuizScreen()
} }
} }