Add filters to Global search (#9691)

* add pinned and available filter chips to global search

* split filter predicate into seperate function

* change the global search available filter to has Results

* reordering of imports
This commit is contained in:
zaghdaneh
2023-07-15 04:49:14 +02:00
committed by GitHub
parent 2f05f7b91f
commit cbcec8c4d9
4 changed files with 120 additions and 10 deletions

View File

@@ -35,6 +35,7 @@ class GlobalSearchScreen(
var showSingleLoadingScreen by remember {
mutableStateOf(searchQuery.isNotEmpty() && extensionFilter.isNotEmpty() && state.total == 1)
}
val filteredSources by screenModel.searchPagerFlow.collectAsState()
if (showSingleLoadingScreen) {
LoadingScreen()
@@ -57,10 +58,12 @@ class GlobalSearchScreen(
} else {
GlobalSearchScreen(
state = state,
items = filteredSources,
navigateUp = navigator::pop,
onChangeSearchQuery = screenModel::updateSearchQuery,
onSearch = screenModel::search,
getManga = { screenModel.getManga(it) },
onChangeFilter = screenModel::setFilter,
onClickSource = {
if (!screenModel.incognitoMode.get()) {
screenModel.lastUsedSourceId.set(it.id)

View File

@@ -3,7 +3,12 @@ package eu.kanade.tachiyomi.ui.browse.source.globalsearch
import androidx.compose.runtime.Immutable
import eu.kanade.domain.base.BasePreferences
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.util.ioCoroutineScope
import eu.kanade.tachiyomi.source.CatalogueSource
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import tachiyomi.domain.source.service.SourceManager
import uy.kohesive.injekt.Injekt
@@ -20,6 +25,13 @@ class GlobalSearchScreenModel(
val incognitoMode = preferences.incognitoMode()
val lastUsedSourceId = sourcePreferences.lastUsedSource()
val searchPagerFlow = state.map { Pair(it.searchFilter, it.items) }
.distinctUntilChanged()
.map { (filter, items) ->
items
.filter { (source, result) -> isSourceVisible(filter, source, result) }
}.stateIn(ioCoroutineScope, SharingStarted.Lazily, state.value.items)
init {
extensionFilter = initialExtensionFilter
if (initialQuery.isNotBlank() || initialExtensionFilter.isNotBlank()) {
@@ -38,6 +50,14 @@ class GlobalSearchScreenModel(
.sortedWith(compareBy({ "${it.id}" !in pinnedSources }, { "${it.name.lowercase()} (${it.lang})" }))
}
private fun isSourceVisible(filter: GlobalSearchFilter, source: CatalogueSource, result: SearchItemResult): Boolean {
return when (filter) {
GlobalSearchFilter.AvailableOnly -> result is SearchItemResult.Success && !result.isEmpty
GlobalSearchFilter.PinnedOnly -> "${source.id}" in sourcePreferences.pinnedSources().get()
GlobalSearchFilter.All -> true
}
}
override fun updateSearchQuery(query: String?) {
mutableState.update {
it.copy(searchQuery = query)
@@ -50,14 +70,23 @@ class GlobalSearchScreenModel(
}
}
fun setFilter(filter: GlobalSearchFilter) {
mutableState.update { it.copy(searchFilter = filter) }
}
override fun getItems(): Map<CatalogueSource, SearchItemResult> {
return mutableState.value.items
}
}
enum class GlobalSearchFilter {
All, PinnedOnly, AvailableOnly
}
@Immutable
data class GlobalSearchState(
val searchQuery: String? = null,
val searchFilter: GlobalSearchFilter = GlobalSearchFilter.All,
val items: Map<CatalogueSource, SearchItemResult> = emptyMap(),
) {