Updated on 2026-08-14
This commit is contained in:
commit
4147ffb34f
7 changed files with 103 additions and 49 deletions
|
|
@ -51,6 +51,7 @@ import com.tangem.features.send.v2.send.confirm.ui.state.ConfirmUM
|
|||
import com.tangem.features.send.v2.send.ui.state.ButtonsUM
|
||||
import com.tangem.features.send.v2.send.ui.state.SendUM
|
||||
import com.tangem.features.send.v2.subcomponents.destination.ui.state.DestinationUM
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadListener
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadTrigger
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.checkAndCalculateSubtractedAmount
|
||||
import com.tangem.features.send.v2.subcomponents.fee.ui.state.FeeSelectorUM
|
||||
|
|
@ -94,6 +95,7 @@ internal class SendConfirmModel @Inject constructor(
|
|||
private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase,
|
||||
private val getTxHistoryItemsUseCase: GetTxHistoryItemsUseCase,
|
||||
private val sendFeeCheckReloadTrigger: SendFeeCheckReloadTrigger,
|
||||
private val sendFeeCheckReloadListener: SendFeeCheckReloadListener,
|
||||
private val txHistoryContentUpdateEmitter: TxHistoryContentUpdateEmitter,
|
||||
private val notificationsUpdateTrigger: NotificationsUpdateTrigger,
|
||||
private val alertFactory: SendConfirmAlertFactory,
|
||||
|
|
@ -445,7 +447,7 @@ internal class SendConfirmModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun subscribeOnCheckFeeResultUpdates() {
|
||||
sendFeeCheckReloadTrigger.checkReloadResultFlow.onEach { isFeeResultSuccess ->
|
||||
sendFeeCheckReloadListener.checkReloadResultFlow.onEach { isFeeResultSuccess ->
|
||||
if (isFeeResultSuccess) {
|
||||
sendIdleTimer = SystemClock.elapsedRealtime()
|
||||
_uiState.update(SendConfirmSendingStateTransformer(isSending = true))
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import com.tangem.features.send.v2.subcomponents.amount.SendAmountComponentParam
|
|||
import com.tangem.features.send.v2.subcomponents.amount.SendAmountReduceListener
|
||||
import com.tangem.features.send.v2.subcomponents.amount.analytics.SendAmountAnalyticEvents
|
||||
import com.tangem.features.send.v2.subcomponents.amount.analytics.SendAmountAnalyticEvents.SelectedCurrencyType
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeData
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeReloadTrigger
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.extensions.orZero
|
||||
import com.tangem.utils.isNullOrZero
|
||||
|
|
@ -43,6 +45,7 @@ internal class SendAmountModel @Inject constructor(
|
|||
private val router: Router,
|
||||
private val getMinimumTransactionAmountSyncUseCase: GetMinimumTransactionAmountSyncUseCase,
|
||||
private val sendAmountReduceListener: SendAmountReduceListener,
|
||||
private val feeReloadTrigger: SendFeeReloadTrigger,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
) : Model(), AmountScreenClickIntents {
|
||||
|
||||
|
|
@ -174,6 +177,11 @@ internal class SendAmountModel @Inject constructor(
|
|||
value = reduceTo,
|
||||
),
|
||||
)
|
||||
feeReloadTrigger.triggerUpdate(
|
||||
feeData = SendFeeData(
|
||||
amount = (uiState.value as? AmountState.Data)?.amountTextField?.cryptoAmount?.value,
|
||||
),
|
||||
)
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
|
@ -188,6 +196,11 @@ internal class SendAmountModel @Inject constructor(
|
|||
value = reduceByData,
|
||||
),
|
||||
)
|
||||
feeReloadTrigger.triggerUpdate(
|
||||
feeData = SendFeeData(
|
||||
amount = (uiState.value as? AmountState.Data)?.amountTextField?.cryptoAmount?.value,
|
||||
),
|
||||
)
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.features.send.v2.subcomponents.fee
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
data class SendFeeData(
|
||||
val amount: BigDecimal?,
|
||||
val destinationAddress: String? = null,
|
||||
)
|
||||
|
|
@ -8,15 +8,24 @@ import javax.inject.Singleton
|
|||
|
||||
interface SendFeeReloadTrigger {
|
||||
|
||||
/** Flow triggers fee reload */
|
||||
val reloadTriggerFlow: Flow<Unit>
|
||||
|
||||
/** Trigger fee update */
|
||||
suspend fun triggerUpdate()
|
||||
suspend fun triggerUpdate(feeData: SendFeeData)
|
||||
}
|
||||
|
||||
interface SendFeeReloadListener {
|
||||
/** Flow triggers fee reload */
|
||||
val reloadTriggerFlow: Flow<SendFeeData>
|
||||
}
|
||||
|
||||
interface SendFeeCheckReloadTrigger {
|
||||
/** Trigger return callback with check result */
|
||||
suspend fun callbackCheckResult(isSuccess: Boolean)
|
||||
|
||||
/** Trigger fee check reload */
|
||||
suspend fun triggerCheckUpdate()
|
||||
}
|
||||
|
||||
interface SendFeeCheckReloadListener {
|
||||
/**
|
||||
* Flow triggers fee check reload before transaction.
|
||||
* Usually after significant time after fee was updated last time
|
||||
|
|
@ -25,18 +34,16 @@ interface SendFeeCheckReloadTrigger {
|
|||
|
||||
/** Flow return result of fee check update */
|
||||
val checkReloadResultFlow: Flow<Boolean>
|
||||
|
||||
/** Trigger return callback with check result */
|
||||
suspend fun callbackCheckResult(isSuccess: Boolean)
|
||||
|
||||
/** Trigger fee check reload */
|
||||
suspend fun triggerCheckUpdate()
|
||||
}
|
||||
|
||||
@Singleton
|
||||
internal class DefaultSendFeeReloadTrigger @Inject constructor() : SendFeeReloadTrigger, SendFeeCheckReloadTrigger {
|
||||
internal class DefaultSendFeeReloadTrigger @Inject constructor() :
|
||||
SendFeeReloadTrigger,
|
||||
SendFeeReloadListener,
|
||||
SendFeeCheckReloadTrigger,
|
||||
SendFeeCheckReloadListener {
|
||||
|
||||
private val _reloadTriggerFlow = MutableSharedFlow<Unit>()
|
||||
private val _reloadTriggerFlow = MutableSharedFlow<SendFeeData>()
|
||||
override val reloadTriggerFlow = _reloadTriggerFlow.asSharedFlow()
|
||||
|
||||
private val _checkReloadTriggerFlow = MutableSharedFlow<Unit>()
|
||||
|
|
@ -45,8 +52,8 @@ internal class DefaultSendFeeReloadTrigger @Inject constructor() : SendFeeReload
|
|||
private val _checkReloadResultFlow = MutableSharedFlow<Boolean>()
|
||||
override val checkReloadResultFlow = _checkReloadResultFlow.asSharedFlow()
|
||||
|
||||
override suspend fun triggerUpdate() {
|
||||
_reloadTriggerFlow.emit(Unit)
|
||||
override suspend fun triggerUpdate(feeData: SendFeeData) {
|
||||
_reloadTriggerFlow.emit(feeData)
|
||||
}
|
||||
|
||||
override suspend fun triggerCheckUpdate() {
|
||||
|
|
|
|||
|
|
@ -1,27 +1,29 @@
|
|||
package com.tangem.features.send.v2.subcomponents.fee.di
|
||||
|
||||
import com.tangem.features.send.v2.subcomponents.fee.DefaultSendFeeReloadTrigger
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadTrigger
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeReloadTrigger
|
||||
import com.tangem.features.send.v2.subcomponents.fee.*
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@InstallIn(SingletonComponent::class)
|
||||
@Module
|
||||
internal object SendFeeModule {
|
||||
internal interface SendFeeModule {
|
||||
|
||||
@Provides
|
||||
@Binds
|
||||
@Singleton
|
||||
fun provideSendFeeReloadTrigger(): SendFeeReloadTrigger {
|
||||
return DefaultSendFeeReloadTrigger()
|
||||
}
|
||||
fun provideSendFeeReloadTrigger(impl: DefaultSendFeeReloadTrigger): SendFeeReloadTrigger
|
||||
|
||||
@Provides
|
||||
@Binds
|
||||
@Singleton
|
||||
fun provideSendFeeCheckReloadTrigger(): SendFeeCheckReloadTrigger {
|
||||
return DefaultSendFeeReloadTrigger()
|
||||
}
|
||||
fun provideSendFeeReloadListener(impl: DefaultSendFeeReloadTrigger): SendFeeReloadListener
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun provideSendFeeCheckReloadTrigger(impl: DefaultSendFeeReloadTrigger): SendFeeCheckReloadTrigger
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun provideSendFeeCheckReloadListener(impl: DefaultSendFeeReloadTrigger): SendFeeCheckReloadListener
|
||||
}
|
||||
|
|
@ -14,9 +14,10 @@ import com.tangem.domain.transaction.usecase.IsFeeApproximateUseCase
|
|||
import com.tangem.features.send.v2.common.NavigationUM
|
||||
import com.tangem.features.send.v2.impl.R
|
||||
import com.tangem.features.send.v2.send.ui.state.ButtonsUM
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadListener
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeCheckReloadTrigger
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeComponentParams
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeReloadTrigger
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeReloadListener
|
||||
import com.tangem.features.send.v2.subcomponents.fee.analytics.SendFeeAnalyticEvents
|
||||
import com.tangem.features.send.v2.subcomponents.fee.analytics.SendFeeAnalyticEvents.GasPriceInserter
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.transformers.*
|
||||
|
|
@ -29,6 +30,7 @@ import com.tangem.utils.coroutines.saveIn
|
|||
import com.tangem.utils.transformer.update
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import java.math.BigDecimal
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -44,7 +46,8 @@ internal class SendFeeModel @Inject constructor(
|
|||
private val urlOpener: UrlOpener,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val sendFeeAlertFactory: SendFeeAlertFactory,
|
||||
private val feeReloadTrigger: SendFeeReloadTrigger,
|
||||
private val feeReloadListener: SendFeeReloadListener,
|
||||
private val feeCheckReloadListener: SendFeeCheckReloadListener,
|
||||
private val feeCheckReloadTrigger: SendFeeCheckReloadTrigger,
|
||||
) : Model(), SendFeeClickIntents {
|
||||
|
||||
|
|
@ -65,14 +68,19 @@ internal class SendFeeModel @Inject constructor(
|
|||
subscribeOnFeeReloadTriggerUpdates()
|
||||
subscribeOnFeeCheckReloadTriggerUpdates()
|
||||
initialState()
|
||||
loadFee()
|
||||
feeReload()
|
||||
}
|
||||
|
||||
fun updateState(state: FeeUM) {
|
||||
_uiState.value = state
|
||||
}
|
||||
|
||||
override fun feeReload() = loadFee()
|
||||
override fun feeReload() {
|
||||
loadFee(
|
||||
amountValue = params.sendAmount,
|
||||
destinationAddress = params.destinationAddress,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onFeeSelectorClick(feeType: FeeType) {
|
||||
_uiState.update(
|
||||
|
|
@ -152,13 +160,18 @@ internal class SendFeeModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun subscribeOnFeeReloadTriggerUpdates() {
|
||||
feeReloadTrigger.reloadTriggerFlow
|
||||
.onEach { feeReload() }
|
||||
feeReloadListener.reloadTriggerFlow
|
||||
.onEach { (amount, destination) ->
|
||||
loadFee(
|
||||
amountValue = amount ?: params.sendAmount,
|
||||
destinationAddress = destination ?: params.destinationAddress,
|
||||
)
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun subscribeOnFeeCheckReloadTriggerUpdates() {
|
||||
feeCheckReloadTrigger.checkReloadTriggerFlow
|
||||
feeCheckReloadListener.checkReloadTriggerFlow
|
||||
.onEach { checkLoadFee() }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
|
@ -175,13 +188,18 @@ internal class SendFeeModel @Inject constructor(
|
|||
params.callback.onFeeResult(uiState.value)
|
||||
}
|
||||
|
||||
private fun loadFee() {
|
||||
private fun loadFee(amountValue: BigDecimal, destinationAddress: String) {
|
||||
modelScope.launch {
|
||||
val isShowLoading = (uiState.value as? FeeUM.Content)?.feeSelectorUM !is FeeSelectorUM.Content
|
||||
if (isShowLoading) {
|
||||
_uiState.update(SendFeeLoadingTransformer)
|
||||
}
|
||||
callFeeUseCase().fold(
|
||||
getFeeUseCase.invoke(
|
||||
amount = amountValue,
|
||||
destination = destinationAddress,
|
||||
userWallet = params.userWallet,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency,
|
||||
).fold(
|
||||
ifRight = {
|
||||
_uiState.update(
|
||||
SendFeeLoadedTransformer(
|
||||
|
|
@ -206,7 +224,12 @@ internal class SendFeeModel @Inject constructor(
|
|||
|
||||
private fun checkLoadFee() {
|
||||
modelScope.launch {
|
||||
callFeeUseCase().fold(
|
||||
getFeeUseCase.invoke(
|
||||
amount = params.sendAmount,
|
||||
destination = params.destinationAddress,
|
||||
userWallet = params.userWallet,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency,
|
||||
).fold(
|
||||
ifRight = {
|
||||
sendFeeAlertFactory.getFeeUpdatedAlert(
|
||||
newFee = it,
|
||||
|
|
@ -236,20 +259,13 @@ internal class SendFeeModel @Inject constructor(
|
|||
ifLeft = { feeError ->
|
||||
feeCheckReloadTrigger.callbackCheckResult(false)
|
||||
_uiState.update(SendFeeFailedTransformer(feeError))
|
||||
sendFeeAlertFactory.getFeeUnreachableErrorState(::loadFee)
|
||||
sendFeeAlertFactory.getFeeUnreachableErrorState(::feeReload)
|
||||
updateFeeNotifications()
|
||||
},
|
||||
)
|
||||
}.saveIn(feeJobHolder)
|
||||
}
|
||||
|
||||
private suspend fun callFeeUseCase() = getFeeUseCase.invoke(
|
||||
amount = params.sendAmount,
|
||||
destination = params.destinationAddress,
|
||||
userWallet = params.userWallet,
|
||||
cryptoCurrency = cryptoCurrencyStatus.currency,
|
||||
)
|
||||
|
||||
private fun isFeeApproximate(amountType: AmountType): Boolean {
|
||||
val networkId = feeCryptoCurrencyStatus.currency.network.id
|
||||
return isFeeApproximateUseCase(
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck
|
|||
import com.tangem.domain.transaction.usecase.ValidateTransactionUseCase
|
||||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
import com.tangem.features.send.v2.subcomponents.amount.SendAmountReduceTrigger
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeData
|
||||
import com.tangem.features.send.v2.subcomponents.fee.SendFeeReloadTrigger
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.checkAndCalculateSubtractedAmount
|
||||
import com.tangem.features.send.v2.subcomponents.fee.model.checkFeeCoverage
|
||||
|
|
@ -52,7 +53,7 @@ import kotlinx.coroutines.launch
|
|||
import java.math.BigDecimal
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class NotificationsModel @Inject constructor(
|
||||
|
|
@ -129,7 +130,12 @@ internal class NotificationsModel @Inject constructor(
|
|||
feeError = feeError,
|
||||
onReload = {
|
||||
modelScope.launch {
|
||||
sendFeeReloadTrigger.triggerUpdate()
|
||||
sendFeeReloadTrigger.triggerUpdate(
|
||||
feeData = SendFeeData(
|
||||
amount = amountValue,
|
||||
destinationAddress = destinationAddress,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onClick = ::showTokenDetails,
|
||||
|
|
@ -366,7 +372,7 @@ internal class NotificationsModel @Inject constructor(
|
|||
},
|
||||
onCloseClick = {
|
||||
modelScope.launch {
|
||||
buildNotifications()
|
||||
sendAmountReduceTrigger.triggerIgnoreReduce()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue