Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-05 20:07:00 +05:00
parent 0fe5355c74
commit c32507b283
21 changed files with 344 additions and 108 deletions

View file

@ -774,6 +774,7 @@
<string name="staking_rewards">Belohnungen</string>
<string name="staking_stake_locked">Stake gesperrt</string>
<string name="staking_stake_more">Mehr staken</string>
<string name="staking_staked_amount">Gestakeder Betrag</string>
<string name="staking_summary_description_text">Du setzt %1$s ein und ethältst Deine Belohnung %2$s</string>
<string name="staking_tap_to_unlock">Zum Entsperren antippen</string>
<string name="staking_tap_to_unlock_or_vote">Tippe zum Entsperren oder Abstimmen</string>

View file

@ -856,6 +856,7 @@
<string name="transaction_history_transaction_from_address">desde: %s</string>
<string name="transaction_history_transaction_to_address">a: %s</string>
<string name="transaction_history_transaction_validator">validador: %s</string>
<string name="transfer_notification_invalid_minimum_transaction_amount_text">El monto mínimo para realizar esta transacción es %1$s.</string>
<string name="try_to_load_data_again_button_title">Inténtelo de nuevo</string>
<string name="twin_error_same_card">Ha escaneado la misma tarjeta. Para crear una billetera gemela, necesite escanear la tarjeta con no. %d</string>
<string name="twin_error_wrong_twin">Ha escaneado la tarjeta gemela incorrecta. Por favor, intente con otra</string>

View file

@ -856,6 +856,7 @@
<string name="transaction_history_transaction_from_address">de : %s</string>
<string name="transaction_history_transaction_to_address">à : %s</string>
<string name="transaction_history_transaction_validator">validateur : %s</string>
<string name="transfer_notification_invalid_minimum_transaction_amount_text">Le montant minimum pour effectuer cette transaction est %1$s.</string>
<string name="try_to_load_data_again_button_title">Réessayez</string>
<string name="twin_error_same_card">Vous avez scanné la même carte. Pour créer un portefeuille jumeau, vous devez scanner la carte portant le numéro %d</string>
<string name="twin_error_wrong_twin">Vous avez scanné une mauvaise carte jumelle. S\'il vous plaît, essayez-en un autre</string>

View file

@ -764,6 +764,7 @@
<string name="staking_rewards">報酬</string>
<string name="staking_stake_locked">ステーキングはロックされています</string>
<string name="staking_stake_more">もっとステーキングする</string>
<string name="staking_staked_amount">ステーキング中の金額</string>
<string name="staking_summary_description_text">%1$sをステーキングし、報酬%2$sを受け取ります</string>
<string name="staking_tap_to_unlock">タップしてロック解除</string>
<string name="staking_tap_to_unlock_or_vote">タップしてロック解除もしくは投票</string>

View file

@ -714,6 +714,7 @@
<string name="settings_wallet_name_title">Имя</string>
<string name="staking_amount_requirement_error">Сумма для стейкинга должна быть не менее %s</string>
<string name="staking_amount_tron_integer_error">Согласно правилам сети, сумма стейкинга будет округлена до %1$sTRX.</string>
<string name="staking_amount_tron_integer_error_unstaking">Сумма для вывода из стейкинга будет округлена до %1$s TRX ввиду особенностей сети.</string>
<string name="staking_claim_unstaked">Забрать средства</string>
<string name="staking_details_account_fee">Комиссия за стейкинг аккаунт</string>
<string name="staking_details_account_fee_info">Стейкинг аккаунт — это специальный счет, на котором хранятся застейканные токены SOL. Он создается при делегировании ваших токенов валидатору для участия в подтверждении транзакций и получении наград. За создание стейкинг аккаунта взимается небольшая комиссия, которая возвращается после завершения стейкинга.</string>
@ -756,6 +757,7 @@
<string name="staking_notification_earn_rewards_text_period_week">Стейкинг дает возможность вам получать %1$s. Награда будет зачисляться каждую неделю.</string>
<string name="staking_notification_earn_rewards_text_weekly">Стейкайте безопасно и начинайте получать еженедельные награды.</string>
<string name="staking_notification_earn_rewards_title">Получите награду за стейкинг</string>
<string name="staking_notification_low_staked_balance_text">Оставшийся застейканный баланс будет слишком мал для вывода. Вам потребуется застейкать больше средств, чтобы достичь минимальной суммы для вывода.</string>
<string name="staking_notification_network_error_text">Стейкинг временно недоступен из-за проблем в сети. Пожалуйста, попробуйте позже.</string>
<string name="staking_notification_new_validator_funds_transfer">Стейкинг в сети %1$s с новым валидатором автоматически переведет ваши текущие застейканные средства на него.</string>
<string name="staking_notification_restake_rewards_text">Реинвестируйте свои заработанные награды в вашу застейканную сумму, увеличивая потенциальный доход</string>
@ -798,7 +800,7 @@
<string name="staking_unbonding">Отзыв</string>
<string name="staking_unlocked_locked">Разблокировать</string>
<string name="staking_unlocking">Разблокировка</string>
<string name="staking_unstake_amount_requirement_error">Сумма для стейкинга должна быть не менее %s</string>
<string name="staking_unstake_amount_requirement_error">Сумма для вывода из стейкинга должна быть не менее %s</string>
<string name="staking_unstake_amount_validation_error">Сумма превышает застейканный баланс</string>
<string name="staking_unstaked">Вывод из стейкинга</string>
<string name="staking_unstaking">Завершение стейкинга</string>
@ -874,6 +876,7 @@
<string name="transaction_history_transaction_from_address">от: %s</string>
<string name="transaction_history_transaction_to_address">на: %s</string>
<string name="transaction_history_transaction_validator">валидатор: %s</string>
<string name="transfer_notification_invalid_minimum_transaction_amount_text">Минимальная сумма транзакции равна %1$s.</string>
<string name="try_to_load_data_again_button_title">Попробовать снова</string>
<string name="twin_error_same_card">Вы отсканировали ту же карту. Для создания twin-кошелька вам необходимо отсканировать карту с номером %d</string>
<string name="twin_error_wrong_twin">Вы отсканировали не ту twin-карту. Пожалуйста, попробуйте отсканировать другую</string>

View file

@ -551,10 +551,16 @@
<string name="onboarding_wallet_info_title_fourth">Access code restore</string>
<string name="onboarding_wallet_info_title_second">Identical cards</string>
<string name="onboarding_wallet_info_title_third">Access code</string>
<string name="onramp_country_search">Search by country</string>
<string name="onramp_country_unavailable">Unavailable</string>
<string name="onramp_currency_search">Search by currency</string>
<string name="onramp_pay_with">Pay with</string>
<string name="onramp_residency_bottomsheet_country_not_supported">Our services are not available in this country</string>
<string name="onramp_residency_bottomsheet_country_subtitle">Change or confirm it</string>
<string name="onramp_residency_bottomsheet_title">Your residence has been identified as</string>
<string name="onramp_settings_residence">Residence</string>
<string name="onramp_settings_residence_description">Please select the correct country to ensure accurate payment options and services.</string>
<string name="onramp_settings_title">Settings</string>
<string name="onramp_via">Via</string>
<string name="organize_tokens_group">Group</string>
<string name="organize_tokens_sort_by_balance">By balance</string>
@ -741,6 +747,8 @@
<string name="staking_notification_earn_rewards_text_period_week">Staking allows you to earn %1$s. Your staking rewards arrive every week.</string>
<string name="staking_notification_earn_rewards_text_weekly">Stake securely and start earning weekly rewards</string>
<string name="staking_notification_earn_rewards_title">Earn staking rewards</string>
<string name="staking_notification_low_staked_balance_text">Your remaining staked balance will be too low to unstake. Youll need to stake more to meet the minimum unstake amount.</string>
<string name="staking_notification_low_staked_balance_title">Low staked balance</string>
<string name="staking_notification_network_error_text">Staking is currently unavailable due to network conditions. Please try again later.</string>
<string name="staking_notification_new_validator_funds_transfer">Staking in the %1$s network with a new validator will automatically transfer all previously staked funds to this validator</string>
<string name="staking_notification_restake_rewards_text">Reinvests your earned rewards in your staked amount, increasing potential earnings.</string>
@ -861,6 +869,7 @@
<string name="transaction_history_transaction_from_address">from: %s</string>
<string name="transaction_history_transaction_to_address">to: %s</string>
<string name="transaction_history_transaction_validator">validator: %s</string>
<string name="transfer_notification_invalid_minimum_transaction_amount_text">The minimum transaction amount is %1$s.</string>
<string name="try_to_load_data_again_button_title">Try again</string>
<string name="twin_error_same_card">You\'ve scanned the same card. To create a twin wallet you need to scan the card with number %d</string>
<string name="twin_error_wrong_twin">You\'ve scanned wrong twin card. Please try another one</string>

