Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-25 03:20:02 -07:00
parent e5c441a9f0
commit acb79b2490
17 changed files with 491 additions and 15 deletions

View file

@ -50,6 +50,7 @@ dependencies {
implementation(projects.domain.legacy)
implementation(projects.domain.settings)
implementation(projects.domain.visa)
implementation(projects.domain.virtualAccount)
/* SDK */
// TODO: For TangemError model, should be removed after card domain scanning refactoring

View file

@ -22,6 +22,9 @@ import com.tangem.domain.pay.TangemPayEligibilityManager
import com.tangem.domain.pay.model.TangemPayEntryPoint
import com.tangem.domain.tangempay.GetTangemPayCustomerIdUseCase
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
import com.tangem.domain.virtualaccount.model.VirtualAccountEligibility
import com.tangem.domain.virtualaccount.model.VirtualAccountEntryPoint
import com.tangem.domain.virtualaccount.usecase.GetVirtualAccountEligibilityUseCase
import com.tangem.domain.walletconnect.CheckIsWalletConnectAvailableUseCase
import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
@ -67,6 +70,7 @@ internal class DetailsModel @Inject constructor(
private val generateBuyTangemCardLinkUseCase: GenerateBuyTangemCardLinkUseCase,
private val analyticsEventHandler: AnalyticsEventHandler,
private val tangemPayEligibilityManager: TangemPayEligibilityManager,
private val getVirtualAccountEligibilityUseCase: GetVirtualAccountEligibilityUseCase,
) : Model() {
private val params: DetailsComponent.Params = paramsContainer.require()
@ -99,6 +103,7 @@ internal class DetailsModel @Inject constructor(
)
addTangemPayItemIfEligible()
addVirtualAccountItemIfEligible()
state = MutableStateFlow(
value = DetailsUM(
@ -285,5 +290,32 @@ internal class DetailsModel @Inject constructor(
}
}
private fun addVirtualAccountItemIfEligible() {
modelScope.launch {
val eligibility = getVirtualAccountEligibilityUseCase(VirtualAccountEntryPoint.DETAILS)
if (eligibility is VirtualAccountEligibility.Available) {
items.update { items ->
itemsBuilder.addVirtualAccountItem(
items = items,
onClick = ::onVirtualAccountItemClicked,
)
}
}
}
}
private fun onVirtualAccountItemClicked() {
modelScope.launch {
when (val eligibility = getVirtualAccountEligibilityUseCase(VirtualAccountEntryPoint.DETAILS)) {
is VirtualAccountEligibility.Available -> router.push(
AppRoute.VirtualAccountOnboarding(
AppRoute.VirtualAccountOnboarding.Mode.FromDetailsScreen(eligibility.wallets.first().walletId),
),
)
VirtualAccountEligibility.NotAvailable -> items.update { itemsBuilder.removeVirtualAccountItem(it) }
}
}
}
private fun getAppVersion(): String = "${appInfoProvider.appVersion} (${appInfoProvider.appVersionCode})"
}

View file

@ -16,6 +16,7 @@ import kotlinx.collections.immutable.toPersistentList
import javax.inject.Inject
private const val TANGEM_PAY_ITEM_ID = "get_tangem_pay"
private const val VIRTUAL_ACCOUNT_ITEM_ID = "get_virtual_account"
@ModelScoped
internal class ItemsBuilder @Inject constructor(
@ -81,6 +82,30 @@ internal class ItemsBuilder @Inject constructor(
}.toImmutableList()
}
fun addVirtualAccountItem(items: ImmutableList<DetailsItemUM>, onClick: () -> Unit): ImmutableList<DetailsItemUM> {
return items.map { block ->
if (block.id == "shop" && block is DetailsItemUM.Basic) {
val newItems = block
.items
.toMutableList()
.apply { add(getVirtualAccountItem(onClick = onClick)) }
block.copy(items = newItems.toImmutableList())
} else {
block
}
}.toImmutableList()
}
fun removeVirtualAccountItem(items: ImmutableList<DetailsItemUM>): ImmutableList<DetailsItemUM> {
return items.map { block ->
if (block is DetailsItemUM.Basic && block.items.any { it.id == VIRTUAL_ACCOUNT_ITEM_ID }) {
block.copy(items = block.items.filter { it.id != VIRTUAL_ACCOUNT_ITEM_ID }.toImmutableList())
} else {
block
}
}.toImmutableList()
}
private fun buildWalletConnectBlock(isWalletConnectAvailable: Boolean, userWalletId: UserWalletId): DetailsItemUM? {
return if (isWalletConnectAvailable) {
DetailsItemUM.WalletConnect(
@ -194,4 +219,13 @@ internal class ItemsBuilder @Inject constructor(
onClick = onClick,
),
)
private fun getVirtualAccountItem(onClick: () -> Unit): DetailsItemUM.Basic.Item = DetailsItemUM.Basic.Item(
id = VIRTUAL_ACCOUNT_ITEM_ID,
block = BlockUM(
text = resourceReference(R.string.virtual_account_title),
iconRes = R.drawable.ic_tangem_pay_24,
onClick = onClick,
),
)
}