Skip to content

Commit

Permalink
suspended setZimReaderSource and launched the coroutine inside a life…
Browse files Browse the repository at this point in the history
…cycle
  • Loading branch information
CalebKL committed Dec 11, 2024
1 parent 9fc6e66 commit d2a796f
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 111 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.lifecycleScope
import com.google.android.material.bottomnavigation.BottomNavigationView
import kotlinx.coroutines.launch
import org.kiwix.kiwixmobile.R
Expand Down Expand Up @@ -165,29 +166,31 @@ class KiwixReaderFragment : CoreReaderFragment() {
}

override fun hideTabSwitcher() {
actionBar?.let { actionBar ->
actionBar.setDisplayShowTitleEnabled(true)
toolbar?.let { activity?.setupDrawerToggle(it, true) }
lifecycleScope.launch {
actionBar?.let { actionBar ->
actionBar.setDisplayShowTitleEnabled(true)
toolbar?.let { activity?.setupDrawerToggle(it, true) }

setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)

closeAllTabsButton?.setImageDrawableCompat(drawable.ic_close_black_24dp)
if (tabSwitcherRoot?.visibility == View.VISIBLE) {
tabSwitcherRoot?.visibility = GONE
startAnimation(tabSwitcherRoot, anim.slide_up)
progressBar?.visibility = View.GONE
progressBar?.progress = 0
contentFrame?.visibility = View.VISIBLE
}
mainMenu?.showWebViewOptions(true)
if (webViewList.isEmpty()) {
exitBook()
} else {
// Reset the top margin of web views to 0 to remove any previously set margin
// This ensures that the web views are displayed without any additional
// top margin for kiwix main app.
setTopMarginToWebViews(0)
selectTab(currentWebViewIndex)
closeAllTabsButton?.setImageDrawableCompat(drawable.ic_close_black_24dp)
if (tabSwitcherRoot?.visibility == View.VISIBLE) {
tabSwitcherRoot?.visibility = GONE
startAnimation(tabSwitcherRoot, anim.slide_up)
progressBar?.visibility = View.GONE
progressBar?.progress = 0
contentFrame?.visibility = View.VISIBLE
}
mainMenu?.showWebViewOptions(true)
if (webViewList.isEmpty()) {
exitBook()
} else {
// Reset the top margin of web views to 0 to remove any previously set margin
// This ensures that the web views are displayed without any additional
// top margin for kiwix main app.
setTopMarginToWebViews(0)
selectTab(currentWebViewIndex)
}
}
}
}
Expand Down Expand Up @@ -229,7 +232,7 @@ class KiwixReaderFragment : CoreReaderFragment() {
}
}

