Updated on 2026-08-14

This commit is contained in:
Tangem 2024-12-06 17:49:11 +05:00
parent e9ed80c7a4
commit cb62ebfd05
42 changed files with 475 additions and 379 deletions

View file

@ -9,6 +9,7 @@ import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.domain.onramp.model.OnrampCurrency
import com.tangem.domain.onramp.model.OnrampProviderWithQuote
import com.tangem.domain.onramp.model.OnrampQuote
import com.tangem.domain.onramp.model.error.OnrampError
import com.tangem.domain.tokens.model.AmountType
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.main.entity.*
@ -162,35 +163,23 @@ internal class OnrampAmountStateFactory(
private fun OnrampQuote.Error.toSecondaryFieldUiModel(
amountState: OnrampAmountBlockUM,
): OnrampAmountSecondaryFieldUM.Error {
return when (this) {
is OnrampQuote.Error.AmountTooBigError -> {
val amount = requiredAmount.value.format {
fiat(
fiatCurrencyCode = amountState.amountFieldModel.fiatAmount.currencySymbol,
fiatCurrencySymbol = amountState.amountFieldModel.fiatAmount.currencySymbol,
)
}
OnrampAmountSecondaryFieldUM.Error(
resourceReference(
R.string.onramp_max_amount_restriction,
wrappedList(amount),
),
)
}
is OnrampQuote.Error.AmountTooSmallError -> {
val amount = requiredAmount.value.format {
fiat(
fiatCurrencyCode = amountState.amountFieldModel.fiatAmount.currencySymbol,
fiatCurrencySymbol = amountState.amountFieldModel.fiatAmount.currencySymbol,
)
}
OnrampAmountSecondaryFieldUM.Error(
resourceReference(
R.string.onramp_min_amount_restriction,
wrappedList(amount),
),
)
}
val amount = error.requiredAmount.format {
fiat(
fiatCurrencyCode = amountState.amountFieldModel.fiatAmount.currencySymbol,
fiatCurrencySymbol = amountState.amountFieldModel.fiatAmount.currencySymbol,
)
}
val errorTextRes = when (error) {
is OnrampError.AmountError.TooBigError -> R.string.onramp_max_amount_restriction
is OnrampError.AmountError.TooSmallError -> R.string.onramp_min_amount_restriction
}
return OnrampAmountSecondaryFieldUM.Error(
resourceReference(
errorTextRes,
wrappedList(amount),
),
)
}
}

View file

@ -113,7 +113,7 @@ internal class OnrampMainComponentModel @Inject constructor(
modelScope.launch {
checkOnrampAvailabilityUseCase.invoke()
.onRight(::handleOnrampAvailability)
.onLeft { Timber.e(it) }
.onLeft { Timber.e(it.toString()) }
}
}

View file

@ -20,15 +20,12 @@ import com.tangem.domain.onramp.OnrampSaveSelectedPaymentMethod
import com.tangem.domain.onramp.analytics.OnrampAnalyticsEvent
import com.tangem.domain.onramp.model.OnrampPaymentMethod
import com.tangem.domain.onramp.model.OnrampProviderWithQuote
import com.tangem.domain.onramp.model.error.OnrampError
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.paymentmethod.entity.PaymentMethodUM
import com.tangem.features.onramp.providers.SelectProviderComponent
import com.tangem.features.onramp.providers.entity.ProviderListBottomSheetConfig
import com.tangem.features.onramp.providers.entity.ProviderListItemUM
import com.tangem.features.onramp.providers.entity.ProviderListPaymentMethodUM
import com.tangem.features.onramp.providers.entity.ProviderListUM
import com.tangem.utils.StringsSigns.MINUS
import com.tangem.features.onramp.providers.entity.*
import com.tangem.utils.StringsSigns.MINUS
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
@ -79,7 +76,7 @@ internal class SelectProviderModel @Inject constructor(
)
}
}
.onLeft { Timber.e(it) }
.onLeft { Timber.e(it.toString()) }
}
}
@ -171,40 +168,25 @@ internal class SelectProviderModel @Inject constructor(
},
)
}
is OnrampProviderWithQuote.Unavailable.AvailableFrom -> {
val amount = quote.requiredAmount.value.format {
crypto(symbol = quote.requiredAmount.symbol, decimals = quote.requiredAmount.decimals)
is OnrampProviderWithQuote.Unavailable.Error -> {
val quoteError = quote.quoteError
val amount = quoteError.error.requiredAmount.format {
crypto(symbol = quoteError.fromAmount.symbol, decimals = quoteError.fromAmount.decimals)
}
val errorSubtitleRes = when (quoteError.error) {
is OnrampError.AmountError.TooBigError -> R.string.express_provider_max_amount
is OnrampError.AmountError.TooSmallError -> R.string.express_provider_min_amount
}
ProviderListItemUM.AvailableWithError(
providerId = quote.provider.id,
imageUrl = quote.provider.info.imageLarge,
name = quote.provider.info.name,
subtitle = resourceReference(R.string.express_provider_min_amount, wrappedList(amount)),
subtitle = resourceReference(errorSubtitleRes, wrappedList(amount)),
onClick = {
onProviderSelected(
result = SelectProviderResult.ProviderWithError(
paymentMethod = quote.paymentMethod,
provider = quote.provider,
quoteError = quote.quoteError,
),
isBestRate = bestProvider == quote,
)
},
)
}
is OnrampProviderWithQuote.Unavailable.AvailableUpTo -> {
val amount = quote.requiredAmount.value.format {
crypto(symbol = quote.requiredAmount.symbol, decimals = quote.requiredAmount.decimals)
}
ProviderListItemUM.AvailableWithError(
providerId = quote.provider.id,
imageUrl = quote.provider.info.imageLarge,
name = quote.provider.info.name,
subtitle = resourceReference(R.string.express_provider_max_amount, wrappedList(amount)),
onClick = {
onProviderSelected(
result = SelectProviderResult.ProviderWithError(
paymentMethod = quote.paymentMethod,
paymentMethod = quoteError.paymentMethod,
provider = quote.provider,
quoteError = quote.quoteError,
),
@ -250,8 +232,13 @@ internal class SelectProviderModel @Inject constructor(
is OnrampProviderWithQuote.Data -> it.toAmount.value
// negative difference to sort both when data and unavailable is present
is OnrampProviderWithQuote.Unavailable.AvailableFrom -> it.fromAmount.value - it.requiredAmount.value
is OnrampProviderWithQuote.Unavailable.AvailableUpTo -> it.requiredAmount.value - it.fromAmount.value
is OnrampProviderWithQuote.Unavailable.Error -> {
when (val error = it.quoteError.error) {
is OnrampError.AmountError.TooSmallError -> it.quoteError.fromAmount.value - error.requiredAmount
is OnrampError.AmountError.TooBigError -> error.requiredAmount - it.quoteError.fromAmount.value
else -> null
}
}
is OnrampProviderWithQuote.Unavailable.NotSupportedPaymentMethod -> null
}
}

View file

@ -15,6 +15,7 @@ import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.message.ContentMessage
import com.tangem.domain.onramp.GetOnrampRedirectUrlUseCase
import com.tangem.domain.onramp.model.error.OnrampError
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.redirect.OnrampRedirectComponent
import com.tangem.features.onramp.redirect.entity.OnrampRedirectTopBarUM
@ -76,8 +77,8 @@ internal class OnrampRedirectModel @Inject constructor(
}
}
private fun handleError(throwable: Throwable) {
Timber.e(throwable)
private fun handleError(error: OnrampError) {
Timber.e(error.toString())
val contentMessage = ContentMessage { onDismiss ->
BasicDialog(

View file

@ -2,13 +2,14 @@ package com.tangem.features.onramp.selectcountry.entity.transformer
import arrow.core.Either
import com.tangem.domain.onramp.model.OnrampCountry
import com.tangem.domain.onramp.model.error.OnrampError
import com.tangem.features.onramp.selectcountry.entity.CountryItemState
import com.tangem.features.onramp.selectcountry.entity.CountryListUM
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.toImmutableList
internal class UpdateCountryItemsTransformer(
private val maybeCountries: Either<Throwable, List<OnrampCountry>>,
private val maybeCountries: Either<OnrampError, List<OnrampCountry>>,
private val defaultCountry: OnrampCountry?,
private val query: String,
private val onRetry: () -> Unit,

View file

@ -4,6 +4,7 @@ import arrow.core.Either
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.onramp.model.OnrampCurrencies
import com.tangem.domain.onramp.model.OnrampCurrency
import com.tangem.domain.onramp.model.error.OnrampError
import com.tangem.features.onramp.selectcurrency.entity.CurrenciesListUM
import com.tangem.features.onramp.selectcurrency.entity.CurrenciesSection
import com.tangem.features.onramp.selectcurrency.entity.CurrencyItemState
@ -11,7 +12,7 @@ import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.toImmutableList
internal class UpdateCurrencyItemsTransformer(
private val maybeCurrencies: Either<Throwable, OnrampCurrencies>,
private val maybeCurrencies: Either<OnrampError, OnrampCurrencies>,
private val query: String,
private val onRetry: () -> Unit,
private val onCurrencyClick: (OnrampCurrency) -> Unit,

View file

@ -10,6 +10,7 @@ import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.onramp.GetOnrampCountryUseCase
import com.tangem.domain.onramp.analytics.OnrampAnalyticsEvent
import com.tangem.domain.onramp.model.OnrampCountry
import com.tangem.domain.onramp.model.error.OnrampError
import com.tangem.features.onramp.settings.OnrampSettingsComponent
import com.tangem.features.onramp.settings.entity.OnrampSettingsConfig
import com.tangem.features.onramp.settings.entity.OnrampSettingsItemUM
@ -44,7 +45,7 @@ internal class OnrampSettingsModel @Inject constructor(
.launchIn(modelScope)
}
private fun updateResidenceState(maybeCountry: Either<Throwable, OnrampCountry?>) {
private fun updateResidenceState(maybeCountry: Either<OnrampError, OnrampCountry?>) {
maybeCountry.onRight { country ->
_state.update { state ->
state.copy(