Skip to content

Commit

Permalink
Revamped Quick Question Screen (#60)
Browse files Browse the repository at this point in the history
* Spotless

* Revamped quick questions

* Refactor snackbar and slide down to up text animation with DRY
  • Loading branch information
JackEblan authored Sep 21, 2024
1 parent c3ef678 commit 071513c
Show file tree
Hide file tree
Showing 16 changed files with 103 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@
*/
package com.eblan.socialworkreviewer.navigation

import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController
Expand All @@ -42,7 +40,6 @@ import com.eblan.socialworkreviewer.navigation.TopLevelDestination.ABOUT
import com.eblan.socialworkreviewer.navigation.TopLevelDestination.CATEGORY
import com.eblan.socialworkreviewer.navigation.TopLevelDestination.NEWS
import com.eblan.socialworkreviewer.navigation.TopLevelDestination.SETTINGS
import kotlinx.coroutines.launch

@Composable
fun SwrNavHost(modifier: Modifier = Modifier) {
Expand All @@ -52,8 +49,6 @@ fun SwrNavHost(modifier: Modifier = Modifier) {
SnackbarHostState()
}

val scope = rememberCoroutineScope()

NavHost(
modifier = modifier,
navController = swrNavHostController,
Expand All @@ -71,28 +66,14 @@ fun SwrNavHost(modifier: Modifier = Modifier) {
ABOUT -> homeNavHostController.navigateToAboutScreen()
}
},
onShowSnackBar = { message ->
scope.launch {
snackbarHostState.showSnackbar(
message = message,
duration = SnackbarDuration.Indefinite,
)
}
},
builder = {
categoryScreen(onCategoryClick = swrNavHostController::navigateToQuestionScreen)

newsScreen()

settingsScreen()

aboutScreen(
onShowSnackBar = { message ->
scope.launch {
snackbarHostState.showSnackbar(message = message)
}
},
)
aboutScreen(snackbarHostState = snackbarHostState)
},
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ enum class TopLevelDestination(
icon = Swr.Info,
contentDescription = R.string.about,
route = AboutRouteData::class,
)
),
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,6 @@ internal class DefaultInMemoryChoiceDataSource @Inject constructor(
)
}

override suspend fun getScore(): Int {
return withContext(defaultDispatcher) {
getQuestionsWithSelectedChoices().count {
it.value.toSet() == it.key.correctChoices.toSet()
}
}
}

private suspend fun getQuestionsWithSelectedChoices(): Map<Question, List<String>> {
return withContext(defaultDispatcher) {
_selectedChoices.groupBy({ it.question }, { it.choice })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,4 @@ interface InMemoryChoiceDataSource {
fun clearCache()

suspend fun addCurrentQuestion(question: Question)

suspend fun getScore(): Int
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue

Expand Down Expand Up @@ -179,25 +178,4 @@ class InMemoryChoiceDataSourceTest {

assertNotNull(inMemoryChoiceDataSource.currentQuestionData.replayCache.firstOrNull())
}

@Test
fun getScore() = runTest {
val question = Question(
question = "Question",
correctChoices = listOf(""),
wrongChoices = listOf(),
choices = listOf(""),
)

val choice = Choice(
question = question,
choice = "",
)

inMemoryChoiceDataSource.addChoice(choice = choice)

inMemoryChoiceDataSource.addCurrentQuestion(question = question)

assertEquals(expected = 1, actual = inMemoryChoiceDataSource.getScore())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,4 @@ interface ChoiceRepository {
fun clearCache()

suspend fun addCurrentQuestion(question: Question)

suspend fun getScore(): Int
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,4 @@ internal class DefaultChoiceRepository @Inject constructor(
override suspend fun addCurrentQuestion(question: Question) {
inMemoryChoiceDataSource.addCurrentQuestion(question)
}

override suspend fun getScore(): Int {
return inMemoryChoiceDataSource.getScore()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,6 @@ class FakeChoiceRepository : ChoiceRepository {
)
}

override suspend fun getScore(): Int {
return getQuestionsWithSelectedChoices().count {
it.value.toSet() == it.key.correctChoices.toSet()
}
}

private fun getQuestionsWithSelectedChoices(): Map<Question, List<String>> {
return _selectedChoices.groupBy({ it.question }, { it.choice })
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
Expand All @@ -58,16 +59,16 @@ import com.eblan.socialworkreviewer.core.model.About
@Composable
internal fun AboutRoute(
modifier: Modifier = Modifier,
snackbarHostState: SnackbarHostState,
viewModel: AboutViewModel = hiltViewModel(),
onShowSnackBar: (String) -> Unit,
) {
val aboutUiState = viewModel.aboutUiState.collectAsStateWithLifecycle().value

val openLinkResult = viewModel.openLinkResult.collectAsStateWithLifecycle().value

LaunchedEffect(key1 = openLinkResult) {
if (openLinkResult != null && openLinkResult.not()) {
onShowSnackBar("Invalid link")
snackbarHostState.showSnackbar(message = "Invalid link")
viewModel.resetOpenLinkResult()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package com.eblan.socialworkreviewer.feature.about.navigation

import androidx.compose.material3.SnackbarHostState
import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavGraphBuilder
Expand All @@ -33,8 +34,8 @@ fun NavController.navigateToAboutScreen() {
}
}

fun NavGraphBuilder.aboutScreen(onShowSnackBar: (String) -> Unit) {
fun NavGraphBuilder.aboutScreen(snackbarHostState: SnackbarHostState) {
composable<AboutRouteData> {
AboutRoute(onShowSnackBar = onShowSnackBar)
AboutRoute(snackbarHostState = snackbarHostState)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
Expand Down Expand Up @@ -60,7 +61,6 @@ internal fun HomeRoute(
topLevelDestinations: List<HomeDestination>,
startDestination: KClass<*>,
onItemClick: (NavHostController, HomeDestination) -> Unit,
onShowSnackBar: (String) -> Unit,
builder: NavGraphBuilder.() -> Unit,
) {
val isOnline = viewModel.isOnline.collectAsStateWithLifecycle().value
Expand All @@ -73,7 +73,6 @@ internal fun HomeRoute(
startDestination = startDestination,
isOnline = isOnline,
onItemClick = onItemClick,
onShowSnackBar = onShowSnackBar,
builder = builder,
)
}
Expand All @@ -88,7 +87,6 @@ internal fun HomeScreen(
startDestination: KClass<*>,
isOnline: Boolean?,
onItemClick: (NavHostController, HomeDestination) -> Unit,
onShowSnackBar: (String) -> Unit,
builder: NavGraphBuilder.() -> Unit,
) {
val topAppBarScrollBehavior = enterAlwaysScrollBehavior()
Expand All @@ -101,7 +99,12 @@ internal fun HomeScreen(

LaunchedEffect(key1 = isOnline) {
if (isOnline != null && isOnline.not()) {
onShowSnackBar("No internet connection")
snackbarHostState.showSnackbar(
message = "No internet connection",
duration = SnackbarDuration.Indefinite,
)
} else {
snackbarHostState.currentSnackbarData?.dismiss()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ fun NavGraphBuilder.homeScreen(
topLevelDestinations: List<HomeDestination>,
startDestination: KClass<*>,
onItemClick: (NavHostController, HomeDestination) -> Unit,
onShowSnackBar: (String) -> Unit,
builder: NavGraphBuilder.() -> Unit,
) {
composable<HomeRouteData> {
Expand All @@ -38,7 +37,6 @@ fun NavGraphBuilder.homeScreen(
topLevelDestinations = topLevelDestinations,
startDestination = startDestination,
onItemClick = onItemClick,
onShowSnackBar = onShowSnackBar,
builder = builder,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,8 @@ class QuestionViewModel @Inject constructor(
}
}

fun showCorrectChoices(questionSettingIndex: Int, questions: List<Question>) {
fun showCorrectChoices(questionSettingIndex: Int, questions: List<Question>, score: Int) {
viewModelScope.launch {
val score = choiceRepository.getScore()

_questionUiState.update {
QuestionUiState.CorrectChoices(
questions = questions,
Expand Down
Loading

0 comments on commit 071513c

Please sign in to comment.