2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-19 09:25:34 +00:00

[fenix] For https://github.com/mozilla-mobile/fenix/issues/24235 - Remove Tip from HomeFragmentStore

This commit is contained in:
Gabriel Luong 2022-03-11 23:05:03 -05:00 committed by mergify[bot]
parent 082705a3c6
commit 13af68853e
17 changed files with 4 additions and 453 deletions

View File

@ -21,7 +21,7 @@ import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.HomeActivityTestRule
// BEFORE INCREASING THESE VALUES, PLEASE CONSULT WITH THE PERF TEAM. // BEFORE INCREASING THESE VALUES, PLEASE CONSULT WITH THE PERF TEAM.
private const val EXPECTED_SUPPRESSION_COUNT = 21 private const val EXPECTED_SUPPRESSION_COUNT = 19
@Suppress("TopLevelPropertyNaming") // it's silly this would have a different naming convention b/c no const @Suppress("TopLevelPropertyNaming") // it's silly this would have a different naming convention b/c no const
private val EXPECTED_RUNBLOCKING_RANGE = 0..1 // CI has +1 counts compared to local runs: increment these together private val EXPECTED_RUNBLOCKING_RANGE = 0..1 // CI has +1 counts compared to local runs: increment these together
private const val EXPECTED_RECYCLER_VIEW_CONSTRAINT_LAYOUT_CHILDREN = 4 private const val EXPECTED_RECYCLER_VIEW_CONSTRAINT_LAYOUT_CHILDREN = 4

View File

@ -1,39 +0,0 @@
/* 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.components.tips
import android.graphics.drawable.Drawable
sealed class TipType {
data class Button(val text: String, val action: () -> Unit) : TipType()
}
open class Tip(
val type: TipType,
val identifier: String,
val title: String,
val description: String,
val learnMoreURL: String?,
val titleDrawable: Drawable? = null
)
interface TipProvider {
val tip: Tip?
val shouldDisplay: Boolean
}
interface TipManager {
fun getTip(): Tip?
}
class FenixTipManager(
private val providers: List<TipProvider>
) : TipManager {
override fun getTip(): Tip? {
return providers
.firstOrNull { it.shouldDisplay }
?.tip
}
}

View File

@ -89,7 +89,6 @@ import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.accounts.AccountState import org.mozilla.fenix.components.accounts.AccountState
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.tips.FenixTipManager
import org.mozilla.fenix.components.toolbar.FenixTabCounterMenu import org.mozilla.fenix.components.toolbar.FenixTabCounterMenu
import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.databinding.FragmentHomeBinding import org.mozilla.fenix.databinding.FragmentHomeBinding
@ -244,11 +243,6 @@ class HomeFragment : Fragment() {
expandedCollections = emptySet(), expandedCollections = emptySet(),
mode = currentMode.getCurrentMode(), mode = currentMode.getCurrentMode(),
topSites = getTopSites(components), topSites = getTopSites(components),
tip = components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
FenixTipManager(
listOf()
).getTip()
},
recentBookmarks = emptyList(), recentBookmarks = emptyList(),
showCollectionPlaceholder = components.settings.showCollectionsPlaceholderOnHome, showCollectionPlaceholder = components.settings.showCollectionsPlaceholderOnHome,
showSetAsDefaultBrowserCard = components.settings.shouldShowSetAsDefaultBrowserCard(), showSetAsDefaultBrowserCard = components.settings.shouldShowSetAsDefaultBrowserCard(),
@ -696,11 +690,6 @@ class HomeFragment : Fragment() {
collections = components.core.tabCollectionStorage.cachedTabCollections, collections = components.core.tabCollectionStorage.cachedTabCollections,
mode = currentMode.getCurrentMode(), mode = currentMode.getCurrentMode(),
topSites = getTopSites(components), topSites = getTopSites(components),
tip = components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
FenixTipManager(
listOf()
).getTip()
},
showCollectionPlaceholder = components.settings.showCollectionsPlaceholderOnHome, showCollectionPlaceholder = components.settings.showCollectionsPlaceholderOnHome,
// Provide an initial state for recent tabs to prevent re-rendering on the home screen. // Provide an initial state for recent tabs to prevent re-rendering on the home screen.
// This will otherwise cause a visual jump as the section gets rendered from no state // This will otherwise cause a visual jump as the section gets rendered from no state

View File

@ -13,7 +13,6 @@ import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.State import mozilla.components.lib.state.State
import mozilla.components.lib.state.Store import mozilla.components.lib.state.Store
import mozilla.components.service.pocket.PocketRecommendedStory import mozilla.components.service.pocket.PocketRecommendedStory
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.ext.filterOutTab import org.mozilla.fenix.ext.filterOutTab
import org.mozilla.fenix.ext.getFilteredStories import org.mozilla.fenix.ext.getFilteredStories
import org.mozilla.fenix.ext.recentSearchGroup import org.mozilla.fenix.ext.recentSearchGroup
@ -45,7 +44,6 @@ class HomeFragmentStore(
* in the [HomeFragment]. * in the [HomeFragment].
* @property mode The state of the [HomeFragment] UI. * @property mode The state of the [HomeFragment] UI.
* @property topSites The list of [TopSite] in the [HomeFragment]. * @property topSites The list of [TopSite] in the [HomeFragment].
* @property tip The current [Tip] to show on the [HomeFragment].
* @property showCollectionPlaceholder If true, shows a placeholder when there are no collections. * @property showCollectionPlaceholder If true, shows a placeholder when there are no collections.
* @property showSetAsDefaultBrowserCard If true, shows the default browser card * @property showSetAsDefaultBrowserCard If true, shows the default browser card
* @property recentTabs The list of recent [RecentTab] in the [HomeFragment]. * @property recentTabs The list of recent [RecentTab] in the [HomeFragment].
@ -60,7 +58,6 @@ data class HomeFragmentState(
val expandedCollections: Set<Long> = emptySet(), val expandedCollections: Set<Long> = emptySet(),
val mode: Mode = Mode.Normal, val mode: Mode = Mode.Normal,
val topSites: List<TopSite> = emptyList(), val topSites: List<TopSite> = emptyList(),
val tip: Tip? = null,
val showCollectionPlaceholder: Boolean = false, val showCollectionPlaceholder: Boolean = false,
val showSetAsDefaultBrowserCard: Boolean = false, val showSetAsDefaultBrowserCard: Boolean = false,
val recentTabs: List<RecentTab> = emptyList(), val recentTabs: List<RecentTab> = emptyList(),
@ -76,7 +73,6 @@ sealed class HomeFragmentAction : Action {
val topSites: List<TopSite>, val topSites: List<TopSite>,
val mode: Mode, val mode: Mode,
val collections: List<TabCollection>, val collections: List<TabCollection>,
val tip: Tip? = null,
val showCollectionPlaceholder: Boolean, val showCollectionPlaceholder: Boolean,
val recentTabs: List<RecentTab>, val recentTabs: List<RecentTab>,
val recentBookmarks: List<RecentBookmark>, val recentBookmarks: List<RecentBookmark>,
@ -90,7 +86,6 @@ sealed class HomeFragmentAction : Action {
data class CollectionsChange(val collections: List<TabCollection>) : HomeFragmentAction() data class CollectionsChange(val collections: List<TabCollection>) : HomeFragmentAction()
data class ModeChange(val mode: Mode) : HomeFragmentAction() data class ModeChange(val mode: Mode) : HomeFragmentAction()
data class TopSitesChange(val topSites: List<TopSite>) : HomeFragmentAction() data class TopSitesChange(val topSites: List<TopSite>) : HomeFragmentAction()
data class RemoveTip(val tip: Tip) : HomeFragmentAction()
data class RecentTabsChange(val recentTabs: List<RecentTab>) : HomeFragmentAction() data class RecentTabsChange(val recentTabs: List<RecentTab>) : HomeFragmentAction()
data class RemoveRecentTab(val recentTab: RecentTab) : HomeFragmentAction() data class RemoveRecentTab(val recentTab: RecentTab) : HomeFragmentAction()
data class RecentBookmarksChange(val recentBookmarks: List<RecentBookmark>) : HomeFragmentAction() data class RecentBookmarksChange(val recentBookmarks: List<RecentBookmark>) : HomeFragmentAction()
@ -122,7 +117,6 @@ private fun homeFragmentStateReducer(
collections = action.collections, collections = action.collections,
mode = action.mode, mode = action.mode,
topSites = action.topSites, topSites = action.topSites,
tip = action.tip,
recentBookmarks = action.recentBookmarks, recentBookmarks = action.recentBookmarks,
recentTabs = action.recentTabs, recentTabs = action.recentTabs,
recentHistory = if (action.recentHistory.isNotEmpty() && action.recentTabs.isNotEmpty()) { recentHistory = if (action.recentHistory.isNotEmpty() && action.recentTabs.isNotEmpty()) {
@ -146,9 +140,6 @@ private fun homeFragmentStateReducer(
is HomeFragmentAction.CollectionsChange -> state.copy(collections = action.collections) is HomeFragmentAction.CollectionsChange -> state.copy(collections = action.collections)
is HomeFragmentAction.ModeChange -> state.copy(mode = action.mode) is HomeFragmentAction.ModeChange -> state.copy(mode = action.mode)
is HomeFragmentAction.TopSitesChange -> state.copy(topSites = action.topSites) is HomeFragmentAction.TopSitesChange -> state.copy(topSites = action.topSites)
is HomeFragmentAction.RemoveTip -> {
state.copy(tip = null)
}
is HomeFragmentAction.RemoveCollectionsPlaceholder -> { is HomeFragmentAction.RemoveCollectionsPlaceholder -> {
state.copy(showCollectionPlaceholder = false) state.copy(showCollectionPlaceholder = false)
} }

View File

@ -92,7 +92,6 @@ class BlocklistMiddleware(
topSites = topSites, topSites = topSites,
mode = mode, mode = mode,
collections = collections, collections = collections,
tip = tip,
showCollectionPlaceholder = showCollectionPlaceholder showCollectionPlaceholder = showCollectionPlaceholder
) )
} }

View File

@ -17,7 +17,6 @@ import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.top.sites.TopSite import mozilla.components.feature.top.sites.TopSite
import mozilla.components.ui.widgets.WidgetSiteItemView import mozilla.components.ui.widgets.WidgetSiteItemView
import org.mozilla.fenix.components.Components import org.mozilla.fenix.components.Components
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.home.BottomSpacerViewHolder import org.mozilla.fenix.home.BottomSpacerViewHolder
import org.mozilla.fenix.home.HomeFragmentStore import org.mozilla.fenix.home.HomeFragmentStore
import org.mozilla.fenix.home.TopPlaceholderViewHolder import org.mozilla.fenix.home.TopPlaceholderViewHolder
@ -45,15 +44,11 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingSe
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingThemePickerViewHolder 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.OnboardingToolbarPositionPickerViewHolder
import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingTrackingProtectionViewHolder import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingTrackingProtectionViewHolder
import org.mozilla.fenix.home.tips.ButtonTipViewHolder
import org.mozilla.fenix.home.topsites.TopSitePagerViewHolder import org.mozilla.fenix.home.topsites.TopSitePagerViewHolder
import mozilla.components.feature.tab.collections.Tab as ComponentTab import mozilla.components.feature.tab.collections.Tab as ComponentTab
sealed class AdapterItem(@LayoutRes val viewType: Int) { sealed class AdapterItem(@LayoutRes val viewType: Int) {
object TopPlaceholderItem : AdapterItem(TopPlaceholderViewHolder.LAYOUT_ID) object TopPlaceholderItem : AdapterItem(TopPlaceholderViewHolder.LAYOUT_ID)
data class TipItem(val tip: Tip) : AdapterItem(
ButtonTipViewHolder.LAYOUT_ID
)
/** /**
* Contains a set of [Pair]s where [Pair.first] is the index of the changed [TopSite] and * Contains a set of [Pair]s where [Pair.first] is the index of the changed [TopSite] and
@ -260,7 +255,6 @@ class SessionControlAdapter(
val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false) val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
return when (viewType) { return when (viewType) {
TopPlaceholderViewHolder.LAYOUT_ID -> TopPlaceholderViewHolder(view) TopPlaceholderViewHolder.LAYOUT_ID -> TopPlaceholderViewHolder(view)
ButtonTipViewHolder.LAYOUT_ID -> ButtonTipViewHolder(view, interactor)
TopSitePagerViewHolder.LAYOUT_ID -> TopSitePagerViewHolder(view, viewLifecycleOwner, interactor) TopSitePagerViewHolder.LAYOUT_ID -> TopSitePagerViewHolder(view, viewLifecycleOwner, interactor)
PrivateBrowsingDescriptionViewHolder.LAYOUT_ID -> PrivateBrowsingDescriptionViewHolder( PrivateBrowsingDescriptionViewHolder.LAYOUT_ID -> PrivateBrowsingDescriptionViewHolder(
view, view,
@ -350,10 +344,6 @@ class SessionControlAdapter(
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = getItem(position) val item = getItem(position)
when (holder) { when (holder) {
is ButtonTipViewHolder -> {
val tipItem = item as AdapterItem.TipItem
holder.bind(tipItem.tip)
}
is TopPlaceholderViewHolder -> { is TopPlaceholderViewHolder -> {
holder.bind() holder.bind()
} }

View File

@ -40,7 +40,6 @@ import org.mozilla.fenix.components.TabCollectionStorage
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.components.metrics.MetricsUtils import org.mozilla.fenix.components.metrics.MetricsUtils
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.nav
@ -148,11 +147,6 @@ interface SessionControlController {
*/ */
fun handleToggleCollectionExpanded(collection: TabCollection, expand: Boolean) fun handleToggleCollectionExpanded(collection: TabCollection, expand: Boolean)
/**
* @see [TipInteractor.onCloseTip]
*/
fun handleCloseTip(tip: Tip)
/** /**
* @see [ToolbarInteractor.onPasteAndGo] * @see [ToolbarInteractor.onPasteAndGo]
*/ */
@ -530,10 +524,6 @@ class DefaultSessionControlController(
fragmentStore.dispatch(HomeFragmentAction.CollectionExpanded(collection, expand)) fragmentStore.dispatch(HomeFragmentAction.CollectionExpanded(collection, expand))
} }
override fun handleCloseTip(tip: Tip) {
fragmentStore.dispatch(HomeFragmentAction.RemoveTip(tip))
}
private fun showTabTrayCollectionCreation() { private fun showTabTrayCollectionCreation() {
val directions = HomeFragmentDirections.actionGlobalTabsTrayFragment( val directions = HomeFragmentDirections.actionGlobalTabsTrayFragment(
enterMultiselect = true enterMultiselect = true

View File

@ -9,7 +9,6 @@ import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.top.sites.TopSite import mozilla.components.feature.top.sites.TopSite
import mozilla.components.service.pocket.PocketRecommendedStory import mozilla.components.service.pocket.PocketRecommendedStory
import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.home.HomeFragmentState import org.mozilla.fenix.home.HomeFragmentState
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesCategory import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesCategory
import org.mozilla.fenix.home.pocket.PocketStoriesController import org.mozilla.fenix.home.pocket.PocketStoriesController
@ -167,13 +166,6 @@ interface OnboardingInteractor {
fun showOnboardingDialog() fun showOnboardingDialog()
} }
interface TipInteractor {
/**
* Dismisses the tip view adapter
*/
fun onCloseTip(tip: Tip)
}
interface CustomizeHomeIteractor { interface CustomizeHomeIteractor {
/** /**
* Opens the customize home settings page. * Opens the customize home settings page.
@ -247,8 +239,8 @@ interface ExperimentCardInteractor {
/** /**
* Interactor for the Home screen. Provides implementations for the CollectionInteractor, * Interactor for the Home screen. Provides implementations for the CollectionInteractor,
* OnboardingInteractor, TopSiteInteractor, TipInteractor, TabSessionInteractor, * OnboardingInteractor, TopSiteInteractor, TabSessionInteractor, ToolbarInteractor,
* ToolbarInteractor, ExperimentCardInteractor, RecentTabInteractor, RecentBookmarksInteractor * ExperimentCardInteractor, RecentTabInteractor, RecentBookmarksInteractor
* and others. * and others.
*/ */
@SuppressWarnings("TooManyFunctions") @SuppressWarnings("TooManyFunctions")
@ -261,7 +253,6 @@ class SessionControlInteractor(
) : CollectionInteractor, ) : CollectionInteractor,
OnboardingInteractor, OnboardingInteractor,
TopSiteInteractor, TopSiteInteractor,
TipInteractor,
TabSessionInteractor, TabSessionInteractor,
ToolbarInteractor, ToolbarInteractor,
ExperimentCardInteractor, ExperimentCardInteractor,
@ -343,10 +334,6 @@ class SessionControlInteractor(
controller.handleCreateCollection() controller.handleCreateCollection()
} }
override fun onCloseTip(tip: Tip) {
controller.handleCloseTip(tip)
}
override fun onPrivateBrowsingLearnMoreClicked() { override fun onPrivateBrowsingLearnMoreClicked() {
controller.handlePrivateBrowsingLearnMoreClicked() controller.handlePrivateBrowsingLearnMoreClicked()
} }

View File

@ -13,7 +13,6 @@ import androidx.recyclerview.widget.RecyclerView
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.service.pocket.PocketRecommendedStory import mozilla.components.service.pocket.PocketRecommendedStory
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.HomeFragmentState import org.mozilla.fenix.home.HomeFragmentState
@ -34,7 +33,6 @@ internal fun normalModeAdapterItems(
topSites: List<TopSite>, topSites: List<TopSite>,
collections: List<TabCollection>, collections: List<TabCollection>,
expandedCollections: Set<Long>, expandedCollections: Set<Long>,
tip: Tip?,
recentBookmarks: List<RecentBookmark>, recentBookmarks: List<RecentBookmark>,
showCollectionsPlaceholder: Boolean, showCollectionsPlaceholder: Boolean,
showSetAsDefaultBrowserCard: Boolean, showSetAsDefaultBrowserCard: Boolean,
@ -48,8 +46,6 @@ internal fun normalModeAdapterItems(
// Add a synchronous, unconditional and invisible placeholder so home is anchored to the top when created. // Add a synchronous, unconditional and invisible placeholder so home is anchored to the top when created.
items.add(AdapterItem.TopPlaceholderItem) items.add(AdapterItem.TopPlaceholderItem)
tip?.let { items.add(AdapterItem.TipItem(it)) }
if (showSetAsDefaultBrowserCard) { if (showSetAsDefaultBrowserCard) {
items.add(AdapterItem.ExperimentDefaultBrowserCard) items.add(AdapterItem.ExperimentDefaultBrowserCard)
} }
@ -157,7 +153,6 @@ private fun HomeFragmentState.toAdapterList(): List<AdapterItem> = when (mode) {
topSites, topSites,
collections, collections,
expandedCollections, expandedCollections,
tip,
recentBookmarks, recentBookmarks,
showCollectionPlaceholder, showCollectionPlaceholder,
showSetAsDefaultBrowserCard, showSetAsDefaultBrowserCard,

View File

@ -1,74 +0,0 @@
/* 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.tips
import android.view.View
import androidx.core.view.isVisible
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.components.tips.TipType
import org.mozilla.fenix.databinding.ButtonTipItemBinding
import org.mozilla.fenix.ext.addUnderline
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
import org.mozilla.fenix.utils.Settings
import org.mozilla.fenix.utils.view.ViewHolder
class ButtonTipViewHolder(
private val view: View,
private val interactor: SessionControlInteractor,
private val settings: Settings = view.context.components.settings
) : ViewHolder(view) {
var tip: Tip? = null
fun bind(tip: Tip) {
val binding = ButtonTipItemBinding.bind(view)
require(tip.type is TipType.Button)
this.tip = tip
with(binding) {
tipHeaderText.text = tip.title
tip.titleDrawable?.let {
tipHeaderText.setCompoundDrawablesWithIntrinsicBounds(it, null, null, null)
}
tipDescriptionText.text = tip.description
tipButton.text = tip.type.text
tipLearnMore.isVisible = tip.learnMoreURL != null
if (tip.learnMoreURL != null) {
tipLearnMore.addUnderline()
tipLearnMore.setOnClickListener {
(itemView.context as HomeActivity).openToBrowserAndLoad(
searchTermOrURL = tip.learnMoreURL,
newTab = true,
from = BrowserDirection.FromHome
)
}
}
tipButton.setOnClickListener {
tip.type.action.invoke()
}
tipClose.setOnClickListener {
settings.preferences
.edit()
.putBoolean(tip.identifier, false)
.apply()
interactor.onCloseTip(tip)
}
}
}
companion object {
const val LAYOUT_ID = R.layout.button_tip_item
}
}

View File

@ -1,83 +0,0 @@
<?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/tip_card"
style="@style/OnboardingCardLight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/home_item_horizontal_margin"
android:background="@drawable/cfr_background_gradient">
<TextView
android:id="@+id/tip_header_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:drawablePadding="12dp"
android:gravity="center_vertical"
android:lineSpacingExtra="2dp"
android:maxLines="2"
android:textAppearance="@style/HeaderTextStyle"
android:textColor="@color/photonLightGrey05"
app:drawableTint="@color/photonLightGrey05"
app:layout_constraintEnd_toStartOf="@id/tip_close"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Header text" />
<ImageButton
android:id="@+id/tip_close"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/create_collection_close"
app:tint="@color/photonLightGrey05"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_close" />
<TextView
android:id="@+id/tip_description_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:lineSpacingExtra="2dp"
android:textAppearance="@style/Body14TextStyle"
android:textColor="@color/photonLightGrey05"
app:layout_constraintEnd_toStartOf="@id/tip_close"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tip_header_text"
tools:text="Tip description" />
<TextView
android:id="@+id/tip_learn_more"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/search_suggestions_onboarding_learn_more_link"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/photonLightGrey05"
app:layout_constraintEnd_toEndOf="@id/tip_description_text"
app:layout_constraintStart_toStartOf="@id/tip_description_text"
app:layout_constraintTop_toBottomOf="@id/tip_description_text"
tools:textColor="@color/accent_high_contrast_private_theme" />
<Button
android:id="@+id/tip_button"
style="@style/NeutralButton"
android:layout_height="36dp"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
app:backgroundTint="@color/photonLightGrey20"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tip_learn_more"
tools:text="Call to action" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -233,7 +233,7 @@
<!-- Search suggestion onboarding hint description text, first parameter is the name of the app defined in app_name (for example: Fenix)--> <!-- Search suggestion onboarding hint description text, first parameter is the name of the app defined in app_name (for example: Fenix)-->
<string name="search_suggestions_onboarding_text">%s will share everything you type in the address bar with your default search engine.</string> <string name="search_suggestions_onboarding_text">%s will share everything you type in the address bar with your default search engine.</string>
<!-- Search suggestion onboarding hint Learn more link text --> <!-- Search suggestion onboarding hint Learn more link text -->
<string name="search_suggestions_onboarding_learn_more_link">Learn more</string> <string name="search_suggestions_onboarding_learn_more_link" moz:RemovedIn="100" tools:ignore="UnusedResources">Learn more</string>
<!-- Search engine suggestion title text. The first parameter is the name of teh suggested engine--> <!-- Search engine suggestion title text. The first parameter is the name of teh suggested engine-->
<string name="search_engine_suggestions_title">Search %s</string> <string name="search_engine_suggestions_title">Search %s</string>
<!-- Search engine suggestion description text --> <!-- Search engine suggestion description text -->

View File

@ -1,46 +0,0 @@
/* 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.components.tips
import io.mockk.mockk
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test
class TipManagerTest {
@Test
fun `test first with shouldDisplay`() {
val shouldDisplayProvider = object : TipProvider {
override val tip = mockk<Tip>()
override val shouldDisplay = true
}
val shouldNotDisplayProvider = object : TipProvider {
override val tip = mockk<Tip>()
override val shouldDisplay = false
}
val manager = FenixTipManager(listOf(shouldNotDisplayProvider, shouldDisplayProvider))
assertEquals(shouldDisplayProvider.tip, manager.getTip())
}
@Test
fun `test first with shouldDisplay even if tip is null`() {
val shouldDisplayProvider = object : TipProvider {
override val tip: Tip? = null
override val shouldDisplay = true
}
val shouldNotDisplayProvider = object : TipProvider {
override val tip = mockk<Tip>()
override val shouldDisplay = false
}
val manager = FenixTipManager(listOf(shouldNotDisplayProvider, shouldDisplayProvider))
assertEquals(shouldDisplayProvider.tip, manager.getTip())
}
@Test
fun `test returns null with empty list`() {
val manager = FenixTipManager(emptyList())
assertNull(manager.getTip())
}
}

View File

@ -54,7 +54,6 @@ import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.Event.PerformedSearch.EngineSource import org.mozilla.fenix.components.metrics.Event.PerformedSearch.EngineSource
import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.recentbookmarks.RecentBookmark import org.mozilla.fenix.home.recentbookmarks.RecentBookmark
@ -775,13 +774,6 @@ class DefaultSessionControlControllerTest {
verify { fragmentStore.dispatch(HomeFragmentAction.CollectionExpanded(collection, true)) } verify { fragmentStore.dispatch(HomeFragmentAction.CollectionExpanded(collection, true)) }
} }
@Test
fun handleCloseTip() {
val tip = mockk<Tip>()
createController().handleCloseTip(tip)
verify { fragmentStore.dispatch(HomeFragmentAction.RemoveTip(tip)) }
}
@Test @Test
fun handleCreateCollection() { fun handleCreateCollection() {
createController().handleCreateCollection() createController().handleCreateCollection()

View File

@ -40,7 +40,6 @@ class BlocklistMiddlewareTest {
topSites = store.state.topSites, topSites = store.state.topSites,
mode = store.state.mode, mode = store.state.mode,
collections = store.state.collections, collections = store.state.collections,
tip = store.state.tip,
showCollectionPlaceholder = store.state.showCollectionPlaceholder, showCollectionPlaceholder = store.state.showCollectionPlaceholder,
recentTabs = store.state.recentTabs, recentTabs = store.state.recentTabs,
recentBookmarks = listOf(updatedBookmark), recentBookmarks = listOf(updatedBookmark),
@ -67,7 +66,6 @@ class BlocklistMiddlewareTest {
topSites = store.state.topSites, topSites = store.state.topSites,
mode = store.state.mode, mode = store.state.mode,
collections = store.state.collections, collections = store.state.collections,
tip = store.state.tip,
showCollectionPlaceholder = store.state.showCollectionPlaceholder, showCollectionPlaceholder = store.state.showCollectionPlaceholder,
recentTabs = store.state.recentTabs, recentTabs = store.state.recentTabs,
recentBookmarks = listOf(updatedBookmark), recentBookmarks = listOf(updatedBookmark),
@ -94,7 +92,6 @@ class BlocklistMiddlewareTest {
topSites = store.state.topSites, topSites = store.state.topSites,
mode = store.state.mode, mode = store.state.mode,
collections = store.state.collections, collections = store.state.collections,
tip = store.state.tip,
showCollectionPlaceholder = store.state.showCollectionPlaceholder, showCollectionPlaceholder = store.state.showCollectionPlaceholder,
recentTabs = store.state.recentTabs, recentTabs = store.state.recentTabs,
recentBookmarks = listOf(updatedBookmark), recentBookmarks = listOf(updatedBookmark),
@ -121,7 +118,6 @@ class BlocklistMiddlewareTest {
topSites = store.state.topSites, topSites = store.state.topSites,
mode = store.state.mode, mode = store.state.mode,
collections = store.state.collections, collections = store.state.collections,
tip = store.state.tip,
showCollectionPlaceholder = store.state.showCollectionPlaceholder, showCollectionPlaceholder = store.state.showCollectionPlaceholder,
recentTabs = store.state.recentTabs, recentTabs = store.state.recentTabs,
recentBookmarks = listOf(updatedBookmark), recentBookmarks = listOf(updatedBookmark),
@ -150,7 +146,6 @@ class BlocklistMiddlewareTest {
topSites = store.state.topSites, topSites = store.state.topSites,
mode = store.state.mode, mode = store.state.mode,
collections = store.state.collections, collections = store.state.collections,
tip = store.state.tip,
showCollectionPlaceholder = store.state.showCollectionPlaceholder, showCollectionPlaceholder = store.state.showCollectionPlaceholder,
recentTabs = updatedRecentTabs, recentTabs = updatedRecentTabs,
recentBookmarks = updatedBookmarks, recentBookmarks = updatedBookmarks,
@ -186,7 +181,6 @@ class BlocklistMiddlewareTest {
topSites = store.state.topSites, topSites = store.state.topSites,
mode = store.state.mode, mode = store.state.mode,
collections = store.state.collections, collections = store.state.collections,
tip = store.state.tip,
showCollectionPlaceholder = store.state.showCollectionPlaceholder, showCollectionPlaceholder = store.state.showCollectionPlaceholder,
recentTabs = updatedRecentTabs, recentTabs = updatedRecentTabs,
recentBookmarks = updatedBookmarks, recentBookmarks = updatedBookmarks,
@ -239,7 +233,6 @@ class BlocklistMiddlewareTest {
topSites = store.state.topSites, topSites = store.state.topSites,
mode = store.state.mode, mode = store.state.mode,
collections = store.state.collections, collections = store.state.collections,
tip = store.state.tip,
showCollectionPlaceholder = store.state.showCollectionPlaceholder, showCollectionPlaceholder = store.state.showCollectionPlaceholder,
recentTabs = store.state.recentTabs, recentTabs = store.state.recentTabs,
recentBookmarks = listOf(updatedBookmark), recentBookmarks = listOf(updatedBookmark),
@ -267,7 +260,6 @@ class BlocklistMiddlewareTest {
topSites = store.state.topSites, topSites = store.state.topSites,
mode = store.state.mode, mode = store.state.mode,
collections = store.state.collections, collections = store.state.collections,
tip = store.state.tip,
showCollectionPlaceholder = store.state.showCollectionPlaceholder, showCollectionPlaceholder = store.state.showCollectionPlaceholder,
recentTabs = store.state.recentTabs, recentTabs = store.state.recentTabs,
recentBookmarks = listOf(updatedBookmark), recentBookmarks = listOf(updatedBookmark),
@ -295,7 +287,6 @@ class BlocklistMiddlewareTest {
topSites = store.state.topSites, topSites = store.state.topSites,
mode = store.state.mode, mode = store.state.mode,
collections = store.state.collections, collections = store.state.collections,
tip = store.state.tip,
showCollectionPlaceholder = store.state.showCollectionPlaceholder, showCollectionPlaceholder = store.state.showCollectionPlaceholder,
recentTabs = store.state.recentTabs, recentTabs = store.state.recentTabs,
recentBookmarks = listOf(updatedBookmark), recentBookmarks = listOf(updatedBookmark),

View File

@ -145,7 +145,6 @@ class SessionControlViewTest {
topSites, topSites,
collections, collections,
expandedCollections, expandedCollections,
null,
recentBookmarks, recentBookmarks,
false, false,
false, false,
@ -174,7 +173,6 @@ class SessionControlViewTest {
topSites, topSites,
collections, collections,
expandedCollections, expandedCollections,
null,
recentBookmarks, recentBookmarks,
false, false,
false, false,
@ -203,7 +201,6 @@ class SessionControlViewTest {
topSites, topSites,
collections, collections,
expandedCollections, expandedCollections,
null,
recentBookmarks, recentBookmarks,
false, false,
false, false,
@ -232,7 +229,6 @@ class SessionControlViewTest {
topSites, topSites,
collections, collections,
expandedCollections, expandedCollections,
null,
recentBookmarks, recentBookmarks,
false, false,
false, false,
@ -262,7 +258,6 @@ class SessionControlViewTest {
topSites, topSites,
collections, collections,
expandedCollections, expandedCollections,
null,
recentBookmarks, recentBookmarks,
false, false,
false, false,
@ -291,7 +286,6 @@ class SessionControlViewTest {
topSites, topSites,
collections, collections,
expandedCollections, expandedCollections,
null,
recentBookmarks, recentBookmarks,
false, false,
false, false,

View File

@ -1,125 +0,0 @@
/* 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.tips
import android.content.SharedPreferences
import android.view.LayoutInflater
import androidx.core.view.isGone
import androidx.core.view.isVisible
import io.mockk.MockKAnnotations
import io.mockk.Runs
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.just
import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.components.tips.TipType
import org.mozilla.fenix.databinding.ButtonTipItemBinding
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
import org.mozilla.fenix.utils.Settings
@RunWith(FenixRobolectricTestRunner::class)
class ButtonTipViewHolderTest {
@MockK private lateinit var activity: HomeActivity
@MockK private lateinit var interactor: SessionControlInteractor
@MockK private lateinit var settings: Settings
@MockK private lateinit var sharedPrefs: SharedPreferences
@MockK private lateinit var sharedPrefsEditor: SharedPreferences.Editor
private lateinit var viewHolder: ButtonTipViewHolder
private lateinit var binding: ButtonTipItemBinding
@Before
fun setup() {
MockKAnnotations.init(this)
val view = spyk(
LayoutInflater.from(testContext)
.inflate(ButtonTipViewHolder.LAYOUT_ID, null)
)
viewHolder = ButtonTipViewHolder(view, interactor, settings)
binding = ButtonTipItemBinding.bind(view)
every { view.context } returns activity
every { activity.openToBrowserAndLoad(any(), any(), any()) } just Runs
every { interactor.onCloseTip(any()) } just Runs
every { settings.preferences } returns sharedPrefs
every { sharedPrefs.edit() } returns sharedPrefsEditor
every { sharedPrefsEditor.putBoolean(any(), any()) } returns sharedPrefsEditor
every { sharedPrefsEditor.apply() } just Runs
}
@Test
fun `text is displayed based on given tip`() {
viewHolder.bind(defaultTip())
assertEquals("Tip Title", binding.tipHeaderText.text)
assertEquals("Tip description", binding.tipDescriptionText.text)
assertEquals("button", binding.tipButton.text)
}
@Test
fun `learn more is hidden if learnMoreURL is null`() {
viewHolder.bind(defaultTip(learnMoreUrl = null))
assertTrue(binding.tipLearnMore.isGone)
}
@Test
fun `learn more is visible if learnMoreURL is not null`() {
viewHolder.bind(defaultTip(learnMoreUrl = "https://learnmore.com"))
assertTrue(binding.tipLearnMore.isVisible)
binding.tipLearnMore.performClick()
verify {
activity.openToBrowserAndLoad(
searchTermOrURL = "https://learnmore.com",
newTab = true,
from = BrowserDirection.FromHome
)
}
}
@Test
fun `tip button invokes tip action`() {
val action = mockk<() -> Unit>(relaxed = true)
viewHolder.bind(defaultTip(action))
binding.tipButton.performClick()
verify { action() }
}
@Test
fun `close button invokes onCloseTip`() {
val tip = defaultTip()
viewHolder.bind(tip)
binding.tipClose.performClick()
verify { interactor.onCloseTip(tip) }
verify { sharedPrefsEditor.putBoolean("tipIdentifier", false) }
}
private fun defaultTip(
action: () -> Unit = mockk(),
learnMoreUrl: String? = null
) = Tip(
type = TipType.Button("button", action),
identifier = "tipIdentifier",
title = "Tip Title",
description = "Tip description",
learnMoreURL = learnMoreUrl
)
}