Enable fennec fullscreen tabs screen + onboarding layout setup

pull/69/head
Abhijit Valluri 4 years ago
parent bb0ef2b659
commit 0464ed8e8c

@ -23,17 +23,7 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.NoCollectionsMessageVie
import org.mozilla.fenix.home.sessioncontrol.viewholders.PrivateBrowsingDescriptionViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.TabInCollectionViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.TopSitePagerViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingAutomaticSignInViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingFinishViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingHeaderViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingManualSignInViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingPrivacyNoticeViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingPrivateBrowsingViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingSectionHeaderViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingThemePickerViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingToolbarPositionPickerViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingTrackingProtectionViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingWhatsNewViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.*
import org.mozilla.fenix.home.tips.ButtonTipViewHolder
import mozilla.components.feature.tab.collections.Tab as ComponentTab
@ -106,6 +96,7 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
object OnboardingFinish : AdapterItem(OnboardingFinishViewHolder.LAYOUT_ID)
object OnboardingToolbarPositionPicker :
AdapterItem(OnboardingToolbarPositionPickerViewHolder.LAYOUT_ID)
object OnboardingTabsTrayLayoutPicker : AdapterItem(OnboardingTabsTrayLayoutViewHolder.LAYOUT_ID)
object OnboardingWhatsNew : AdapterItem(OnboardingWhatsNewViewHolder.LAYOUT_ID)
@ -189,6 +180,7 @@ class SessionControlAdapter(
OnboardingToolbarPositionPickerViewHolder.LAYOUT_ID -> OnboardingToolbarPositionPickerViewHolder(
view
)
OnboardingTabsTrayLayoutViewHolder.LAYOUT_ID -> OnboardingTabsTrayLayoutViewHolder(view)
else -> throw IllegalStateException()
}
}

@ -99,6 +99,7 @@ private fun onboardingAdapterItems(onboardingState: OnboardingState): List<Adapt
AdapterItem.OnboardingThemePicker,
AdapterItem.OnboardingPrivateBrowsing,
AdapterItem.OnboardingToolbarPositionPicker,
AdapterItem.OnboardingTabsTrayLayoutPicker,
AdapterItem.OnboardingPrivacyNotice,
AdapterItem.OnboardingFinish
)

