fix: 详情页搜索等待并使用已设置的搜索范围,返回不再清空结果

This commit is contained in:
HapeLee committed 2026-06-29 02:28:17 +08:00
1 parent 5287fe6457
commit e59a5d198f
2 files changed
+28 -5

No files matched your search

@@ -23,6 +23,9 @@ import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toImmutableSet import kotlinx.collections.immutable.toImmutableSet
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
@@ -37,8 +40,6 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
@@ -87,10 +88,15 @@ class SearchViewModel(
private var persistedSearchScopeRaw = "" private var persistedSearchScopeRaw = ""
private var hasTemporaryScope = false private var hasTemporaryScope = false
private val searchScope = SearchScope("") private val searchScope = SearchScope("")
private val searchScopeReady = CompletableDeferred<Unit>()
private val preferenceWriteScope = CoroutineScope(Dispatchers.IO + SupervisorJob()) private val preferenceWriteScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
private val searchControl = BookSearchControl() private val searchControl = BookSearchControl()
private val searchResultBooks = LinkedHashMap<SearchResultKey, SearchBook>() private val searchResultBooks = LinkedHashMap<SearchResultKey, SearchBook>()
private var initializeJob: Job? = null
private var lastInitializedKey: String? = null
private var lastInitializedScopeRaw: String? = null
private var hasInitialized = false
private var searchJob: Job? = null private var searchJob: Job? = null
private var currentSearchPage = 1 private var currentSearchPage = 1
private var resultCountBeforeCurrentPage = 0 private var resultCountBeforeCurrentPage = 0
@@ -323,6 +329,23 @@ class SearchViewModel(
} }
private fun initialize(key: String?, scopeRaw: String?) { private fun initialize(key: String?, scopeRaw: String?) {
initializeJob?.cancel()
initializeJob = viewModelScope.launch {
searchScopeReady.await()
initializeAfterScopeLoaded(key, scopeRaw)
}
}
private fun initializeAfterScopeLoaded(key: String?, scopeRaw: String?) {
val normalizedKey = key?.trim()
val normalizedScopeRaw = scopeRaw?.takeIf { it.isNotBlank() }
val isSameRequest = hasInitialized &&
lastInitializedKey == normalizedKey &&
lastInitializedScopeRaw == normalizedScopeRaw
lastInitializedKey = normalizedKey
lastInitializedScopeRaw = normalizedScopeRaw
hasInitialized = true
val temporaryScope = scopeRaw?.takeIf { it.isNotBlank() } val temporaryScope = scopeRaw?.takeIf { it.isNotBlank() }
if (temporaryScope != null) { if (temporaryScope != null) {
hasTemporaryScope = true hasTemporaryScope = true
@@ -339,11 +362,11 @@ class SearchViewModel(
// This happens when returning from BookInfo — the LaunchedEffect // This happens when returning from BookInfo — the LaunchedEffect
// re-fires but we must not wipe the existing results. // re-fires but we must not wipe the existing results.
val hasActiveSearch = _uiState.value.committedQuery.isNotEmpty() val hasActiveSearch = _uiState.value.committedQuery.isNotEmpty()
if (hasActiveSearch) return if (isSameRequest && hasActiveSearch) return
clearSearchResults() clearSearchResults()
val initKey = key?.trim().orEmpty() val initKey = normalizedKey.orEmpty()
if (initKey.isNotEmpty()) { if (initKey.isNotEmpty()) {
updateQuery(initKey, showSuggestions = false) updateQuery(initKey, showSuggestions = false)
submitSearch(initKey) submitSearch(initKey)
@@ -732,6 +755,7 @@ class SearchViewModel(
searchScope.update(scopeRaw, postValue = false) searchScope.update(scopeRaw, postValue = false)
syncScopeState() syncScopeState()
} }
searchScopeReady.complete(Unit)
} }
} }
} }
@@ -455,7 +455,6 @@ fun MainActivity.mainEntryProvider(
SearchScreen( SearchScreen(
viewModel = searchViewModel, viewModel = searchViewModel,
onBack = { onBack = {
searchViewModel.onIntent(SearchIntent.ClearSearchResults)
onNavigateBack() onNavigateBack()
}, },
onOpenBookInfo = { name, author, bookUrl, origin, coverPath, sharedCoverKey -> onOpenBookInfo = { name, author, bookUrl, origin, coverPath, sharedCoverKey ->