Updated on 2026-08-14
This commit is contained in:
parent
2fd16863a7
commit
9b6de19ebe
25 changed files with 376 additions and 201 deletions
|
|
@ -52,6 +52,7 @@ dependencies {
|
||||||
implementation(projects.domain.balanceHiding.models)
|
implementation(projects.domain.balanceHiding.models)
|
||||||
implementation(projects.domain.transaction)
|
implementation(projects.domain.transaction)
|
||||||
implementation(projects.domain.analytics)
|
implementation(projects.domain.analytics)
|
||||||
|
implementation(projects.domain.visa)
|
||||||
|
|
||||||
implementation(projects.common)
|
implementation(projects.common)
|
||||||
implementation(projects.core.analytics)
|
implementation(projects.core.analytics)
|
||||||
|
|
@ -78,6 +79,7 @@ dependencies {
|
||||||
implementation(projects.data.wallets)
|
implementation(projects.data.wallets)
|
||||||
implementation(projects.data.analytics)
|
implementation(projects.data.analytics)
|
||||||
implementation(projects.data.transaction)
|
implementation(projects.data.transaction)
|
||||||
|
implementation(projects.data.visa)
|
||||||
|
|
||||||
/** Features */
|
/** Features */
|
||||||
implementation(projects.features.onboarding)
|
implementation(projects.features.onboarding)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.tangem.tap.di.domain
|
||||||
|
|
||||||
|
import com.tangem.domain.visa.GetVisaCurrencyUseCase
|
||||||
|
import com.tangem.domain.visa.repository.VisaRepository
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.android.components.ViewModelComponent
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(ViewModelComponent::class)
|
||||||
|
internal object VisaDomainModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun provideVisaCurrencyUseCase(visaRepository: VisaRepository): GetVisaCurrencyUseCase {
|
||||||
|
return GetVisaCurrencyUseCase(visaRepository)
|
||||||
|
}
|
||||||
|
}
|
||||||
1
data/visa/.gitignore
vendored
Normal file
1
data/visa/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/build
|
||||||
21
data/visa/build.gradle.kts
Normal file
21
data/visa/build.gradle.kts
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
plugins {
|
||||||
|
alias(deps.plugins.android.library)
|
||||||
|
alias(deps.plugins.kotlin.android)
|
||||||
|
alias(deps.plugins.kotlin.kapt)
|
||||||
|
id("configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.tangem.data.visa"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
/** Project - Domain */
|
||||||
|
implementation(projects.domain.visa)
|
||||||
|
implementation(projects.domain.wallets.models)
|
||||||
|
|
||||||
|
/** DI */
|
||||||
|
implementation(deps.hilt.core)
|
||||||
|
kapt(deps.hilt.kapt)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.tangem.data.visa
|
||||||
|
|
||||||
|
import com.tangem.domain.visa.model.VisaCurrency
|
||||||
|
import com.tangem.domain.visa.repository.VisaRepository
|
||||||
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
|
||||||
|
internal class DummyVisaRepository : VisaRepository {
|
||||||
|
|
||||||
|
override suspend fun getVisaCurrency(userWalletId: UserWalletId, isRefresh: Boolean): VisaCurrency {
|
||||||
|
TODO(reason = "Implement in [REDACTED_JIRA]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.tangem.data.visa.di
|
||||||
|
|
||||||
|
import com.tangem.data.visa.DummyVisaRepository
|
||||||
|
import com.tangem.domain.visa.repository.VisaRepository
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
internal object VisaDataModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideVisaRepository(): VisaRepository {
|
||||||
|
return DummyVisaRepository()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -72,7 +72,10 @@ internal class TangemCardTypesResolver(
|
||||||
override fun isSingleWalletWithToken(): Boolean = walletData?.token != null && !isMultiwalletAllowed()
|
override fun isSingleWalletWithToken(): Boolean = walletData?.token != null && !isMultiwalletAllowed()
|
||||||
|
|
||||||
override fun isMultiwalletAllowed(): Boolean {
|
override fun isMultiwalletAllowed(): Boolean {
|
||||||
return !isTangemTwins() && !card.isStart2Coin && !isTangemNote() &&
|
return !isTangemTwins() &&
|
||||||
|
!card.isStart2Coin &&
|
||||||
|
!isTangemNote() &&
|
||||||
|
!isVisaWallet() &&
|
||||||
(multiWalletAvailable() || card.wallets.firstOrNull()?.curve == EllipticCurve.Secp256k1)
|
(multiWalletAvailable() || card.wallets.firstOrNull()?.curve == EllipticCurve.Secp256k1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,6 +84,7 @@ internal class TangemCardTypesResolver(
|
||||||
override fun getBlockchain(): Blockchain {
|
override fun getBlockchain(): Blockchain {
|
||||||
return when (productType) {
|
return when (productType) {
|
||||||
ProductType.Start2Coin -> if (card.isTestCard) Blockchain.BitcoinTestnet else Blockchain.Bitcoin
|
ProductType.Start2Coin -> if (card.isTestCard) Blockchain.BitcoinTestnet else Blockchain.Bitcoin
|
||||||
|
ProductType.Visa -> Blockchain.PolygonTestnet
|
||||||
else -> {
|
else -> {
|
||||||
val blockchainName: String = walletData?.blockchain
|
val blockchainName: String = walletData?.blockchain
|
||||||
?: if (productType == ProductType.Note) {
|
?: if (productType == ProductType.Note) {
|
||||||
|
|
|
||||||
1
domain/visa/.gitignore
vendored
Normal file
1
domain/visa/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/build
|
||||||
22
domain/visa/build.gradle.kts
Normal file
22
domain/visa/build.gradle.kts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
plugins {
|
||||||
|
alias(deps.plugins.android.library)
|
||||||
|
alias(deps.plugins.kotlin.android)
|
||||||
|
id("configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.tangem.domain.visa"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
/** Project - Domain */
|
||||||
|
implementation(projects.core.utils)
|
||||||
|
implementation(projects.domain.core)
|
||||||
|
implementation(projects.domain.wallets.models)
|
||||||
|
implementation(projects.domain.tokens.models)
|
||||||
|
implementation(projects.domain.appCurrency.models)
|
||||||
|
|
||||||
|
/** Libs - Other */
|
||||||
|
implementation(deps.jodatime)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.tangem.domain.visa
|
||||||
|
|
||||||
|
import arrow.core.Either
|
||||||
|
import com.tangem.domain.visa.model.VisaCurrency
|
||||||
|
import com.tangem.domain.visa.repository.VisaRepository
|
||||||
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
|
||||||
|
class GetVisaCurrencyUseCase(
|
||||||
|
private val repository: VisaRepository,
|
||||||
|
) {
|
||||||
|
|
||||||
|
suspend operator fun invoke(
|
||||||
|
userWalletId: UserWalletId,
|
||||||
|
isRefresh: Boolean = false,
|
||||||
|
): Either<Throwable, VisaCurrency> {
|
||||||
|
return Either.catch { repository.getVisaCurrency(userWalletId, isRefresh) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.tangem.domain.visa.model
|
||||||
|
|
||||||
|
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
import java.math.BigDecimal
|
||||||
|
|
||||||
|
data class VisaCurrency(
|
||||||
|
val networkName: String,
|
||||||
|
val symbol: String,
|
||||||
|
val decimals: Int,
|
||||||
|
val fiatRate: BigDecimal?,
|
||||||
|
val fiatCurrency: AppCurrency,
|
||||||
|
val balances: Balances,
|
||||||
|
val limits: Limits,
|
||||||
|
) {
|
||||||
|
|
||||||
|
data class Balances(
|
||||||
|
val total: BigDecimal,
|
||||||
|
val verified: BigDecimal,
|
||||||
|
val available: BigDecimal,
|
||||||
|
val blocked: BigDecimal,
|
||||||
|
val debt: BigDecimal,
|
||||||
|
val pendingRefund: BigDecimal,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Limits(
|
||||||
|
val remainingOtp: BigDecimal,
|
||||||
|
val remainingNoOtp: BigDecimal,
|
||||||
|
val singleTransaction: BigDecimal,
|
||||||
|
val expirationDate: DateTime,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.tangem.domain.visa.repository
|
||||||
|
|
||||||
|
import com.tangem.domain.visa.model.VisaCurrency
|
||||||
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
|
|
||||||
|
interface VisaRepository {
|
||||||
|
|
||||||
|
suspend fun getVisaCurrency(userWalletId: UserWalletId, isRefresh: Boolean = false): VisaCurrency
|
||||||
|
}
|
||||||
|
|
@ -69,6 +69,7 @@ dependencies {
|
||||||
implementation(projects.domain.balanceHiding)
|
implementation(projects.domain.balanceHiding)
|
||||||
implementation(projects.domain.balanceHiding.models)
|
implementation(projects.domain.balanceHiding.models)
|
||||||
implementation(projects.domain.analytics)
|
implementation(projects.domain.analytics)
|
||||||
|
implementation(projects.domain.visa)
|
||||||
|
|
||||||
//TODO: Create api/impl modules for onboarding [REDACTED_JIRA]
|
//TODO: Create api/impl modules for onboarding [REDACTED_JIRA]
|
||||||
implementation(projects.features.onboarding)
|
implementation(projects.features.onboarding)
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
||||||
|
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
|
||||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
|
||||||
import com.tangem.domain.settings.SetWalletWithFundsFoundUseCase
|
|
||||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||||
|
import com.tangem.domain.visa.GetVisaCurrencyUseCase
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.WalletStateController
|
import com.tangem.feature.wallet.presentation.wallet.state2.WalletStateController
|
||||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.PrimaryCurrencySubscriber
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.TxHistorySubscriber
|
import com.tangem.feature.wallet.presentation.wallet.subscribers.TxHistorySubscriber
|
||||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.VisaWalletBalancesAndLimitsSubscriber
|
import com.tangem.feature.wallet.presentation.wallet.subscribers.VisaWalletBalancesAndLimitsSubscriber
|
||||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.WalletSubscriber
|
import com.tangem.feature.wallet.presentation.wallet.subscribers.WalletSubscriber
|
||||||
|
|
@ -21,24 +18,20 @@ internal class VisaWalletContentLoader(
|
||||||
private val isRefresh: Boolean,
|
private val isRefresh: Boolean,
|
||||||
private val stateHolder: WalletStateController,
|
private val stateHolder: WalletStateController,
|
||||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||||
private val setWalletWithFundsFoundUseCase: SetWalletWithFundsFoundUseCase,
|
|
||||||
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
||||||
private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase,
|
private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase,
|
||||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
private val getVisaCurrencyUseCase: GetVisaCurrencyUseCase,
|
||||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
|
||||||
) : WalletContentLoader(id = userWallet.walletId) {
|
) : WalletContentLoader(id = userWallet.walletId) {
|
||||||
|
|
||||||
override fun create(): List<WalletSubscriber> {
|
override fun create(): List<WalletSubscriber> {
|
||||||
return listOf(
|
return listOf(
|
||||||
PrimaryCurrencySubscriber(
|
VisaWalletBalancesAndLimitsSubscriber(
|
||||||
userWallet = userWallet,
|
userWallet = userWallet,
|
||||||
stateHolder = stateHolder,
|
stateHolder = stateHolder,
|
||||||
getPrimaryCurrencyStatusUpdatesUseCase = getPrimaryCurrencyStatusUpdatesUseCase,
|
isRefresh = isRefresh,
|
||||||
setWalletWithFundsFoundUseCase = setWalletWithFundsFoundUseCase,
|
getVisaCurrencyUseCase = getVisaCurrencyUseCase,
|
||||||
analyticsEventHandler = analyticsEventHandler,
|
clickIntents = clickIntents,
|
||||||
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
|
|
||||||
),
|
),
|
||||||
VisaWalletBalancesAndLimitsSubscriber(userWallet, stateHolder, clickIntents),
|
|
||||||
TxHistorySubscriber(
|
TxHistorySubscriber(
|
||||||
userWallet = userWallet,
|
userWallet = userWallet,
|
||||||
isRefresh = isRefresh,
|
isRefresh = isRefresh,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
||||||
|
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
|
||||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
|
||||||
import com.tangem.domain.settings.SetWalletWithFundsFoundUseCase
|
|
||||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||||
|
import com.tangem.domain.visa.GetVisaCurrencyUseCase
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.WalletStateController
|
import com.tangem.feature.wallet.presentation.wallet.state2.WalletStateController
|
||||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntentsV2
|
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntentsV2
|
||||||
|
|
@ -17,11 +15,9 @@ import javax.inject.Inject
|
||||||
internal class VisaWalletContentLoaderFactory @Inject constructor(
|
internal class VisaWalletContentLoaderFactory @Inject constructor(
|
||||||
private val stateHolder: WalletStateController,
|
private val stateHolder: WalletStateController,
|
||||||
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
||||||
private val setWalletWithFundsFoundUseCase: SetWalletWithFundsFoundUseCase,
|
|
||||||
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
||||||
private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase,
|
private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase,
|
||||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
private val getVisaCurrencyUseCase: GetVisaCurrencyUseCase,
|
||||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun create(userWallet: UserWallet, clickIntents: WalletClickIntentsV2, isRefresh: Boolean): WalletContentLoader {
|
fun create(userWallet: UserWallet, clickIntents: WalletClickIntentsV2, isRefresh: Boolean): WalletContentLoader {
|
||||||
|
|
@ -31,11 +27,9 @@ internal class VisaWalletContentLoaderFactory @Inject constructor(
|
||||||
isRefresh = isRefresh,
|
isRefresh = isRefresh,
|
||||||
stateHolder = stateHolder,
|
stateHolder = stateHolder,
|
||||||
getPrimaryCurrencyStatusUpdatesUseCase = getPrimaryCurrencyStatusUpdatesUseCase,
|
getPrimaryCurrencyStatusUpdatesUseCase = getPrimaryCurrencyStatusUpdatesUseCase,
|
||||||
setWalletWithFundsFoundUseCase = setWalletWithFundsFoundUseCase,
|
|
||||||
txHistoryItemsCountUseCase = txHistoryItemsCountUseCase,
|
txHistoryItemsCountUseCase = txHistoryItemsCountUseCase,
|
||||||
txHistoryItemsUseCase = txHistoryItemsUseCase,
|
txHistoryItemsUseCase = txHistoryItemsUseCase,
|
||||||
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
|
getVisaCurrencyUseCase = getVisaCurrencyUseCase,
|
||||||
analyticsEventHandler = analyticsEventHandler,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -11,7 +11,6 @@ internal sealed class BalancesAndLimitsBlockState {
|
||||||
|
|
||||||
data class Content(
|
data class Content(
|
||||||
val availableBalance: String,
|
val availableBalance: String,
|
||||||
val currencySymbol: String,
|
|
||||||
val limitDays: Int,
|
val limitDays: Int,
|
||||||
val isEnabled: Boolean,
|
val isEnabled: Boolean,
|
||||||
val onClick: () -> Unit,
|
val onClick: () -> Unit,
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,98 @@
|
||||||
package com.tangem.feature.wallet.presentation.wallet.state2.transformers
|
package com.tangem.feature.wallet.presentation.wallet.state2.transformers
|
||||||
|
|
||||||
|
import arrow.core.Either
|
||||||
|
import arrow.core.getOrElse
|
||||||
|
import com.tangem.core.ui.extensions.stringReference
|
||||||
|
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||||
|
import com.tangem.domain.visa.model.VisaCurrency
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
|
import com.tangem.feature.wallet.presentation.wallet.domain.getCardsCount
|
||||||
|
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletAdditionalInfo
|
||||||
|
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletCardState
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.model.BalancesAndLimitsBlockState
|
import com.tangem.feature.wallet.presentation.wallet.state2.model.BalancesAndLimitsBlockState
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.model.WalletState
|
import com.tangem.feature.wallet.presentation.wallet.state2.model.WalletState
|
||||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntentsV2
|
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntentsV2
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
import org.joda.time.Days
|
||||||
|
|
||||||
internal class SetBalancesAndLimitsTransformer(
|
internal class SetBalancesAndLimitsTransformer(
|
||||||
userWallet: UserWallet,
|
private val userWallet: UserWallet,
|
||||||
|
private val maybeVisaCurrency: Either<Throwable, VisaCurrency>,
|
||||||
private val clickIntents: WalletClickIntentsV2,
|
private val clickIntents: WalletClickIntentsV2,
|
||||||
) : WalletStateTransformer(userWallet.walletId) {
|
) : WalletStateTransformer(userWallet.walletId) {
|
||||||
|
|
||||||
override fun transform(prevState: WalletState): WalletState {
|
override fun transform(prevState: WalletState): WalletState {
|
||||||
return prevState.transformWhenInState<WalletState.Visa.Content> { state ->
|
return prevState.transformWhenInState<WalletState.Visa.Content> { state ->
|
||||||
|
val visaCurrency = maybeVisaCurrency.getOrElse {
|
||||||
|
return state.copy(
|
||||||
|
walletCardState = getErrorWalletCardState(state.walletCardState),
|
||||||
|
balancesAndLimitBlockState = BalancesAndLimitsBlockState.Error,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
state.copy(
|
state.copy(
|
||||||
balancesAndLimitBlockState = state.balancesAndLimitBlockState.toLoadedState(),
|
walletCardState = getContentWalletCardState(state.walletCardState, visaCurrency),
|
||||||
|
balancesAndLimitBlockState = getContentBlockState(visaCurrency),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement in [REDACTED_JIRA]
|
private fun getContentBlockState(visaCurrency: VisaCurrency) = BalancesAndLimitsBlockState.Content(
|
||||||
@Suppress("UnusedReceiverParameter")
|
availableBalance = BigDecimalFormatter.formatCryptoAmount(
|
||||||
private fun BalancesAndLimitsBlockState.toLoadedState(): BalancesAndLimitsBlockState {
|
visaCurrency.limits.remainingOtp,
|
||||||
return BalancesAndLimitsBlockState.Content(
|
visaCurrency.symbol,
|
||||||
availableBalance = "400.00",
|
visaCurrency.decimals,
|
||||||
currencySymbol = "USDT",
|
),
|
||||||
limitDays = 7,
|
limitDays = Days.daysBetween(DateTime.now(), visaCurrency.limits.expirationDate).days.inc(),
|
||||||
isEnabled = true,
|
isEnabled = true,
|
||||||
onClick = clickIntents::onBalancesAndLimitsClick,
|
onClick = clickIntents::onBalancesAndLimitsClick,
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun getErrorWalletCardState(prevState: WalletCardState): WalletCardState {
|
||||||
|
return with(prevState) {
|
||||||
|
WalletCardState.Error(
|
||||||
|
id = id,
|
||||||
|
title = title,
|
||||||
|
imageResId = imageResId,
|
||||||
|
onRenameClick = onRenameClick,
|
||||||
|
onDeleteClick = onDeleteClick,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getContentWalletCardState(prevState: WalletCardState, visaCurrency: VisaCurrency): WalletCardState {
|
||||||
|
return with(prevState) {
|
||||||
|
WalletCardState.Content(
|
||||||
|
id = id,
|
||||||
|
title = title,
|
||||||
|
additionalInfo = createAdditionalInfo(visaCurrency),
|
||||||
|
imageResId = imageResId,
|
||||||
|
onRenameClick = onRenameClick,
|
||||||
|
onDeleteClick = onDeleteClick,
|
||||||
|
balance = BigDecimalFormatter.formatCryptoAmount(
|
||||||
|
visaCurrency.balances.available,
|
||||||
|
visaCurrency.symbol,
|
||||||
|
visaCurrency.decimals,
|
||||||
|
),
|
||||||
|
cardCount = userWallet.getCardsCount(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createAdditionalInfo(visaCurrency: VisaCurrency): WalletAdditionalInfo {
|
||||||
|
val fiatAmount = BigDecimalFormatter.formatFiatAmount(
|
||||||
|
fiatAmount = visaCurrency.fiatRate?.let { visaCurrency.balances.available.multiply(it) },
|
||||||
|
fiatCurrencyCode = visaCurrency.fiatCurrency.code,
|
||||||
|
fiatCurrencySymbol = visaCurrency.fiatCurrency.symbol,
|
||||||
)
|
)
|
||||||
|
val infoContent = stringReference(
|
||||||
|
value = buildString {
|
||||||
|
append(fiatAmount)
|
||||||
|
append(" • ")
|
||||||
|
append(visaCurrency.networkName)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return WalletAdditionalInfo(hideable = true, infoContent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8,7 +8,6 @@ import com.tangem.feature.wallet.presentation.wallet.state.components.WalletCard
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.model.WalletState
|
import com.tangem.feature.wallet.presentation.wallet.state2.model.WalletState
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.converter.SingleWalletCardStateConverter
|
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.converter.SingleWalletCardStateConverter
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.converter.SingleWalletMarketPriceConverter
|
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.converter.SingleWalletMarketPriceConverter
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.converter.VisaWalletCardStateConverter
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
internal class SetPrimaryCurrencyTransformer(
|
internal class SetPrimaryCurrencyTransformer(
|
||||||
|
|
@ -25,15 +24,11 @@ internal class SetPrimaryCurrencyTransformer(
|
||||||
marketPriceBlockState = prevState.marketPriceBlockState.toLoadedState(),
|
marketPriceBlockState = prevState.marketPriceBlockState.toLoadedState(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is WalletState.Visa.Content -> {
|
is WalletState.Visa -> {
|
||||||
prevState.copy(
|
Timber.w("Impossible to load primary currency status for VISA wallet")
|
||||||
walletCardState = prevState.walletCardState.toLoadedVisaState(),
|
prevState
|
||||||
depositButtonState = prevState.depositButtonState.copy(isEnabled = true),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
is WalletState.Visa.Locked,
|
is WalletState.SingleCurrency.Locked -> {
|
||||||
is WalletState.SingleCurrency.Locked,
|
|
||||||
-> {
|
|
||||||
Timber.w("Impossible to load primary currency status for locked wallet")
|
Timber.w("Impossible to load primary currency status for locked wallet")
|
||||||
prevState
|
prevState
|
||||||
}
|
}
|
||||||
|
|
@ -48,10 +43,6 @@ internal class SetPrimaryCurrencyTransformer(
|
||||||
return SingleWalletCardStateConverter(status.value, userWallet, appCurrency).convert(value = this)
|
return SingleWalletCardStateConverter(status.value, userWallet, appCurrency).convert(value = this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun WalletCardState.toLoadedVisaState(): WalletCardState {
|
|
||||||
return VisaWalletCardStateConverter(status, userWallet, appCurrency).convert(value = this)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MarketPriceBlockState.toLoadedState(): MarketPriceBlockState {
|
private fun MarketPriceBlockState.toLoadedState(): MarketPriceBlockState {
|
||||||
return SingleWalletMarketPriceConverter(status.value, appCurrency).convert(value = this)
|
return SingleWalletMarketPriceConverter(status.value, appCurrency).convert(value = this)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.tangem.feature.wallet.presentation.wallet.state2.transformers.converter
|
||||||
|
|
||||||
|
import com.tangem.core.ui.utils.BigDecimalFormatter
|
||||||
|
import com.tangem.core.ui.utils.DateTimeFormatters
|
||||||
|
import com.tangem.domain.visa.model.VisaCurrency
|
||||||
|
import com.tangem.feature.wallet.presentation.wallet.state.WalletAlertState
|
||||||
|
import com.tangem.feature.wallet.presentation.wallet.state.WalletEvent
|
||||||
|
import com.tangem.feature.wallet.presentation.wallet.state2.model.BalancesAndLimitsBottomSheetConfig
|
||||||
|
import com.tangem.feature.wallet.presentation.wallet.state2.utils.WalletEventSender
|
||||||
|
import com.tangem.utils.converter.Converter
|
||||||
|
import java.math.BigDecimal
|
||||||
|
|
||||||
|
internal class BalancesAndLimitsBottomSheetConverter(
|
||||||
|
private val eventSender: WalletEventSender,
|
||||||
|
) : Converter<VisaCurrency, BalancesAndLimitsBottomSheetConfig> {
|
||||||
|
|
||||||
|
override fun convert(value: VisaCurrency): BalancesAndLimitsBottomSheetConfig {
|
||||||
|
return BalancesAndLimitsBottomSheetConfig(
|
||||||
|
currency = value.symbol,
|
||||||
|
balance = BalancesAndLimitsBottomSheetConfig.Balance(
|
||||||
|
totalBalance = value.balances.total.let(::formatAmount),
|
||||||
|
availableBalance = value.balances.available.let(::formatAmount),
|
||||||
|
blockedBalance = value.balances.blocked.let(::formatAmount),
|
||||||
|
debit = value.balances.debt.let(::formatAmount),
|
||||||
|
pending = value.balances.pendingRefund.let(::formatAmount),
|
||||||
|
amlVerified = value.balances.verified.let(::formatAmount),
|
||||||
|
),
|
||||||
|
limit = BalancesAndLimitsBottomSheetConfig.Limit(
|
||||||
|
availableBy = DateTimeFormatters.formatDate(date = value.limits.expirationDate),
|
||||||
|
inStore = value.limits.remainingOtp.let(::formatAmount),
|
||||||
|
other = value.limits.remainingNoOtp.let(::formatAmount),
|
||||||
|
singleTransaction = value.limits.singleTransaction.let(::formatAmount),
|
||||||
|
),
|
||||||
|
onBalanceInfoClick = this::showBalanceInfo,
|
||||||
|
onLimitInfoClick = this::showLimitInfo,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun formatAmount(amount: BigDecimal): String = BigDecimalFormatter.formatCryptoAmount(
|
||||||
|
amount,
|
||||||
|
cryptoCurrency = "",
|
||||||
|
decimals = 2,
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun showBalanceInfo() {
|
||||||
|
eventSender.send(WalletEvent.ShowAlert(WalletAlertState.VisaBalancesInfo))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showLimitInfo() {
|
||||||
|
eventSender.send(WalletEvent.ShowAlert(WalletAlertState.VisaLimitsInfo))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
package com.tangem.feature.wallet.presentation.wallet.state2.transformers.converter
|
|
||||||
|
|
||||||
import com.tangem.core.ui.extensions.stringReference
|
|
||||||
import com.tangem.core.ui.utils.BigDecimalFormatter
|
|
||||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.domain.getCardsCount
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletAdditionalInfo
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletCardState
|
|
||||||
import com.tangem.utils.converter.Converter
|
|
||||||
|
|
||||||
internal class VisaWalletCardStateConverter(
|
|
||||||
private val status: CryptoCurrencyStatus,
|
|
||||||
private val selectedWallet: UserWallet,
|
|
||||||
private val appCurrency: AppCurrency,
|
|
||||||
) : Converter<WalletCardState, WalletCardState> {
|
|
||||||
|
|
||||||
override fun convert(value: WalletCardState): WalletCardState {
|
|
||||||
return when (status.value) {
|
|
||||||
is CryptoCurrencyStatus.Loading -> value.toLoadingState()
|
|
||||||
is CryptoCurrencyStatus.Custom,
|
|
||||||
is CryptoCurrencyStatus.MissedDerivation,
|
|
||||||
is CryptoCurrencyStatus.Unreachable,
|
|
||||||
-> value.toErrorState()
|
|
||||||
is CryptoCurrencyStatus.NoQuote,
|
|
||||||
is CryptoCurrencyStatus.Loaded,
|
|
||||||
is CryptoCurrencyStatus.NoAccount,
|
|
||||||
is CryptoCurrencyStatus.NoAmount,
|
|
||||||
-> value.toContentState(status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun WalletCardState.toLoadingState(): WalletCardState {
|
|
||||||
return WalletCardState.Loading(
|
|
||||||
id = id,
|
|
||||||
title = title,
|
|
||||||
imageResId = imageResId,
|
|
||||||
onRenameClick = onRenameClick,
|
|
||||||
onDeleteClick = onDeleteClick,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun WalletCardState.toErrorState(): WalletCardState {
|
|
||||||
return WalletCardState.Error(
|
|
||||||
id = id,
|
|
||||||
title = title,
|
|
||||||
imageResId = imageResId,
|
|
||||||
onRenameClick = onRenameClick,
|
|
||||||
onDeleteClick = onDeleteClick,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun WalletCardState.toContentState(status: CryptoCurrencyStatus): WalletCardState {
|
|
||||||
return WalletCardState.Content(
|
|
||||||
id = id,
|
|
||||||
title = title,
|
|
||||||
additionalInfo = createAdditionalInfo(status),
|
|
||||||
imageResId = imageResId,
|
|
||||||
onRenameClick = onRenameClick,
|
|
||||||
onDeleteClick = onDeleteClick,
|
|
||||||
balance = formatAmount(status),
|
|
||||||
cardCount = selectedWallet.getCardsCount(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createAdditionalInfo(status: CryptoCurrencyStatus): WalletAdditionalInfo {
|
|
||||||
val fiatAmount = BigDecimalFormatter.formatFiatAmount(
|
|
||||||
status.value.fiatAmount,
|
|
||||||
fiatCurrencyCode = appCurrency.code,
|
|
||||||
fiatCurrencySymbol = appCurrency.symbol,
|
|
||||||
)
|
|
||||||
val infoContent = stringReference(
|
|
||||||
value = buildString {
|
|
||||||
append(fiatAmount)
|
|
||||||
append(" • ")
|
|
||||||
append(status.currency.network.name)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
return WalletAdditionalInfo(hideable = true, infoContent)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun formatAmount(status: CryptoCurrencyStatus): String {
|
|
||||||
val amount = status.value.amount ?: return BigDecimalFormatter.EMPTY_BALANCE_SIGN
|
|
||||||
|
|
||||||
return BigDecimalFormatter.formatCryptoAmount(amount, status.currency)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,6 +3,8 @@ package com.tangem.feature.wallet.presentation.wallet.subscribers
|
||||||
import androidx.paging.PagingData
|
import androidx.paging.PagingData
|
||||||
import androidx.paging.cachedIn
|
import androidx.paging.cachedIn
|
||||||
import arrow.core.Either
|
import arrow.core.Either
|
||||||
|
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||||
|
import com.tangem.domain.common.util.cardTypesResolver
|
||||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||||
|
|
@ -13,10 +15,8 @@ import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.feature.wallet.presentation.wallet.domain.collectLatest
|
import com.tangem.feature.wallet.presentation.wallet.domain.collectLatest
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.WalletStateController
|
import com.tangem.feature.wallet.presentation.wallet.state2.WalletStateController
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.SetTxHistoryCountErrorTransformer
|
import com.tangem.feature.wallet.presentation.wallet.state2.model.WalletState
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.SetTxHistoryCountTransformer
|
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.*
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.SetTxHistoryItemsErrorTransformer
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.SetTxHistoryItemsTransformer
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntentsV2
|
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntentsV2
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
@ -37,6 +37,24 @@ internal class TxHistorySubscriber(
|
||||||
) : WalletSubscriber() {
|
) : WalletSubscriber() {
|
||||||
|
|
||||||
override fun create(coroutineScope: CoroutineScope): Flow<PagingData<TxHistoryItem>> {
|
override fun create(coroutineScope: CoroutineScope): Flow<PagingData<TxHistoryItem>> {
|
||||||
|
// TODO: [REDACTED_JIRA]
|
||||||
|
if (userWallet.scanResponse.cardTypesResolver.isVisaWallet()) {
|
||||||
|
return flow {
|
||||||
|
stateHolder.update(
|
||||||
|
object : WalletStateTransformer(userWallet.walletId) {
|
||||||
|
override fun transform(prevState: WalletState): WalletState {
|
||||||
|
return when (prevState) {
|
||||||
|
is WalletState.Visa.Content -> prevState.copy(
|
||||||
|
txHistoryState = TxHistoryState.Empty(onExploreClick = {}),
|
||||||
|
)
|
||||||
|
else -> prevState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return flow {
|
return flow {
|
||||||
getPrimaryCurrencyStatusUpdatesUseCase.collectLatest(userWalletId = userWallet.walletId) { status ->
|
getPrimaryCurrencyStatusUpdatesUseCase.collectLatest(userWalletId = userWallet.walletId) { status ->
|
||||||
val maybeTxHistoryItemCount = txHistoryItemsCountUseCase(
|
val maybeTxHistoryItemCount = txHistoryItemsCountUseCase(
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,32 @@
|
||||||
package com.tangem.feature.wallet.presentation.wallet.subscribers
|
package com.tangem.feature.wallet.presentation.wallet.subscribers
|
||||||
|
|
||||||
|
import com.tangem.domain.visa.GetVisaCurrencyUseCase
|
||||||
import com.tangem.domain.wallets.models.UserWallet
|
import com.tangem.domain.wallets.models.UserWallet
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.WalletStateController
|
import com.tangem.feature.wallet.presentation.wallet.state2.WalletStateController
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.SetBalancesAndLimitsTransformer
|
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.SetBalancesAndLimitsTransformer
|
||||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntentsV2
|
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntentsV2
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.asFlow
|
import kotlinx.coroutines.flow.flow
|
||||||
|
|
||||||
|
@Suppress("LongParameterList")
|
||||||
internal class VisaWalletBalancesAndLimitsSubscriber(
|
internal class VisaWalletBalancesAndLimitsSubscriber(
|
||||||
private val userWallet: UserWallet,
|
private val userWallet: UserWallet,
|
||||||
private val stateHolder: WalletStateController,
|
private val stateHolder: WalletStateController,
|
||||||
|
private val isRefresh: Boolean,
|
||||||
|
private val getVisaCurrencyUseCase: GetVisaCurrencyUseCase,
|
||||||
private val clickIntents: WalletClickIntentsV2,
|
private val clickIntents: WalletClickIntentsV2,
|
||||||
) : WalletSubscriber() {
|
) : WalletSubscriber() {
|
||||||
|
|
||||||
// TODO: Implement in [REDACTED_JIRA]
|
override fun create(coroutineScope: CoroutineScope): Flow<*> {
|
||||||
override fun create(coroutineScope: CoroutineScope): Flow<*> = suspend {
|
return flow<Any> {
|
||||||
delay(timeMillis = 500)
|
stateHolder.update(
|
||||||
stateHolder.update(SetBalancesAndLimitsTransformer(userWallet, clickIntents))
|
SetBalancesAndLimitsTransformer(
|
||||||
}.asFlow()
|
userWallet = userWallet,
|
||||||
|
maybeVisaCurrency = getVisaCurrencyUseCase(userWallet.walletId, isRefresh),
|
||||||
|
clickIntents = clickIntents,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +113,6 @@ private fun Content(state: BalancesAndLimitsBlockState, modifier: Modifier = Mod
|
||||||
is BalancesAndLimitsBlockState.Content -> with(blockState) {
|
is BalancesAndLimitsBlockState.Content -> with(blockState) {
|
||||||
AvailableLimit(
|
AvailableLimit(
|
||||||
availableBalance = availableBalance,
|
availableBalance = availableBalance,
|
||||||
currencySymbol = currencySymbol,
|
|
||||||
limitDays = limitDays,
|
limitDays = limitDays,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -136,19 +135,14 @@ private fun Content(state: BalancesAndLimitsBlockState, modifier: Modifier = Mod
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AvailableLimit(
|
private fun AvailableLimit(availableBalance: String, limitDays: Int, modifier: Modifier = Modifier) {
|
||||||
availableBalance: String,
|
|
||||||
currencySymbol: String,
|
|
||||||
limitDays: Int,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
|
||||||
Row(
|
Row(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = "$availableBalance $currencySymbol",
|
text = availableBalance,
|
||||||
style = TangemTheme.typography.body2,
|
style = TangemTheme.typography.body2,
|
||||||
color = TangemTheme.colors.text.primary1,
|
color = TangemTheme.colors.text.primary1,
|
||||||
)
|
)
|
||||||
|
|
@ -186,8 +180,7 @@ private class BalancesAndLimitsBlockParameterProvider : CollectionPreviewParamet
|
||||||
BalancesAndLimitsBlockState.Loading,
|
BalancesAndLimitsBlockState.Loading,
|
||||||
BalancesAndLimitsBlockState.Error,
|
BalancesAndLimitsBlockState.Error,
|
||||||
BalancesAndLimitsBlockState.Content(
|
BalancesAndLimitsBlockState.Content(
|
||||||
availableBalance = "400.00",
|
availableBalance = "400.00 USDT",
|
||||||
currencySymbol = "USDT",
|
|
||||||
limitDays = 7,
|
limitDays = 7,
|
||||||
isEnabled = true,
|
isEnabled = true,
|
||||||
onClick = {},
|
onClick = {},
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,16 @@ import arrow.core.getOrElse
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
|
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
|
||||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.mapToAddressModels
|
import com.tangem.core.ui.components.bottomsheets.tokenreceive.mapToAddressModels
|
||||||
import com.tangem.domain.tokens.GetPrimaryCurrencyStatusUpdatesUseCase
|
import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase
|
||||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||||
|
import com.tangem.domain.visa.GetVisaCurrencyUseCase
|
||||||
import com.tangem.domain.wallets.models.UserWalletId
|
import com.tangem.domain.wallets.models.UserWalletId
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletAlertState
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletEvent
|
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.WalletStateController
|
import com.tangem.feature.wallet.presentation.wallet.state2.WalletStateController
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.model.BalancesAndLimitsBottomSheetConfig
|
import com.tangem.feature.wallet.presentation.wallet.state2.transformers.converter.BalancesAndLimitsBottomSheetConverter
|
||||||
import com.tangem.feature.wallet.presentation.wallet.state2.utils.WalletEventSender
|
import com.tangem.feature.wallet.presentation.wallet.state2.utils.WalletEventSender
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import dagger.hilt.android.scopes.ViewModelScoped
|
import dagger.hilt.android.scopes.ViewModelScoped
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -31,10 +29,15 @@ internal interface VisaWalletIntents {
|
||||||
internal class VisaWalletIntentsImplementor @Inject constructor(
|
internal class VisaWalletIntentsImplementor @Inject constructor(
|
||||||
private val stateController: WalletStateController,
|
private val stateController: WalletStateController,
|
||||||
private val eventSender: WalletEventSender,
|
private val eventSender: WalletEventSender,
|
||||||
private val getPrimaryCurrencyUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
|
private val getCurrencyStatusUseCase: GetCryptoCurrencyStatusSyncUseCase,
|
||||||
|
private val getVisaCurrencyUseCase: GetVisaCurrencyUseCase,
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
) : BaseWalletClickIntents(), VisaWalletIntents {
|
) : BaseWalletClickIntents(), VisaWalletIntents {
|
||||||
|
|
||||||
|
private val balancesAndLimitsBottomSheetConverter by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||||
|
BalancesAndLimitsBottomSheetConverter(eventSender)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDepositClick() {
|
override fun onDepositClick() {
|
||||||
val userWalletId = stateController.getSelectedWalletId()
|
val userWalletId = stateController.getSelectedWalletId()
|
||||||
|
|
||||||
|
|
@ -47,15 +50,6 @@ internal class VisaWalletIntentsImplementor @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getPrimaryCurrencyStatus(userWalletId: UserWalletId): CryptoCurrencyStatus? {
|
|
||||||
return getPrimaryCurrencyUseCase(userWalletId)
|
|
||||||
.firstOrNull()
|
|
||||||
?.getOrElse {
|
|
||||||
Timber.e("Failed to get primary currency $it")
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createReceiveBottomSheetContent(currencyStatus: CryptoCurrencyStatus): TangemBottomSheetConfigContent? {
|
private fun createReceiveBottomSheetContent(currencyStatus: CryptoCurrencyStatus): TangemBottomSheetConfigContent? {
|
||||||
val currency = currencyStatus.currency
|
val currency = currencyStatus.currency
|
||||||
val addresses = currencyStatus.value.networkAddress?.availableAddresses
|
val addresses = currencyStatus.value.networkAddress?.availableAddresses
|
||||||
|
|
@ -76,35 +70,27 @@ internal class VisaWalletIntentsImplementor @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBalancesAndLimitsClick() {
|
override fun onBalancesAndLimitsClick() {
|
||||||
stateController.showBottomSheet(getBalancesAndLimitsConfig())
|
viewModelScope.launch(dispatchers.main) {
|
||||||
|
val userWalletId = stateController.getSelectedWalletId()
|
||||||
|
val balancesAndLimits = getVisaCurrencyUseCase(userWalletId)
|
||||||
|
.getOrElse {
|
||||||
|
Timber.e("Unable to get balances and limits: $it")
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
|
||||||
|
val bottomSheetContent = balancesAndLimitsBottomSheetConverter.convert(
|
||||||
|
value = balancesAndLimits,
|
||||||
|
)
|
||||||
|
|
||||||
|
stateController.showBottomSheet(bottomSheetContent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement
|
private suspend fun getPrimaryCurrencyStatus(userWalletId: UserWalletId): CryptoCurrencyStatus? {
|
||||||
private fun getBalancesAndLimitsConfig() = BalancesAndLimitsBottomSheetConfig(
|
return getCurrencyStatusUseCase(userWalletId)
|
||||||
currency = "USDT",
|
.getOrElse {
|
||||||
balance = BalancesAndLimitsBottomSheetConfig.Balance(
|
Timber.e("Failed to get primary currency $it")
|
||||||
totalBalance = "492.45",
|
null
|
||||||
availableBalance = "392.45",
|
}
|
||||||
blockedBalance = "36.00",
|
|
||||||
debit = "00.00",
|
|
||||||
pending = "20.99",
|
|
||||||
amlVerified = "356.45",
|
|
||||||
),
|
|
||||||
limit = BalancesAndLimitsBottomSheetConfig.Limit(
|
|
||||||
availableBy = "Nov, 11",
|
|
||||||
inStore = "563.00",
|
|
||||||
other = "100.00",
|
|
||||||
singleTransaction = "100.00",
|
|
||||||
),
|
|
||||||
onBalanceInfoClick = this::showBalanceInfo,
|
|
||||||
onLimitInfoClick = this::showLimitInfo,
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun showBalanceInfo() {
|
|
||||||
eventSender.send(WalletEvent.ShowAlert(WalletAlertState.VisaBalancesInfo))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showLimitInfo() {
|
|
||||||
eventSender.send(WalletEvent.ShowAlert(WalletAlertState.VisaLimitsInfo))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -135,6 +135,7 @@ include(":domain:balance-hiding")
|
||||||
include(":domain:balance-hiding:models")
|
include(":domain:balance-hiding:models")
|
||||||
include(":domain:transaction")
|
include(":domain:transaction")
|
||||||
include(":domain:analytics")
|
include(":domain:analytics")
|
||||||
|
include(":domain:visa")
|
||||||
// endregion Domain modules
|
// endregion Domain modules
|
||||||
|
|
||||||
// region Data modules
|
// region Data modules
|
||||||
|
|
@ -150,4 +151,5 @@ include(":data:txhistory")
|
||||||
include(":data:wallets")
|
include(":data:wallets")
|
||||||
include(":data:analytics")
|
include(":data:analytics")
|
||||||
include(":data:transaction")
|
include(":data:transaction")
|
||||||
|
include(":data:visa")
|
||||||
// endregion Data modules
|
// endregion Data modules
|
||||||
Loading…
Add table
Add a link
Reference in a new issue