Bug 1837961 - Part 2:Replace usages of ifChanged to distinctUntilChanged

fenix/116.0
rahulsainani 1 year ago committed by mergify[bot]
parent ac949e7668
commit 3561733a01

@ -35,6 +35,8 @@ import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.launch
@ -100,7 +102,6 @@ import mozilla.components.support.ktx.android.view.exitImmersiveMode
import mozilla.components.support.ktx.android.view.hideKeyboard
import mozilla.components.support.ktx.kotlin.getOrigin
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import mozilla.components.support.locale.ActivityContextWrapper
import mozilla.components.ui.widgets.withCenterAlignedButtons
import org.mozilla.fenix.BuildConfig
@ -862,7 +863,7 @@ abstract class BaseBrowserFragment :
store.flowScoped(viewLifecycleOwner) { flow ->
flow.mapNotNull { state -> state.findTabOrCustomTabOrSelectedTab(customTabSessionId) }
.ifChanged { tab -> tab.content.pictureInPictureEnabled }
.distinctUntilChangedBy { tab -> tab.content.pictureInPictureEnabled }
.collect { tab -> pipModeChanged(tab) }
}
@ -1127,7 +1128,7 @@ abstract class BaseBrowserFragment :
val activity = activity as HomeActivity
consumeFlow(store) { flow ->
flow.map { state -> state.restoreComplete }
.ifChanged()
.distinctUntilChanged()
.collect { restored ->
if (restored) {
// Once tab restoration is complete, if there are no tabs to show in the browser, go home
@ -1146,7 +1147,7 @@ abstract class BaseBrowserFragment :
@VisibleForTesting
internal fun observeTabSelection(store: BrowserStore) {
consumeFlow(store) { flow ->
flow.ifChanged {
flow.distinctUntilChangedBy {
it.selectedTabId
}
.mapNotNull {

@ -7,7 +7,7 @@ package org.mozilla.fenix.crashes
import android.view.ViewGroup.MarginLayoutParams
import androidx.navigation.NavController
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.mapNotNull
import mozilla.components.browser.state.selector.findTabOrCustomTabOrSelectedTab
import mozilla.components.browser.state.selector.normalTabs
@ -17,7 +17,6 @@ import mozilla.components.browser.state.state.EngineState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.Components
import org.mozilla.fenix.utils.Settings
@ -53,7 +52,7 @@ class CrashContentIntegration(
) : AbstractBinding<BrowserState>(browserStore) {
override suspend fun onState(flow: Flow<BrowserState>) {
flow.mapNotNull { state -> state.findTabOrCustomTabOrSelectedTab(sessionId) }
.ifChanged { tab -> tab.engineState.crashed }
.distinctUntilChangedBy { tab -> tab.engineState.crashed }
.collect { tab ->
if (tab.engineState.crashed) {
toolbar.expand()

@ -11,6 +11,7 @@ import androidx.annotation.VisibleForTesting
import androidx.fragment.app.FragmentManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.mapNotNull
import mozilla.components.browser.state.action.WebExtensionAction
import mozilla.components.browser.state.state.extension.WebExtensionPromptRequest
@ -19,7 +20,6 @@ import mozilla.components.feature.addons.Addon
import mozilla.components.feature.addons.ui.PermissionsDialogFragment
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.base.feature.LifecycleAwareFeature
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.addons.showSnackBar
import org.mozilla.fenix.components.FenixSnackbar
@ -50,7 +50,7 @@ class WebExtensionPromptFeature(
scope = store.flowScoped { flow ->
flow.mapNotNull { state ->
state.webExtensionPromptRequest
}.ifChanged().collect { promptRequest ->
}.distinctUntilChanged().collect { promptRequest ->
if (promptRequest is WebExtensionPromptRequest.Permissions && !hasExistingPermissionDialogFragment()) {
val addon = provideAddons().find { addon ->
addon.id == promptRequest.extension.id

@ -37,6 +37,7 @@ import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import mozilla.components.browser.state.selector.findTab
@ -59,7 +60,6 @@ import mozilla.components.lib.state.ext.consumeFlow
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.GleanMetrics.HomeScreen
import org.mozilla.fenix.GleanMetrics.PrivateBrowsingShortcutCfr
import org.mozilla.fenix.HomeActivity
@ -617,7 +617,7 @@ class HomeFragment : Fragment() {
else -> null
}
}
.ifChanged()
.distinctUntilChanged()
.collect {
topSitesFeature.withFeature {
it.storage.notifyObservers { onStorageUpdated() }

@ -6,6 +6,7 @@ package org.mozilla.fenix.home.recentsyncedtabs
import android.content.Context
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import mozilla.components.browser.storage.sync.Tab
@ -23,7 +24,6 @@ import mozilla.components.service.fxa.store.SyncStore
import mozilla.components.service.fxa.sync.SyncReason
import mozilla.components.support.base.feature.LifecycleAwareFeature
import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import mozilla.telemetry.glean.GleanTimerId
import org.mozilla.fenix.GleanMetrics.RecentSyncedTabs
import org.mozilla.fenix.components.AppStore
@ -63,7 +63,7 @@ class RecentSyncedTabFeature(
private fun collectAccountUpdates() {
syncStore.flow()
.ifChanged { state ->
.distinctUntilChangedBy { state ->
state.account != null
}.onEach { state ->
if (state.account != null) {
@ -82,7 +82,7 @@ class RecentSyncedTabFeature(
private fun collectStatusUpdates() {
syncStore.flow()
.ifChanged { state ->
.distinctUntilChangedBy { state ->
state.status
}.onEach { state ->
when (state.status) {

@ -6,12 +6,12 @@ package org.mozilla.fenix.home.recenttabs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.ext.asRecentTabs
@ -30,7 +30,7 @@ class RecentTabsListFeature(
// Listen for changes regarding the currently selected tab and in progress media tab.
flow
.map { it.asRecentTabs() }
.ifChanged()
.distinctUntilChanged()
.collect {
appStore.dispatch(AppAction.RecentTabsChange(it))
}

@ -10,12 +10,12 @@ import androidx.compose.ui.graphics.toArgb
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleOwner
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.selector.normalTabs
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.databinding.NoCollectionsMessageBinding
@ -53,7 +53,7 @@ class NoCollectionsMessageViewHolder(
store.flowScoped(viewLifecycleOwner) { flow ->
flow.map { state -> state.normalTabs.size }
.ifChanged()
.distinctUntilChanged()
.collect { tabs ->
binding.addTabsToCollectionsButton.isVisible = tabs > 0
}
@ -61,7 +61,7 @@ class NoCollectionsMessageViewHolder(
appStore.flowScoped(viewLifecycleOwner) { flow ->
flow.map { state -> state.wallpaperState }
.ifChanged()
.distinctUntilChanged()
.collect { wallpaperState ->
val textColor = wallpaperState.currentWallpaper.textColor
if (textColor == null) {

@ -9,6 +9,7 @@ import android.graphics.drawable.BitmapDrawable
import androidx.core.view.isGone
import androidx.core.view.isVisible
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.state.BrowserState
@ -18,7 +19,6 @@ import mozilla.components.concept.menu.Orientation
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.GleanMetrics.UnifiedSearch
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.FragmentHomeBinding
@ -63,7 +63,7 @@ class SearchSelectorBinding(
override suspend fun onState(flow: Flow<BrowserState>) {
flow.map { state -> state.search.selectedOrDefaultSearchEngine }
.ifChanged()
.distinctUntilChanged()
.collect { searchEngine ->
val name = searchEngine?.name
val icon = searchEngine?.let {

@ -7,6 +7,7 @@ package org.mozilla.fenix.home.toolbar
import android.content.Context
import androidx.core.graphics.drawable.toDrawable
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.state.BrowserState
@ -15,7 +16,6 @@ import mozilla.components.concept.menu.candidate.DrawableMenuIcon
import mozilla.components.concept.menu.candidate.TextMenuCandidate
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.search.ext.searchEngineShortcuts
import org.mozilla.fenix.search.toolbar.SearchSelectorInteractor
@ -33,7 +33,7 @@ class SearchSelectorMenuBinding(
override suspend fun onState(flow: Flow<BrowserState>) {
flow.map { state -> state.search }
.ifChanged()
.distinctUntilChanged()
.collect { search ->
updateSearchSelectorMenu(search.searchEngineShortcuts)
}

@ -20,13 +20,13 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import mozilla.components.feature.top.sites.TopSite
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.GleanMetrics.Pings
import org.mozilla.fenix.GleanMetrics.TopSites
import org.mozilla.fenix.R
@ -97,7 +97,7 @@ class TopSiteItemViewHolder(
appStore.flowScoped(viewLifecycleOwner) { flow ->
flow.map { state -> state.wallpaperState }
.ifChanged()
.distinctUntilChanged()
.collect { currentState ->
var backgroundColor = ContextCompat.getColor(view.context, R.color.fx_mobile_layer_color_2)

@ -29,7 +29,7 @@ import androidx.constraintlayout.widget.ConstraintProperties.TOP
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import mozilla.components.browser.toolbar.BrowserToolbar
@ -37,7 +37,6 @@ import mozilla.components.lib.state.ext.consumeFlow
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.ktx.android.view.hideKeyboard
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
@ -186,7 +185,7 @@ class BookmarkSearchDialogFragment : AppCompatDialogFragment(), UserInteractionH
private fun observeAwesomeBarState() = consumeFlow(store) { flow ->
flow.map { state -> state.query.isNotBlank() }
.ifChanged()
.distinctUntilChanged()
.collect { shouldShowAwesomebar ->
binding.awesomeBar.visibility = if (shouldShowAwesomebar) {
View.VISIBLE

@ -29,7 +29,7 @@ import androidx.constraintlayout.widget.ConstraintProperties.TOP
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import mozilla.components.browser.toolbar.BrowserToolbar
@ -37,7 +37,6 @@ import mozilla.components.lib.state.ext.consumeFlow
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.ktx.android.view.hideKeyboard
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
@ -186,7 +185,7 @@ class HistorySearchDialogFragment : AppCompatDialogFragment(), UserInteractionHa
private fun observeAwesomeBarState() = consumeFlow(store) { flow ->
flow.map { state -> state.query.isNotBlank() }
.ifChanged()
.distinctUntilChanged()
.collect { shouldShowAwesomebar ->
binding.awesomeBar.visibility = if (shouldShowAwesomebar) {
View.VISIBLE

@ -16,13 +16,12 @@ import androidx.core.view.MenuProvider
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.state.recover.RecoverableTab
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import mozilla.telemetry.glean.private.NoExtras
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.GleanMetrics.RecentlyClosedTabs
@ -158,7 +157,7 @@ class RecentlyClosedFragment :
requireComponents.core.store.flowScoped(viewLifecycleOwner) { flow ->
flow.map { state -> state.closedTabs }
.ifChanged()
.distinctUntilChanged()
.collect { tabs ->
recentlyClosedFragmentStore.dispatch(
RecentlyClosedFragmentAction.Change(tabs),

@ -43,6 +43,7 @@ import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavGraph
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import mozilla.components.browser.state.search.SearchEngine
@ -69,7 +70,6 @@ import mozilla.components.support.ktx.android.view.findViewInHierarchy
import mozilla.components.support.ktx.android.view.hideKeyboard
import mozilla.components.support.ktx.kotlin.toNormalizedUrl
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import mozilla.components.ui.autocomplete.InlineAutocompleteEditText
import mozilla.components.ui.widgets.withCenterAlignedButtons
import org.mozilla.fenix.BrowserDirection
@ -331,7 +331,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
consumeFlow(requireComponents.core.store) { flow ->
flow.map { state -> state.search }
.ifChanged()
.distinctUntilChanged()
.collect { search ->
store.dispatch(
SearchFragmentAction.UpdateSearchState(
@ -540,7 +540,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
private fun observeSuggestionProvidersState() = consumeFlow(store) { flow ->
flow.map { state -> state.toSearchProviderState() }
.ifChanged()
.distinctUntilChanged()
.collect { state -> awesomeBarView.updateSuggestionProvidersVisibility(state) }
}
@ -557,7 +557,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
* */
flow.map { state -> state.url != state.query && state.query.isNotBlank() || state.showSearchShortcuts }
.ifChanged()
.distinctUntilChanged()
.collect { shouldShowAwesomebar ->
binding.awesomeBar.visibility = if (shouldShowAwesomebar) {
View.VISIBLE
@ -574,7 +574,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
state.clipboardHasUrl && !state.showSearchShortcuts
Pair(shouldShowView, state.clipboardHasUrl)
}
.ifChanged()
.distinctUntilChanged()
.collect { (shouldShowView) ->
updateClipboardSuggestion(shouldShowView)
}

@ -11,6 +11,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
@ -21,7 +22,6 @@ import mozilla.components.lib.state.ext.flow
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.content.res.resolveAttribute
import mozilla.components.support.ktx.android.view.toScope
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import mozilla.telemetry.glean.private.NoExtras
import org.mozilla.fenix.GleanMetrics.UnifiedSearch
import org.mozilla.fenix.R
@ -87,7 +87,7 @@ class SearchSelectorToolbarAction(
store.flow()
.map { state -> state.searchEngineSource.searchEngine }
.filterNotNull()
.ifChanged()
.distinctUntilChanged()
.collect { searchEngine ->
view.setIcon(
icon = searchEngine.getScaledIcon(view.context).apply {

@ -15,11 +15,11 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import mozilla.components.ui.widgets.withCenterAlignedButtons
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
@ -99,7 +99,7 @@ class DeleteBrowsingDataFragment : Fragment(R.layout.fragment_delete_browsing_da
scope = requireComponents.core.store.flowScoped(viewLifecycleOwner) { flow ->
flow.map { state -> state.tabs.size }
.ifChanged()
.distinctUntilChanged()
.collect { openTabs -> updateTabCount(openTabs) }
}
}

@ -20,6 +20,7 @@ import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import mozilla.components.browser.state.search.SearchEngine
@ -29,7 +30,6 @@ import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.lib.state.ext.flow
import mozilla.components.support.ktx.android.view.toScope
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.GleanMetrics.Events
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.SearchEngineRadioButtonBinding
@ -64,7 +64,7 @@ class RadioSearchEngineListPreference @JvmOverloads constructor(
private fun subscribeToSearchEngineUpdates(store: BrowserStore, view: View) = view.toScope().launch {
store.flow()
.map { state -> state.search }
.ifChanged()
.distinctUntilChanged()
.collect { state -> refreshSearchEngineViews(view, state) }
}

@ -9,13 +9,12 @@ import androidx.lifecycle.LifecycleOwner
import androidx.navigation.NavController
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.mapNotNull
import mozilla.components.browser.state.selector.selectedTab
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.feature.pwa.WebAppUseCases
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.BrowserFragmentDirections
import org.mozilla.fenix.ext.nav
@ -39,7 +38,7 @@ class PwaOnboardingObserver(
flow.mapNotNull { state ->
state.selectedTab
}
.ifChanged {
.distinctUntilChangedBy {
it.content.webAppManifest
}
.collect {

@ -12,12 +12,11 @@ import androidx.navigation.fragment.findNavController
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.mapNotNull
import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.FragmentTabHistoryDialogBinding
import org.mozilla.fenix.ext.requireComponents
@ -54,7 +53,7 @@ class TabHistoryDialogFragment : BottomSheetDialogFragment() {
requireComponents.core.store.flowScoped(viewLifecycleOwner) { flow ->
flow.mapNotNull { state -> state.findCustomTabOrSelectedTab(customTabSessionId)?.content?.history }
.ifChanged()
.distinctUntilChanged()
.collect { historyState ->
tabHistoryView.updateState(historyState)
}

@ -6,7 +6,7 @@ package org.mozilla.fenix.tabstray
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.selector.normalTabs
@ -14,7 +14,6 @@ import mozilla.components.browser.state.selector.privateTabs
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
/**
* A binding that closes the tabs tray when the last tab is closed.
@ -29,7 +28,7 @@ class CloseOnLastTabBinding(
flow.map { it }
// Ignore the initial state; we don't want to close immediately.
.drop(1)
.ifChanged { it.tabs }
.distinctUntilChangedBy { it.tabs }
.collect { state ->
val selectedPage = tabsTrayStore.state.selectedPage
val tabs = when (selectedPage) {

@ -6,13 +6,12 @@ package org.mozilla.fenix.tabstray
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.selector.normalTabs
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import mozilla.components.ui.tabcounter.TabCounter
/**
@ -26,7 +25,7 @@ class TabCounterBinding(
override suspend fun onState(flow: Flow<BrowserState>) {
flow.map { it.normalTabs }
.ifChanged()
.distinctUntilChanged()
.collect {
counter.setCount(it.size)
}

@ -17,14 +17,13 @@ import android.view.View
import androidx.annotation.VisibleForTesting
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.selector.normalTabs
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.android.util.dpToPx
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import mozilla.telemetry.glean.private.NoExtras
import org.mozilla.fenix.GleanMetrics.TabsTray
import org.mozilla.fenix.R
@ -50,7 +49,7 @@ class TabsTrayInactiveTabsOnboardingBinding(
override suspend fun onState(flow: Flow<BrowserState>) {
flow.map { state -> state.normalTabs.size }
.ifChanged()
.distinctUntilChanged()
.collect {
val inactiveTabsList =
if (settings.inactiveTabsAreEnabled) { store.state.potentialInactiveTabs } else { emptyList() }

@ -10,14 +10,13 @@ import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.selector.normalTabs
import mozilla.components.browser.state.selector.privateTabs
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.infobanner.InfoBanner
import org.mozilla.fenix.utils.Settings
@ -37,7 +36,7 @@ class TabsTrayInfoBannerBinding(
override suspend fun onState(flow: Flow<BrowserState>) {
flow.map { state -> max(state.normalTabs.size, state.privateTabs.size) }
.ifChanged()
.distinctUntilChanged()
.collect { tabCount ->
if (tabCount >= TAB_COUNT_SHOW_CFR) {
displayInfoBannerIfNeeded(settings)

@ -5,11 +5,10 @@
package org.mozilla.fenix.tabstray.browser
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChangedBy
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.browser.tabstray.TabsTray
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.tabstray.TabsTrayState
import org.mozilla.fenix.tabstray.TabsTrayStore
@ -22,7 +21,7 @@ class NormalTabsBinding(
private val tabsTray: TabsTray,
) : AbstractBinding<TabsTrayState>(store) {
override suspend fun onState(flow: Flow<TabsTrayState>) {
flow.ifChanged { it.normalTabs }
flow.distinctUntilChangedBy { it.normalTabs }
.collect {
tabsTray.updateTabs(it.normalTabs, null, browserStore.state.selectedTabId)
}

@ -5,12 +5,11 @@
package org.mozilla.fenix.tabstray.browser
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.browser.tabstray.TabsTray
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.tabstray.TabsTrayState
import org.mozilla.fenix.tabstray.TabsTrayStore
@ -24,7 +23,7 @@ class PrivateTabsBinding(
) : AbstractBinding<TabsTrayState>(store) {
override suspend fun onState(flow: Flow<TabsTrayState>) {
flow.map { it.privateTabs }
.ifChanged()
.distinctUntilChanged()
.collect {
// Getting the selectedTabId from the BrowserStore at a different time might lead to a race.
tray.updateTabs(it, null, browserStore.state.selectedTabId)

@ -7,12 +7,11 @@ package org.mozilla.fenix.tabstray.browser
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.browser.tabstray.TabsAdapter.Companion.PAYLOAD_DONT_HIGHLIGHT_SELECTED_ITEM
import mozilla.components.browser.tabstray.TabsAdapter.Companion.PAYLOAD_HIGHLIGHT_SELECTED_ITEM
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.tabstray.TabsTrayState
import org.mozilla.fenix.tabstray.TabsTrayState.Mode
import org.mozilla.fenix.tabstray.TabsTrayStore
@ -28,7 +27,7 @@ class SelectedItemAdapterBinding(
override suspend fun onState(flow: Flow<TabsTrayState>) {
flow.map { it.mode }
.ifChanged()
.distinctUntilChanged()
.collect { mode ->
notifyAdapter(mode)
}

@ -11,9 +11,9 @@ import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.ComponentTabstray2Binding
import org.mozilla.fenix.databinding.TabstrayMultiselectItemsBinding
@ -62,7 +62,7 @@ class SelectionBannerBinding(
override suspend fun onState(flow: Flow<TabsTrayState>) {
flow.map { it.mode }
.ifChanged()
.distinctUntilChanged()
.collect { mode ->
val isSelectMode = mode is Select

@ -12,10 +12,9 @@ import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.tabstray.TabsTrayState
import org.mozilla.fenix.tabstray.TabsTrayState.Mode
@ -42,7 +41,7 @@ class SelectionHandleBinding(
override suspend fun onState(flow: Flow<TabsTrayState>) {
flow.map { it.mode }
.ifChanged()
.distinctUntilChanged()
.collect { mode ->
val isSelectMode = mode is Mode.Select

@ -6,10 +6,9 @@ package org.mozilla.fenix.tabstray.browser
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.tabstray.TabsTrayState
import org.mozilla.fenix.tabstray.TabsTrayStore
@ -25,7 +24,7 @@ class SwipeToDeleteBinding(
override suspend fun onState(flow: Flow<TabsTrayState>) {
flow.map { it.mode }
.ifChanged()
.distinctUntilChanged()
.collect { mode ->
isSwipeable = mode == TabsTrayState.Mode.Normal
}

@ -6,11 +6,10 @@ package org.mozilla.fenix.tabstray.syncedtabs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.feature.syncedtabs.view.SyncedTabsView
import mozilla.components.lib.state.helpers.AbstractBinding
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.tabstray.TabsTrayState
import org.mozilla.fenix.tabstray.TabsTrayStore
@ -27,7 +26,7 @@ class SyncButtonBinding(
) : AbstractBinding<TabsTrayState>(tabsTrayStore) {
override suspend fun onState(flow: Flow<TabsTrayState>) {
flow.map { it.syncing }
.ifChanged()
.distinctUntilChanged()
.collect { syncingNow ->
if (syncingNow) {
onSyncNow()

@ -10,12 +10,12 @@ import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.selector.selectedNormalTab
import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction
@ -129,7 +129,7 @@ class NormalBrowserPageViewHolder(
private fun observeTabsTrayInactiveTabsState(adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder>) {
tabsTrayStore.flowScoped(lifecycleOwner) { flow ->
flow.map { state -> state.inactiveTabs }
.ifChanged()
.distinctUntilChanged()
.collect { inactiveTabs ->
inactiveTabsSize = inactiveTabs.size
updateTrayVisibility(showTrayList(adapter))

@ -24,6 +24,7 @@ import androidx.navigation.fragment.navArgs
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.launch
import kotlinx.coroutines.plus
@ -36,7 +37,6 @@ import mozilla.components.lib.state.ext.observe
import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import mozilla.telemetry.glean.private.NoExtras
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.GleanMetrics.TrackingProtection
@ -221,7 +221,7 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), UserInt
consumeFlow(store) { flow ->
flow.mapNotNull { state ->
state.findTabOrCustomTab(provideCurrentTabId())
}.ifChanged { tab -> tab.content.url }
}.distinctUntilChangedBy { tab -> tab.content.url }
.collect {
protectionsStore.dispatch(ProtectionsAction.UrlChange(it.content.url))
}

Loading…
Cancel
Save