Skip to content

Commit

Permalink
Handle exception on ton fee estimation
Browse files Browse the repository at this point in the history
 * Add 1 sec debounce for fee estimation
 * Add loading fee state in Ton send
  • Loading branch information
abdrasulov committed Dec 24, 2024
1 parent 8d02a1d commit 730781d
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ fun HSFee(
fee: BigDecimal?,
amountInputType: AmountInputType,
rate: CurrencyValue?,
navController: NavController
navController: NavController,
viewState: ViewState? = null
) {
CellUniversalLawrenceSection(
listOf {
Expand All @@ -33,7 +34,8 @@ fun HSFee(
fee = fee,
amountInputType = amountInputType,
rate = rate,
navController = navController
navController = navController,
viewState = viewState
)
})
}
Expand All @@ -47,7 +49,8 @@ fun HSFeeRaw(
fee: BigDecimal?,
amountInputType: AmountInputType,
rate: CurrencyValue?,
navController: NavController
navController: NavController,
viewState: ViewState? = null
) {

var formatted by remember { mutableStateOf<FeeItem?>(null) }
Expand All @@ -60,7 +63,7 @@ fun HSFeeRaw(
title = title,
info = info,
value = formatted,
viewState = null,
viewState = viewState,
navController = navController
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<AddressParserViewModel>(
Expand Down Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -91,6 +93,7 @@ class SendTonViewModel(
canBeSend = amountState.canBeSend && addressState.canBeSend,
showAddressInput = showAddressInput,
fee = feeState.fee,
feeInProgress = feeState.inProgress,
)

fun onEnterAmount(amount: BigDecimal?) {
Expand Down Expand Up @@ -154,15 +157,15 @@ 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)

emitState()
}

private suspend fun handleUpdatedAddressState(addressState: SendTonAddressService.State) {
private fun handleUpdatedAddressState(addressState: SendTonAddressService.State) {
this.addressState = addressState

feeService.setTonAddress(addressState.tonAddress)
Expand All @@ -185,4 +188,5 @@ data class SendTonUiState(
val canBeSend: Boolean,
val showAddressInput: Boolean,
val fee: BigDecimal?,
val feeInProgress: Boolean,
)

0 comments on commit 730781d

Please sign in to comment.