diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt index 130ed9ab9..cfc6c8360 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.tabstray import android.content.Context +import android.content.res.Configuration import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -27,6 +28,8 @@ import kotlinx.android.synthetic.main.tabstray_multiselect_items.* import kotlinx.android.synthetic.main.tabstray_multiselect_items.view.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.plus +import mozilla.components.browser.state.selector.normalTabs +import mozilla.components.browser.state.selector.privateTabs import mozilla.components.concept.tabstray.Tab import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import org.mozilla.fenix.HomeActivity @@ -34,8 +37,10 @@ import org.mozilla.fenix.NavGraphDirections import org.mozilla.fenix.R import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.metrics.Event +import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph import org.mozilla.fenix.ext.requireComponents +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.home.HomeScreenViewModel import org.mozilla.fenix.tabstray.browser.BrowserTrayInteractor import org.mozilla.fenix.tabstray.browser.DefaultBrowserTrayInteractor @@ -44,6 +49,7 @@ import org.mozilla.fenix.tabstray.browser.SelectionBannerBinding import org.mozilla.fenix.tabstray.browser.SelectionBannerBinding.VisibilityModifier import org.mozilla.fenix.tabstray.ext.showWithTheme import org.mozilla.fenix.tabstray.syncedtabs.SyncedTabsInteractor +import kotlin.math.max @Suppress("TooManyFunctions", "LargeClass") class TabsTrayFragment : AppCompatDialogFragment(), TabsTrayInteractor { @@ -150,11 +156,18 @@ class TabsTrayFragment : AppCompatDialogFragment(), TabsTrayInteractor { dismissAllowingStateLoss() } - behavior.addBottomSheetCallback( - TraySheetBehaviorCallback( - behavior, - navigationInteractor - ) + behavior.setUpTrayBehavior( + isLandscape = requireContext().resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE, + maxNumberOfTabs = max( + requireContext().components.core.store.state.normalTabs.size, + requireContext().components.core.store.state.privateTabs.size + ), + numberForExpandingTray = if (requireContext().settings().gridTabView) { + EXPAND_AT_GRID_SIZE + } else { + EXPAND_AT_LIST_SIZE + }, + navigationInteractor = navigationInteractor ) tabsTrayCtaBinding.set( @@ -335,4 +348,12 @@ class TabsTrayFragment : AppCompatDialogFragment(), TabsTrayInteractor { dismissAllowingStateLoss() requireComponents.analytics.metrics.track(Event.TabsTrayClosed) } + + companion object { + // Minimum number of list items for which to show the tabs tray as expanded. + const val EXPAND_AT_LIST_SIZE = 4 + + // Minimum number of grid items for which to show the tabs tray as expanded. + private const val EXPAND_AT_GRID_SIZE = 3 + } } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/TraySheetBehaviorCallback.kt b/app/src/main/java/org/mozilla/fenix/tabstray/TraySheetBehaviorCallback.kt index 413e84976..5c92df303 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/TraySheetBehaviorCallback.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/TraySheetBehaviorCallback.kt @@ -26,3 +26,19 @@ class TraySheetBehaviorCallback( override fun onSlide(bottomSheet: View, slideOffset: Float) = Unit } + +fun BottomSheetBehavior.setUpTrayBehavior( + isLandscape: Boolean, + maxNumberOfTabs: Int, + numberForExpandingTray: Int, + navigationInteractor: DefaultNavigationInteractor +) { + addBottomSheetCallback( + TraySheetBehaviorCallback(this, navigationInteractor) + ) + state = if (isLandscape || maxNumberOfTabs >= numberForExpandingTray) { + BottomSheetBehavior.STATE_EXPANDED + } else { + BottomSheetBehavior.STATE_COLLAPSED + } +} diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/TraySheetBehaviorCallbackTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/TraySheetBehaviorCallbackTest.kt index 6d62dbf98..d388290a2 100644 --- a/app/src/test/java/org/mozilla/fenix/tabstray/TraySheetBehaviorCallbackTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabstray/TraySheetBehaviorCallbackTest.kt @@ -14,6 +14,7 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_SETTLIN import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED import io.mockk.Called import io.mockk.mockk +import io.mockk.spyk import io.mockk.verify import org.junit.Test @@ -53,4 +54,40 @@ class TraySheetBehaviorCallbackTest { verify { behavior wasNot Called } verify { interactor wasNot Called } } + + @Test + fun `GIVEN portraitMode and 5 tabs WHEN setUpTrayBehavior THEN add TraySheetBehaviorCallback and STATE_COLLAPSED`() { + // given + val behavior = spyk(BottomSheetBehavior()) + val interactor = mockk(relaxed = true) + + // when + behavior.setUpTrayBehavior( + isLandscape = false, + maxNumberOfTabs = 5, + numberForExpandingTray = TabsTrayFragment.EXPAND_AT_LIST_SIZE, + navigationInteractor = interactor + ) + + // then + assert(behavior.state == STATE_EXPANDED) + } + + @Test + fun `GIVEN portraitMode and 2 tabs WHEN setUpTrayBehavior THEN add TraySheetBehaviorCallback and STATE_COLLAPSED`() { + // given + val behavior = spyk(BottomSheetBehavior()) + val interactor = mockk(relaxed = true) + + // when + behavior.setUpTrayBehavior( + isLandscape = false, + maxNumberOfTabs = 2, + numberForExpandingTray = TabsTrayFragment.EXPAND_AT_LIST_SIZE, + navigationInteractor = interactor + ) + + // then + assert(behavior.state == STATE_COLLAPSED) + } }