Add a filter in the quest list screen to filter out finished quest.

This commit is contained in:
Andres Gomez, Thomas (ITDV RL) 2024-05-30 15:14:28 +02:00
parent b14e836d80
commit be6d5c0063
2 changed files with 40 additions and 2 deletions

View file

@ -4,6 +4,7 @@ import android.content.res.Configuration
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -22,6 +23,8 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Switch
import androidx.compose.material3.SwitchDefaults
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -85,12 +88,18 @@ fun QuestListScreen(
refreshState = refresh, refreshState = refresh,
refreshing = viewModel.isLoading, refreshing = viewModel.isLoading,
isFabExpended = isFabExpended, isFabExpended = isFabExpended,
filterOutFinishedQuest = viewModel.filterOutFinishedQuest,
onBack = { onBack = {
screen.popBackStack() screen.popBackStack()
}, },
onSearch = { onSearch = {
screen.navigateToSearch(enableQuests = true) screen.navigateToSearch(enableQuests = true)
}, },
onFilter = {
scope.launch {
viewModel.toggleFinishedQuestFilter(it)
}
},
onItem = { onItem = {
screen.navigateToQuestDetail(id = it.id) screen.navigateToQuestDetail(id = it.id)
}, },
@ -102,7 +111,10 @@ fun QuestListScreen(
} }
} }
@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class) @OptIn(
ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class,
ExperimentalFoundationApi::class
)
@Composable @Composable
private fun QuestListContent( private fun QuestListContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ -110,8 +122,10 @@ private fun QuestListContent(
refreshState: PullRefreshState, refreshState: PullRefreshState,
refreshing: State<Boolean>, refreshing: State<Boolean>,
isFabExpended: State<Boolean>, isFabExpended: State<Boolean>,
filterOutFinishedQuest: State<Boolean>,
onBack: () -> Unit, onBack: () -> Unit,
onSearch: () -> Unit, onSearch: () -> Unit,
onFilter: (Boolean) -> Unit,
items: State<List<QuestGroupUio>>, items: State<List<QuestGroupUio>>,
onItem: (QuestItemUio) -> Unit, onItem: (QuestItemUio) -> Unit,
) { ) {
@ -133,6 +147,13 @@ private fun QuestListContent(
title = { title = {
Text(text = stringResource(id = R.string.quest_list__title)) Text(text = stringResource(id = R.string.quest_list__title))
}, },
actions = {
Switch(
checked = filterOutFinishedQuest.value,
onCheckedChange = onFilter,
colors = SwitchDefaults.colors(),
)
}
) )
}, },
) { paddingValues -> ) { paddingValues ->
@ -250,8 +271,10 @@ private fun QuestListPreview() {
) )
}, },
isFabExpended = remember { mutableStateOf(true) }, isFabExpended = remember { mutableStateOf(true) },
filterOutFinishedQuest = remember { mutableStateOf(true) },
onBack = { }, onBack = { },
onSearch = { }, onSearch = { },
onFilter = { },
onItem = { }, onItem = { },
) )
} }

View file

@ -2,7 +2,9 @@ package com.pixelized.rplexicon.ui.screens.quest.list
import android.app.Application import android.app.Application
import android.util.Log import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
@ -18,6 +20,7 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -40,13 +43,21 @@ class QuestListViewModel @Inject constructor(
private val _error = MutableSharedFlow<FetchErrorUio>() private val _error = MutableSharedFlow<FetchErrorUio>()
val error: SharedFlow<FetchErrorUio> get() = _error val error: SharedFlow<FetchErrorUio> get() = _error
private val _filterOutFinishedQuest = MutableStateFlow(true)
val filterOutFinishedQuest: State<Boolean>
@Composable
get() = _filterOutFinishedQuest.collectAsState()
init { init {
viewModelScope.launch { viewModelScope.launch {
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
order.data.combine(repository.data) { _, quests -> quests } _filterOutFinishedQuest
.combine(order.data) { _, _ -> }
.combine(repository.data) { _, quests -> quests }
.collect { items -> .collect { items ->
val quests = items val quests = items
.asSequence() .asSequence()
.filter { _filterOutFinishedQuest.value.not() || it.complete.not() }
.sortedBy { it.title } .sortedBy { it.title }
.sortedBy { it.complete } .sortedBy { it.complete }
.groupBy( .groupBy(
@ -130,6 +141,10 @@ class QuestListViewModel @Inject constructor(
} }
} }
suspend fun toggleFinishedQuestFilter(filter: Boolean) {
_filterOutFinishedQuest.emit(filter)
}
companion object { companion object {
const val TAG = "QuestListViewModel" const val TAG = "QuestListViewModel"
} }