#2319 observing fragment results instead of using navigation bundles

This commit is contained in:
HissPirat 2020-08-28 12:31:38 +02:00
parent 3e58e145e3
commit fe61430fb3
7 changed files with 116 additions and 37 deletions

View File

@ -34,6 +34,7 @@ import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.net.toFile import androidx.core.net.toFile
import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.Observer
import kotlinx.android.synthetic.main.activity_kiwix_main.bottom_nav_view import kotlinx.android.synthetic.main.activity_kiwix_main.bottom_nav_view
import org.kiwix.kiwixmobile.R import org.kiwix.kiwixmobile.R
import org.kiwix.kiwixmobile.cachedComponent import org.kiwix.kiwixmobile.cachedComponent
@ -42,6 +43,8 @@ import org.kiwix.kiwixmobile.core.base.BaseActivity
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldCall import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldCall
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldNotCall import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldNotCall
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.consumeObservable
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.observeNavigationResult
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setupDrawerToggle import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setupDrawerToggle
import org.kiwix.kiwixmobile.core.extensions.getAttribute import org.kiwix.kiwixmobile.core.extensions.getAttribute
import org.kiwix.kiwixmobile.core.extensions.setImageDrawableCompat import org.kiwix.kiwixmobile.core.extensions.setImageDrawableCompat
@ -50,11 +53,16 @@ import org.kiwix.kiwixmobile.core.extensions.toast
import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.core.main.CoreReaderFragment import org.kiwix.kiwixmobile.core.main.CoreReaderFragment
import org.kiwix.kiwixmobile.core.main.CoreWebViewClient import org.kiwix.kiwixmobile.core.main.CoreWebViewClient
import org.kiwix.kiwixmobile.core.main.FIND_IN_PAGE_SEARCH_STRING
import org.kiwix.kiwixmobile.core.main.ToolbarScrollingKiwixWebView import org.kiwix.kiwixmobile.core.main.ToolbarScrollingKiwixWebView
import org.kiwix.kiwixmobile.core.search.viewmodel.effects.SearchItemToOpen
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.core.utils.TAG_CURRENT_FILE import org.kiwix.kiwixmobile.core.utils.TAG_CURRENT_FILE
import org.kiwix.kiwixmobile.core.utils.TAG_FILE_SEARCHED
import org.kiwix.kiwixmobile.core.utils.TAG_KIWIX import org.kiwix.kiwixmobile.core.utils.TAG_KIWIX
import org.kiwix.kiwixmobile.core.utils.files.FileUtils import org.kiwix.kiwixmobile.core.utils.files.FileUtils
import org.kiwix.kiwixmobile.core.utils.titleToUrl
import org.kiwix.kiwixmobile.core.utils.urlSuffixToParsableUrl
import java.io.File import java.io.File
private const val HIDE_TAB_SWITCHER_DELAY: Long = 300 private const val HIDE_TAB_SWITCHER_DELAY: Long = 300
@ -78,6 +86,27 @@ class KiwixReaderFragment : CoreReaderFragment() {
activity.setupDrawerToggle(toolbar) activity.setupDrawerToggle(toolbar)
setFragmentContainerBottomMarginToSizeOfNavBar() setFragmentContainerBottomMarginToSizeOfNavBar()
openPageInBookFromNavigationArguments() openPageInBookFromNavigationArguments()
requireActivity().observeNavigationResult<String>(
FIND_IN_PAGE_SEARCH_STRING,
viewLifecycleOwner,
Observer(this::findInPage)
)
requireActivity().observeNavigationResult<SearchItemToOpen>(
TAG_FILE_SEARCHED,
viewLifecycleOwner,
Observer(::openSearchItem)
)
}
private fun openSearchItem(item: SearchItemToOpen) {
zimReaderContainer.titleToUrl(item.pageTitle)?.apply {
if (item.shouldOpenInNewTab) {
createNewTab()
}
loadUrlWithCurrentWebview(zimReaderContainer.urlSuffixToParsableUrl(this))
}
requireActivity().consumeObservable<SearchItemToOpen>(TAG_FILE_SEARCHED)
} }
private fun openPageInBookFromNavigationArguments() { private fun openPageInBookFromNavigationArguments() {
@ -86,10 +115,6 @@ class KiwixReaderFragment : CoreReaderFragment() {
if (args.zimFileUri.isNotEmpty()) { if (args.zimFileUri.isNotEmpty()) {
tryOpeningZimFile(args.zimFileUri) tryOpeningZimFile(args.zimFileUri)
} }
if (args.shouldOpenInNewTab) {
manageExternalLaunchAndRestoringViewState()
createNewTab()
}
loadUrlWithCurrentWebview(args.pageUrl) loadUrlWithCurrentWebview(args.pageUrl)
} else { } else {
if (args.zimFileUri.isNotEmpty()) { if (args.zimFileUri.isNotEmpty()) {
@ -98,9 +123,6 @@ class KiwixReaderFragment : CoreReaderFragment() {
manageExternalLaunchAndRestoringViewState() manageExternalLaunchAndRestoringViewState()
} }
} }
if (args.findInPageSearchString.isNotEmpty()) {
findInPage(args.findInPageSearchString)
}
requireArguments().clear() requireArguments().clear()
} }

View File

@ -27,11 +27,13 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.lifecycle.observe
import androidx.navigation.NavDirections import androidx.navigation.NavDirections
import org.kiwix.kiwixmobile.core.CoreApp
import org.kiwix.kiwixmobile.core.di.components.CoreActivityComponent import org.kiwix.kiwixmobile.core.di.components.CoreActivityComponent
import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.main.CoreMainActivity
@ -81,27 +83,51 @@ object ActivityExtensions {
.get(T::class.java) .get(T::class.java)
fun Activity.navigate(action: NavDirections) { fun Activity.navigate(action: NavDirections) {
(this as CoreMainActivity).navigate(action) asCoreMainActivity().navigate(action)
} }
val Activity.cachedComponent: CoreActivityComponent val Activity.cachedComponent: CoreActivityComponent
get() = (this as CoreMainActivity).cachedComponent get() = asCoreMainActivity().cachedComponent
fun Activity.setupDrawerToggle(toolbar: Toolbar) = fun Activity.setupDrawerToggle(toolbar: Toolbar) =
(this as CoreMainActivity).setupDrawerToggle(toolbar) asCoreMainActivity().setupDrawerToggle(toolbar)
fun Activity.navigate(fragmentId: Int) { fun Activity.navigate(fragmentId: Int) {
(this as CoreMainActivity).navigate(fragmentId) asCoreMainActivity().navigate(fragmentId)
} }
fun Activity.navigate(fragmentId: Int, bundle: Bundle) { fun Activity.navigate(fragmentId: Int, bundle: Bundle) {
(this as CoreMainActivity).navigate(fragmentId, bundle) asCoreMainActivity().navigate(fragmentId, bundle)
} }
fun Activity.popNavigationBackstack() { fun Activity.popNavigationBackstack() {
(this as CoreMainActivity).navController.popBackStack() asCoreMainActivity().navController.popBackStack()
} }
val Activity.coreActivityComponent private fun Activity.asCoreMainActivity() = (this as CoreMainActivity)
get() = CoreApp.coreComponent.activityComponentBuilder().activity(this).build()
fun <T> Activity.getObservableNavigationResult(key: String = "result") =
asCoreMainActivity().navController.currentBackStackEntry?.savedStateHandle
?.getLiveData<T>(key)
fun <T> Activity.observeNavigationResult(
key: String,
owner: LifecycleOwner,
observer: Observer<T>
) {
getObservableNavigationResult<T>(key)?.observe(owner) {
observer.onChanged(it)
asCoreMainActivity().consumeObservable<T>(key)
}
}
fun <T> Activity.consumeObservable(key: String = "result") =
asCoreMainActivity().navController.currentBackStackEntry?.savedStateHandle?.remove<T>(key)
fun <T> Activity.setNavigationResult(result: T, key: String = "result") {
asCoreMainActivity().navController.previousBackStackEntry?.savedStateHandle?.set(
key,
result
)
}
} }

View File

@ -46,8 +46,6 @@ import org.kiwix.kiwixmobile.core.utils.EXTRA_IS_WIDGET_VOICE
import org.kiwix.kiwixmobile.core.utils.ExternalLinkOpener import org.kiwix.kiwixmobile.core.utils.ExternalLinkOpener
import org.kiwix.kiwixmobile.core.utils.TAG_FROM_TAB_SWITCHER import org.kiwix.kiwixmobile.core.utils.TAG_FROM_TAB_SWITCHER
import org.kiwix.kiwixmobile.core.utils.dialog.RateDialogHandler import org.kiwix.kiwixmobile.core.utils.dialog.RateDialogHandler
import org.kiwix.kiwixmobile.core.utils.titleToUrl
import org.kiwix.kiwixmobile.core.utils.urlSuffixToParsableUrl
import javax.inject.Inject import javax.inject.Inject
import kotlin.system.exitProcess import kotlin.system.exitProcess
@ -297,13 +295,6 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider {
disableDrawer() disableDrawer()
} }
fun openSearchItem(searchItemTitle: String, shouldOpenInNewTab: Boolean) {
val url = zimReaderContainer.titleToUrl(searchItemTitle)
if (url != null) {
openPage(zimReaderContainer.urlSuffixToParsableUrl(url), "", shouldOpenInNewTab)
}
}
fun findInPage(searchString: String) { fun findInPage(searchString: String) {
navigate(readerFragmentResId, bundleOf(FIND_IN_PAGE_SEARCH_STRING to searchString)) navigate(readerFragmentResId, bundleOf(FIND_IN_PAGE_SEARCH_STRING to searchString))
} }

View File

@ -110,6 +110,7 @@ import org.kiwix.kiwixmobile.core.extensions.ViewGroupExtensions;
import org.kiwix.kiwixmobile.core.page.bookmark.adapter.BookmarkItem; import org.kiwix.kiwixmobile.core.page.bookmark.adapter.BookmarkItem;
import org.kiwix.kiwixmobile.core.reader.ZimFileReader; import org.kiwix.kiwixmobile.core.reader.ZimFileReader;
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer; import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer;
import org.kiwix.kiwixmobile.core.search.viewmodel.effects.SearchItemToOpen;
import org.kiwix.kiwixmobile.core.utils.ExternalLinkOpener; import org.kiwix.kiwixmobile.core.utils.ExternalLinkOpener;
import org.kiwix.kiwixmobile.core.utils.LanguageUtils; import org.kiwix.kiwixmobile.core.utils.LanguageUtils;
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil; import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil;
@ -346,6 +347,7 @@ public abstract class CoreReaderFragment extends BaseFragment
} }
} }
private void initTabCallback() { private void initTabCallback() {
tabCallback = new ItemTouchHelper.Callback() { tabCallback = new ItemTouchHelper.Callback() {
@Override @Override
@ -1582,4 +1584,7 @@ public abstract class CoreReaderFragment extends BaseFragment
String zimPositions, int currentTab); String zimPositions, int currentTab);
public abstract void restoreViewStateOnInvalidJSON(); public abstract void restoreViewStateOnInvalidJSON();
} }

View File

@ -18,18 +18,30 @@
package org.kiwix.kiwixmobile.core.search.viewmodel.effects package org.kiwix.kiwixmobile.core.search.viewmodel.effects
import android.os.Parcelable
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.parcel.Parcelize
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.popNavigationBackstack import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.popNavigationBackstack
import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setNavigationResult
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem
import org.kiwix.kiwixmobile.core.utils.TAG_FILE_SEARCHED
data class OpenSearchItem( data class OpenSearchItem(
private val searchListItem: SearchListItem, private val searchListItem: SearchListItem,
private val openInNewTab: Boolean = false private val openInNewTab: Boolean = false
) : SideEffect<Unit> { ) : SideEffect<Unit> {
override fun invokeWith(activity: AppCompatActivity) { override fun invokeWith(activity: AppCompatActivity) {
activity.setNavigationResult(
SearchItemToOpen(searchListItem.value, openInNewTab),
TAG_FILE_SEARCHED
)
activity.popNavigationBackstack() activity.popNavigationBackstack()
(activity as CoreMainActivity).openSearchItem(searchListItem.value, openInNewTab)
} }
} }
@Parcelize
data class SearchItemToOpen(
val pageTitle: String,
val shouldOpenInNewTab: Boolean
) : Parcelable

View File

@ -21,12 +21,13 @@ package org.kiwix.kiwixmobile.core.search.viewmodel.effects
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.popNavigationBackstack import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.popNavigationBackstack
import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setNavigationResult
import org.kiwix.kiwixmobile.core.main.FIND_IN_PAGE_SEARCH_STRING
data class SearchInPreviousScreen(private val searchString: String) : SideEffect<Unit> { data class SearchInPreviousScreen(private val searchString: String) : SideEffect<Unit> {
override fun invokeWith(activity: AppCompatActivity) { override fun invokeWith(activity: AppCompatActivity) {
activity.setNavigationResult(searchString, FIND_IN_PAGE_SEARCH_STRING)
activity.popNavigationBackstack() activity.popNavigationBackstack()
(activity as CoreMainActivity).findInPage(searchString)
} }
companion object { companion object {

View File

@ -36,17 +36,25 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.Observer
import org.kiwix.kiwixmobile.core.base.BaseActivity import org.kiwix.kiwixmobile.core.base.BaseActivity
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldCall import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldCall
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.consumeObservable
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.observeNavigationResult
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setupDrawerToggle import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.setupDrawerToggle
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start
import org.kiwix.kiwixmobile.core.main.CoreReaderFragment import org.kiwix.kiwixmobile.core.main.CoreReaderFragment
import org.kiwix.kiwixmobile.core.main.FIND_IN_PAGE_SEARCH_STRING
import org.kiwix.kiwixmobile.core.main.MainMenu import org.kiwix.kiwixmobile.core.main.MainMenu
import org.kiwix.kiwixmobile.core.reader.ZimFileReader.Companion.CONTENT_PREFIX import org.kiwix.kiwixmobile.core.reader.ZimFileReader.Companion.CONTENT_PREFIX
import org.kiwix.kiwixmobile.core.search.viewmodel.effects.SearchItemToOpen
import org.kiwix.kiwixmobile.core.utils.LanguageUtils
import org.kiwix.kiwixmobile.core.utils.TAG_FILE_SEARCHED
import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower
import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog
import org.kiwix.kiwixmobile.core.utils.LanguageUtils import org.kiwix.kiwixmobile.core.utils.titleToUrl
import org.kiwix.kiwixmobile.core.utils.urlSuffixToParsableUrl
import org.kiwix.kiwixmobile.custom.BuildConfig import org.kiwix.kiwixmobile.custom.BuildConfig
import org.kiwix.kiwixmobile.custom.R import org.kiwix.kiwixmobile.custom.R
import org.kiwix.kiwixmobile.custom.customActivityComponent import org.kiwix.kiwixmobile.custom.customActivityComponent
@ -81,23 +89,37 @@ class CustomReaderFragment : CoreReaderFragment() {
setupDrawerToggle(toolbar) setupDrawerToggle(toolbar)
} }
loadPageFromNavigationArguments() loadPageFromNavigationArguments()
requireActivity().observeNavigationResult<String>(
FIND_IN_PAGE_SEARCH_STRING,
viewLifecycleOwner,
Observer(this::findInPage)
)
requireActivity().observeNavigationResult<SearchItemToOpen>(
TAG_FILE_SEARCHED,
viewLifecycleOwner,
Observer(::openSearchItem)
)
}
private fun openSearchItem(item: SearchItemToOpen) {
zimReaderContainer.titleToUrl(item.pageTitle)?.apply {
if (item.shouldOpenInNewTab) {
createNewTab()
}
loadUrlWithCurrentWebview(zimReaderContainer.urlSuffixToParsableUrl(this))
}
requireActivity().consumeObservable<SearchItemToOpen>(TAG_FILE_SEARCHED)
} }
private fun loadPageFromNavigationArguments() { private fun loadPageFromNavigationArguments() {
val args = CustomReaderFragmentArgs.fromBundle(requireArguments()) val args = CustomReaderFragmentArgs.fromBundle(requireArguments())
if (args.pageUrl.isNotEmpty()) { if (args.pageUrl.isNotEmpty()) {
if (args.shouldOpenInNewTab) {
manageExternalLaunchAndRestoringViewState()
createNewTab()
}
loadUrlWithCurrentWebview(args.pageUrl) loadUrlWithCurrentWebview(args.pageUrl)
} else { } else {
openObbOrZim() openObbOrZim()
manageExternalLaunchAndRestoringViewState() manageExternalLaunchAndRestoringViewState()
} }
if (args.findInPageSearchString.isNotEmpty()) {
findInPage(args.findInPageSearchString)
}
requireArguments().clear() requireArguments().clear()
} }