Updated on 2026-08-14

This commit is contained in:
Tangem 2026-01-22 16:14:14 +03:00
parent 081128f2cf
commit 63b07cccc3
53 changed files with 614 additions and 464 deletions

View file

@ -7,4 +7,7 @@ internal class DefaultHotWalletFeatureToggles(
) : HotWalletFeatureToggles {
override val isHotWalletEnabled: Boolean
get() = featureTogglesManager.isFeatureEnabled(name = "HOT_WALLET_ENABLED")
override val isWalletCreationRestrictionEnabled: Boolean
get() = isHotWalletEnabled &&
featureTogglesManager.isFeatureEnabled(name = "HOT_WALLET_CREATION_RESTRICTION_ENABLED")
}

View file

@ -26,11 +26,11 @@ private const val DISABLED_COLORS_ALPHA = 0.5f
internal fun OptionBlock(
title: String,
description: String,
badge: (@Composable () -> Unit)?,
onClick: (() -> Unit)?,
enabled: Boolean,
backgroundColor: Color,
modifier: Modifier = Modifier,
backgroundColor: Color = TangemTheme.colors.background.primary,
badge: (@Composable () -> Unit)? = null,
enabled: Boolean = true,
) {
Column(
modifier = modifier

View file

@ -66,7 +66,7 @@ internal fun CreateHardwareWalletContent(state: CreateHardwareWalletUM, modifier
top = 20.dp,
end = 16.dp,
),
text = stringResourceSafe(R.string.wallet_create_common_title),
text = stringResourceSafe(R.string.hardware_wallet_create_title),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
@ -74,22 +74,22 @@ internal fun CreateHardwareWalletContent(state: CreateHardwareWalletUM, modifier
FeatureBlock(
modifier = Modifier
.padding(top = 32.dp),
title = stringResourceSafe(R.string.hw_upgrade_key_migration_title),
description = stringResourceSafe(R.string.hw_upgrade_key_migration_description),
iconRes = R.drawable.ic_mobile_security_24,
title = stringResourceSafe(R.string.hardware_wallet_key_feature_title),
description = stringResourceSafe(R.string.hardware_wallet_key_feature_description),
iconRes = R.drawable.ic_mobile_security_2_24,
)
FeatureBlock(
modifier = Modifier
.padding(top = 24.dp),
title = stringResourceSafe(R.string.hw_upgrade_funds_access_title),
description = stringResourceSafe(R.string.hw_upgrade_funds_access_description),
iconRes = R.drawable.ic_knight_shield_24,
title = stringResourceSafe(R.string.hardware_wallet_backup_feature_title),
description = stringResourceSafe(R.string.hardware_wallet_backup_feature_description),
iconRes = R.drawable.ic_double_star_24,
)
FeatureBlock(
modifier = Modifier
.padding(top = 24.dp),
title = stringResourceSafe(R.string.hw_upgrade_general_security_title),
description = stringResourceSafe(R.string.hw_upgrade_general_security_description),
title = stringResourceSafe(R.string.hardware_wallet_security_feature_title),
description = stringResourceSafe(R.string.hardware_wallet_security_feature_description),
iconRes = R.drawable.ic_protect_24,
)
}

View file

@ -75,14 +75,21 @@ internal fun CreateMobileWalletContent(state: CreateMobileWalletUM, modifier: Mo
.padding(top = 32.dp),
title = stringResourceSafe(R.string.hw_create_keys_title),
description = stringResourceSafe(R.string.hw_create_keys_description),
iconRes = R.drawable.ic_lock_24,
iconRes = R.drawable.ic_protect_24,
)
FeatureBlock(
modifier = Modifier
.padding(top = 24.dp),
title = stringResourceSafe(R.string.hw_create_seed_title),
description = stringResourceSafe(R.string.hw_create_seed_description),
iconRes = R.drawable.ic_settings_24,
iconRes = R.drawable.ic_seed_phrase_24,
)
FeatureBlock(
modifier = Modifier
.padding(top = 24.dp),
title = stringResourceSafe(R.string.hw_create_upgrade_title),
description = stringResourceSafe(R.string.hw_create_upgrade_description),
iconRes = R.drawable.ic_tangem_card_24,
)
}
SecondaryButton(

View file

@ -83,9 +83,9 @@ internal fun UpgradeWalletContent(state: UpgradeWalletUM, modifier: Modifier = M
FeatureBlock(
modifier = Modifier
.padding(top = 24.dp),
title = stringResourceSafe(R.string.hw_upgrade_funds_access_title),
description = stringResourceSafe(R.string.hw_upgrade_funds_access_description),
iconRes = R.drawable.ic_knight_shield_24,
title = stringResourceSafe(R.string.hw_upgrade_backup_title),
description = stringResourceSafe(R.string.hw_upgrade_backup_description),
iconRes = R.drawable.ic_smartphone_24,
)
FeatureBlock(
modifier = Modifier

View file

@ -19,6 +19,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@Stable
@ -48,19 +49,19 @@ internal class ViewPhraseModel @Inject constructor(
private fun loadSeedPhrase() {
val userWallet = getUserWalletUseCase(params.userWalletId)
.getOrElse { error("User wallet with id ${params.userWalletId} not found") }
if (userWallet is UserWallet.Hot) {
modelScope.launch {
val words = exportSeedPhraseUseCase.invoke(userWallet.hotWalletId)
.getOrElse { error("Unable to export seed phrase for wallet with id ${params.userWalletId}") }
.mnemonic
.mnemonicComponents
uiState.update {
it.copy(
words = words.mapIndexed { index, s ->
EnumeratedTwoColumnGridItem(index + 1, s)
}.toImmutableList(),
)
}
as? UserWallet.Hot ?: return
modelScope.launch {
val words = exportSeedPhraseUseCase.invoke(userWallet.hotWalletId)
.getOrElse { error -> Timber.e(error); throw error }
.mnemonic.mnemonicComponents
uiState.update {
it.copy(
words = words.mapIndexed { index, s ->
EnumeratedTwoColumnGridItem(index + 1, s)
}.toImmutableList(),
)
}
}
}

View file

@ -8,7 +8,6 @@ internal data class WalletBackupUM(
val recoveryPhraseOption: LabelUM?,
val googleDriveOption: LabelUM?,
val googleDriveStatus: BackupStatus,
val onBuyClick: () -> Unit,
val onRecoveryPhraseClick: () -> Unit,
val onGoogleDriveClick: () -> Unit,
val onHardwareWalletClick: () -> Unit,

View file

@ -2,21 +2,17 @@ package com.tangem.features.hotwallet.walletbackup.model
import com.tangem.common.routing.AppRoute
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.Basic
import com.tangem.core.analytics.utils.TrackingContextProxy
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.R
import com.tangem.core.ui.components.label.entity.LabelStyle
import com.tangem.core.ui.components.label.entity.LabelUM
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents
import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.domain.wallets.usecase.UnlockHotWalletContextualUseCase
import com.tangem.features.hotwallet.WalletBackupComponent
@ -36,8 +32,6 @@ internal class WalletBackupModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val getUserWalletUseCase: GetUserWalletUseCase,
private val unlockHotWalletContextualUseCase: UnlockHotWalletContextualUseCase,
private val generateBuyTangemCardLinkUseCase: GenerateBuyTangemCardLinkUseCase,
private val urlOpener: UrlOpener,
private val router: Router,
private val trackingContextProxy: TrackingContextProxy,
private val analyticsEventHandler: AnalyticsEventHandler,
@ -54,7 +48,7 @@ internal class WalletBackupModel @Inject constructor(
hardwareWalletOption = LabelUM(
text = resourceReference(R.string.common_recommended),
style = LabelStyle.ACCENT,
),
).takeIf { params.isColdWalletOptionShown },
recoveryPhraseOption = LabelUM(
text = resourceReference(R.string.hw_backup_no_backup),
style = LabelStyle.WARNING,
@ -64,7 +58,6 @@ internal class WalletBackupModel @Inject constructor(
style = LabelStyle.REGULAR,
),
googleDriveStatus = BackupStatus.ComingSoon,
onBuyClick = ::onBuyClick,
onRecoveryPhraseClick = ::onRecoveryPhraseClick,
onGoogleDriveClick = { },
onHardwareWalletClick = ::onHardwareWalletClick,
@ -129,14 +122,6 @@ internal class WalletBackupModel @Inject constructor(
backedUp = userWallet.backedUp,
)
private fun onBuyClick() {
analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.Backup))
modelScope.launch {
generateBuyTangemCardLinkUseCase
.invoke(GenerateBuyTangemCardLinkUseCase.Source.Backup).let { urlOpener.openUrl(it) }
}
}
private fun onRecoveryPhraseClick() {
analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonRecoveryPhrase())
if (uiState.value.backedUp) {
@ -157,10 +142,9 @@ internal class WalletBackupModel @Inject constructor(
)
} else {
router.push(
AppRoute.CreateWalletBackup(
AppRoute.WalletActivation(
userWalletId = params.userWalletId,
analyticsSource = AnalyticsParam.ScreensSources.Backup.value,
analyticsAction = WalletSettingsAnalyticEvents.RecoveryPhraseScreenAction.Backup.value,
isBackupExists = false,
),
)
}

View file

@ -1,36 +1,25 @@
package com.tangem.features.hotwallet.walletbackup.ui
import android.content.res.Configuration
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.components.label.Label
import com.tangem.core.ui.components.label.entity.LabelStyle
import com.tangem.core.ui.components.label.entity.LabelUM
import com.tangem.core.ui.components.rows.NetworkTitle
import com.tangem.core.ui.extensions.TextReference
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.ForceDarkTheme
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.hotwallet.common.ui.OptionBlock
@ -61,33 +50,31 @@ internal fun WalletBackupContent(state: WalletBackupUM, modifier: Modifier = Mod
end = 16.dp,
),
) {
Banner(state)
if (state.hardwareWalletOption != null) {
OptionBlock(
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
title = stringResourceSafe(R.string.hw_backup_upgrade_title),
description = stringResourceSafe(R.string.hw_backup_upgrade_description),
badge = { Label(state.hardwareWalletOption) },
onClick = state.onHardwareWalletClick,
enabled = true,
backgroundColor = TangemTheme.colors.background.primary,
)
OptionBlock(
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp),
title = stringResourceSafe(R.string.hw_backup_hardware_title),
description = stringResourceSafe(R.string.hw_backup_hardware_description),
badge = {
state.hardwareWalletOption?.let { Label(it) }
},
onClick = state.onHardwareWalletClick,
enabled = true,
backgroundColor = TangemTheme.colors.background.primary,
)
NetworkTitle(
modifier = Modifier
.padding(top = 8.dp),
title = {
Text(
modifier = Modifier,
text = stringResourceSafe(R.string.onboarding_create_wallet_options_button_options),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
)
},
)
NetworkTitle(
modifier = Modifier.padding(top = 8.dp),
title = {
Text(
modifier = Modifier,
text = stringResourceSafe(R.string.onboarding_create_wallet_options_button_options),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
)
},
)
}
OptionBlock(
modifier = Modifier,
title = stringResourceSafe(R.string.hw_backup_seed_title),
@ -116,120 +103,6 @@ internal fun WalletBackupContent(state: WalletBackupUM, modifier: Modifier = Mod
}
}
@Suppress("LongMethod")
@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun Banner(state: WalletBackupUM, modifier: Modifier = Modifier) {
ForceDarkTheme {
Column(
modifier = modifier
.background(
color = TangemTheme.colors.background.primary,
shape = RoundedCornerShape(16.dp),
),
) {
Column(
modifier = Modifier
.padding(
start = 12.dp,
top = 20.dp,
end = 12.dp,
),
) {
Text(
modifier = Modifier
.fillMaxWidth(),
text = "Tangem Wallet",
style = TangemTheme.typography.h3,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
)
Text(
modifier = Modifier
.fillMaxWidth()
.padding(
top = 4.dp,
),
text = "Keeps your crypto safe and offline. Slim as a credit card, safer than a bank vault.",
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
textAlign = TextAlign.Center,
)
FlowRow(
modifier = Modifier
.fillMaxWidth()
.padding(
start = 24.dp,
top = 16.dp,
end = 24.dp,
),
horizontalArrangement = Arrangement.Center,
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
FeatureItem(
iconResId = R.drawable.ic_shield_check_16,
text = resourceReference(R.string.welcome_create_wallet_feature_class),
)
FeatureItem(
iconResId = R.drawable.ic_flash_16,
text = resourceReference(R.string.welcome_create_wallet_feature_delivery),
)
FeatureItem(
iconResId = R.drawable.ic_sparkles_16,
text = resourceReference(R.string.welcome_create_wallet_feature_use),
)
}
Box(
modifier = Modifier
.padding(
start = 8.dp,
top = 12.dp,
end = 8.dp,
bottom = 20.dp,
),
) {
Image(
painter = painterResource(id = R.drawable.img_tangem_cards_vertical),
contentDescription = null,
)
SecondaryButton(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter),
text = stringResourceSafe(R.string.details_buy_wallet),
onClick = state.onBuyClick,
)
}
}
}
}
}
@Composable
private fun FeatureItem(@DrawableRes iconResId: Int, text: TextReference) {
Row(
modifier = Modifier
.wrapContentWidth()
.padding(horizontal = 8.dp),
horizontalArrangement = Arrangement.spacedBy(6.dp),
) {
Icon(
modifier = Modifier.size(16.dp),
painter = painterResource(iconResId),
tint = TangemTheme.colors.icon.accent,
contentDescription = null,
)
Text(
text = text.resolveReference(),
style = TangemTheme.typography.caption1,
color = TangemTheme.colors.text.secondary,
)
}
}
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@ -256,7 +129,6 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider<Wallet
),
googleDriveStatus = BackupStatus.ComingSoon,
onBackClick = {},
onBuyClick = {},
onRecoveryPhraseClick = {},
onGoogleDriveClick = {},
onHardwareWalletClick = {},
@ -277,7 +149,6 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider<Wallet
),
googleDriveStatus = BackupStatus.NoBackup,
onBackClick = {},
onBuyClick = {},
onRecoveryPhraseClick = {},
onGoogleDriveClick = {},
onHardwareWalletClick = {},
@ -298,7 +169,23 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider<Wallet
),
googleDriveStatus = BackupStatus.Done,
onBackClick = {},
onBuyClick = {},
onRecoveryPhraseClick = {},
onGoogleDriveClick = {},
onHardwareWalletClick = {},
backedUp = false,
),
WalletBackupUM(
hardwareWalletOption = null,
recoveryPhraseOption = LabelUM(
text = resourceReference(R.string.common_done),
style = LabelStyle.ACCENT,
),
googleDriveOption = LabelUM(
text = resourceReference(R.string.common_done),
style = LabelStyle.ACCENT,
),
googleDriveStatus = BackupStatus.Done,
onBackClick = {},
onRecoveryPhraseClick = {},
onGoogleDriveClick = {},
onHardwareWalletClick = {},

View file

@ -5,7 +5,6 @@ import com.tangem.core.ui.extensions.TextReference
import kotlinx.collections.immutable.ImmutableList
internal data class WalletHardwareBackupUM(
val showPurchaseBlock: Boolean = false,
val blocks: ImmutableList<Block>,
val onBackClick: () -> Unit,
val onBuyClick: () -> Unit,

View file

@ -32,10 +32,8 @@ import com.tangem.features.hotwallet.wallethardwarebackup.entity.WalletHardwareB
import com.tangem.hot.sdk.model.HotWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@ -119,7 +117,6 @@ internal class WalletHardwareBackupModel @Inject constructor(
init {
trackingContextProxy.addHotWalletContext()
analyticsEventHandler.send(WalletSettingsAnalyticEvents.HardwareBackupScreenOpened())
showPurchaseBlockWithDelay()
}
override fun onDestroy() {
@ -127,13 +124,6 @@ internal class WalletHardwareBackupModel @Inject constructor(
super.onDestroy()
}
private fun showPurchaseBlockWithDelay() {
modelScope.launch {
delay(SHOW_PURCHASE_BLOCK_DELAY)
uiState.update { it.copy(showPurchaseBlock = true) }
}
}
private fun onCreateNewWalletClick() {
analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonCreateNewWallet())
router.push(AppRoute.CreateHardwareWallet)
@ -175,8 +165,4 @@ internal class WalletHardwareBackupModel @Inject constructor(
.invoke(GenerateBuyTangemCardLinkUseCase.Source.Backup).let { urlOpener.openUrl(it) }
}
}
companion object {
private const val SHOW_PURCHASE_BLOCK_DELAY = 3000L
}
}

View file

@ -1,26 +1,26 @@
package com.tangem.features.hotwallet.wallethardwarebackup.ui
import android.content.res.Configuration
import androidx.compose.animation.AnimatedVisibility
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.components.buttons.common.TangemButtonSize
import com.tangem.core.ui.components.label.Label
import com.tangem.core.ui.components.label.entity.LabelStyle
import com.tangem.core.ui.components.label.entity.LabelUM
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.ForceDarkTheme
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.hotwallet.common.ui.OptionBlock
@ -71,6 +71,8 @@ internal fun WalletHardwareBackupContent(state: WalletHardwareBackupUM, modifier
end = 16.dp,
),
) {
Banner(onBuyClick = state.onBuyClick)
state.blocks.forEach { block ->
OptionBlock(
modifier = Modifier
@ -86,45 +88,119 @@ internal fun WalletHardwareBackupContent(state: WalletHardwareBackupUM, modifier
)
}
}
AnimatedVisibility(state.showPurchaseBlock) {
PurchaseBlock(
onBuyClick = state.onBuyClick,
)
}
}
@Suppress("LongMethod")
@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun Banner(onBuyClick: () -> Unit, modifier: Modifier = Modifier) {
ForceDarkTheme {
Column(
modifier = modifier
.background(
color = TangemTheme.colors.background.primary,
shape = RoundedCornerShape(16.dp),
),
) {
Column(
modifier = Modifier
.padding(
start = 12.dp,
top = 20.dp,
end = 12.dp,
),
) {
Text(
modifier = Modifier
.fillMaxWidth(),
text = stringResourceSafe(R.string.common_tangem_wallet),
style = TangemTheme.typography.h3,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
)
Text(
modifier = Modifier
.fillMaxWidth()
.padding(
top = 4.dp,
),
text = stringResourceSafe(R.string.hw_backup_banner_description),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
textAlign = TextAlign.Center,
)
FlowRow(
modifier = Modifier
.fillMaxWidth()
.padding(
start = 24.dp,
top = 16.dp,
end = 24.dp,
),
horizontalArrangement = Arrangement.Center,
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
FeatureItem(
iconResId = R.drawable.ic_shield_check_16,
text = resourceReference(R.string.welcome_create_wallet_feature_class),
)
FeatureItem(
iconResId = R.drawable.ic_flash_16,
text = resourceReference(R.string.welcome_create_wallet_feature_delivery),
)
FeatureItem(
iconResId = R.drawable.ic_sparkles_16,
text = resourceReference(R.string.welcome_create_wallet_feature_seedphrase),
)
}
Box(
modifier = Modifier
.padding(
start = 8.dp,
top = 12.dp,
end = 8.dp,
bottom = 20.dp,
),
) {
Image(
painter = painterResource(id = R.drawable.img_tangem_cards_vertical),
contentDescription = null,
)
SecondaryButton(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter),
text = stringResourceSafe(R.string.details_buy_wallet),
onClick = onBuyClick,
)
}
}
}
}
}
@Composable
private fun PurchaseBlock(onBuyClick: () -> Unit, modifier: Modifier = Modifier) {
private fun FeatureItem(@DrawableRes iconResId: Int, text: TextReference) {
Row(
modifier = modifier
.fillMaxWidth()
.padding(16.dp)
.background(
color = TangemTheme.colors.background.primary,
shape = TangemTheme.shapes.roundedCornersXMedium,
)
.padding(
horizontal = 20.dp,
vertical = 16.dp,
),
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.wrapContentWidth()
.padding(horizontal = 8.dp),
horizontalArrangement = Arrangement.spacedBy(6.dp),
) {
Text(
modifier = Modifier
.weight(1f)
.padding(end = 16.dp),
text = stringResourceSafe(R.string.wallet_add_hardware_purchase),
style = TangemTheme.typography.button,
color = TangemTheme.colors.text.primary1,
maxLines = 3,
overflow = TextOverflow.Ellipsis,
Icon(
modifier = Modifier.size(16.dp),
painter = painterResource(iconResId),
tint = TangemTheme.colors.icon.accent,
contentDescription = null,
)
SecondaryButton(
text = stringResourceSafe(R.string.wallet_import_buy_title),
onClick = onBuyClick,
size = TangemButtonSize.RoundedAction,
Text(
text = text.resolveReference(),
style = TangemTheme.typography.caption1,
color = TangemTheme.colors.text.secondary,
)
}
}
@ -156,7 +232,6 @@ private fun PreviewWalletHardwareBackupContent() {
onClick = { },
),
),
showPurchaseBlock = true,
onBuyClick = { },
),
)