diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt index 849ac9e64..dd72cf8b4 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt @@ -161,14 +161,13 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler if (newConfig.orientation != currentOrientation) { tabTrayView.dismissMenu() - tabTrayView.expand() + tabTrayView.updateBottomSheetBehavior() if (requireContext().settings().gridTabView) { // Update the number of columns to use in the grid view when the screen // orientation changes. tabTrayView.updateTabsTrayLayout() } - currentOrientation = newConfig.orientation } } @@ -205,8 +204,7 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler ), store = tabTrayDialogStore, isPrivate = isPrivate, - startingInLandscape = requireContext().resources.configuration.orientation == - Configuration.ORIENTATION_LANDSCAPE, + isInLandscape = ::isInLandscape, lifecycleOwner = viewLifecycleOwner ) { private -> val filter: (TabSessionState) -> Boolean = { state -> private == state.content.private } @@ -450,6 +448,10 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler } } + private fun isInLandscape(): Boolean { + return requireContext().resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + } + companion object { private const val ELEVATION = 80f } diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt index 25eaad1cf..87894865a 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt @@ -40,6 +40,7 @@ import mozilla.components.browser.state.selector.getNormalOrPrivateTabs import mozilla.components.browser.state.selector.normalTabs import mozilla.components.browser.state.selector.privateTabs import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.tabstray.TabViewHolder import mozilla.components.feature.syncedtabs.SyncedTabsFeature import mozilla.components.support.base.feature.ViewBoundFeatureWrapper @@ -54,6 +55,7 @@ import org.mozilla.fenix.ext.settings import org.mozilla.fenix.tabtray.SaveToCollectionsButtonAdapter.MultiselectModeChange import org.mozilla.fenix.tabtray.TabTrayDialogFragmentState.Mode import java.text.NumberFormat +import kotlin.math.max import mozilla.components.browser.storage.sync.Tab as SyncTab /** @@ -66,7 +68,7 @@ class TabTrayView( private val interactor: TabTrayInteractor, store: TabTrayDialogFragmentStore, isPrivate: Boolean, - startingInLandscape: Boolean, + private val isInLandscape: () -> Boolean, lifecycleOwner: LifecycleOwner, private val filterTabs: (Boolean) -> Unit ) : LayoutContainer, TabLayout.OnTabSelectedListener { @@ -145,20 +147,14 @@ class TabTrayView( view.tab_layout.addOnTabSelectedListener(this) - val tabs = if (isPrivate) { - view.context.components.core.store.state.privateTabs - } else { - view.context.components.core.store.state.normalTabs - } + val tabs = getTabs(isPrivate) val selectedBrowserTabIndex = tabs .indexOfFirst { it.id == view.context.components.core.store.state.selectedTabId } - if (tabs.size > EXPAND_AT_SIZE || startingInLandscape) { - expand() - } + updateBottomSheetBehavior() - setTopOffset(startingInLandscape) + setTopOffset(isInLandscape()) if (view.context.settings().syncedTabsInTabsTray) { syncedTabsFeature.set( @@ -280,6 +276,27 @@ class TabTrayView( } } + private fun getTabs(isPrivate: Boolean): List = if (isPrivate) { + view.context.components.core.store.state.privateTabs + } else { + view.context.components.core.store.state.normalTabs + } + + private fun getTabsNumberInAnyMode(): Int { + return max( + view.context.components.core.store.state.normalTabs.size, + view.context.components.core.store.state.privateTabs.size + ) + } + + private fun getTabsNumberForExpandingTray(): Int { + return if (container.context.settings().gridTabView) { + EXPAND_AT_GRID_SIZE + } else { + EXPAND_AT_LIST_SIZE + } + } + private fun handleTabClicked(tab: SyncTab) { interactor.onSyncedTabClicked(tab) } @@ -312,8 +329,17 @@ class TabTrayView( components.analytics.metrics.track(eventToSend) } - fun expand() { - behavior.state = BottomSheetBehavior.STATE_EXPANDED + /** + * Updates the bottom sheet height based on the number tabs or screen orientation. + * Show the bottom sheet fully expanded if it is in landscape mode or the number of + * tabs are greater or equal to the expand size limit. + */ + fun updateBottomSheetBehavior() { + if (isInLandscape() || getTabsNumberInAnyMode() >= getTabsNumberForExpandingTray()) { + behavior.state = BottomSheetBehavior.STATE_EXPANDED + } else { + behavior.state = BottomSheetBehavior.STATE_COLLAPSED + } } enum class TabChange { @@ -668,7 +694,10 @@ class TabTrayView( private const val TAB_COUNT_SHOW_CFR = 6 private const val DEFAULT_TAB_ID = 0 private const val PRIVATE_TAB_ID = 1 - private const val EXPAND_AT_SIZE = 3 + // Minimum number of list items for which to show the tabs tray as expanded. + private 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 private const val SLIDE_OFFSET = 0 private const val SELECTION_DELAY = 500 private const val NORMAL_HANDLE_PERCENT_WIDTH = 0.1F