Updated on 2026-08-14
This commit is contained in:
parent
081128f2cf
commit
63b07cccc3
53 changed files with 614 additions and 464 deletions
|
|
@ -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")
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = {},
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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 = { },
|
||||
),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue