Issue #19002: Use AbstractBinding from lib-state
This commit is contained in:
parent
551031eee3
commit
e66983d093
|
@ -489,6 +489,7 @@ dependencies {
|
|||
|
||||
implementation Deps.mozilla_lib_crash
|
||||
implementation Deps.mozilla_lib_push_firebase
|
||||
implementation Deps.mozilla_lib_state
|
||||
implementation Deps.mozilla_lib_dataprotect
|
||||
debugImplementation Deps.leakcanary
|
||||
|
||||
|
|
|
@ -1,43 +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
|
||||
|
||||
import androidx.annotation.CallSuper
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import mozilla.components.lib.state.Action
|
||||
import mozilla.components.lib.state.State
|
||||
import mozilla.components.lib.state.Store
|
||||
import mozilla.components.lib.state.ext.flowScoped
|
||||
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
||||
|
||||
/**
|
||||
* Helper class for creating small binding classes that are responsible for reacting to state
|
||||
* changes.
|
||||
*
|
||||
* Taken with ♥️ from Focus.
|
||||
*/
|
||||
abstract class AbstractBinding<in S : State>(
|
||||
private val store: Store<S, out Action>
|
||||
) : LifecycleAwareFeature {
|
||||
private var scope: CoroutineScope? = null
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@CallSuper
|
||||
override fun start() {
|
||||
scope = store.flowScoped { flow ->
|
||||
onState(flow)
|
||||
}
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun stop() {
|
||||
scope?.cancel()
|
||||
}
|
||||
|
||||
abstract suspend fun onState(flow: Flow<S>)
|
||||
}
|
|
@ -6,13 +6,11 @@ package org.mozilla.fenix.tabstray
|
|||
|
||||
import android.view.View
|
||||
import android.widget.ImageButton
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.map
|
||||
import mozilla.components.lib.state.ext.flowScoped
|
||||
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
||||
import mozilla.components.lib.state.helpers.AbstractBinding
|
||||
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.tabstray.browser.BrowserTrayInteractor
|
||||
|
@ -24,38 +22,33 @@ import org.mozilla.fenix.utils.Settings
|
|||
* This binding is coupled with [FloatingActionButtonBinding].
|
||||
* When [FloatingActionButtonBinding] is visible this should not be visible
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class AccessibleNewTabButtonBinding(
|
||||
private val store: TabsTrayStore,
|
||||
private val settings: Settings,
|
||||
private val newTabButton: ImageButton,
|
||||
private val browserTrayInteractor: BrowserTrayInteractor
|
||||
) : LifecycleAwareFeature {
|
||||
) : AbstractBinding<TabsTrayState>(store) {
|
||||
|
||||
private var scope: CoroutineScope? = null
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun start() {
|
||||
if (!settings.accessibilityServicesEnabled) {
|
||||
newTabButton.visibility = View.GONE
|
||||
return
|
||||
}
|
||||
|
||||
scope = store.flowScoped { flow ->
|
||||
flow.map { it }
|
||||
.ifAnyChanged { state ->
|
||||
arrayOf(
|
||||
state.selectedPage,
|
||||
state.syncing
|
||||
)
|
||||
}
|
||||
.collect { state ->
|
||||
setAccessibleNewTabButton(state.selectedPage, state.syncing)
|
||||
}
|
||||
}
|
||||
super.start()
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
scope?.cancel()
|
||||
override suspend fun onState(flow: Flow<TabsTrayState>) {
|
||||
flow.map { it }
|
||||
.ifAnyChanged { state ->
|
||||
arrayOf(
|
||||
state.selectedPage,
|
||||
state.syncing
|
||||
)
|
||||
}
|
||||
.collect { state ->
|
||||
setAccessibleNewTabButton(state.selectedPage, state.syncing)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setAccessibleNewTabButton(selectedPage: Page, syncing: Boolean) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package org.mozilla.fenix.tabstray
|
||||
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.drop
|
||||
|
@ -12,12 +13,13 @@ 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.components.AbstractBinding
|
||||
|
||||
/**
|
||||
* A binding that closes the tabs tray when the last tab is closed.
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class CloseOnLastTabBinding(
|
||||
browserStore: BrowserStore,
|
||||
private val tabsTrayStore: TabsTrayStore,
|
||||
|
|
|
@ -5,13 +5,11 @@
|
|||
package org.mozilla.fenix.tabstray
|
||||
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.map
|
||||
import mozilla.components.lib.state.ext.flowScoped
|
||||
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
||||
import mozilla.components.lib.state.helpers.AbstractBinding
|
||||
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.tabstray.browser.BrowserTrayInteractor
|
||||
|
@ -23,38 +21,33 @@ import org.mozilla.fenix.utils.Settings
|
|||
* This binding is coupled with [AccessibleNewTabButtonBinding].
|
||||
* When [AccessibleNewTabButtonBinding] is visible this should not be visible
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class FloatingActionButtonBinding(
|
||||
private val store: TabsTrayStore,
|
||||
private val settings: Settings,
|
||||
private val actionButton: ExtendedFloatingActionButton,
|
||||
private val browserTrayInteractor: BrowserTrayInteractor
|
||||
) : LifecycleAwareFeature {
|
||||
) : AbstractBinding<TabsTrayState>(store) {
|
||||
|
||||
private var scope: CoroutineScope? = null
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun start() {
|
||||
if (settings.accessibilityServicesEnabled) {
|
||||
actionButton.hide()
|
||||
return
|
||||
}
|
||||
|
||||
scope = store.flowScoped { flow ->
|
||||
flow.map { it }
|
||||
.ifAnyChanged { state ->
|
||||
arrayOf(
|
||||
state.selectedPage,
|
||||
state.syncing
|
||||
)
|
||||
}
|
||||
.collect { state ->
|
||||
setFab(state.selectedPage, state.syncing)
|
||||
}
|
||||
}
|
||||
super.start()
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
scope?.cancel()
|
||||
override suspend fun onState(flow: Flow<TabsTrayState>) {
|
||||
flow.map { it }
|
||||
.ifAnyChanged { state ->
|
||||
arrayOf(
|
||||
state.selectedPage,
|
||||
state.syncing
|
||||
)
|
||||
}
|
||||
.collect { state ->
|
||||
setFab(state.selectedPage, state.syncing)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setFab(selectedPage: Page, syncing: Boolean) {
|
||||
|
|
|
@ -4,41 +4,31 @@
|
|||
|
||||
package org.mozilla.fenix.tabstray
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
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.ext.flowScoped
|
||||
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
||||
import mozilla.components.lib.state.helpers.AbstractBinding
|
||||
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
|
||||
import mozilla.components.ui.tabcounter.TabCounter
|
||||
|
||||
/**
|
||||
* Updates the tab counter to the size of [BrowserState.normalTabs].
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class TabCounterBinding(
|
||||
private val store: BrowserStore,
|
||||
private val counter: TabCounter
|
||||
) : LifecycleAwareFeature {
|
||||
) : AbstractBinding<BrowserState>(store) {
|
||||
|
||||
private var scope: CoroutineScope? = null
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun start() {
|
||||
scope = store.flowScoped { flow ->
|
||||
flow.map { it.normalTabs }
|
||||
.ifChanged()
|
||||
.collect {
|
||||
counter.setCount(it.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
scope?.cancel()
|
||||
override suspend fun onState(flow: Flow<BrowserState>) {
|
||||
flow.map { it.normalTabs }
|
||||
.ifChanged()
|
||||
.collect {
|
||||
counter.setCount(it.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,16 +9,15 @@ import android.view.View.VISIBLE
|
|||
import android.view.ViewGroup
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import kotlin.math.max
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
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.ext.flowScoped
|
||||
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
||||
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
|
||||
|
@ -26,34 +25,27 @@ import org.mozilla.fenix.components.metrics.Event
|
|||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class TabsTrayInfoBannerBinding(
|
||||
private val context: Context,
|
||||
private val store: BrowserStore,
|
||||
store: BrowserStore,
|
||||
private val infoBannerView: ViewGroup,
|
||||
private val settings: Settings,
|
||||
private val navigationInteractor: NavigationInteractor,
|
||||
private val metrics: MetricController?
|
||||
) : LifecycleAwareFeature {
|
||||
private var scope: CoroutineScope? = null
|
||||
) : AbstractBinding<BrowserState>(store) {
|
||||
|
||||
@VisibleForTesting
|
||||
internal var banner: InfoBanner? = null
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
override fun start() {
|
||||
scope = store.flowScoped { flow ->
|
||||
flow.map { state -> max(state.normalTabs.size, state.privateTabs.size) }
|
||||
.ifChanged()
|
||||
.collect { tabCount ->
|
||||
if (tabCount >= TAB_COUNT_SHOW_CFR) {
|
||||
displayInfoBannerIfNeeded(settings)
|
||||
}
|
||||
override suspend fun onState(flow: Flow<BrowserState>) {
|
||||
flow.map { state -> max(state.normalTabs.size, state.privateTabs.size) }
|
||||
.ifChanged()
|
||||
.collect { tabCount ->
|
||||
if (tabCount >= TAB_COUNT_SHOW_CFR) {
|
||||
displayInfoBannerIfNeeded(settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
scope?.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
private fun displayInfoBannerIfNeeded(settings: Settings) {
|
||||
|
|
|
@ -4,44 +4,36 @@
|
|||
|
||||
package org.mozilla.fenix.tabstray.browser
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.drop
|
||||
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.ext.flowScoped
|
||||
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
||||
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
|
||||
|
||||
/**
|
||||
* Notifies the adapter when the selection mode changes.
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class SelectedItemAdapterBinding(
|
||||
val store: TabsTrayStore,
|
||||
store: TabsTrayStore,
|
||||
val adapter: BrowserTabsAdapter
|
||||
) : LifecycleAwareFeature {
|
||||
private var scope: CoroutineScope? = null
|
||||
) : AbstractBinding<TabsTrayState>(store) {
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun start() {
|
||||
scope = store.flowScoped { flow ->
|
||||
flow.map { it.mode }
|
||||
// ignore initial mode update; the adapter is already in an updated state.
|
||||
.drop(1)
|
||||
.ifChanged()
|
||||
.collect { mode ->
|
||||
notifyAdapter(mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
scope?.cancel()
|
||||
override suspend fun onState(flow: Flow<TabsTrayState>) {
|
||||
flow.map { it.mode }
|
||||
// ignore initial mode update; the adapter is already in an updated state.
|
||||
.drop(1)
|
||||
.ifChanged()
|
||||
.collect { mode ->
|
||||
notifyAdapter(mode)
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyAdapter(mode: Mode) = with(adapter) {
|
||||
|
|
|
@ -12,13 +12,14 @@ import androidx.core.view.isVisible
|
|||
import kotlinx.android.synthetic.main.component_tabstray2.view.exit_multi_select
|
||||
import kotlinx.android.synthetic.main.component_tabstray2.view.multiselect_title
|
||||
import kotlinx.android.synthetic.main.tabstray_multiselect_items.view.*
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.drop
|
||||
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.components.AbstractBinding
|
||||
import org.mozilla.fenix.tabstray.NavigationInteractor
|
||||
import org.mozilla.fenix.tabstray.TabsTrayInteractor
|
||||
import org.mozilla.fenix.tabstray.TabsTrayState
|
||||
|
@ -41,6 +42,7 @@ import org.mozilla.fenix.tabstray.ext.showWithTheme
|
|||
* @property showOnSelectViews A variable list of views that will be made visible when in select mode.
|
||||
* @property showOnNormalViews A variable list of views that will be made visible when in normal mode.
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Suppress("LongParameterList")
|
||||
class SelectionBannerBinding(
|
||||
private val context: Context,
|
||||
|
|
|
@ -10,13 +10,14 @@ import androidx.constraintlayout.widget.ConstraintLayout
|
|||
import androidx.constraintlayout.widget.ConstraintSet
|
||||
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.drop
|
||||
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.components.AbstractBinding
|
||||
import org.mozilla.fenix.tabstray.TabsTrayState
|
||||
import org.mozilla.fenix.tabstray.TabsTrayState.Mode
|
||||
import org.mozilla.fenix.tabstray.TabsTrayStore
|
||||
|
@ -31,6 +32,7 @@ private const val NORMAL_HANDLE_PERCENT_WIDTH = 0.1F
|
|||
* @property handle The "handle" of the Tabs Tray that is used to drag the tray open/close.
|
||||
* @property containerLayout The [ConstraintLayout] that contains the "handle".
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class SelectionHandleBinding(
|
||||
store: TabsTrayStore,
|
||||
private val handle: View,
|
||||
|
|
|
@ -4,13 +4,11 @@
|
|||
|
||||
package org.mozilla.fenix.tabstray.browser
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.map
|
||||
import mozilla.components.lib.state.ext.flowScoped
|
||||
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
||||
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
|
||||
|
@ -18,25 +16,18 @@ import org.mozilla.fenix.tabstray.TabsTrayStore
|
|||
/**
|
||||
* Notifies whether a tab is accessible for using the swipe-to-delete gesture.
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class SwipeToDeleteBinding(
|
||||
private val store: TabsTrayStore
|
||||
) : LifecycleAwareFeature {
|
||||
private var scope: CoroutineScope? = null
|
||||
) : AbstractBinding<TabsTrayState>(store) {
|
||||
var isSwipeable = false
|
||||
private set
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun start() {
|
||||
scope = store.flowScoped { flow ->
|
||||
flow.map { it.mode }
|
||||
.ifChanged()
|
||||
.collect { mode ->
|
||||
isSwipeable = mode == TabsTrayState.Mode.Normal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
scope?.cancel()
|
||||
override suspend fun onState(flow: Flow<TabsTrayState>) {
|
||||
flow.map { it.mode }
|
||||
.ifChanged()
|
||||
.collect { mode ->
|
||||
isSwipeable = mode == TabsTrayState.Mode.Normal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
|
||||
package org.mozilla.fenix.tabstray.syncedtabs
|
||||
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
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.components.AbstractBinding
|
||||
import org.mozilla.fenix.tabstray.TabsTrayState
|
||||
import org.mozilla.fenix.tabstray.TabsTrayStore
|
||||
|
||||
|
@ -19,6 +20,7 @@ import org.mozilla.fenix.tabstray.TabsTrayStore
|
|||
*
|
||||
* This binding is useful for connecting with [SyncedTabsView.Listener].
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class SyncButtonBinding(
|
||||
tabsTrayStore: TabsTrayStore,
|
||||
private val onSyncNow: () -> Unit
|
||||
|
|
|
@ -1,71 +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
|
||||
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||
import mozilla.components.browser.state.action.TabListAction
|
||||
import mozilla.components.browser.state.state.BrowserState
|
||||
import mozilla.components.browser.state.state.createTab
|
||||
import mozilla.components.browser.state.store.BrowserStore
|
||||
import mozilla.components.support.test.libstate.ext.waitUntilIdle
|
||||
import mozilla.components.support.test.rule.MainCoroutineRule
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
class AbstractBindingTest {
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@get:Rule
|
||||
val coroutinesTestRule = MainCoroutineRule(TestCoroutineDispatcher())
|
||||
|
||||
@Test
|
||||
fun `WHEN started THEN onState flow is invoked`() {
|
||||
val store = BrowserStore()
|
||||
var invoked = false
|
||||
val binding = TestBinding(store) {
|
||||
invoked = true
|
||||
}
|
||||
|
||||
binding.start()
|
||||
|
||||
store.waitUntilIdle()
|
||||
|
||||
assertTrue(invoked)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN actions are dispatched THEN onState flow is invoked`() {
|
||||
val store = BrowserStore()
|
||||
var invoked = false
|
||||
val binding = TestBinding(store) {
|
||||
if (store.state.tabs.isNotEmpty()) {
|
||||
invoked = true
|
||||
}
|
||||
}
|
||||
|
||||
binding.start()
|
||||
|
||||
store.dispatch(TabListAction.AddTabAction(createTab("https://mozilla.org")))
|
||||
|
||||
store.waitUntilIdle()
|
||||
|
||||
assertTrue(invoked)
|
||||
}
|
||||
|
||||
class TestBinding(
|
||||
store: BrowserStore,
|
||||
private val invoked: (BrowserState) -> Unit
|
||||
) : AbstractBinding<BrowserState>(store) {
|
||||
override suspend fun onState(flow: Flow<BrowserState>) {
|
||||
flow.collect {
|
||||
invoked(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -145,6 +145,7 @@ object Deps {
|
|||
const val mozilla_lib_crash = "org.mozilla.components:lib-crash:${Versions.mozilla_android_components}"
|
||||
const val mozilla_lib_push_firebase = "org.mozilla.components:lib-push-firebase:${Versions.mozilla_android_components}"
|
||||
const val mozilla_lib_dataprotect = "org.mozilla.components:lib-dataprotect:${Versions.mozilla_android_components}"
|
||||
const val mozilla_lib_state = "org.mozilla.components:lib-state:${Versions.mozilla_android_components}"
|
||||
|
||||
const val mozilla_lib_publicsuffixlist = "org.mozilla.components:lib-publicsuffixlist:${Versions.mozilla_android_components}"
|
||||
|
||||
|
|
Loading…
Reference in New Issue