feat: Enhance QuizScreen UI and introduce core design system module

This commit significantly revamps the `QuizScreen` UI to display question details including image and text, and introduces a new `core:designsystem` module to centralize theme, colors, typography, and drawable resources.

Key changes:

- **UI Layer (`ui:quiz` module):**
    - Updated `QuizScreen.kt`:
        - Implemented a background image for the screen.
        - Added a `Toolbar` composable to display question progress and type.
        - Created `QuestionContent` composable to show the question image (using Coil for image loading) and text.
        - Added a placeholder `Choices` composable (currently an empty `LazyVerticalGrid`).
        - Applied `fillMaxSize()` to the main `QuizScreen` modifier.
        - Included a `@Preview` for `QuizScreen` with sample data.
    - Modified `QuizScreenViewModel.kt` to update `QuizUiState` with the first `Question` from the fetched quiz.
    - Added a `quiz` string resource in `strings.xml`.
    - Added dependencies for Coil (compose and okhttp) in `ui/quiz/build.gradle.kts`.
- **Core Design System (`core:designsystem` module):**
    - Created a new Android library module `core:designsystem`.
    - Moved `Color.kt`, `Theme.kt`, and `Type.kt` from `app/src/main/java/dev/adriankuta/kahootquiz/ui/theme` to this new module.
    - Added a new `Grey` color to `Color.kt`.
    - Added `bg_image.webp` and `ic_type.xml` drawable resources.
    - Configured the module with `kahootquiz.android.library.compose` plugin.
- **App Module (`app` module):**
    - Updated `MainActivity.kt` to import `KahootQuizTheme` from the new `core.designsystem` package.
    - Added `implementation(projects.core.designsystem)` dependency in `app/build.gradle.kts`.
- **Domain Layer (`domain` module):**
    - Made several fields in `Question.kt` and `Choice.kt` nullable and provided default null values to accommodate potential missing data from the API.
    - Specifically, `Question.image` is now non-nullable (`String`).
- **Build System:**
    - Added `coilCompose` and `coilNetworkOkhttp` versions to `gradle/libs.versions.toml`.
    - Included `:core:designsystem` in `settings.gradle.kts`.
This commit is contained in:
2025-09-03 21:57:18 +02:00
parent 57313de1d7
commit 45550ecf76
17 changed files with 249 additions and 24 deletions

View File

@@ -0,0 +1,7 @@
plugins {
alias(libs.plugins.kahootquiz.android.library.compose)
}
android {
namespace = "dev.adriankuta.kahootquiz.core.designsystem"
}

View File

@@ -0,0 +1,13 @@
package dev.adriankuta.kahootquiz.core.designsystem
import androidx.compose.ui.graphics.Color
val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)
val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)
val Grey = Color(0xFFFAFAFA)

View File

@@ -0,0 +1,57 @@
package dev.adriankuta.kahootquiz.core.designsystem
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
private val DarkColorScheme = darkColorScheme(
primary = Purple80,
secondary = PurpleGrey80,
tertiary = Pink80
)
private val LightColorScheme = lightColorScheme(
primary = Purple40,
secondary = PurpleGrey40,
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
fun KahootQuizTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}

View File

@@ -0,0 +1,34 @@
package dev.adriankuta.kahootquiz.core.designsystem
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
// Set of Material typography styles to start with
val Typography = Typography(
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.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
)
*/
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,50 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,22C6.477,22 2,17.523 2,12C2,6.477 6.477,2 12,2C17.523,2 22,6.477 22,12C22,17.523 17.523,22 12,22Z"
android:fillColor="#F2F2F2"
android:fillType="evenOdd"/>
<path
android:pathData="M19.802,21.989L7.899,23.992C7.584,24.045 7.285,23.833 7.232,23.517L3.724,2.678C3.671,2.363 3.883,2.064 4.198,2.011L16.101,0.008C16.416,-0.045 16.715,0.168 16.768,0.483L20.276,21.322C20.33,21.637 20.117,21.936 19.802,21.989Z"
android:fillColor="#333333"
android:fillType="evenOdd"/>
<path
android:pathData="M19.083,20.611L8.127,22.455C7.951,22.485 7.784,22.366 7.754,22.189L4.538,3.09C4.509,2.913 4.627,2.746 4.804,2.716L15.759,0.872C15.936,0.843 16.103,0.962 16.133,1.139L19.349,20.238C19.378,20.414 19.259,20.582 19.083,20.611Z"
android:fillColor="#FAFAFA"
android:fillType="evenOdd"/>
<path
android:pathData="M18.499,20.05L13.849,20.833C13.79,20.843 13.733,20.803 13.724,20.744L12.306,12.325C12.296,12.266 12.336,12.209 12.395,12.199L17.045,11.417C17.104,11.407 17.16,11.447 17.17,11.506L18.587,19.925C18.597,19.984 18.558,20.04 18.499,20.05Z"
android:fillColor="#26890C"
android:fillType="evenOdd"/>
<path
android:pathData="M12.967,20.981L8.317,21.764C8.258,21.774 8.202,21.733 8.192,21.674L6.775,13.255C6.765,13.196 6.805,13.14 6.864,13.13L11.514,12.347C11.573,12.337 11.629,12.377 11.639,12.437L13.057,20.856C13.066,20.915 13.026,20.971 12.967,20.981Z"
android:fillColor="#FFA602"
android:fillType="evenOdd"/>
<path
android:pathData="M16.947,10.835L12.297,11.618C12.238,11.628 12.182,11.588 12.172,11.529L10.64,2.434C10.631,2.374 10.67,2.318 10.73,2.308L15.379,1.526C15.439,1.516 15.495,1.556 15.505,1.615L17.036,10.71C17.046,10.769 17.006,10.825 16.947,10.835Z"
android:fillColor="#1368CE"
android:fillType="evenOdd"/>
<path
android:pathData="M11.416,11.766L6.766,12.548C6.707,12.558 6.651,12.518 6.641,12.459L5.109,3.364C5.099,3.305 5.139,3.249 5.199,3.239L9.848,2.456C9.907,2.446 9.964,2.486 9.974,2.546L11.505,11.641C11.515,11.7 11.475,11.756 11.416,11.766Z"
android:fillColor="#E11C3C"
android:fillType="evenOdd"/>
<path
android:pathData="M7.317,8.677L8.107,6.504L9.544,8.316L7.317,8.677Z"
android:fillColor="#FAFAFA"
android:fillType="evenOdd"/>
<path
android:pathData="M13.596,5.437L15.014,6.416L14.017,7.822L12.598,6.842L13.596,5.437Z"
android:fillColor="#FAFAFA"
android:fillType="evenOdd"/>
<path
android:pathData="M10.79,16.727C10.704,16.175 10.188,15.796 9.637,15.881C9.086,15.967 8.709,16.484 8.795,17.037C8.881,17.59 9.397,17.968 9.948,17.883C10.498,17.798 10.875,17.28 10.79,16.727Z"
android:fillColor="#FAFAFA"
android:fillType="evenOdd"/>
<path
android:pathData="M16.618,16.843L14.628,17.181L14.288,15.184L16.278,14.846L16.618,16.843Z"
android:fillColor="#FAFAFA"
android:fillType="evenOdd"/>
</vector>