mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 18:56:44 -04:00
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:
parent
734885a527
commit
acf45a0f60
@ -40,7 +40,9 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import org.kiwix.kiwixmobile.core.R
|
import org.kiwix.kiwixmobile.core.R
|
||||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||||
import org.kiwix.kiwixmobile.core.base.BaseFragment
|
import org.kiwix.kiwixmobile.core.base.BaseFragment
|
||||||
@ -82,6 +84,7 @@ class SearchFragment : BaseFragment() {
|
|||||||
private var searchAdapter: SearchAdapter? = null
|
private var searchAdapter: SearchAdapter? = null
|
||||||
private var isDataLoading = false
|
private var isDataLoading = false
|
||||||
private var searchState: SearchState? = null
|
private var searchState: SearchState? = null
|
||||||
|
private var renderingJob: Job? = null
|
||||||
|
|
||||||
override fun inject(baseActivity: BaseActivity) {
|
override fun inject(baseActivity: BaseActivity) {
|
||||||
baseActivity.cachedComponent.inject(this)
|
baseActivity.cachedComponent.inject(this)
|
||||||
@ -200,6 +203,8 @@ class SearchFragment : BaseFragment() {
|
|||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
|
renderingJob?.cancel()
|
||||||
|
renderingJob = null
|
||||||
searchState = null
|
searchState = null
|
||||||
activity?.intent?.action = null
|
activity?.intent?.action = null
|
||||||
searchView = 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
|
isDataLoading = false
|
||||||
searchState = state
|
searchState = state
|
||||||
searchInTextMenuItem?.isVisible = state.searchOrigin == FromWebView
|
searchInTextMenuItem?.isVisible = state.searchOrigin == FromWebView
|
||||||
searchInTextMenuItem?.isEnabled = state.searchTerm.isNotBlank()
|
searchInTextMenuItem?.isEnabled = state.searchTerm.isNotBlank()
|
||||||
fragmentSearchBinding?.searchLoadingIndicator?.isShowing(state.isLoading)
|
fragmentSearchBinding?.searchLoadingIndicator?.isShowing(true)
|
||||||
val searchResult = state.getVisibleResults(0)
|
renderingJob = CoroutineScope(Dispatchers.Main).launch {
|
||||||
fragmentSearchBinding?.searchNoResults?.isVisible =
|
val searchResult = withContext(Dispatchers.IO) {
|
||||||
searchResult?.isEmpty() == true
|
state.getVisibleResults(0)
|
||||||
searchResult?.let {
|
}
|
||||||
searchAdapter?.items = it
|
|
||||||
|
fragmentSearchBinding?.searchLoadingIndicator?.isShowing(false)
|
||||||
|
|
||||||
|
searchResult?.let {
|
||||||
|
fragmentSearchBinding?.searchNoResults?.isVisible = it.isEmpty()
|
||||||
|
searchAdapter?.items = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,13 +26,10 @@ data class SearchState(
|
|||||||
val recentResults: List<SearchListItem.RecentSearchListItem>,
|
val recentResults: List<SearchListItem.RecentSearchListItem>,
|
||||||
val searchOrigin: SearchOrigin
|
val searchOrigin: SearchOrigin
|
||||||
) {
|
) {
|
||||||
private var isDataLoading = false
|
fun getVisibleResults(startIndex: Int): List<SearchListItem.RecentSearchListItem>? =
|
||||||
suspend fun getVisibleResults(startIndex: Int): List<SearchListItem.RecentSearchListItem>? =
|
|
||||||
if (searchTerm.isEmpty()) {
|
if (searchTerm.isEmpty()) {
|
||||||
isDataLoading = false
|
|
||||||
recentResults
|
recentResults
|
||||||
} else {
|
} else {
|
||||||
isDataLoading = true
|
|
||||||
searchResultsWithTerm.suggestionSearch?.let {
|
searchResultsWithTerm.suggestionSearch?.let {
|
||||||
val maximumResults = it.estimatedMatches
|
val maximumResults = it.estimatedMatches
|
||||||
val safeEndIndex =
|
val safeEndIndex =
|
||||||
@ -49,15 +46,13 @@ data class SearchState(
|
|||||||
* We check this in SearchFragment to avoid unnecessary data loading
|
* We check this in SearchFragment to avoid unnecessary data loading
|
||||||
* while scrolling to the end of the list when there are no items available.
|
* while scrolling to the end of the list when there are no items available.
|
||||||
*/
|
*/
|
||||||
isDataLoading = false
|
|
||||||
searchResults.ifEmpty { null }
|
searchResults.ifEmpty { null }
|
||||||
} ?: kotlin.run {
|
} ?: kotlin.run {
|
||||||
isDataLoading = false
|
|
||||||
recentResults
|
recentResults
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val isLoading get() = searchTerm != searchResultsWithTerm.searchTerm || isDataLoading
|
val isLoading = searchTerm != searchResultsWithTerm.searchTerm
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class SearchOrigin {
|
enum class SearchOrigin {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user