Updated on 2026-08-14
This commit is contained in:
parent
404bcc011a
commit
7ed060a37d
31 changed files with 351 additions and 66 deletions
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.send.impl.presentation.state.amount
|
||||
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer
|
||||
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.impl.presentation.state.SendUiState
|
||||
import com.tangem.features.send.impl.presentation.state.StateRouter
|
||||
|
|
@ -16,6 +17,7 @@ internal class AmountStateFactory(
|
|||
private val stateRouterProvider: Provider<StateRouter>,
|
||||
private val currentStateProvider: Provider<SendUiState>,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
private val minimumTransactionAmountProvider: Provider<EnterAmountBoundary?>,
|
||||
) {
|
||||
|
||||
private val amountFieldChangeConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||
|
|
@ -23,6 +25,7 @@ internal class AmountStateFactory(
|
|||
stateRouterProvider = stateRouterProvider,
|
||||
currentStateProvider = currentStateProvider,
|
||||
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
|
||||
minimumTransactionAmountProvider = minimumTransactionAmountProvider,
|
||||
)
|
||||
}
|
||||
private val amountFieldMaxAmountConverter by lazy(LazyThreadSafetyMode.NONE) {
|
||||
|
|
@ -30,6 +33,7 @@ internal class AmountStateFactory(
|
|||
stateRouterProvider = stateRouterProvider,
|
||||
currentStateProvider = currentStateProvider,
|
||||
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
|
||||
minimumTransactionAmountProvider = minimumTransactionAmountProvider,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -51,6 +55,7 @@ internal class AmountStateFactory(
|
|||
stateRouterProvider = stateRouterProvider,
|
||||
currentStateProvider = currentStateProvider,
|
||||
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
|
||||
minimumTransactionAmountProvider = minimumTransactionAmountProvider,
|
||||
)
|
||||
}
|
||||
private val amountReduceToConverter by lazy {
|
||||
|
|
@ -58,6 +63,7 @@ internal class AmountStateFactory(
|
|||
stateRouterProvider = stateRouterProvider,
|
||||
currentStateProvider = currentStateProvider,
|
||||
cryptoCurrencyStatusProvider = cryptoCurrencyStatusProvider,
|
||||
minimumTransactionAmountProvider = minimumTransactionAmountProvider,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.send.impl.presentation.state.amount
|
||||
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountReduceByTransformer
|
||||
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.impl.presentation.state.SendUiState
|
||||
import com.tangem.features.send.impl.presentation.state.StateRouter
|
||||
|
|
@ -11,6 +12,7 @@ internal class SendAmountReduceByConverter(
|
|||
private val stateRouterProvider: Provider<StateRouter>,
|
||||
private val currentStateProvider: Provider<SendUiState>,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
private val minimumTransactionAmountProvider: Provider<EnterAmountBoundary?>,
|
||||
) : Converter<AmountReduceByTransformer.ReduceByData, SendUiState> {
|
||||
|
||||
override fun convert(value: AmountReduceByTransformer.ReduceByData): SendUiState {
|
||||
|
|
@ -23,7 +25,11 @@ internal class SendAmountReduceByConverter(
|
|||
sendState = state.sendState?.copy(
|
||||
reduceAmountBy = value.reduceAmountBy,
|
||||
),
|
||||
amountState = AmountReduceByTransformer(cryptoCurrencyStatusProvider(), value).transform(amountState),
|
||||
amountState = AmountReduceByTransformer(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatusProvider(),
|
||||
minimumTransactionAmount = minimumTransactionAmountProvider(),
|
||||
value = value,
|
||||
).transform(amountState),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.send.impl.presentation.state.amount
|
||||
|
||||
import com.tangem.common.ui.amountScreen.converters.AmountReduceToTransformer
|
||||
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.impl.presentation.state.SendUiState
|
||||
import com.tangem.features.send.impl.presentation.state.StateRouter
|
||||
|
|
@ -12,6 +13,7 @@ internal class SendAmountReduceToConverter(
|
|||
private val stateRouterProvider: Provider<StateRouter>,
|
||||
private val currentStateProvider: Provider<SendUiState>,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
private val minimumTransactionAmountProvider: Provider<EnterAmountBoundary?>,
|
||||
) : Converter<BigDecimal, SendUiState> {
|
||||
|
||||
override fun convert(value: BigDecimal): SendUiState {
|
||||
|
|
@ -21,7 +23,11 @@ internal class SendAmountReduceToConverter(
|
|||
|
||||
return state.copyWrapped(
|
||||
isEditState = isEditState,
|
||||
amountState = AmountReduceToTransformer(cryptoCurrencyStatusProvider(), value).transform(amountState),
|
||||
amountState = AmountReduceToTransformer(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatusProvider(),
|
||||
minimumTransactionAmount = minimumTransactionAmountProvider(),
|
||||
value = value,
|
||||
).transform(amountState),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import com.tangem.common.ui.notifications.NotificationsFactory.addExceedsBalance
|
|||
import com.tangem.common.ui.notifications.NotificationsFactory.addExistentialWarningNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addFeeCoverageNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addFeeUnreachableNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addMinimumAmountErrorNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addReserveAmountErrorNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addTransactionLimitErrorNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addValidateTransactionNotifications
|
||||
|
|
@ -192,6 +193,11 @@ internal class SendNotificationFactory(
|
|||
cryptoCurrency = currency,
|
||||
isAccountFunded = currencyCheck.isAccountFunded,
|
||||
)
|
||||
addMinimumAmountErrorNotification(
|
||||
minimumSendAmount = currencyCheck.minimumSendAmount,
|
||||
sendingAmount = sendingAmount,
|
||||
cryptoCurrency = currency,
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun MutableList<NotificationUM>.addWarningNotifications(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.send.impl.presentation.state.fields
|
|||
|
||||
import com.tangem.common.ui.amountScreen.converters.MaxEnterAmountConverter
|
||||
import com.tangem.common.ui.amountScreen.converters.field.AmountFieldChangeTransformer
|
||||
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.impl.presentation.state.SendUiState
|
||||
import com.tangem.features.send.impl.presentation.state.StateRouter
|
||||
|
|
@ -12,21 +13,29 @@ internal class SendAmountFieldChangeConverter(
|
|||
private val stateRouterProvider: Provider<StateRouter>,
|
||||
private val currentStateProvider: Provider<SendUiState>,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
private val minimumTransactionAmountProvider: Provider<EnterAmountBoundary?>,
|
||||
) : Converter<String, SendUiState> {
|
||||
|
||||
private val maxEnterAmountConverter = MaxEnterAmountConverter()
|
||||
|
||||
override fun convert(value: String): SendUiState {
|
||||
val state = currentStateProvider()
|
||||
val cryptoCurrencyStatus = cryptoCurrencyStatusProvider()
|
||||
val isEditState = stateRouterProvider().isEditState
|
||||
val amountState = state.getAmountState(isEditState)
|
||||
|
||||
val maxEnterAmount = maxEnterAmountConverter.convert(cryptoCurrencyStatusProvider())
|
||||
val maxEnterAmount = maxEnterAmountConverter.convert(cryptoCurrencyStatus)
|
||||
val minimumTransactionAmount = minimumTransactionAmountProvider()
|
||||
|
||||
return state.copyWrapped(
|
||||
isEditState = isEditState,
|
||||
sendState = state.sendState?.copy(reduceAmountBy = null),
|
||||
amountState = AmountFieldChangeTransformer(maxEnterAmount, value).transform(amountState),
|
||||
amountState = AmountFieldChangeTransformer(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
maxEnterAmount = maxEnterAmount,
|
||||
minimumTransactionAmount = minimumTransactionAmount,
|
||||
value = value,
|
||||
).transform(amountState),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.send.impl.presentation.state.fields
|
|||
|
||||
import com.tangem.common.ui.amountScreen.converters.MaxEnterAmountConverter
|
||||
import com.tangem.common.ui.amountScreen.converters.field.AmountFieldSetMaxAmountTransformer
|
||||
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.features.send.impl.presentation.state.SendUiState
|
||||
import com.tangem.features.send.impl.presentation.state.StateRouter
|
||||
|
|
@ -13,6 +14,7 @@ internal class SendAmountFieldMaxAmountConverter(
|
|||
private val stateRouterProvider: Provider<StateRouter>,
|
||||
private val currentStateProvider: Provider<SendUiState>,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
private val minimumTransactionAmountProvider: Provider<EnterAmountBoundary?>,
|
||||
) : Converter<Unit, SendUiState> {
|
||||
|
||||
private val maxEnterAmountConverter = MaxEnterAmountConverter()
|
||||
|
|
@ -27,11 +29,16 @@ internal class SendAmountFieldMaxAmountConverter(
|
|||
if (decimalCryptoValue.isNullOrZero()) return state
|
||||
|
||||
val maxEnterAmount = maxEnterAmountConverter.convert(cryptoCurrencyStatus)
|
||||
val minimumTransactionAmount = minimumTransactionAmountProvider()
|
||||
|
||||
return state.copyWrapped(
|
||||
isEditState = isEditState,
|
||||
sendState = state.sendState?.copy(reduceAmountBy = null),
|
||||
amountState = AmountFieldSetMaxAmountTransformer(maxEnterAmount).transform(amountState),
|
||||
amountState = AmountFieldSetMaxAmountTransformer(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
maxAmount = maxEnterAmount,
|
||||
minAmount = minimumTransactionAmount,
|
||||
).transform(amountState),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ import com.tangem.blockchain.common.transaction.TransactionFee
|
|||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.bundle.unbundle
|
||||
import com.tangem.common.ui.amountScreen.models.AmountState
|
||||
import com.tangem.common.ui.amountScreen.models.EnterAmountBoundary
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
|
|
@ -59,6 +60,7 @@ import com.tangem.features.send.impl.presentation.state.recipient.RecipientSendF
|
|||
import com.tangem.lib.crypto.BlockchainUtils
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.*
|
||||
import com.tangem.utils.extensions.orZero
|
||||
import com.tangem.utils.extensions.stripZeroPlainString
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.*
|
||||
|
|
@ -78,6 +80,7 @@ internal class SendViewModel @Inject constructor(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val getFeePaidCryptoCurrencyStatusSyncUseCase: GetFeePaidCryptoCurrencyStatusSyncUseCase,
|
||||
private val getMinimumTransactionAmountSyncUseCase: GetMinimumTransactionAmountSyncUseCase,
|
||||
private val getCryptoCurrencyUseCase: GetCryptoCurrencyUseCase,
|
||||
private val getNetworkAddressesUseCase: GetNetworkAddressesUseCase,
|
||||
private val getTxHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
||||
|
|
@ -153,6 +156,7 @@ internal class SendViewModel @Inject constructor(
|
|||
stateRouterProvider = Provider { stateRouter },
|
||||
currentStateProvider = Provider { uiState.value },
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
minimumTransactionAmountProvider = Provider { minimumTransactionAmount },
|
||||
)
|
||||
|
||||
private val feeStateFactory = FeeStateFactory(
|
||||
|
|
@ -212,6 +216,7 @@ internal class SendViewModel @Inject constructor(
|
|||
private var isTapHelpPreviewEnabled: Boolean = false
|
||||
private var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
|
||||
private var feeCryptoCurrencyStatus: CryptoCurrencyStatus? = null
|
||||
private var minimumTransactionAmount: EnterAmountBoundary? = null
|
||||
|
||||
private var balanceJobHolder = JobHolder()
|
||||
private var balanceHidingJobHolder = JobHolder()
|
||||
|
|
@ -295,6 +300,7 @@ internal class SendViewModel @Inject constructor(
|
|||
onDataLoaded(
|
||||
currencyStatus = cryptoCurrencyStatus,
|
||||
feeCurrencyStatus = getFeeCurrencyStatusSync(cryptoCurrencyStatus, isMultiCurrency),
|
||||
minTransactionAmount = getMinimumTransactionAmount(cryptoCurrencyStatus),
|
||||
)
|
||||
},
|
||||
ifLeft = { showErrorAlert() },
|
||||
|
|
@ -336,6 +342,18 @@ internal class SendViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private suspend fun getMinimumTransactionAmount(cryptoCurrencyStatus: CryptoCurrencyStatus): EnterAmountBoundary? {
|
||||
return getMinimumTransactionAmountSyncUseCase(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
).getOrNull()?.let {
|
||||
EnterAmountBoundary(
|
||||
amount = it,
|
||||
fiatRate = cryptoCurrencyStatus.value.fiatRate.orZero(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSelectedAppCurrencyFlow(): StateFlow<AppCurrency> {
|
||||
return getSelectedAppCurrencyUseCase()
|
||||
.map { maybeAppCurrency ->
|
||||
|
|
@ -348,9 +366,14 @@ internal class SendViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun onDataLoaded(currencyStatus: CryptoCurrencyStatus, feeCurrencyStatus: CryptoCurrencyStatus?) {
|
||||
private fun onDataLoaded(
|
||||
currencyStatus: CryptoCurrencyStatus,
|
||||
feeCurrencyStatus: CryptoCurrencyStatus?,
|
||||
minTransactionAmount: EnterAmountBoundary?,
|
||||
) {
|
||||
cryptoCurrencyStatus = currencyStatus
|
||||
feeCryptoCurrencyStatus = feeCurrencyStatus
|
||||
minimumTransactionAmount = minTransactionAmount
|
||||
subscribeOnQRScannerResult()
|
||||
when {
|
||||
uiState.value.sendState?.isSuccess == true -> return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue