Realtime update of the tags list

master
Wynd 2026-03-01 14:54:11 +02:00
parent 9131a028a3
commit 0507bbf4c7
3 changed files with 24 additions and 48 deletions

View File

@ -44,20 +44,14 @@ class RecipesView : ViewModel() {
}
}
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 } }
}
val filters = filtersMap.map { TagFilter(it.key, checked = activeFilterNames.contains(it.key), count = it.value) }
_tagFilters.update { filters.distinct().sortedBy { it.tag }.toList() }
}
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.map { if (tag == it.tag) it.checked = state; it }
this.reloadTagFilterState()
}
fun setKeepScreenOn(flag: Boolean) {
@ -67,19 +61,7 @@ class RecipesView : ViewModel() {
fun setRecipes(recipes: List<RecipeWithTags>) {
_recipes.update { recipes.sortedBy { it.recipe.title } }
val filtersMap = mutableMapOf<String, Int>()
_recipes.value.stream()
.filter { it.tags.isNotEmpty() }
.forEach {
it.tags.forEach { tag ->
val count = filtersMap[tag.name] ?: 0
filtersMap[tag.name] = count + 1;
}
}
val filters = filtersMap.map { it -> TagFilter(it.key, count = it.value) }.toList()
_tagFilters.update { filters.distinct().sortedBy { it.tag } }
this.reloadTagFilterState()
}
fun removeRecipe(recipe: RecipeWithTags) {

View File

@ -42,12 +42,12 @@ import java.io.File
@Composable
fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
val recipes = view.recipes.collectAsState()
val active = view.activeRecipe.collectAsState()
val search = view.search.collectAsState()
val filters = view.tagFilters.collectAsState()
val recipes by view.recipes.collectAsState()
val active by view.activeRecipe.collectAsState()
val search by view.search.collectAsState()
val filters by view.tagFilters.collectAsState()
var activeRecipes = remember { recipes.value }
var activeRecipes by remember { mutableStateOf(recipes) }
var activeTags = 0
val navController = rememberNavController()
@ -73,11 +73,11 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
modifier = Modifier
.weight(0.7f)
.padding(end = 4.dp),
value = search.value.orEmpty(),
value = search.orEmpty(),
onValueChange = { search ->
view.setSearch(search)
activeRecipes =
recipes.value.filter { filterRecipe(it, search, filters.value) }
recipes.filter { filterRecipe(it, search, filters) }
},
)
// Tags / Delete
@ -178,12 +178,12 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
onAccept = {
openTagFilterDialog = false
view.reloadTagFilterState()
activeTags = filters.value.count { f -> f.checked }
activeRecipes = recipes.value.filter {
activeTags = filters.count { f -> f.checked }
activeRecipes = recipes.filter {
filterRecipe(
it,
search.value,
filters.value
search,
filters
)
}
},
@ -193,7 +193,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
}
}
composable("info") {
RecipeInfo(ctx, view, navController, padding, active.value!!)
RecipeInfo(ctx, view, navController, padding, active!!)
}
composable("settings") {
SettingsScreen(ctx, navController)

View File

@ -16,20 +16,23 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import xyz.pixelatedw.recipe.data.RecipesView
@Composable
fun TagFilterDialog(onAccept: () -> Unit, view: RecipesView) {
val filters = view.tagFilters.collectAsState()
val filters by view.tagFilters.collectAsState()
Dialog(onDismissRequest = { }) {
Card(
@ -46,19 +49,11 @@ fun TagFilterDialog(onAccept: () -> Unit, view: RecipesView) {
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
.wrapContentSize(Alignment.TopStart)
) {
items(filters.value) { tag ->
if (tag.count <= 0) {
return@items
}
// TODO This doesn't really feel right lmao, but for now it works
val filterChecked = remember { mutableStateOf(tag.checked) }
items(filters) { tag ->
Row(
verticalAlignment = Alignment.CenterVertically
) {
Checkbox(checked = filterChecked.value, onCheckedChange = {
filterChecked.value = !tag.checked
Checkbox(checked = tag.checked, onCheckedChange = {
view.setTagFilterState(tag.tag, !tag.checked)
})
TextButton(
@ -68,7 +63,6 @@ fun TagFilterDialog(onAccept: () -> Unit, view: RecipesView) {
containerColor = Color.Transparent
),
onClick = {
filterChecked.value = !tag.checked
view.setTagFilterState(tag.tag, !tag.checked)
}
) {