mirror of
https://github.com/AdrianKuta/KahootQuiz.git
synced 2025-09-14 17:24:21 +02:00
feat: Implement QuizScreen and basic navigation structure
This commit introduces the `QuizScreen` composable, its associated `QuizScreenViewModel`, and sets up the basic navigation graph for the application. Key changes: - **UI Layer (`ui:quiz` module):** - Added `QuizScreen.kt` with a basic composable structure. - Implemented `QuizScreenViewModel.kt` which fetches quiz data using `GetQuizUseCase` and exposes it via `QuizUiState`. - Created `QuizUiState` data class to hold the quiz data for the UI. - Added `navigation/QuizNavigation.kt` to define the `QuizRoute` and `quizScreen` navigation extension. - Updated `ui/quiz/build.gradle.kts` to include dependencies for Hilt navigation and Timber. - **App Module (`app` module):** - Created `KahootQuizApp.kt` which sets up the main `Scaffold` and includes the navigation graph. - Added `KahootQuizNavGraph.kt` to define the `NavHost` and integrate the `quizScreen`. - Modified `MainActivity.kt` to call the new `KahootQuizApp` composable, removing the previous direct use case call and UI. - **Data Layer (`model:data` module):** - Updated `QuizMapper.kt` to convert `time` from `Long?` to `Duration?` (using `milliseconds`) when mapping `QuestionDto` to the domain `Question` model.
This commit is contained in:
20
app/src/main/java/dev/adriankuta/kahootquiz/KahootQuizApp.kt
Normal file
20
app/src/main/java/dev/adriankuta/kahootquiz/KahootQuizApp.kt
Normal file
@@ -0,0 +1,20 @@
|
||||
package dev.adriankuta.kahootquiz
|
||||
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
@Composable
|
||||
fun KahootQuizApp(
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Scaffold(
|
||||
contentWindowInsets = WindowInsets.safeDrawing,
|
||||
modifier = modifier,
|
||||
) { paddingValues ->
|
||||
KahootQuizNavGraph(modifier = modifier.padding(paddingValues))
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package dev.adriankuta.kahootquiz
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import dev.adriankuta.kahootquiz.ui.quiz.navigation.QuizRoute
|
||||
import dev.adriankuta.kahootquiz.ui.quiz.navigation.quizScreen
|
||||
|
||||
@Composable
|
||||
fun KahootQuizNavGraph(
|
||||
modifier: Modifier = Modifier,
|
||||
navController: NavHostController = rememberNavController(),
|
||||
) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = QuizRoute,
|
||||
modifier = modifier
|
||||
) {
|
||||
quizScreen()
|
||||
}
|
||||
}
|
@@ -4,64 +4,19 @@ import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import dev.adriankuta.kahootquiz.domain.usecases.GetQuizUseCase
|
||||
import dev.adriankuta.kahootquiz.ui.theme.KahootQuizTheme
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
||||
@Inject
|
||||
lateinit var getQuizUseCase: GetQuizUseCase
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContent {
|
||||
KahootQuizTheme {
|
||||
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
||||
|
||||
var quizId by remember { mutableStateOf<String?>(null) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
quizId = getQuizUseCase().id.value
|
||||
}
|
||||
|
||||
Greeting(
|
||||
name = quizId ?: "Android",
|
||||
modifier = Modifier.padding(innerPadding)
|
||||
)
|
||||
KahootQuizApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
text = "Hello $name!",
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun GreetingPreview() {
|
||||
KahootQuizTheme {
|
||||
Greeting("Android")
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@ package dev.adriankuta.kahootquiz.model.data.mappers
|
||||
|
||||
import dev.adriankuta.kahootquiz.core.network.models.*
|
||||
import dev.adriankuta.kahootquiz.domain.models.*
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
internal fun QuizResponseDto.toDomainModel(): Quiz =
|
||||
Quiz(
|
||||
@@ -110,7 +111,7 @@ private fun ChannelDto.toDomain(): Channel = Channel(id = id)
|
||||
private fun QuestionDto.toDomain(): Question = Question(
|
||||
type = type,
|
||||
question = question,
|
||||
time = time,
|
||||
time = time?.milliseconds,
|
||||
points = points,
|
||||
pointsMultiplier = pointsMultiplier,
|
||||
choices = choices?.map { it.toDomain() },
|
||||
|
@@ -1,6 +1,7 @@
|
||||
plugins {
|
||||
alias(libs.plugins.kahootquiz.android.library.compose)
|
||||
alias(libs.plugins.kahootquiz.android.library.hilt)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -9,4 +10,6 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation(projects.domain)
|
||||
implementation(libs.androidx.hilt.navigation.compose)
|
||||
implementation(libs.timber)
|
||||
}
|
||||
|
@@ -0,0 +1,29 @@
|
||||
package dev.adriankuta.kahootquiz.ui.quiz
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
|
||||
@Composable
|
||||
fun QuizScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: QuizScreenViewModel = hiltViewModel()
|
||||
) {
|
||||
|
||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||
|
||||
QuizScreen(
|
||||
uiState = uiState,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun QuizScreen(
|
||||
uiState: QuizUiState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package dev.adriankuta.kahootquiz.ui.quiz
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dev.adriankuta.kahootquiz.domain.models.Quiz
|
||||
import dev.adriankuta.kahootquiz.domain.usecases.GetQuizUseCase
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class QuizScreenViewModel @Inject constructor(
|
||||
private val getQuizUseCase: GetQuizUseCase
|
||||
) : ViewModel() {
|
||||
private val _uiState = MutableStateFlow(QuizUiState())
|
||||
val uiState: StateFlow<QuizUiState> = _uiState.asStateFlow()
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
_uiState.value = QuizUiState(getQuizUseCase())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data class QuizUiState(
|
||||
val quiz: Quiz? = null
|
||||
)
|
@@ -0,0 +1,14 @@
|
||||
package dev.adriankuta.kahootquiz.ui.quiz.navigation
|
||||
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.compose.composable
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data object QuizRoute
|
||||
|
||||
fun NavGraphBuilder.quizScreen() {
|
||||
composable<QuizRoute> {
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user