Updated on 2026-08-14
This commit is contained in:
parent
920fc0ff57
commit
17a97c66b6
8 changed files with 59 additions and 18 deletions
|
|
@ -947,6 +947,7 @@
|
|||
</plurals>
|
||||
<string name="onramp_timing_minutes">%s min</string>
|
||||
<string name="onramp_title_available_from">Available from</string>
|
||||
<string name="onramp_title_available_up_to">Available up to</string>
|
||||
<string name="onramp_title_you_get">You get</string>
|
||||
<string name="onramp_tos_external_providers">Service is provided by an external provider. \nTangem is not responsible.</string>
|
||||
<string name="onramp_transaction_status_footer_text">You can close this screen and check the transaction status on the token details screen.</string>
|
||||
|
|
|
|||
|
|
@ -13,5 +13,10 @@ data class OnrampPaymentMethodGroup(
|
|||
|
||||
sealed interface PaymentMethodStatus {
|
||||
data object Available : PaymentMethodStatus
|
||||
data class Unavailable(val availableFrom: BigDecimal) : PaymentMethodStatus
|
||||
sealed interface Unavailable : PaymentMethodStatus {
|
||||
val requiredAmount: BigDecimal
|
||||
|
||||
data class MinAmount(override val requiredAmount: BigDecimal) : Unavailable
|
||||
data class MaxAmount(override val requiredAmount: BigDecimal) : Unavailable
|
||||
}
|
||||
}
|
||||
|
|
@ -167,10 +167,16 @@ class GetOnrampAllOffersUseCase(
|
|||
return if (hasAtLeastOneValidQuote) {
|
||||
PaymentMethodStatus.Available
|
||||
} else {
|
||||
val minSum = methodQuotes
|
||||
.filterIsInstance<OnrampQuote.AmountError>()
|
||||
.minOfOrNull { it.error.requiredAmount } ?: BigDecimal.ZERO
|
||||
PaymentMethodStatus.Unavailable(minSum)
|
||||
val amountErrorQuotes = methodQuotes.filterIsInstance<OnrampQuote.AmountError>()
|
||||
val minAmountErrors = amountErrorQuotes.filter { it.error is OnrampError.AmountError.TooSmallError }
|
||||
|
||||
if (minAmountErrors.isNotEmpty()) {
|
||||
val minRequiredAmount = minAmountErrors.minOf { it.error.requiredAmount }
|
||||
PaymentMethodStatus.Unavailable.MinAmount(minRequiredAmount)
|
||||
} else {
|
||||
val maxAmount = amountErrorQuotes.maxOfOrNull { it.error.requiredAmount } ?: BigDecimal.ZERO
|
||||
PaymentMethodStatus.Unavailable.MaxAmount(maxAmount)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -240,7 +240,7 @@ class GetOnrampAllOffersUseCaseTest {
|
|||
val cardGroup = offers.first()
|
||||
Truth.assertThat(
|
||||
cardGroup.methodStatus,
|
||||
).isEqualTo(PaymentMethodStatus.Unavailable(BigDecimal("50.0")))
|
||||
).isEqualTo(PaymentMethodStatus.Unavailable.MinAmount(BigDecimal("50.0")))
|
||||
Truth.assertThat(cardGroup.offers).hasSize(2)
|
||||
|
||||
Truth.assertThat(cardGroup.bestRateOffer).isNotNull()
|
||||
|
|
@ -446,14 +446,17 @@ class GetOnrampAllOffersUseCaseTest {
|
|||
paymentMethod: OnrampPaymentMethod,
|
||||
provider: OnrampProvider,
|
||||
requiredAmount: BigDecimal = BigDecimal("50.0"),
|
||||
isMinAmountError: Boolean = true,
|
||||
): OnrampQuote.AmountError {
|
||||
return mockk<OnrampQuote.AmountError> {
|
||||
every { this@mockk.paymentMethod } returns paymentMethod
|
||||
every { this@mockk.provider } returns provider
|
||||
every { this@mockk.fromAmount } returns createMockAmount(BigDecimal("10.0"))
|
||||
every { this@mockk.countryCode } returns "US"
|
||||
every { this@mockk.error } returns mockk<OnrampError.AmountError> {
|
||||
every { this@mockk.requiredAmount } returns requiredAmount
|
||||
every { this@mockk.error } returns if (isMinAmountError) {
|
||||
OnrampError.AmountError.TooSmallError(requiredAmount = requiredAmount)
|
||||
} else {
|
||||
OnrampError.AmountError.TooBigError(requiredAmount = requiredAmount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,9 +175,14 @@ internal class AllOffersStateFactory(
|
|||
offer: OnrampOffer,
|
||||
currencyCode: String,
|
||||
): OnrampOfferUM {
|
||||
val advantages = when (quote.error) {
|
||||
is OnrampError.AmountError.TooSmallError -> OnrampOfferAdvantagesUM.Unavailable.MinAmount
|
||||
is OnrampError.AmountError.TooBigError -> OnrampOfferAdvantagesUM.Unavailable.MaxAmount
|
||||
}
|
||||
|
||||
return OnrampOfferUM(
|
||||
category = OnrampOfferCategoryUM.Recommended,
|
||||
advantages = OnrampOfferAdvantagesUM.Unavailable,
|
||||
advantages = advantages,
|
||||
paymentMethod = quote.paymentMethod,
|
||||
providerName = quote.provider.info.name,
|
||||
rate = formatRequiredAmount(quote, currencyCode),
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ private fun PaymentMethod(methodUM: AllOffersPaymentMethodUM, modifier: Modifier
|
|||
UnavailablePaymentMethodInfoBlock(
|
||||
paymentMethodName = methodUM.methodConfig.method.name,
|
||||
errorAmount = methodUM.rate,
|
||||
unavailableStatus = methodUM.paymentMethodStatus,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -116,7 +117,11 @@ private fun PaymentMethod(methodUM: AllOffersPaymentMethodUM, modifier: Modifier
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun UnavailablePaymentMethodInfoBlock(paymentMethodName: String, errorAmount: String) {
|
||||
private fun UnavailablePaymentMethodInfoBlock(
|
||||
paymentMethodName: String,
|
||||
errorAmount: String,
|
||||
unavailableStatus: PaymentMethodStatus.Unavailable,
|
||||
) {
|
||||
Column(modifier = Modifier.padding(bottom = 14.dp)) {
|
||||
Text(
|
||||
text = paymentMethodName,
|
||||
|
|
@ -125,8 +130,12 @@ private fun UnavailablePaymentMethodInfoBlock(paymentMethodName: String, errorAm
|
|||
modifier = Modifier.testTag(SelectPaymentMethodBottomSheetTestTags.PAYMENT_METHOD_NAME),
|
||||
)
|
||||
SpacerH(2.dp)
|
||||
val messageResId = when (unavailableStatus) {
|
||||
is PaymentMethodStatus.Unavailable.MinAmount -> R.string.onramp_provider_min_amount
|
||||
is PaymentMethodStatus.Unavailable.MaxAmount -> R.string.onramp_provider_max_amount
|
||||
}
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.onramp_provider_min_amount, errorAmount),
|
||||
text = stringResourceSafe(messageResId, errorAmount),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier.testTag(SelectPaymentMethodBottomSheetTestTags.UP_TO_TEXT),
|
||||
|
|
|
|||
|
|
@ -34,8 +34,16 @@ internal enum class OnrampOfferCategoryUM {
|
|||
RecentlyUsed, Recommended
|
||||
}
|
||||
|
||||
internal enum class OnrampOfferAdvantagesUM {
|
||||
Default, BestRate, GreatRate, Fastest, Unavailable;
|
||||
internal sealed interface OnrampOfferAdvantagesUM {
|
||||
data object Default : OnrampOfferAdvantagesUM
|
||||
data object BestRate : OnrampOfferAdvantagesUM
|
||||
data object GreatRate : OnrampOfferAdvantagesUM
|
||||
data object Fastest : OnrampOfferAdvantagesUM
|
||||
|
||||
sealed interface Unavailable : OnrampOfferAdvantagesUM {
|
||||
data object MinAmount : Unavailable
|
||||
data object MaxAmount : Unavailable
|
||||
}
|
||||
|
||||
fun toAnalyticsEvent(
|
||||
cryptoCurrencySymbol: String,
|
||||
|
|
@ -55,7 +63,7 @@ internal enum class OnrampOfferAdvantagesUM {
|
|||
)
|
||||
Default,
|
||||
BestRate,
|
||||
Unavailable,
|
||||
is Unavailable,
|
||||
-> null
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ internal fun Offer(onrampOfferUM: OnrampOfferUM, modifier: Modifier = Modifier)
|
|||
RateBlock(
|
||||
rate = onrampOfferUM.rate,
|
||||
diff = onrampOfferUM.diff,
|
||||
isOfferUnavailable = onrampOfferUM.advantages == OnrampOfferAdvantagesUM.Unavailable,
|
||||
isOfferUnavailable = onrampOfferUM.advantages is OnrampOfferAdvantagesUM.Unavailable,
|
||||
)
|
||||
}
|
||||
SpacerWMax()
|
||||
|
|
@ -127,7 +127,7 @@ internal fun Offer(onrampOfferUM: OnrampOfferUM, modifier: Modifier = Modifier)
|
|||
size = TangemButtonSize.RoundedAction,
|
||||
text = stringResourceSafe(R.string.common_buy),
|
||||
onClick = onrampOfferUM.onBuyClicked,
|
||||
enabled = onrampOfferUM.advantages != OnrampOfferAdvantagesUM.Unavailable,
|
||||
enabled = onrampOfferUM.advantages !is OnrampOfferAdvantagesUM.Unavailable,
|
||||
)
|
||||
}
|
||||
SpacerH(10.dp)
|
||||
|
|
@ -184,9 +184,13 @@ private fun OfferHeader(advantage: OnrampOfferAdvantagesUM) {
|
|||
color = TangemTheme.colors.icon.attention,
|
||||
)
|
||||
}
|
||||
OnrampOfferAdvantagesUM.Unavailable -> {
|
||||
is OnrampOfferAdvantagesUM.Unavailable -> {
|
||||
val textResId = when (advantage) {
|
||||
OnrampOfferAdvantagesUM.Unavailable.MinAmount -> R.string.onramp_title_available_from
|
||||
OnrampOfferAdvantagesUM.Unavailable.MaxAmount -> R.string.onramp_title_available_up_to
|
||||
}
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.onramp_title_available_from),
|
||||
text = stringResourceSafe(textResId),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue