diff --git a/composeApp/src/commonMain/kotlin/App.kt b/composeApp/src/commonMain/kotlin/App.kt index 33de674..2184c66 100644 --- a/composeApp/src/commonMain/kotlin/App.kt +++ b/composeApp/src/commonMain/kotlin/App.kt @@ -7,10 +7,21 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController +import androidx.navigation.toRoute import screens.questionScreen import screens.scoreScreen import screens.welcomeScreen import kotlin.random.Random +import kotlinx.serialization.Serializable + +@Serializable +object WelcomeRoute + +@Serializable +object QuizRoute + +@Serializable +data class ScoreRoute(val score: Int, val questionSize: Int) @Composable fun App( @@ -21,28 +32,141 @@ fun App( MaterialTheme { NavHost( navController = navController, - startDestination = "/welcome", + startDestination = WelcomeRoute, ) { - composable(route = "/welcome") { + composable() { welcomeScreen( onStartButtonPushed = { - navController.navigate(route = "/quiz") + navController.navigate(route = QuizRoute) } ) } - composable(route = "/quiz") { + composable() { val questions by viewModel.questionState.collectAsState() // random manga character names - val nicknames = listOf("Naruto", "Goku", "Luffy", "Ichigo", "Saitama", "Kenshin", "Yusuke", "Gon", "Killua", "Natsu", - "Gon", "Gintoki", "Koro-sensei", "Kakashi", "Vegeta", "Sasuke", "Zoro", "Sanji", "Shanks", "Ace", "Kaido", "Katakuri", - "Law", "Deku", "Bakugo", "Todoroki", "All Might", "Asta", "Yuno", "Yami", "Julius", "Licht", "Nero", "Grimm", "Gordon", - "Yami", "Magna", "Luck", "Noelle", "Mimosa", "Vanessa", "Finral", "Charmy", "Gordon", "Grey", "Gimodelo", "Zora", "Mereoleona", - "Fuegoleon", "Leopold", "Kahono", "Kiato", "Yuno", "Yami", "Julius", "Licht", "Nero", "Grimm", "Gordon", "Yami", "Magna", - "Luck", "Noelle", "Mimosa", "Vanessa", "Finral", "Charmy", "Gordon", "Grey", "Gimodelo", "Zora", "Mereoleona", "Fuegoleon", - "Leopold", "Kahono", "Kiato", "Yuno", "Yami", "Julius", "Licht", "Nero", "Grimm", "Gordon", "Yami", "Magna", "Luck", "Noelle", - "Mimosa", "Vanessa", "Finral", "Charmy", "Gordon", "Grey", "Gimodelo", "Zora", "Mereoleona", "Fuegoleon", "Leopold", "Kahono", - "Kiato", "Yuno", "Yami", "Julius", "Licht", "Nero", "Grimm", "Gordon", "Yami", "Magna", "Luck", "Noelle", "Mimosa", "Vanessa", - "Finral", "Charmy", "Gordon", "Grey", "Gimodelo", "Zora", "Mereoleona", "Fuegoleon") + val nicknames = listOf( + "Naruto", + "Goku", + "Luffy", + "Ichigo", + "Saitama", + "Kenshin", + "Yusuke", + "Gon", + "Killua", + "Natsu", + "Gon", + "Gintoki", + "Koro-sensei", + "Kakashi", + "Vegeta", + "Sasuke", + "Zoro", + "Sanji", + "Shanks", + "Ace", + "Kaido", + "Katakuri", + "Law", + "Deku", + "Bakugo", + "Todoroki", + "All Might", + "Asta", + "Yuno", + "Yami", + "Julius", + "Licht", + "Nero", + "Grimm", + "Gordon", + "Yami", + "Magna", + "Luck", + "Noelle", + "Mimosa", + "Vanessa", + "Finral", + "Charmy", + "Gordon", + "Grey", + "Gimodelo", + "Zora", + "Mereoleona", + "Fuegoleon", + "Leopold", + "Kahono", + "Kiato", + "Yuno", + "Yami", + "Julius", + "Licht", + "Nero", + "Grimm", + "Gordon", + "Yami", + "Magna", + "Luck", + "Noelle", + "Mimosa", + "Vanessa", + "Finral", + "Charmy", + "Gordon", + "Grey", + "Gimodelo", + "Zora", + "Mereoleona", + "Fuegoleon", + "Leopold", + "Kahono", + "Kiato", + "Yuno", + "Yami", + "Julius", + "Licht", + "Nero", + "Grimm", + "Gordon", + "Yami", + "Magna", + "Luck", + "Noelle", + "Mimosa", + "Vanessa", + "Finral", + "Charmy", + "Gordon", + "Grey", + "Gimodelo", + "Zora", + "Mereoleona", + "Fuegoleon", + "Leopold", + "Kahono", + "Kiato", + "Yuno", + "Yami", + "Julius", + "Licht", + "Nero", + "Grimm", + "Gordon", + "Yami", + "Magna", + "Luck", + "Noelle", + "Mimosa", + "Vanessa", + "Finral", + "Charmy", + "Gordon", + "Grey", + "Gimodelo", + "Zora", + "Mereoleona", + "Fuegoleon" + ) if (questions.isNotEmpty()) { questionScreen( @@ -52,7 +176,7 @@ fun App( score, "${nicknames.random()}-${Random.nextInt(1000)}" ) - navController.navigate(route = "/score/$score/$questionSize") + navController.navigate(route = ScoreRoute(score, questionSize)) }, /* FOR SPEAKER TALK DEMO ON WEB APP */ onSaveStatQuestion = { id: Long, question: String, answerId: Long, correctAnswerId: Long, answer: String -> @@ -61,16 +185,16 @@ fun App( ) } } - composable(route = "/score/{score}/{total}") { + composable { backStackEntry -> + val scoreRoute: ScoreRoute = backStackEntry.toRoute() scoreScreen( - score = it.arguments?.getString("score").toString(), - total = it.arguments?.getString("total").toString(), + score = scoreRoute.score, + total = scoreRoute.questionSize, onResetButtonPushed = { - navController.navigate(route = "/quiz") + navController.navigate(route = QuizRoute) } ) } - } } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/data/QuizRepository.kt b/composeApp/src/commonMain/kotlin/data/QuizRepository.kt index 8e75a26..a679775 100755 --- a/composeApp/src/commonMain/kotlin/data/QuizRepository.kt +++ b/composeApp/src/commonMain/kotlin/data/QuizRepository.kt @@ -8,7 +8,7 @@ import data.datasources.QuizKStoreDataSource import data.datasources.StatsApiDatasource import kotlinx.datetime.Clock -class QuizRepository { +class QuizRepository { private val mockDataSource = MockDataSource() private val quizApiDatasource = QuizApiDatasource() @@ -16,21 +16,22 @@ class QuizRepository { private suspend fun fetchQuiz(): List = quizApiDatasource.getAllQuestions().questions - /* FOR SPEAKER TALK DEMO ON WEB APP */ private val statsDataSource = StatsApiDatasource() + /* FOR SPEAKER TALK DEMO ON WEB APP */ private val statsDataSource = StatsApiDatasource() - private suspend fun fetchAndStoreQuiz(): List{ + private suspend fun fetchAndStoreQuiz(): List { quizKStoreDataSource.resetQuizKstore() - val questions = fetchQuiz() + val questions = fetchQuiz() quizKStoreDataSource.insertQuestions(questions) quizKStoreDataSource.setUpdateTimeStamp(Clock.System.now().epochSeconds) return questions } - suspend fun updateQuiz():List{ + + suspend fun updateQuiz(): List { try { val lastRequest = quizKStoreDataSource.getUpdateTimeStamp() - return if(lastRequest == 0L || lastRequest - Clock.System.now().epochSeconds > 300000){ + return if (lastRequest == 0L || lastRequest - Clock.System.now().epochSeconds > 300000) { fetchAndStoreQuiz() - }else{ + } else { quizKStoreDataSource.getAllQuestions() } } catch (e: NullPointerException) { @@ -42,7 +43,7 @@ class QuizRepository { } /* FOR SPEAKER TALK DEMO ON WEB APP */ - suspend fun storeStats(nickname:String, score: Int, responses : List){ - statsDataSource.postQuestionStats(score,nickname,responses) + suspend fun storeStats(nickname: String, score: Int, responses: List) { + statsDataSource.postQuestionStats(score, nickname, responses) } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/screens/ScoreScreen.kt b/composeApp/src/commonMain/kotlin/screens/ScoreScreen.kt index 17da2fa..5bd9bac 100755 --- a/composeApp/src/commonMain/kotlin/screens/ScoreScreen.kt +++ b/composeApp/src/commonMain/kotlin/screens/ScoreScreen.kt @@ -20,11 +20,11 @@ import org.jetbrains.compose.ui.tooling.preview.Preview @Composable internal fun scoreScreenPreview() { val onResetButtonPushed = { } - scoreScreen(onResetButtonPushed, score = "10", total = "10") + scoreScreen(onResetButtonPushed, score = 10, total = 10) } @Composable -internal fun scoreScreen(onResetButtonPushed: () -> Unit, score: String, total: String) { +internal fun scoreScreen(onResetButtonPushed: () -> Unit, score: Int, total: Int) { Box( contentAlignment = Alignment.Center, modifier = Modifier.fillMaxWidth().fillMaxHeight() @@ -45,7 +45,7 @@ internal fun scoreScreen(onResetButtonPushed: () -> Unit, score: String, total: fontSize = 30.sp, text = "$score/$total", ) - + Button( modifier = Modifier.padding(all = 20.dp), onClick = { @@ -61,7 +61,7 @@ internal fun scoreScreen(onResetButtonPushed: () -> Unit, score: String, total: } } -private fun generateScoringColor(score: String, total: String): Color { +private fun generateScoringColor(score: Int, total: Int): Color { val percentage = (score.toFloat() / total.toFloat()) * 100 return when { percentage <= 40 -> Color.Red // red diff --git a/composeApp/src/commonMain/kotlin/screens/WelcomeScreen.kt b/composeApp/src/commonMain/kotlin/screens/WelcomeScreen.kt index db0684b..71e686d 100755 --- a/composeApp/src/commonMain/kotlin/screens/WelcomeScreen.kt +++ b/composeApp/src/commonMain/kotlin/screens/WelcomeScreen.kt @@ -1,4 +1,5 @@ package screens + import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape @@ -21,12 +22,12 @@ import quiz.composeapp.generated.resources.question @Preview @Composable internal fun welcomeScreenPreview() { - val onStartButtonPushed = { } + val onStartButtonPushed = { } welcomeScreen(onStartButtonPushed) } @Composable -internal fun welcomeScreen(onStartButtonPushed: () -> Unit) { +fun welcomeScreen(onStartButtonPushed: () -> Unit) { Box( contentAlignment = Alignment.Center, modifier = Modifier.fillMaxWidth().fillMaxHeight() @@ -35,33 +36,33 @@ internal fun welcomeScreen(onStartButtonPushed: () -> Unit) { shape = RoundedCornerShape(8.dp), modifier = Modifier.padding(10.dp), ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Image( - modifier = Modifier.size(70.dp), - painter = painterResource(Res.drawable.question), - contentDescription = null - ) - Text( - text = "Quiz", - fontSize = 30.sp, - modifier = Modifier.padding(all = 10.dp) - ) - Text( - modifier = Modifier.padding(all = 10.dp), - text = "A simple Quiz to discovers KMP and compose.", - ) - Button( - modifier = Modifier.padding(all = 10.dp), - onClick = { onStartButtonPushed() } + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Image( + modifier = Modifier.size(70.dp), + painter = painterResource(Res.drawable.question), + contentDescription = null + ) + Text( + text = "Quiz", + fontSize = 30.sp, + modifier = Modifier.padding(all = 10.dp) + ) + Text( + modifier = Modifier.padding(all = 10.dp), + text = "A simple Quiz to discovers KMP and compose.", + ) + Button( + modifier = Modifier.padding(all = 10.dp), + onClick = { onStartButtonPushed() } - ) { - Icon( - Icons.AutoMirrored.Filled.ArrowForward, - contentDescription = "Localized description", - Modifier.padding(end = 15.dp) - ) - Text("Start the Quiz") - } + ) { + Icon( + Icons.AutoMirrored.Filled.ArrowForward, + contentDescription = "Localized description", + Modifier.padding(end = 15.dp) + ) + Text("Start the Quiz") + } } } } diff --git a/composeApp/src/desktopMain/kotlin/Platform.jvm.kt b/composeApp/src/desktopMain/kotlin/Platform.jvm.kt index c6a5cad..f4e0ea5 100644 --- a/composeApp/src/desktopMain/kotlin/Platform.jvm.kt +++ b/composeApp/src/desktopMain/kotlin/Platform.jvm.kt @@ -1,7 +1,6 @@ import data.dataclasses.Quiz import io.github.xxfast.kstore.KStore import io.github.xxfast.kstore.file.storeOf -import net.harawata.appdirs.AppDirsFactory import okio.Path.Companion.toPath class JVMPlatform : Platform {