Tags list updates based on previously checked tags
parent
9f740e5bcc
commit
6735593517
|
|
@ -6,13 +6,13 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
|
|
||||||
class RecipesView : ViewModel() {
|
class RecipesView : ViewModel() {
|
||||||
private val _activeRecipe = MutableStateFlow<RecipeWithTags?>( null )
|
private val _activeRecipe = MutableStateFlow<RecipeWithTags?>(null)
|
||||||
val activeRecipe = _activeRecipe.asStateFlow()
|
val activeRecipe = _activeRecipe.asStateFlow()
|
||||||
|
|
||||||
private val _recipes = MutableStateFlow<List<RecipeWithTags>>( arrayListOf() )
|
private val _recipes = MutableStateFlow<List<RecipeWithTags>>(arrayListOf())
|
||||||
val recipes = _recipes.asStateFlow()
|
val recipes = _recipes.asStateFlow()
|
||||||
|
|
||||||
private val _tagFilters = MutableStateFlow<List<TagFilter>>( arrayListOf() )
|
private val _tagFilters = MutableStateFlow<List<TagFilter>>(arrayListOf())
|
||||||
val tagFilters = _tagFilters.asStateFlow()
|
val tagFilters = _tagFilters.asStateFlow()
|
||||||
|
|
||||||
private val _search = MutableStateFlow<String?>(null)
|
private val _search = MutableStateFlow<String?>(null)
|
||||||
|
|
@ -22,11 +22,42 @@ class RecipesView : ViewModel() {
|
||||||
val keepScreenOn = _keepScreenOn.asStateFlow()
|
val keepScreenOn = _keepScreenOn.asStateFlow()
|
||||||
|
|
||||||
fun reloadTagFilterState() {
|
fun reloadTagFilterState() {
|
||||||
_tagFilters.value = _tagFilters.value
|
// TODO Honestly quite a messy bit of logic, would be nice to have a more streamlined function here.
|
||||||
|
|
||||||
|
// If this is empty that means no filters are active, which means we don't do any special tag counting
|
||||||
|
val activeFilterNames = _tagFilters.value.filter { f -> f.checked }.map { f -> f.tag }
|
||||||
|
val filtersMap = mutableMapOf<String, Int>()
|
||||||
|
|
||||||
|
_recipes.value.stream()
|
||||||
|
.filter { it.tags.isNotEmpty() }
|
||||||
|
.filter {
|
||||||
|
if (activeFilterNames.isNotEmpty()) {
|
||||||
|
it.tags.count { t -> activeFilterNames.contains(t.name) } >= activeFilterNames.size
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.forEach {
|
||||||
|
it.tags.forEach { tag ->
|
||||||
|
val count = filtersMap[tag.name] ?: 0
|
||||||
|
filtersMap[tag.name] = count + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeFilterNames.isNotEmpty()) {
|
||||||
|
_tagFilters.value = _tagFilters.value.map {
|
||||||
|
it.count = filtersMap[it.tag] ?: 0
|
||||||
|
it
|
||||||
|
}.toList()
|
||||||
|
} else {
|
||||||
|
val filters = filtersMap.map { TagFilter(it.key, count = it.value) }.toList()
|
||||||
|
_tagFilters.update { filters.distinct().sortedBy { it.tag } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setTagFilterState(tag: String, state: Boolean) {
|
fun setTagFilterState(tag: String, state: Boolean) {
|
||||||
_tagFilters.value = _tagFilters.value.toMutableList().apply { replaceAll { it -> if (tag == it.tag) it.checked = state; it } }.toList()
|
_tagFilters.value = _tagFilters.value.toMutableList()
|
||||||
|
.apply { replaceAll { it -> if (tag == it.tag) it.checked = state; it } }.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setKeepScreenOn(flag: Boolean) {
|
fun setKeepScreenOn(flag: Boolean) {
|
||||||
|
|
@ -48,7 +79,6 @@ class RecipesView : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
val filters = filtersMap.map { it -> TagFilter(it.key, count = it.value) }.toList()
|
val filters = filtersMap.map { it -> TagFilter(it.key, count = it.value) }.toList()
|
||||||
|
|
||||||
_tagFilters.update { filters.distinct().sortedBy { it.tag } }
|
_tagFilters.update { filters.distinct().sortedBy { it.tag } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,12 @@ import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.icons.filled.Settings
|
||||||
|
import androidx.compose.material3.Badge
|
||||||
|
import androidx.compose.material3.BadgedBox
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
|
@ -43,6 +46,8 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
val search = view.search.collectAsState()
|
val search = view.search.collectAsState()
|
||||||
val filters = view.tagFilters.collectAsState()
|
val filters = view.tagFilters.collectAsState()
|
||||||
|
|
||||||
|
var activeTags = 0
|
||||||
|
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
|
|
||||||
var openDeletionDialog by remember { mutableStateOf(false) }
|
var openDeletionDialog by remember { mutableStateOf(false) }
|
||||||
|
|
@ -123,6 +128,15 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier.weight(0.1f),
|
modifier = Modifier.weight(0.1f),
|
||||||
onClick = { openTagFilterDialog = true },
|
onClick = { openTagFilterDialog = true },
|
||||||
|
) {
|
||||||
|
BadgedBox(
|
||||||
|
badge = {
|
||||||
|
if (activeTags > 0) {
|
||||||
|
Badge {
|
||||||
|
Text("$activeTags")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = ImageVector.vectorResource(R.drawable.filter_24),
|
imageVector = ImageVector.vectorResource(R.drawable.filter_24),
|
||||||
|
|
@ -130,6 +144,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Options
|
// Options
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier.weight(0.1f),
|
modifier = Modifier.weight(0.1f),
|
||||||
|
|
@ -195,6 +210,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
onAccept = {
|
onAccept = {
|
||||||
openTagFilterDialog = false
|
openTagFilterDialog = false
|
||||||
view.reloadTagFilterState()
|
view.reloadTagFilterState()
|
||||||
|
activeTags = filters.value.count { f -> f.checked }
|
||||||
},
|
},
|
||||||
view,
|
view,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue