Updated on 2026-08-14
This commit is contained in:
parent
3e8e14a114
commit
720d5e0cb7
9 changed files with 91 additions and 16 deletions
|
|
@ -21,6 +21,7 @@ import com.tangem.features.tangempay.cashback.api.TangemPayCashbackComponent
|
|||
import com.tangem.features.tangempay.navigation.TangemPayAccountDetailsInnerRoute
|
||||
import com.tangem.features.tangempay.tiers.current.TangemPayCurrentPlanComponent
|
||||
import com.tangem.features.tangempay.tiers.select.TangemPaySelectPlanComponent
|
||||
import com.tangem.features.tangempay.tiers.select.TangemPaySelectPlanSource
|
||||
import com.tangem.features.tangempay.utils.tariffPlan
|
||||
import com.tangem.features.tangempay.utils.userWalletId
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
||||
|
|
@ -61,8 +62,11 @@ internal class DefaultTangemPayDetailsContainerComponent @AssistedInject constru
|
|||
val tariffPlan = params.initialStatus.tariffPlan
|
||||
return when (params.initialRoute) {
|
||||
TangemPayDetailsInitialRoute.ACCOUNT_DETAILS -> TangemPayAccountDetailsInnerRoute.AccountDetails
|
||||
TangemPayDetailsInitialRoute.SELECT_PLAN -> if (tariffPlan != null) {
|
||||
TangemPayAccountDetailsInnerRoute.SelectPlan(tariffPlan = tariffPlan)
|
||||
TangemPayDetailsInitialRoute.TIERS_ONBOARDING -> if (tariffPlan != null) {
|
||||
TangemPayAccountDetailsInnerRoute.SelectPlan(
|
||||
tariffPlan = tariffPlan,
|
||||
source = TangemPaySelectPlanSource.TIERS_ONBOARDING,
|
||||
)
|
||||
} else {
|
||||
TangemPayAccountDetailsInnerRoute.AccountDetails
|
||||
}
|
||||
|
|
@ -117,6 +121,7 @@ internal class DefaultTangemPayDetailsContainerComponent @AssistedInject constru
|
|||
params = TangemPaySelectPlanComponent.Params(
|
||||
userWalletId = params.initialStatus.userWalletId,
|
||||
tariffPlan = config.tariffPlan,
|
||||
source = config.source,
|
||||
),
|
||||
)
|
||||
TangemPayAccountDetailsInnerRoute.VirtualAccountDepositSuccess ->
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.features.tangempay.navigation
|
|||
import com.tangem.core.decompose.navigation.Route
|
||||
import com.tangem.domain.models.account.TangemPayCustomerTariffPlan
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import com.tangem.features.tangempay.tiers.select.TangemPaySelectPlanSource
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
|
|
@ -24,6 +25,7 @@ internal sealed class TangemPayAccountDetailsInnerRoute : Route {
|
|||
@Serializable
|
||||
data class SelectPlan(
|
||||
val tariffPlan: TangemPayCustomerTariffPlan,
|
||||
val source: TangemPaySelectPlanSource,
|
||||
) : TangemPayAccountDetailsInnerRoute()
|
||||
|
||||
@Serializable
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.tangempay.tiers.current
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -19,6 +20,8 @@ internal class TangemPayCurrentPlanComponent(
|
|||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
BackHandler { model.onBackClick() }
|
||||
|
||||
val state by model.state.collectAsStateWithLifecycle()
|
||||
TangemPayCurrentPlanScreen(state = state, modifier = modifier)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,21 +13,27 @@ import com.tangem.core.decompose.ui.UiMessageSender
|
|||
import com.tangem.core.ui.utils.DateTimeFormatters
|
||||
import com.tangem.domain.models.account.TangemPayCustomerTariffPlan
|
||||
import com.tangem.domain.models.account.TangemPayTariffPlan
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||
import com.tangem.domain.pay.usecase.CancelTariffPlanPendingTransitionUseCase
|
||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.navigation.TangemPayAccountDetailsInnerRoute
|
||||
import com.tangem.features.tangempay.tiers.formatNextBillingDateOrNull
|
||||
import com.tangem.features.tangempay.tiers.formatRecurringFeeOrNull
|
||||
import com.tangem.features.tangempay.tiers.select.TangemPaySelectPlanSource
|
||||
import com.tangem.features.tangempay.utils.TangemPayMessagesFactory
|
||||
import com.tangem.features.tangempay.utils.tariffPlan
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class TangemPayCurrentPlanModel @Inject constructor(
|
||||
|
|
@ -35,6 +41,7 @@ internal class TangemPayCurrentPlanModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val router: Router,
|
||||
private val cancelPendingTransition: CancelTariffPlanPendingTransitionUseCase,
|
||||
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val analytics: AnalyticsEventHandler,
|
||||
) : Model() {
|
||||
|
|
@ -42,15 +49,37 @@ internal class TangemPayCurrentPlanModel @Inject constructor(
|
|||
private val params = paramsContainer.require<TangemPayCurrentPlanComponent.Params>()
|
||||
|
||||
private var isProcessing: Boolean = false
|
||||
private var currentPlan: TangemPayCustomerTariffPlan = params.tariffPlan
|
||||
|
||||
val state: StateFlow<TangemPayCurrentPlanUM>
|
||||
field = MutableStateFlow(createState(params.tariffPlan))
|
||||
field = MutableStateFlow(createState(currentPlan))
|
||||
|
||||
init {
|
||||
observePlanChanges()
|
||||
}
|
||||
|
||||
private fun observePlanChanges() {
|
||||
modelScope.launch {
|
||||
paymentAccountStatusSupplier(params.userWalletId)
|
||||
.mapNotNull { it.tariffPlan }
|
||||
.distinctUntilChanged()
|
||||
.collect { plan ->
|
||||
currentPlan = plan
|
||||
state.value = createState(plan)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onBackClick() {
|
||||
if (isProcessing) return
|
||||
router.pop()
|
||||
}
|
||||
|
||||
private fun createState(customerPlan: TangemPayCustomerTariffPlan): TangemPayCurrentPlanUM = TangemPayCurrentPlanUM(
|
||||
planName = stringReference(customerPlan.plan.name),
|
||||
notification = createNotification(customerPlan),
|
||||
sections = buildSections(customerPlan.plan),
|
||||
onBackClick = router::pop,
|
||||
onBackClick = ::onBackClick,
|
||||
onChangePlanClick = ::onChangePlanClick
|
||||
.takeIf {
|
||||
customerPlan.status != TangemPayCustomerTariffPlan.Status.DOWNGRADE_PENDING
|
||||
|
|
@ -59,7 +88,12 @@ internal class TangemPayCurrentPlanModel @Inject constructor(
|
|||
|
||||
private fun onChangePlanClick() {
|
||||
analytics.send(TangemPayAnalyticsEvents.Tiers.ChangePlanClicked())
|
||||
router.push(TangemPayAccountDetailsInnerRoute.SelectPlan(params.tariffPlan))
|
||||
router.push(
|
||||
TangemPayAccountDetailsInnerRoute.SelectPlan(
|
||||
tariffPlan = currentPlan,
|
||||
source = TangemPaySelectPlanSource.CHANGE_PLAN,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createNotification(customerPlan: TangemPayCustomerTariffPlan): TangemPayCurrentPlanUM.Notification? {
|
||||
|
|
@ -95,7 +129,7 @@ internal class TangemPayCurrentPlanModel @Inject constructor(
|
|||
|
||||
private fun onStayOnPlanClick() {
|
||||
if (isProcessing) return
|
||||
val customerPlan = params.tariffPlan
|
||||
val customerPlan = currentPlan
|
||||
val targetPlanName = customerPlan.pendingPlan?.name ?: return
|
||||
analytics.send(TangemPayAnalyticsEvents.Tiers.StayOnPlusConditionsClicked())
|
||||
analytics.send(TangemPayAnalyticsEvents.Tiers.StayOnPlusPopupShowed())
|
||||
|
|
@ -112,16 +146,16 @@ internal class TangemPayCurrentPlanModel @Inject constructor(
|
|||
if (isProcessing) return
|
||||
analytics.send(TangemPayAnalyticsEvents.Tiers.StayOnPlusPopupClicked())
|
||||
isProcessing = true
|
||||
state.value = createState(params.tariffPlan)
|
||||
state.value = createState(currentPlan)
|
||||
modelScope.launch {
|
||||
cancelPendingTransition(params.userWalletId).fold(
|
||||
ifRight = { router.pop() },
|
||||
ifRight = {},
|
||||
ifLeft = {
|
||||
isProcessing = false
|
||||
state.value = createState(params.tariffPlan)
|
||||
state.value = createState(currentPlan)
|
||||
uiMessageSender.send(message = TangemPayMessagesFactory.createGenericError())
|
||||
},
|
||||
)
|
||||
isProcessing = false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.tangempay.tiers.select
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -19,6 +20,8 @@ internal class TangemPaySelectPlanComponent(
|
|||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
BackHandler { model.onBackClick() }
|
||||
|
||||
val state by model.state.collectAsStateWithLifecycle()
|
||||
TangemPaySelectPlanScreen(state = state, modifier = modifier)
|
||||
}
|
||||
|
|
@ -26,5 +29,6 @@ internal class TangemPaySelectPlanComponent(
|
|||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val tariffPlan: TangemPayCustomerTariffPlan,
|
||||
val source: TangemPaySelectPlanSource,
|
||||
)
|
||||
}
|
||||
|
|
@ -108,7 +108,7 @@ internal class TangemPaySelectPlanModel @Inject constructor(
|
|||
state.update { buildState(showPlanCompare = false) }
|
||||
}
|
||||
|
||||
private fun onBackClick() {
|
||||
fun onBackClick() {
|
||||
if (isProcessing) return
|
||||
if (isConfirm) {
|
||||
analytics.send(TangemPayAnalyticsEvents.Tiers.PlanChangeCancelClicked())
|
||||
|
|
@ -119,6 +119,11 @@ internal class TangemPaySelectPlanModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun onCloseClick() {
|
||||
if (isProcessing) return
|
||||
router.pop()
|
||||
}
|
||||
|
||||
private fun onConfirmClick() {
|
||||
if (isProcessing) return
|
||||
|
||||
|
|
@ -151,7 +156,16 @@ internal class TangemPaySelectPlanModel @Inject constructor(
|
|||
state.update { buildState() }
|
||||
modelScope.launch {
|
||||
action().fold(
|
||||
ifRight = { router.replaceAll(TangemPayAccountDetailsInnerRoute.AccountDetails) },
|
||||
ifRight = {
|
||||
when (params.source) {
|
||||
TangemPaySelectPlanSource.TIERS_ONBOARDING -> {
|
||||
router.replaceAll(TangemPayAccountDetailsInnerRoute.AccountDetails)
|
||||
}
|
||||
TangemPaySelectPlanSource.CHANGE_PLAN -> {
|
||||
router.pop()
|
||||
}
|
||||
}
|
||||
},
|
||||
ifLeft = {
|
||||
isProcessing = false
|
||||
state.update { buildState() }
|
||||
|
|
@ -173,7 +187,7 @@ internal class TangemPaySelectPlanModel @Inject constructor(
|
|||
selectedIndex = selectedIndex,
|
||||
onPlanSelected = ::onPlanSelected,
|
||||
onBackClick = ::onBackClick,
|
||||
onCloseClick = router::pop,
|
||||
onCloseClick = ::onCloseClick,
|
||||
content = if (isConfirm) buildConfirmContent() else buildSelectContent(),
|
||||
compare = if (showPlanCompare) buildCompare() else null,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.features.tangempay.tiers.select
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
internal enum class TangemPaySelectPlanSource {
|
||||
@SerialName("tiers_onboarding")
|
||||
TIERS_ONBOARDING,
|
||||
|
||||
@SerialName("change_plan")
|
||||
CHANGE_PLAN,
|
||||
}
|
||||
|
|
@ -160,7 +160,7 @@ internal class DefaultWalletRouter @Inject constructor(
|
|||
override fun openTangemPaySelectPlan(status: AccountStatus.Payment) {
|
||||
val route = AppRoute.TangemPayDetails(
|
||||
status = status,
|
||||
initialRoute = TangemPayDetailsInitialRoute.SELECT_PLAN,
|
||||
initialRoute = TangemPayDetailsInitialRoute.TIERS_ONBOARDING,
|
||||
)
|
||||
router.push(route)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue