Fixed: When opening the search from widget or from outside the application then search is broken with large ZIM files.

* Fixed: When launching the app fresh (cold start), the search screen could appear before the ZIM file was ready (because ZIM file loading in the reader happens on the IO thread), resulting in no search results. Now, incoming actions are delayed until the ZIM file finishes loading so that search works correctly.
* Fixed: Multiple fragment instances were created when repeatedly opening different fragments via bottomAppBar buttons, causing the back button to bring them to the foreground one by one instead of expected behavior.
This commit is contained in:
MohitMaliFtechiz 2025-08-13 14:22:02 +05:30
parent bd7228354f
commit 67a05315a7
2 changed files with 33 additions and 7 deletions

View File

@ -43,6 +43,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import kotlinx.coroutines.CoroutineScope
@ -189,11 +190,20 @@ fun BottomNavigationBar(
NavigationBarItem(
selected = currentDestinationRoute == item.route,
onClick = {
// Do not load again fragment that is already loaded.
if (item.route == currentDestinationRoute) return@NavigationBarItem
uiCoroutineScope.launch {
leftDrawerState.close()
navController.navigate(item.route)
navController.navigate(item.route) {
// Avoid multiple copies of the same destination
launchSingleTop = true
// Pop up to the start destination of the graph to avoid building up a large stack
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
// Restore state when reselecting a previously selected tab
restoreState = true
}
}
},
icon = {

View File

@ -338,6 +338,13 @@ abstract class CoreReaderFragment :
return readerLifeCycleScope
}
/**
* Handles actions that require the ZIM file to be fully loaded in the reader
* before opening the search screen. The search screen depends on the ZIM file,
* as its results come from the ZimFileReader.
*/
private var pendingIntent: Intent? = null
private var storagePermissionForNotesLauncher: ActivityResultLauncher<String>? =
registerForActivityResult(
ActivityResultContracts.RequestPermission()
@ -1073,6 +1080,7 @@ abstract class CoreReaderFragment :
super.onDestroyView()
findInPageTitle = null
searchItemToOpen = null
pendingIntent = null
try {
coreReaderLifeCycleScope?.cancel()
readerLifeCycleScope?.cancel()
@ -1907,12 +1915,15 @@ abstract class CoreReaderFragment :
requireActivity().consumeObservable<SearchItemToOpen>(TAG_FILE_SEARCHED)
}
private fun handleIntentActions(intent: Intent) {
Log.d(TAG_KIWIX, "action" + requireActivity().intent?.action)
startIntentBasedOnAction(intent)
private fun handlePendingIntent() {
pendingIntent?.let {
startIntentBasedOnAction(it)
}
pendingIntent = null
}
private fun startIntentBasedOnAction(intent: Intent?) {
Log.d(TAG_KIWIX, "action" + requireActivity().intent?.action)
when (intent?.action) {
Intent.ACTION_PROCESS_TEXT -> {
goToSearchWithText(intent)
@ -1981,7 +1992,7 @@ abstract class CoreReaderFragment :
intent: Intent,
activity: AppCompatActivity
): FragmentActivityExtensions.Super {
handleIntentActions(intent)
pendingIntent = intent
return FragmentActivityExtensions.Super.ShouldCall
}
@ -2483,6 +2494,8 @@ abstract class CoreReaderFragment :
}
if (webViewHistoryList.isEmpty()) {
restoreViewStateOnInvalidWebViewHistory()
// handle the pending intent if any present.
handlePendingIntent()
return
}
restoreViewStateOnValidWebViewHistory(
@ -2499,6 +2512,7 @@ abstract class CoreReaderFragment :
searchItemToOpen = null
findInPageTitle?.let(::findInPage)
findInPageTitle = null
handlePendingIntent()
}
} catch (e: Exception) {
Log.e(
@ -2506,6 +2520,8 @@ abstract class CoreReaderFragment :
"Could not restore tabs. Original exception = ${e.printStackTrace()}"
)
restoreViewStateOnInvalidWebViewHistory()
// handle the pending intent if any present.
handlePendingIntent()
}
}