For #21095 allow users to configure their home screen.

upstream-sync
Arturo Mejia 3 years ago
parent 7d481a7836
commit d4a212f235

@ -58,4 +58,9 @@ object FeatureFlags {
* Enables showing the home screen behind the search dialog * Enables showing the home screen behind the search dialog
*/ */
val showHomeBehindSearch = Config.channel.isNightlyOrDebug val showHomeBehindSearch = Config.channel.isNightlyOrDebug
/**
* Enables customizing the home screen
*/
val customizeHome = Config.channel.isNightlyOrDebug
} }

@ -221,6 +221,10 @@ class DefaultBrowserToolbarMenuController(
val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment() val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment()
navController.nav(R.id.browserFragment, directions) navController.nav(R.id.browserFragment, directions)
} }
is ToolbarMenu.Item.CustomizeHome -> browserAnimator.captureEngineViewAndDrawStatically {
val directions = BrowserFragmentDirections.actionBrowserFragmentToCustomFragment()
navController.nav(R.id.browserFragment, directions)
}
is ToolbarMenu.Item.SyncAccount -> { is ToolbarMenu.Item.SyncAccount -> {
val directions = when (item.accountState) { val directions = when (item.accountState) {
AccountState.AUTHENTICATED -> AccountState.AUTHENTICATED ->
@ -384,6 +388,7 @@ class DefaultBrowserToolbarMenuController(
is ToolbarMenu.Item.Stop -> Event.BrowserMenuItemTapped.Item.STOP is ToolbarMenu.Item.Stop -> Event.BrowserMenuItemTapped.Item.STOP
is ToolbarMenu.Item.Share -> Event.BrowserMenuItemTapped.Item.SHARE is ToolbarMenu.Item.Share -> Event.BrowserMenuItemTapped.Item.SHARE
is ToolbarMenu.Item.Settings -> Event.BrowserMenuItemTapped.Item.SETTINGS is ToolbarMenu.Item.Settings -> Event.BrowserMenuItemTapped.Item.SETTINGS
is ToolbarMenu.Item.CustomizeHome -> return
is ToolbarMenu.Item.RequestDesktop -> is ToolbarMenu.Item.RequestDesktop ->
if (item.isChecked) { if (item.isChecked) {
Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_ON Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_ON

@ -34,6 +34,7 @@ import mozilla.components.feature.webcompat.reporter.WebCompatReporterFeature
import mozilla.components.lib.state.ext.flowScoped import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.android.content.getColorFromAttr import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.accounts.FenixAccountManager import org.mozilla.fenix.components.accounts.FenixAccountManager
import org.mozilla.fenix.experiments.ExperimentBranch import org.mozilla.fenix.experiments.ExperimentBranch
@ -308,6 +309,14 @@ open class DefaultToolbarMenu(
onItemTapped.invoke(ToolbarMenu.Item.Settings) onItemTapped.invoke(ToolbarMenu.Item.Settings)
} }
val customizeHomeItem = BrowserMenuImageText(
label = context.getString(R.string.browser_menu_customize_home),
imageResource = R.drawable.ic_customize,
iconTintColorResource = primaryTextColor()
) {
onItemTapped.invoke(ToolbarMenu.Item.CustomizeHome)
}
val bookmarksItem = BrowserMenuImageTextCheckboxButton( val bookmarksItem = BrowserMenuImageTextCheckboxButton(
imageResource = R.drawable.ic_bookmarks_menu, imageResource = R.drawable.ic_bookmarks_menu,
iconTintColorResource = primaryTextColor(), iconTintColorResource = primaryTextColor(),
@ -372,6 +381,7 @@ open class DefaultToolbarMenu(
addToTopSitesItem, addToTopSitesItem,
saveToCollectionItem, saveToCollectionItem,
BrowserMenuDivider(), BrowserMenuDivider(),
if (FeatureFlags.customizeHome) customizeHomeItem else null,
settingsItem, settingsItem,
if (shouldDeleteDataOnQuit) deleteDataOnQuit else null, if (shouldDeleteDataOnQuit) deleteDataOnQuit else null,
if (shouldUseBottomToolbar) BrowserMenuDivider() else null, if (shouldUseBottomToolbar) BrowserMenuDivider() else null,

@ -34,6 +34,7 @@ interface ToolbarMenu {
object History : Item() object History : Item()
object Downloads : Item() object Downloads : Item()
object NewTab : Item() object NewTab : Item()
object CustomizeHome : Item()
} }
val menuBuilder: BrowserMenuBuilder val menuBuilder: BrowserMenuBuilder

@ -257,7 +257,7 @@ class HomeFragment : Fragment() {
view = binding.root view = binding.root
) )
if (FeatureFlags.showRecentTabsFeature) { if (requireContext().settings().showRecentTabsFeature) {
recentTabsListFeature.set( recentTabsListFeature.set(
feature = RecentTabsListFeature( feature = RecentTabsListFeature(
browserStore = components.core.store, browserStore = components.core.store,
@ -268,7 +268,7 @@ class HomeFragment : Fragment() {
) )
} }
if (FeatureFlags.recentBookmarksFeature) { if (requireContext().settings().showRecentBookmarksFeature) {
recentBookmarksFeature.set( recentBookmarksFeature.set(
feature = RecentBookmarksFeature( feature = RecentBookmarksFeature(
homeStore = homeFragmentStore, homeStore = homeFragmentStore,
@ -853,6 +853,13 @@ class HomeFragment : Fragment() {
) )
requireComponents.analytics.metrics.track(Event.HomeMenuSettingsItemClicked) requireComponents.analytics.metrics.track(Event.HomeMenuSettingsItemClicked)
} }
HomeMenu.Item.CustomizeHome -> {
hideOnboardingIfNeeded()
nav(
R.id.homeFragment,
HomeFragmentDirections.actionGlobalCustomizationFragment()
)
}
is HomeMenu.Item.SyncAccount -> { is HomeMenu.Item.SyncAccount -> {
hideOnboardingIfNeeded() hideOnboardingIfNeeded()
val directions = when (it.accountState) { val directions = when (it.accountState) {

@ -23,6 +23,7 @@ import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.AuthType
import mozilla.components.concept.sync.OAuthAccount import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.support.ktx.android.content.getColorFromAttr import mozilla.components.support.ktx.android.content.getColorFromAttr
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.accounts.AccountState import org.mozilla.fenix.components.accounts.AccountState
import org.mozilla.fenix.components.accounts.FenixAccountManager import org.mozilla.fenix.components.accounts.FenixAccountManager
@ -49,6 +50,7 @@ class HomeMenu(
data class SyncAccount(val accountState: AccountState) : Item() data class SyncAccount(val accountState: AccountState) : Item()
object WhatsNew : Item() object WhatsNew : Item()
object Help : Item() object Help : Item()
object CustomizeHome : Item()
object Settings : Item() object Settings : Item()
object Quit : Item() object Quit : Item()
object ReconnectSync : Item() object ReconnectSync : Item()
@ -167,6 +169,14 @@ class HomeMenu(
onItemTapped.invoke(Item.Help) onItemTapped.invoke(Item.Help)
} }
val customizeHomeItem = BrowserMenuImageText(
context.getString(R.string.browser_menu_customize_home),
R.drawable.ic_customize,
primaryTextColor
) {
onItemTapped.invoke(Item.CustomizeHome)
}
// Use nimbus to set the icon and title. // Use nimbus to set the icon and title.
val variables = experiments.getVariables(FeatureId.NIMBUS_VALIDATION) val variables = experiments.getVariables(FeatureId.NIMBUS_VALIDATION)
val settingsItem = BrowserMenuImageText( val settingsItem = BrowserMenuImageText(
@ -200,6 +210,7 @@ class HomeMenu(
BrowserMenuDivider(), BrowserMenuDivider(),
whatsNewItem, whatsNewItem,
helpItem, helpItem,
if (FeatureFlags.customizeHome) customizeHomeItem else null,
settingsItem, settingsItem,
if (settings.shouldDeleteBrowsingDataOnQuit) quitItem else null if (settings.shouldDeleteBrowsingDataOnQuit) quitItem else null
).also { items -> ).also { items ->

@ -144,6 +144,30 @@ class CustomizationFragment : PreferenceFragmentCompat() {
isChecked = context.settings().showTopFrecentSites isChecked = context.settings().showTopFrecentSites
onPreferenceChangeListener = SharedPreferenceUpdater() onPreferenceChangeListener = SharedPreferenceUpdater()
} }
requirePreference<SwitchPreference>(R.string.pref_key_recent_tabs).apply {
isVisible = FeatureFlags.showRecentTabsFeature
isChecked = context.settings().showRecentTabsFeature
onPreferenceChangeListener = SharedPreferenceUpdater()
}
requirePreference<SwitchPreference>(R.string.pref_key_recent_bookmarks).apply {
isVisible = FeatureFlags.recentBookmarksFeature
isChecked = context.settings().showRecentBookmarksFeature
onPreferenceChangeListener = SharedPreferenceUpdater()
}
requirePreference<SwitchPreference>(R.string.pref_key_pocket_homescreen_recommendations).apply {
isVisible = false
isChecked = context.settings().pocketRecommendations
onPreferenceChangeListener = SharedPreferenceUpdater()
}
requirePreference<SwitchPreference>(R.string.pref_key_history_metadata_feature).apply {
isVisible = FeatureFlags.historyMetadataUIFeature
isChecked = context.settings().historyMetadataUIFeature
onPreferenceChangeListener = SharedPreferenceUpdater()
}
} }
private fun setupGesturesCategory() { private fun setupGesturesCategory() {

@ -1107,6 +1107,26 @@ class Settings(private val appContext: Context) : PreferencesHolder {
featureFlag = FeatureFlags.historyMetadataUIFeature || isHistoryMetadataEnabled featureFlag = FeatureFlags.historyMetadataUIFeature || isHistoryMetadataEnabled
) )
/**
* Indicates if the recent tabs functionality should be visible.
* Returns true if the [FeatureFlags.showRecentTabsFeature] and [R.string.pref_key_recent_tabs] are true.
*/
var showRecentTabsFeature by featureFlagPreference(
appContext.getPreferenceKey(R.string.pref_key_recent_tabs),
default = FeatureFlags.showRecentTabsFeature,
featureFlag = FeatureFlags.showRecentTabsFeature
)
/**
* Indicates if the recent saved bookmarks functionality should be visible.
* Returns true if the [FeatureFlags.showRecentTabsFeature] and [R.string.pref_key_recent_bookmarks] are true.
*/
var showRecentBookmarksFeature by featureFlagPreference(
appContext.getPreferenceKey(R.string.pref_key_recent_bookmarks),
default = FeatureFlags.recentBookmarksFeature,
featureFlag = FeatureFlags.recentBookmarksFeature
)
/** /**
* Storing desktop item checkbox value in the home screen menu. * Storing desktop item checkbox value in the home screen menu.
* If set to true, next opened tab from home screen will be opened in desktop mode. * If set to true, next opened tab from home screen will be opened in desktop mode.

@ -57,6 +57,9 @@
<action <action
android:id="@+id/action_global_settingsFragment" android:id="@+id/action_global_settingsFragment"
app:destination="@id/settingsFragment" /> app:destination="@id/settingsFragment" />
<action
android:id="@+id/action_global_customizationFragment"
app:destination="@id/customizationFragment" />
<action <action
android:id="@+id/action_global_privateBrowsingFragment" android:id="@+id/action_global_privateBrowsingFragment"
app:destination="@id/privateBrowsingFragment" /> app:destination="@id/privateBrowsingFragment" />
@ -199,6 +202,9 @@
<action <action
android:id="@+id/action_browserFragment_to_settingsFragment" android:id="@+id/action_browserFragment_to_settingsFragment"
app:destination="@id/settingsFragment" /> app:destination="@id/settingsFragment" />
<action
android:id="@+id/action_browserFragment_to_customFragment"
app:destination="@id/customizationFragment" />
<action <action
android:id="@+id/action_browserFragment_to_createShortcutFragment" android:id="@+id/action_browserFragment_to_createShortcutFragment"
app:destination="@id/createShortcutFragment" /> app:destination="@id/createShortcutFragment" />

@ -147,6 +147,8 @@
<string name="pref_key_dynamic_toolbar" translatable="false">pref_key_dynamic_toolbar</string> <string name="pref_key_dynamic_toolbar" translatable="false">pref_key_dynamic_toolbar</string>
<string name="pref_key_swipe_toolbar_switch_tabs" translatable="false">pref_key_swipe_toolbar_switch_tabs</string> <string name="pref_key_swipe_toolbar_switch_tabs" translatable="false">pref_key_swipe_toolbar_switch_tabs</string>
<string name="pref_key_swipe_toolbar_show_tabs" translatable="false">pref_key_swipe_toolbar_show_tabs</string> <string name="pref_key_swipe_toolbar_show_tabs" translatable="false">pref_key_swipe_toolbar_show_tabs</string>
<string name="pref_key_recent_tabs" translatable="false">pref_key_recent_tabs</string>
<string name="pref_key_recent_bookmarks" translatable="false">pref_key_recent_bookmarks</string>
<!-- Tracking Protection Settings --> <!-- Tracking Protection Settings -->
<string name="pref_key_etp_learn_more" translatable="false">pref_key_etp_learn_more</string> <string name="pref_key_etp_learn_more" translatable="false">pref_key_etp_learn_more</string>

@ -194,7 +194,8 @@
<string name="browser_menu_add">Add</string> <string name="browser_menu_add">Add</string>
<!-- Browser menu label for editing a bookmark --> <!-- Browser menu label for editing a bookmark -->
<string name="browser_menu_edit">Edit</string> <string name="browser_menu_edit">Edit</string>
<!-- Browser menu button that opens the Customize menu -->
<string name="browser_menu_customize_home">Customize home</string>
<!-- Browser Toolbar --> <!-- Browser Toolbar -->
<!-- Content description for the Home screen button on the browser toolbar --> <!-- Content description for the Home screen button on the browser toolbar -->
<string name="browser_toolbar_home">Home screen</string> <string name="browser_toolbar_home">Home screen</string>
@ -382,6 +383,16 @@
<!-- Toast shown after confirming the custom add-on collection configuration --> <!-- Toast shown after confirming the custom add-on collection configuration -->
<string name="toast_customize_addon_collection_done">Add-on collection modified. Quitting the application to apply changes…</string> <string name="toast_customize_addon_collection_done">Add-on collection modified. Quitting the application to apply changes…</string>
<!-- Customize Home -->
<!-- Header text for jumping back into the recent tab in customize the home screen -->
<string name="customize_toggle_jump_back_in">Jump back in</string>
<!-- Title for the customize home screen section with recently saved bookmarks. -->
<string name="customize_toggle_recently_saved_bookmarks">Recently saved</string>
<!-- Title for the customize home screen section with recently visited. -->
<string name="customize_toggle_recently_visited">Recently visited</string>
<!-- Title for the customize home screen section with pocket. -->
<string name="customize_toggle_pocket">Pocket</string>
<!-- Add-on Installation from AMO--> <!-- Add-on Installation from AMO-->
<!-- Error displayed when user attempts to install an add-on from AMO (addons.mozilla.org) that is not supported --> <!-- Error displayed when user attempts to install an add-on from AMO (addons.mozilla.org) that is not supported -->
<string name="addon_not_supported_error">Add-on is not supported</string> <string name="addon_not_supported_error">Add-on is not supported</string>
@ -1810,8 +1821,10 @@
<string name="top_sites_max_limit_content_2">To add a new top site, remove one. Touch and hold the site and select remove.</string> <string name="top_sites_max_limit_content_2">To add a new top site, remove one. Touch and hold the site and select remove.</string>
<!-- Confirmation dialog button text when top sites limit is reached. --> <!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">OK, Got It</string> <string name="top_sites_max_limit_confirmation_button">OK, Got It</string>
<!-- Label for the show most visited top sites preference -->
<string name="top_sites_toggle_top_frecent_sites_2">Show most visited top sites</string>
<!-- Label for the show most visited sites preference --> <!-- Label for the show most visited sites preference -->
<string name="top_sites_toggle_top_frecent_sites">Show most visited sites</string> <string name="top_sites_toggle_top_frecent_sites" moz:removedIn="93" tools:ignore="UnusedResources">Show most visited sites</string>
<!-- Title text displayed in the rename top site dialog. --> <!-- Title text displayed in the rename top site dialog. -->
<string name="top_sites_rename_dialog_title">Name</string> <string name="top_sites_rename_dialog_title">Name</string>
<!-- Hint for renaming title of a top site --> <!-- Hint for renaming title of a top site -->

@ -49,7 +49,27 @@
app:iconSpaceReserved="false"> app:iconSpaceReserved="false">
<androidx.preference.SwitchPreference <androidx.preference.SwitchPreference
android:key="@string/pref_key_enable_top_frecent_sites" android:key="@string/pref_key_enable_top_frecent_sites"
android:title="@string/top_sites_toggle_top_frecent_sites" /> android:title="@string/top_sites_toggle_top_frecent_sites_2" />
<androidx.preference.SwitchPreference
android:key="@string/pref_key_recent_tabs"
android:title="@string/customize_toggle_jump_back_in"
app:isPreferenceVisible="false" />
<androidx.preference.SwitchPreference
android:key="@string/pref_key_recent_bookmarks"
android:title="@string/customize_toggle_recently_saved_bookmarks"
app:isPreferenceVisible="false" />
<androidx.preference.SwitchPreference
android:key="@string/pref_key_history_metadata_feature"
android:title="@string/customize_toggle_recently_visited"
app:isPreferenceVisible="false" />
<androidx.preference.SwitchPreference
android:key="@string/pref_key_pocket_homescreen_recommendations"
android:title="@string/customize_toggle_pocket"
app:isPreferenceVisible="false" />
</androidx.preference.PreferenceCategory> </androidx.preference.PreferenceCategory>
<androidx.preference.PreferenceCategory <androidx.preference.PreferenceCategory

@ -337,6 +337,18 @@ class DefaultBrowserToolbarMenuControllerTest {
verify { navController.navigate(directions, null) } verify { navController.navigate(directions, null) }
} }
@Test
fun `WHEN CustomizeHome menu item is pressed THEN menu item is handled`() = runBlockingTest {
val item = ToolbarMenu.Item.CustomizeHome
val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item)
val directions = BrowserFragmentDirections.actionBrowserFragmentToCustomFragment()
verify { navController.navigate(directions, null) }
}
@Test @Test
fun `WHEN bookmark menu item is pressed THEN navigate to bookmarks page`() = runBlockingTest { fun `WHEN bookmark menu item is pressed THEN navigate to bookmarks page`() = runBlockingTest {
val item = ToolbarMenu.Item.Bookmarks val item = ToolbarMenu.Item.Bookmarks

Loading…
Cancel
Save