diff --git a/app/src/main/java/xyz/pixelatedw/recipe/ui/components/MainScreen.kt b/app/src/main/java/xyz/pixelatedw/recipe/ui/components/MainScreen.kt index f3e5c85..ca6ee14 100644 --- a/app/src/main/java/xyz/pixelatedw/recipe/ui/components/MainScreen.kt +++ b/app/src/main/java/xyz/pixelatedw/recipe/ui/components/MainScreen.kt @@ -36,6 +36,7 @@ import xyz.pixelatedw.recipe.MainActivity import xyz.pixelatedw.recipe.R import xyz.pixelatedw.recipe.data.RecipeWithTags import xyz.pixelatedw.recipe.data.RecipesView +import xyz.pixelatedw.recipe.data.TagFilter import java.io.File @@ -46,6 +47,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) { val search = view.search.collectAsState() val filters = view.tagFilters.collectAsState() + var activeRecipes = remember { recipes.value } var activeTags = 0 val navController = rememberNavController() @@ -54,42 +56,6 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) { var openTagFilterDialog by remember { mutableStateOf(false) } var selectedEntries by remember { mutableStateOf(listOf()) } - val isInSearch = isInSearch@{ entry: RecipeWithTags -> - val isSearchEmpty = search.value == null || search.value!!.isEmpty() - val hasTitle = entry.recipe.title.contains(search.value.orEmpty(), ignoreCase = true) - val hasTags = entry.tags.stream() - .filter { tag -> tag.name.contains(search.value.orEmpty(), ignoreCase = true) } - .count() > 0 - - if (!isSearchEmpty && !hasTitle && !hasTags) { - return@isInSearch false - } - - val totalFilters = filters.value.stream().filter { f -> f.checked }.count() - var checkedFilters = 0 - - for (filter in filters.value) { - if (filter.checked) { - val hasTagFilters = entry.tags.isNotEmpty() && entry.tags.stream() - .filter { tag -> tag.name.contains(filter.tag, ignoreCase = true) } - .count() > 0 - - if (hasTagFilters) { - checkedFilters += 1 - } else { - checkedFilters -= 1 - } - } - } - - val hasTagFilters = checkedFilters >= totalFilters - if (totalFilters > 0 && !hasTagFilters) { - return@isInSearch false - } - - true - } - NavHost( navController = navController, startDestination = "list" @@ -108,7 +74,11 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) { .weight(0.7f) .padding(end = 4.dp), value = search.value.orEmpty(), - onValueChange = { search -> view.setSearch(search) }, + onValueChange = { search -> + view.setSearch(search) + activeRecipes = + recipes.value.filter { filterRecipe(it, search, filters.value) } + }, ) // Tags / Delete if (selectedEntries.isNotEmpty()) { @@ -160,23 +130,21 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) { } } LazyColumn { - items(recipes.value) { entry -> - if (isInSearch(entry)) { - val isSelected = selectedEntries.contains(entry) - RecipePreview(entry, isSelected, onClick = { - view.setActive(entry) - navController.navigate("info") - }, onSelected = { flag -> - selectedEntries = - selectedEntries.toMutableList().apply { - if (flag) { - add(entry) - } else { - remove(entry) - } - }.toList() - }) - } + items(activeRecipes) { entry -> + val isSelected = selectedEntries.contains(entry) + RecipePreview(entry, isSelected, onClick = { + view.setActive(entry) + navController.navigate("info") + }, onSelected = { flag -> + selectedEntries = + selectedEntries.toMutableList().apply { + if (flag) { + add(entry) + } else { + remove(entry) + } + }.toList() + }) } } } @@ -211,6 +179,13 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) { openTagFilterDialog = false view.reloadTagFilterState() activeTags = filters.value.count { f -> f.checked } + activeRecipes = recipes.value.filter { + filterRecipe( + it, + search.value, + filters.value + ) + } }, view, ) @@ -225,3 +200,39 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) { } } } + +private fun filterRecipe( + entry: RecipeWithTags, + search: String?, + filters: List +): Boolean { + val isSearchEmpty = search.isNullOrEmpty() + val hasTitle = entry.recipe.title.contains(search.orEmpty(), ignoreCase = true) + val hasTags = entry.tags.stream() + .filter { tag -> tag.name.contains(search.orEmpty(), ignoreCase = true) } + .count() > 0 + + if (!isSearchEmpty && !hasTitle && !hasTags) { + return false + } + + val totalFilters = filters.stream().filter { f -> f.checked }.count() + var checkedFilters = 0 + + for (filter in filters) { + if (filter.checked) { + val hasTagFilters = entry.tags.isNotEmpty() && entry.tags.stream() + .filter { tag -> tag.name.contains(filter.tag, ignoreCase = true) } + .count() > 0 + + if (hasTagFilters) { + checkedFilters += 1 + } else { + checkedFilters -= 1 + } + } + } + + val hasTagFilters = checkedFilters >= totalFilters + return !(totalFilters > 0 && !hasTagFilters) +} diff --git a/app/src/main/java/xyz/pixelatedw/recipe/ui/components/TagFilterDialog.kt b/app/src/main/java/xyz/pixelatedw/recipe/ui/components/TagFilterDialog.kt index 929491f..c04077f 100644 --- a/app/src/main/java/xyz/pixelatedw/recipe/ui/components/TagFilterDialog.kt +++ b/app/src/main/java/xyz/pixelatedw/recipe/ui/components/TagFilterDialog.kt @@ -47,6 +47,10 @@ fun TagFilterDialog(onAccept: () -> Unit, view: RecipesView) { .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) }