Updated on 2026-08-14

This commit is contained in:
Tangem 2024-03-06 11:03:37 +05:00
parent 6c8865caae
commit bf72de17e1
7 changed files with 38 additions and 20 deletions

View file

@ -31,6 +31,7 @@ internal class SendStateFactory(
private val userWalletProvider: Provider<UserWallet>,
private val appCurrencyProvider: Provider<AppCurrency>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val validateWalletMemoUseCase: ValidateWalletMemoUseCase,
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
) {
@ -62,7 +63,7 @@ internal class SendStateFactory(
private val feeStateConverter by lazy(LazyThreadSafetyMode.NONE) {
SendFeeStateConverter(
appCurrencyProvider = appCurrencyProvider,
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
feeCryptoCurrencyStatusProvider = feeCryptoCurrencyStatusProvider,
)
}

View file

@ -13,14 +13,14 @@ import com.tangem.utils.converter.Converter
internal class FeeConverter(
private val clickIntents: SendClickIntents,
private val appCurrencyProvider: Provider<AppCurrency>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
) : Converter<FeeSelectorState.Content, Fee> {
private val ethereumCustomFeeConverter by lazy {
EthereumCustomFeeConverter(
clickIntents = clickIntents,
appCurrencyProvider = appCurrencyProvider,
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
feeCryptoCurrencyStatusProvider = feeCryptoCurrencyStatusProvider,
)
}

View file

@ -20,7 +20,7 @@ import kotlinx.collections.immutable.persistentListOf
internal class FeeStateFactory(
private val clickIntents: SendClickIntents,
private val currentStateProvider: Provider<SendUiState>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val appCurrencyProvider: Provider<AppCurrency>,
private val isFeeApproximateUseCase: IsFeeApproximateUseCase,
) {
@ -28,7 +28,7 @@ internal class FeeStateFactory(
SendFeeCustomFieldConverter(
clickIntents = clickIntents,
appCurrencyProvider = appCurrencyProvider,
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
feeCryptoCurrencyStatusProvider = feeCryptoCurrencyStatusProvider,
)
}
@ -36,7 +36,7 @@ internal class FeeStateFactory(
FeeConverter(
clickIntents = clickIntents,
appCurrencyProvider = appCurrencyProvider,
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
feeCryptoCurrencyStatusProvider = feeCryptoCurrencyStatusProvider,
)
}
@ -140,7 +140,7 @@ internal class FeeStateFactory(
}
private fun isFeeApproximate(fee: Fee): Boolean {
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
val cryptoCurrencyStatus = feeCryptoCurrencyStatusProvider()
return isFeeApproximateUseCase(
networkId = cryptoCurrencyStatus.currency.network.id,
amountType = fee.amount.type,

View file

@ -14,14 +14,14 @@ import kotlinx.collections.immutable.persistentListOf
internal class SendFeeCustomFieldConverter(
private val clickIntents: SendClickIntents,
private val appCurrencyProvider: Provider<AppCurrency>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
) : Converter<Fee, ImmutableList<SendTextField.CustomFee>> {
private val ethereumCustomFeeConverter by lazy {
EthereumCustomFeeConverter(
clickIntents = clickIntents,
appCurrencyProvider = appCurrencyProvider,
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
feeCryptoCurrencyStatusProvider = feeCryptoCurrencyStatusProvider,
)
}

View file

@ -9,16 +9,15 @@ import kotlinx.collections.immutable.persistentListOf
internal class SendFeeStateConverter(
private val appCurrencyProvider: Provider<AppCurrency>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
) : Converter<Unit, SendStates.FeeState> {
override fun convert(value: Unit): SendStates.FeeState {
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
return SendStates.FeeState(
feeSelectorState = FeeSelectorState.Loading,
fee = null,
notifications = persistentListOf(),
rate = cryptoCurrencyStatus.value.fiatRate,
rate = feeCryptoCurrencyStatusProvider().value.fiatRate,
appCurrency = appCurrencyProvider(),
isFeeApproximate = false,
)

View file

@ -28,7 +28,7 @@ import java.math.RoundingMode
internal class EthereumCustomFeeConverter(
private val clickIntents: SendClickIntents,
private val appCurrencyProvider: Provider<AppCurrency>,
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
) : Converter<Fee.Ethereum, ImmutableList<SendTextField.CustomFee>> {
override fun convert(value: Fee.Ethereum): ImmutableList<SendTextField.CustomFee> {
@ -152,7 +152,7 @@ internal class EthereumCustomFeeConverter(
private fun getFeeFormatted(fee: BigDecimal?): TextReference {
val appCurrency = appCurrencyProvider()
val rate = cryptoCurrencyStatusProvider().value.fiatRate
val rate = feeCryptoCurrencyStatusProvider().value.fiatRate
val fiatFee = rate?.let { fee?.multiply(it) }
return stringReference(
BigDecimalFormatter.formatFiatAmount(
@ -164,7 +164,7 @@ internal class EthereumCustomFeeConverter(
}
private fun checkExceedBalance(feeAmount: BigDecimal?): Boolean {
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
val cryptoCurrencyStatus = feeCryptoCurrencyStatusProvider()
val currencyCryptoAmount = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO
return feeAmount == null || feeAmount.isZero() || feeAmount > currencyCryptoAmount

View file

@ -1,3 +1,4 @@
package com.tangem.features.send.impl.presentation.viewmodel
import androidx.compose.runtime.getValue
@ -66,6 +67,7 @@ internal class SendViewModel @Inject constructor(
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val getWalletsUseCase: GetWalletsUseCase,
private val getCryptoCurrenciesUseCase: GetCryptoCurrenciesUseCase,
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
private val getFixedTxHistoryItemsUseCase: GetFixedTxHistoryItemsUseCase,
private val getFeeUseCase: GetFeeUseCase,
private val sendTransactionUseCase: SendTransactionUseCase,
@ -108,6 +110,7 @@ internal class SendViewModel @Inject constructor(
userWalletProvider = Provider { userWallet },
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
feeCryptoCurrencyStatusProvider = Provider { feeCryptoCurrencyStatus },
validateWalletMemoUseCase = validateWalletMemoUseCase,
getExplorerTransactionUrlUseCase = getExplorerTransactionUrlUseCase,
)
@ -120,7 +123,7 @@ internal class SendViewModel @Inject constructor(
private val feeStateFactory = FeeStateFactory(
clickIntents = this,
currentStateProvider = Provider { uiState },
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
feeCryptoCurrencyStatusProvider = Provider { feeCryptoCurrencyStatus },
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
isFeeApproximateUseCase = isFeeApproximateUseCase,
)
@ -165,6 +168,7 @@ internal class SendViewModel @Inject constructor(
private var isAmountSubtractAvailable: Boolean = false
private var coinCryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
private var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
private var feeCryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
private var balanceJobHolder = JobHolder()
private var balanceHidingJobHolder = JobHolder()
@ -237,6 +241,7 @@ internal class SendViewModel @Inject constructor(
onDataLoaded(
currencyStatus = it,
coinCurrencyStatus = it,
feeCurrencyStatus = getFeeCurrencyStatusSync(it),
)
}
}
@ -247,11 +252,13 @@ internal class SendViewModel @Inject constructor(
combine(
flow = getCoinCurrencyStatusUpdates(isSingleWallet = isSingleWallet),
flow2 = getCurrencyStatusUpdates(isSingleWallet = isSingleWallet),
) { coinStatus, currencyStatus ->
if (coinStatus.isRight() && currencyStatus.isRight()) {
) { coinStatus, maybeCurrencyStatus ->
if (coinStatus.isRight() && maybeCurrencyStatus.isRight()) {
val currencyStatus = maybeCurrencyStatus.getOrElse { error("Currency status is unreachable") }
onDataLoaded(
currencyStatus = currencyStatus.getOrElse { error("Currency status is unreachable") },
currencyStatus = currencyStatus,
coinCurrencyStatus = coinStatus.getOrElse { error("Coin status is unreachable") },
feeCurrencyStatus = getFeeCurrencyStatusSync(currencyStatus),
)
}
}
@ -274,6 +281,12 @@ internal class SendViewModel @Inject constructor(
isSingleWalletWithTokens = isSingleWallet,
).conflate().distinctUntilChanged()
private suspend fun getFeeCurrencyStatusSync(cryptoCurrencyStatus: CryptoCurrencyStatus) =
getFeePaidCryptoCurrencyStatusSyncUseCase(
userWalletId = userWalletId,
cryptoCurrencyStatus = cryptoCurrencyStatus,
).getOrNull() ?: error("Fee currency is unreachable")
private fun createSelectedAppCurrencyFlow(): StateFlow<AppCurrency> {
return getSelectedAppCurrencyUseCase()
.map { maybeAppCurrency ->
@ -286,9 +299,14 @@ internal class SendViewModel @Inject constructor(
)
}
private fun onDataLoaded(currencyStatus: CryptoCurrencyStatus, coinCurrencyStatus: CryptoCurrencyStatus) {
private fun onDataLoaded(
currencyStatus: CryptoCurrencyStatus,
coinCurrencyStatus: CryptoCurrencyStatus,
feeCurrencyStatus: CryptoCurrencyStatus,
) {
cryptoCurrencyStatus = currencyStatus
coinCryptoCurrencyStatus = coinCurrencyStatus
feeCryptoCurrencyStatus = feeCurrencyStatus
if (transactionId != null && amount != null && destinationAddress != null) {
uiState = stateFactory.getReadyState(amount, destinationAddress)