Updated on 2026-08-14
This commit is contained in:
commit
4aa09819aa
5 changed files with 96 additions and 78 deletions
|
|
@ -88,7 +88,10 @@ internal class OnrampAmountStateFactory(
|
|||
)
|
||||
}
|
||||
|
||||
fun getAmountSecondaryUpdatedState(quoteWithProvider: OnrampProviderWithQuote.Data): OnrampMainComponentUM {
|
||||
fun getAmountSecondaryUpdatedState(
|
||||
quoteWithProvider: OnrampProviderWithQuote.Data,
|
||||
isBestRate: Boolean,
|
||||
): OnrampMainComponentUM {
|
||||
val currentState = currentStateProvider()
|
||||
if (currentState !is OnrampMainComponentUM.Content) return currentState
|
||||
|
||||
|
|
@ -103,7 +106,7 @@ internal class OnrampAmountStateFactory(
|
|||
providerBlockState = OnrampProviderBlockUM.Content(
|
||||
paymentMethod = quoteWithProvider.paymentMethod,
|
||||
providerName = quoteWithProvider.provider.info.name,
|
||||
isBestRate = true,
|
||||
isBestRate = isBestRate,
|
||||
onClick = onrampIntents::openProviders,
|
||||
),
|
||||
buyButtonConfig = currentState.buyButtonConfig.copy(
|
||||
|
|
|
|||
|
|
@ -99,8 +99,8 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
subscribeToQuotesUpdate()
|
||||
}
|
||||
|
||||
fun onProviderSelected(providerWithQuote: OnrampProviderWithQuote.Data) {
|
||||
_state.update { amountStateFactory.getAmountSecondaryUpdatedState(providerWithQuote) }
|
||||
fun onProviderSelected(providerWithQuote: OnrampProviderWithQuote.Data, isBestRate: Boolean) {
|
||||
_state.update { amountStateFactory.getAmountSecondaryUpdatedState(providerWithQuote, isBestRate) }
|
||||
}
|
||||
|
||||
private fun checkResidenceCountry() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package com.tangem.features.onramp.main.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
|
|
@ -68,20 +71,27 @@ private fun OnrampProviderBlock(state: OnrampProviderBlockUM.Content, modifier:
|
|||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
color = TangemTheme.colors.icon.accent,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius4),
|
||||
)
|
||||
.padding(
|
||||
horizontal = TangemTheme.dimens.spacing6,
|
||||
vertical = TangemTheme.dimens.spacing1,
|
||||
),
|
||||
text = stringResource(id = R.string.express_provider_best_rate),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.primary2,
|
||||
)
|
||||
AnimatedVisibility(
|
||||
visible = state.isBestRate,
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut(),
|
||||
label = "Best Rate visibility animation",
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
color = TangemTheme.colors.icon.accent,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius4),
|
||||
)
|
||||
.padding(
|
||||
horizontal = TangemTheme.dimens.spacing6,
|
||||
vertical = TangemTheme.dimens.spacing1,
|
||||
),
|
||||
text = stringResource(id = R.string.express_provider_best_rate),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.primary2,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import com.tangem.domain.tokens.model.CryptoCurrency
|
|||
internal interface SelectProviderComponent : ComposableBottomSheetComponent {
|
||||
|
||||
data class Params(
|
||||
val onProviderClick: (OnrampProviderWithQuote.Data) -> Unit,
|
||||
val onProviderClick: (OnrampProviderWithQuote.Data, Boolean) -> Unit,
|
||||
val onDismiss: () -> Unit,
|
||||
val selectedPaymentMethod: OnrampPaymentMethod,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ 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.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -123,64 +124,68 @@ internal class SelectProviderModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun List<OnrampProviderWithQuote>.toProvidersListItems() = sortedByDescending {
|
||||
(it as? OnrampProviderWithQuote.Data)?.toAmount?.value ?: BigDecimal.ZERO
|
||||
}.mapIndexed { index, quote ->
|
||||
when (quote) {
|
||||
is OnrampProviderWithQuote.Data -> {
|
||||
val rate = quote.toAmount.value.format {
|
||||
crypto(symbol = quote.toAmount.symbol, decimals = quote.toAmount.decimals)
|
||||
}
|
||||
ProviderListItemUM.Available(
|
||||
providerId = quote.provider.id,
|
||||
imageUrl = quote.provider.info.imageLarge,
|
||||
name = quote.provider.info.name,
|
||||
rate = rate,
|
||||
isSelected = index == 0,
|
||||
onClick = {
|
||||
analyticsEventHandler.send(
|
||||
OnrampAnalyticsEvent.OnProviderChosen(
|
||||
providerName = quote.provider.info.name,
|
||||
tokenSymbol = params.cryptoCurrency.symbol,
|
||||
),
|
||||
)
|
||||
params.onProviderClick(quote)
|
||||
params.onDismiss()
|
||||
},
|
||||
)
|
||||
}
|
||||
is OnrampProviderWithQuote.Unavailable.AvailableFrom -> {
|
||||
val amount = quote.amount.value.format {
|
||||
crypto(symbol = quote.amount.symbol, decimals = quote.amount.decimals)
|
||||
}
|
||||
ProviderListItemUM.Unavailable(
|
||||
providerId = quote.provider.id,
|
||||
imageUrl = quote.provider.info.imageLarge,
|
||||
name = quote.provider.info.name,
|
||||
subtitle = resourceReference(R.string.express_provider_min_amount, wrappedList(amount)),
|
||||
)
|
||||
}
|
||||
is OnrampProviderWithQuote.Unavailable.AvailableUpTo -> {
|
||||
val amount = quote.amount.value.format {
|
||||
crypto(symbol = quote.amount.symbol, decimals = quote.amount.decimals)
|
||||
}
|
||||
ProviderListItemUM.Unavailable(
|
||||
providerId = quote.provider.id,
|
||||
imageUrl = quote.provider.info.imageLarge,
|
||||
name = quote.provider.info.name,
|
||||
subtitle = resourceReference(R.string.express_provider_max_amount, wrappedList(amount)),
|
||||
)
|
||||
}
|
||||
is OnrampProviderWithQuote.Unavailable.NotSupportedPaymentMethod -> {
|
||||
ProviderListItemUM.Unavailable(
|
||||
providerId = quote.provider.id,
|
||||
imageUrl = quote.provider.info.imageLarge,
|
||||
name = quote.provider.info.name,
|
||||
subtitle = stringReference(
|
||||
"Available with ${quote.availablePaymentMethods.joinToString { it.name }}",
|
||||
),
|
||||
)
|
||||
}
|
||||
private fun List<OnrampProviderWithQuote>.toProvidersListItems(): ImmutableList<ProviderListItemUM> {
|
||||
val sortedByRate = sortedByDescending {
|
||||
(it as? OnrampProviderWithQuote.Data)?.toAmount?.value ?: BigDecimal.ZERO
|
||||
}
|
||||
}.toImmutableList()
|
||||
val bestProvider = sortedByRate.firstOrNull()
|
||||
return sortedByRate.mapIndexed { index, quote ->
|
||||
when (quote) {
|
||||
is OnrampProviderWithQuote.Data -> {
|
||||
val rate = quote.toAmount.value.format {
|
||||
crypto(symbol = quote.toAmount.symbol, decimals = quote.toAmount.decimals)
|
||||
}
|
||||
ProviderListItemUM.Available(
|
||||
providerId = quote.provider.id,
|
||||
imageUrl = quote.provider.info.imageLarge,
|
||||
name = quote.provider.info.name,
|
||||
rate = rate,
|
||||
isSelected = index == 0,
|
||||
onClick = {
|
||||
analyticsEventHandler.send(
|
||||
OnrampAnalyticsEvent.OnProviderChosen(
|
||||
providerName = quote.provider.info.name,
|
||||
tokenSymbol = params.cryptoCurrency.symbol,
|
||||
),
|
||||
)
|
||||
params.onProviderClick(quote, bestProvider == quote)
|
||||
params.onDismiss()
|
||||
},
|
||||
)
|
||||
}
|
||||
is OnrampProviderWithQuote.Unavailable.AvailableFrom -> {
|
||||
val amount = quote.amount.value.format {
|
||||
crypto(symbol = quote.amount.symbol, decimals = quote.amount.decimals)
|
||||
}
|
||||
ProviderListItemUM.Unavailable(
|
||||
providerId = quote.provider.id,
|
||||
imageUrl = quote.provider.info.imageLarge,
|
||||
name = quote.provider.info.name,
|
||||
subtitle = resourceReference(R.string.express_provider_min_amount, wrappedList(amount)),
|
||||
)
|
||||
}
|
||||
is OnrampProviderWithQuote.Unavailable.AvailableUpTo -> {
|
||||
val amount = quote.amount.value.format {
|
||||
crypto(symbol = quote.amount.symbol, decimals = quote.amount.decimals)
|
||||
}
|
||||
ProviderListItemUM.Unavailable(
|
||||
providerId = quote.provider.id,
|
||||
imageUrl = quote.provider.info.imageLarge,
|
||||
name = quote.provider.info.name,
|
||||
subtitle = resourceReference(R.string.express_provider_max_amount, wrappedList(amount)),
|
||||
)
|
||||
}
|
||||
is OnrampProviderWithQuote.Unavailable.NotSupportedPaymentMethod -> {
|
||||
ProviderListItemUM.Unavailable(
|
||||
providerId = quote.provider.id,
|
||||
imageUrl = quote.provider.info.imageLarge,
|
||||
name = quote.provider.info.name,
|
||||
subtitle = stringReference(
|
||||
"Available with ${quote.availablePaymentMethods.joinToString { it.name }}",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}.toImmutableList()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue