Updated on 2026-08-14
This commit is contained in:
parent
bc12ef112d
commit
a887727d6a
25 changed files with 136 additions and 103 deletions
|
|
@ -146,5 +146,9 @@
|
|||
{
|
||||
"name": "AND_15489_EXPRESS_SHARE_BUTTON_ENABLED",
|
||||
"version": "undefined"
|
||||
},
|
||||
{
|
||||
"name": "AND_15235_VISA_MULTIPLE_CARDS",
|
||||
"version": "5.40"
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -274,6 +274,16 @@ sealed class TangemPayAnalyticsEvents(
|
|||
event = "Visa Add Extra Card Clicked",
|
||||
)
|
||||
|
||||
class FakeDoorPopupDisplayed : TangemPayAnalyticsEvents(
|
||||
categoryName = "Visa Card Management",
|
||||
event = "Visa Fakedoor Popup Displayed",
|
||||
)
|
||||
|
||||
class FakeDoorGotitClicked : TangemPayAnalyticsEvents(
|
||||
categoryName = "Visa Card Management",
|
||||
event = "Visa Fakedoor Gotit Clicked",
|
||||
)
|
||||
|
||||
class IssueAdditionalCardPopupShown : TangemPayAnalyticsEvents(
|
||||
categoryName = "Visa Card Management",
|
||||
event = "Visa Extra Card Issuance Popup Displayed",
|
||||
|
|
|
|||
|
|
@ -4,4 +4,5 @@ interface TangemPayFeatureToggles {
|
|||
val isRedesignEnabled: Boolean
|
||||
val isCloseCardEnabled: Boolean
|
||||
val isRemoveAccountEnabled: Boolean
|
||||
val isMultipleCardsEnabled: Boolean
|
||||
}
|
||||
|
|
@ -15,4 +15,7 @@ internal class DefaultTangemPayFeatureToggles(
|
|||
|
||||
override val isRemoveAccountEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15741_VISA_PAY_REMOVE_ACCOUNT)
|
||||
|
||||
override val isMultipleCardsEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15235_VISA_MULTIPLE_CARDS)
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ import com.tangem.core.decompose.context.childByContext
|
|||
import com.tangem.core.decompose.navigation.inner.InnerRouter
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.features.tangempay.navigation.TangemPayAccountDetailsInnerRoute
|
||||
import com.tangem.features.tangempay.utils.userWalletId
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
||||
import com.tangem.features.tokenreceive.TokenReceiveComponent
|
||||
import dagger.assisted.Assisted
|
||||
|
|
@ -72,9 +73,12 @@ internal class DefaultTangemPayDetailsContainerComponent @AssistedInject constru
|
|||
cardId = config.cardId,
|
||||
),
|
||||
)
|
||||
TangemPayAccountDetailsInnerRoute.AddToWallet -> TangemPayAddToWalletComponent(
|
||||
is TangemPayAccountDetailsInnerRoute.AddToWallet -> TangemPayAddToWalletComponent(
|
||||
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
||||
params = params,
|
||||
params = TangemPayAddToWalletComponent.Params(
|
||||
card = config.card,
|
||||
userWalletId = params.initialStatus.userWalletId,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,13 +10,15 @@ import com.tangem.core.decompose.context.AppComponentContext
|
|||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.res.LocalVisaRedesignEnabled
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.tangempay.model.TangemPayAddToWalletModel
|
||||
import com.tangem.features.tangempay.ui.TangemPayAddToWalletScreen
|
||||
import com.tangem.features.tangempay.ui.TangemPayAddToWalletScreenV2
|
||||
|
||||
internal class TangemPayAddToWalletComponent(
|
||||
private val appComponentContext: AppComponentContext,
|
||||
private val params: TangemPayDetailsContainerComponent.Params,
|
||||
params: Params,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
private val model: TangemPayAddToWalletModel = getOrCreateModel(params)
|
||||
|
|
@ -40,4 +42,6 @@ internal class TangemPayAddToWalletComponent(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class Params(val card: TangemPayCard, val userWalletId: UserWalletId)
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ import com.tangem.features.tangempay.TangemPayFeatureToggles
|
|||
import com.tangem.features.tangempay.limit.setup.TangemPayCardLimitSetupComponent
|
||||
import com.tangem.features.tangempay.limit.setup.TangemPayCardLimitSetupSuccessComponent
|
||||
import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute
|
||||
import com.tangem.features.tangempay.utils.userWalletId
|
||||
import com.tangem.features.tokenreceive.TokenReceiveComponent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
|
|
@ -80,20 +81,26 @@ internal class TangemPayCardPageComponent @AssistedInject constructor(
|
|||
),
|
||||
isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled,
|
||||
)
|
||||
TangemPayCardDetailsInnerRoute.AddToWallet -> TangemPayAddToWalletComponent(
|
||||
is TangemPayCardDetailsInnerRoute.AddToWallet -> TangemPayAddToWalletComponent(
|
||||
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
||||
params = TangemPayDetailsContainerComponent.Params(initialStatus = params.initialStatus),
|
||||
params = TangemPayAddToWalletComponent.Params(
|
||||
card = config.card,
|
||||
userWalletId = params.initialStatus.userWalletId,
|
||||
),
|
||||
)
|
||||
is TangemPayCardDetailsInnerRoute.EditCardDisplayName -> TangemPayEditDisplayNameComponent(
|
||||
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
||||
params = TangemPayCardScopedParams(
|
||||
initialStatus = params.initialStatus,
|
||||
cardId = config.cardId,
|
||||
params = TangemPayEditDisplayNameComponent.Params(
|
||||
card = config.card,
|
||||
userWalletId = params.initialStatus.userWalletId,
|
||||
),
|
||||
)
|
||||
TangemPayCardDetailsInnerRoute.LimitSetup -> TangemPayCardLimitSetupComponent(
|
||||
is TangemPayCardDetailsInnerRoute.LimitSetup -> TangemPayCardLimitSetupComponent(
|
||||
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
||||
params = TangemPayDetailsContainerComponent.Params(initialStatus = params.initialStatus),
|
||||
params = TangemPayCardLimitSetupComponent.Params(
|
||||
card = config.card,
|
||||
userWalletId = params.initialStatus.userWalletId,
|
||||
),
|
||||
)
|
||||
TangemPayCardDetailsInnerRoute.LimitSetupSuccess -> TangemPayCardLimitSetupSuccessComponent(
|
||||
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
||||
|
|
|
|||
|
|
@ -10,13 +10,15 @@ import com.tangem.core.decompose.context.AppComponentContext
|
|||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.res.LocalVisaRedesignEnabled
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.tangempay.entity.DisplayNameState
|
||||
import com.tangem.features.tangempay.model.TangemPayEditDisplayNameModel
|
||||
import com.tangem.features.tangempay.ui.TangemPayEditDisplayNameScreen
|
||||
|
||||
internal class TangemPayEditDisplayNameComponent(
|
||||
private val appComponentContext: AppComponentContext,
|
||||
params: TangemPayCardScopedParams,
|
||||
params: Params,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
private val model: TangemPayEditDisplayNameModel = getOrCreateModel(params)
|
||||
|
|
@ -45,4 +47,6 @@ internal class TangemPayEditDisplayNameComponent(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Params(val card: TangemPayCard, val userWalletId: UserWalletId)
|
||||
}
|
||||
|
|
@ -8,11 +8,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
internal class TangemPayCardLimitSetupComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
params: TangemPayDetailsContainerComponent.Params,
|
||||
params: Params,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
private val model: TangemPayCardLimitSetupModel = getOrCreateModel(params)
|
||||
|
|
@ -33,4 +34,6 @@ internal class TangemPayCardLimitSetupComponent(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Params(val card: TangemPayCard, val userWalletId: UserWalletId)
|
||||
}
|
||||
|
|
@ -23,11 +23,8 @@ import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
|||
import com.tangem.domain.pay.usecase.SetTangemPayCardLimitUseCase
|
||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute
|
||||
import com.tangem.features.tangempay.utils.firstCard
|
||||
import com.tangem.features.tangempay.utils.userWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
|
@ -51,9 +48,9 @@ internal class TangemPayCardLimitSetupModel @Inject constructor(
|
|||
private val featureToggles: TangemPayFeatureToggles,
|
||||
) : Model() {
|
||||
|
||||
private val params: TangemPayDetailsContainerComponent.Params = paramsContainer.require()
|
||||
private val cardId: String = params.initialStatus.firstCard().id
|
||||
private val userWalletId = params.initialStatus.userWalletId
|
||||
private val params: TangemPayCardLimitSetupComponent.Params = paramsContainer.require()
|
||||
private val cardId: String = params.card.id
|
||||
private val userWalletId = params.userWalletId
|
||||
private var currentAdminLimit: BigDecimal? = null
|
||||
|
||||
val uiState: StateFlow<TangemPayCardLimitSetupUM>
|
||||
|
|
|
|||
|
|
@ -7,15 +7,13 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent
|
||||
import com.tangem.features.tangempay.components.TangemPayAddToWalletComponent
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.TangemPayAddToWalletStepItemUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayAddToWalletUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
||||
import com.tangem.features.tangempay.model.controller.TangemPayCardDetailsController
|
||||
import com.tangem.features.tangempay.utils.GoogleWalletUtil
|
||||
import com.tangem.features.tangempay.utils.firstCard
|
||||
import com.tangem.features.tangempay.utils.userWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -33,12 +31,12 @@ internal class TangemPayAddToWalletModel @Inject constructor(
|
|||
cardDetailsControllerFactory: TangemPayCardDetailsController.Factory,
|
||||
) : Model() {
|
||||
|
||||
private val params: TangemPayDetailsContainerComponent.Params = paramsContainer.require()
|
||||
private val params: TangemPayAddToWalletComponent.Params = paramsContainer.require()
|
||||
|
||||
private val cardDetailsController = cardDetailsControllerFactory.create(
|
||||
scope = modelScope,
|
||||
initialCard = params.initialStatus.firstCard(),
|
||||
userWalletId = params.initialStatus.userWalletId,
|
||||
card = params.card,
|
||||
userWalletId = params.userWalletId,
|
||||
config = TangemPayCardDetailsController.Config(
|
||||
isEditingNameEnabled = false,
|
||||
shouldShowCardDetailsButtonOnCard = true,
|
||||
|
|
|
|||
|
|
@ -112,9 +112,7 @@ internal class TangemPayCardPageModel @Inject constructor(
|
|||
|
||||
private val cryptoCurrency
|
||||
get() = currentStatus.value.cryptoCurrency
|
||||
|
||||
// Multiple cards are temporarily gated behind the same toggle as close-card.
|
||||
private val isMultipleCardsEnabled: Boolean get() = tangemPayFeatureToggles.isCloseCardEnabled
|
||||
private val isMultipleCardsEnabled: Boolean get() = tangemPayFeatureToggles.isMultipleCardsEnabled
|
||||
|
||||
val uiState: StateFlow<TangemPayCardPageUM>
|
||||
field = MutableStateFlow(
|
||||
|
|
@ -203,13 +201,13 @@ internal class TangemPayCardPageModel @Inject constructor(
|
|||
cards.forEach { card ->
|
||||
ordered[card.id] = cardControllers[card.id] ?: cardDetailsControllerFactory.create(
|
||||
scope = childCardScope(),
|
||||
initialCard = card,
|
||||
card = card,
|
||||
userWalletId = userWalletId,
|
||||
config = TangemPayCardDetailsController.Config(
|
||||
isEditingNameEnabled = true,
|
||||
shouldShowCardDetailsButtonOnCard = false,
|
||||
),
|
||||
onEditNameClick = { router.push(TangemPayCardDetailsInnerRoute.EditCardDisplayName(card.id)) },
|
||||
onEditNameClick = { router.push(TangemPayCardDetailsInnerRoute.EditCardDisplayName(card)) },
|
||||
)
|
||||
}
|
||||
cardControllers.clear()
|
||||
|
|
@ -378,8 +376,9 @@ internal class TangemPayCardPageModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun onClickLimitChange() {
|
||||
val card = selectedCard() ?: return
|
||||
analytics.send(TangemPayAnalyticsEvents.LimitChangeClicked())
|
||||
router.push(TangemPayCardDetailsInnerRoute.LimitSetup)
|
||||
router.push(TangemPayCardDetailsInnerRoute.LimitSetup(card))
|
||||
}
|
||||
|
||||
private fun onClickChangePIN(isPinSet: Boolean) {
|
||||
|
|
@ -542,7 +541,8 @@ internal class TangemPayCardPageModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun onClickAddToWallet() {
|
||||
router.push(TangemPayCardDetailsInnerRoute.AddToWallet)
|
||||
val card = selectedCard() ?: return
|
||||
router.push(TangemPayCardDetailsInnerRoute.AddToWallet(card))
|
||||
}
|
||||
|
||||
private fun onClickCloseBanner() {
|
||||
|
|
|
|||
|
|
@ -99,8 +99,7 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
val cryptoCurrency
|
||||
get() = currentStatus.value.cryptoCurrency
|
||||
|
||||
// Multiple cards are temporarily gated behind the same toggle as close-card.
|
||||
private val isMultipleCardsEnabled: Boolean get() = tangemPayFeatureToggles.isCloseCardEnabled
|
||||
private val isMultipleCardsEnabled: Boolean get() = tangemPayFeatureToggles.isMultipleCardsEnabled
|
||||
|
||||
private val stateFactory = TangemPayDetailsStateFactory(
|
||||
onBack = router::pop,
|
||||
|
|
@ -279,7 +278,8 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
|
||||
private fun onClickAddToWalletBlock() {
|
||||
analytics.send(TangemPayAnalyticsEvents.AddToWalletClicked())
|
||||
router.push(TangemPayAccountDetailsInnerRoute.AddToWallet)
|
||||
val card = currentStatus.value.ifLoadedOrNull { it.cards.firstOrNull() } ?: return
|
||||
router.push(TangemPayAccountDetailsInnerRoute.AddToWallet(card))
|
||||
}
|
||||
|
||||
private fun onClickCloseAddToWalletBlock() {
|
||||
|
|
@ -367,14 +367,19 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
override fun onAddCardClick() {
|
||||
analytics.send(TangemPayAnalyticsEvents.AddExtraCardClicked())
|
||||
if (!isMultipleCardsEnabled) {
|
||||
uiMessageSender.send(TangemPayMessagesFactory.createFutureFeature(onGotItClick = {}))
|
||||
analytics.send(TangemPayAnalyticsEvents.FakeDoorPopupDisplayed())
|
||||
uiMessageSender.send(
|
||||
TangemPayMessagesFactory.createFutureFeature(
|
||||
onGotItClick = {
|
||||
analytics.send(TangemPayAnalyticsEvents.FakeDoorGotitClicked())
|
||||
},
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
val activeCardsCount = currentStatus.value.ifLoadedOrNull { loaded ->
|
||||
loaded.cards.count { it.cardStatus.isActive }
|
||||
} ?: 0
|
||||
if (activeCardsCount >= MAX_ACTIVE_CARDS) {
|
||||
uiMessageSender.send(TangemPayMessagesFactory.createMaximumCardsIssued(maxCards = MAX_ACTIVE_CARDS))
|
||||
val activeCardsCount = currentStatus.value.ifLoadedOrNull { loaded -> loaded.cards.count() } ?: 0
|
||||
if (activeCardsCount >= ALLOWED_MAX_CARDS_COUNT) {
|
||||
uiMessageSender.send(TangemPayMessagesFactory.createMaximumCardsIssued(maxCards = ALLOWED_MAX_CARDS_COUNT))
|
||||
return
|
||||
}
|
||||
modelScope.launch {
|
||||
|
|
@ -459,6 +464,6 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
}
|
||||
|
||||
private companion object {
|
||||
const val MAX_ACTIVE_CARDS = 3
|
||||
const val ALLOWED_MAX_CARDS_COUNT = 3
|
||||
}
|
||||
}
|
||||
|
|
@ -19,13 +19,11 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||
import com.tangem.domain.pay.usecase.UpdateTangemPayCardNameUseCase
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import com.tangem.features.tangempay.components.TangemPayCardScopedParams
|
||||
import com.tangem.features.tangempay.components.TangemPayEditDisplayNameComponent
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayEditDisplayNameUM
|
||||
import com.tangem.features.tangempay.model.controller.TangemPayCardDetailsController
|
||||
import com.tangem.features.tangempay.utils.requireLoaded
|
||||
import com.tangem.features.tangempay.utils.userWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -45,15 +43,15 @@ internal class TangemPayEditDisplayNameModel @Inject constructor(
|
|||
cardDetailsControllerFactory: TangemPayCardDetailsController.Factory,
|
||||
) : Model() {
|
||||
|
||||
private val params: TangemPayCardScopedParams = paramsContainer.require()
|
||||
private val params: TangemPayEditDisplayNameComponent.Params = paramsContainer.require()
|
||||
|
||||
private val card = params.initialStatus.requireLoaded().requireCardWithId(params.cardId)
|
||||
private val card = params.card
|
||||
private val originalDisplayName = card.displayName?.value.orEmpty()
|
||||
|
||||
private val cardDetailsController = cardDetailsControllerFactory.create(
|
||||
scope = modelScope,
|
||||
initialCard = card,
|
||||
userWalletId = params.initialStatus.userWalletId,
|
||||
card = card,
|
||||
userWalletId = params.userWalletId,
|
||||
config = TangemPayCardDetailsController.Config(
|
||||
isEditingNameEnabled = false,
|
||||
shouldShowCardDetailsButtonOnCard = false,
|
||||
|
|
@ -79,7 +77,7 @@ internal class TangemPayEditDisplayNameModel @Inject constructor(
|
|||
)
|
||||
|
||||
init {
|
||||
subscribeToCardNameChanges(card.id, params.initialStatus.userWalletId)
|
||||
subscribeToCardNameChanges(card.id, params.userWalletId)
|
||||
}
|
||||
|
||||
fun isRedesignEnabled() = featureToggles.isRedesignEnabled
|
||||
|
|
@ -126,7 +124,7 @@ internal class TangemPayEditDisplayNameModel @Inject constructor(
|
|||
uiState.update { it.copy(isLoading = true) }
|
||||
updateCardNameUseCase(
|
||||
cardId = card.id,
|
||||
userWalletId = params.initialStatus.userWalletId,
|
||||
userWalletId = params.userWalletId,
|
||||
displayName = cardDisplayName,
|
||||
).onRight {
|
||||
router.pop()
|
||||
|
|
|
|||
|
|
@ -33,12 +33,8 @@ import com.tangem.utils.transformer.update
|
|||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import com.tangem.utils.transformer.update as transformerUpdate
|
||||
|
||||
private const val SHOW_DETAILS_TIME = 30_000L
|
||||
|
|
@ -57,7 +53,7 @@ private const val SHOW_DETAILS_TIME = 30_000L
|
|||
@Stable
|
||||
internal class TangemPayCardDetailsController @AssistedInject constructor(
|
||||
@Assisted private val scope: CoroutineScope,
|
||||
@Assisted private val initialCard: TangemPayCard,
|
||||
@Assisted private val card: TangemPayCard,
|
||||
@Assisted private val userWalletId: UserWalletId,
|
||||
@Assisted private val config: Config,
|
||||
@Assisted private val onEditNameClick: () -> Unit,
|
||||
|
|
@ -69,13 +65,13 @@ internal class TangemPayCardDetailsController @AssistedInject constructor(
|
|||
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier,
|
||||
) {
|
||||
|
||||
val cardId: String = initialCard.id
|
||||
val cardId: String = card.id
|
||||
|
||||
private var frozenStateJob: Job? = null
|
||||
|
||||
private val stateFactory = TangemPayCardDetailsBlockStateFactory(
|
||||
cardNumberEnd = initialCard.lastDigits,
|
||||
displayName = initialCard.displayName,
|
||||
cardNumberEnd = card.lastDigits,
|
||||
displayName = card.displayName,
|
||||
isEditingNameEnabled = config.isEditingNameEnabled,
|
||||
onEditNameClick = onEditNameClick,
|
||||
onReveal = ::requestReveal,
|
||||
|
|
@ -219,7 +215,7 @@ internal class TangemPayCardDetailsController @AssistedInject constructor(
|
|||
interface Factory {
|
||||
fun create(
|
||||
scope: CoroutineScope,
|
||||
initialCard: TangemPayCard,
|
||||
card: TangemPayCard,
|
||||
userWalletId: UserWalletId,
|
||||
config: Config,
|
||||
onEditNameClick: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.tangempay.navigation
|
||||
|
||||
import com.tangem.core.decompose.navigation.Route
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
|
|
@ -12,5 +13,5 @@ internal sealed class TangemPayAccountDetailsInnerRoute : Route {
|
|||
data class CardDetails(val cardId: String) : TangemPayAccountDetailsInnerRoute()
|
||||
|
||||
@Serializable
|
||||
data object AddToWallet : TangemPayAccountDetailsInnerRoute()
|
||||
data class AddToWallet(val card: TangemPayCard) : TangemPayAccountDetailsInnerRoute()
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.tangempay.navigation
|
||||
|
||||
import com.tangem.core.decompose.navigation.Route
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
|
|
@ -16,13 +17,13 @@ internal sealed class TangemPayCardDetailsInnerRoute : Route {
|
|||
data object ChangePINSuccess : TangemPayCardDetailsInnerRoute()
|
||||
|
||||
@Serializable
|
||||
data object AddToWallet : TangemPayCardDetailsInnerRoute()
|
||||
data class AddToWallet(val card: TangemPayCard) : TangemPayCardDetailsInnerRoute()
|
||||
|
||||
@Serializable
|
||||
data class EditCardDisplayName(val cardId: String) : TangemPayCardDetailsInnerRoute()
|
||||
data class EditCardDisplayName(val card: TangemPayCard) : TangemPayCardDetailsInnerRoute()
|
||||
|
||||
@Serializable
|
||||
data object LimitSetup : TangemPayCardDetailsInnerRoute()
|
||||
data class LimitSetup(val card: TangemPayCard) : TangemPayCardDetailsInnerRoute()
|
||||
|
||||
@Serializable
|
||||
data object LimitSetupSuccess : TangemPayCardDetailsInnerRoute()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import com.tangem.core.decompose.model.MutableParamsContainer
|
|||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.pay.*
|
||||
|
|
@ -15,7 +14,6 @@ import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
|||
import com.tangem.domain.pay.usecase.SetTangemPayCardLimitUseCase
|
||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
|
|
@ -52,14 +50,7 @@ internal class TangemPayCardLimitSetupModelTest {
|
|||
state = TangemPayCardState.Active,
|
||||
)
|
||||
|
||||
private val initialStatus: AccountStatus.Payment = AccountStatus.Payment(
|
||||
account = Account.Payment(userWalletId = userWalletId),
|
||||
value = mockk<PaymentAccountStatusValue.Loaded>(relaxed = true) {
|
||||
every { cards } returns listOf(initialCard)
|
||||
},
|
||||
)
|
||||
|
||||
private val params = TangemPayDetailsContainerComponent.Params(initialStatus = initialStatus)
|
||||
private val params = TangemPayCardLimitSetupComponent.Params(card = initialCard, userWalletId = userWalletId)
|
||||
|
||||
private fun createModel(
|
||||
adminLimit: BigDecimal? = BigDecimal("1000"),
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ import arrow.core.left
|
|||
import arrow.core.right
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.error.UniversalError
|
||||
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.account.CardDisplayName
|
||||
|
|
@ -24,19 +24,11 @@ import com.tangem.features.tangempay.entity.CardDataType
|
|||
import com.tangem.features.tangempay.model.listener.CardDetailsEvent
|
||||
import com.tangem.features.tangempay.model.listener.DefaultCardDetailsEventListener
|
||||
import com.tangem.utils.StringsSigns
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.advanceTimeBy
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.coroutines.test.*
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
private const val SHOW_DETAILS_TIME = 30_000L
|
||||
|
|
@ -219,7 +211,7 @@ internal class TangemPayCardDetailsControllerTest {
|
|||
onEditNameClick: () -> Unit = {},
|
||||
): TangemPayCardDetailsController = TangemPayCardDetailsController(
|
||||
scope = scope,
|
||||
initialCard = card,
|
||||
card = card,
|
||||
userWalletId = userWalletId,
|
||||
config = config,
|
||||
onEditNameClick = onEditNameClick,
|
||||
|
|
|
|||
|
|
@ -28,12 +28,14 @@ internal class SetTokenListTransformer(
|
|||
private val isAccountsModeEnabled: Boolean,
|
||||
private val isRedesignEnabled: Boolean,
|
||||
private val isAddAndManageTokensEnabled: Boolean,
|
||||
private val isMultipleCardsEnabled: Boolean,
|
||||
) : WalletStateTransformer(userWallet.walletId) {
|
||||
|
||||
private val tangemPayConverter by lazy {
|
||||
TangemPayMainBlockConverter(
|
||||
tangemPayClickIntents = clickIntents,
|
||||
isRedesignEnabled = isRedesignEnabled,
|
||||
isMultipleCardsEnabled = isMultipleCardsEnabled,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers.convert
|
|||
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import com.tangem.common.ui.R
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.core.ui.format.bigdecimal.formatStyled
|
||||
|
|
@ -23,6 +21,7 @@ import java.util.Currency
|
|||
internal class TangemPayMainBlockConverter(
|
||||
private val tangemPayClickIntents: TangemPayIntents,
|
||||
private val isRedesignEnabled: Boolean,
|
||||
private val isMultipleCardsEnabled: Boolean,
|
||||
) : Converter<AccountStatus.Payment, TangemPayMainUM> {
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||
override fun convert(value: AccountStatus.Payment): TangemPayMainUM {
|
||||
|
|
@ -66,13 +65,19 @@ internal class TangemPayMainBlockConverter(
|
|||
onClick = { tangemPayClickIntents.openDetails(value) },
|
||||
)
|
||||
is PaymentAccountStatusValue.Loaded -> {
|
||||
val cardsCount = statusValue.cards.count()
|
||||
val card = statusValue.cards.firstOrNull() ?: return TangemPayMainUM.TemporaryUnavailable
|
||||
val subtitle = when {
|
||||
isMultipleCardsEnabled -> pluralReference(
|
||||
id = R.plurals.tangempay_cards_count,
|
||||
count = cardsCount,
|
||||
formatArgs = wrappedList(cardsCount),
|
||||
)
|
||||
card.state == TangemPayCardState.Reissuing -> resourceReference(R.string.tangempay_status_replacing)
|
||||
else -> stringReference("*${card.lastDigits}")
|
||||
}
|
||||
TangemPayMainUM.Content(
|
||||
subtitle = if (card.state == TangemPayCardState.Reissuing) {
|
||||
resourceReference(R.string.tangempay_status_replacing)
|
||||
} else {
|
||||
stringReference("*${card.lastDigits}")
|
||||
},
|
||||
subtitle = subtitle,
|
||||
isBalanceFlickering = statusValue.source == StatusSource.CACHE,
|
||||
balance = getBalanceText(
|
||||
currencyCode = statusValue.balance.fiatBalance.currency,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoU
|
|||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles
|
||||
import com.tangem.utils.coroutines.combine7
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
|
|
@ -19,12 +20,7 @@ import dagger.assisted.Assisted
|
|||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.flow.*
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
|
|
@ -44,6 +40,7 @@ internal class AccountListSubscriber @AssistedInject constructor(
|
|||
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
|
||||
private val designFeatureToggles: DesignFeatureToggles,
|
||||
private val walletFeatureToggles: WalletFeatureToggles,
|
||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
) : BasicAccountListSubscriber() {
|
||||
|
||||
override val isAddAndManageTokensEnabled: Boolean
|
||||
|
|
@ -100,6 +97,7 @@ internal class AccountListSubscriber @AssistedInject constructor(
|
|||
yieldSupplyApyMap = yieldSupplyApyMap,
|
||||
stakingAvailabilityMap = stakingAvailabilityMap,
|
||||
shouldShowMainPromo = shouldShowMainPromo,
|
||||
isMultipleCardsEnabled = tangemPayFeatureToggles.isMultipleCardsEnabled,
|
||||
)
|
||||
} else {
|
||||
updateState(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.subscribers
|
||||
|
||||
import com.tangem.common.ui.tokens.TokenConverterParams
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
|
|
@ -7,6 +8,7 @@ import com.tangem.domain.appcurrency.model.AppCurrency
|
|||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.core.utils.getOrElse
|
||||
import com.tangem.domain.models.account.AccountId
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.tokenlist.TokenList
|
||||
import com.tangem.domain.staking.model.StakingAvailability
|
||||
|
|
@ -16,8 +18,6 @@ import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTokenListErrorTransformer
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTokenListTransformer
|
||||
import com.tangem.common.ui.tokens.TokenConverterParams
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
|
|
@ -91,6 +91,7 @@ internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
|
|||
appCurrency: AppCurrency,
|
||||
expandedAccounts: Set<AccountId>,
|
||||
isAccountMode: Boolean,
|
||||
isMultipleCardsEnabled: Boolean,
|
||||
yieldSupplyApyMap: Map<String, BigDecimal> = emptyMap(),
|
||||
stakingAvailabilityMap: Map<CryptoCurrency, StakingAvailability> = emptyMap(),
|
||||
shouldShowMainPromo: Boolean = false,
|
||||
|
|
@ -107,6 +108,7 @@ internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
|
|||
isAccountsModeEnabled = isAccountMode,
|
||||
isRedesignEnabled = true,
|
||||
isAddAndManageTokensEnabled = isAddAndManageTokensEnabled,
|
||||
isMultipleCardsEnabled = isMultipleCardsEnabled,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -171,6 +173,7 @@ internal abstract class BasicAccountListSubscriber : BasicWalletSubscriber() {
|
|||
isAccountsModeEnabled = false,
|
||||
isRedesignEnabled = false,
|
||||
isAddAndManageTokensEnabled = isAddAndManageTokensEnabled,
|
||||
isMultipleCardsEnabled = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
|
|
@ -12,7 +13,9 @@ import dagger.assisted.AssistedInject
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class SingleWalletSubscriber @AssistedInject constructor(
|
||||
@Assisted override val userWallet: UserWallet.Cold,
|
||||
override val accountDependencies: AccountDependencies,
|
||||
|
|
@ -20,6 +23,7 @@ internal class SingleWalletSubscriber @AssistedInject constructor(
|
|||
override val stateController: WalletStateController,
|
||||
override val clickIntents: WalletClickIntents,
|
||||
private val walletFeatureToggles: WalletFeatureToggles,
|
||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
) : BasicAccountListSubscriber() {
|
||||
|
||||
override val isAddAndManageTokensEnabled: Boolean
|
||||
|
|
@ -30,6 +34,7 @@ internal class SingleWalletSubscriber @AssistedInject constructor(
|
|||
flow2 = getAppCurrencyFlow(),
|
||||
flow3 = accountDependencies.expandedAccountsHolder.expandedAccounts(userWallet),
|
||||
flow4 = accountDependencies.isAccountsModeEnabledUseCase(),
|
||||
flow5 = flowOf(tangemPayFeatureToggles.isMultipleCardsEnabled),
|
||||
transform = ::updateState2,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ class SetTokenListTransformerTest {
|
|||
isAccountsModeEnabled = false,
|
||||
isRedesignEnabled = true,
|
||||
isAddAndManageTokensEnabled = false,
|
||||
isMultipleCardsEnabled = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue