1
0
Fork 0
fenix/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt

218 lines
8.2 KiB
Kotlin
Raw Normal View History

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.browser
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.coordinatorlayout.widget.CoordinatorLayout
2019-08-08 00:41:52 +02:00
import androidx.transition.TransitionInflater
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.fragment_browser.*
import kotlinx.android.synthetic.main.fragment_browser.view.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import mozilla.components.browser.session.Session
import mozilla.components.feature.contextmenu.ContextMenuCandidate
import mozilla.components.feature.readerview.ReaderViewFeature
2019-10-02 06:45:04 +02:00
import mozilla.components.feature.session.TrackingProtectionUseCases
2019-08-12 18:31:59 +02:00
import mozilla.components.feature.sitepermissions.SitePermissions
For #5574 - Migrate SessionControl to LibState (#6651) * For #5574 - Part 1: Port TabAction.SaveTabGroup to TabSessionInteractor and SessionControlController. (#6651) - Introduces the TabSessionInteractor, SessionControlInteractor and SessionControlController classes. - Removes the TabAction.SaveTabGroup. * For #5574 - Part 2: Port TabAction.PrivateBrowsingLearnMore to TabSessionInteractor and SessionControlController (#6651) * For #5574 - Part 3: Port TabAction.ShareTabs to TabSessionInteractor and SessionControlController (#6651) * For #5574 - Part 4: Remove unused TabAction.Share and TabItemMenu (#6651) In #2205, the tab overflow button was removed which would have shown the TabItemMenu when clicked. So, we can remove TabItemMenu since it is not used and as a result, we can also remove TabAction.Share since there are no consumers. * For #5574 - Part 5: Port TabAction.PlayMedia and TabAction.PauseMedia to TabSessionInteractor and SessionControlController (#6651) * For #5574 - Part 6: Port TabAction.Select to TabSessionInteractor and SessionControlController (#6651) * For #5574 - Part 7: Port Onboarding.Finish to OnboardingInteractor and SessionControlController (#6651) * For #5574 - Part 8: Port TabAction.Close and TabAction.CloseAll to TabSessionInteractor and SessionControlController (#6651) - Removes TabAction * For #5574 - Part 9: Port CollectionAction.Delete to CollectionInteractor and SessionControlController (#6651) * For #5574 - Part 10: Port CollectionAction.ShareTabs to CollectionInteractor and SessionControlController (#6651) * For #5574 - Part 11: Port CollectionAction.AddTab and CollectionAction.Rename to CollectionInteractor and SessionControlController (#6651) * For #5574 - Part 12: Port CollectionAction.RemoveTab to CollectionInteractor and SessionControlController (#6651) * For #5574 - Part 13: Port CollectionAction.OpenTab to CollectionInteractor and SessionControlController (#6651) * For #5574 - Part 14: Port CollectionAction.CloseTabs to CollectionInteractor and SessionControlController (#6651) * For #5574 - Part 15: Introduce a HomeFragmentStore (#6651) - We will hook up the HomeFragmentStore in later parts. - Removes List<Tab>.toSessionBundle(context: Context) since it is unused. * For #5574 - Part 16: Port CollectionAction.Collapse and CollectionAction.Expand to CollectionInteractor and SessionControlController (#6651) - We assume the store is hooked up to the SessionControlController in this part, but this work will be done in a later part. - Removes CollectionAction. * For #5574 - Part 20: Remove the architecture module. (#6651) * For #5574 - Part 17: Remove duplicate subscribeToTabCollections in BrowserFragment.kt (#6651) There is a duplicate call of subscribeToTabCollections() in both HomeFragment and BrowserFragment. In this patch, we remove the call in BrowserFragment to avoid passing the HomeFragmentStore to BrowserFragment in order to dispatch the CollectionsChange event. * For #5574 - Part 18: Delete SessionControlComponent and fix TabCollection and Tab imports (#6651) * For #5574 - Part 19: Use the new HomeFragmentStore in the HomeFragment (#6651) - Renames SessionControlUIView to SessionControlView * For #5574 - Part 21: Fix white screen on home fragment (#6651) * For #5574 - Part 22: Fix formatting in SessionControlInteractor and replace See with @see in SessionControlController (#6651) * For #5574 - Part 23: Move to metrics.track call to the beginning of handleCollectionRemoveTab (#6651) This ensures that the metrics.track will be called immediately before the tab is removed from the collection. * For #5574 - Part 24: Use the sessionManager getter in SessionControlController (#6651) * For #5574 - Part 25: Use mapNotNull in List<Tab>.toSessionBundle (#6651) * For #5574 - Part 26: Simplify closeTab and closeAllTabs functions by assigning a deletionJob constant (#6651) * For #5574 - Part 27: Replace listOf() with emptyList() in removeAllTabsWithUndo (#6651) * For #5574 - Part 28: Replace the Context parameter with the HomeActivity in SessionControlController (#6651) * For #5574 - Part 29: Add test for HomeFragmentStore, DefaultSessionControlController and SessionControlInteractor (#6651) * For #5574 - Removes running CI against the architecture debug build varient
2019-12-05 04:06:05 +01:00
import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.tabs.WindowFeature
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents
2019-09-10 22:29:21 +02:00
import org.mozilla.fenix.ext.settings
2019-11-21 23:23:35 +01:00
import org.mozilla.fenix.trackingprotection.TrackingProtectionOverlay
/**
2019-08-12 18:31:59 +02:00
* Fragment used for browsing the web within the main app.
*/
@ExperimentalCoroutinesApi
@Suppress("TooManyFunctions", "LargeClass")
class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
private val windowFeature = ViewBoundFeatureWrapper<WindowFeature>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
2019-07-23 23:15:46 +02:00
postponeEnterTransition()
sharedElementEnterTransition =
2019-08-08 00:41:52 +02:00
TransitionInflater.from(context).inflateTransition(android.R.transition.move)
.setDuration(
SHARED_TRANSITION_MS
)
}
2019-08-08 00:41:52 +02:00
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val view = super.onCreateView(inflater, container, savedInstanceState)
view.browserLayout.transitionName = "$TAB_ITEM_TRANSITION_NAME${getSessionById()?.id}"
return view
}
override fun initializeUI(view: View): Session? {
val context = requireContext()
val sessionManager = context.components.core.sessionManager
return super.initializeUI(view)?.also {
readerViewFeature.set(
feature = ReaderViewFeature(
context,
context.components.core.engine,
sessionManager,
view.readerViewControlsBar
) { available ->
if (available) {
context.components.analytics.metrics.track(Event.ReaderModeAvailable)
}
},
owner = this,
view = view
)
windowFeature.set(
feature = WindowFeature(
store = context.components.core.store,
tabsUseCases = context.components.useCases.tabsUseCases
),
owner = this,
view = view
)
4281 remove qab (#6310) * For #4281: small ToolbarMenu refactor This makes it easier to see how items are ordered in the menuItems list * For 4281: add QAB buttons to menu * For 4281: removed menu back button per mocks I double checked with UX, and we'll be relying on the hardware back button for its functionality * For 4281: add content descriptions for bookmarking * For 4281: updated BrowserToolbarController for new functionality * For 4281: provided simple dependencies to browser controller More complex changes will be in a following commit, for review readability * For 4281: move toolbar controller dependencies up to BaseBrowserFragment The functionality they control is being moved into the toolbar menu, which is shared by both normal tabs and custom ones * For 4281: removed (now unused) code related to QAB * For 4281: fix test compilation after QAB removal Tests still need to be expanded to include added functionality * For 4281: updated menu to show if url is bookmarked This sloppy workaround is required because TwoStateButton requires that `isInPrimaryState` be a synchronous call, and checking whether or not the current site is bookmarked is quite slow (10-50 MS, in my tests). After days of work and many attempted solutions, this was the least abhorrent among them. https://github.com/mozilla-mobile/android-components/issues/4915 was opened against AC to evaluate potentially supporting async `isInPrimaryState` functions. https://github.com/mozilla-mobile/fenix/issues/6370 was opened against Fenix to investigate the unexpectedly slow call to `BookmarkStorage`. * For 4281: update reader mode switch * For 4281: selectively show/hide menu items * For 4281: add reader mode appearance * For 4281: update bookmark button when it is clicked * For 4281: removed unused QAB code * For 4281: removed QAB robot, updated UI tests * For 4281: removed QuickActionSheet metrics Since this behavior now lives in the toolbar, it is tracked via Event.BrowserMenuItemTapped * For 4281: fixed lint errors * For 4281: add new strings for buttons added to menu This is necessary because the location change (from QAB to toolbar menu) could affect the grammar in some languages * For 4281: remove outdated TODOs * For 4281: removed QAB container * For 4281: removed back button reference from UI test This button no longer exists * For 4821: Fixes a visual defect (extra padding on top of toolbar) * For 4281: update copy on reader mode * For 4281: fixed review nits
2019-11-12 02:10:14 +01:00
consumeFrom(browserFragmentStore) {
browserToolbarView.update(it)
}
}
}
override fun onStart() {
super.onStart()
val toolbarSessionObserver = TrackingProtectionOverlay(
context = requireContext(),
settings = requireContext().settings()
) {
browserToolbarView.view
}
getSessionById()?.register(toolbarSessionObserver, this, autoPause = true)
updateEngineBottomMargin()
}
private fun updateEngineBottomMargin() {
val browserEngine = swipeRefresh.layoutParams as CoordinatorLayout.LayoutParams
browserEngine.bottomMargin = if (requireContext().settings().shouldUseBottomToolbar) {
2019-12-18 18:04:02 +01:00
requireContext().resources.getDimensionPixelSize(R.dimen.browser_toolbar_height)
} else {
0
}
2019-09-10 22:29:21 +02:00
2019-11-21 23:23:35 +01:00
val toolbarSessionObserver = TrackingProtectionOverlay(
context = requireContext(),
2019-11-23 07:27:33 +01:00
settings = requireContext().settings()
) {
browserToolbarView.view
}
2019-11-21 23:23:35 +01:00
getSessionById()?.register(toolbarSessionObserver, this, autoPause = true)
}
override fun onResume() {
super.onResume()
getSessionById()?.let {
/**
* The session mode may be changed if the user is originally in Normal Mode and then
* opens a 3rd party link in Private Browsing Mode. Hence, we update the theme here.
* This fixes issue #5254.
*/
(activity as HomeActivity).updateThemeForSession(it)
}
requireComponents.core.tabCollectionStorage.register(collectionStorageObserver, this)
}
override fun onBackPressed(): Boolean {
return readerViewFeature.onBackPressed() || super.onBackPressed()
}
2019-08-12 18:31:59 +02:00
override fun navToQuickSettingsSheet(session: Session, sitePermissions: SitePermissions?) {
2019-09-10 22:29:21 +02:00
val directions =
BrowserFragmentDirections.actionBrowserFragmentToQuickSettingsSheetDialogFragment(
sessionId = session.id,
url = session.url,
title = session.title,
2019-09-10 22:29:21 +02:00
isSecured = session.securityInfo.secure,
sitePermissions = sitePermissions,
2020-01-31 13:27:48 +01:00
gravity = getAppropriateLayoutGravity(),
certificateName = session.securityInfo.issuer
2019-09-10 22:29:21 +02:00
)
nav(R.id.browserFragment, directions)
}
override fun navToTrackingProtectionPanel(session: Session) {
2019-10-02 06:45:04 +02:00
val useCase = TrackingProtectionUseCases(
sessionManager = requireComponents.core.sessionManager,
engine = requireComponents.core.engine
)
useCase.containsException(session) { contains ->
val isEnabled = session.trackerBlockingEnabled && !contains
val directions =
BrowserFragmentDirections.actionBrowserFragmentToTrackingProtectionPanelDialogFragment(
sessionId = session.id,
url = session.url,
trackingProtectionEnabled = isEnabled,
gravity = getAppropriateLayoutGravity()
)
nav(R.id.browserFragment, directions)
}
2019-08-12 18:31:59 +02:00
}
private val collectionStorageObserver = object : TabCollectionStorage.Observer {
override fun onCollectionCreated(title: String, sessions: List<Session>) {
showTabSavedToCollectionSnackbar()
}
2019-07-23 23:15:46 +02:00
override fun onTabsAdded(tabCollection: TabCollection, sessions: List<Session>) {
showTabSavedToCollectionSnackbar()
}
private fun showTabSavedToCollectionSnackbar() {
view?.let { view ->
FenixSnackbar.makeWithToolbarPadding(view, Snackbar.LENGTH_SHORT)
.setText(view.context.getString(R.string.create_collection_tab_saved))
.show()
}
}
}
override fun getContextMenuCandidates(
context: Context,
view: View
): List<ContextMenuCandidate> = ContextMenuCandidate.defaultCandidates(
context,
context.components.useCases.tabsUseCases,
context.components.useCases.contextMenuUseCases,
view,
FenixSnackbarDelegate(view)
)
companion object {
private const val SHARED_TRANSITION_MS = 200L
private const val TAB_ITEM_TRANSITION_NAME = "tab_item"
const val REPORT_SITE_ISSUE_URL =
"https://webcompat.com/issues/new?url=%s&label=browser-fenix"
}
}