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