Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-21 12:43:59 +03:00
commit fe2cfac54d
1140 changed files with 23493 additions and 8579 deletions

View file

@ -2,7 +2,7 @@ package com.tangem.features.onramp.hottokens
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWalletId
/**

View file

@ -4,7 +4,7 @@ import arrow.core.getOrElse
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.card.DerivePublicKeysUseCase
import com.tangem.domain.wallets.usecase.DerivePublicKeysUseCase
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase

View file

@ -24,14 +24,13 @@ internal sealed interface OnrampMainComponentUM {
) : OnrampMainComponentUM {
override val topBarConfig: OnrampMainTopBarUM = OnrampMainTopBarUM(
title = combinedReference(resourceReference(R.string.common_buy), stringReference(" $currency")),
startButtonUM = TopAppBarButtonUM(
iconRes = R.drawable.ic_close_24,
onIconClicked = onClose,
startButtonUM = TopAppBarButtonUM.Back(
onBackClicked = onClose,
enabled = true,
),
endButtonUM = TopAppBarButtonUM(
endButtonUM = TopAppBarButtonUM.Icon(
iconRes = R.drawable.ic_more_vertical_24,
onIconClicked = openSettings,
onClicked = openSettings,
enabled = false,
),
)

View file

@ -6,6 +6,7 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import com.tangem.common.ui.amountScreen.models.AmountFieldModel
import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.models.currency.CryptoCurrency
@ -37,7 +38,10 @@ internal class OnrampStateFactory(
fun getReadyState(currency: OnrampCurrency): OnrampMainComponentUM.Content {
val state = currentStateProvider()
val endButton = state.topBarConfig.endButtonUM.copy(enabled = true)
val endButton = when (val button = state.topBarConfig.endButtonUM) {
is TopAppBarButtonUM.Icon -> button.copy(enabled = true)
is TopAppBarButtonUM.Text -> button.copy(enabled = true)
}
return OnrampMainComponentUM.Content(
topBarConfig = state.topBarConfig.copy(endButtonUM = endButton),
buyButtonConfig = state.buyButtonConfig,
@ -80,7 +84,10 @@ internal class OnrampStateFactory(
fun getErrorState(errorCode: String? = null, onRefresh: () -> Unit): OnrampMainComponentUM {
val state = currentStateProvider()
val endButton = state.topBarConfig.endButtonUM.copy(enabled = true)
val endButton = when (val button = state.topBarConfig.endButtonUM) {
is TopAppBarButtonUM.Icon -> button.copy(enabled = true)
is TopAppBarButtonUM.Text -> button.copy(enabled = true)
}
return when (state) {
is OnrampMainComponentUM.Content -> state.copy(

View file

@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDirection
@ -26,6 +27,7 @@ import com.tangem.core.ui.components.fields.AmountTextField
import com.tangem.core.ui.components.fields.visualtransformations.AmountVisualTransformation
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.BuyTokenDetailsScreenTestTags
import com.tangem.core.ui.utils.rememberDecimalFormat
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.main.entity.OnrampAmountBlockUM
@ -84,7 +86,8 @@ private fun OnrampAmountField(amountField: AmountFieldModel) {
start = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing12,
)
.requiredHeightIn(min = TangemTheme.dimens.size32),
.requiredHeightIn(min = TangemTheme.dimens.size32)
.testTag(BuyTokenDetailsScreenTestTags.FIAT_AMOUNT_TEXT_FIELD),
)
LaunchedEffect(key1 = Unit) {
@ -101,7 +104,8 @@ private fun OnrampAmountSecondary(state: OnrampAmountSecondaryFieldUM) {
top = TangemTheme.dimens.spacing8,
start = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing12,
),
)
.testTag(BuyTokenDetailsScreenTestTags.TOKEN_AMOUNT),
contentAlignment = Alignment.Center,
) {
when (state) {
@ -138,12 +142,15 @@ private fun OnrampCurrencyIcon(currencyUM: OnrampCurrencyUM, modifier: Modifier
AsyncImage(
modifier = Modifier
.size(TangemTheme.dimens.size40)
.clip(CircleShape),
.clip(CircleShape)
.testTag(BuyTokenDetailsScreenTestTags.FIAT_CURRENCY_ICON),
model = currencyUM.iconUrl,
contentDescription = null,
)
Icon(
modifier = Modifier.size(TangemTheme.dimens.size16),
modifier = Modifier
.size(TangemTheme.dimens.size16)
.testTag(BuyTokenDetailsScreenTestTags.EXPAND_FIAT_LIST_BUTTON),
painter = painterResource(id = R.drawable.ic_chevron_24),
tint = TangemTheme.colors.icon.informative,
contentDescription = null,

View file

@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.ClickableText
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@ -15,6 +16,7 @@ import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.extensions.appendColored
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.BuyTokenDetailsScreenTestTags
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.main.entity.OnrampMainComponentUM
import com.tangem.features.onramp.main.entity.OnrampProviderBlockUM
@ -77,6 +79,7 @@ private fun OnrampTosText(provider: OnrampProviderBlockUM.Content?) {
color = TangemTheme.colors.text.tertiary,
textAlign = TextAlign.Center,
),
modifier = Modifier.testTag(BuyTokenDetailsScreenTestTags.TOS_BLOCK),
onClick = { offset ->
clickableAnnotation.getStringAnnotations(
tag = TERMS_OF_USE_KEY,

View file

@ -13,12 +13,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import com.tangem.core.ui.extensions.appendSpace
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.BuyTokenDetailsScreenTestTags
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.main.entity.OnrampProviderBlockUM
import com.tangem.features.onramp.paymentmethod.ui.PaymentMethodIcon
@ -60,6 +62,7 @@ private fun OnrampProviderBlock(state: OnrampProviderBlockUM.Content, modifier:
},
color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.body2,
modifier = Modifier.testTag(BuyTokenDetailsScreenTestTags.PROVIDER_TITLE),
)
Text(
text = buildAnnotatedString {
@ -69,6 +72,7 @@ private fun OnrampProviderBlock(state: OnrampProviderBlockUM.Content, modifier:
},
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier.testTag(BuyTokenDetailsScreenTestTags.PROVIDER_TEXT),
)
}
AnimatedVisibility(
@ -108,6 +112,7 @@ private fun OnrampProviderLoading(modifier: Modifier = Modifier) {
text = stringResourceSafe(id = R.string.express_provider),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier.testTag(BuyTokenDetailsScreenTestTags.PROVIDER_LOADING_TITLE),
)
Row(
verticalAlignment = Alignment.CenterVertically,
@ -122,6 +127,7 @@ private fun OnrampProviderLoading(modifier: Modifier = Modifier) {
text = stringResourceSafe(id = R.string.express_fetch_best_rates),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier.testTag(BuyTokenDetailsScreenTestTags.PROVIDER_LOADING_TEXT),
)
}
}

View file

@ -7,10 +7,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import coil.compose.SubcomposeAsyncImage
import coil.request.ImageRequest
import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.SelectProviderBottomSheetTestTags
@Composable
internal fun PaymentMethodIcon(imageUrl: String, modifier: Modifier = Modifier) {
@ -19,7 +21,8 @@ internal fun PaymentMethodIcon(imageUrl: String, modifier: Modifier = Modifier)
.size(TangemTheme.dimens.size40)
.clip(TangemTheme.shapes.roundedCorners8)
.background(TangemColorPalette.Light1)
.padding(TangemTheme.dimens.spacing6),
.padding(TangemTheme.dimens.spacing6)
.testTag(SelectProviderBottomSheetTestTags.PAYMENT_METHOD_ICON),
model = ImageRequest.Builder(context = LocalContext.current)
.data(imageUrl)
.crossfade(enable = true)

View file

@ -11,11 +11,13 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheet
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.selectedBorder
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.SelectPaymentMethodBottomSheetTestTags
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.paymentmethod.entity.PaymentMethodUM
import com.tangem.features.onramp.paymentmethod.entity.PaymentMethodsBottomSheetConfig
@ -49,7 +51,7 @@ private fun SelectPaymentMethodBottomSheetContent(
modifier: Modifier = Modifier,
) {
LazyColumn(
modifier = modifier,
modifier = modifier.testTag(SelectPaymentMethodBottomSheetTestTags.LAZY_LIST),
) {
items(
items = methods,
@ -86,7 +88,10 @@ private fun PaymentMethodItem(paymentMethod: PaymentMethodUM, isSelected: Boolea
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
) {
PaymentMethodIcon(paymentMethod.imageUrl)
PaymentMethodIcon(
imageUrl = paymentMethod.imageUrl,
modifier = Modifier.testTag(SelectPaymentMethodBottomSheetTestTags.PAYMENT_METHOD_ICON),
)
Text(
text = paymentMethod.name,
style = TangemTheme.typography.subtitle2,

View file

@ -15,6 +15,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextAlign
@ -32,6 +33,7 @@ import com.tangem.core.ui.components.bottomsheets.sheet.TangemBottomSheet
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.test.SelectProviderBottomSheetTestTags
import com.tangem.domain.onramp.model.OnrampPaymentMethod
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.paymentmethod.ui.PaymentMethodIcon
@ -101,15 +103,19 @@ private fun PaymentMethodBlock(
text = stringResourceSafe(id = R.string.onramp_pay_with),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier.testTag(SelectProviderBottomSheetTestTags.PAYMENT_METHOD_TITLE),
)
Text(
text = state.name,
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.primary1,
modifier = Modifier.testTag(SelectProviderBottomSheetTestTags.PAYMENT_METHOD_NAME),
)
}
Icon(
modifier = Modifier.size(TangemTheme.dimens.size24),
modifier = Modifier
.size(TangemTheme.dimens.size24)
.testTag(SelectProviderBottomSheetTestTags.PAYMENT_METHOD_EXPAND_BUTTON),
painter = painterResource(id = R.drawable.ic_chevron_24),
contentDescription = null,
tint = TangemTheme.colors.icon.informative,
@ -149,14 +155,16 @@ private fun AvailableProviderItem(state: ProviderListItemUM.Available.Content, m
modifier = modifier
.selectedBorder(isSelected = state.isSelected)
.clickable(onClick = state.onClick)
.padding(all = TangemTheme.dimens.spacing12),
.padding(all = TangemTheme.dimens.spacing12)
.testTag(SelectProviderBottomSheetTestTags.AVAILABLE_PROVIDER_ITEM),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
) {
SubcomposeAsyncImage(
modifier = Modifier
.size(size = TangemTheme.dimens.size40)
.clip(TangemTheme.shapes.roundedCorners8),
.clip(TangemTheme.shapes.roundedCorners8)
.testTag(SelectProviderBottomSheetTestTags.AVAILABLE_PROVIDER_NAME),
model = ImageRequest.Builder(context = LocalContext.current)
.data(state.imageUrl)
.crossfade(enable = true)
@ -166,7 +174,9 @@ private fun AvailableProviderItem(state: ProviderListItemUM.Available.Content, m
contentDescription = null,
)
Text(
modifier = Modifier.weight(1F),
modifier = Modifier
.weight(1F)
.testTag(SelectProviderBottomSheetTestTags.TOKEN_AMOUNT),
text = state.name,
style = TangemTheme.typography.subtitle2,
color = if (state.isSelected) TangemTheme.colors.text.primary1 else TangemTheme.colors.text.secondary,
@ -189,7 +199,8 @@ private fun AvailableProviderItem(state: ProviderListItemUM.Available.Content, m
modifier = Modifier
.clip(RoundedCornerShape(4.dp))
.background(TangemTheme.colors.icon.accent)
.padding(vertical = 1.dp, horizontal = 6.dp),
.padding(vertical = 1.dp, horizontal = 6.dp)
.testTag(SelectProviderBottomSheetTestTags.BEST_RATE_LABEL),
)
}
state.diffRate != null -> {
@ -218,7 +229,8 @@ private fun UnavailableProviderItem(
Row(
modifier = modifier
.selectedBorder(isSelected = isSelected)
.padding(all = TangemTheme.dimens.spacing12),
.padding(all = TangemTheme.dimens.spacing12)
.testTag(SelectProviderBottomSheetTestTags.UNAVAILABLE_PROVIDER_ITEM),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
) {
@ -240,11 +252,13 @@ private fun UnavailableProviderItem(
text = providerName,
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.secondary,
modifier = Modifier.testTag(SelectProviderBottomSheetTestTags.UNAVAILABLE_PROVIDER_NAME),
)
Text(
text = subtitle.resolveReference(),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
modifier = Modifier.testTag(SelectProviderBottomSheetTestTags.UNAVAILABLE_PROVIDER_SUBTITLE),
)
}
}
@ -259,7 +273,8 @@ private fun OnrampMoreProviders() {
contentDescription = null,
tint = TangemTheme.colors.icon.informative,
modifier = Modifier
.padding(top = 16.dp),
.padding(top = 16.dp)
.testTag(SelectProviderBottomSheetTestTags.MORE_PROVIDERS_ICON),
)
Text(
text = stringResourceSafe(R.string.express_more_providers_soon),
@ -267,7 +282,8 @@ private fun OnrampMoreProviders() {
color = TangemTheme.colors.icon.informative,
modifier = Modifier
.padding(top = 4.dp, bottom = 24.dp)
.padding(horizontal = TangemTheme.dimens.spacing56),
.padding(horizontal = TangemTheme.dimens.spacing56)
.testTag(SelectProviderBottomSheetTestTags.MORE_PROVIDERS_TEXT),
textAlign = TextAlign.Center,
)
}

View file

@ -54,9 +54,8 @@ internal class OnrampRedirectModel @Inject constructor(
resourceReference(R.string.common_buy),
stringReference(" ${params.cryptoCurrency.name}"),
),
startButtonUM = TopAppBarButtonUM(
iconRes = R.drawable.ic_close_24,
onIconClicked = appRouter::pop,
startButtonUM = TopAppBarButtonUM.Back(
onBackClicked = appRouter::pop,
enabled = true,
),
),

View file

@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import coil.compose.AsyncImage
@ -25,6 +26,7 @@ import com.tangem.core.ui.components.fields.SearchBar
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.SelectCountryBottomSheetTestTags
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.selectcountry.entity.CountryItemState
import com.tangem.features.onramp.selectcountry.entity.CountryListUM
@ -40,7 +42,7 @@ internal fun SelectCountryBottomSheet(config: TangemBottomSheetConfig, content:
@Composable
internal fun OnrampCountryList(state: CountryListUM, modifier: Modifier = Modifier) {
LazyColumn(
modifier = modifier,
modifier = modifier.testTag(SelectCountryBottomSheetTestTags.LAZY_LIST),
contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing16),
) {
item(key = "search_bar") {
@ -102,13 +104,15 @@ private fun LazyListScope.countryListWithContent(state: CountryListUM.Content) {
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = item.onClick)
.padding(vertical = TangemTheme.dimens.spacing16),
.padding(vertical = TangemTheme.dimens.spacing16)
.testTag(SelectCountryBottomSheetTestTags.COUNTRY_ITEM),
state = item,
)
is CountryItemState.WithContent.Unavailable -> UnavailableCountryItem(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = TangemTheme.dimens.spacing16),
.padding(vertical = TangemTheme.dimens.spacing16)
.testTag(SelectCountryBottomSheetTestTags.UNAVAILABLE_COUNTRY_ITEM),
state = item,
)
}
@ -138,13 +142,17 @@ private fun ContentCountryItem(state: CountryItemState.WithContent.Content, modi
verticalAlignment = Alignment.CenterVertically,
) {
AsyncImage(
modifier = Modifier.size(TangemTheme.dimens.size36),
modifier = Modifier
.size(TangemTheme.dimens.size36)
.testTag(SelectCountryBottomSheetTestTags.COUNTRY_ICON),
model = state.flagUrl,
contentDescription = null,
)
Text(
text = state.countryName,
modifier = Modifier.weight(1F),
modifier = Modifier
.weight(1F)
.testTag(SelectCountryBottomSheetTestTags.COUNTRY_NAME),
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = TangemTheme.typography.subtitle2,
@ -172,7 +180,8 @@ private fun UnavailableCountryItem(state: CountryItemState.WithContent.Unavailab
AsyncImage(
modifier = Modifier
.size(TangemTheme.dimens.size36)
.alpha(0.4F),
.alpha(0.4F)
.testTag(SelectCountryBottomSheetTestTags.UNAVAILABLE_COUNTRY_ICON),
model = state.flagUrl,
contentDescription = null,
)

View file

@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.util.fastForEach
import coil.compose.AsyncImage
import com.tangem.core.ui.components.CircleShimmer
@ -25,6 +26,7 @@ import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.BuyTokenFiatListTestTags
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.selectcurrency.entity.CurrenciesListUM
import com.tangem.features.onramp.selectcurrency.entity.CurrencyItemState
@ -40,7 +42,7 @@ internal fun SelectCurrencyBottomSheet(config: TangemBottomSheetConfig, content:
@Composable
internal fun OnrampCurrencyList(state: CurrenciesListUM, modifier: Modifier = Modifier) {
LazyColumn(
modifier = modifier,
modifier = modifier.testTag(BuyTokenFiatListTestTags.LAZY_LIST),
contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing16),
) {
item(key = "search_bar") {
@ -106,7 +108,8 @@ private fun LazyListScope.currencyListContent(state: CurrenciesListUM.Content) {
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = item.onClick)
.padding(vertical = TangemTheme.dimens.spacing16),
.padding(vertical = TangemTheme.dimens.spacing16)
.testTag(BuyTokenFiatListTestTags.LAZY_LIST_ITEM),
currency = item,
)
},

View file

@ -17,12 +17,12 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.onramp.model.OnrampSource
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.tokens.legacy.TradeCryptoAction
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.selecttoken.OnrampOperationComponent.Params
@ -57,7 +57,6 @@ internal class OnrampOperationModel @Inject constructor(
private val selectedUserWallet = getWalletsUseCase.invokeSync()
.first { it.walletId == params.userWalletId }
.requireColdWallet()
init {
analyticsEventHandler.send(
@ -154,7 +153,7 @@ internal class OnrampOperationModel @Inject constructor(
}
private fun showErrorIfDemoModeOrElse(action: () -> Unit) {
if (isDemoCardUseCase(cardId = selectedUserWallet.cardId)) {
if (selectedUserWallet is UserWallet.Cold && isDemoCardUseCase(cardId = selectedUserWallet.cardId)) {
val alertUM = AlertDemoModeUM(onConfirmClick = {})
val message = DialogMessage(

View file

@ -10,10 +10,12 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.BuyTokenScreenTestTags
import com.tangem.core.ui.utils.rememberHideKeyboardNestedScrollConnection
import com.tangem.features.onramp.hottokens.HotCryptoComponent
import com.tangem.features.onramp.impl.R
@ -36,7 +38,8 @@ internal fun OnrampSelectToken(
.nestedScroll(nestedScrollConnection)
.background(TangemTheme.colors.background.secondary)
.imePadding()
.systemBarsPadding(),
.systemBarsPadding()
.testTag(BuyTokenScreenTestTags.LAZY_LIST),
) {
stickyHeader(key = "header") {
AppBarWithBackButton(

View file

@ -12,6 +12,7 @@ import androidx.compose.runtime.key
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.util.fastForEach
import coil.compose.AsyncImage
@ -19,6 +20,7 @@ import com.tangem.core.ui.components.SpacerWMax
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.test.ResidenceSettingsScreenTestTags
import com.tangem.core.ui.utils.WindowInsetsZero
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.settings.entity.OnrampSettingsItemUM
@ -95,6 +97,7 @@ private fun ResidenceSection(state: OnrampSettingsItemUM.Residence, modifier: Mo
text = state.countryName,
color = TangemTheme.colors.text.primary1,
style = TangemTheme.typography.body2,
modifier = Modifier.testTag(ResidenceSettingsScreenTestTags.COUNTRY_NAME),
)
Icon(
painter = painterResource(id = R.drawable.ic_chevron_right_24),

View file

@ -61,9 +61,8 @@ private fun Content(state: OnrampSuccessComponentUM.Content, onBackClick: () ->
.systemBarsPadding(),
topBar = {
TangemTopAppBar(
startButton = TopAppBarButtonUM(
iconRes = R.drawable.ic_close_24,
onIconClicked = onBackClick,
startButton = TopAppBarButtonUM.Back(
onBackClicked = onBackClick,
),
)
},

View file

@ -4,8 +4,8 @@ import androidx.compose.runtime.Stable
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import kotlinx.coroutines.flow.StateFlow
/** Token list component that present list of available tokens for swap */

