2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-15 18:12:54 +00:00

For #23431 - Display the order of Contile Top Sites correctly

This commit is contained in:
Gabriel Luong 2022-02-07 17:11:37 -05:00 committed by mergify[bot]
parent 6c59fd424b
commit 37a0edceb6
7 changed files with 182 additions and 12 deletions

View File

@ -36,6 +36,7 @@ import mozilla.components.feature.addons.update.GlobalAddonDependencyProvider
import mozilla.components.feature.autofill.AutofillUseCases import mozilla.components.feature.autofill.AutofillUseCases
import mozilla.components.feature.search.ext.buildSearchUrl import mozilla.components.feature.search.ext.buildSearchUrl
import mozilla.components.feature.search.ext.waitForSelectedOrDefaultSearchEngine import mozilla.components.feature.search.ext.waitForSelectedOrDefaultSearchEngine
import mozilla.components.feature.top.sites.TopSitesProviderConfig
import mozilla.components.lib.crash.CrashReporter import mozilla.components.lib.crash.CrashReporter
import mozilla.components.service.fxa.manager.SyncEnginesStorage import mozilla.components.service.fxa.manager.SyncEnginesStorage
import mozilla.components.service.glean.Glean import mozilla.components.service.glean.Glean
@ -82,6 +83,7 @@ import org.mozilla.fenix.session.VisibilityLifecycleCallback
import org.mozilla.fenix.telemetry.TelemetryLifecycleObserver import org.mozilla.fenix.telemetry.TelemetryLifecycleObserver
import org.mozilla.fenix.utils.BrowsersCache import org.mozilla.fenix.utils.BrowsersCache
import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.utils.Settings
import org.mozilla.fenix.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
/** /**
@ -258,11 +260,14 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
// we can prevent with this. // we can prevent with this.
components.core.topSitesStorage.getTopSites( components.core.topSitesStorage.getTopSites(
totalSites = components.settings.topSitesMaxLimit, totalSites = components.settings.topSitesMaxLimit,
fetchProvidedTopSites = components.settings.showContileFeature,
frecencyConfig = if (components.settings.showTopFrecentSites) frecencyConfig = if (components.settings.showTopFrecentSites)
FrecencyThresholdOption.SKIP_ONE_TIME_PAGES FrecencyThresholdOption.SKIP_ONE_TIME_PAGES
else else
null null,
providerConfig = TopSitesProviderConfig(
showProviderTopSites = components.settings.showContileFeature,
maxThreshold = TOP_SITES_PROVIDER_MAX_THRESHOLD
)
) )
// This service uses `historyStorage`, and so we can only touch it when we know // This service uses `historyStorage`, and so we can only touch it when we know

View File

@ -5,6 +5,7 @@
package org.mozilla.fenix.ext package org.mozilla.fenix.ext
import mozilla.components.feature.top.sites.TopSite import mozilla.components.feature.top.sites.TopSite
import org.mozilla.fenix.settings.SupportUtils
/** /**
* Returns the type name of the [TopSite]. * Returns the type name of the [TopSite].
@ -15,3 +16,22 @@ fun TopSite.name(): String = when (this) {
is TopSite.Pinned -> "PINNED" is TopSite.Pinned -> "PINNED"
is TopSite.Provided -> "PROVIDED" is TopSite.Provided -> "PROVIDED"
} }
/**
* Returns a sorted list of [TopSite] with the default Google top site always appearing
* as the first item.
*/
fun List<TopSite>.sort(): List<TopSite> {
val defaultGoogleTopSiteIndex = this.indexOfFirst {
it is TopSite.Default && it.url == SupportUtils.GOOGLE_URL
}
return if (defaultGoogleTopSiteIndex == -1) {
this
} else {
val result = this.toMutableList()
result.removeAt(defaultGoogleTopSiteIndex)
result.add(0, this[defaultGoogleTopSiteIndex])
result
}
}

View File

@ -66,6 +66,7 @@ import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.top.sites.TopSitesConfig import mozilla.components.feature.top.sites.TopSitesConfig
import mozilla.components.feature.top.sites.TopSitesFeature import mozilla.components.feature.top.sites.TopSitesFeature
import mozilla.components.feature.top.sites.TopSitesProviderConfig
import mozilla.components.lib.state.ext.consumeFlow import mozilla.components.lib.state.ext.consumeFlow
import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
@ -102,6 +103,7 @@ import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.runIfFragmentIsAttached import org.mozilla.fenix.ext.runIfFragmentIsAttached
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.sort
import org.mozilla.fenix.home.mozonline.showPrivacyPopWindow import org.mozilla.fenix.home.mozonline.showPrivacyPopWindow
import org.mozilla.fenix.home.pocket.DefaultPocketStoriesController import org.mozilla.fenix.home.pocket.DefaultPocketStoriesController
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesCategory import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesCategory
@ -124,6 +126,7 @@ import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.SupportUtils.SumoTopic.HELP import org.mozilla.fenix.settings.SupportUtils.SumoTopic.HELP
import org.mozilla.fenix.settings.deletebrowsingdata.deleteAndQuit import org.mozilla.fenix.settings.deletebrowsingdata.deleteAndQuit
import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.utils.Settings.Companion.TOP_SITES_PROVIDER_MAX_THRESHOLD
import org.mozilla.fenix.utils.ToolbarPopupWindow import org.mozilla.fenix.utils.ToolbarPopupWindow
import org.mozilla.fenix.utils.allowUndo import org.mozilla.fenix.utils.allowUndo
import org.mozilla.fenix.wallpapers.WallpaperManager import org.mozilla.fenix.wallpapers.WallpaperManager
@ -237,7 +240,7 @@ class HomeFragment : Fragment() {
collections = components.core.tabCollectionStorage.cachedTabCollections, collections = components.core.tabCollectionStorage.cachedTabCollections,
expandedCollections = emptySet(), expandedCollections = emptySet(),
mode = currentMode.getCurrentMode(), mode = currentMode.getCurrentMode(),
topSites = components.core.topSitesStorage.cachedTopSites, topSites = components.core.topSitesStorage.cachedTopSites.sort(),
tip = components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) { tip = components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
FenixTipManager( FenixTipManager(
listOf( listOf(
@ -282,7 +285,10 @@ class HomeFragment : Fragment() {
topSitesFeature.set( topSitesFeature.set(
feature = TopSitesFeature( feature = TopSitesFeature(
view = DefaultTopSitesView(homeFragmentStore), view = DefaultTopSitesView(
store = homeFragmentStore,
settings = components.settings
),
storage = components.core.topSitesStorage, storage = components.core.topSitesStorage,
config = ::getTopSitesConfig config = ::getTopSitesConfig
), ),
@ -421,8 +427,11 @@ class HomeFragment : Fragment() {
val settings = requireContext().settings() val settings = requireContext().settings()
return TopSitesConfig( return TopSitesConfig(
totalSites = settings.topSitesMaxLimit, totalSites = settings.topSitesMaxLimit,
fetchProvidedTopSites = settings.showContileFeature, frecencyConfig = if (settings.showTopFrecentSites) FrecencyThresholdOption.SKIP_ONE_TIME_PAGES else null,
frecencyConfig = if (settings.showTopFrecentSites) FrecencyThresholdOption.SKIP_ONE_TIME_PAGES else null providerConfig = TopSitesProviderConfig(
showProviderTopSites = settings.showContileFeature,
maxThreshold = TOP_SITES_PROVIDER_MAX_THRESHOLD
)
) )
} }
@ -690,7 +699,7 @@ class HomeFragment : Fragment() {
HomeFragmentAction.Change( HomeFragmentAction.Change(
collections = components.core.tabCollectionStorage.cachedTabCollections, collections = components.core.tabCollectionStorage.cachedTabCollections,
mode = currentMode.getCurrentMode(), mode = currentMode.getCurrentMode(),
topSites = components.core.topSitesStorage.cachedTopSites, topSites = components.core.topSitesStorage.cachedTopSites.sort(),
tip = components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) { tip = components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
FenixTipManager( FenixTipManager(
listOf( listOf(

View File

@ -6,14 +6,25 @@ package org.mozilla.fenix.home.topsites
import mozilla.components.feature.top.sites.TopSite import mozilla.components.feature.top.sites.TopSite
import mozilla.components.feature.top.sites.view.TopSitesView import mozilla.components.feature.top.sites.view.TopSitesView
import org.mozilla.fenix.ext.sort
import org.mozilla.fenix.home.HomeFragmentAction import org.mozilla.fenix.home.HomeFragmentAction
import org.mozilla.fenix.home.HomeFragmentStore import org.mozilla.fenix.home.HomeFragmentStore
import org.mozilla.fenix.utils.Settings
class DefaultTopSitesView( class DefaultTopSitesView(
val store: HomeFragmentStore val store: HomeFragmentStore,
val settings: Settings
) : TopSitesView { ) : TopSitesView {
override fun displayTopSites(topSites: List<TopSite>) { override fun displayTopSites(topSites: List<TopSite>) {
store.dispatch(HomeFragmentAction.TopSitesChange(topSites)) store.dispatch(
HomeFragmentAction.TopSitesChange(
if (!settings.showContileFeature) {
topSites
} else {
topSites.sort()
}
)
)
} }
} }

View File

@ -18,6 +18,7 @@ import androidx.lifecycle.LifecycleOwner
import mozilla.components.feature.sitepermissions.SitePermissionsRules import mozilla.components.feature.sitepermissions.SitePermissionsRules
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action
import mozilla.components.feature.sitepermissions.SitePermissionsRules.AutoplayAction import mozilla.components.feature.sitepermissions.SitePermissionsRules.AutoplayAction
import mozilla.components.service.contile.ContileTopSitesProvider
import mozilla.components.support.ktx.android.content.PreferencesHolder import mozilla.components.support.ktx.android.content.PreferencesHolder
import mozilla.components.support.ktx.android.content.booleanPreference import mozilla.components.support.ktx.android.content.booleanPreference
import mozilla.components.support.ktx.android.content.floatPreference import mozilla.components.support.ktx.android.content.floatPreference
@ -61,7 +62,6 @@ private const val AUTOPLAY_USER_SETTING = "AUTOPLAY_USER_SETTING"
class Settings(private val appContext: Context) : PreferencesHolder { class Settings(private val appContext: Context) : PreferencesHolder {
companion object { companion object {
const val topSitesMaxCount = 16
const val FENIX_PREFERENCES = "fenix_preferences" const val FENIX_PREFERENCES = "fenix_preferences"
private const val BLOCKED_INT = 0 private const val BLOCKED_INT = 0
@ -84,6 +84,14 @@ class Settings(private val appContext: Context) : PreferencesHolder {
*/ */
const val SEARCH_GROUP_MINIMUM_SITES: Int = 2 const val SEARCH_GROUP_MINIMUM_SITES: Int = 2
// The maximum number of top sites to display.
const val TOP_SITES_MAX_COUNT = 16
/**
* Only fetch top sites from the [ContileTopSitesProvider] when the number of default and
* pinned sites are below this maximum threshold.
*/
const val TOP_SITES_PROVIDER_MAX_THRESHOLD = 8
private fun Action.toInt() = when (this) { private fun Action.toInt() = when (this) {
Action.BLOCKED -> BLOCKED_INT Action.BLOCKED -> BLOCKED_INT
Action.ASK_TO_ALLOW -> ASK_TO_ALLOW_INT Action.ASK_TO_ALLOW -> ASK_TO_ALLOW_INT
@ -1122,7 +1130,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {
val topSitesMaxLimit by intPreference( val topSitesMaxLimit by intPreference(
appContext.getPreferenceKey(R.string.pref_key_top_sites_max_limit), appContext.getPreferenceKey(R.string.pref_key_top_sites_max_limit),
default = topSitesMaxCount default = TOP_SITES_MAX_COUNT
) )
var openTabsCount by intPreference( var openTabsCount by intPreference(

View File

@ -0,0 +1,117 @@
/* 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.ext
import mozilla.components.feature.top.sites.TopSite
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.settings.SupportUtils
@RunWith(FenixRobolectricTestRunner::class)
class TopSiteTest {
val defaultGoogleTopSite = TopSite.Default(
id = 1L,
title = "Google",
url = SupportUtils.GOOGLE_URL,
createdAt = 0
)
val providedSite1 = TopSite.Provided(
id = 3,
title = "Mozilla",
url = "https://mozilla.com",
clickUrl = "https://mozilla.com/click",
imageUrl = "https://test.com/image2.jpg",
impressionUrl = "https://example.com",
createdAt = 3
)
val providedSite2 = TopSite.Provided(
id = 3,
title = "Firefox",
url = "https://firefox.com",
clickUrl = "https://firefox.com/click",
imageUrl = "https://test.com/image2.jpg",
impressionUrl = "https://example.com",
createdAt = 3
)
val pinnedSite1 = TopSite.Pinned(
id = 1L,
title = "DuckDuckGo",
url = "https://duckduckgo.com",
createdAt = 0
)
val pinnedSite2 = TopSite.Pinned(
id = 1L,
title = "Mozilla",
url = "mozilla.org",
createdAt = 0
)
val frecentSite = TopSite.Frecent(
id = 1L,
title = "Mozilla",
url = "mozilla.org",
createdAt = 0
)
@Test
fun `GIVEN the default Google top site is the first item WHEN the list of top sites is sorted THEN the order doesn't change`() {
val topSites = listOf(
defaultGoogleTopSite,
providedSite1,
providedSite2,
pinnedSite1,
pinnedSite2,
frecentSite
)
assertEquals(topSites.sort(), topSites)
}
@Test
fun `GIVEN the default Google top site is after the provided top sites WHEN the list of top sites is sorted THEN the default Google top site should be first`() {
val topSites = listOf(
providedSite1,
providedSite2,
defaultGoogleTopSite,
pinnedSite1,
pinnedSite2,
frecentSite
)
val expected = listOf(
defaultGoogleTopSite,
providedSite1,
providedSite2,
pinnedSite1,
pinnedSite2,
frecentSite
)
assertEquals(topSites.sort(), expected)
}
@Test
fun `GIVEN the default Google top site is the last item WHEN the list of top sites is sorted THEN the default Google top site should be first`() {
val topSites = listOf(
providedSite1,
providedSite2,
pinnedSite1,
pinnedSite2,
frecentSite,
defaultGoogleTopSite
)
val expected = listOf(
defaultGoogleTopSite,
providedSite1,
providedSite2,
pinnedSite1,
pinnedSite2,
frecentSite
)
assertEquals(topSites.sort(), expected)
}
}

View File

@ -3,5 +3,5 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
object AndroidComponents { object AndroidComponents {
const val VERSION = "99.0.20220209143350" const val VERSION = "99.0.20220209170927"
} }