Fix extension search query cursor and debounce (#8972)

* Fix extension search query cursor

* debounce

* extract debounce constant

(cherry picked from commit 1a319601de03d91131a7ad3b39fe6a8bf75e6ebb)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/BrowseTab.kt
This commit is contained in:
stevenyomi 2023-01-23 05:19:46 +08:00 committed by Jobobby04
parent 887757691c
commit b5df879392
6 changed files with 17 additions and 14 deletions

View File

@ -61,7 +61,7 @@ import exh.source.anyIs
fun ExtensionScreen(
state: ExtensionsState,
contentPadding: PaddingValues,
searchQuery: String? = null,
searchQuery: String?,
onLongClickItem: (Extension) -> Unit,
onClickItemCancel: (Extension) -> Unit,
onInstallExtension: (Extension.Available) -> Unit,

View File

@ -48,6 +48,8 @@ import eu.kanade.presentation.util.runOnEnterKeyPressed
import eu.kanade.presentation.util.secondaryItemAlpha
import eu.kanade.tachiyomi.R
const val SEARCH_DEBOUNCE_MILLIS = 250L
@Composable
fun AppBar(
modifier: Modifier = Modifier,

View File

@ -57,7 +57,7 @@ data class BrowseTab(
// Hoisted for extensions tab's search bar
val extensionsScreenModel = rememberScreenModel { ExtensionsScreenModel() }
val extensionsQuery by extensionsScreenModel.query.collectAsState()
val extensionsState by extensionsScreenModel.state.collectAsState()
TabbedScreen(
titleRes = R.string.browse,
@ -79,7 +79,7 @@ data class BrowseTab(
},
startIndex = 2.takeIf { toExtensions },
// SY <--
searchQuery = extensionsQuery,
searchQuery = extensionsState.searchQuery,
onChangeSearchQuery = extensionsScreenModel::search,
)

View File

@ -6,6 +6,7 @@ import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.coroutineScope
import eu.kanade.domain.extension.interactor.GetExtensionsByType
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.presentation.components.SEARCH_DEBOUNCE_MILLIS
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.extension.model.Extension
@ -15,11 +16,12 @@ import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.system.LocaleHelper
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import rx.Observable
@ -33,9 +35,6 @@ class ExtensionsScreenModel(
private val getExtensions: GetExtensionsByType = Injekt.get(),
) : StateScreenModel<ExtensionsState>(ExtensionsState()) {
private val _query: MutableStateFlow<String?> = MutableStateFlow(null)
val query: StateFlow<String?> = _query.asStateFlow()
private var _currentDownloads = MutableStateFlow<Map<String, InstallStep>>(hashMapOf())
init {
@ -74,7 +73,7 @@ class ExtensionsScreenModel(
coroutineScope.launchIO {
combine(
_query,
state.map { it.searchQuery }.distinctUntilChanged().debounce(SEARCH_DEBOUNCE_MILLIS),
_currentDownloads,
getExtensions.subscribe(),
) { query, downloads, (_updates, _installed, _available, _untrusted) ->
@ -124,8 +123,8 @@ class ExtensionsScreenModel(
}
fun search(query: String?) {
coroutineScope.launchIO {
_query.emit(query)
mutableState.update {
it.copy(searchQuery = query)
}
}
@ -211,6 +210,7 @@ data class ExtensionsState(
val isRefreshing: Boolean = false,
val items: ItemGroups = mutableMapOf(),
val updates: Int = 0,
val searchQuery: String? = null,
) {
val isEmpty = items.isEmpty()
}

View File

@ -21,7 +21,6 @@ fun extensionsTab(
): TabContent {
val navigator = LocalNavigator.currentOrThrow
val state by extensionsScreenModel.state.collectAsState()
val searchQuery by extensionsScreenModel.query.collectAsState()
return TabContent(
titleRes = R.string.label_extensions,
@ -38,7 +37,7 @@ fun extensionsTab(
ExtensionScreen(
state = state,
contentPadding = contentPadding,
searchQuery = searchQuery,
searchQuery = state.searchQuery,
onLongClickItem = { extension ->
when (extension) {
is Extension.Available -> extensionsScreenModel.installExtension(extension)

View File

@ -37,6 +37,7 @@ import eu.kanade.domain.manga.model.isLocal
import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.domain.track.interactor.GetTracks
import eu.kanade.domain.track.interactor.GetTracksPerManga
import eu.kanade.presentation.components.SEARCH_DEBOUNCE_MILLIS
import eu.kanade.presentation.library.components.LibraryToolbarTitle
import eu.kanade.presentation.manga.DownloadAction
import eu.kanade.tachiyomi.R
@ -80,6 +81,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
@ -156,7 +158,7 @@ class LibraryScreenModel(
init {
coroutineScope.launchIO {
combine(
state.map { it.searchQuery }.distinctUntilChanged(),
state.map { it.searchQuery }.distinctUntilChanged().debounce(SEARCH_DEBOUNCE_MILLIS),
getLibraryFlow(),
getTracksPerManga.subscribe(),
combine(