Updated on 2026-08-14
This commit is contained in:
parent
4aa09819aa
commit
98fee821fa
9 changed files with 73 additions and 11 deletions
|
|
@ -162,6 +162,12 @@ internal object OnrampDomainModule {
|
|||
return OnrampSaveSelectedPaymentMethod(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideOnrampFetchPairsUseCase(onrampRepository: OnrampRepository): OnrampFetchPairsUseCase {
|
||||
return OnrampFetchPairsUseCase(onrampRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetOnrampRedirectUrlUseCase(
|
||||
|
|
|
|||
|
|
@ -16,4 +16,7 @@ data class OnrampCurrencyDTO(
|
|||
|
||||
@Json(name = "precision")
|
||||
val precision: Int,
|
||||
|
||||
@Json(name = "unit")
|
||||
val unit: String?,
|
||||
)
|
||||
|
|
@ -11,6 +11,7 @@ internal class CurrencyConverter : TwoWayConverter<OnrampCurrencyDTO, OnrampCurr
|
|||
code = value.code,
|
||||
image = value.image,
|
||||
precision = value.precision,
|
||||
unit = value.unit ?: value.code,
|
||||
)
|
||||
|
||||
override fun convertBack(value: OnrampCurrency): OnrampCurrencyDTO = OnrampCurrencyDTO(
|
||||
|
|
@ -18,5 +19,6 @@ internal class CurrencyConverter : TwoWayConverter<OnrampCurrencyDTO, OnrampCurr
|
|||
code = value.code,
|
||||
image = value.image,
|
||||
precision = value.precision,
|
||||
unit = value.unit,
|
||||
)
|
||||
}
|
||||
|
|
@ -8,4 +8,5 @@ data class OnrampCurrency(
|
|||
val code: String,
|
||||
val image: String,
|
||||
val precision: Int,
|
||||
val unit: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.domain.onramp
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.onramp.repositories.OnrampRepository
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
|
||||
class OnrampFetchPairsUseCase(private val repository: OnrampRepository) {
|
||||
|
||||
suspend operator fun invoke(cryptoCurrency: CryptoCurrency): Either<Throwable, Unit> {
|
||||
return Either.catch {
|
||||
val country = requireNotNull(repository.getDefaultCountrySync()) { "Country must not be null" }
|
||||
val currency = requireNotNull(repository.getDefaultCurrencySync()) { "Currency must not be null" }
|
||||
repository.fetchPairs(currency = currency, country = country, cryptoCurrency = cryptoCurrency)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,10 +12,6 @@ import com.tangem.domain.tokens.model.AmountType
|
|||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.convertToAmount
|
||||
import com.tangem.features.onramp.main.entity.*
|
||||
import com.tangem.features.onramp.main.entity.OnrampAmountBlockUM
|
||||
import com.tangem.features.onramp.main.entity.OnrampAmountSecondaryFieldUM
|
||||
import com.tangem.features.onramp.main.entity.OnrampCurrencyUM
|
||||
import com.tangem.features.onramp.main.entity.OnrampMainComponentUM
|
||||
import com.tangem.utils.Provider
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -77,7 +73,7 @@ internal class OnrampStateFactory(
|
|||
}
|
||||
|
||||
private fun BigDecimal.convertToFiatAmount(currency: OnrampCurrency): Amount = Amount(
|
||||
currencySymbol = currency.name,
|
||||
currencySymbol = currency.unit,
|
||||
value = this,
|
||||
decimals = currency.precision,
|
||||
type = AmountType.FiatType(currency.code),
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ internal class OnrampAmountStateFactory(
|
|||
),
|
||||
amountFieldModel = amountState.amountFieldModel.copy(
|
||||
fiatAmount = amountState.amountFieldModel.fiatAmount.copy(
|
||||
currencySymbol = currency.code,
|
||||
currencySymbol = currency.unit,
|
||||
decimals = currency.precision,
|
||||
type = AmountType.FiatType(currency.code),
|
||||
),
|
||||
|
|
@ -65,6 +65,8 @@ internal class OnrampAmountStateFactory(
|
|||
if (currentState !is OnrampMainComponentUM.Content) return currentState
|
||||
|
||||
val amountState = currentState.amountBlockState
|
||||
if (amountState.amountFieldModel.fiatValue.isEmpty()) return currentState
|
||||
|
||||
return currentState.copy(
|
||||
amountBlockState = amountState.copy(
|
||||
secondaryFieldModel = quote.toSecondaryFieldUiModel(amountState),
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ import com.tangem.features.onramp.main.entity.factory.amount.OnrampAmountStateFa
|
|||
import com.tangem.features.onramp.utils.InputManager
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.PeriodicTask
|
||||
import com.tangem.utils.coroutines.SingleTaskScheduler
|
||||
import com.tangem.utils.isNullOrZero
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
|
@ -50,6 +53,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
private val clearOnrampCacheUseCase: ClearOnrampCacheUseCase,
|
||||
private val fetchQuotesUseCase: OnrampFetchQuotesUseCase,
|
||||
private val getOnrampQuotesUseCase: GetOnrampQuotesUseCase,
|
||||
private val fetchPairsUseCase: OnrampFetchPairsUseCase,
|
||||
private val amountInputManager: InputManager,
|
||||
private val messageSender: UiMessageSender,
|
||||
getWalletsUseCase: GetWalletsUseCase,
|
||||
|
|
@ -73,6 +77,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
onClose = router::pop,
|
||||
),
|
||||
)
|
||||
private val quotesTaskScheduler = SingleTaskScheduler<Unit>()
|
||||
val state: StateFlow<OnrampMainComponentUM> get() = _state.asStateFlow()
|
||||
val bottomSheetNavigation: SlotNavigation<OnrampMainBottomSheetConfig> = SlotNavigation()
|
||||
|
||||
|
|
@ -126,6 +131,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
val currency = maybeCurrency.getOrNull()
|
||||
if (currency != null) {
|
||||
_state.update { amountStateFactory.getUpdatedCurrencyState(currency) }
|
||||
updatePairsAndQuotes()
|
||||
}
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
|
|
@ -135,15 +141,39 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
amountInputManager.query
|
||||
.filter(String::isNotEmpty)
|
||||
.collectLatest { _ ->
|
||||
val content = state.value as? OnrampMainComponentUM.Content ?: return@collectLatest
|
||||
_state.update { amountStateFactory.getAmountSecondaryLoadingState() }
|
||||
fetchQuotesUseCase.invoke(
|
||||
amount = content.amountBlockState.amountFieldModel.fiatAmount,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
)
|
||||
startLoadingQuotes()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updatePairsAndQuotes() {
|
||||
fetchPairsUseCase.invoke(params.cryptoCurrency)
|
||||
startLoadingQuotes()
|
||||
}
|
||||
|
||||
private fun startLoadingQuotes() {
|
||||
quotesTaskScheduler.cancelTask()
|
||||
quotesTaskScheduler.scheduleTask(scope = modelScope, task = loadQuotesTask())
|
||||
}
|
||||
|
||||
private fun loadQuotesTask(): PeriodicTask<Unit> {
|
||||
return PeriodicTask(
|
||||
delay = UPDATE_DELAY,
|
||||
task = {
|
||||
runCatching {
|
||||
val content = state.value as? OnrampMainComponentUM.Content ?: return@runCatching
|
||||
if (content.amountBlockState.amountFieldModel.fiatAmount.value.isNullOrZero()) return@runCatching
|
||||
fetchQuotesUseCase.invoke(
|
||||
amount = content.amountBlockState.amountFieldModel.fiatAmount,
|
||||
cryptoCurrency = params.cryptoCurrency,
|
||||
)
|
||||
}
|
||||
},
|
||||
onSuccess = {},
|
||||
onError = {},
|
||||
)
|
||||
}
|
||||
|
||||
private fun subscribeToQuotesUpdate() {
|
||||
getOnrampQuotesUseCase.invoke()
|
||||
.onEach { maybeQuotes ->
|
||||
|
|
@ -205,6 +235,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
|
||||
override fun onDestroy() {
|
||||
modelScope.launch { clearOnrampCacheUseCase.invoke() }
|
||||
quotesTaskScheduler.cancelTask()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
|
@ -236,4 +267,8 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val UPDATE_DELAY = 10_000L
|
||||
}
|
||||
}
|
||||
|
|
@ -60,6 +60,7 @@ private fun OnrampAmountField(amountField: AmountFieldModel) {
|
|||
visualTransformation = AmountVisualTransformation(
|
||||
decimals = amountField.fiatAmount.decimals,
|
||||
symbol = amountField.fiatAmount.currencySymbol,
|
||||
currencyCode = amountField.fiatAmount.currencySymbol,
|
||||
decimalFormat = decimalFormat,
|
||||
),
|
||||
onValueChange = amountField.onValueChange,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue