Fixed bugs and enhanced search functionality.

* A bug was introduced after enhancing the search functionality to align with the new `java-libkiwix` wrapper. Initially, when searching for any article in the ZIM file, the loading progress bar was not being displayed. This commit resolves this issue.
* While searching within large ZIM files, the application used to freeze momentarily due to fetching data from the `libkiwix` on the UI thread. We have improved this functionality to provide a seamless user experience.
This commit is contained in:
MohitMali 2023-08-10 18:32:20 +05:30 committed by Kelson
parent 609e9e268f
commit f1889ee1d2
2 changed files with 21 additions and 14 deletions

View File

@ -40,7 +40,9 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.base.BaseActivity
import org.kiwix.kiwixmobile.core.base.BaseFragment
@ -82,6 +84,7 @@ class SearchFragment : BaseFragment() {
private var searchAdapter: SearchAdapter? = null
private var isDataLoading = false
private var searchState: SearchState? = null
private var renderingJob: Job? = null
override fun inject(baseActivity: BaseActivity) {
baseActivity.cachedComponent.inject(this)
@ -200,6 +203,8 @@ class SearchFragment : BaseFragment() {
override fun onDestroyView() {
super.onDestroyView()
renderingJob?.cancel()
renderingJob = null
searchState = null
activity?.intent?.action = null
searchView = null
@ -258,17 +263,24 @@ class SearchFragment : BaseFragment() {
)
}
private suspend fun render(state: SearchState) {
private fun render(state: SearchState) {
renderingJob?.cancel()
isDataLoading = false
searchState = state
searchInTextMenuItem?.isVisible = state.searchOrigin == FromWebView
searchInTextMenuItem?.isEnabled = state.searchTerm.isNotBlank()
fragmentSearchBinding?.searchLoadingIndicator?.isShowing(state.isLoading)
val searchResult = state.getVisibleResults(0)
fragmentSearchBinding?.searchNoResults?.isVisible =
searchResult?.isEmpty() == true
searchResult?.let {
searchAdapter?.items = it
fragmentSearchBinding?.searchLoadingIndicator?.isShowing(true)
renderingJob = CoroutineScope(Dispatchers.Main).launch {
val searchResult = withContext(Dispatchers.IO) {
state.getVisibleResults(0)
}
fragmentSearchBinding?.searchLoadingIndicator?.isShowing(false)
searchResult?.let {
fragmentSearchBinding?.searchNoResults?.isVisible = it.isEmpty()
searchAdapter?.items = it
}
}
}

View File

@ -26,13 +26,10 @@ data class SearchState(
val recentResults: List<SearchListItem.RecentSearchListItem>,
val searchOrigin: SearchOrigin
) {
private var isDataLoading = false
suspend fun getVisibleResults(startIndex: Int): List<SearchListItem.RecentSearchListItem>? =
fun getVisibleResults(startIndex: Int): List<SearchListItem.RecentSearchListItem>? =
if (searchTerm.isEmpty()) {
isDataLoading = false
recentResults
} else {
isDataLoading = true
searchResultsWithTerm.suggestionSearch?.let {
val maximumResults = it.estimatedMatches
val safeEndIndex =
@ -49,15 +46,13 @@ data class SearchState(
* We check this in SearchFragment to avoid unnecessary data loading
* while scrolling to the end of the list when there are no items available.
*/
isDataLoading = false
searchResults.ifEmpty { null }
} ?: kotlin.run {
isDataLoading = false
recentResults
}
}
val isLoading get() = searchTerm != searchResultsWithTerm.searchTerm || isDataLoading
val isLoading = searchTerm != searchResultsWithTerm.searchTerm
}
enum class SearchOrigin {