Better filtering for both searching and tags
parent
67659a0af6
commit
357cab1afa
|
|
@ -21,6 +21,10 @@ class RecipesView : ViewModel() {
|
|||
private val _keepScreenOn = MutableStateFlow<Boolean>(false)
|
||||
val keepScreenOn = _keepScreenOn.asStateFlow()
|
||||
|
||||
fun reloadTagFilterState() {
|
||||
_tagFilters.value = _tagFilters.value
|
||||
}
|
||||
|
||||
fun setTagFilterState(tag: String, state: Boolean) {
|
||||
_tagFilters.value = _tagFilters.value.toMutableList().apply { replaceAll { it -> if (tag == it.tag) it.checked = state; it } }.toList()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import androidx.navigation.compose.rememberNavController
|
|||
import xyz.pixelatedw.recipe.MainActivity
|
||||
import xyz.pixelatedw.recipe.data.RecipeWithTags
|
||||
import xyz.pixelatedw.recipe.data.RecipesView
|
||||
import xyz.pixelatedw.recipe.data.TagFilter
|
||||
|
||||
@Composable
|
||||
fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||
|
|
@ -41,32 +40,40 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
|||
val navController = rememberNavController()
|
||||
|
||||
val isInSearch = isInSearch@{ entry: RecipeWithTags ->
|
||||
val hasTitle = search.value != null && search.value!!.isNotEmpty() && entry.recipe.title.contains(search.value.orEmpty(), ignoreCase = true)
|
||||
val hasTags = entry.tags.isNotEmpty() && entry.tags.stream()
|
||||
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
|
||||
var hasAtLeastOneFilter = false
|
||||
var hasTagFilters = false
|
||||
|
||||
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) {
|
||||
hasAtLeastOneFilter = true
|
||||
hasTagFilters = entry.tags.isNotEmpty() && entry.tags.stream()
|
||||
val hasTagFilters = entry.tags.isNotEmpty() && entry.tags.stream()
|
||||
.filter { tag -> tag.name.contains(filter.tag, ignoreCase = true) }
|
||||
.count() > 0
|
||||
|
||||
if(hasTagFilters) {
|
||||
break
|
||||
checkedFilters += 1
|
||||
}
|
||||
else {
|
||||
checkedFilters -= 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Needs much better filtering
|
||||
if (hasAtLeastOneFilter) {
|
||||
return@isInSearch hasTagFilters
|
||||
val hasTagFilters = checkedFilters >= totalFilters
|
||||
if (totalFilters > 0 && !hasTagFilters) {
|
||||
return@isInSearch false
|
||||
}
|
||||
|
||||
hasTitle || hasTags
|
||||
true
|
||||
}
|
||||
|
||||
val openTagFilterDialog = remember { mutableStateOf(false) }
|
||||
|
|
@ -127,9 +134,8 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
|||
openTagFilterDialog.value -> {
|
||||
TagFilterDialog(
|
||||
onAccept = {
|
||||
// TODO This calls twice and therefore updates the search twice too, also hella stupid updating logic
|
||||
openTagFilterDialog.value = false
|
||||
view.setTagFilterState("", true)
|
||||
view.reloadTagFilterState()
|
||||
},
|
||||
view,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import xyz.pixelatedw.recipe.data.TagFilter
|
|||
fun TagFilterDialog(onAccept: ( ) -> Unit, view: RecipesView) {
|
||||
val filters = view.tagFilters.collectAsState()
|
||||
|
||||
Dialog(onDismissRequest = onAccept) {
|
||||
Dialog(onDismissRequest = { }) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
@ -69,7 +69,9 @@ fun TagFilterDialog(onAccept: ( ) -> Unit, view: RecipesView) {
|
|||
}
|
||||
}
|
||||
|
||||
Row(modifier = Modifier.fillMaxWidth().padding(end = 16.dp), horizontalArrangement = Arrangement.End) {
|
||||
Row(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(end = 16.dp), horizontalArrangement = Arrangement.End) {
|
||||
TextButton(onClick = onAccept) {
|
||||
Text("Done")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue