Use updated webapphidetoolbarfeature
This commit is contained in:
parent
fc96e188ab
commit
704fc6f983
|
@ -15,6 +15,7 @@ import android.view.ViewGroup
|
||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
@ -24,15 +25,19 @@ import kotlinx.android.synthetic.main.fragment_browser.*
|
||||||
import kotlinx.android.synthetic.main.fragment_browser.view.*
|
import kotlinx.android.synthetic.main.fragment_browser.view.*
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.MainScope
|
import kotlinx.coroutines.MainScope
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.flow.mapNotNull
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import mozilla.appservices.places.BookmarkRoot
|
import mozilla.appservices.places.BookmarkRoot
|
||||||
import mozilla.components.browser.session.Session
|
import mozilla.components.browser.session.Session
|
||||||
import mozilla.components.browser.session.SessionManager
|
import mozilla.components.browser.session.SessionManager
|
||||||
import mozilla.components.browser.session.runWithSessionIdOrSelected
|
|
||||||
import mozilla.components.browser.state.action.ContentAction
|
import mozilla.components.browser.state.action.ContentAction
|
||||||
|
import mozilla.components.browser.state.selector.findTabOrCustomTabOrSelectedTab
|
||||||
|
import mozilla.components.browser.state.state.SessionState
|
||||||
import mozilla.components.browser.state.state.content.DownloadState
|
import mozilla.components.browser.state.state.content.DownloadState
|
||||||
import mozilla.components.browser.state.store.BrowserStore
|
import mozilla.components.browser.state.store.BrowserStore
|
||||||
import mozilla.components.browser.thumbnails.BrowserThumbnails
|
import mozilla.components.browser.thumbnails.BrowserThumbnails
|
||||||
|
@ -59,12 +64,14 @@ import mozilla.components.feature.session.behavior.EngineViewBottomBehavior
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissions
|
import mozilla.components.feature.sitepermissions.SitePermissions
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissionsFeature
|
import mozilla.components.feature.sitepermissions.SitePermissionsFeature
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
||||||
|
import mozilla.components.lib.state.ext.flowScoped
|
||||||
import mozilla.components.service.sync.logins.DefaultLoginValidationDelegate
|
import mozilla.components.service.sync.logins.DefaultLoginValidationDelegate
|
||||||
import mozilla.components.support.base.feature.PermissionsFeature
|
import mozilla.components.support.base.feature.PermissionsFeature
|
||||||
import mozilla.components.support.base.feature.UserInteractionHandler
|
import mozilla.components.support.base.feature.UserInteractionHandler
|
||||||
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
||||||
import mozilla.components.support.ktx.android.view.exitImmersiveModeIfNeeded
|
import mozilla.components.support.ktx.android.view.exitImmersiveModeIfNeeded
|
||||||
import mozilla.components.support.ktx.android.view.hideKeyboard
|
import mozilla.components.support.ktx.android.view.hideKeyboard
|
||||||
|
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
|
||||||
import org.mozilla.fenix.FeatureFlags
|
import org.mozilla.fenix.FeatureFlags
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.IntentReceiverActivity
|
import org.mozilla.fenix.IntentReceiverActivity
|
||||||
|
@ -105,6 +112,7 @@ import java.lang.ref.WeakReference
|
||||||
* This class only contains shared code focused on the main browsing content.
|
* This class only contains shared code focused on the main browsing content.
|
||||||
* UI code specific to the app or to custom tabs can be found in the subclasses.
|
* UI code specific to the app or to custom tabs can be found in the subclasses.
|
||||||
*/
|
*/
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
@Suppress("TooManyFunctions", "LargeClass")
|
@Suppress("TooManyFunctions", "LargeClass")
|
||||||
abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, SessionManager.Observer {
|
abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, SessionManager.Observer {
|
||||||
protected lateinit var browserFragmentStore: BrowserFragmentStore
|
protected lateinit var browserFragmentStore: BrowserFragmentStore
|
||||||
|
@ -143,7 +151,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
||||||
|
|
||||||
private var browserInitialized: Boolean = false
|
private var browserInitialized: Boolean = false
|
||||||
private var initUIJob: Job? = null
|
private var initUIJob: Job? = null
|
||||||
private var enteredPip = false
|
protected var webAppToolbarShouldBeVisible = true
|
||||||
|
|
||||||
private val sharedViewModel: SharedViewModel by activityViewModels()
|
private val sharedViewModel: SharedViewModel by activityViewModels()
|
||||||
|
|
||||||
|
@ -383,11 +391,10 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
||||||
resumeDownloadDialogState(session, store, view, context, toolbarHeight)
|
resumeDownloadDialogState(session, store, view, context, toolbarHeight)
|
||||||
|
|
||||||
pipFeature = PictureInPictureFeature(
|
pipFeature = PictureInPictureFeature(
|
||||||
requireComponents.core.sessionManager,
|
store = store,
|
||||||
requireActivity(),
|
activity = requireActivity(),
|
||||||
requireComponents.analytics.crashReporter,
|
crashReporting = context.components.analytics.crashReporter,
|
||||||
customTabSessionId,
|
tabId = customTabSessionId
|
||||||
::pipModeChanged
|
|
||||||
)
|
)
|
||||||
|
|
||||||
appLinksFeature.set(
|
appLinksFeature.set(
|
||||||
|
@ -528,6 +535,12 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
||||||
}
|
}
|
||||||
}, owner = viewLifecycleOwner)
|
}, owner = viewLifecycleOwner)
|
||||||
|
|
||||||
|
store.flowScoped(viewLifecycleOwner) { flow ->
|
||||||
|
flow.mapNotNull { state -> state.findTabOrCustomTabOrSelectedTab(customTabSessionId) }
|
||||||
|
.ifChanged { tab -> tab.content.pictureInPictureEnabled }
|
||||||
|
.collect { tab -> pipModeChanged(tab) }
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("ConstantConditionIf")
|
@Suppress("ConstantConditionIf")
|
||||||
if (FeatureFlags.pullToRefreshEnabled) {
|
if (FeatureFlags.pullToRefreshEnabled) {
|
||||||
val primaryTextColor =
|
val primaryTextColor =
|
||||||
|
@ -694,11 +707,11 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
||||||
@CallSuper
|
@CallSuper
|
||||||
final override fun onPause() {
|
final override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
|
val session = requireComponents.core.store.state.findTabOrCustomTabOrSelectedTab(customTabSessionId)
|
||||||
// If we didn't enter PiP, exit full screen on pause
|
// If we didn't enter PiP, exit full screen on pause
|
||||||
if (!enteredPip && fullScreenFeature.onBackPressed()) {
|
if (session?.content?.pictureInPictureEnabled == false && fullScreenFeature.onBackPressed()) {
|
||||||
fullScreenChanged(false)
|
fullScreenChanged(false)
|
||||||
}
|
}
|
||||||
enteredPip = false
|
|
||||||
if (findNavController().currentDestination?.id != R.id.searchFragment) {
|
if (findNavController().currentDestination?.id != R.id.searchFragment) {
|
||||||
view?.hideKeyboard()
|
view?.hideKeyboard()
|
||||||
}
|
}
|
||||||
|
@ -894,21 +907,13 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onHomePressed(): Boolean {
|
override fun onHomePressed() = pipFeature?.onHomePressed() ?: false
|
||||||
if (pipFeature?.onHomePressed() == true) {
|
|
||||||
enteredPip = true
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun pipModeChanged(enabled: Boolean) {
|
/**
|
||||||
val fullScreenMode =
|
* Exit fullscreen mode when exiting PIP mode
|
||||||
requireComponents.core.sessionManager.runWithSessionIdOrSelected(customTabSessionId) { session ->
|
*/
|
||||||
session.fullScreenMode
|
private fun pipModeChanged(session: SessionState) {
|
||||||
}
|
if (!session.content.pictureInPictureEnabled && session.content.fullScreen) {
|
||||||
// If we're exiting PIP mode and we're in fullscreen mode, then we should exit fullscreen mode as well.
|
|
||||||
if (!enabled && fullScreenMode) {
|
|
||||||
onBackPressed()
|
onBackPressed()
|
||||||
fullScreenChanged(false)
|
fullScreenChanged(false)
|
||||||
}
|
}
|
||||||
|
@ -938,7 +943,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
||||||
.setText(getString(R.string.full_screen_notification))
|
.setText(getString(R.string.full_screen_notification))
|
||||||
.show()
|
.show()
|
||||||
activity?.enterToImmersiveMode()
|
activity?.enterToImmersiveMode()
|
||||||
browserToolbarView.view.visibility = View.GONE
|
browserToolbarView.view.isVisible = false
|
||||||
|
|
||||||
engineView.setDynamicToolbarMaxHeight(0)
|
engineView.setDynamicToolbarMaxHeight(0)
|
||||||
browserToolbarView.expand()
|
browserToolbarView.expand()
|
||||||
|
@ -949,19 +954,14 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
||||||
(activity as? HomeActivity)?.let { activity ->
|
(activity as? HomeActivity)?.let { activity ->
|
||||||
activity.themeManager.applyStatusBarTheme(activity)
|
activity.themeManager.applyStatusBarTheme(activity)
|
||||||
}
|
}
|
||||||
browserToolbarView.view.visibility = View.VISIBLE
|
if (webAppToolbarShouldBeVisible) {
|
||||||
val toolbarHeight = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height)
|
browserToolbarView.view.isVisible = true
|
||||||
engineView.setDynamicToolbarMaxHeight(toolbarHeight)
|
val toolbarHeight = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height)
|
||||||
|
engineView.setDynamicToolbarMaxHeight(toolbarHeight)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getListOfSessions(
|
|
||||||
private: Boolean = (activity as HomeActivity).browsingModeManager.mode.isPrivate
|
|
||||||
): List<Session> {
|
|
||||||
return requireComponents.core.sessionManager.sessionsOfType(private = private)
|
|
||||||
.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dereference these views when the fragment view is destroyed to prevent memory leaks
|
* Dereference these views when the fragment view is destroyed to prevent memory leaks
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,7 +14,6 @@ import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import kotlinx.android.synthetic.main.fragment_browser.*
|
|
||||||
import kotlinx.android.synthetic.main.fragment_browser.view.*
|
import kotlinx.android.synthetic.main.fragment_browser.view.*
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import mozilla.components.browser.session.Session
|
import mozilla.components.browser.session.Session
|
||||||
|
|
|
@ -7,6 +7,7 @@ package org.mozilla.fenix.customtabs
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import kotlinx.android.synthetic.main.component_browser_top_toolbar.*
|
import kotlinx.android.synthetic.main.component_browser_top_toolbar.*
|
||||||
import kotlinx.android.synthetic.main.fragment_browser.*
|
import kotlinx.android.synthetic.main.fragment_browser.*
|
||||||
|
@ -17,15 +18,12 @@ import mozilla.components.concept.engine.manifest.WebAppManifestParser
|
||||||
import mozilla.components.concept.engine.manifest.getOrNull
|
import mozilla.components.concept.engine.manifest.getOrNull
|
||||||
import mozilla.components.feature.contextmenu.ContextMenuCandidate
|
import mozilla.components.feature.contextmenu.ContextMenuCandidate
|
||||||
import mozilla.components.feature.customtabs.CustomTabWindowFeature
|
import mozilla.components.feature.customtabs.CustomTabWindowFeature
|
||||||
import mozilla.components.feature.pwa.ext.getTrustedScope
|
|
||||||
import mozilla.components.feature.pwa.ext.trustedOrigins
|
|
||||||
import mozilla.components.feature.pwa.feature.ManifestUpdateFeature
|
import mozilla.components.feature.pwa.feature.ManifestUpdateFeature
|
||||||
import mozilla.components.feature.pwa.feature.WebAppActivityFeature
|
import mozilla.components.feature.pwa.feature.WebAppActivityFeature
|
||||||
import mozilla.components.feature.pwa.feature.WebAppHideToolbarFeature
|
import mozilla.components.feature.pwa.feature.WebAppHideToolbarFeature
|
||||||
import mozilla.components.feature.pwa.feature.WebAppSiteControlsFeature
|
import mozilla.components.feature.pwa.feature.WebAppSiteControlsFeature
|
||||||
import mozilla.components.feature.session.TrackingProtectionUseCases
|
import mozilla.components.feature.session.TrackingProtectionUseCases
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissions
|
import mozilla.components.feature.sitepermissions.SitePermissions
|
||||||
import mozilla.components.lib.state.ext.consumeFrom
|
|
||||||
import mozilla.components.support.base.feature.UserInteractionHandler
|
import mozilla.components.support.base.feature.UserInteractionHandler
|
||||||
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
||||||
import mozilla.components.support.ktx.android.arch.lifecycle.addObservers
|
import mozilla.components.support.ktx.android.arch.lifecycle.addObservers
|
||||||
|
@ -60,7 +58,6 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
|
||||||
val manifest = args.webAppManifest?.let { json ->
|
val manifest = args.webAppManifest?.let { json ->
|
||||||
WebAppManifestParser().parse(json).getOrNull()
|
WebAppManifestParser().parse(json).getOrNull()
|
||||||
}
|
}
|
||||||
val trustedScopes = listOfNotNull(manifest?.getTrustedScope())
|
|
||||||
|
|
||||||
customTabSessionId?.let { customTabSessionId ->
|
customTabSessionId?.let { customTabSessionId ->
|
||||||
customTabsIntegration.set(
|
customTabsIntegration.set(
|
||||||
|
@ -99,11 +96,13 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
|
||||||
|
|
||||||
hideToolbarFeature.set(
|
hideToolbarFeature.set(
|
||||||
feature = WebAppHideToolbarFeature(
|
feature = WebAppHideToolbarFeature(
|
||||||
requireComponents.core.sessionManager,
|
store = requireComponents.core.store,
|
||||||
toolbar,
|
customTabsStore = requireComponents.core.customTabsStore,
|
||||||
customTabSessionId,
|
tabId = customTabSessionId,
|
||||||
trustedScopes
|
manifest = manifest
|
||||||
) { toolbarVisible ->
|
) { toolbarVisible ->
|
||||||
|
browserToolbarView.view.isVisible = toolbarVisible
|
||||||
|
webAppToolbarShouldBeVisible = toolbarVisible
|
||||||
if (!toolbarVisible) { engineView.setDynamicToolbarMaxHeight(0) }
|
if (!toolbarVisible) { engineView.setDynamicToolbarMaxHeight(0) }
|
||||||
},
|
},
|
||||||
owner = this,
|
owner = this,
|
||||||
|
@ -151,17 +150,6 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
consumeFrom(components.core.customTabsStore) { state ->
|
|
||||||
getSessionById()
|
|
||||||
?.let { session -> session.customTabConfig?.sessionToken }
|
|
||||||
?.let { token -> state.tabs[token] }
|
|
||||||
?.let { tabState ->
|
|
||||||
hideToolbarFeature.withFeature {
|
|
||||||
it.onTrustedScopesChange(tabState.trustedOrigins)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user