View file

@ -1,61 +1,62 @@
package com.tangem.features.onramp.component.impl
import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.stack.Children
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.arkivanov.decompose.router.stack.StackNavigation
import com.arkivanov.decompose.router.stack.childStack
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.features.onramp.component.OnrampComponent
import com.tangem.features.onramp.component.ConfirmResidencyComponent
import com.tangem.features.onramp.entity.OnrampBottomSheetConfig
import com.tangem.features.onramp.model.OnrampModel
import com.tangem.features.onramp.entity.OnrampChild
import com.tangem.features.onramp.settings.OnrampSettingsComponent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@Suppress("UnusedPrivateMember")
internal class DefaultOnrampComponent @AssistedInject constructor(
@Assisted context: AppComponentContext,
@Assisted private val params: OnrampComponent.Params,
private val confirmResidencyComponentFactory: ConfirmResidencyComponent.Factory,
@Assisted params: OnrampComponent.Params,
private val settingsComponentFactory: OnrampSettingsComponent.Factory,
) : OnrampComponent, AppComponentContext by context {
private val model: OnrampModel = getOrCreateModel(params)
private val confirmResidencyBottomSheetSlot = childSlot(
source = model.bottomSheetNavigation,
serializer = null,
private val navigation = StackNavigation<OnrampChild>()
private val contentStack = childStack(
key = "onramp_content_stack",
source = navigation,
serializer = OnrampChild.serializer(),
initialConfiguration = OnrampChild.Settings,
handleBackButton = false,
childFactory = ::bottomSheetChild,
childFactory = ::screenChild,
)
@Composable
override fun Content(modifier: Modifier) {
val bottomSheet by confirmResidencyBottomSheetSlot.subscribeAsState()
BackHandler(onBack = router::pop)
val childStack by contentStack.subscribeAsState()
bottomSheet.child?.instance?.BottomSheet()
Children(
stack = childStack,
animation = stackAnimation(),
) { child ->
child.instance.Content(modifier = modifier)
}
}
private fun bottomSheetChild(
config: OnrampBottomSheetConfig,
componentContext: ComponentContext,
): ComposableBottomSheetComponent = when (config) {
OnrampBottomSheetConfig.ConfirmResidency -> confirmResidencyComponentFactory.create(
context = childByContext(componentContext),
params = ConfirmResidencyComponent.Params(
countryName = "United States",
isOnrampSupported = true,
countryFlagUrl = "https://hatscripts.github.io/circle-flags/flags/us.svg",
onDismiss = model.bottomSheetNavigation::dismiss,
),
)
}
private fun screenChild(config: OnrampChild, componentContext: ComponentContext): ComposableContentComponent =
when (config) {
OnrampChild.Settings -> settingsComponentFactory.create(
context = childByContext(componentContext),
// params = OnrampSettingsComponent.Params(navigation::pop) // todo uncomment after [REDACTED_JIRA]
params = OnrampSettingsComponent.Params(router::pop),
)
OnrampChild.Main -> TODO("[REDACTED_JIRA]")
}
@AssistedFactory
interface Factory : OnrampComponent.Factory {

View file

@ -1,26 +0,0 @@
package com.tangem.features.onramp.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.model.OnrampModel
import com.tangem.features.onramp.model.ConfirmResidencyModel
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
internal interface OnrampModelModule {
@Binds
@IntoMap
@ClassKey(OnrampModel::class)
fun provideOnrampModel(model: OnrampModel): Model
@Binds
@IntoMap
@ClassKey(ConfirmResidencyModel::class)
fun provideConfirmResidencyModel(model: ConfirmResidencyModel): Model
}

View file

@ -1,10 +0,0 @@
package com.tangem.features.onramp.entity
import kotlinx.serialization.Serializable
@Serializable
internal sealed class OnrampBottomSheetConfig {
@Serializable
data object ConfirmResidency : OnrampBottomSheetConfig()
}

View file

@ -0,0 +1,12 @@
package com.tangem.features.onramp.entity
import kotlinx.serialization.Serializable
@Serializable
internal sealed class OnrampChild {
@Serializable
data object Main : OnrampChild()
@Serializable
data object Settings : OnrampChild()
}

View file

@ -1,38 +0,0 @@
package com.tangem.features.onramp.model
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.features.onramp.component.OnrampComponent
import com.tangem.features.onramp.entity.OnrampBottomSheetConfig
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import javax.inject.Inject
@Suppress("MagicNumber")
@ComponentScoped
internal class OnrampModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val router: Router,
paramsContainer: ParamsContainer,
) : Model() {
@Suppress("UnusedPrivateMember")
private val params: OnrampComponent.Params = paramsContainer.require()
val bottomSheetNavigation: SlotNavigation<OnrampBottomSheetConfig> = SlotNavigation()
init {
modelScope.launch {
delay(1500)
bottomSheetNavigation.activate(OnrampBottomSheetConfig.ConfirmResidency)
}
}
fun pop() {
router.pop()
}
}

View file

@ -3,7 +3,7 @@ package com.tangem.features.onramp.selectcountry
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
interface SelectCountryComponent : ComposableBottomSheetComponent {
internal interface SelectCountryComponent : ComposableBottomSheetComponent {
data class Params(val onDismiss: () -> Unit)

View file

@ -0,0 +1,63 @@
package com.tangem.features.onramp.settings
import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.features.onramp.selectcountry.SelectCountryComponent
import com.tangem.features.onramp.settings.entity.OnrampSettingsConfig
import com.tangem.features.onramp.settings.model.OnrampSettingsModel
import com.tangem.features.onramp.settings.ui.OnrampSettingsContent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
internal class DefaultOnrampSettingsComponent @AssistedInject constructor(
@Assisted appComponentContext: AppComponentContext,
@Assisted private val params: OnrampSettingsComponent.Params,
private val selectCountryComponentFactory: SelectCountryComponent.Factory,
) : OnrampSettingsComponent, AppComponentContext by appComponentContext {
private val model: OnrampSettingsModel = getOrCreateModel(params)
private val bottomSheetSlot = childSlot(
source = model.bottomSheetNavigation,
serializer = null,
handleBackButton = false,
childFactory = ::bottomSheetChild,
)
@Composable
override fun Content(modifier: Modifier) {
BackHandler(onBack = params.onBack)
OnrampSettingsContent(modifier = modifier, state = model.state)
val bottomSheet by bottomSheetSlot.subscribeAsState()
bottomSheet.child?.instance?.BottomSheet()
}
private fun bottomSheetChild(
config: OnrampSettingsConfig,
componentContext: ComponentContext,
): ComposableBottomSheetComponent = when (config) {
OnrampSettingsConfig.SelectCountry -> selectCountryComponentFactory.create(
context = childByContext(componentContext),
params = SelectCountryComponent.Params(model.bottomSheetNavigation::dismiss),
)
}
@AssistedFactory
interface Factory : OnrampSettingsComponent.Factory {
override fun create(
context: AppComponentContext,
params: OnrampSettingsComponent.Params,
): DefaultOnrampSettingsComponent
}
}

View file

@ -0,0 +1,11 @@
package com.tangem.features.onramp.settings
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
internal interface OnrampSettingsComponent : ComposableContentComponent {
data class Params(val onBack: () -> Unit)
interface Factory : ComponentFactory<Params, OnrampSettingsComponent>
}

View file

@ -0,0 +1,20 @@
package com.tangem.features.onramp.settings.di
import com.tangem.features.onramp.settings.DefaultOnrampSettingsComponent
import com.tangem.features.onramp.settings.OnrampSettingsComponent
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal interface OnrampSettingsComponentModule {
@Binds
@Singleton
fun bindOnrampSettingsComponentFactory(
factory: DefaultOnrampSettingsComponent.Factory,
): OnrampSettingsComponent.Factory
}

View file

@ -0,0 +1,20 @@
package com.tangem.features.onramp.settings.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.settings.model.OnrampSettingsModel
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
internal interface OnrampSettingsModelModule {
@Binds
@IntoMap
@ClassKey(OnrampSettingsModel::class)
fun bindOnrampSettingsModelModel(model: OnrampSettingsModel): Model
}

View file

@ -0,0 +1,9 @@
package com.tangem.features.onramp.settings.entity
import kotlinx.serialization.Serializable
@Serializable
sealed class OnrampSettingsConfig {
data object SelectCountry : OnrampSettingsConfig()
}

View file

@ -0,0 +1,5 @@
package com.tangem.features.onramp.settings.entity
sealed class OnrampSettingsItemUM {
data class Residence(val countryName: String, val flagUrl: String, val onClick: () -> Unit) : OnrampSettingsItemUM()
}

View file

@ -0,0 +1,8 @@
package com.tangem.features.onramp.settings.entity
import kotlinx.collections.immutable.ImmutableList
internal data class OnrampSettingsUM(
val onBack: () -> Unit,
val items: ImmutableList<OnrampSettingsItemUM>,
)

View file

@ -0,0 +1,34 @@
package com.tangem.features.onramp.settings.model
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.features.onramp.settings.OnrampSettingsComponent
import com.tangem.features.onramp.settings.entity.OnrampSettingsConfig
import com.tangem.features.onramp.settings.entity.OnrampSettingsItemUM
import com.tangem.features.onramp.settings.entity.OnrampSettingsUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.collections.immutable.toImmutableList
import javax.inject.Inject
@ComponentScoped
internal class OnrampSettingsModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
paramsContainer: ParamsContainer,
) : Model() {
private val params: OnrampSettingsComponent.Params = paramsContainer.require()
val bottomSheetNavigation: SlotNavigation<OnrampSettingsConfig> = SlotNavigation()
val state = OnrampSettingsUM(
onBack = params.onBack,
items = listOf(
OnrampSettingsItemUM.Residence(
countryName = "United States of America",
flagUrl = "",
onClick = { bottomSheetNavigation.activate(OnrampSettingsConfig.SelectCountry) },
),
).toImmutableList(),
)
}

View file

@ -0,0 +1,111 @@
package com.tangem.features.onramp.settings.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
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.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.util.fastForEach
import coil.compose.AsyncImage
import com.tangem.core.ui.components.SpacerWMax
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.WindowInsetsZero
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.settings.entity.OnrampSettingsItemUM
import com.tangem.features.onramp.settings.entity.OnrampSettingsUM
import kotlinx.collections.immutable.ImmutableList
@Composable
internal fun OnrampSettingsContent(state: OnrampSettingsUM, modifier: Modifier = Modifier) {
Scaffold(
modifier = modifier,
contentWindowInsets = WindowInsetsZero,
containerColor = TangemTheme.colors.background.secondary,
topBar = {
AppBarWithBackButton(
modifier = Modifier.statusBarsPadding(),
onBackClick = state.onBack,
text = stringResource(id = R.string.onramp_settings_title),
iconRes = R.drawable.ic_close_24,
)
},
content = { innerPadding ->
Content(
modifier = Modifier
.padding(innerPadding)
.fillMaxSize()
.padding(horizontal = TangemTheme.dimens.spacing16),
items = state.items,
)
},
)
}
@Composable
private fun Content(items: ImmutableList<OnrampSettingsItemUM>, modifier: Modifier = Modifier) {
Column(modifier = modifier) {
items.fastForEach { model ->
key(model) {
when (model) {
is OnrampSettingsItemUM.Residence -> ResidenceSection(model)
}
}
}
}
}
@Composable
private fun ResidenceSection(state: OnrampSettingsItemUM.Residence, modifier: Modifier = Modifier) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
) {
Row(
modifier = Modifier
.clip(RoundedCornerShape(TangemTheme.dimens.radius16))
.background(TangemTheme.colors.background.primary)
.clickable(onClick = state.onClick)
.padding(TangemTheme.dimens.spacing12)
.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = stringResource(id = R.string.onramp_settings_residence),
color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.subtitle2,
)
SpacerWMax()
AsyncImage(
modifier = Modifier.size(TangemTheme.dimens.size20),
model = state.flagUrl,
contentDescription = null,
)
Text(
text = state.countryName,
color = TangemTheme.colors.text.primary1,
style = TangemTheme.typography.body2,
)
Icon(
painter = painterResource(id = R.drawable.ic_chevron_right_24),
contentDescription = null,
tint = TangemTheme.colors.icon.informative,
)
}
Text(
text = stringResource(id = R.string.onramp_settings_residence_description),
color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.caption2,
)
}
}