diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/fee/FeeCell.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/fee/FeeCell.kt index 5d538c23ccb..c9b9932409a 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/fee/FeeCell.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/fee/FeeCell.kt @@ -64,7 +64,7 @@ fun FeeCell( Spacer(Modifier.weight(1f)) - Box(contentAlignment = Alignment.Center) { + Box(contentAlignment = Alignment.CenterEnd) { if (viewState == ViewState.Loading) { CircularProgressIndicator( modifier = Modifier.size(16.dp), diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/fee/HSFeeInput.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/fee/HSFeeInput.kt index 1c6e60c6365..96bca559a54 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/fee/HSFeeInput.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/fee/HSFeeInput.kt @@ -23,7 +23,8 @@ fun HSFee( fee: BigDecimal?, amountInputType: AmountInputType, rate: CurrencyValue?, - navController: NavController + navController: NavController, + viewState: ViewState? = null ) { CellUniversalLawrenceSection( listOf { @@ -33,7 +34,8 @@ fun HSFee( fee = fee, amountInputType = amountInputType, rate = rate, - navController = navController + navController = navController, + viewState = viewState ) }) } @@ -47,7 +49,8 @@ fun HSFeeRaw( fee: BigDecimal?, amountInputType: AmountInputType, rate: CurrencyValue?, - navController: NavController + navController: NavController, + viewState: ViewState? = null ) { var formatted by remember { mutableStateOf(null) } @@ -60,7 +63,7 @@ fun HSFeeRaw( title = title, info = info, value = formatted, - viewState = null, + viewState = viewState, navController = navController ) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonFeeService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonFeeService.kt index af669235d32..159a9c60b56 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonFeeService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonFeeService.kt @@ -2,67 +2,97 @@ package io.horizontalsystems.bankwallet.modules.send.ton import io.horizontalsystems.bankwallet.core.ISendTonAdapter import io.horizontalsystems.tonkit.FriendlyAddress +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel +import kotlinx.coroutines.delay +import kotlinx.coroutines.ensureActive import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch import java.math.BigDecimal -class SendTonFeeService(private val adapter: ISendTonAdapter) { +class SendTonFeeService(private val adapter: ISendTonAdapter) : AutoCloseable { private var memo: String? = null private var address: FriendlyAddress? = null private var amount: BigDecimal? = null private var fee: BigDecimal? = null + private var inProgress = false private val _stateFlow = MutableStateFlow( State( - fee = fee + fee = fee, + inProgress = inProgress ) ) val stateFlow = _stateFlow.asStateFlow() + private val coroutineScope = CoroutineScope(Dispatchers.Default) + private var estimateFeeJob: Job? = null - private suspend fun refreshFee() { + private fun refreshFeeAndEmitState() { val amount = amount val address = address val memo = memo - fee = if (amount != null && address != null) { - adapter.estimateFee(amount, address, memo) - } else { - null + estimateFeeJob?.cancel() + estimateFeeJob = coroutineScope.launch { + if (amount != null && address != null) { + inProgress = true + emitState() + + delay(1000) + ensureActive() + try { + fee = adapter.estimateFee(amount, address, memo) + } catch (e: Throwable) { + delay(500) + refreshFeeAndEmitState() + } + } else { + fee = null + } + + inProgress = false + emitState() } } - suspend fun setAmount(amount: BigDecimal?) { + fun setAmount(amount: BigDecimal?) { this.amount = amount - refreshFee() - emitState() + refreshFeeAndEmitState() } - suspend fun setTonAddress(address: FriendlyAddress?) { + fun setTonAddress(address: FriendlyAddress?) { this.address = address - refreshFee() - emitState() + refreshFeeAndEmitState() } - suspend fun setMemo(memo: String?) { + fun setMemo(memo: String?) { this.memo = memo - refreshFee() - emitState() + refreshFeeAndEmitState() } private fun emitState() { _stateFlow.update { State( - fee = fee + fee = fee, + inProgress = inProgress ) } } data class State( - val fee: BigDecimal? + val fee: BigDecimal?, + val inProgress: Boolean ) + + override fun close() { + coroutineScope.cancel() + } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonScreen.kt index 367f5141b5d..dc147cfafdb 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonScreen.kt @@ -14,6 +14,7 @@ import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.slideFromRight import io.horizontalsystems.bankwallet.entities.Address +import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.address.AddressParserModule import io.horizontalsystems.bankwallet.modules.address.AddressParserViewModel import io.horizontalsystems.bankwallet.modules.address.HSAddressInput @@ -47,6 +48,7 @@ fun SendTonScreen( val amountCaution = uiState.amountCaution val proceedEnabled = uiState.canBeSend val fee = uiState.fee + val feeInProgress = uiState.feeInProgress val amountInputType = amountInputModeViewModel.inputType val paymentAddressViewModel = viewModel( @@ -122,7 +124,8 @@ fun SendTonScreen( fee = fee, amountInputType = amountInputType, rate = viewModel.feeCoinRate, - navController = navController + navController = navController, + viewState = if (feeInProgress) ViewState.Loading else null ) ButtonPrimaryYellow( diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonViewModel.kt index b4f5bf68fc0..b294960a2d8 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/ton/SendTonViewModel.kt @@ -57,6 +57,8 @@ class SendTonViewModel( private val logger: AppLogger = AppLogger("send-ton") init { + addCloseable(feeService) + viewModelScope.launch(Dispatchers.Default) { amountService.stateFlow.collect { handleUpdatedAmountState(it) @@ -91,6 +93,7 @@ class SendTonViewModel( canBeSend = amountState.canBeSend && addressState.canBeSend, showAddressInput = showAddressInput, fee = feeState.fee, + feeInProgress = feeState.inProgress, ) fun onEnterAmount(amount: BigDecimal?) { @@ -154,7 +157,7 @@ class SendTonViewModel( else -> HSCaution(TranslatableString.PlainString(error.message ?: "")) } - private suspend fun handleUpdatedAmountState(amountState: SendTonAmountService.State) { + private fun handleUpdatedAmountState(amountState: SendTonAmountService.State) { this.amountState = amountState feeService.setAmount(amountState.amount) @@ -162,7 +165,7 @@ class SendTonViewModel( emitState() } - private suspend fun handleUpdatedAddressState(addressState: SendTonAddressService.State) { + private fun handleUpdatedAddressState(addressState: SendTonAddressService.State) { this.addressState = addressState feeService.setTonAddress(addressState.tonAddress) @@ -185,4 +188,5 @@ data class SendTonUiState( val canBeSend: Boolean, val showAddressInput: Boolean, val fee: BigDecimal?, + val feeInProgress: Boolean, )