@ -0,0 +1,54 @@
/* 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.components.metrics.Event
import org.mozilla.fenix.components.metrics.Event.OnboardingTrackingProtection.Setting
import org.mozilla.fenix.ext.components
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
}
}

@ -148,6 +148,11 @@ class CustomizationFragment : PreferenceFragmentCompat() {
onPreferenceChangeListener = SharedPreferenceUpdater()
}
requirePreference<SwitchPreference>(R.string.pref_key_use_fullscreen_tabs_screen).apply {
isChecked = context.settings().useFullScreenTabScreen
onPreferenceChangeListener = SharedPreferenceUpdater()
}
val reverseOrderPref = requirePreference<SwitchPreference>(R.string.pref_key_tabs_tray_reverse_tab_order).apply {
if (context.settings().enableCompactTabs) {
isChecked = false
@ -178,15 +183,34 @@ class CustomizationFragment : PreferenceFragmentCompat() {
}
private fun setupFabCategory() {
requirePreference<SwitchPreference>(R.string.pref_key_tabs_tray_use_fab).apply {
isChecked = context.settings().useNewTabFloatingActionButton
val fabPositionTop = requirePreference<SwitchPreference>(R.string.pref_key_tabs_tray_fab_top_position).apply {
if (context.settings().useNewTabFloatingActionButton) {
isChecked = context.settings().placeNewTabFloatingActionButtonAtTop
isEnabled = true
} else {
isChecked = false
isEnabled = false
}
onPreferenceChangeListener = SharedPreferenceUpdater()
}
requirePreference<SwitchPreference>(R.string.pref_key_tabs_tray_fab_top_position).apply {
isChecked = context.settings().placeNewTabFloatingActionButtonAtTop
onPreferenceChangeListener = SharedPreferenceUpdater()
requirePreference<SwitchPreference>(R.string.pref_key_tabs_tray_use_fab).apply {
isChecked = context.settings().useNewTabFloatingActionButton
onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference, newValue ->
val newValueBoolean = newValue as Boolean
preference.context.settings().preferences.edit {
putBoolean(preference.key, newValueBoolean)
if (!newValueBoolean) {
fabPositionTop.isChecked = false
putBoolean(getString(R.string.pref_key_tabs_tray_fab_top_position), false)
}
fabPositionTop.isEnabled = newValueBoolean
}
true
}
}
}
private fun setupHomeCategory() {

@ -25,7 +25,18 @@ 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_tabstray_bottom.view.*
import kotlinx.android.synthetic.main.component_tabs_screen_top.view.*
import kotlinx.android.synthetic.main.component_tabstray_bottom.view.collect_multi_select
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.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.*
import kotlinx.android.synthetic.main.tabs_tray_tab_counter.*
import kotlinx.coroutines.Dispatchers.Main
@ -81,19 +92,33 @@ class TabTrayView(
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 = 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: 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)
}
}
private val isPrivateModeSelected: Boolean get() = view.tab_layout.selectedTabPosition == PRIVATE_TAB_ID
private val behavior = when (useTopTabsTray) {
true -> TopSheetBehavior.from(view.tab_wrapper)
false -> BottomSheetBehavior.from(view.tab_wrapper)
private val behavior = if (isTabsTrayFullScreenMode) null else {
when (useTopTabsTray) {
true -> TopSheetBehavior.from(view.tab_wrapper)
false -> BottomSheetBehavior.from(view.tab_wrapper)
}
}
private val concatAdapter = ConcatAdapter(tabsAdapter)
@ -118,46 +143,54 @@ class TabTrayView(
toggleFabText(isPrivate)
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()
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()
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()
})
} 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()
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
components.analytics.metrics.track(Event.TabsTrayClosed)
interactor.onTabTrayDismissed()
}
}
}
})
})
}
}
if (isTabsTrayFullScreenMode) {
view.exit_tabs_screen.setOnClickListener {
interactor.onTabTrayDismissed()
}
}
val selectedTabIndex = if (!isPrivate) {
@ -367,10 +400,12 @@ class TabTrayView(
}
fun expand() {
if (useTopTabsTray) {
(behavior as TopSheetBehavior).state = TopSheetBehavior.STATE_EXPANDED
} else {
(behavior as BottomSheetBehavior).state = BottomSheetBehavior.STATE_EXPANDED
if (!isTabsTrayFullScreenMode) {
if (useTopTabsTray) {
(behavior as TopSheetBehavior).state = TopSheetBehavior.STATE_EXPANDED
} else {
(behavior as BottomSheetBehavior).state = BottomSheetBehavior.STATE_EXPANDED
}
}
}
@ -555,10 +590,12 @@ 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) {
@ -607,14 +644,16 @@ class TabTrayView(
}
fun setTopOffset(landscape: Boolean) {
val topOffset = if (landscape) {
0
} else {
view.context.resources.getDimension(R.dimen.tab_tray_top_offset).toInt()
}
if (!isTabsTrayFullScreenMode) {
val topOffset = if (landscape) {
0
} else {
view.context.resources.getDimension(R.dimen.tab_tray_top_offset).toInt()
}
if (!useTopTabsTray) {
(behavior as BottomSheetBehavior).setExpandedOffset(topOffset)
if (!useTopTabsTray) {
(behavior as BottomSheetBehavior).setExpandedOffset(topOffset)
}
}
}

@ -875,9 +875,9 @@ class Settings(private val appContext: Context) : PreferencesHolder {
BuildConfig.AMO_COLLECTION
)
val enableCompactTabs by booleanPreference(
var enableCompactTabs by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_tabs_tray_compact_tab),
default = false
default = true
)
val useTopTabsTray by booleanPreference(
@ -885,17 +885,25 @@ class Settings(private val appContext: Context) : PreferencesHolder {
default = false
)
val reverseTabOrderInTabsTray by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_tabs_tray_reverse_tab_order),
var useFullScreenTabScreen by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_use_fullscreen_tabs_screen),
default = true
)
val useNewTabFloatingActionButton by booleanPreference(
val shouldUseFennecStyleTabsScreen: Boolean
get() = enableCompactTabs && useFullScreenTabScreen
var reverseTabOrderInTabsTray by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_tabs_tray_reverse_tab_order),
default = false
)
var useNewTabFloatingActionButton by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_tabs_tray_use_fab),
default = true
default = false
)
val placeNewTabFloatingActionButtonAtTop by booleanPreference(
var placeNewTabFloatingActionButtonAtTop by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_tabs_tray_fab_top_position),
default = false
)

@ -0,0 +1,191 @@
<?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" />
<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/divider" />
<androidx.constraintlayout.widget.ConstraintLayout
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: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/topBar" />
<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>

@ -0,0 +1,192 @@
<?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="3dp"
android:layout_marginTop="8dp"
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" />
<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/topBar" />
<androidx.constraintlayout.widget.ConstraintLayout
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: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/topBar" />
<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>

@ -0,0 +1,83 @@
<?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>

@ -130,6 +130,8 @@
<string name="pref_tabs_tray_settings_category" translatable="false">pref_tabs_tray_settings_category</string>
<string name="pref_key_tabs_tray_compact_tab" translatable="false">pref_key_tabs_tray_compact_tab</string>
<string name="pref_key_tabs_tray_top_tray" translatable="false">pref_key_tabs_tray_top_tray</string>
<string name="pref_key_use_fullscreen_tabs_screen" translatable="false">pref_key_use_fullscreen_tabs_screen</string>
<string name="pref_key_use_fenix_tabs_tray" translatable="false">pref_key_use_fenix_tabs_tray</string>
<string name="pref_key_tabs_tray_reverse_tab_order" translatable="false">pref_key_tabs_tray_reverse_tab_order</string>
<!-- Tabs Tray FAB Customization Settings -->

@ -33,6 +33,8 @@
<string name="tab_tray_select_collection">Select collection</string>
<!-- Content description for close button while in multiselect mode in tab tray -->
<string name="tab_tray_close_multiselect_content_description">Exit multiselect mode</string>
<!-- Content description for back button in full screen tabs screen -->
<string name="tabs_screen_close_screen_description">Close tabs screen</string>
<!-- Content description for save to collection button while in multiselect mode in tab tray -->
<string name="tab_tray_collection_button_multiselect_content_description">Save selected tabs to collection</string>
<!-- Content description for checkmark while tab is selected while in multiselect mode in tab tray. The first parameter is the title of the tab selected -->
@ -1072,6 +1074,18 @@
<string name="onboarding_tracking_protection_strict_option">Strict</string>
<!-- text for strict blocking option button description -->
<string name="onboarding_tracking_protection_strict_button_description_2">Blocks more trackers, ads, and popups. Pages load faster, but some functionality might not work.</string>
<!-- text for the tabs tray layout onboarding card header -->
<string name="onboarding_tabs_layout_header">Choose your tabs tray layout</string>
<!-- text for the tabs tray layout card description-->
<string name="onboarding_tabs_tray_layout_description">Pick either the old Firefox (Fennec) style tabs screen or the new and fancy (Fenix) style tabs tray.</string>
<!-- text for old Fennec style tab screen layout -->
<string name="onboarding_tabs_tray_fennec_layout_button">Old Fennec style (default)</string>
<!-- text for old Fennec style description -->
<string name="onboarding_tabs_tray_fennec_layout_description">Clicking the tab count on the toolbar will show you a tabs screen with a layout similar to the previous (Fennec) version of Firefox.</string>
<!-- text for Fenix style tab tray layout -->
<string name="onboarding_tabs_tray_fenix_layout_button">New Fenix style</string>
<!-- text for strict blocking option button description -->
<string name="onboarding_tabs_tray_fenix_layout_description">Clicking the tab count on the toolbar will show you a new tabs tray layout from the Fenix version of Firefox.</string>
<!-- text for the toolbar position card header
In English this is an idiom for "choose a side as in an argument or fight"
but it is ok to make this more literally about "choosing a position in a physical space -->
@ -1549,6 +1563,8 @@
<string name="enable_compact_tabs">Enable compact tabs</string>
<!-- Label for enable top tabs tray preference -->
<string name="enable_top_tabs_tray">Enable top tabs tray</string>
<!-- Label for fullscreen tabs tray preference -->
<string name="use_fullscreen_tabs_screen">Enable fullscreen tabs screen</string>
<!-- Label for reverse tab order in tabs tray preference -->
<string name="reverse_tab_order_tabs_tray">Reverse tab order in tray</string>
<!-- Summary for reverse tab order preference -->

@ -57,7 +57,7 @@
app:allowDividerAbove="true"
app:iconSpaceReserved="false">
<SwitchPreference
android:defaultValue="false"
android:defaultValue="true"
android:key="@string/pref_key_tabs_tray_compact_tab"
android:title="@string/enable_compact_tabs" />
<SwitchPreference
@ -66,6 +66,10 @@
android:title="@string/enable_top_tabs_tray" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/pref_key_use_fullscreen_tabs_screen"
android:title="@string/use_fullscreen_tabs_screen" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/pref_key_tabs_tray_reverse_tab_order"
android:title="@string/reverse_tab_order_tabs_tray"
android:summary="@string/reverse_tab_order_description" />
@ -78,7 +82,7 @@
app:allowDividerAbove="false"
app:iconSpaceReserved="false">
<SwitchPreference
android:defaultValue="true"
android:defaultValue="false"
android:key="@string/pref_key_tabs_tray_use_fab"
android:title="@string/enable_fab_tabs_tray" />
<SwitchPreference

Loading…
Cancel
Save