View file

@ -3,7 +3,7 @@ package com.tangem.features.onramp.swap.availablepairs.entity.converters
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.utils.converter.Converter
/**

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.swap.availablepairs.entity.transformers
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.onramp.swap.availablepairs.entity.converters.LoadingTokenListItemConverter
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer

View file

@ -4,7 +4,7 @@ import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
import com.tangem.features.onramp.tokenlist.entity.utils.OnrampTokenItemStateConverterFactory

View file

@ -16,9 +16,9 @@ import com.tangem.domain.core.utils.lceContent
import com.tangem.domain.core.utils.lceError
import com.tangem.domain.core.utils.lceLoading
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.feature.swap.domain.GetAvailablePairsUseCase
import com.tangem.feature.swap.domain.models.domain.LeastTokenInfo
@ -200,7 +200,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
.collectLatest { selectedStatus ->
val networkInfo = selectedStatus.toLeastTokenInfo()
val isAlreadyLoaded = availablePairsByNetworkFlow.value[networkInfo]?.isContent() ?: false
val isAlreadyLoaded = availablePairsByNetworkFlow.value[networkInfo]?.isContent() == true
if (isAlreadyLoaded) return@collectLatest
val statuses = tokenListFlow.firstOrNull() ?: return@collectLatest

View file

@ -9,7 +9,7 @@ import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.onramp.component.SwapSelectTokensComponent
import com.tangem.features.onramp.swap.entity.SwapSelectTokensController
import com.tangem.features.onramp.swap.entity.SwapSelectTokensUM

View file

@ -4,7 +4,7 @@ import androidx.compose.runtime.Stable
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.features.onramp.tokenlist.entity.OnrampOperation

View file

@ -7,7 +7,7 @@ import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer

View file

@ -8,7 +8,7 @@ import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIco
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.models.currency.CryptoCurrencyStatus
/**
[REDACTED_AUTHOR]

View file

@ -13,15 +13,14 @@ import com.tangem.domain.core.lce.Lce
import com.tangem.domain.core.utils.getOrElse
import com.tangem.domain.exchange.RampStateManager
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.models.tokenlist.TokenList
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
import com.tangem.domain.settings.usercountry.models.UserCountry
import com.tangem.domain.tokens.GetAssetRequirementsUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.error.TokenListError
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
@ -63,7 +62,6 @@ internal class OnrampTokenListModel @Inject constructor(
private val params: OnrampTokenListComponent.Params = paramsContainer.require()
private val userWallet by lazy {
getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId }
.requireColdWallet() // TODO [REDACTED_TASK_KEY]
}
init {

View file

@ -9,6 +9,8 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.key
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
@ -24,6 +26,8 @@ import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.test.BuyTokenScreenTestTags
import com.tangem.core.ui.utils.lazyListItemPosition
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
import com.tangem.features.onramp.tokenlist.ui.preview.PreviewTokenListUMProvider
import kotlinx.collections.immutable.ImmutableList
@ -90,7 +94,9 @@ private fun ItemsBlock(items: ImmutableList<TokensListItemUM>, isBalanceHidden:
lastIndex = items.lastIndex,
addDefaultPadding = false,
backgroundColor = TangemTheme.colors.background.primary,
),
)
.testTag(BuyTokenScreenTestTags.LAZY_LIST_ITEM)
.semantics { lazyListItemPosition = index },
)
}
}