Updated on 2026-08-14
This commit is contained in:
commit
0e515c142e
7 changed files with 38 additions and 20 deletions
|
|
@ -31,6 +31,7 @@ internal class SendStateFactory(
|
||||||
private val userWalletProvider: Provider<UserWallet>,
|
private val userWalletProvider: Provider<UserWallet>,
|
||||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||||
|
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||||
private val validateWalletMemoUseCase: ValidateWalletMemoUseCase,
|
private val validateWalletMemoUseCase: ValidateWalletMemoUseCase,
|
||||||
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
||||||
) {
|
) {
|
||||||
|
|
@ -62,7 +63,7 @@ internal class SendStateFactory(
|
||||||
private val feeStateConverter by lazy(LazyThreadSafetyMode.NONE) {
|
private val feeStateConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
SendFeeStateConverter(
|
SendFeeStateConverter(
|
||||||
appCurrencyProvider = appCurrencyProvider,
|
appCurrencyProvider = appCurrencyProvider,
|
||||||
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
|
feeCryptoCurrencyStatusProvider = feeCryptoCurrencyStatusProvider,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@ import com.tangem.utils.converter.Converter
|
||||||
internal class FeeConverter(
|
internal class FeeConverter(
|
||||||
private val clickIntents: SendClickIntents,
|
private val clickIntents: SendClickIntents,
|
||||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||||
) : Converter<FeeSelectorState.Content, Fee> {
|
) : Converter<FeeSelectorState.Content, Fee> {
|
||||||
|
|
||||||
private val ethereumCustomFeeConverter by lazy {
|
private val ethereumCustomFeeConverter by lazy {
|
||||||
EthereumCustomFeeConverter(
|
EthereumCustomFeeConverter(
|
||||||
clickIntents = clickIntents,
|
clickIntents = clickIntents,
|
||||||
appCurrencyProvider = appCurrencyProvider,
|
appCurrencyProvider = appCurrencyProvider,
|
||||||
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
|
feeCryptoCurrencyStatusProvider = feeCryptoCurrencyStatusProvider,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import kotlinx.collections.immutable.persistentListOf
|
||||||
internal class FeeStateFactory(
|
internal class FeeStateFactory(
|
||||||
private val clickIntents: SendClickIntents,
|
private val clickIntents: SendClickIntents,
|
||||||
private val currentStateProvider: Provider<SendUiState>,
|
private val currentStateProvider: Provider<SendUiState>,
|
||||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||||
private val isFeeApproximateUseCase: IsFeeApproximateUseCase,
|
private val isFeeApproximateUseCase: IsFeeApproximateUseCase,
|
||||||
) {
|
) {
|
||||||
|
|
@ -28,7 +28,7 @@ internal class FeeStateFactory(
|
||||||
SendFeeCustomFieldConverter(
|
SendFeeCustomFieldConverter(
|
||||||
clickIntents = clickIntents,
|
clickIntents = clickIntents,
|
||||||
appCurrencyProvider = appCurrencyProvider,
|
appCurrencyProvider = appCurrencyProvider,
|
||||||
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
|
feeCryptoCurrencyStatusProvider = feeCryptoCurrencyStatusProvider,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,7 +36,7 @@ internal class FeeStateFactory(
|
||||||
FeeConverter(
|
FeeConverter(
|
||||||
clickIntents = clickIntents,
|
clickIntents = clickIntents,
|
||||||
appCurrencyProvider = appCurrencyProvider,
|
appCurrencyProvider = appCurrencyProvider,
|
||||||
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
|
feeCryptoCurrencyStatusProvider = feeCryptoCurrencyStatusProvider,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,7 +140,7 @@ internal class FeeStateFactory(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isFeeApproximate(fee: Fee): Boolean {
|
private fun isFeeApproximate(fee: Fee): Boolean {
|
||||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
val cryptoCurrencyStatus = feeCryptoCurrencyStatusProvider()
|
||||||
return isFeeApproximateUseCase(
|
return isFeeApproximateUseCase(
|
||||||
networkId = cryptoCurrencyStatus.currency.network.id,
|
networkId = cryptoCurrencyStatus.currency.network.id,
|
||||||
amountType = fee.amount.type,
|
amountType = fee.amount.type,
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,14 @@ import kotlinx.collections.immutable.persistentListOf
|
||||||
internal class SendFeeCustomFieldConverter(
|
internal class SendFeeCustomFieldConverter(
|
||||||
private val clickIntents: SendClickIntents,
|
private val clickIntents: SendClickIntents,
|
||||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||||
) : Converter<Fee, ImmutableList<SendTextField.CustomFee>> {
|
) : Converter<Fee, ImmutableList<SendTextField.CustomFee>> {
|
||||||
|
|
||||||
private val ethereumCustomFeeConverter by lazy {
|
private val ethereumCustomFeeConverter by lazy {
|
||||||
EthereumCustomFeeConverter(
|
EthereumCustomFeeConverter(
|
||||||
clickIntents = clickIntents,
|
clickIntents = clickIntents,
|
||||||
appCurrencyProvider = appCurrencyProvider,
|
appCurrencyProvider = appCurrencyProvider,
|
||||||
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
|
feeCryptoCurrencyStatusProvider = feeCryptoCurrencyStatusProvider,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,16 +9,15 @@ import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
||||||
internal class SendFeeStateConverter(
|
internal class SendFeeStateConverter(
|
||||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||||
) : Converter<Unit, SendStates.FeeState> {
|
) : Converter<Unit, SendStates.FeeState> {
|
||||||
|
|
||||||
override fun convert(value: Unit): SendStates.FeeState {
|
override fun convert(value: Unit): SendStates.FeeState {
|
||||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
|
||||||
return SendStates.FeeState(
|
return SendStates.FeeState(
|
||||||
feeSelectorState = FeeSelectorState.Loading,
|
feeSelectorState = FeeSelectorState.Loading,
|
||||||
fee = null,
|
fee = null,
|
||||||
notifications = persistentListOf(),
|
notifications = persistentListOf(),
|
||||||
rate = cryptoCurrencyStatus.value.fiatRate,
|
rate = feeCryptoCurrencyStatusProvider().value.fiatRate,
|
||||||
appCurrency = appCurrencyProvider(),
|
appCurrency = appCurrencyProvider(),
|
||||||
isFeeApproximate = false,
|
isFeeApproximate = false,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import java.math.RoundingMode
|
||||||
internal class EthereumCustomFeeConverter(
|
internal class EthereumCustomFeeConverter(
|
||||||
private val clickIntents: SendClickIntents,
|
private val clickIntents: SendClickIntents,
|
||||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
private val feeCryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||||
) : Converter<Fee.Ethereum, ImmutableList<SendTextField.CustomFee>> {
|
) : Converter<Fee.Ethereum, ImmutableList<SendTextField.CustomFee>> {
|
||||||
|
|
||||||
override fun convert(value: 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 {
|
private fun getFeeFormatted(fee: BigDecimal?): TextReference {
|
||||||
val appCurrency = appCurrencyProvider()
|
val appCurrency = appCurrencyProvider()
|
||||||
val rate = cryptoCurrencyStatusProvider().value.fiatRate
|
val rate = feeCryptoCurrencyStatusProvider().value.fiatRate
|
||||||
val fiatFee = rate?.let { fee?.multiply(it) }
|
val fiatFee = rate?.let { fee?.multiply(it) }
|
||||||
return stringReference(
|
return stringReference(
|
||||||
BigDecimalFormatter.formatFiatAmount(
|
BigDecimalFormatter.formatFiatAmount(
|
||||||
|
|
@ -164,7 +164,7 @@ internal class EthereumCustomFeeConverter(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkExceedBalance(feeAmount: BigDecimal?): Boolean {
|
private fun checkExceedBalance(feeAmount: BigDecimal?): Boolean {
|
||||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
val cryptoCurrencyStatus = feeCryptoCurrencyStatusProvider()
|
||||||
val currencyCryptoAmount = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO
|
val currencyCryptoAmount = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO
|
||||||
|
|
||||||
return feeAmount == null || feeAmount.isZero() || feeAmount > currencyCryptoAmount
|
return feeAmount == null || feeAmount.isZero() || feeAmount > currencyCryptoAmount
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
package com.tangem.features.send.impl.presentation.viewmodel
|
package com.tangem.features.send.impl.presentation.viewmodel
|
||||||
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
|
@ -66,6 +67,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||||
private val getWalletsUseCase: GetWalletsUseCase,
|
private val getWalletsUseCase: GetWalletsUseCase,
|
||||||
private val getCryptoCurrenciesUseCase: GetCryptoCurrenciesUseCase,
|
private val getCryptoCurrenciesUseCase: GetCryptoCurrenciesUseCase,
|
||||||
|
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
|
||||||
private val getFixedTxHistoryItemsUseCase: GetFixedTxHistoryItemsUseCase,
|
private val getFixedTxHistoryItemsUseCase: GetFixedTxHistoryItemsUseCase,
|
||||||
private val getFeeUseCase: GetFeeUseCase,
|
private val getFeeUseCase: GetFeeUseCase,
|
||||||
private val sendTransactionUseCase: SendTransactionUseCase,
|
private val sendTransactionUseCase: SendTransactionUseCase,
|
||||||
|
|
@ -108,6 +110,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
userWalletProvider = Provider { userWallet },
|
userWalletProvider = Provider { userWallet },
|
||||||
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
|
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
|
||||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||||
|
feeCryptoCurrencyStatusProvider = Provider { feeCryptoCurrencyStatus },
|
||||||
validateWalletMemoUseCase = validateWalletMemoUseCase,
|
validateWalletMemoUseCase = validateWalletMemoUseCase,
|
||||||
getExplorerTransactionUrlUseCase = getExplorerTransactionUrlUseCase,
|
getExplorerTransactionUrlUseCase = getExplorerTransactionUrlUseCase,
|
||||||
)
|
)
|
||||||
|
|
@ -120,7 +123,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
private val feeStateFactory = FeeStateFactory(
|
private val feeStateFactory = FeeStateFactory(
|
||||||
clickIntents = this,
|
clickIntents = this,
|
||||||
currentStateProvider = Provider { uiState },
|
currentStateProvider = Provider { uiState },
|
||||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
feeCryptoCurrencyStatusProvider = Provider { feeCryptoCurrencyStatus },
|
||||||
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
|
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
|
||||||
isFeeApproximateUseCase = isFeeApproximateUseCase,
|
isFeeApproximateUseCase = isFeeApproximateUseCase,
|
||||||
)
|
)
|
||||||
|
|
@ -165,6 +168,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
private var isAmountSubtractAvailable: Boolean = false
|
private var isAmountSubtractAvailable: Boolean = false
|
||||||
private var coinCryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
|
private var coinCryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
|
||||||
private var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
|
private var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
|
||||||
|
private var feeCryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
|
||||||
|
|
||||||
private var balanceJobHolder = JobHolder()
|
private var balanceJobHolder = JobHolder()
|
||||||
private var balanceHidingJobHolder = JobHolder()
|
private var balanceHidingJobHolder = JobHolder()
|
||||||
|
|
@ -237,6 +241,7 @@ internal class SendViewModel @Inject constructor(
|
||||||
onDataLoaded(
|
onDataLoaded(
|
||||||
currencyStatus = it,
|
currencyStatus = it,
|
||||||
coinCurrencyStatus = it,
|
coinCurrencyStatus = it,
|
||||||
|
feeCurrencyStatus = getFeeCurrencyStatusSync(it),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -247,11 +252,13 @@ internal class SendViewModel @Inject constructor(
|
||||||
combine(
|
combine(
|
||||||
flow = getCoinCurrencyStatusUpdates(isSingleWallet = isSingleWallet),
|
flow = getCoinCurrencyStatusUpdates(isSingleWallet = isSingleWallet),
|
||||||
flow2 = getCurrencyStatusUpdates(isSingleWallet = isSingleWallet),
|
flow2 = getCurrencyStatusUpdates(isSingleWallet = isSingleWallet),
|
||||||
) { coinStatus, currencyStatus ->
|
) { coinStatus, maybeCurrencyStatus ->
|
||||||
if (coinStatus.isRight() && currencyStatus.isRight()) {
|
if (coinStatus.isRight() && maybeCurrencyStatus.isRight()) {
|
||||||
|
val currencyStatus = maybeCurrencyStatus.getOrElse { error("Currency status is unreachable") }
|
||||||
onDataLoaded(
|
onDataLoaded(
|
||||||
currencyStatus = currencyStatus.getOrElse { error("Currency status is unreachable") },
|
currencyStatus = currencyStatus,
|
||||||
coinCurrencyStatus = coinStatus.getOrElse { error("Coin status is unreachable") },
|
coinCurrencyStatus = coinStatus.getOrElse { error("Coin status is unreachable") },
|
||||||
|
feeCurrencyStatus = getFeeCurrencyStatusSync(currencyStatus),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -274,6 +281,12 @@ internal class SendViewModel @Inject constructor(
|
||||||
isSingleWalletWithTokens = isSingleWallet,
|
isSingleWalletWithTokens = isSingleWallet,
|
||||||
).conflate().distinctUntilChanged()
|
).conflate().distinctUntilChanged()
|
||||||
|
|
||||||
|
private suspend fun getFeeCurrencyStatusSync(cryptoCurrencyStatus: CryptoCurrencyStatus) =
|
||||||
|
getFeePaidCryptoCurrencyStatusSyncUseCase(
|
||||||
|
userWalletId = userWalletId,
|
||||||
|
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||||
|
).getOrNull() ?: error("Fee currency is unreachable")
|
||||||
|
|
||||||
private fun createSelectedAppCurrencyFlow(): StateFlow<AppCurrency> {
|
private fun createSelectedAppCurrencyFlow(): StateFlow<AppCurrency> {
|
||||||
return getSelectedAppCurrencyUseCase()
|
return getSelectedAppCurrencyUseCase()
|
||||||
.map { maybeAppCurrency ->
|
.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
|
cryptoCurrencyStatus = currencyStatus
|
||||||
coinCryptoCurrencyStatus = coinCurrencyStatus
|
coinCryptoCurrencyStatus = coinCurrencyStatus
|
||||||
|
feeCryptoCurrencyStatus = feeCurrencyStatus
|
||||||
|
|
||||||
if (transactionId != null && amount != null && destinationAddress != null) {
|
if (transactionId != null && amount != null && destinationAddress != null) {
|
||||||
uiState = stateFactory.getReadyState(amount, destinationAddress)
|
uiState = stateFactory.getReadyState(amount, destinationAddress)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue