Updated on 2026-08-14

This commit is contained in:
Tangem 2024-04-08 15:31:30 +05:00
parent 7e8b587fbb
commit c68c5db506
6 changed files with 41 additions and 66 deletions

View file

@ -75,4 +75,12 @@ internal sealed class SendAlertState {
override val message: TextReference =
resourceReference(id = R.string.send_notification_invalid_reserve_amount_text)
}
data class FeeUnreachableError(
override val onConfirmClick: (() -> Unit),
) : SendAlertState() {
override val title: TextReference = resourceReference(R.string.send_fee_unreachable_error_title)
override val message: TextReference = resourceReference(R.string.send_fee_unreachable_error_text)
override val confirmButtonText = resourceReference(R.string.warning_button_refresh)
}
}

View file

@ -123,4 +123,18 @@ internal class SendEventStateFactory(
),
)
}
fun getFeeUnreachableErrorState(onConsume: () -> Unit): SendUiState {
val state = currentStateProvider()
return state.copy(
event = triggeredEvent(
data = SendEvent.ShowAlert(
SendAlertState.FeeUnreachableError(
onConfirmClick = { clickIntents.feeReload(true) },
),
),
onConsume = onConsume,
),
)
}
}

View file

@ -1,38 +0,0 @@
package com.tangem.features.send.impl.presentation.state.amount
import com.tangem.features.send.impl.presentation.state.SendUiState
import com.tangem.features.send.impl.presentation.state.SendUiStateType
import com.tangem.features.send.impl.presentation.state.StateRouter
import com.tangem.features.send.impl.presentation.state.SendNotification
import com.tangem.features.send.impl.presentation.state.fee.FeeSelectorState
import com.tangem.features.send.impl.presentation.viewmodel.SendClickIntents
import com.tangem.utils.Provider
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
internal class AmountNotificationFactory(
private val stateRouterProvider: Provider<StateRouter>,
private val currentStateProvider: Provider<SendUiState>,
private val clickIntents: SendClickIntents,
) {
fun create() = stateRouterProvider().currentState
.filter { it.type == SendUiStateType.Amount }
.map {
buildList {
addFeeUnreachableNotification()
}.toImmutableList()
}
private fun MutableList<SendNotification>.addFeeUnreachableNotification() {
val state = currentStateProvider()
val feeState = state.feeState ?: return
if (feeState.feeSelectorState is FeeSelectorState.Error) {
add(
SendNotification.Warning.NetworkFeeUnreachable(clickIntents::feeReload),
)
}
}
}

View file

@ -33,7 +33,7 @@ internal object SendClickIntentsStub : SendClickIntents {
override fun onRecipientMemoValueChange(value: String) {}
override fun feeReload() {}
override fun feeReload(isToNextState: Boolean) {}
override fun onFeeSelectorClick(feeType: FeeType) {}

View file

@ -38,7 +38,7 @@ internal interface SendClickIntents {
// endregion
// region Fee
fun feeReload()
fun feeReload(isToNextState: Boolean = false)
fun onFeeSelectorClick(feeType: FeeType)

View file

@ -46,7 +46,6 @@ import com.tangem.features.send.impl.presentation.analytics.SendScreenSource
import com.tangem.features.send.impl.presentation.analytics.utils.SendOnNextScreenAnalyticSender
import com.tangem.features.send.impl.presentation.domain.AvailableWallet
import com.tangem.features.send.impl.presentation.state.*
import com.tangem.features.send.impl.presentation.state.amount.AmountNotificationFactory
import com.tangem.features.send.impl.presentation.state.amount.AmountStateFactory
import com.tangem.features.send.impl.presentation.state.confirm.SendNotificationFactory
import com.tangem.features.send.impl.presentation.state.fee.*
@ -147,12 +146,6 @@ internal class SendViewModel @Inject constructor(
feeStateFactory = feeStateFactory,
)
private val amountNotificationFactory = AmountNotificationFactory(
currentStateProvider = Provider { uiState },
stateRouterProvider = Provider { stateRouter },
clickIntents = this,
)
private val feeNotificationFactory = FeeNotificationFactory(
currentStateProvider = Provider { uiState },
stateRouterProvider = Provider { stateRouter },
@ -194,7 +187,6 @@ internal class SendViewModel @Inject constructor(
private var memoValidationJobHolder = JobHolder()
private var sendNotificationsJobHolder = JobHolder()
private var feeNotificationsJobHolder = JobHolder()
private var amountNotificationsJobHolder = JobHolder()
private var qrScannerJobHolder = JobHolder()
private var sendIdleTimer = 0L
@ -478,16 +470,6 @@ internal class SendViewModel @Inject constructor(
.saveIn(feeNotificationsJobHolder)
}
private fun updateAmountNotifications() {
amountNotificationFactory.create()
.conflate()
.distinctUntilChanged()
.onEach { uiState = amountStateFactory.getAmountNotificationState(notifications = it) }
.flowOn(dispatchers.io)
.launchIn(viewModelScope)
.saveIn(amountNotificationsJobHolder)
}
// region screen state navigation
override fun popBackStack() = stateRouter.popBackStack()
override fun onBackClick() {
@ -661,7 +643,7 @@ internal class SendViewModel @Inject constructor(
// endregion
// region fee
override fun feeReload() = loadFee()
override fun feeReload(isToNextState: Boolean) = loadFee(isToNextState = isToNextState)
override fun onFeeSelectorClick(feeType: FeeType) {
uiState = feeStateFactory.onFeeSelectedState(feeType)
@ -706,20 +688,30 @@ internal class SendViewModel @Inject constructor(
}
},
ifLeft = {
if (isShowStatus) uiState = feeStateFactory.onFeeOnErrorState()
onFeeLoadFailed(isShowStatus, isToNextState)
},
)
if (result == null && isShowStatus) {
uiState = feeStateFactory.onFeeOnErrorState()
if (result == null) {
onFeeLoadFailed(isShowStatus, isToNextState)
}
updateFeeNotifications()
updateAmountNotifications()
}.saveIn(feeJobHolder)
.invokeOnCompletion {
uiState = amountStateFactory.getOnAmountFeeLoadingCancel()
}
}
private fun onFeeLoadFailed(isShowStatus: Boolean, isToNextState: Boolean) {
when {
isToNextState -> {
uiState = eventStateFactory.getFeeUnreachableErrorState {
uiState = eventStateFactory.onConsumeEventState()
}
}
isShowStatus -> uiState = feeStateFactory.onFeeOnErrorState()
}
}
private suspend fun checkIfSubtractAvailable() {
isAmountSubtractAvailable = isAmountSubtractAvailableUseCase(userWalletId, cryptoCurrency).fold(
ifRight = { it },
@ -884,8 +876,7 @@ internal class SendViewModel @Inject constructor(
},
ifLeft = {
uiState = stateFactory.getSendingStateUpdate(isSending = false)
eventStateFactory.getGenericErrorState(
error = (it as? GetFeeError.DataError)?.cause,
eventStateFactory.getFeeUnreachableErrorState(
onConsume = { uiState = eventStateFactory.onConsumeEventState() },
)
},
@ -895,7 +886,7 @@ internal class SendViewModel @Inject constructor(
feeUpdatedState
} else {
uiState = stateFactory.getSendingStateUpdate(isSending = false)
eventStateFactory.getGenericErrorState(
eventStateFactory.getFeeUnreachableErrorState(
onConsume = { uiState = eventStateFactory.onConsumeEventState() },
)
}