diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderContainer.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderContainer.kt index e26df34cd..c550a94e7 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderContainer.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/reader/ZimReaderContainer.kt @@ -70,6 +70,8 @@ class ZimReaderContainer @Inject constructor( zimFileReader?.load(url) ) + fun copyReader(): ZimFileReader? = zimFile?.let(zimFileReaderFactory::create) + val zimFile get() = zimFileReader?.zimFile val zimCanonicalPath get() = zimFileReader?.zimFile?.canonicalPath diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchResultGenerator.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchResultGenerator.kt index e249e5495..7bd361cb7 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchResultGenerator.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchResultGenerator.kt @@ -18,6 +18,7 @@ package org.kiwix.kiwixmobile.core.search.viewmodel +import org.kiwix.kiwixmobile.core.reader.ZimFileReader import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem.ZimSearchResultListItem @@ -33,22 +34,26 @@ class ZimSearchResultGenerator @Inject constructor( private val zimReaderContainer: ZimReaderContainer ) : SearchResultGenerator { override fun generateSearchResults(searchTerm: String) = - if (searchTerm.isNotEmpty()) readResultsFromZim(searchTerm) + if (searchTerm.isNotEmpty()) readResultsFromZim(searchTerm, zimReaderContainer.copyReader()) else emptyList() - private fun readResultsFromZim(it: String) = + private fun readResultsFromZim( + it: String, + reader: ZimFileReader? + ) = if (sharedPreferenceUtil.prefFullTextSearch) zimReaderContainer.search(it, 200).run { fullTextResults() } else - zimReaderContainer.searchSuggestions(it, 200).run { suggestionResults() } + reader?.searchSuggestions(it, 200).run { suggestionResults(reader) } private fun fullTextResults() = generateSequence { zimReaderContainer.getNextResult()?.title?.let(::ZimSearchResultListItem) }.filter { it.value.isNotBlank() } .toList() - private fun suggestionResults() = generateSequence { - zimReaderContainer.getNextSuggestion()?.let { ZimSearchResultListItem(it.title) } - }.distinct() + private fun suggestionResults(reader: ZimFileReader?) = generateSequence { + reader?.getNextSuggestion()?.let { ZimSearchResultListItem(it.title) } + } + .distinct() .toList() } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchViewModel.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchViewModel.kt index a7d0aeffb..b22dcbc23 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchViewModel.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchViewModel.kt @@ -55,8 +55,11 @@ import org.kiwix.kiwixmobile.core.search.viewmodel.effects.SearchIntentProcessin import org.kiwix.kiwixmobile.core.search.viewmodel.effects.ShowDeleteSearchDialog import org.kiwix.kiwixmobile.core.search.viewmodel.effects.ShowToast import org.kiwix.kiwixmobile.core.search.viewmodel.effects.StartSpeechInput +import java.util.concurrent.TimeUnit import javax.inject.Inject +private const val DEBOUNCE_MS = 500L + class SearchViewModel @Inject constructor( private val recentSearchDao: NewRecentSearchDao, private val zimReaderContainer: ZimReaderContainer, @@ -148,6 +151,7 @@ class SearchViewModel @Inject constructor( private fun searchResultsFromZimReader() = filter .distinctUntilChanged() + .debounce(DEBOUNCE_MS, TimeUnit.MILLISECONDS) .switchMap(::searchResults) private fun searchResults(it: String) = Flowable.fromCallable { diff --git a/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchViewModelTest.kt b/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchViewModelTest.kt index 0ab4deb8a..e6ff3cd31 100644 --- a/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchViewModelTest.kt +++ b/core/src/test/java/org/kiwix/kiwixmobile/core/search/viewmodel/SearchViewModelTest.kt @@ -46,8 +46,8 @@ import org.kiwix.kiwixmobile.core.search.viewmodel.Action.Filter import org.kiwix.kiwixmobile.core.search.viewmodel.Action.OnItemClick import org.kiwix.kiwixmobile.core.search.viewmodel.Action.OnItemLongClick import org.kiwix.kiwixmobile.core.search.viewmodel.Action.ReceivedPromptForSpeechInput -import org.kiwix.kiwixmobile.core.search.viewmodel.Action.StartSpeechInputFailed import org.kiwix.kiwixmobile.core.search.viewmodel.Action.ScreenWasStartedFrom +import org.kiwix.kiwixmobile.core.search.viewmodel.Action.StartSpeechInputFailed import org.kiwix.kiwixmobile.core.search.viewmodel.SearchOrigin.FromTabView import org.kiwix.kiwixmobile.core.search.viewmodel.SearchOrigin.FromWebView import org.kiwix.kiwixmobile.core.search.viewmodel.State.NoResults @@ -166,7 +166,6 @@ internal class SearchViewModelTest { viewModel.state.test() .also { testScheduler.advanceTimeBy(100, MILLISECONDS) } .assertValueHistory( - NoResults("", FromWebView), Results(searchString, listOf(item), FromWebView) ) } @@ -188,7 +187,7 @@ internal class SearchViewModelTest { ) viewModel.state.test() .also { testScheduler.advanceTimeBy(100, MILLISECONDS) } - .assertValueHistory(NoResults("", FromWebView), Results("b", listOf(item), FromWebView)) + .assertValueHistory(Results("b", listOf(item), FromWebView)) } @Test @@ -315,5 +314,6 @@ internal class SearchViewModelTest { viewModel.actions.offer(Filter(searchTerm)) recentsFromDb.offer(databaseResults) viewModel.actions.offer(ScreenWasStartedFrom(searchOrigin)) + testScheduler.advanceTimeBy(500, MILLISECONDS) } }