Start ripping out the custom tab tray that I lack the resources to maintain

pull/257/head
Adam Novak 3 years ago
parent 39bb01f3c9
commit 7b9eaa9304

@ -1,50 +0,0 @@
/* 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.home.sessioncontrol.viewholders.onboarding
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.onboarding_tabs_tray_layout.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.onboarding.OnboardingRadioButton
import org.mozilla.fenix.utils.view.addToRadioGroup
class OnboardingTabsTrayLayoutViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private var fennecStyleTabsScreen: OnboardingRadioButton = view.tabs_tray_fennec_style
private var fenixStyleTabsTray: OnboardingRadioButton = view.tabs_tray_fenix_style
init {
addToRadioGroup(fennecStyleTabsScreen, fenixStyleTabsTray)
fennecStyleTabsScreen.isChecked =
itemView.context.settings().shouldUseFennecStyleTabsScreen
fenixStyleTabsTray.isChecked =
!itemView.context.settings().shouldUseFennecStyleTabsScreen
fennecStyleTabsScreen.onClickListener {
setFennecStyleTabsScreen(true)
}
fenixStyleTabsTray.onClickListener {
setFennecStyleTabsScreen(false)
}
}
private fun setFennecStyleTabsScreen(enabled: Boolean) {
itemView.context.settings().apply {
enableCompactTabs = enabled
useFullScreenTabScreen = enabled
reverseTabOrderInTabsTray = !enabled
useNewTabFloatingActionButton = !enabled
placeNewTabFloatingActionButtonAtTop = false
}
}
companion object {
const val LAYOUT_ID = R.layout.onboarding_tabs_tray_layout
}
}

@ -17,6 +17,8 @@ import org.mozilla.fenix.utils.view.addToRadioGroup
* Lets the user customize auto closing tabs.
*/
class TabsSettingsFragment : PreferenceFragmentCompat() {
private lateinit var listRadioButton: RadioButtonPreference
private lateinit var gridRadioButton: RadioButtonPreference
private lateinit var radioManual: RadioButtonPreference
private lateinit var radioOneDay: RadioButtonPreference
private lateinit var radioOneWeek: RadioButtonPreference
@ -38,6 +40,9 @@ class TabsSettingsFragment : PreferenceFragmentCompat() {
}
private fun setupPreferences() {
listRadioButton = requirePreference(R.string.pref_key_tab_view_list)
gridRadioButton = requirePreference(R.string.pref_key_tab_view_grid)
radioManual = requirePreference(R.string.pref_key_close_tabs_manually)
radioOneDay = requirePreference(R.string.pref_key_close_tabs_after_one_day)
radioOneWeek = requirePreference(R.string.pref_key_close_tabs_after_one_week)
@ -47,6 +52,11 @@ class TabsSettingsFragment : PreferenceFragmentCompat() {
}
private fun setupRadioGroups() {
addToRadioGroup(
listRadioButton,
gridRadioButton
)
addToRadioGroup(
radioManual,
radioOneDay,

@ -31,7 +31,7 @@ class FenixTabsAdapter(
viewHolderProvider = { parentView ->
TabTrayViewHolder(
LayoutInflater.from(context).inflate(
if (context.settings().enableCompactTabs) R.layout.tab_tray_item_compact else R.layout.tab_tray_item,
if (context.settings().gridTabView) R.layout.tab_tray_grid_item else R.layout.tab_tray_item,
parentView,
false
),

@ -21,7 +21,6 @@ import mozilla.components.browser.storage.sync.SyncedDeviceTabs
import mozilla.components.feature.syncedtabs.view.SyncedTabsView
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.sync.ListenerDelegate
import org.mozilla.fenix.sync.SyncedTabsAdapter
import org.mozilla.fenix.sync.ext.toAdapterList
@ -64,11 +63,8 @@ class SyncedTabsController(
override fun displaySyncedTabs(syncedTabs: List<SyncedDeviceTabs>) {
scope.launch {
val tabsList = listOf(SyncedTabsAdapter.AdapterItem.Title) + syncedTabs.toAdapterList()
if (view.context.settings().reverseTabOrderInTabsTray) {
adapter.submitList(tabsList.reversed())
} else {
adapter.submitList(tabsList)
}
// Reverse layout for TabTrayView which does things backwards.
adapter.submitList(tabsList.reversed())
}
}

@ -22,8 +22,8 @@ import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.*
import kotlinx.android.synthetic.main.component_tabstray_fab_bottom.view.*
import kotlinx.android.synthetic.main.component_tabstray.view.*
import kotlinx.android.synthetic.main.component_tabstray_fab.view.*
import kotlinx.android.synthetic.main.fragment_tab_tray_dialog.*
import kotlinx.android.synthetic.main.fragment_tab_tray_dialog.view.*
import kotlinx.coroutines.Dispatchers
@ -168,8 +168,6 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler
if (newConfig.orientation != currentOrientation) {
tabTrayView.dismissMenu()
tabTrayView.expand()
tabTrayView.updateTabsTrayLayout()
tabTrayView.updateBottomSheetBehavior()
if (requireContext().settings().gridTabView) {
@ -188,10 +186,6 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler
val activity = activity as HomeActivity
val isPrivate = activity.browsingModeManager.mode.isPrivate
if (requireContext().settings().useTopTabsTray) {
dialog?.window?.attributes?.windowAnimations = R.style.TopTabTrayAnimation
}
val thumbnailLoader = ThumbnailLoader(requireContext().components.core.thumbnailStorage)
val adapter = FenixTabsAdapter(requireContext(), thumbnailLoader)
currentOrientation = resources.configuration.orientation

@ -25,19 +25,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.tabs.TabLayout
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.component_tabs_screen_top.view.exit_tabs_screen
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.exit_multi_select
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.handle
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.infoBanner
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.multiselect_title
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.tab_layout
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.tab_tray_empty_view
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.tab_tray_new_tab
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.tab_tray_overflow
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.tab_wrapper
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.tabsTray
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.topBar
import kotlinx.android.synthetic.main.component_tabstray_fab_bottom.view.new_tab_button
import kotlinx.android.synthetic.main.component_tabstray.view.*
import kotlinx.android.synthetic.main.component_tabstray_fab.view.*
import kotlinx.android.synthetic.main.tabs_tray_tab_counter.*
import kotlinx.android.synthetic.main.tabstray_multiselect_items.view.*
import kotlinx.coroutines.Dispatchers.Main
@ -59,7 +48,6 @@ import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.toolbar.TabCounter.Companion.INFINITE_CHAR_PADDING_BOTTOM
import org.mozilla.fenix.components.toolbar.TabCounter.Companion.MAX_VISIBLE_TABS
import org.mozilla.fenix.components.toolbar.TabCounter.Companion.SO_MANY_TABS_OPEN
import org.mozilla.fenix.components.topsheet.TopSheetBehavior
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.updateAccessibilityCollectionInfo
@ -67,7 +55,6 @@ import org.mozilla.fenix.tabtray.SaveToCollectionsButtonAdapter.MultiselectModeC
import org.mozilla.fenix.tabtray.TabTrayDialogFragmentState.Mode
import java.text.NumberFormat
import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt
import mozilla.components.browser.storage.sync.Tab as SyncTab
@ -86,43 +73,17 @@ class TabTrayView(
private val filterTabs: (Boolean) -> Unit
) : LayoutContainer, TabLayout.OnTabSelectedListener {
val lifecycleScope = lifecycleOwner.lifecycleScope
val fabView = LayoutInflater.from(container.context)
.inflate(R.layout.component_tabstray_fab, container, true)
private val useFab = container.context.settings().useNewTabFloatingActionButton
val fabView: View = when (container.context.settings().placeNewTabFloatingActionButtonAtTop) {
true -> LayoutInflater.from(container.context).inflate(R.layout.component_tabstray_fab_top, container, true)
false -> LayoutInflater.from(container.context).inflate(R.layout.component_tabstray_fab_bottom, container, true)
}
private val enableCompactTabs = container.context.settings().enableCompactTabs
private val reverseTabOrderInTabsTray = container.context.settings().reverseTabOrderInTabsTray
private val isTabsTrayFullScreenMode = container.context.settings().useFullScreenTabScreen
private val hasAccessibilityEnabled = container.context.settings().accessibilityServicesEnabled
private val useTopTabsTray = container.context.settings().useTopTabsTray
val view: View = if (isTabsTrayFullScreenMode) {
when (useTopTabsTray) {
true -> LayoutInflater.from(container.context)
.inflate(R.layout.component_tabs_screen_bottom, container, true)
false -> LayoutInflater.from(container.context)
.inflate(R.layout.component_tabs_screen_top, container, true)
}
} else {
when (useTopTabsTray) {
true -> LayoutInflater.from(container.context)
.inflate(R.layout.component_tabstray_top, container, true)
false -> LayoutInflater.from(container.context)
.inflate(R.layout.component_tabstray_bottom, container, true)
}
}
val view = LayoutInflater.from(container.context)
.inflate(R.layout.component_tabstray, container, true)
private val isPrivateModeSelected: Boolean get() = view.tab_layout.selectedTabPosition == PRIVATE_TAB_ID
private val behavior = if (isTabsTrayFullScreenMode) null else {
when (useTopTabsTray) {
true -> TopSheetBehavior.from(view.tab_wrapper)
false -> BottomSheetBehavior.from(view.tab_wrapper)
}
}
private val behavior = BottomSheetBehavior.from(view.tab_wrapper)
private val concatAdapter = ConcatAdapter(tabsAdapter)
private val tabTrayItemMenu: TabTrayItemMenu
@ -157,64 +118,32 @@ class TabTrayView(
components.analytics.metrics.track(Event.TabsTrayOpened)
toggleFabText(isPrivate)
view.topBar.setOnClickListener {
// no-op, consume the touch event to prevent it advancing the tray to the next state.
}
if (!isTabsTrayFullScreenMode) {
if (useTopTabsTray) {
(behavior as TopSheetBehavior).setTopSheetCallback(object :
TopSheetBehavior.TopSheetCallback {
override fun onSlide(topSheet: View, slideOffset: Float, isOpening: Boolean?) {
if (interactor.onModeRequested() is Mode.Normal && useFab) {
if (slideOffset >= SLIDE_OFFSET) {
fabView.new_tab_button.show()
} else {
fabView.new_tab_button.hide()
}
}
}
override fun onStateChanged(topSheet: View, newState: Int) {
if (newState == TopSheetBehavior.STATE_HIDDEN) {
components.analytics.metrics.track(Event.TabsTrayClosed)
interactor.onTabTrayDismissed()
}
}
})
} else {
(behavior as BottomSheetBehavior).addBottomSheetCallback(object :
BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
if (interactor.onModeRequested() is Mode.Normal && useFab) {
if (slideOffset >= SLIDE_OFFSET) {
fabView.new_tab_button.show()
} else {
fabView.new_tab_button.hide()
}
}
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
components.analytics.metrics.track(Event.TabsTrayClosed)
interactor.onTabTrayDismissed()
}
// We only support expanded and collapsed states. Don't allow STATE_HALF_EXPANDED.
else if (newState == BottomSheetBehavior.STATE_HALF_EXPANDED) {
behavior.state = BottomSheetBehavior.STATE_HIDDEN
}
behavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
if (interactor.onModeRequested() is Mode.Normal && !hasAccessibilityEnabled) {
if (slideOffset >= SLIDE_OFFSET) {
fabView.new_tab_button.show()
} else {
fabView.new_tab_button.hide()
}
})
}
}
}
if (isTabsTrayFullScreenMode) {
view.exit_tabs_screen.setOnClickListener {
interactor.onTabTrayDismissed()
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
components.analytics.metrics.track(Event.TabsTrayClosed)
interactor.onTabTrayDismissed()
}
// We only support expanded and collapsed states. Don't allow STATE_HALF_EXPANDED.
else if (newState == BottomSheetBehavior.STATE_HALF_EXPANDED) {
behavior.state = BottomSheetBehavior.STATE_HIDDEN
}
}
}
})
val selectedTabIndex = if (!isPrivate) {
DEFAULT_TAB_ID
@ -263,26 +192,16 @@ class TabTrayView(
tabsAdapter.tabTrayInteractor = interactor
tabsAdapter.onTabsUpdated = {
// Put the 'Add to collections' button after the tabs have loaded.
// And, put the Synced Tabs adapter at the end.
if (reverseTabOrderInTabsTray) {
// Put these at the start when reverse tab order is enabled. Also, we disallow
// reverse tab order for compact tabs in settings.
concatAdapter.addAdapter(0, collectionsButtonAdapter)
concatAdapter.addAdapter(0, syncedTabsController.adapter)
} else {
concatAdapter.addAdapter(collectionsButtonAdapter)
concatAdapter.addAdapter(syncedTabsController.adapter)
}
concatAdapter.addAdapter(collectionsButtonAdapter)
concatAdapter.addAdapter(syncedTabsController.adapter)
if (hasAccessibilityEnabled) {
tabsAdapter.notifyItemRangeChanged(0, tabs.size)
}
if (!hasLoaded) {
hasLoaded = true
scrollToSelectedBrowserTab()
if (hasAccessibilityEnabled) {
if (view.context.settings().accessibilityServicesEnabled) {
lifecycleScope.launch {
delay(SELECTION_DELAY.toLong())
lifecycleScope.launch(Main) {
@ -374,13 +293,13 @@ class TabTrayView(
tabs.size >= TAB_COUNT_SHOW_CFR
) {
InfoBanner(
context = view.context,
message = view.context.getString(R.string.tab_tray_close_tabs_banner_message),
dismissText = view.context.getString(R.string.tab_tray_close_tabs_banner_negative_button_text),
actionText = view.context.getString(R.string.tab_tray_close_tabs_banner_positive_button_text),
container = view.infoBanner,
dismissByHiding = true,
dismissAction = { view.context.settings().shouldShowAutoCloseTabsBanner = false }
context = view.context,
message = view.context.getString(R.string.tab_tray_close_tabs_banner_message),
dismissText = view.context.getString(R.string.tab_tray_close_tabs_banner_negative_button_text),
actionText = view.context.getString(R.string.tab_tray_close_tabs_banner_positive_button_text),
container = view.infoBanner,
dismissByHiding = true,
dismissAction = { view.context.settings().shouldShowAutoCloseTabsBanner = false }
) {
interactor.onGoToTabsSettings()
view.context.settings().shouldShowAutoCloseTabsBanner = false
@ -418,7 +337,7 @@ class TabTrayView(
private fun adjustNewTabButtonsForNormalMode() {
view.tab_tray_new_tab.apply {
isVisible = !useFab
isVisible = hasAccessibilityEnabled
setOnClickListener {
sendNewTabEvent(isPrivateModeSelected)
interactor.onNewTabTapped(isPrivateModeSelected)
@ -426,7 +345,7 @@ class TabTrayView(
}
fabView.new_tab_button.apply {
isVisible = useFab
isVisible = !hasAccessibilityEnabled
setOnClickListener {
sendNewTabEvent(isPrivateModeSelected)
interactor.onNewTabTapped(isPrivateModeSelected)
@ -444,67 +363,6 @@ class TabTrayView(
components.analytics.metrics.track(eventToSend)
}
fun updateTabsTrayLayout() {
if (enableCompactTabs) {
setupCompactTabsTrayLayout()
} else {
setupRegularTabsTrayLayout()
}
// We will need to learn call setupGridTabView(), Mozilla's new
// official grid layout, by preference.
}
private fun setupCompactTabsTrayLayout() {
view.tabsTray.apply {
val gridLayoutManager = GridLayoutManager(container.context, getNumberOfGridColumns(container.context))
if (useTopTabsTray) {
gridLayoutManager.reverseLayout = true
}
gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
val numTabs = tabsAdapter.itemCount
return if (position < numTabs) {
1
} else {
getNumberOfGridColumns(container.context)
}
}
}
layoutManager = gridLayoutManager
}
}
private fun setupRegularTabsTrayLayout() {
view.tabsTray.apply {
val linearLayoutManager = LinearLayoutManager(container.context)
if (useTopTabsTray) {
if (!reverseTabOrderInTabsTray) {
linearLayoutManager.reverseLayout = true
} else {
linearLayoutManager.stackFromEnd = true
}
} else {
if (reverseTabOrderInTabsTray) {
linearLayoutManager.reverseLayout = true
linearLayoutManager.stackFromEnd = true
}
}
layoutManager = linearLayoutManager
}
}
fun expand() {
if (!isTabsTrayFullScreenMode) {
if (useTopTabsTray) {
(behavior as TopSheetBehavior).state = TopSheetBehavior.STATE_EXPANDED
} else {
(behavior as BottomSheetBehavior).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
@ -512,17 +370,9 @@ class TabTrayView(
*/
fun updateBottomSheetBehavior() {
if (isInLandscape() || getTabsNumberInAnyMode() >= getTabsNumberForExpandingTray()) {
if (useTopTabsTray) {
(behavior as TopSheetBehavior).state = TopSheetBehavior.STATE_EXPANDED
} else {
(behavior as BottomSheetBehavior).state = BottomSheetBehavior.STATE_EXPANDED
}
behavior.state = BottomSheetBehavior.STATE_EXPANDED
} else {
if (useTopTabsTray) {
(behavior as TopSheetBehavior).state = TopSheetBehavior.STATE_COLLAPSED
} else {
(behavior as BottomSheetBehavior).state = BottomSheetBehavior.STATE_COLLAPSED
}
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
}
}
@ -557,7 +407,15 @@ class TabTrayView(
var mode: Mode = Mode.Normal
private set
fun updateTabsTrayLayout() {
if (container.context.settings().gridTabView) {
setupGridTabView()
} else {
setupListTabView()
}
}
private fun setupGridTabView() {
view.tabsTray.apply {
val gridLayoutManager =
@ -608,7 +466,7 @@ class TabTrayView(
if (oldMode::class != state.mode::class) {
updateTabsForMultiselectModeChanged(state.mode is Mode.MultiSelect)
if (hasAccessibilityEnabled) {
if (view.context.settings().accessibilityServicesEnabled) {
view.announceForAccessibility(
if (state.mode == Mode.Normal) view.context.getString(
R.string.tab_tray_exit_multiselect_content_description
@ -671,7 +529,7 @@ class TabTrayView(
val unselectedItems = oldMode.selectedItems - state.mode.selectedItems
state.mode.selectedItems.union(unselectedItems).forEach { item ->
if (hasAccessibilityEnabled) {
if (view.context.settings().accessibilityServicesEnabled) {
view.announceForAccessibility(
if (unselectedItems.contains(item)) view.context.getString(
R.string.tab_tray_item_unselected_multiselect_content_description,
@ -747,23 +605,13 @@ class TabTrayView(
R.dimen.bottom_sheet_handle_height
}
)
if (useTopTabsTray) {
bottomMargin = view.resources.getDimensionPixelSize(
if (multiselect) {
R.dimen.tab_tray_multiselect_handle_bottom_margin
} else {
R.dimen.top_sheet_handle_bottom_margin
}
)
} else {
topMargin = view.resources.getDimensionPixelSize(
if (multiselect) {
R.dimen.tab_tray_multiselect_handle_top_margin
} else {
R.dimen.bottom_sheet_handle_top_margin
}
)
}
topMargin = view.resources.getDimensionPixelSize(
if (multiselect) {
R.dimen.tab_tray_multiselect_handle_top_margin
} else {
R.dimen.bottom_sheet_handle_top_margin
}
)
}
view.tab_wrapper.setChildWPercent(
@ -778,12 +626,10 @@ class TabTrayView(
)
)
if (isTabsTrayFullScreenMode) {
view.exit_tabs_screen.isVisible = !multiselect
}
view.tab_layout.isVisible = !multiselect
view.tab_tray_empty_view.isVisible = !multiselect
view.tab_tray_overflow.isVisible = !multiselect
view.tab_layout.isVisible = !multiselect
}
private fun updateTabsForMultiselectModeChanged(inMultiselectMode: Boolean) {
@ -838,17 +684,13 @@ class TabTrayView(
}
fun setTopOffset(landscape: Boolean) {
if (!isTabsTrayFullScreenMode) {
val topOffset = if (landscape) {
0
} else {
view.context.resources.getDimensionPixelSize(R.dimen.tab_tray_top_offset)
}
if (!useTopTabsTray) {
(behavior as BottomSheetBehavior).setExpandedOffset(topOffset)
}
val topOffset = if (landscape) {
0
} else {
view.resources.getDimensionPixelSize(R.dimen.tab_tray_top_offset)
}
behavior.setExpandedOffset(topOffset)
}
fun dismissMenu() {
@ -873,19 +715,7 @@ class TabTrayView(
fun scrollToSelectedBrowserTab(selectedTabId: String? = null) {
view.tabsTray.apply {
val selectedBrowserTabIndex = getSelectedBrowserTabViewIndex(selectedTabId)
val recyclerViewIndex = if (reverseTabOrderInTabsTray) {
// For reverse tab order and non-compact tabs, we add the items in collections button
// adapter and synced tabs adapter, and offset by 1 to show the tab above the
// current tab, unless current tab is first in reverse order.
min(selectedBrowserTabIndex + 1, tabsAdapter.itemCount - 1) +
collectionsButtonAdapter.itemCount + syncedTabsController.adapter.itemCount
} else {
// We offset index by -1 to show the tab above the current tab, unless current tab
// is the first.
max(0, selectedBrowserTabIndex - 1)
}
val recyclerViewIndex = getSelectedBrowserTabViewIndex(selectedTabId)
layoutManager?.scrollToPosition(recyclerViewIndex)
smoothScrollBy(
@ -922,7 +752,7 @@ class TabTrayView(
private const val SLIDE_OFFSET = 0
private const val SELECTION_DELAY = 500
private const val NORMAL_HANDLE_PERCENT_WIDTH = 0.1F
private const val COLUMN_WIDTH_DP = 190
private const val COLUMN_WIDTH_DP = 180
// The remaining padding offset needed to provide a 16dp column spacing between the grid items.
const val GRID_ITEM_PARENT_PADDING = 8

@ -11,7 +11,6 @@ import android.widget.TextView
import androidx.annotation.VisibleForTesting
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.widget.AppCompatImageButton
import androidx.cardview.widget.CardView
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.tab_tray_grid_item.view.*
import mozilla.components.browser.state.state.MediaState
@ -51,8 +50,8 @@ class TabTrayViewHolder(
private val metrics: MetricController = itemView.context.components.analytics.metrics
) : TabViewHolder(itemView) {
private val iconCard: CardView = itemView.findViewById(R.id.mozac_browser_tabstray_icon_card)
private val iconView: ImageView = itemView.findViewById(R.id.mozac_browser_tabstray_icon)
private val faviconView: ImageView? =
itemView.findViewById(R.id.mozac_browser_tabstray_favicon_icon)
private val titleView: TextView = itemView.findViewById(R.id.mozac_browser_tabstray_title)
private val closeView: AppCompatImageButton =
itemView.findViewById(R.id.mozac_browser_tabstray_close)
@ -79,7 +78,7 @@ class TabTrayViewHolder(
updateTitle(tab)
updateUrl(tab)
updateIcon(tab)
updateFavicon(tab)
updateCloseButtonDescription(tab.title)
updateSelectedTabIndicator(isSelected)
@ -146,6 +145,15 @@ class TabTrayViewHolder(
}
}
private fun updateFavicon(tab: Tab) {
if (tab.icon != null) {
faviconView?.visibility = View.VISIBLE
faviconView?.setImageBitmap(tab.icon)
} else {
faviconView?.visibility = View.GONE
}
}
private fun updateTitle(tab: Tab) {
val title = if (tab.title.isNotEmpty()) {
tab.title
@ -161,27 +169,11 @@ class TabTrayViewHolder(
// is done in the toolbar and awesomebar:
// https://github.com/mozilla-mobile/fenix/issues/1824
// https://github.com/mozilla-mobile/android-components/issues/6985
urlView?.apply {
text =
if (context.settings().shouldStripUrl) {
tab.url
.toShortUrl(itemView.context.components.publicSuffixList)
.take(MAX_URI_LENGTH)
} else {
tab.url.take(MAX_URI_LENGTH)
}
}
urlView?.text = tab.url
.toShortUrl(itemView.context.components.publicSuffixList)
.take(MAX_URI_LENGTH)
}
private fun updateIcon(tab: Tab) {
if (tab.icon != null) {
iconCard.visibility = View.VISIBLE
iconView.setImageBitmap(tab.icon)
} else {
iconCard.visibility = View.GONE
}
}
@VisibleForTesting
internal fun updateSelectedTabIndicator(isSelected: Boolean) {
if (itemView.context.settings().gridTabView) {
@ -192,10 +184,7 @@ class TabTrayViewHolder(
}
return
}
}
@VisibleForTesting
internal fun updateBackgroundColor(isSelected: Boolean) {
val color = if (isSelected) {
R.color.tab_tray_item_selected_background_normal_theme
} else {
@ -215,10 +204,17 @@ class TabTrayViewHolder(
}
private fun loadIntoThumbnailView(thumbnailView: ImageView, id: String) {
val thumbnailSize = max(
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_thumbnail_height),
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_thumbnail_width)
)
val thumbnailSize = if (itemView.context.settings().gridTabView) {
max(
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_grid_item_thumbnail_height),
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_grid_item_thumbnail_width)
)
} else {
max(
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_list_item_thumbnail_height),
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_list_item_thumbnail_width)
)
}
imageLoader.loadIntoView(thumbnailView, ImageLoadRequest(id, thumbnailSize))
}

@ -17,6 +17,7 @@ import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.content.getDrawableWithTint
import mozilla.components.support.ktx.android.util.dpToPx
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.sessioncontrol.SwipeToDeleteCallback
/**
@ -68,6 +69,10 @@ class TouchCallback(
) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
if (recyclerView.context.settings().gridTabView) {
return
}
val icon = recyclerView.context.getDrawableWithTint(
R.drawable.ic_delete,
recyclerView.context.getColorFromAttr(R.attr.destructive)

@ -1,203 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tab_wrapper"
style="@style/TopSheetModal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:backgroundTint="@color/foundation_normal_theme">
<View
android:id="@+id/handle"
android:layout_width="0dp"
android:layout_height="3dp"
android:layout_marginBottom="8dp"
android:visibility="gone"
android:background="@color/secondary_text_normal_theme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintWidth_percent="0.1" />
<androidx.constraintlayout.widget.ConstraintLayout
tools:ignore="MozMultipleConstraintLayouts"
android:id="@+id/infoBanner"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/foundation_normal_theme"
app:layout_constraintBottom_toTopOf="@id/topBar"/>
<TextView
android:id="@+id/tab_tray_empty_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center_horizontal"
android:paddingBottom="80dp"
android:text="@string/no_open_tabs_description"
android:textColor="?secondaryText"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/infoBanner" />
<androidx.constraintlayout.widget.ConstraintLayout
tools:ignore="MozMultipleConstraintLayouts"
android:id="@+id/topBar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/foundation_normal_theme"
app:layout_constraintBottom_toTopOf="@id/handle">
<ImageButton
android:id="@+id/exit_multi_select"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="0dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/tab_tray_close_multiselect_content_description"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/multiselect_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/multiselect_title"
app:srcCompat="@drawable/ic_close"
app:tint="@color/contrast_text_normal_theme" />
<TextView
android:id="@+id/multiselect_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:textColor="@color/contrast_text_normal_theme"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/collect_multi_select"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/exit_multi_select"
app:layout_constraintTop_toTopOf="parent"
tools:text="3 selected" />
<TextView
android:id="@+id/collect_multi_select"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="16dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/tab_tray_collection_button_multiselect_content_description"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:text="@string/tab_tray_save_to_collection"
android:textAllCaps="true"
android:textColor="@color/contrast_text_normal_theme"
android:textSize="14sp"
android:textStyle="bold"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_tab_collection"
app:drawableTint="@color/contrast_text_normal_theme"
app:fontFamily="@font/metropolis_medium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/exit_tabs_screen"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="0dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/tabs_screen_close_screen_description"
app:layout_constraintBottom_toBottomOf="@id/tab_layout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/tab_layout"
app:srcCompat="@drawable/mozac_ic_back"
app:tint="@color/primary_text_normal_theme" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="@color/foundation_normal_theme"
app:layout_constraintStart_toEndOf="@id/exit_tabs_screen"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.35"
app:tabGravity="fill"
app:tabIconTint="@color/tab_icon"
app:tabIndicatorColor="@color/accent_normal_theme"
app:tabIndicatorGravity="top"
app:tabRippleColor="@android:color/transparent">
<com.google.android.material.tabs.TabItem
android:id="@+id/default_tab_item"
android:layout_width="0dp"
android:layout_height="match_parent"
android:contentDescription="@string/tab_header_label"
android:layout="@layout/tabs_tray_tab_counter"
app:tabIconTint="@color/tab_icon" />
<com.google.android.material.tabs.TabItem
android:id="@+id/private_tab_item"
android:layout_width="0dp"
android:layout_height="match_parent"
android:contentDescription="@string/tabs_header_private_tabs_title"
android:icon="@drawable/ic_private_browsing" />
</com.google.android.material.tabs.TabLayout>
<ImageButton
android:id="@+id/tab_tray_new_tab"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/add_tab"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@id/tab_layout"
app:layout_constraintEnd_toStartOf="@id/tab_tray_overflow"
app:layout_constraintTop_toTopOf="@id/tab_layout"
app:tint="@color/primary_text_normal_theme"
app:srcCompat="@drawable/ic_new" />
<ImageButton
android:id="@+id/tab_tray_overflow"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/open_tabs_menu"
android:visibility="visible"
app:tint="@color/accent_normal_theme"
app:layout_constraintBottom_toBottomOf="@id/tab_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tab_layout"
app:srcCompat="@drawable/ic_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/divider"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="@color/tab_tray_item_divider_normal_theme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/infoBanner" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tabsTray"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipToPadding="false"
android:scrollbars="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/divider" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -1,204 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tab_wrapper"
style="@style/BottomSheetModal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:backgroundTint="@color/foundation_normal_theme">
<View
android:id="@+id/handle"
android:layout_width="0dp"
android:layout_height="@dimen/bottom_sheet_handle_height"
android:layout_marginTop="@dimen/bottom_sheet_handle_top_margin"
android:visibility="gone"
android:background="@color/secondary_text_normal_theme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.1" />
<androidx.constraintlayout.widget.ConstraintLayout
tools:ignore="MozMultipleConstraintLayouts"
android:id="@+id/infoBanner"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/foundation_normal_theme"
app:layout_constraintTop_toBottomOf="@id/topBar"/>
<TextView
android:id="@+id/tab_tray_empty_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center_horizontal"
android:paddingTop="80dp"
android:text="@string/no_open_tabs_description"
android:textColor="?secondaryText"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/infoBanner" />
<androidx.constraintlayout.widget.ConstraintLayout
tools:ignore="MozMultipleConstraintLayouts"
android:id="@+id/topBar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/foundation_normal_theme"
app:layout_constraintTop_toBottomOf="@id/handle">
<ImageButton
android:id="@+id/exit_multi_select"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="0dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/tab_tray_close_multiselect_content_description"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/multiselect_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/multiselect_title"
app:srcCompat="@drawable/ic_close"
app:tint="@color/contrast_text_normal_theme" />
<TextView
android:id="@+id/multiselect_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:textColor="@color/contrast_text_normal_theme"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/collect_multi_select"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/exit_multi_select"
app:layout_constraintTop_toTopOf="parent"
tools:text="3 selected" />
<TextView
android:id="@+id/collect_multi_select"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="16dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/tab_tray_collection_button_multiselect_content_description"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:text="@string/tab_tray_save_to_collection"
android:textAllCaps="true"
android:textColor="@color/contrast_text_normal_theme"
android:textSize="14sp"
android:textStyle="bold"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_tab_collection"
app:drawableTint="@color/contrast_text_normal_theme"
app:fontFamily="@font/metropolis_medium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/exit_tabs_screen"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="0dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/tabs_screen_close_screen_description"
app:layout_constraintBottom_toBottomOf="@id/tab_layout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/tab_layout"
app:srcCompat="@drawable/mozac_ic_back"
app:tint="@color/primary_text_normal_theme" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="@color/foundation_normal_theme"
app:layout_constraintStart_toEndOf="@id/exit_tabs_screen"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.35"
app:tabGravity="fill"
app:tabIconTint="@color/tab_icon"
app:tabIndicatorColor="@color/accent_normal_theme"
app:tabRippleColor="@android:color/transparent">
<com.google.android.material.tabs.TabItem
android:id="@+id/default_tab_item"
android:layout_width="0dp"
android:layout_height="match_parent"
android:contentDescription="@string/tab_header_label"
android:layout="@layout/tabs_tray_tab_counter"
app:tabIconTint="@color/tab_icon" />
<com.google.android.material.tabs.TabItem
android:id="@+id/private_tab_item"
android:layout_width="0dp"
android:layout_height="match_parent"
android:contentDescription="@string/tabs_header_private_tabs_title"
android:icon="@drawable/ic_private_browsing" />
</com.google.android.material.tabs.TabLayout>
<ImageButton
android:id="@+id/tab_tray_new_tab"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/add_tab"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@id/tab_layout"
app:layout_constraintEnd_toStartOf="@id/tab_tray_overflow"
app:layout_constraintTop_toTopOf="@id/tab_layout"
app:tint="@color/primary_text_normal_theme"
app:srcCompat="@drawable/ic_new" />
<ImageButton
android:id="@+id/tab_tray_overflow"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/open_tabs_menu"
android:visibility="visible"
app:tint="@color/accent_normal_theme"
app:layout_constraintBottom_toBottomOf="@id/tab_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tab_layout"
app:srcCompat="@drawable/ic_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/divider"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="@color/tab_tray_item_divider_normal_theme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/infoBanner" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tabsTray"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipToPadding="false"
android:paddingBottom="140dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/divider" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -24,7 +24,6 @@
app:layout_constraintWidth_percent="0.1" />
<androidx.constraintlayout.widget.ConstraintLayout
tools:ignore="MozMultipleConstraintLayouts"
android:id="@+id/infoBanner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -49,7 +48,6 @@
app:layout_constraintTop_toBottomOf="@id/infoBanner" />
<androidx.constraintlayout.widget.ConstraintLayout
tools:ignore="MozMultipleConstraintLayouts"
android:id="@+id/topBar"
android:layout_width="match_parent"
android:layout_height="80dp"
@ -65,9 +63,9 @@
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/tab_tray_close_multiselect_content_description"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/multiselect_title"
app:layout_constraintBottom_toBottomOf="@+id/multiselect_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/multiselect_title"
app:layout_constraintTop_toTopOf="@+id/multiselect_title"
app:srcCompat="@drawable/ic_close"
app:tint="@color/contrast_text_normal_theme" />
@ -84,7 +82,7 @@
app:layout_constraintEnd_toStartOf="@id/collect_multi_select"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/exit_multi_select"
app:layout_constraintStart_toEndOf="@+id/exit_multi_select"
app:layout_constraintTop_toTopOf="parent"
tools:text="3 selected" />
@ -127,7 +125,7 @@
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/add_tab"
android:visibility="visible"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/tab_layout"
app:layout_constraintEnd_toStartOf="@id/tab_tray_overflow"
app:layout_constraintTop_toTopOf="@id/tab_layout"
@ -156,7 +154,7 @@
android:background="@color/tab_tray_item_divider_normal_theme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/infoBanner" />
app:layout_constraintTop_toBottomOf="@+id/infoBanner" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tabsTray"
@ -169,6 +167,6 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/divider" />
app:layout_constraintTop_toBottomOf="@+id/divider" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -19,4 +19,4 @@
app:elevation="99dp"
app:borderWidth="0dp"
app:icon="@drawable/ic_new"
app:iconTint="@color/photonWhite" />
app:iconTint="@color/photonWhite" />

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!-- 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/. -->
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/new_tab_button"
style="@style/TabTrayFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|end"
android:scrollbars="none"
android:layout_margin="16dp"
android:backgroundTint="@color/accent_normal_theme"
android:contentDescription="@string/add_tab"
android:elevation="99dp"
android:text="@string/tab_drawer_fab_content"
android:textColor="@color/photonWhite"
app:elevation="99dp"
app:borderWidth="0dp"
app:icon="@drawable/ic_new"
app:iconTint="@color/photonWhite" />

@ -1,190 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tab_wrapper"
style="@style/TopSheetModal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:backgroundTint="@color/foundation_normal_theme"
app:layout_behavior="org.mozilla.fenix.components.topsheet.TopSheetBehavior">
<View
android:id="@+id/handle"
android:layout_width="0dp"
android:layout_height="3dp"
android:layout_marginBottom="8dp"
android:background="@color/secondary_text_normal_theme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintWidth_percent="0.1" />
<androidx.constraintlayout.widget.ConstraintLayout
tools:ignore="MozMultipleConstraintLayouts"
android:id="@+id/infoBanner"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/foundation_normal_theme"
app:layout_constraintBottom_toTopOf="@id/topBar"/>
<TextView
android:id="@+id/tab_tray_empty_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center_horizontal"
android:paddingBottom="80dp"
android:text="@string/no_open_tabs_description"
android:textColor="?secondaryText"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/infoBanner" />
<androidx.constraintlayout.widget.ConstraintLayout
tools:ignore="MozMultipleConstraintLayouts"
android:id="@+id/topBar"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@color/foundation_normal_theme"
app:layout_constraintBottom_toTopOf="@id/handle">
<ImageButton
android:id="@+id/exit_multi_select"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="0dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/tab_tray_close_multiselect_content_description"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/multiselect_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/multiselect_title"
app:srcCompat="@drawable/ic_close"
app:tint="@color/contrast_text_normal_theme" />
<TextView
android:id="@+id/multiselect_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:textColor="@color/contrast_text_normal_theme"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/collect_multi_select"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/exit_multi_select"
app:layout_constraintTop_toTopOf="parent"
tools:text="3 selected" />
<TextView
android:id="@+id/collect_multi_select"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="16dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/tab_tray_collection_button_multiselect_content_description"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:text="@string/tab_tray_save_to_collection"
android:textAllCaps="true"
android:textColor="@color/contrast_text_normal_theme"
android:textSize="14sp"
android:textStyle="bold"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_tab_collection"
app:drawableTint="@color/contrast_text_normal_theme"
app:fontFamily="@font/metropolis_medium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="0dp"
android:layout_height="80dp"
android:background="@color/foundation_normal_theme"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.5"
app:tabGravity="fill"
app:tabIconTint="@color/tab_icon"
app:tabIndicatorColor="@color/accent_normal_theme"
app:tabIndicatorGravity="top"
app:tabRippleColor="@android:color/transparent">
<com.google.android.material.tabs.TabItem
android:id="@+id/default_tab_item"
android:layout_width="0dp"
android:layout_height="match_parent"
android:contentDescription="@string/tab_header_label"
android:layout="@layout/tabs_tray_tab_counter"
app:tabIconTint="@color/tab_icon" />
<com.google.android.material.tabs.TabItem
android:id="@+id/private_tab_item"
android:layout_width="0dp"
android:layout_height="match_parent"
android:contentDescription="@string/tabs_header_private_tabs_title"
android:icon="@drawable/ic_private_browsing" />
</com.google.android.material.tabs.TabLayout>
<ImageButton
android:id="@+id/tab_tray_new_tab"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/add_tab"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@id/tab_layout"
app:layout_constraintEnd_toStartOf="@id/tab_tray_overflow"
app:layout_constraintTop_toTopOf="@id/tab_layout"
app:tint="@color/primary_text_normal_theme"
app:srcCompat="@drawable/ic_new" />
<ImageButton
android:id="@+id/tab_tray_overflow"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/open_tabs_menu"
android:visibility="visible"
app:tint="@color/accent_normal_theme"
app:layout_constraintBottom_toBottomOf="@id/tab_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tab_layout"
app:srcCompat="@drawable/ic_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/divider"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="@color/tab_tray_item_divider_normal_theme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/infoBanner" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tabsTray"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipToPadding="false"
android:scrollbars="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/divider" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -1,83 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!-- 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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/onboarding_card"
style="@style/OnboardingCardLightWithPadding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false">
<TextView
android:id="@+id/header_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:drawablePadding="12dp"
android:gravity="center_vertical"
android:lines="1"
android:text="@string/onboarding_tabs_layout_header"
android:textAppearance="@style/HeaderTextStyle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/description_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:textAppearance="@style/Body14TextStyle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/header_text"
android:text="@string/onboarding_tabs_tray_layout_description" />
<org.mozilla.fenix.onboarding.OnboardingRadioButton
android:id="@+id/tabs_tray_fennec_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:background="@android:color/transparent"
android:checked="true"
android:foreground="@drawable/rounded_ripple"
android:gravity="top"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:theme="@style/Checkable.Colored"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/description_text"
app:onboardingKey="@string/pref_key_use_fullscreen_tabs_screen"
app:onboardingKeyDescription="@string/onboarding_tabs_tray_fennec_layout_description"
app:onboardingKeyTitle="@string/onboarding_tabs_tray_fennec_layout_button"
tools:text="Standard" />
<org.mozilla.fenix.onboarding.OnboardingRadioButton
android:id="@+id/tabs_tray_fenix_style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:background="@android:color/transparent"
android:checked="false"
android:foreground="@drawable/rounded_ripple"
android:gravity="top"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:textColor="@color/primary_state_list_text_color"
android:theme="@style/Checkable.Colored"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tabs_tray_fennec_style"
app:onboardingKey="@string/pref_key_use_fenix_tabs_tray"
app:onboardingKeyDescription="@string/onboarding_tabs_tray_fenix_layout_description"
app:onboardingKeyTitle="@string/onboarding_tabs_tray_fenix_layout_button"
tools:text="Strict" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -28,8 +28,8 @@
<androidx.cardview.widget.CardView
android:id="@+id/mozac_browser_tabstray_card"
android:layout_width="@dimen/tab_tray_thumbnail_width_original"
android:layout_height="@dimen/tab_tray_thumbnail_height_original"
android:layout_width="@dimen/tab_tray_list_item_thumbnail_width"
android:layout_height="@dimen/tab_tray_list_item_thumbnail_height"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
@ -57,42 +57,22 @@
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/mozac_browser_tabstray_icon_card"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="8dp"
app:layout_constraintStart_toEndOf="@id/mozac_browser_tabstray_card"
app:layout_constraintBottom_toBottomOf="@id/mozac_browser_tabstray_title"
app:cardCornerRadius="5dp" >
<ImageView
android:id="@+id/mozac_browser_tabstray_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="no" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/mozac_browser_tabstray_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:requiresFadingEdge="horizontal"
android:fadingEdgeLength="25dp"
android:ellipsize="none"
android:singleLine="true"
android:layout_marginTop="24dp"
android:layout_marginStart="12dp"
android:ellipsize="end"
android:textColor="@color/tab_tray_item_text_normal_theme"
android:textSize="16sp"
android:lineSpacingExtra="4sp"
android:maxLines="2"
tools:text="Example Domain"
tools:text="Firefox"
app:layout_constraintEnd_toStartOf="@id/mozac_browser_tabstray_close"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/mozac_browser_tabstray_icon_card"
app:layout_constraintStart_toEndOf="@id/mozac_browser_tabstray_card"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/mozac_browser_tabstray_url" />
@ -101,16 +81,14 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:requiresFadingEdge="horizontal"
android:fadingEdgeLength="25dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="24dp"
android:layout_marginStart="12dp"
android:ellipsize="none"
android:singleLine="true"
android:ellipsize="end"
android:lines="1"
android:textColor="@color/tab_tray_item_url_normal_theme"
android:textSize="14sp"
tools:text="example.com"
tools:text="firefox.com"
app:layout_constraintEnd_toStartOf="@id/mozac_browser_tabstray_close"
app:layout_constraintStart_toEndOf="@id/mozac_browser_tabstray_card"
app:layout_constraintTop_toBottomOf="@id/mozac_browser_tabstray_title"

@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tab_item"
android:layout_width="match_parent"
android:layout_height="165dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:selectableItemBackground">
<ImageButton
android:id="@+id/play_pause_button"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="23dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/mozac_feature_media_notification_action_pause"
android:elevation="10dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/media_state_play" />
<androidx.cardview.widget.CardView
android:id="@+id/mozac_browser_tabstray_card"
android:layout_width="match_parent"
android:layout_height="@dimen/tab_tray_thumbnail_height"
android:layout_marginHorizontal="7dp"
android:layout_marginTop="30dp"
android:backgroundTint="?tabTrayThumbnailItemBackground"
app:cardBackgroundColor="@color/photonWhite"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/default_tab_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="no"
android:padding="22dp"
app:srcCompat="@drawable/mozac_ic_globe"
app:tint="?tabTrayThumbnailIcon" />
<mozilla.components.browser.tabstray.thumbnail.TabThumbnailView
android:id="@+id/mozac_browser_tabstray_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/mozac_browser_tabstray_open_tab" />
<include layout="@layout/checkbox_item" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/mozac_browser_tabstray_icon_card"
android:layout_width="20dp"
android:layout_height="20dp"
app:layout_constraintStart_toStartOf="@id/mozac_browser_tabstray_card"
app:layout_constraintBottom_toTopOf="@id/mozac_browser_tabstray_card"
app:layout_constraintTop_toTopOf="parent"
app:cardCornerRadius="5dp" >
<ImageView
android:id="@+id/mozac_browser_tabstray_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="no" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/mozac_browser_tabstray_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:requiresFadingEdge="horizontal"
android:fadingEdgeLength="25dp"
android:ellipsize="none"
android:singleLine="true"
android:paddingHorizontal="7dp"
android:paddingVertical="5dp"
android:textColor="@color/tab_tray_item_text_normal_theme"
android:textSize="14sp"
android:visibility="visible"
tools:text="Example Domain"
app:layout_constraintEnd_toStartOf="@id/mozac_browser_tabstray_close"
app:layout_constraintStart_toEndOf="@id/mozac_browser_tabstray_icon_card"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/mozac_browser_tabstray_url"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:lines="1"
android:paddingStart="8dp"
android:textColor="@color/tab_tray_item_url_normal_theme"
android:textSize="14sp"
tools:text="example.com"
android:visibility="gone"
app:layout_constraintEnd_toStartOf="@id/mozac_browser_tabstray_close"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/mozac_browser_tabstray_card"
app:layout_constraintTop_toBottomOf="@id/mozac_browser_tabstray_title" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/mozac_browser_tabstray_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/close_tab"
app:layout_constraintEnd_toEndOf="@id/mozac_browser_tabstray_card"
app:layout_constraintBottom_toTopOf="@id/mozac_browser_tabstray_card"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/mozac_ic_close"
app:tint="@color/tab_tray_item_text_normal_theme" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -75,7 +75,7 @@ class SyncedTabsControllerTest {
}
@Test
fun `display synced tabs in correct order`() {
fun `display synced tabs in reverse`() {
val tabs = listOf(
SyncedDeviceTabs(
device = mockk(relaxed = true),
@ -94,19 +94,19 @@ class SyncedTabsControllerTest {
assertEquals(4, itemCount)
assertEquals(
SyncedTabsViewHolder.TitleViewHolder.LAYOUT_ID,
controller.adapter.getItemViewType(0)
controller.adapter.getItemViewType(itemCount - 1)
)
assertEquals(
SyncedTabsViewHolder.DeviceViewHolder.LAYOUT_ID,
controller.adapter.getItemViewType(1)
controller.adapter.getItemViewType(itemCount - 2)
)
assertEquals(
SyncedTabsViewHolder.TabViewHolder.LAYOUT_ID,
controller.adapter.getItemViewType(2)
controller.adapter.getItemViewType(itemCount - 3)
)
assertEquals(
SyncedTabsViewHolder.TabViewHolder.LAYOUT_ID,
controller.adapter.getItemViewType(3)
controller.adapter.getItemViewType(itemCount - 4)
)
}

@ -62,7 +62,7 @@ class TabTrayViewHolderTest {
tabViewHolder.bind(tab, false, mockk(), mockk())
assertEquals("m".repeat(MAX_URI_LENGTH), tabViewHolder.urlView?.text)
verify { imageLoader.loadIntoView(any(), ImageLoadRequest("123", 130)) }
verify { imageLoader.loadIntoView(any(), ImageLoadRequest("123", 92)) }
}
@Test

Loading…
Cancel
Save