Updated on 2026-08-14
This commit is contained in:
parent
2b928cfa9d
commit
7472e7b1dc
13 changed files with 138 additions and 5 deletions
|
|
@ -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.model.Model
|
||||
import com.tangem.features.promobanners.api.deeplink.CampaignsDeepLinkHandler
|
||||
import com.tangem.features.promobanners.api.swapcashback.CampaignsComponent
|
||||
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.CampaignsModel
|
||||
import com.tangem.features.promobanners.impl.campaigns.service.CampaignsService
|
||||
import com.tangem.features.promobanners.impl.campaigns.service.DefaultCampaignsService
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -21,6 +25,16 @@ internal interface CampaignsModule {
|
|||
@Binds
|
||||
@Singleton
|
||||
fun bindCampaignsComponentFactory(factory: DefaultCampaignsComponent.Factory): CampaignsComponent.Factory
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindCampaignsDeepLinkHandlerFactory(
|
||||
factory: DefaultCampaignsDeepLinkHandler.Factory,
|
||||
): CampaignsDeepLinkHandler.Factory
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindCampaignsService(service: DefaultCampaignsService): CampaignsService
|
||||
}
|
||||
|
||||
@Module
|
||||
|
|
|
|||
|
|
@ -5,24 +5,28 @@ import com.arkivanov.decompose.router.slot.activate
|
|||
import com.arkivanov.decompose.router.slot.dismiss
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
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.CampaignType
|
||||
import com.tangem.features.promobanners.impl.campaigns.service.CampaignsService
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import javax.inject.Inject
|
||||
|
||||
@ModelScoped
|
||||
internal class CampaignsModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
// private val campaignIdConverter: CampaignIdConverter,
|
||||
// campaignsService: CampaignsService,
|
||||
private val campaignIdConverter: CampaignIdConverter,
|
||||
campaignsService: CampaignsService,
|
||||
) : Model() {
|
||||
|
||||
val bottomSheetNavigation: SlotNavigation<CampaignsBottomSheetConfig> = SlotNavigation()
|
||||
|
||||
init {
|
||||
// campaignsService.campaignFlow
|
||||
// .onEach { campaignId -> resolveStartNavigation(campaignIdConverter.convert(campaignId)) }
|
||||
// .launchIn(modelScope)
|
||||
campaignsService.campaignFlow
|
||||
.onEach { campaignId -> resolveStartNavigation(campaignIdConverter.convert(campaignId)) }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
@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