Updated on 2026-08-14
This commit is contained in:
parent
2b928cfa9d
commit
7472e7b1dc
13 changed files with 138 additions and 5 deletions
|
|
@ -347,6 +347,16 @@
|
||||||
android:host="yield"
|
android:host="yield"
|
||||||
android:scheme="tangem" />
|
android:scheme="tangem" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
|
<data
|
||||||
|
android:host="campaigns"
|
||||||
|
android:scheme="tangem" />
|
||||||
|
</intent-filter>
|
||||||
<intent-filter android:autoVerify="true">
|
<intent-filter android:autoVerify="true">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ internal fun RootContent(
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
wcContent: @Composable (modifier: Modifier) -> Unit,
|
wcContent: @Composable (modifier: Modifier) -> Unit,
|
||||||
|
promoContent: @Composable (modifier: Modifier) -> Unit,
|
||||||
hotAccessCodeContent: @Composable (modifier: Modifier) -> Unit,
|
hotAccessCodeContent: @Composable (modifier: Modifier) -> Unit,
|
||||||
rootDetectedWarningContent: @Composable (modifier: Modifier) -> Unit,
|
rootDetectedWarningContent: @Composable (modifier: Modifier) -> Unit,
|
||||||
scanFailsContent: @Composable (modifier: Modifier) -> Unit,
|
scanFailsContent: @Composable (modifier: Modifier) -> Unit,
|
||||||
|
|
@ -80,6 +81,8 @@ internal fun RootContent(
|
||||||
|
|
||||||
wcContent(Modifier.fillMaxSize())
|
wcContent(Modifier.fillMaxSize())
|
||||||
|
|
||||||
|
promoContent(Modifier.fillMaxSize())
|
||||||
|
|
||||||
hotAccessCodeContent(Modifier.fillMaxSize())
|
hotAccessCodeContent(Modifier.fillMaxSize())
|
||||||
|
|
||||||
rootDetectedWarningContent(Modifier.fillMaxSize())
|
rootDetectedWarningContent(Modifier.fillMaxSize())
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ import com.tangem.features.hotwallet.HotAccessCodeRequestComponent
|
||||||
import com.tangem.features.hotwallet.accesscoderequest.proxy.HotWalletPasswordRequesterProxy
|
import com.tangem.features.hotwallet.accesscoderequest.proxy.HotWalletPasswordRequesterProxy
|
||||||
import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent
|
import com.tangem.features.onboarding.v2.common.analytics.OnboardingEvent
|
||||||
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
|
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
|
||||||
|
import com.tangem.features.promobanners.api.swapcashback.CampaignsComponent
|
||||||
import com.tangem.features.walletconnect.components.WcRoutingComponent
|
import com.tangem.features.walletconnect.components.WcRoutingComponent
|
||||||
import com.tangem.hot.sdk.TangemHotSdk
|
import com.tangem.hot.sdk.TangemHotSdk
|
||||||
import com.tangem.hot.sdk.android.create
|
import com.tangem.hot.sdk.android.create
|
||||||
|
|
@ -83,6 +84,7 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
|
||||||
private val appRouterConfig: AppRouterConfig,
|
private val appRouterConfig: AppRouterConfig,
|
||||||
private val uiDependencies: UiDependencies,
|
private val uiDependencies: UiDependencies,
|
||||||
private val wcRoutingComponentFactory: WcRoutingComponent.Factory,
|
private val wcRoutingComponentFactory: WcRoutingComponent.Factory,
|
||||||
|
private val campaignsComponentFactory: CampaignsComponent.Factory,
|
||||||
private val deeplinkFactory: DeepLinkFactory,
|
private val deeplinkFactory: DeepLinkFactory,
|
||||||
private val tangemHotSDKProxy: TangemHotSDKProxy,
|
private val tangemHotSDKProxy: TangemHotSDKProxy,
|
||||||
private val hotAccessCodeRequestComponentFactory: HotAccessCodeRequestComponent.Factory,
|
private val hotAccessCodeRequestComponentFactory: HotAccessCodeRequestComponent.Factory,
|
||||||
|
|
@ -112,6 +114,11 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
|
||||||
.create(child("wcRoutingComponent"), params = Unit)
|
.create(child("wcRoutingComponent"), params = Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val campaignsComponent: CampaignsComponent by lazy {
|
||||||
|
campaignsComponentFactory
|
||||||
|
.create(child("swapCashbackCampaign"), params = Unit)
|
||||||
|
}
|
||||||
|
|
||||||
private val hotAccessCodeRequestComponent: HotAccessCodeRequestComponent by lazy {
|
private val hotAccessCodeRequestComponent: HotAccessCodeRequestComponent by lazy {
|
||||||
hotAccessCodeRequestComponentFactory
|
hotAccessCodeRequestComponentFactory
|
||||||
.create(child("hotAccessCodeRequestComponent"), Unit)
|
.create(child("hotAccessCodeRequestComponent"), Unit)
|
||||||
|
|
@ -278,6 +285,7 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
|
||||||
onBack = router::pop,
|
onBack = router::pop,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
wcContent = { wcRoutingComponent.Content(it) },
|
wcContent = { wcRoutingComponent.Content(it) },
|
||||||
|
promoContent = { campaignsComponent.Content(it) },
|
||||||
hotAccessCodeContent = { hotAccessCodeRequestComponent.Content(it) },
|
hotAccessCodeContent = { hotAccessCodeRequestComponent.Content(it) },
|
||||||
rootDetectedWarningContent = { rootDetectedWarningComponent.Content(it) },
|
rootDetectedWarningContent = { rootDetectedWarningComponent.Content(it) },
|
||||||
scanFailsContent = { scanFailsComponent.Content(it) },
|
scanFailsContent = { scanFailsComponent.Content(it) },
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import com.tangem.features.onramp.deeplink.BuyDeepLinkHandler
|
||||||
import com.tangem.features.onramp.deeplink.OnrampDeepLinkHandler
|
import com.tangem.features.onramp.deeplink.OnrampDeepLinkHandler
|
||||||
import com.tangem.features.onramp.deeplink.SellDeepLinkHandler
|
import com.tangem.features.onramp.deeplink.SellDeepLinkHandler
|
||||||
import com.tangem.features.onramp.deeplink.SwapDeepLinkHandler
|
import com.tangem.features.onramp.deeplink.SwapDeepLinkHandler
|
||||||
|
import com.tangem.features.promobanners.api.deeplink.CampaignsDeepLinkHandler
|
||||||
import com.tangem.features.send.api.deeplink.SellRedirectDeepLinkHandler
|
import com.tangem.features.send.api.deeplink.SellRedirectDeepLinkHandler
|
||||||
import com.tangem.features.staking.api.deeplink.StakingDeepLinkHandler
|
import com.tangem.features.staking.api.deeplink.StakingDeepLinkHandler
|
||||||
import com.tangem.features.survey.deeplink.SurveyDeepLinkHandler
|
import com.tangem.features.survey.deeplink.SurveyDeepLinkHandler
|
||||||
|
|
@ -66,6 +67,7 @@ internal class DeepLinkFactory @Inject constructor(
|
||||||
private val earnDeepLink: EarnDeepLinkHandler.Factory,
|
private val earnDeepLink: EarnDeepLinkHandler.Factory,
|
||||||
private val yieldDeepLink: YieldDeepLinkHandler.Factory,
|
private val yieldDeepLink: YieldDeepLinkHandler.Factory,
|
||||||
private val surveyDeepLink: SurveyDeepLinkHandler.Factory,
|
private val surveyDeepLink: SurveyDeepLinkHandler.Factory,
|
||||||
|
private val promoCampaignsDeepLink: CampaignsDeepLinkHandler.Factory,
|
||||||
) {
|
) {
|
||||||
private val permittedAppRoute = MutableStateFlow(false)
|
private val permittedAppRoute = MutableStateFlow(false)
|
||||||
|
|
||||||
|
|
@ -181,6 +183,7 @@ internal class DeepLinkFactory @Inject constructor(
|
||||||
DeepLinkRoute.Yield.host -> yieldDeepLink.create(coroutineScope, queryParams)
|
DeepLinkRoute.Yield.host -> yieldDeepLink.create(coroutineScope, queryParams)
|
||||||
DeepLinkRoute.PayAppMain.host -> tangemPayMainDeepLink.create(coroutineScope, queryParams)
|
DeepLinkRoute.PayAppMain.host -> tangemPayMainDeepLink.create(coroutineScope, queryParams)
|
||||||
DeepLinkRoute.Survey.host -> surveyDeepLink.create(queryParams)
|
DeepLinkRoute.Survey.host -> surveyDeepLink.create(queryParams)
|
||||||
|
DeepLinkRoute.Campaigns.host -> promoCampaignsDeepLink.create(queryParams)
|
||||||
else -> {
|
else -> {
|
||||||
TangemLogger.i(
|
TangemLogger.i(
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import com.tangem.features.onramp.deeplink.BuyDeepLinkHandler
|
||||||
import com.tangem.features.onramp.deeplink.OnrampDeepLinkHandler
|
import com.tangem.features.onramp.deeplink.OnrampDeepLinkHandler
|
||||||
import com.tangem.features.onramp.deeplink.SellDeepLinkHandler
|
import com.tangem.features.onramp.deeplink.SellDeepLinkHandler
|
||||||
import com.tangem.features.onramp.deeplink.SwapDeepLinkHandler
|
import com.tangem.features.onramp.deeplink.SwapDeepLinkHandler
|
||||||
|
import com.tangem.features.promobanners.api.deeplink.CampaignsDeepLinkHandler
|
||||||
import com.tangem.features.send.api.deeplink.SellRedirectDeepLinkHandler
|
import com.tangem.features.send.api.deeplink.SellRedirectDeepLinkHandler
|
||||||
import com.tangem.features.staking.api.deeplink.StakingDeepLinkHandler
|
import com.tangem.features.staking.api.deeplink.StakingDeepLinkHandler
|
||||||
import com.tangem.features.tangempay.deeplink.OnboardVisaDeepLinkHandler
|
import com.tangem.features.tangempay.deeplink.OnboardVisaDeepLinkHandler
|
||||||
|
|
@ -117,6 +118,10 @@ class DeepLinkFactoryTest {
|
||||||
every { create(any(), any()) } returns mockk()
|
every { create(any(), any()) } returns mockk()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val campaignsDeepLinkHandlerFactory = mockk<CampaignsDeepLinkHandler.Factory>(relaxed = true) {
|
||||||
|
every { create(any()) } returns mockk()
|
||||||
|
}
|
||||||
|
|
||||||
private val marketsTokenExchangesDeepLinkFactory =
|
private val marketsTokenExchangesDeepLinkFactory =
|
||||||
mockk<MarketsTokenExchangesDeepLinkHandler.Factory>(relaxed = true) {
|
mockk<MarketsTokenExchangesDeepLinkHandler.Factory>(relaxed = true) {
|
||||||
every { create(any(), any()) } returns mockk()
|
every { create(any(), any()) } returns mockk()
|
||||||
|
|
@ -152,6 +157,7 @@ class DeepLinkFactoryTest {
|
||||||
earnDeepLink = earnDeepLinkFactory,
|
earnDeepLink = earnDeepLinkFactory,
|
||||||
yieldDeepLink = yieldDeepLinkFactory,
|
yieldDeepLink = yieldDeepLinkFactory,
|
||||||
surveyDeepLink = surveyDeepLinkFactory,
|
surveyDeepLink = surveyDeepLinkFactory,
|
||||||
|
promoCampaignsDeepLink = campaignsDeepLinkHandlerFactory,
|
||||||
)
|
)
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,10 @@ sealed class DeepLinkRoute {
|
||||||
data object Survey : DeepLinkRoute() {
|
data object Survey : DeepLinkRoute() {
|
||||||
override val host: String = "survey"
|
override val host: String = "survey"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data object Campaigns : DeepLinkRoute() {
|
||||||
|
override val host: String = "campaigns"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class DeepLinkScheme(val scheme: String) {
|
enum class DeepLinkScheme(val scheme: String) {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ object DeeplinkConst {
|
||||||
const val PROMO_CODE_KEY = "promo_code"
|
const val PROMO_CODE_KEY = "promo_code"
|
||||||
const val REF_KEY = "ref"
|
const val REF_KEY = "ref"
|
||||||
const val CAMPAIGN_KEY = "campaign"
|
const val CAMPAIGN_KEY = "campaign"
|
||||||
|
const val CAMPAIGN_ID_KEY = "campaignId"
|
||||||
const val NAME_KEY = "name"
|
const val NAME_KEY = "name"
|
||||||
const val ORDER_KEY = "order"
|
const val ORDER_KEY = "order"
|
||||||
const val INTERVAL_KEY = "interval"
|
const val INTERVAL_KEY = "interval"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.tangem.features.promobanners.api.deeplink
|
||||||
|
|
||||||
|
interface CampaignsDeepLinkHandler {
|
||||||
|
|
||||||
|
interface Factory {
|
||||||
|
fun create(queryParams: Map<String, String>): CampaignsDeepLinkHandler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.tangem.features.promobanners.impl.campaigns.deeplink
|
||||||
|
|
||||||
|
import com.tangem.common.routing.deeplink.DeeplinkConst
|
||||||
|
import com.tangem.features.promobanners.api.deeplink.CampaignsDeepLinkHandler
|
||||||
|
import com.tangem.features.promobanners.api.toggles.PromoBannersFeatureToggles
|
||||||
|
import com.tangem.features.promobanners.impl.campaigns.service.CampaignsService
|
||||||
|
import com.tangem.utils.logging.TangemLogger
|
||||||
|
import dagger.assisted.Assisted
|
||||||
|
import dagger.assisted.AssistedFactory
|
||||||
|
import dagger.assisted.AssistedInject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the campaigns deeplink (`tangem://campaigns?campaignId=1&lang=ru`): extracts the `campaignId` and
|
||||||
|
* pushes it to the promo-campaigns bus. The always-alive [com.tangem.features.promobanners.api.swapcashback
|
||||||
|
* .SwapCashbackCampaignComponent] listens to the bus, maps the id to a campaign type, resolves the campaign
|
||||||
|
* state and shows the right sheet over the current screen.
|
||||||
|
*/
|
||||||
|
internal class DefaultCampaignsDeepLinkHandler @AssistedInject constructor(
|
||||||
|
@Assisted private val queryParams: Map<String, String>,
|
||||||
|
campaignsService: CampaignsService,
|
||||||
|
private val promoBannersFeatureToggles: PromoBannersFeatureToggles,
|
||||||
|
) : CampaignsDeepLinkHandler {
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (promoBannersFeatureToggles.isCampaignsToggleEnabled) {
|
||||||
|
val campaignId = queryParams[DeeplinkConst.CAMPAIGN_ID_KEY].orEmpty()
|
||||||
|
campaignsService.show(campaignId)
|
||||||
|
} else {
|
||||||
|
TangemLogger.i("Campaigns feature is disabled")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AssistedFactory
|
||||||
|
interface Factory : CampaignsDeepLinkHandler.Factory {
|
||||||
|
override fun create(queryParams: Map<String, String>): DefaultCampaignsDeepLinkHandler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,10 +2,14 @@ package com.tangem.features.promobanners.impl.campaigns.di
|
||||||
|
|
||||||
import com.tangem.core.decompose.di.ModelComponent
|
import com.tangem.core.decompose.di.ModelComponent
|
||||||
import com.tangem.core.decompose.model.Model
|
import com.tangem.core.decompose.model.Model
|
||||||
|
import com.tangem.features.promobanners.api.deeplink.CampaignsDeepLinkHandler
|
||||||
import com.tangem.features.promobanners.api.swapcashback.CampaignsComponent
|
import com.tangem.features.promobanners.api.swapcashback.CampaignsComponent
|
||||||
import com.tangem.features.promobanners.impl.campaigns.component.DefaultCampaignsComponent
|
import com.tangem.features.promobanners.impl.campaigns.component.DefaultCampaignsComponent
|
||||||
|
import com.tangem.features.promobanners.impl.campaigns.deeplink.DefaultCampaignsDeepLinkHandler
|
||||||
import com.tangem.features.promobanners.impl.campaigns.model.ActivateCampaignsModel
|
import com.tangem.features.promobanners.impl.campaigns.model.ActivateCampaignsModel
|
||||||
import com.tangem.features.promobanners.impl.campaigns.model.CampaignsModel
|
import com.tangem.features.promobanners.impl.campaigns.model.CampaignsModel
|
||||||
|
import com.tangem.features.promobanners.impl.campaigns.service.CampaignsService
|
||||||
|
import com.tangem.features.promobanners.impl.campaigns.service.DefaultCampaignsService
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
|
@ -21,6 +25,16 @@ internal interface CampaignsModule {
|
||||||
@Binds
|
@Binds
|
||||||
@Singleton
|
@Singleton
|
||||||
fun bindCampaignsComponentFactory(factory: DefaultCampaignsComponent.Factory): CampaignsComponent.Factory
|
fun bindCampaignsComponentFactory(factory: DefaultCampaignsComponent.Factory): CampaignsComponent.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
fun bindCampaignsDeepLinkHandlerFactory(
|
||||||
|
factory: DefaultCampaignsDeepLinkHandler.Factory,
|
||||||
|
): CampaignsDeepLinkHandler.Factory
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@Singleton
|
||||||
|
fun bindCampaignsService(service: DefaultCampaignsService): CampaignsService
|
||||||
}
|
}
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
|
|
|
||||||
|
|
@ -5,24 +5,28 @@ import com.arkivanov.decompose.router.slot.activate
|
||||||
import com.arkivanov.decompose.router.slot.dismiss
|
import com.arkivanov.decompose.router.slot.dismiss
|
||||||
import com.tangem.core.decompose.di.ModelScoped
|
import com.tangem.core.decompose.di.ModelScoped
|
||||||
import com.tangem.core.decompose.model.Model
|
import com.tangem.core.decompose.model.Model
|
||||||
|
import com.tangem.features.promobanners.impl.campaigns.converters.CampaignIdConverter
|
||||||
import com.tangem.features.promobanners.impl.campaigns.entity.CampaignsBottomSheetConfig
|
import com.tangem.features.promobanners.impl.campaigns.entity.CampaignsBottomSheetConfig
|
||||||
import com.tangem.features.promobanners.impl.campaigns.entity.CampaignType
|
import com.tangem.features.promobanners.impl.campaigns.entity.CampaignType
|
||||||
|
import com.tangem.features.promobanners.impl.campaigns.service.CampaignsService
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ModelScoped
|
@ModelScoped
|
||||||
internal class CampaignsModel @Inject constructor(
|
internal class CampaignsModel @Inject constructor(
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
// private val campaignIdConverter: CampaignIdConverter,
|
private val campaignIdConverter: CampaignIdConverter,
|
||||||
// campaignsService: CampaignsService,
|
campaignsService: CampaignsService,
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
val bottomSheetNavigation: SlotNavigation<CampaignsBottomSheetConfig> = SlotNavigation()
|
val bottomSheetNavigation: SlotNavigation<CampaignsBottomSheetConfig> = SlotNavigation()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// campaignsService.campaignFlow
|
campaignsService.campaignFlow
|
||||||
// .onEach { campaignId -> resolveStartNavigation(campaignIdConverter.convert(campaignId)) }
|
.onEach { campaignId -> resolveStartNavigation(campaignIdConverter.convert(campaignId)) }
|
||||||
// .launchIn(modelScope)
|
.launchIn(modelScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UnusedPrivateMember")
|
@Suppress("UnusedPrivateMember")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.tangem.features.promobanners.impl.campaigns.service
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App-wide bus that decouples the promo-campaigns deeplink handler from the UI that shows the campaign
|
||||||
|
* bottom sheet. A producer (deeplink handler) calls [show]; the always-alive campaign component listens
|
||||||
|
* to [campaignFlow] and activates the appropriate sheet over the current screen.
|
||||||
|
*/
|
||||||
|
internal interface CampaignsService {
|
||||||
|
|
||||||
|
/** Emits the campaignId requested via [show]. */
|
||||||
|
val campaignFlow: Flow<String>
|
||||||
|
|
||||||
|
/** Requests showing the campaign identified by [campaignId]. */
|
||||||
|
fun show(campaignId: String)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.tangem.features.promobanners.impl.campaigns.service
|
||||||
|
|
||||||
|
import kotlinx.coroutines.channels.Channel
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
internal class DefaultCampaignsService @Inject constructor() : CampaignsService {
|
||||||
|
|
||||||
|
private val _campaignFlow: Channel<String> = Channel(Channel.BUFFERED)
|
||||||
|
override val campaignFlow: Flow<String> = _campaignFlow.receiveAsFlow()
|
||||||
|
|
||||||
|
override fun show(campaignId: String) {
|
||||||
|
_campaignFlow.trySend(campaignId)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue