Merge pull request #4419 from kiwix/Fixes#4418

Fixed: The Tabs history is not restoring in custom apps.
This commit is contained in:
Kelson 2025-09-06 13:42:49 +02:00 committed by GitHub
commit 7b4afafa2d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 54 additions and 33 deletions

View File

@ -81,7 +81,6 @@ class KiwixReaderFragment : CoreReaderFragment() {
activity.navigate(KiwixDestination.Library.route, navOptions)
})
}
activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
activity.enableLeftDrawer()
openPageInBookFromNavigationArguments()
}
@ -110,6 +109,8 @@ class KiwixReaderFragment : CoreReaderFragment() {
if (zimFileUri.isNotEmpty()) {
tryOpeningZimFile(zimFileUri)
} else {
isWebViewHistoryRestoring = true
isFromManageExternalLaunch = true
val restoreOrigin =
if (searchItemTitle.isNotEmpty()) FromSearchScreen else FromExternalLaunch
manageExternalLaunchAndRestoringViewState(restoreOrigin)
@ -224,7 +225,7 @@ class KiwixReaderFragment : CoreReaderFragment() {
}
}
override fun restoreViewStateOnInvalidWebViewHistory() {
override suspend fun restoreViewStateOnInvalidWebViewHistory() {
Log.d(TAG_KIWIX, "Kiwix normal start, no zimFile loaded last time -> display home page")
exitBook()
}
@ -242,7 +243,7 @@ class KiwixReaderFragment : CoreReaderFragment() {
* @param restoreOrigin Indicates whether the restoration is triggered from an external launch or the search screen.
* @param onComplete Callback to be invoked upon completion of the restoration process.
*/
override fun restoreViewStateOnValidWebViewHistory(
override suspend fun restoreViewStateOnValidWebViewHistory(
webViewHistoryItemList: List<WebViewHistoryItem>,
currentTab: Int,
restoreOrigin: RestoreOrigin,
@ -250,29 +251,27 @@ class KiwixReaderFragment : CoreReaderFragment() {
) {
when (restoreOrigin) {
FromExternalLaunch -> {
coreReaderLifeCycleScope?.launch {
if (!isAdded) return@launch
val settings =
activity?.getSharedPreferences(SharedPreferenceUtil.PREF_KIWIX_MOBILE, 0)
val zimReaderSource = fromDatabaseValue(settings?.getString(TAG_CURRENT_FILE, null))
if (zimReaderSource?.canOpenInLibkiwix() == true) {
if (zimReaderContainer?.zimReaderSource == null) {
openZimFile(zimReaderSource, isFromManageExternalLaunch = true)
Log.d(
TAG_KIWIX,
"Kiwix normal start, Opened last used zimFile: -> ${zimReaderSource.toDatabase()}"
)
} else {
zimReaderContainer?.zimFileReader?.let(::setUpBookmarks)
}
restoreTabs(webViewHistoryItemList, currentTab, onComplete)
} else {
readerScreenState.value.snackBarHostState.snack(
requireActivity().getString(string.zim_not_opened),
lifecycleScope = lifecycleScope
if (!isAdded) return
val settings =
activity?.getSharedPreferences(SharedPreferenceUtil.PREF_KIWIX_MOBILE, 0)
val zimReaderSource = fromDatabaseValue(settings?.getString(TAG_CURRENT_FILE, null))
if (zimReaderSource?.canOpenInLibkiwix() == true) {
if (zimReaderContainer?.zimReaderSource == null) {
openZimFile(zimReaderSource, isFromManageExternalLaunch = true)
Log.d(
TAG_KIWIX,
"Kiwix normal start, Opened last used zimFile: -> ${zimReaderSource.toDatabase()}"
)
exitBook() // hide the options for zim file to avoid unexpected UI behavior
} else {
zimReaderContainer?.zimFileReader?.let(::setUpBookmarks)
}
restoreTabs(webViewHistoryItemList, currentTab, onComplete)
} else {
readerScreenState.value.snackBarHostState.snack(
requireActivity().getString(string.zim_not_opened),
lifecycleScope = lifecycleScope
)
exitBook() // hide the options for zim file to avoid unexpected UI behavior
}
}

View File

@ -172,6 +172,7 @@ import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
import javax.inject.Inject
import kotlin.concurrent.Volatile
import kotlin.math.max
const val SEARCH_ITEM_TITLE_KEY = "searchItemTitle"
@ -224,7 +225,8 @@ abstract class CoreReaderFragment :
protected var currentWebViewIndex by mutableStateOf(0)
private var currentTtsWebViewIndex = 0
private var isFirstTimeMainPageLoaded = true
private var isFromManageExternalLaunch = false
@Volatile var isFromManageExternalLaunch = false
private val savingTabsMutex = Mutex()
private var searchItemToOpen: SearchItemToOpen? = null
private var findInPageTitle: String? = null
@ -340,6 +342,8 @@ abstract class CoreReaderFragment :
*/
private var pendingIntent: Intent? = null
@Volatile var isWebViewHistoryRestoring = false
private var storagePermissionForNotesLauncher: ActivityResultLauncher<String>? =
registerForActivityResult(
ActivityResultContracts.RequestPermission()
@ -2304,6 +2308,9 @@ abstract class CoreReaderFragment :
}
updateBottomToolbarVisibility()
updateNightMode()
if (!isWebViewHistoryRestoring) {
saveTabStates()
}
}
}
@ -2333,7 +2340,6 @@ abstract class CoreReaderFragment :
showProgressBarWithProgress(progress)
if (progress == 100) {
hideProgressBar()
saveTabStates()
Log.d(TAG_KIWIX, "Loaded URL: " + getCurrentWebView()?.url)
}
(webView.context as AppCompatActivity).invalidateOptionsMenu()
@ -2434,6 +2440,7 @@ abstract class CoreReaderFragment :
restoreViewStateOnInvalidWebViewHistory()
// handle the pending intent if any present.
handlePendingIntent()
isWebViewHistoryRestoring = false
return
}
restoreViewStateOnValidWebViewHistory(
@ -2446,11 +2453,14 @@ abstract class CoreReaderFragment :
// to open the specified item, then sets `searchItemToOpen` to null to prevent
// any unexpected behavior on future calls. Similarly, if `findInPageTitle` is set,
// it invokes `findInPage` and resets `findInPageTitle` to null.
isWebViewHistoryRestoring = false
searchItemToOpen?.let(::openSearchItem)
searchItemToOpen = null
findInPageTitle?.let(::findInPage)
findInPageTitle = null
handlePendingIntent()
// When the restoration completes than save the tabs history.
saveTabStates()
}
}.onFailure {
Log.e(
@ -2460,6 +2470,7 @@ abstract class CoreReaderFragment :
restoreViewStateOnInvalidWebViewHistory()
// handle the pending intent if any present.
handlePendingIntent()
isWebViewHistoryRestoring = false
}
}
@ -2487,7 +2498,7 @@ abstract class CoreReaderFragment :
* @Warning: This method restores tabs state in new launches, do not modify it
* unless it is explicitly mentioned in the issue you're fixing.
*/
protected fun restoreTabs(
protected suspend fun restoreTabs(
webViewHistoryItemList: List<WebViewHistoryItem>,
currentTab: Int,
onComplete: () -> Unit
@ -2612,7 +2623,7 @@ abstract class CoreReaderFragment :
* KiwixReaderFragment.restoreViewStateOnValidWebViewHistory) to ensure consistent behavior
* when handling valid webViewHistory scenarios.
*/
protected abstract fun restoreViewStateOnValidWebViewHistory(
protected abstract suspend fun restoreViewStateOnValidWebViewHistory(
webViewHistoryItemList: List<WebViewHistoryItem>,
currentTab: Int,
restoreOrigin: RestoreOrigin,
@ -2627,7 +2638,7 @@ abstract class CoreReaderFragment :
* KiwixReaderFragment.restoreViewStateOnInvalidWebViewHistory) to ensure consistent behavior
* when handling invalid JSON scenarios.
*/
abstract fun restoreViewStateOnInvalidWebViewHistory()
abstract suspend fun restoreViewStateOnInvalidWebViewHistory()
}
enum class RestoreOrigin {

View File

@ -185,8 +185,14 @@ class CustomReaderFragment : CoreReaderFragment() {
// See https://github.com/kiwix/kiwix-android/issues/3541
zimReaderContainer?.zimFileReader?.let(::setUpBookmarks)
} else {
isWebViewHistoryRestoring = true
isFromManageExternalLaunch = true
coreReaderLifeCycleScope?.launch {
openObbOrZim(true)
if (zimReaderContainer?.zimFileReader == null || zimReaderContainer?.zimReaderSource?.exists() == false) {
openObbOrZim(true)
} else {
manageExternalLaunchAndRestoringViewState()
}
}
}
customMainActivity?.consumeObservable<String>(PAGE_URL_KEY)
@ -197,7 +203,7 @@ class CustomReaderFragment : CoreReaderFragment() {
* due to the absence of any history records. In this case, it navigates to the homepage of the
* ZIM file, as custom apps are expected to have the ZIM file readily available.
*/
override fun restoreViewStateOnInvalidWebViewHistory() {
override suspend fun restoreViewStateOnInvalidWebViewHistory() {
openHomeScreen()
}
@ -205,7 +211,7 @@ class CustomReaderFragment : CoreReaderFragment() {
* Restores the view state when the webViewHistory data is valid.
* This method restores the tabs with webView pages history.
*/
override fun restoreViewStateOnValidWebViewHistory(
override suspend fun restoreViewStateOnValidWebViewHistory(
webViewHistoryItemList: List<WebViewHistoryItem>,
currentTab: Int,
// Unused in custom apps as there is only one ZIM file that is already set.
@ -430,8 +436,13 @@ class CustomReaderFragment : CoreReaderFragment() {
super.onResume()
if (appSettingsLaunched) {
appSettingsLaunched = false
isWebViewHistoryRestoring = true
coreReaderLifeCycleScope?.launch {
openObbOrZim(true)
if (zimReaderContainer?.zimFileReader == null) {
openObbOrZim(true)
} else {
manageExternalLaunchAndRestoringViewState()
}
}
}
}