1
0
Fork 0

For #1063: Put tab tray behind a feature flag and hidden pref (#10313)

* For #1063 - Adds feature flag and pref for new tab tray

* For #1063 - Swaps add tab to tab tray button when newTabTray is enabled

* For #1063 - Creates hidden preference to use new tab tray

* For #1063 - Hides tabs on home screen when setting is enabled

* For #1063 - Navigate to new tab tray from browser with setting enabled

* For #1063 - Fixes regression where we dont show the new tab message with no tabs and no collections

* For #1063 - Fixes crash when toggling to private mode on the home screen

* For #1063 - combines both settings. Cleans up lint errors
master
Jeff Boek 2020-04-30 13:53:10 -07:00 committed by GitHub
parent f7dcb9f7b3
commit a8a90bd4d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 172 additions and 26 deletions

View File

@ -43,4 +43,9 @@ object FeatureFlags {
* Enables tip feature
*/
val tips = Config.channel.isDebug
/**
* Enables new tab tray pref
*/
val tabTray = Config.channel.isDebug
}

View File

@ -313,6 +313,12 @@ class DefaultBrowserToolbarController(
}
private fun animateTabAndNavigateHome() {
if (activity.settings().useNewTabTray) {
val directions = BrowserFragmentDirections.actionBrowserFragmentToTabsTrayFragment()
navController.navigate(directions)
return
}
scope.launch {
browserAnimator.beginAnimateOut()
// Delay for a short amount of time so the browser has time to start animating out

View File

@ -26,6 +26,7 @@ import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import androidx.constraintlayout.widget.ConstraintSet.TOP
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
@ -64,6 +65,7 @@ import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.feature.media.ext.pauseIfPlaying
import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.top.sites.TopSite
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.android.util.dpToPx
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
@ -98,6 +100,7 @@ import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.deletebrowsingdata.deleteAndQuit
import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.utils.FragmentPreDrawManager
import org.mozilla.fenix.utils.Settings
import org.mozilla.fenix.utils.allowUndo
import org.mozilla.fenix.whatsnew.WhatsNew
import java.lang.ref.WeakReference
@ -232,14 +235,20 @@ class HomeFragment : Fragment() {
updateLayout(view)
setOffset(view)
sessionControlView = SessionControlView(
homeFragmentStore,
view.sessionControlRecyclerView,
sessionControlInteractor,
viewLifecycleOwner,
homeViewModel
)
activity.themeManager.applyStatusBarTheme(activity)
view.consumeFrom(homeFragmentStore, viewLifecycleOwner) {
sessionControlView?.update(it)
if (context?.settings()?.useNewTabTray == true) {
view.tab_button.setCountWithAnimation(it.tabs.size)
}
}
return view
}
@ -344,6 +353,12 @@ class HomeFragment : Fragment() {
navigateToSearch()
}
view.tab_button.setOnClickListener {
invokePendingDeleteJobs()
hideOnboardingIfNeeded()
findNavController().navigate(HomeFragmentDirections.actionGlobalTabTrayFragment())
}
PrivateBrowsingButtonView(
privateBrowsingButton,
browsingModeManager
@ -538,6 +553,11 @@ class HomeFragment : Fragment() {
scrollToSelectedTab()
sharedViewModel.shouldScrollToSelectedTab = false
}
requireContext().settings().useNewTabTray.also {
view?.add_tab_button?.isVisible = !it
view?.tab_button?.isVisible = it
}
}
override fun onPause() {

View File

@ -4,9 +4,9 @@
package org.mozilla.fenix.home.sessioncontrol
import android.content.Context
import android.os.Build
import android.view.View
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -14,15 +14,14 @@ import kotlinx.android.extensions.LayoutContainer
import kotlinx.coroutines.ExperimentalCoroutinesApi
import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.top.sites.TopSite
import mozilla.components.lib.state.ext.consumeFrom
import org.mozilla.fenix.R
import org.mozilla.fenix.home.HomeFragmentState
import org.mozilla.fenix.home.HomeFragmentStore
import org.mozilla.fenix.home.HomeScreenViewModel
import org.mozilla.fenix.home.Mode
import org.mozilla.fenix.home.OnboardingState
import org.mozilla.fenix.home.Tab
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.ext.settings
val noTabMessage = AdapterItem.NoContentMessageWithAction(
R.string.no_open_tabs_header_2,
@ -36,7 +35,11 @@ val noCollectionMessage = AdapterItem.NoContentMessage(
R.string.collections_description
)
// This method got a little complex with the addition of the tab tray feature flag
// When we remove the tabs from the home screen this will get much simpler again.
@SuppressWarnings("LongParameterList", "ComplexMethod")
private fun normalModeAdapterItems(
context: Context,
tabs: List<Tab>,
topSites: List<TopSite>,
collections: List<TabCollection>,
@ -52,26 +55,30 @@ private fun normalModeAdapterItems(
items.add(AdapterItem.TopSiteList(topSites))
}
items.add(AdapterItem.TabHeader(false, tabs.isNotEmpty()))
val useNewTabTray = context.settings().useNewTabTray
if (!useNewTabTray) {
items.add(AdapterItem.TabHeader(false, tabs.isNotEmpty()))
}
when {
tabs.isNotEmpty() && collections.isNotEmpty() -> {
showTabs(items, tabs)
if (!useNewTabTray) { showTabs(items, tabs) }
showCollections(collections, expandedCollections, tabs, items)
}
tabs.isNotEmpty() && collections.isEmpty() -> {
showTabs(items, tabs)
if (!useNewTabTray) { showTabs(items, tabs) }
items.add(AdapterItem.CollectionHeader)
items.add(noCollectionMessage)
}
tabs.isEmpty() && collections.isNotEmpty() -> {
items.add(noTabMessage)
if (!useNewTabTray) { items.add(noTabMessage) }
showCollections(collections, expandedCollections, tabs, items)
}
tabs.isEmpty() && collections.isEmpty() -> {
tabs.isEmpty() && collections.isEmpty() && !useNewTabTray -> {
items.add(noTabMessage)
}
}
@ -105,14 +112,21 @@ private fun showCollections(
}
}
private fun privateModeAdapterItems(tabs: List<Tab>): List<AdapterItem> {
private fun privateModeAdapterItems(context: Context, tabs: List<Tab>): List<AdapterItem> {
val items = mutableListOf<AdapterItem>()
items.add(AdapterItem.TabHeader(true, tabs.isNotEmpty()))
if (tabs.isNotEmpty()) {
items.addAll(tabs.reversed().map(AdapterItem::TabItem))
} else {
val useNewTabTray = context.settings().useNewTabTray
if (useNewTabTray) {
items.add(AdapterItem.PrivateBrowsingDescription)
} else {
items.add(AdapterItem.TabHeader(true, tabs.isNotEmpty()))
if (tabs.isNotEmpty()) {
items.addAll(tabs.reversed().map(AdapterItem::TabItem))
} else {
items.add(AdapterItem.PrivateBrowsingDescription)
}
}
return items
@ -153,9 +167,9 @@ private fun onboardingAdapterItems(onboardingState: OnboardingState): List<Adapt
return items
}
private fun HomeFragmentState.toAdapterList(): List<AdapterItem> = when (mode) {
is Mode.Normal -> normalModeAdapterItems(tabs, topSites, collections, expandedCollections, tip)
is Mode.Private -> privateModeAdapterItems(tabs)
private fun HomeFragmentState.toAdapterList(context: Context): List<AdapterItem> = when (mode) {
is Mode.Normal -> normalModeAdapterItems(context, tabs, topSites, collections, expandedCollections, tip)
is Mode.Private -> privateModeAdapterItems(context, tabs)
is Mode.Onboarding -> onboardingAdapterItems(mode.state)
}
@ -165,10 +179,8 @@ private fun collectionTabItems(collection: TabCollection) = collection.tabs.mapI
@ExperimentalCoroutinesApi
class SessionControlView(
private val homeFragmentStore: HomeFragmentStore,
override val containerView: View?,
interactor: SessionControlInteractor,
private val viewLifecycleOwner: LifecycleOwner,
private var homeScreenViewModel: HomeScreenViewModel
) : LayoutContainer {
@ -187,10 +199,6 @@ class SessionControlView(
)
)
itemTouchHelper.attachToRecyclerView(this)
view.consumeFrom(homeFragmentStore, viewLifecycleOwner) {
update(it)
}
}
}
@ -200,7 +208,7 @@ class SessionControlView(
sessionControlAdapter.submitList(null)
}
val stateAdapterList = state.toAdapterList()
val stateAdapterList = state.toAdapterList(view.context)
if (homeScreenViewModel.shouldScrollToTopSites) {
sessionControlAdapter.submitList(stateAdapterList) {

View File

@ -0,0 +1,35 @@
/* 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.settings
import android.os.Bundle
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
/**
* Lets the user customize Private browsing options.
*/
class SecretSettingsPreference : PreferenceFragmentCompat() {
override fun onResume() {
super.onResume()
showToolbar(getString(R.string.preferences_debug_settings))
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.secret_settings_preferences, rootKey)
updatePreferences()
}
private fun updatePreferences() {
findPreference<SwitchPreference>(getPreferenceKey(R.string.pref_key_enable_new_tab_tray))?.apply {
onPreferenceChangeListener = SharedPreferenceUpdater()
isChecked = context.settings().useNewTabTray
}
}
}

View File

@ -277,6 +277,9 @@ class SettingsFragment : PreferenceFragmentCompat() {
startActivity(intent)
null
}
resources.getString(R.string.pref_key_debug_settings) -> {
SettingsFragmentDirections.actionSettingsFragmentToSecretSettingsFragment()
}
else -> null
}
directions?.let { navigateFromSettings(directions) }
@ -327,6 +330,9 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
preferenceFxAOverride?.onPreferenceChangeListener = syncFxAOverrideUpdater
preferenceSyncOverride?.onPreferenceChangeListener = syncFxAOverrideUpdater
findPreference<Preference>(
getPreferenceKey(R.string.pref_key_debug_settings)
)?.isVisible = requireContext().settings().showSecretDebugMenuThisSession
}
private fun navigateFromSettings(directions: NavDirections) {

View File

@ -24,6 +24,7 @@ import mozilla.components.support.ktx.android.content.longPreference
import mozilla.components.support.ktx.android.content.stringPreference
import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.Config
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.metrics.MozillaProductDetector
@ -635,4 +636,15 @@ class Settings private constructor(
appContext.getPreferenceKey(R.string.pref_key_top_sites_size),
default = 0
)
var useNewTabTray: Boolean
get() = preferences.let {
val prefKey = appContext.getPreferenceKey(R.string.pref_key_enable_new_tab_tray)
val useNewTabTray = it.getBoolean(prefKey, false)
FeatureFlags.tabTray && useNewTabTray }
set(value) {
preferences.edit()
.putBoolean(appContext.getPreferenceKey(R.string.pref_key_enable_new_tab_tray), value)
.apply()
}
}

View File

@ -105,7 +105,7 @@
android:contentDescription="@string/search_hint"
android:focusable="true"
app:layout_constraintBottom_toBottomOf="@id/bottom_bar"
app:layout_constraintEnd_toStartOf="@+id/add_tab_button"
app:layout_constraintEnd_toStartOf="@+id/accessory_button_barrier"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/bottom_bar">
@ -135,6 +135,13 @@
android:textSize="15sp" />
</FrameLayout>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/accessory_button_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="start"
app:constraint_referenced_ids="tab_button,add_tab_button" />
<ImageButton
android:id="@+id/add_tab_button"
android:layout_width="48dp"
@ -147,6 +154,17 @@
app:layout_constraintEnd_toStartOf="@+id/menuButton"
app:layout_constraintStart_toEndOf="@id/toolbar_wrapper"/>
<org.mozilla.fenix.components.toolbar.TabCounter
android:id="@+id/tab_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:visibility="gone"
app:layout_constraintTop_toTopOf="@id/bottom_bar"
app:layout_constraintBottom_toBottomOf="@id/bottom_bar"
app:layout_constraintEnd_toStartOf="@+id/menuButton"
app:layout_constraintStart_toEndOf="@id/toolbar_wrapper"/>
<mozilla.components.browser.menu.view.MenuButton
android:id="@+id/menuButton"
android:layout_width="36dp"

View File

@ -365,6 +365,13 @@
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right"
app:destination="@id/aboutFragment" />
<action
android:id="@+id/action_settingsFragment_to_secretSettingsFragment"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right"
app:destination="@id/secretSettingsPreference" />
<action
android:id="@+id/action_settingsFragment_to_customizationFragment"
app:enterAnim="@anim/slide_in_right"
@ -500,6 +507,10 @@
<fragment
android:id="@+id/aboutFragment"
android:name="org.mozilla.fenix.settings.about.AboutFragment"/>
<fragment
android:id="@+id/secretSettingsPreference"
android:name="org.mozilla.fenix.settings.SecretSettingsPreference"
android:label="@string/preferences_debug_settings" />
<fragment
android:id="@+id/crashReporterFragment"
android:name="org.mozilla.fenix.crashes.CrashReporterFragment">

View File

@ -165,4 +165,7 @@
<string name="pref_key_migrating_from_firefox_nightly_tip" translatable="false">pref_key_migrating_from_firefox_nightly_tip</string>
<string name="pref_key_migrating_from_fenix_tip" translatable="false">pref_key_migrating_from_fenix_tip</string>
<string name="pref_key_enable_new_tab_tray" translatable="false">pref_key_new_tab_tray</string>
<string name="pref_key_debug_settings" translatable="false">pref_key_debug_settings</string>
</resources>

View File

@ -43,4 +43,8 @@
<string name="tab_tray_menu_home" translatable="false">Go home</string>
<!-- Shortcut action to toggle private mode -->
<string name="tab_tray_menu_toggle" translatable="false">Toggle tab mode</string>
<!-- Label for the secret settings preference -->
<string name="preferences_debug_settings">Secret Settings</string>
<string name="preferences_debug_settings_enable_tab_tray">Use New Tab Tray</string>
</resources>

View File

@ -159,5 +159,11 @@
android:icon="@drawable/ic_info"
android:key="@string/pref_key_about"
android:title="@string/preferences_about" />
<androidx.preference.Preference
android:icon="@drawable/ic_info"
android:key="@string/pref_key_debug_settings"
android:title="@string/preferences_debug_settings"
app:isPreferenceVisible="false" />
</androidx.preference.PreferenceCategory>
</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,12 @@
<?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/. -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<SwitchPreference
android:defaultValue="false"
android:key="@string/pref_key_enable_new_tab_tray"
android:title="@string/preferences_debug_settings_enable_tab_tray"
app:iconSpaceReserved="false" />
</PreferenceScreen>