override fun restoreViewStateOnInvalidJSON() {
override suspend fun restoreViewStateOnInvalidJSON() {
Log.d(TAG_KIWIX, "Kiwix normal start, no zimFile loaded last time -> display home page")
exitBook()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1398,7 +1398,7 @@ abstract class CoreReaderFragment :
mainMenu?.showBookSpecificMenuItems()
}

protected fun exitBook() {
protected suspend fun exitBook() {
showNoBookOpenViews()
bottomToolbar?.visibility = View.GONE
actionBar?.title = getString(R.string.reader)
Expand All @@ -1408,7 +1408,7 @@ abstract class CoreReaderFragment :
closeZimBook()
}

fun closeZimBook() {
suspend fun closeZimBook() {
zimReaderContainer?.setZimReaderSource(null)
}

Expand All @@ -1428,29 +1428,31 @@ abstract class CoreReaderFragment :
}

private fun restoreDeletedTab(index: Int) {
if (webViewList.isEmpty()) {
reopenBook()
}
tempWebViewForUndo?.let {
if (tabSwitcherRoot?.visibility == View.GONE) {
// Remove the top margin from the webView when the tabSwitcher is not visible.
// We have added this margin in `TabsAdapter` to not show the top margin in tabs.
// `tempWebViewForUndo` saved with that margin so before showing it to the `contentFrame`
// We need to set full width and height for properly showing the content of webView.
it.layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
lifecycleScope.launch {
if (webViewList.isEmpty()) {
reopenBook()
}
zimReaderContainer?.setZimReaderSource(tempZimSourceForUndo)
webViewList.add(index, it)
tabsAdapter?.notifyDataSetChanged()
snackBarRoot?.let { root ->
Snackbar.make(root, R.string.tab_restored, Snackbar.LENGTH_SHORT).show()
tempWebViewForUndo?.let {
if (tabSwitcherRoot?.visibility == View.GONE) {
// Remove the top margin from the webView when the tabSwitcher is not visible.
// We have added this margin in `TabsAdapter` to not show the top margin in tabs.
// `tempWebViewForUndo` saved with that margin so before showing it to the `contentFrame`
// We need to set full width and height for properly showing the content of webView.
it.layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
}
zimReaderContainer?.setZimReaderSource(tempZimSourceForUndo)
webViewList.add(index, it)
tabsAdapter?.notifyDataSetChanged()
snackBarRoot?.let { root ->
Snackbar.make(root, R.string.tab_restored, Snackbar.LENGTH_SHORT).show()
}
setUpWithTextToSpeech(it)
updateBottomToolbarVisibility()
safelyAddWebView(it)
}
setUpWithTextToSpeech(it)
updateBottomToolbarVisibility()
safelyAddWebView(it)
}
}

Expand Down Expand Up @@ -1861,18 +1863,20 @@ abstract class CoreReaderFragment :
}

private fun restoreDeletedTabs() {
if (tempWebViewListForUndo.isNotEmpty()) {
zimReaderContainer?.setZimReaderSource(tempZimSourceForUndo)
webViewList.addAll(tempWebViewListForUndo)
tabsAdapter?.notifyDataSetChanged()
snackBarRoot?.let { root ->
Snackbar.make(root, R.string.tabs_restored, Snackbar.LENGTH_SHORT).show()
lifecycleScope.launch {
if (tempWebViewListForUndo.isNotEmpty()) {
zimReaderContainer?.setZimReaderSource(tempZimSourceForUndo)
webViewList.addAll(tempWebViewListForUndo)
tabsAdapter?.notifyDataSetChanged()
snackBarRoot?.let { root ->
Snackbar.make(root, R.string.tabs_restored, Snackbar.LENGTH_SHORT).show()
}
reopenBook()
showTabSwitcher()
setUpWithTextToSpeech(tempWebViewListForUndo.last())
updateBottomToolbarVisibility()
safelyAddWebView(tempWebViewListForUndo.last())
}
reopenBook()
showTabSwitcher()
setUpWithTextToSpeech(tempWebViewListForUndo.last())
updateBottomToolbarVisibility()
safelyAddWebView(tempWebViewListForUndo.last())
}
}

Expand Down Expand Up @@ -2496,7 +2500,7 @@ abstract class CoreReaderFragment :
private fun isInvalidJson(jsonString: String?): Boolean =
jsonString == null || jsonString == "[]"

protected fun manageExternalLaunchAndRestoringViewState(
protected suspend fun manageExternalLaunchAndRestoringViewState(
restoreOrigin: RestoreOrigin = FromExternalLaunch
) {
val settings = requireActivity().getSharedPreferences(
Expand Down Expand Up @@ -2637,7 +2641,7 @@ abstract class CoreReaderFragment :
* KiwixReaderFragment.restoreViewStateOnInvalidJSON) to ensure consistent behavior
* when handling invalid JSON scenarios.
*/
abstract fun restoreViewStateOnInvalidJSON()
abstract suspend fun restoreViewStateOnInvalidJSON()
}

enum class RestoreOrigin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
package org.kiwix.kiwixmobile.core.page.notes.viewmodel.effects

import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import io.reactivex.processors.PublishProcessor
import kotlinx.coroutines.launch
import org.json.JSONArray
import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent
Expand Down Expand Up @@ -51,36 +53,38 @@ data class ShowOpenNoteDialog(
ShowNoteDialog,
{ effects.offer(OpenPage(page, zimReaderContainer)) },
{
val item = page as NoteListItem
// Check if toDatabase is not null, and then set it in zimReaderContainer.
// For custom apps, we are currently using fileDescriptor, and they only have a single file in them,
// which is already set in zimReaderContainer, so there's no need to set it again.
item.zimReaderSource?.toDatabase().let {
val currentZimReaderSource = zimReaderContainer.zimReaderSource
if (!activity.isCustomApp()) {
zimReaderContainer.setZimReaderSource(item.zimReaderSource)
}
if (zimReaderContainer.zimReaderSource != currentZimReaderSource) {
// if current zim file is not the same set the main page of that zim file
// so that when we go back it properly loads the article, and do nothing if the
// zim file is same because there might be multiple tabs opened.
val settings = activity.getSharedPreferences(
SharedPreferenceUtil.PREF_KIWIX_MOBILE,
0
)
val editor = settings.edit()
val urls = JSONArray()
val positions = JSONArray()
urls.put(CONTENT_PREFIX + zimReaderContainer.mainPage)
positions.put(0)
editor.putString(TAG_CURRENT_FILE, zimReaderContainer.zimReaderSource?.toDatabase())
editor.putString(TAG_CURRENT_ARTICLES, "$urls")
editor.putString(TAG_CURRENT_POSITIONS, "$positions")
editor.putInt(TAG_CURRENT_TAB, 0)
editor.apply()
activity.lifecycleScope.launch {
val item = page as NoteListItem
// Check if toDatabase is not null, and then set it in zimReaderContainer.
// For custom apps, we are currently using fileDescriptor, and they only have a single file in them,
// which is already set in zimReaderContainer, so there's no need to set it again.
item.zimReaderSource?.toDatabase().let {
val currentZimReaderSource = zimReaderContainer.zimReaderSource
if (!activity.isCustomApp()) {
zimReaderContainer.setZimReaderSource(item.zimReaderSource)
}
if (zimReaderContainer.zimReaderSource != currentZimReaderSource) {
// if current zim file is not the same set the main page of that zim file
// so that when we go back it properly loads the article, and do nothing if the
// zim file is same because there might be multiple tabs opened.
val settings = activity.getSharedPreferences(
SharedPreferenceUtil.PREF_KIWIX_MOBILE,
0
)
val editor = settings.edit()
val urls = JSONArray()
val positions = JSONArray()
urls.put(CONTENT_PREFIX + zimReaderContainer.mainPage)
positions.put(0)
editor.putString(TAG_CURRENT_FILE, zimReaderContainer.zimReaderSource?.toDatabase())
editor.putString(TAG_CURRENT_ARTICLES, "$urls")
editor.putString(TAG_CURRENT_POSITIONS, "$positions")
editor.putInt(TAG_CURRENT_TAB, 0)
editor.apply()
}
}
effects.offer(OpenNote(item.noteFilePath, item.zimUrl, item.title))
}
effects.offer(OpenNote(item.noteFilePath, item.zimUrl, item.title))
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,14 @@ class ZimReaderContainer @Inject constructor(private val zimFileReaderFactory: F
field = value
}

fun setZimReaderSource(zimReaderSource: ZimReaderSource?) {
suspend fun setZimReaderSource(zimReaderSource: ZimReaderSource?) {
if (zimReaderSource == zimFileReader?.zimReaderSource) {
return
}
zimFileReader = runBlocking {
zimFileReader =
if (zimReaderSource?.exists() == true && zimReaderSource.canOpenInLibkiwix())
zimFileReaderFactory.create(zimReaderSource)
else null
}
}

fun getPageUrlFromTitle(title: String) = zimFileReader?.getPageUrlFrom(title)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.net.toUri
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import kotlinx.coroutines.launch
import org.kiwix.kiwixmobile.core.R.dimen
Expand Down Expand Up @@ -70,27 +71,29 @@ class CustomReaderFragment : CoreReaderFragment() {
@Suppress("NestedBlockDepth")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (enforcedLanguage()) {
return
}

if (isAdded) {
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
if (BuildConfig.DISABLE_SIDEBAR) {
val toolbarToc =
activity?.findViewById<ImageView>(org.kiwix.kiwixmobile.core.R.id.bottom_toolbar_toc)
toolbarToc?.isEnabled = false
lifecycleScope.launch {
if (enforcedLanguage()) {
return@launch
}
with(activity as AppCompatActivity) {
supportActionBar?.setDisplayHomeAsUpEnabled(true)
toolbar?.let(::setUpDrawerToggle)
}
loadPageFromNavigationArguments()
if (BuildConfig.DISABLE_EXTERNAL_LINK) {
// If "external links" are disabled in a custom app,
// this sets the shared preference to not show the external link popup
// when opening external links.
sharedPreferenceUtil?.putPrefExternalLinkPopup(false)

if (isAdded) {
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
if (BuildConfig.DISABLE_SIDEBAR) {
val toolbarToc =
activity?.findViewById<ImageView>(org.kiwix.kiwixmobile.core.R.id.bottom_toolbar_toc)
toolbarToc?.isEnabled = false
}
with(activity as AppCompatActivity) {
supportActionBar?.setDisplayHomeAsUpEnabled(true)
toolbar?.let(::setUpDrawerToggle)
}
loadPageFromNavigationArguments()
if (BuildConfig.DISABLE_EXTERNAL_LINK) {
// If "external links" are disabled in a custom app,
// this sets the shared preference to not show the external link popup
// when opening external links.
sharedPreferenceUtil?.putPrefExternalLinkPopup(false)
}
}
}
}
Expand Down Expand Up @@ -135,7 +138,7 @@ class CustomReaderFragment : CoreReaderFragment() {
super.setTabSwitcherVisibility(visibility)
}

private fun loadPageFromNavigationArguments() {
private suspend fun loadPageFromNavigationArguments() {
val args = CustomReaderFragmentArgs.fromBundle(requireArguments())
if (args.pageUrl.isNotEmpty()) {
loadUrlWithCurrentWebview(args.pageUrl)
Expand All @@ -154,7 +157,7 @@ class CustomReaderFragment : CoreReaderFragment() {
* 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.
*/
override fun restoreViewStateOnInvalidJSON() {
override suspend fun restoreViewStateOnInvalidJSON() {
openHomeScreen()
}

Expand Down

0 comments on commit d2a796f

Please sign in to comment.