Fixed: Restore web view history in Kiwix app.

* Improved restoration of web view history after opening a searched article.
* Refactored `restoreViewStateOnValidJSON` and `restoreViewStateOnInvalidJSON` methods to save and retrieve web view history from the Room database.
* Added detailed comments to methods for better understanding, including guidance for developers to check subclass implementations before making modifications.
* Fixed the `static analysis` errors.
This commit is contained in:
MohitMaliFtechiz 2024-10-25 16:23:23 +05:30
parent ee50417154
commit 2fb1896cea
6 changed files with 254 additions and 61 deletions

View File

@ -58,6 +58,7 @@ import org.kiwix.kiwixmobile.core.main.ToolbarScrollingKiwixWebView
import org.kiwix.kiwixmobile.core.page.history.adapter.WebViewHistoryItem
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource
import org.kiwix.kiwixmobile.core.reader.ZimReaderSource.Companion.fromDatabaseValue
import org.kiwix.kiwixmobile.core.search.viewmodel.effects.SearchItemToOpen
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.core.utils.TAG_CURRENT_FILE
import org.kiwix.kiwixmobile.core.utils.TAG_KIWIX
@ -69,6 +70,7 @@ private const val HIDE_TAB_SWITCHER_DELAY: Long = 300
class KiwixReaderFragment : CoreReaderFragment() {
private var isFullScreenVideo: Boolean = false
private var searchItemToOpen: SearchItemToOpen? = null
override fun inject(baseActivity: BaseActivity) {
baseActivity.cachedComponent.inject(this)
@ -111,7 +113,16 @@ class KiwixReaderFragment : CoreReaderFragment() {
} else {
val restoreOrigin =
if (args.searchItemTitle.isNotEmpty()) FromSearchScreen else FromExternalLaunch
manageExternalLaunchAndRestoringViewState(restoreOrigin)
manageExternalLaunchAndRestoringViewState(restoreOrigin) {
// This lambda function is invoked after restoring the tabs. It checks if there is a
// search item to open. If `searchItemToOpen` is not null, it will call the superclass
// method to open the specified search item. After opening, it sets `searchItemToOpen`
// to null to prevent any unexpected behavior on subsequent calls.
searchItemToOpen?.let {
super.openSearchItem(it)
}
searchItemToOpen = null
}
}
}
requireArguments().clear()
@ -151,6 +162,18 @@ class KiwixReaderFragment : CoreReaderFragment() {
openZimFile(zimReaderSource)
}
/**
* Stores the specified search item to be opened later.
*
* This method saves the provided `SearchItemToOpen` object, which will be used to
* open the searched item after the tabs have been restored.
*
* @param item The search item to be opened after restoring the tabs.
*/
override fun openSearchItem(item: SearchItemToOpen) {
searchItemToOpen = item
}
override fun loadDrawerViews() {
drawerLayout = requireActivity().findViewById(R.id.navigation_container)
tableDrawerRightContainer = requireActivity().findViewById(R.id.reader_drawer_nav_view)
@ -243,7 +266,7 @@ class KiwixReaderFragment : CoreReaderFragment() {
}
}
override fun restoreViewStateOnInvalidJSON() {
override fun restoreViewStateOnInvalidWebViewHistory() {
Log.d(TAG_KIWIX, "Kiwix normal start, no zimFile loaded last time -> display home page")
exitBook()
}
@ -256,15 +279,16 @@ class KiwixReaderFragment : CoreReaderFragment() {
* as the ZIM file is already set in the reader. The method handles setting up the ZIM file and bookmarks,
* and restores the tabs and positions from the provided data.
*
* @param webViewHistoryItemList JSON string representing the list of articles to be restored.
* @param currentTab Index of the tab to be restored as the currently active one.
* @param webViewHistoryItemList WebViewHistoryItem list representing the list of articles to be restored.
* @param currentTab Index of the tab to be restored as the currently active one.
* @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 restoreViewStateOnValidJSON(
override fun restoreViewStateOnValidWebViewHistory(
webViewHistoryItemList: List<WebViewHistoryItem>,
currentTab: Int,
restoreOrigin: RestoreOrigin
restoreOrigin: RestoreOrigin,
onComplete: () -> Unit
) {
when (restoreOrigin) {
FromExternalLaunch -> {
@ -274,7 +298,7 @@ class KiwixReaderFragment : CoreReaderFragment() {
val zimReaderSource = fromDatabaseValue(settings.getString(TAG_CURRENT_FILE, null))
if (zimReaderSource?.canOpenInLibkiwix() == true) {
if (zimReaderContainer?.zimReaderSource == null) {
openZimFile(zimReaderSource)
openZimFile(zimReaderSource, isFromManageExternalLaunch = true)
Log.d(
TAG_KIWIX,
"Kiwix normal start, Opened last used zimFile: -> ${zimReaderSource.toDatabase()}"
@ -282,7 +306,7 @@ class KiwixReaderFragment : CoreReaderFragment() {
} else {
zimReaderContainer?.zimFileReader?.let(::setUpBookmarks)
}
restoreTabs(webViewHistoryItemList, currentTab)
restoreTabs(webViewHistoryItemList, currentTab, onComplete)
} else {
getCurrentWebView()?.snack(string.zim_not_opened)
exitBook() // hide the options for zim file to avoid unexpected UI behavior
@ -291,7 +315,7 @@ class KiwixReaderFragment : CoreReaderFragment() {
}
FromSearchScreen -> {
restoreTabs(webViewHistoryItemList, currentTab)
restoreTabs(webViewHistoryItemList, currentTab, onComplete)
}
}
}

View File

@ -24,7 +24,6 @@ import org.kiwix.kiwixmobile.core.dao.entities.WebViewHistoryEntity
import org.kiwix.kiwixmobile.core.page.bookmark.adapter.LibkiwixBookmarkItem
import org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem
import org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem.HistoryItem
import org.kiwix.kiwixmobile.core.page.history.adapter.WebViewHistoryItem
import org.kiwix.kiwixmobile.core.page.notes.adapter.NoteListItem
import org.kiwix.kiwixmobile.core.zim_manager.Language
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem

View File

@ -28,8 +28,8 @@ import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks
import org.kiwix.kiwixmobile.core.dao.NewBookDao
import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
import org.kiwix.kiwixmobile.core.dao.NotesRoomDao
import org.kiwix.kiwixmobile.core.dao.WebViewHistoryRoomDao
import org.kiwix.kiwixmobile.core.dao.RecentSearchRoomDao
import org.kiwix.kiwixmobile.core.dao.WebViewHistoryRoomDao
import org.kiwix.kiwixmobile.core.dao.entities.WebViewHistoryEntity
import org.kiwix.kiwixmobile.core.di.qualifiers.IO
import org.kiwix.kiwixmobile.core.di.qualifiers.MainThread
@ -37,7 +37,6 @@ import org.kiwix.kiwixmobile.core.extensions.HeaderizableList
import org.kiwix.kiwixmobile.core.page.bookmark.adapter.LibkiwixBookmarkItem
import org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem
import org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem.HistoryItem
import org.kiwix.kiwixmobile.core.page.history.adapter.WebViewHistoryItem
import org.kiwix.kiwixmobile.core.page.notes.adapter.NoteListItem
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
import org.kiwix.kiwixmobile.core.zim_manager.Language
@ -148,7 +147,9 @@ class Repository @Inject internal constructor(
Completable.fromAction { notesRoomDao.deleteNotes(noteList) }
.subscribeOn(ioThread)
override suspend fun insertWebViewPageHistoryItems(webViewHistoryEntityList: List<WebViewHistoryEntity>) {
override suspend fun insertWebViewPageHistoryItems(
webViewHistoryEntityList: List<WebViewHistoryEntity>
) {
webViewHistoryRoomDao.insertWebViewPageHistoryItems(webViewHistoryEntityList)
}
@ -159,7 +160,7 @@ class Repository @Inject internal constructor(
.observeOn(mainThread)
override suspend fun clearWebViewPagesHistory() {
webViewHistoryRoomDao.clearPageHistoryWithPrimaryKey()
webViewHistoryRoomDao.clearWebViewPagesHistory()
}
override fun deleteNote(noteTitle: String): Completable =

View File

@ -100,8 +100,8 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONException
import org.kiwix.kiwixmobile.core.BuildConfig
import org.kiwix.kiwixmobile.core.CoreApp
import org.kiwix.kiwixmobile.core.DarkModeConfig
import org.kiwix.kiwixmobile.core.R
import org.kiwix.kiwixmobile.core.StorageObserver
@ -286,6 +286,7 @@ abstract class CoreReaderFragment :
private var isFirstTimeMainPageLoaded = true
private var isFromManageExternalLaunch = false
private var shouldSaveTabsOnPause = true
@JvmField
@Inject
@ -421,6 +422,9 @@ abstract class CoreReaderFragment :
savedInstanceState: Bundle?
) {
super.onViewCreated(view, savedInstanceState)
// Set this to true to enable saving the tab history
// when the fragment goes into the paused state.
shouldSaveTabsOnPause = true
setupMenu()
donationDialogHandler?.setDonationDialogCallBack(this)
val activity = requireActivity() as AppCompatActivity?
@ -1306,6 +1310,15 @@ abstract class CoreReaderFragment :
}
}
/**
* Initializes a new instance of `KiwixWebView` with the specified URL.
*
* @param url The URL to load in the web view. This is ignored if `shouldLoadUrl` is false.
* @param shouldLoadUrl A flag indicating whether to load the specified URL in the web view.
* When restoring tabs, this should be set to false to avoid loading
* an extra page, as the previous web view history will be restored directly.
* @return The initialized `KiwixWebView` instance, or null if initialization fails.
*/
private fun initalizeWebView(url: String, shouldLoadUrl: Boolean = true): KiwixWebView? {
if (isAdded) {
val attrs = requireActivity().getAttributes(R.xml.webview)
@ -1354,6 +1367,17 @@ abstract class CoreReaderFragment :
newTab(url, false)
}
/**
* Creates a new instance of `KiwixWebView` and adds it to the list of web views.
*
* @param url The URL to load in the newly created web view.
* @param selectTab A flag indicating whether to select the newly created tab immediately.
* Defaults to true, which means the new tab will be selected.
* @param shouldLoadUrl A flag indicating whether to load the specified URL in the web view.
* If set to false, the web view will be created without loading the URL,
* which is useful when restoring tabs.
* @return The newly created `KiwixWebView` instance, or null if the initialization fails.
*/
private fun newTab(
url: String,
selectTab: Boolean = true,
@ -1529,6 +1553,17 @@ abstract class CoreReaderFragment :
}
}
override fun onSearchMenuClickedMenuClicked() {
// Set this to false to prevent saving the tab history in onPause
// when opening the search fragment.
shouldSaveTabsOnPause = false
saveTabStates {
// Pass this function to saveTabStates so that after saving
// the tab state in the database, it will open the search fragment.
openSearch("", isOpenedFromTabView = isInTabSwitcher, false)
}
}
@Suppress("NestedBlockDepth")
override fun onReadAloudMenuClicked() {
if (requireActivity().hasNotificationPermission(sharedPreferenceUtil)) {
@ -2103,7 +2138,21 @@ abstract class CoreReaderFragment :
openSearch("", isOpenedFromTabView = false, isVoice)
}
private fun openSearchItem(item: SearchItemToOpen) {
/**
* Opens a search item based on its properties.
*
* If the item should open in a new tab, a new tab is created.
*
* The method attempts to load the page URL directly. If the page URL is not available,
* it attempts to convert the page title to a URL using the ZIM reader container. The
* resulting URL is then loaded in the current web view.
*
* Note: This method is overridden in the `KiwixReaderFragment` class to store the
* `SearchItemToOpen` object for later use. If modifications are made to this method,
* please check the overridden version to understand how it interacts with the fragment's
* navigation logic.
*/
open fun openSearchItem(item: SearchItemToOpen) {
if (item.shouldOpenInNewTab) {
createNewTab()
}
@ -2360,13 +2409,42 @@ abstract class CoreReaderFragment :
updateNightMode()
}
private fun saveTabStates() {
/**
* Saves the current state of tabs and web view history to persistent storage.
*
* This method is designed to be called when the fragment is about to pause,
* ensuring that the current tab states are preserved. It performs the following steps:
*
* 1. Clears any previous web view page history stored in the database.
* 2. Retrieves the current activity's shared preferences to store the tab states.
* 3. Iterates over the currently opened web views, creating a list of
* `WebViewHistoryEntity` objects based on their URLs.
* 4. Saves the collected web view history entities to the database.
* 5. Updates the shared preferences with the current ZIM file and tab index.
* 6. Logs the current ZIM file being saved for debugging purposes.
* 7. Calls the provided `onComplete` callback function once all operations are finished.
*
* Note: This method runs on the main thread and performs database operations
* in a background thread to avoid blocking the UI.
*
* @param onComplete A lambda function to be executed after the tab states have
* been successfully saved. This is optional and defaults to
* an empty function.
*
* Example usage:
* ```
* saveTabStates {
* openSearch("", isOpenedFromTabView = isInTabSwitcher, false)
* }
*/
private fun saveTabStates(onComplete: () -> Unit = {}) {
CoroutineScope(Dispatchers.Main).launch {
// clear the previous history saved in database
withContext(Dispatchers.IO) {
repositoryActions?.clearWebViewPageHistory()
}
val settings = requireActivity().getSharedPreferences(
val coreApp = sharedPreferenceUtil?.context as CoreApp
val settings = coreApp.getMainActivity().getSharedPreferences(
SharedPreferenceUtil.PREF_KIWIX_MOBILE,
0
)
@ -2382,10 +2460,43 @@ abstract class CoreReaderFragment :
editor.putString(TAG_CURRENT_FILE, zimReaderContainer?.zimReaderSource?.toDatabase())
editor.putInt(TAG_CURRENT_TAB, currentWebViewIndex)
editor.apply()
Log.d(
TAG_KIWIX,
"Save current zim file to preferences: " +
"${zimReaderContainer?.zimReaderSource?.toDatabase()}"
)
onComplete.invoke()
}
}
private fun getWebViewHistoryEntity(
/**
* Retrieves a `WebViewHistoryEntity` from the given `KiwixWebView` instance.
*
* This method captures the current state of the specified web view, including its
* scroll position and back-forward list, and creates a `WebViewHistoryEntity`
* if the necessary conditions are met. The steps involved are as follows:
*
* 1. Initializes a `Bundle` to store the state of the web view.
* 2. Calls `saveState` on the provided `webView`, which populates the bundle
* with the current state of the web view's back-forward list.
* 3. Retrieves the ID of the currently loaded ZIM file from the `zimReaderContainer`.
* 4. Checks if the ZIM ID is not null and if the web back-forward list contains any entries:
* - If both conditions are satisfied, it creates and returns a `WebViewHistoryEntity`
* containing a `WebViewHistoryItem` with the following data:
* - `zimId`: The ID of the current ZIM file.
* - `webViewIndex`: The index of the web view in the list of opened views.
* - `webViewPosition`: The current vertical scroll position of the web view.
* - `webViewBackForwardList`: The bundle containing the saved state of the
* web view's back-forward list.
* 5. If the ZIM ID is null or the web back-forward list is empty, the method returns null.
*
* @param webView The `KiwixWebView` instance from which to retrieve the history entity.
* @param webViewIndex The index of the web view in the list of opened web views,
* used to identify the position of this web view in the history.
* @return A `WebViewHistoryEntity` containing the state information of the web view,
* or null if the necessary conditions for creating the entity are not met.
*/
private suspend fun getWebViewHistoryEntity(
webView: KiwixWebView,
webViewIndex: Int
): WebViewHistoryEntity? {
@ -2406,14 +2517,14 @@ abstract class CoreReaderFragment :
return null
}
/**
* @see shouldSaveTabsOnPause
*/
override fun onPause() {
super.onPause()
saveTabStates()
Log.d(
TAG_KIWIX,
"onPause Save current zim file to preferences: " +
"${zimReaderContainer?.zimReaderSource?.toDatabase()}"
)
if (shouldSaveTabsOnPause) {
saveTabStates()
}
}
override fun webViewUrlLoading() {
@ -2597,7 +2708,8 @@ abstract class CoreReaderFragment :
@SuppressLint("CheckResult")
protected fun manageExternalLaunchAndRestoringViewState(
restoreOrigin: RestoreOrigin = FromExternalLaunch
restoreOrigin: RestoreOrigin = FromExternalLaunch,
onComplete: () -> Unit = {}
) {
val settings = requireActivity().getSharedPreferences(
SharedPreferenceUtil.PREF_KIWIX_MOBILE,
@ -2606,29 +2718,49 @@ abstract class CoreReaderFragment :
val currentTab = safelyGetCurrentTab(settings)
repositoryActions?.loadWebViewPagesHistory()
?.subscribe({ webViewHistoryItemList ->
Log.e(
"VALID_DATA",
"manageExternalLaunchAndRestoringViewState: ${webViewHistoryItemList.size}"
)
if (webViewHistoryItemList.isEmpty()) {
restoreViewStateOnInvalidJSON()
restoreViewStateOnInvalidWebViewHistory()
return@subscribe
}
restoreViewStateOnValidJSON(webViewHistoryItemList, currentTab, restoreOrigin)
restoreViewStateOnValidWebViewHistory(
webViewHistoryItemList,
currentTab,
restoreOrigin,
onComplete
)
}, {
Log.e("INVALID_DATA", "manageExternalLaunchAndRestoringViewState: $it")
restoreViewStateOnInvalidJSON()
restoreViewStateOnInvalidWebViewHistory()
})
}
private fun safelyGetCurrentTab(settings: SharedPreferences): Int =
max(settings.getInt(TAG_CURRENT_TAB, 0), 0)
/* This method restores tabs state in new launches, do not modify it
unless it is explicitly mentioned in the issue you're fixing */
/**
* Restores the tabs based on the provided webViewHistoryItemList.
*
* This method performs the following actions:
* - Resets the current web view index to zero.
* - Removes the first tab from the webViewList and updates the tabs adapter.
* - Iterates over the provided webViewHistoryItemList, creating new tabs and restoring
* their states based on the historical data.
* - Selects the specified tab to make it the currently active one.
* - Invokes the onComplete callback once the restoration is finished.
*
* If any error occurs during the restoration process, it logs a warning and displays
* a toast message to inform the user that the tabs could not be restored.
*
* @param webViewHistoryItemList List of WebViewHistoryItem representing the historical data for restoring tabs.
* @param currentTab Index of the tab to be set as the currently active tab after restoration.
* @param onComplete Callback to be invoked upon successful restoration of the tabs.
*
* @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(
webViewHistoryItemList: List<WebViewHistoryItem>,
currentTab: Int
currentTab: Int,
onComplete: () -> Unit
) {
try {
currentWebViewIndex = 0
@ -2643,8 +2775,9 @@ abstract class CoreReaderFragment :
}
}
selectTab(currentTab)
} catch (e: JSONException) {
Log.w(TAG_KIWIX, "Kiwix shared preferences corrupted", e)
onComplete.invoke()
} catch (ignore: Exception) {
Log.w(TAG_KIWIX, "Kiwix shared preferences corrupted", ignore)
activity.toast(R.string.could_not_restore_tabs, Toast.LENGTH_LONG)
}
// After restoring the tabs, observe any search actions that the user might have triggered.
@ -2671,6 +2804,18 @@ abstract class CoreReaderFragment :
)
}
/**
* Restores the state of a given KiwixWebView based on the provided WebViewHistoryItem.
*
* This method retrieves the back-forward list from the WebViewHistoryItem and
* uses it to restore the web view's state. It also sets the vertical scroll position
* of the web view to the position stored in the WebViewHistoryItem.
*
* If the provided WebViewHistoryItem is null, the method does nothing.
*
* @param webView The KiwixWebView instance whose state is to be restored.
* @param webViewHistoryItem The WebViewHistoryItem containing the saved state and scroll position.
*/
private fun restoreTabState(webView: KiwixWebView, webViewHistoryItem: WebViewHistoryItem?) {
webViewHistoryItem?.webViewBackForwardListBundle?.let { bundle ->
webView.restoreState(bundle)
@ -2744,28 +2889,29 @@ abstract class CoreReaderFragment :
}
/**
* Restores the view state after successfully reading valid JSON from shared preferences.
* Restores the view state after successfully reading valid webViewHistory from room database.
* Developers modifying this method in subclasses, such as CustomReaderFragment and
* KiwixReaderFragment, should review and consider the implementations in those subclasses
* (e.g., CustomReaderFragment.restoreViewStateOnValidJSON,
* KiwixReaderFragment.restoreViewStateOnValidJSON) to ensure consistent behavior
* when handling valid JSON scenarios.
* (e.g., CustomReaderFragment.restoreViewStateOnValidWebViewHistory,
* KiwixReaderFragment.restoreViewStateOnValidWebViewHistory) to ensure consistent behavior
* when handling valid webViewHistory scenarios.
*/
protected abstract fun restoreViewStateOnValidJSON(
protected abstract fun restoreViewStateOnValidWebViewHistory(
webViewHistoryItemList: List<WebViewHistoryItem>,
currentTab: Int,
restoreOrigin: RestoreOrigin
restoreOrigin: RestoreOrigin,
onComplete: () -> Unit
)
/**
* Restores the view state when the attempt to read JSON from shared preferences fails
* due to invalid or corrupted data. Developers modifying this method in subclasses, such as
* Restores the view state when the attempt to read webViewHistory from room database fails
* due to the absence of any history records. Developers modifying this method in subclasses, such as
* CustomReaderFragment and KiwixReaderFragment, should review and consider the implementations
* in those subclasses (e.g., CustomReaderFragment.restoreViewStateOnInvalidJSON,
* KiwixReaderFragment.restoreViewStateOnInvalidJSON) to ensure consistent behavior
* in those subclasses (e.g., CustomReaderFragment.restoreViewStateOnInvalidWebViewHistory,
* KiwixReaderFragment.restoreViewStateOnInvalidWebViewHistory) to ensure consistent behavior
* when handling invalid JSON scenarios.
*/
abstract fun restoreViewStateOnInvalidJSON()
abstract fun restoreViewStateOnInvalidWebViewHistory()
}
enum class RestoreOrigin {

View File

@ -61,6 +61,7 @@ class MainMenu(
fun onRandomArticleMenuClicked()
fun onReadAloudMenuClicked()
fun onFullscreenMenuClicked()
fun onSearchMenuClickedMenuClicked()
}
init {
@ -154,7 +155,7 @@ class MainMenu(
}
private fun navigateToSearch(): Boolean {
(activity as CoreMainActivity).openSearch(isOpenedFromTabView = isInTabSwitcher)
menuClickListener.onSearchMenuClickedMenuClicked()
return true
}

View File

@ -150,25 +150,26 @@ class CustomReaderFragment : CoreReaderFragment() {
}
/**
* Restores the view state when the attempt to read JSON from shared preferences fails
* due to invalid or corrupted data. In this case, it opens the homepage of the zim file,
* as custom apps always have the zim file available.
* Restores the view state when the attempt to read web view history from the room database fails
* 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 restoreViewStateOnInvalidJSON() {
override fun restoreViewStateOnInvalidWebViewHistory() {
openHomeScreen()
}
/**
* Restores the view state when the JSON data is valid. This method restores the tabs
* and loads the last opened article in the specified tab.
* Restores the view state when the webViewHistory data is valid.
* This method restores the tabs with webView pages history.
*/
override fun restoreViewStateOnValidJSON(
override fun restoreViewStateOnValidWebViewHistory(
webViewHistoryItemList: List<WebViewHistoryItem>,
currentTab: Int,
// Unused in custom apps as there is only one ZIM file that is already set.
restoreOrigin: RestoreOrigin
restoreOrigin: RestoreOrigin,
onComplete: () -> Unit
) {
restoreTabs(webViewHistoryItemList, currentTab)
restoreTabs(webViewHistoryItemList, currentTab, onComplete)
}
/**
@ -183,6 +184,27 @@ class CustomReaderFragment : CoreReaderFragment() {
)
}
/**
* Opens a ZIM file or an OBB file based on the validation of available files.
*
* This method uses the `customFileValidator` to check for the presence of required files.
* Depending on the validation results, it performs the following actions:
*
* - If a valid ZIM file is found:
* - It opens the ZIM file and creates a `ZimReaderSource` for it.
* - Saves the book information in the database to be displayed in the `ZimHostFragment`.
* - Manages the external launch and restores the view state if specified.
*
* - If both ZIM and OBB files are found:
* - The ZIM file is deleted, and the OBB file is opened instead.
* - Manages the external launch and restores the view state if specified.
*
* If no valid files are found and the app is not in test mode, the user is navigated to
* the `customDownloadFragment` to facilitate downloading the required files.
*
* @param shouldManageExternalLaunch Indicates whether to manage external launch and
* restore the view state after opening the file. Default is false.
*/
private fun openObbOrZim(shouldManageExternalLaunch: Boolean = false) {
customFileValidator.validate(
onFilesFound = {