1
0
Fork 0

For #8126 - Adds default top sites

master
ekager 2020-02-13 20:08:05 -08:00 committed by Emily Kager
parent 2e1202cbd1
commit b72550c28a
12 changed files with 138 additions and 5 deletions

View File

@ -1765,3 +1765,27 @@ app_theme:
notification_emails: notification_emails:
- fenix-core@mozilla.com - fenix-core@mozilla.com
expires: "2020-09-01" expires: "2020-09-01"
pocket:
pocket_top_site_clicked:
type: event
description: >
A user clicked on the trending Pocket top site
bugs:
- https://github.com/mozilla-mobile/fenix/issues/8126
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/8098
notification_emails:
- fenix-core@mozilla.com
expires: "2020-09-01"
pocket_top_site_removed:
type: event
description: >
A user removed the trending Pocket top site
bugs:
- https://github.com/mozilla-mobile/fenix/issues/8126
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/8098
notification_emails:
- fenix-core@mozilla.com
expires: "2020-09-01"

View File

@ -6,8 +6,17 @@ package org.mozilla.fenix.components
import android.content.Context import android.content.Context
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import mozilla.components.feature.top.sites.TopSite import mozilla.components.feature.top.sites.TopSite
import mozilla.components.feature.top.sites.TopSiteStorage import mozilla.components.feature.top.sites.TopSiteStorage
import mozilla.components.support.locale.LocaleManager
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.advanced.getSelectedLocale
import org.mozilla.fenix.test.Mockable import org.mozilla.fenix.test.Mockable
@Mockable @Mockable
@ -18,6 +27,10 @@ class TopSiteStorage(private val context: Context) {
TopSiteStorage(context) TopSiteStorage(context)
} }
init {
addDefaultTopSites()
}
/** /**
* Adds a new [TopSite]. * Adds a new [TopSite].
*/ */
@ -38,4 +51,42 @@ class TopSiteStorage(private val context: Context) {
fun removeTopSite(topSite: TopSite) { fun removeTopSite(topSite: TopSite) {
storage.removeTopSite(topSite) storage.removeTopSite(topSite)
} }
private fun addDefaultTopSites() {
val topSiteCandidates = mutableListOf<Pair<String, String>>()
if (!context.settings().defaultTopSitesAdded) {
if (LocaleManager.getSelectedLocale(context).language == "en") {
topSiteCandidates.add(
Pair(
context.getString(R.string.pocket_pinned_top_articles),
SupportUtils.POCKET_TRENDING_URL
)
)
}
topSiteCandidates.add(
Pair(
context.getString(R.string.default_top_site_wikipedia),
SupportUtils.WIKIPEDIA_URL
)
)
topSiteCandidates.add(
Pair(
context.getString(R.string.default_top_site_youtube),
SupportUtils.YOUTUBE_URL
)
)
GlobalScope.launch(Dispatchers.Main) {
withContext(Dispatchers.IO) {
topSiteCandidates.forEach {
addTopSite(it.first, it.second)
}
}
}
context.settings().preferences.edit()
.putBoolean(context.getString(R.string.default_top_sites_added), true).apply()
}
}
} }

View File

@ -29,6 +29,7 @@ import org.mozilla.fenix.GleanMetrics.MediaNotification
import org.mozilla.fenix.GleanMetrics.MediaState import org.mozilla.fenix.GleanMetrics.MediaState
import org.mozilla.fenix.GleanMetrics.Metrics import org.mozilla.fenix.GleanMetrics.Metrics
import org.mozilla.fenix.GleanMetrics.Pings import org.mozilla.fenix.GleanMetrics.Pings
import org.mozilla.fenix.GleanMetrics.Pocket
import org.mozilla.fenix.GleanMetrics.PrivateBrowsingMode import org.mozilla.fenix.GleanMetrics.PrivateBrowsingMode
import org.mozilla.fenix.GleanMetrics.PrivateBrowsingShortcut import org.mozilla.fenix.GleanMetrics.PrivateBrowsingShortcut
import org.mozilla.fenix.GleanMetrics.QrScanner import org.mozilla.fenix.GleanMetrics.QrScanner
@ -483,6 +484,12 @@ private val Event.wrapper: EventWrapper<*>?
is Event.LibrariesThatWeUseTapped -> EventWrapper<NoExtraKeys>( is Event.LibrariesThatWeUseTapped -> EventWrapper<NoExtraKeys>(
{ AboutPage.librariesTapped.record(it) } { AboutPage.librariesTapped.record(it) }
) )
is Event.PocketTopSiteClicked -> EventWrapper<NoExtraKeys>(
{ Pocket.pocketTopSiteClicked.record(it) }
)
is Event.PocketTopSiteRemoved -> EventWrapper<NoExtraKeys>(
{ Pocket.pocketTopSiteRemoved.record(it) }
)
is Event.DarkThemeSelected -> EventWrapper( is Event.DarkThemeSelected -> EventWrapper(
{ AppTheme.darkThemeSelected.record(it) }, { AppTheme.darkThemeSelected.record(it) },
{ AppTheme.darkThemeSelectedKeys.valueOf(it) } { AppTheme.darkThemeSelectedKeys.valueOf(it) }

View File

@ -149,6 +149,8 @@ sealed class Event {
object RightsTapped : Event() object RightsTapped : Event()
object LicensingTapped : Event() object LicensingTapped : Event()
object LibrariesThatWeUseTapped : Event() object LibrariesThatWeUseTapped : Event()
object PocketTopSiteClicked : Event()
object PocketTopSiteRemoved : Event()
object FennecToFenixMigrated : Event() object FennecToFenixMigrated : Event()
// Interaction events with extras // Interaction events with extras

View File

@ -17,7 +17,6 @@ import mozilla.components.feature.media.ext.playIfPaused
import mozilla.components.feature.media.state.MediaStateMachine import mozilla.components.feature.media.state.MediaStateMachine
import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.top.sites.TopSite import mozilla.components.feature.top.sites.TopSite
import mozilla.components.feature.tab.collections.Tab as ComponentTab
import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
@ -26,9 +25,9 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.collections.SaveCollectionStep import org.mozilla.fenix.collections.SaveCollectionStep
import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.TopSiteStorage import org.mozilla.fenix.components.TopSiteStorage
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.sessionsOfType import org.mozilla.fenix.ext.sessionsOfType
import org.mozilla.fenix.home.HomeFragment import org.mozilla.fenix.home.HomeFragment
@ -37,6 +36,7 @@ import org.mozilla.fenix.home.HomeFragmentDirections
import org.mozilla.fenix.home.HomeFragmentStore import org.mozilla.fenix.home.HomeFragmentStore
import org.mozilla.fenix.home.Tab import org.mozilla.fenix.home.Tab
import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.settings.SupportUtils
import mozilla.components.feature.tab.collections.Tab as ComponentTab
/** /**
* [HomeFragment] controller. An interface that handles the view manipulation of the Tabs triggered * [HomeFragment] controller. An interface that handles the view manipulation of the Tabs triggered
@ -294,6 +294,9 @@ class DefaultSessionControlController(
override fun handleRemoveTopSiteClicked(topSite: TopSite) { override fun handleRemoveTopSiteClicked(topSite: TopSite) {
metrics.track(Event.TopSiteRemoved) metrics.track(Event.TopSiteRemoved)
if (topSite.url == SupportUtils.POCKET_TRENDING_URL) {
metrics.track(Event.PocketTopSiteRemoved)
}
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
topSiteStorage.removeTopSite(topSite) topSiteStorage.removeTopSite(topSite)
@ -335,7 +338,8 @@ class DefaultSessionControlController(
val directions = HomeFragmentDirections.actionHomeFragmentToBrowserFragment(null) val directions = HomeFragmentDirections.actionHomeFragmentToBrowserFragment(null)
val extras = val extras =
FragmentNavigator.Extras.Builder() FragmentNavigator.Extras.Builder()
.addSharedElement(tabView, .addSharedElement(
tabView,
"$TAB_ITEM_TRANSITION_NAME$sessionId" "$TAB_ITEM_TRANSITION_NAME$sessionId"
) )
.build() .build()
@ -344,6 +348,9 @@ class DefaultSessionControlController(
override fun handleSelectTopSite(url: String) { override fun handleSelectTopSite(url: String) {
metrics.track(Event.TopSiteOpenInNewTab) metrics.track(Event.TopSiteOpenInNewTab)
if (url == SupportUtils.POCKET_TRENDING_URL) {
metrics.track(Event.PocketTopSiteClicked)
}
activity.components.useCases.tabsUseCases.addTab.invoke(url, true, true) activity.components.useCases.tabsUseCases.addTab.invoke(url, true, true)
navController.nav( navController.nav(
R.id.homeFragment, R.id.homeFragment,

View File

@ -8,13 +8,14 @@ import android.content.Context
import android.view.View import android.view.View
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.top_site_item.view.* import kotlinx.android.synthetic.main.top_site_item.view.*
import mozilla.components.feature.top.sites.TopSite
import mozilla.components.browser.menu.BrowserMenuBuilder import mozilla.components.browser.menu.BrowserMenuBuilder
import mozilla.components.browser.menu.item.SimpleBrowserMenuItem import mozilla.components.browser.menu.item.SimpleBrowserMenuItem
import mozilla.components.feature.top.sites.TopSite
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.loadIntoView import org.mozilla.fenix.ext.loadIntoView
import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor
import org.mozilla.fenix.settings.SupportUtils
class TopSiteItemViewHolder( class TopSiteItemViewHolder(
private val view: View, private val view: View,
@ -46,7 +47,14 @@ class TopSiteItemViewHolder(
fun bind(topSite: TopSite) { fun bind(topSite: TopSite) {
this.topSite = topSite this.topSite = topSite
view.top_site_title.text = topSite.title view.top_site_title.text = topSite.title
view.context.components.core.icons.loadIntoView(view.favicon_image, topSite.url) when {
topSite.url == SupportUtils.POCKET_TRENDING_URL -> {
view.favicon_image.setImageDrawable(view.context.getDrawable(R.drawable.ic_pocket))
}
else -> {
view.context.components.core.icons.loadIntoView(view.favicon_image, topSite.url)
}
}
} }
companion object { companion object {

View File

@ -22,7 +22,10 @@ import java.util.Locale
object SupportUtils { object SupportUtils {
const val RATE_APP_URL = "market://details?id=" + BuildConfig.APPLICATION_ID const val RATE_APP_URL = "market://details?id=" + BuildConfig.APPLICATION_ID
const val MOZILLA_MANIFESTO_URL = "https://www.mozilla.org/en-GB/about/manifesto/" const val MOZILLA_MANIFESTO_URL = "https://www.mozilla.org/en-GB/about/manifesto/"
const val POCKET_TRENDING_URL = "https://getpocket.com/fenix-top-articles"
const val WIKIPEDIA_URL = "https://www.wikipedia.org/"
const val FENIX_PLAY_STORE_URL = "https://play.google.com/store/apps/details?id=${BuildConfig.APPLICATION_ID}" const val FENIX_PLAY_STORE_URL = "https://play.google.com/store/apps/details?id=${BuildConfig.APPLICATION_ID}"
const val YOUTUBE_URL = "https://www.youtube.com/"
enum class SumoTopic(internal val topicStr: String) { enum class SumoTopic(internal val topicStr: String) {
HELP("faq-android"), HELP("faq-android"),

View File

@ -339,6 +339,11 @@ class Settings private constructor(
default = true default = true
) )
val defaultTopSitesAdded by booleanPreference(
appContext.getPreferenceKey(R.string.default_top_sites_added),
default = false
)
var shouldShowSearchSuggestionsInPrivate by booleanPreference( var shouldShowSearchSuggestionsInPrivate by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_show_search_suggestions_in_private), appContext.getPreferenceKey(R.string.pref_key_show_search_suggestions_in_private),
default = false default = false

View File

@ -0,0 +1,16 @@
<?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/. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#EF4056"
android:pathData="M21.7684 2H2.31579C1.05263 2 0 2.95079 0 4.19094V11.2598C0 17.6673 5.38947 23 12.0421 23C18.6526 23 24 17.6673 24 11.2598V4.19094C24 2.95079 22.9895 2 21.7684 2Z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M18.5749 10.9349L13.0682 16.52C12.7848 16.8691 12.3394 17 12.0154 17C11.6105 17 11.2056 16.8691 10.8817 16.52L5.45602 10.9349C4.88916 10.2804 4.80818 9.18956 5.45602 8.49142C6.06337 7.88055 7.07563 7.79328 7.68298 8.49142L12.0154 12.9857L16.4289 8.49142C16.9957 7.79328 18.008 7.88055 18.5749 8.49142C19.1417 9.18956 19.1417 10.2804 18.5749 10.9349Z" />
</vector>

View File

@ -136,4 +136,5 @@
<string name="pref_key_testing_stage" translatable="false">pref_key_testing_stage</string> <string name="pref_key_testing_stage" translatable="false">pref_key_testing_stage</string>
<string name="pref_key_encryption_key_generated" translatable="false">pref_key_encryption_key_generated</string> <string name="pref_key_encryption_key_generated" translatable="false">pref_key_encryption_key_generated</string>
<string name="default_top_sites_added" translatable="false">pref_key_pocket_top_site_added</string>
</resources> </resources>

View File

@ -23,4 +23,11 @@
<!-- GeckoView abbreviation used in AboutFragment --> <!-- GeckoView abbreviation used in AboutFragment -->
<string name="gecko_view_abbreviation" translatable="false">GV</string> <string name="gecko_view_abbreviation" translatable="false">GV</string>
<!-- Default title for pinned Pocket top site that links to trending Pocket site -->
<string name="pocket_pinned_top_articles" translatable="false">Top Articles</string>
<!-- Default title for pinned Wikipedia top site that links to Wikipedia home page -->
<string name="default_top_site_wikipedia" translatable="false">Wikipedia</string>
<!-- Default title for pinned YouTube top site that links to Youtube home page -->
<string name="default_top_site_youtube" translatable="false">YouTube</string>
</resources> </resources>

View File

@ -114,6 +114,8 @@ The following metrics are added to the ping:
| media_state.pause |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Media playback was paused. |[1](https://github.com/mozilla-mobile/fenix/pull/6463)||2020-09-01 | | media_state.pause |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Media playback was paused. |[1](https://github.com/mozilla-mobile/fenix/pull/6463)||2020-09-01 |
| media_state.play |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Media started playing. |[1](https://github.com/mozilla-mobile/fenix/pull/6463)||2020-09-01 | | media_state.play |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Media started playing. |[1](https://github.com/mozilla-mobile/fenix/pull/6463)||2020-09-01 |
| media_state.stop |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Media playback has ended. |[1](https://github.com/mozilla-mobile/fenix/pull/6463)||2020-09-01 | | media_state.stop |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Media playback has ended. |[1](https://github.com/mozilla-mobile/fenix/pull/6463)||2020-09-01 |
| pocket.pocket_top_site_clicked |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user clicked on the trending Pocket top site |[1](https://github.com/mozilla-mobile/fenix/pull/8098)||2020-09-01 |
| pocket.pocket_top_site_removed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user removed the trending Pocket top site |[1](https://github.com/mozilla-mobile/fenix/pull/8098)||2020-09-01 |
| private_browsing_mode.garbage_icon |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the garbage can icon on the private browsing home page, deleting all private tabs. |[1](https://github.com/mozilla-mobile/fenix/pull/4968)||2020-09-01 | | private_browsing_mode.garbage_icon |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the garbage can icon on the private browsing home page, deleting all private tabs. |[1](https://github.com/mozilla-mobile/fenix/pull/4968)||2020-09-01 |
| private_browsing_mode.notification_delete |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the private browsing mode notification's "Delete and Open" button. |[1](https://github.com/mozilla-mobile/fenix/pull/4968)||2020-09-01 | | private_browsing_mode.notification_delete |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the private browsing mode notification's "Delete and Open" button. |[1](https://github.com/mozilla-mobile/fenix/pull/4968)||2020-09-01 |
| private_browsing_mode.notification_open |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the private browsing mode notification's "Open" button. |[1](https://github.com/mozilla-mobile/fenix/pull/4968)||2020-09-01 | | private_browsing_mode.notification_open |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the private browsing mode notification's "Open" button. |[1](https://github.com/mozilla-mobile/fenix/pull/4968)||2020-09-01 |