Updated on 2026-08-14
This commit is contained in:
parent
081128f2cf
commit
63b07cccc3
53 changed files with 614 additions and 464 deletions
|
|
@ -92,7 +92,7 @@ internal class CreateWalletStartModel @Inject constructor(
|
|||
onPrimaryButtonClick = ::onBuyClick,
|
||||
primaryButtonText = resourceReference(R.string.details_buy_wallet),
|
||||
otherMethodTitle = resourceReference(R.string.welcome_create_wallet_mobile_title),
|
||||
otherMethodDescription = resourceReference(R.string.welcome_create_wallet_mobile_description),
|
||||
otherMethodDescription = null,
|
||||
otherMethodClick = ::onStartWithMobileWalletClick,
|
||||
onBackClick = { router.pop() },
|
||||
onScanClick = ::onScanClick,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ internal data class CreateWalletStartUM(
|
|||
val shouldShowScanSecondaryButton: Boolean,
|
||||
val primaryButtonText: TextReference,
|
||||
val onPrimaryButtonClick: () -> Unit,
|
||||
val otherMethodDescription: TextReference,
|
||||
val otherMethodDescription: TextReference?,
|
||||
val otherMethodTitle: TextReference,
|
||||
val otherMethodClick: () -> Unit,
|
||||
val onScanClick: () -> Unit,
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ internal fun CreateWalletStartContent(state: CreateWalletStartUM, modifier: Modi
|
|||
.height(16.dp),
|
||||
)
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.welcome_create_wallet_other_method),
|
||||
text = stringResourceSafe(R.string.common_or),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
|
|
@ -193,19 +193,21 @@ internal fun CreateWalletStartContent(state: CreateWalletStartUM, modifier: Modi
|
|||
.scale(scaleX = -1f, scaleY = 1f),
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = 16.dp,
|
||||
top = 16.dp,
|
||||
end = 16.dp,
|
||||
),
|
||||
text = state.otherMethodDescription.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
if (state.otherMethodDescription != null) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = 16.dp,
|
||||
top = 16.dp,
|
||||
end = 16.dp,
|
||||
),
|
||||
text = state.otherMethodDescription.resolveReference(),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.wrapContentWidth()
|
||||
|
|
@ -429,9 +431,7 @@ private class CreateWalletStartStateProvider : CollectionPreviewParameterProvide
|
|||
onPrimaryButtonClick = { },
|
||||
primaryButtonText = resourceReference(R.string.details_buy_wallet),
|
||||
otherMethodTitle = resourceReference(R.string.welcome_create_wallet_mobile_title),
|
||||
otherMethodDescription = resourceReference(
|
||||
R.string.welcome_create_wallet_mobile_description,
|
||||
),
|
||||
otherMethodDescription = null,
|
||||
otherMethodClick = { },
|
||||
onBackClick = { },
|
||||
onScanClick = { },
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import com.tangem.features.details.entity.DetailsUM
|
|||
import com.tangem.features.details.ui.DetailsScreen
|
||||
import com.tangem.features.details.utils.ItemsBuilder
|
||||
import com.tangem.features.details.utils.SocialsBuilder
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
internal class PreviewDetailsComponent : DetailsComponent {
|
||||
|
|
@ -19,9 +20,14 @@ internal class PreviewDetailsComponent : DetailsComponent {
|
|||
private val previewBlocks = runBlocking {
|
||||
ItemsBuilder(
|
||||
router = DummyRouter(),
|
||||
hotWalletFeatureToggles = object : HotWalletFeatureToggles {
|
||||
override val isHotWalletEnabled: Boolean = true
|
||||
override val isWalletCreationRestrictionEnabled: Boolean = true
|
||||
},
|
||||
).buildAll(
|
||||
isWalletConnectAvailable = true,
|
||||
isSupportChatAvailable = true,
|
||||
hasAnyMobileWallet = true,
|
||||
userWalletId = UserWalletId(""),
|
||||
onSupportEmailClick = {},
|
||||
onSupportChatClick = {},
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ internal class PreviewUserWalletListComponent : UserWalletListComponent {
|
|||
),
|
||||
addNewWalletText = resourceReference(R.string.user_wallet_list_add_button),
|
||||
isWalletSavingInProgress = true,
|
||||
addNewWalletIconRes = R.drawable.ic_plus_24,
|
||||
onAddNewWalletClick = {},
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.details.entity
|
|||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.components.block.model.BlockUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@Immutable
|
||||
|
|
@ -27,4 +28,9 @@ internal sealed class DetailsItemUM {
|
|||
data object UserWalletList : DetailsItemUM() {
|
||||
override val id: String = "user_wallet_list"
|
||||
}
|
||||
|
||||
data class UnderSectionText(
|
||||
override val id: String,
|
||||
val text: TextReference,
|
||||
) : DetailsItemUM()
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.details.entity
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
|
@ -10,5 +11,6 @@ internal data class UserWalletListUM(
|
|||
val userWallets: ImmutableList<UserWalletItemUM>,
|
||||
val isWalletSavingInProgress: Boolean,
|
||||
val addNewWalletText: TextReference,
|
||||
@DrawableRes val addNewWalletIconRes: Int?,
|
||||
val onAddNewWalletClick: () -> Unit,
|
||||
)
|
||||
|
|
@ -97,6 +97,7 @@ internal class DetailsModel @Inject constructor(
|
|||
itemsBuilder.buildAll(
|
||||
isWalletConnectAvailable = isWalletConnectAvailable,
|
||||
isSupportChatAvailable = feedbackFeatureToggles.isUsedeskEnabled,
|
||||
hasAnyMobileWallet = getWalletsUseCase.invokeSync().any { it is UserWallet.Hot },
|
||||
userWalletId = params.userWalletId,
|
||||
onSupportEmailClick = ::sendFeedback,
|
||||
onSupportChatClick = ::openUseDesk,
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ internal class UserWalletListModel @Inject constructor(
|
|||
isWalletSavingInProgress = false,
|
||||
addNewWalletText = TextReference.EMPTY,
|
||||
onAddNewWalletClick = ::onAddNewWalletClick,
|
||||
addNewWalletIconRes = R.drawable.ic_plus_24,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -81,10 +82,11 @@ internal class UserWalletListModel @Inject constructor(
|
|||
value.copy(
|
||||
userWallets = userWallets,
|
||||
isWalletSavingInProgress = isWalletSavingInProgress,
|
||||
addNewWalletText = if (shouldSaveUserWallets || hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
resourceReference(R.string.user_wallet_list_add_button)
|
||||
} else {
|
||||
resourceReference(R.string.scan_card_settings_button)
|
||||
addNewWalletText = when {
|
||||
shouldSaveUserWallets || hotWalletFeatureToggles.isHotWalletEnabled -> {
|
||||
resourceReference(R.string.user_wallet_list_add_button)
|
||||
}
|
||||
else -> resourceReference(R.string.scan_card_settings_button)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -92,7 +94,14 @@ internal class UserWalletListModel @Inject constructor(
|
|||
private fun onAddNewWalletClick() {
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
analyticsEventHandler.send(SignIn.ButtonAddWallet(AnalyticsParam.ScreensSources.Settings))
|
||||
router.push(AppRoute.CreateWalletSelection)
|
||||
|
||||
if (hotWalletFeatureToggles.isWalletCreationRestrictionEnabled) {
|
||||
withProgress(isWalletSavingInProgress) {
|
||||
userWalletSaver.scanAndSaveUserWallet(modelScope)
|
||||
}
|
||||
} else {
|
||||
router.push(AppRoute.CreateWalletSelection)
|
||||
}
|
||||
} else {
|
||||
withProgress(isWalletSavingInProgress) {
|
||||
userWalletSaver.scanAndSaveUserWallet(modelScope)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import androidx.compose.foundation.background
|
|||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.scrollable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
|
|
@ -18,10 +19,14 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SpacerH16
|
||||
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
import com.tangem.core.ui.components.block.BlockItem
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
|
@ -68,7 +73,7 @@ private fun Content(
|
|||
) {
|
||||
LazyColumn(
|
||||
modifier = modifier.testTag(DetailsScreenTestTags.SCREEN_CONTAINER),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
|
||||
verticalArrangement = Arrangement.SpaceBetween,
|
||||
contentPadding = PaddingValues(
|
||||
top = TangemTheme.dimens.spacing12,
|
||||
bottom = TangemTheme.dimens.spacing16,
|
||||
|
|
@ -94,6 +99,7 @@ private fun Content(
|
|||
}
|
||||
|
||||
item(key = "footer") {
|
||||
SpacerH16()
|
||||
Footer(
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing12),
|
||||
model = state.footer,
|
||||
|
|
@ -108,6 +114,16 @@ private fun Block(
|
|||
userWalletListBlockContent: ComposableContentComponent,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
if (model is DetailsItemUM.UnderSectionText) {
|
||||
UnderSectionTextBlock(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = model.text,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
SpacerH16()
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
|
|
@ -142,10 +158,21 @@ private fun Block(
|
|||
is DetailsItemUM.UserWalletList -> {
|
||||
userWalletListBlockContent.Content(modifier = itemModifier)
|
||||
}
|
||||
is DetailsItemUM.UnderSectionText -> { /* Handled above */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UnderSectionTextBlock(text: TextReference, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
modifier = modifier.padding(horizontal = 30.dp, vertical = 8.dp),
|
||||
text = text.resolveReference(),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Footer(model: DetailsFooterUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.details.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
|
|
@ -23,7 +24,6 @@ import com.tangem.core.ui.res.TangemThemePreview
|
|||
import com.tangem.features.details.component.UserWalletListComponent
|
||||
import com.tangem.features.details.component.preview.PreviewUserWalletListComponent
|
||||
import com.tangem.features.details.entity.UserWalletListUM
|
||||
import com.tangem.features.details.impl.R
|
||||
|
||||
@Composable
|
||||
internal fun UserWalletListBlock(state: UserWalletListUM, modifier: Modifier = Modifier) {
|
||||
|
|
@ -42,6 +42,7 @@ internal fun UserWalletListBlock(state: UserWalletListUM, modifier: Modifier = M
|
|||
text = state.addNewWalletText,
|
||||
isInProgress = state.isWalletSavingInProgress,
|
||||
onClick = state.onAddNewWalletClick,
|
||||
icon = state.addNewWalletIconRes,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -49,6 +50,7 @@ internal fun UserWalletListBlock(state: UserWalletListUM, modifier: Modifier = M
|
|||
@Composable
|
||||
private fun AddWalletButton(
|
||||
text: TextReference,
|
||||
@DrawableRes icon: Int?,
|
||||
isInProgress: Boolean,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
@ -65,23 +67,25 @@ private fun AddWalletButton(
|
|||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||
) {
|
||||
AnimatedContent(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
targetState = isInProgress,
|
||||
label = "Add wallet progress",
|
||||
) { isInProgress ->
|
||||
if (isInProgress) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
color = TangemTheme.colors.icon.accent,
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
painter = painterResource(id = R.drawable.ic_plus_24),
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
contentDescription = null,
|
||||
)
|
||||
if (icon != null) {
|
||||
AnimatedContent(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
targetState = isInProgress,
|
||||
label = "Add wallet progress",
|
||||
) { isInProgress ->
|
||||
if (isInProgress) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
color = TangemTheme.colors.icon.accent,
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
painter = painterResource(id = icon),
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.details.entity.DetailsItemUM
|
||||
import com.tangem.features.details.impl.R
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
|
@ -17,12 +18,16 @@ import javax.inject.Inject
|
|||
private const val TANGEM_PAY_ITEM_ID = "get_tangem_pay"
|
||||
|
||||
@ModelScoped
|
||||
internal class ItemsBuilder @Inject constructor(private val router: Router) {
|
||||
internal class ItemsBuilder @Inject constructor(
|
||||
private val router: Router,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) {
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
fun buildAll(
|
||||
isWalletConnectAvailable: Boolean,
|
||||
isSupportChatAvailable: Boolean,
|
||||
hasAnyMobileWallet: Boolean,
|
||||
userWalletId: UserWalletId,
|
||||
onSupportEmailClick: () -> Unit,
|
||||
onSupportChatClick: () -> Unit,
|
||||
|
|
@ -30,6 +35,14 @@ internal class ItemsBuilder @Inject constructor(private val router: Router) {
|
|||
): ImmutableList<DetailsItemUM> = buildList {
|
||||
buildWalletConnectBlock(isWalletConnectAvailable, userWalletId)?.let(::add)
|
||||
buildUserWalletListBlock().let(::add)
|
||||
|
||||
if (hotWalletFeatureToggles.isWalletCreationRestrictionEnabled && hasAnyMobileWallet) {
|
||||
DetailsItemUM.UnderSectionText(
|
||||
id = "only_one_mobile_wallet_explanation",
|
||||
text = resourceReference(R.string.only_one_mobile_wallet_explanation),
|
||||
).let(::add)
|
||||
}
|
||||
|
||||
buildShopBlock(onBuyClick).let(::add)
|
||||
buildSettingsBlock().let(::add)
|
||||
buildSupportBlock(
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.common.routing)
|
||||
|
||||
/* Project - Domain */
|
||||
implementation(projects.domain.models)
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@ package com.tangem.features.hotwallet
|
|||
|
||||
interface HotWalletFeatureToggles {
|
||||
val isHotWalletEnabled: Boolean
|
||||
val isWalletCreationRestrictionEnabled: Boolean
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ interface WalletBackupComponent : ComposableContentComponent {
|
|||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val isColdWalletOptionShown: Boolean,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, WalletBackupComponent>
|
||||
|
|
|
|||
|
|
@ -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 = { },
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
|
|||
onNotificationsDescriptionClick = {},
|
||||
isNotificationsPermissionGranted = false,
|
||||
onAccessCodeClick = {},
|
||||
onUpgradeWalletClick = {},
|
||||
onBackupClick = {},
|
||||
onCardSettingsClick = {},
|
||||
accountsUM = previewAccounts(),
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ internal sealed class WalletSettingsItemUM {
|
|||
val text: TextReference,
|
||||
val isEnabled: Boolean,
|
||||
val imageState: ImageState,
|
||||
val additionalBlock: BlockUM? = null,
|
||||
val onClick: () -> Unit,
|
||||
) : WalletSettingsItemUM()
|
||||
|
||||
|
|
@ -46,13 +47,6 @@ internal sealed class WalletSettingsItemUM {
|
|||
val title: TextReference,
|
||||
val description: TextReference,
|
||||
) : WalletSettingsItemUM()
|
||||
|
||||
data class UpgradeWallet(
|
||||
override val id: String,
|
||||
val title: TextReference,
|
||||
val description: TextReference,
|
||||
val onClick: () -> Unit,
|
||||
) : WalletSettingsItemUM()
|
||||
}
|
||||
|
||||
@Immutable
|
||||
|
|
|
|||
|
|
@ -96,7 +96,10 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
val params: WalletSettingsComponent.Params = paramsContainer.require()
|
||||
val dialogNavigation = SlotNavigation<DialogConfig>()
|
||||
val bottomSheetNavigation: SlotNavigation<NetworksAvailableForNotificationBSConfig> = SlotNavigation()
|
||||
private val walletCardItemDelegate = walletCardItemDelegateFactory.create(dialogNavigation)
|
||||
private val walletCardItemDelegate = walletCardItemDelegateFactory.create(
|
||||
dialogNavigation = dialogNavigation,
|
||||
onUpgradeHotWalletClick = ::onUpgradeWalletClick,
|
||||
)
|
||||
|
||||
val state: MutableStateFlow<WalletSettingsUM> = MutableStateFlow(
|
||||
value = WalletSettingsUM(
|
||||
|
|
@ -249,7 +252,6 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
onCheckedNotificationsChanged = ::onCheckedNotificationsChange,
|
||||
onNotificationsDescriptionClick = ::onNotificationsDescriptionClick,
|
||||
onAccessCodeClick = { onAccessCodeClick(userWallet) },
|
||||
onUpgradeWalletClick = { onUpgradeWalletClick() },
|
||||
onBackupClick = ::onBackupClick,
|
||||
onCardSettingsClick = ::onCardSettingsClick,
|
||||
accountsUM = accountList,
|
||||
|
|
@ -374,10 +376,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
val isCodeSet = userWallet.hotWalletId.authType != HotWalletId.AuthType.NoPassword
|
||||
analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonAccessCode(isCodeSet))
|
||||
if (!state.value.isWalletBackedUp) {
|
||||
showMakeBackupAtFirstAlertBS(
|
||||
isUpgradeFlow = false,
|
||||
action = WalletSettingsAnalyticEvents.NoticeBackupFirst.Action.AccessCode,
|
||||
)
|
||||
showMakeBackupAtFirstAlertBS()
|
||||
} else {
|
||||
unlockWalletIfNeedAndProceed { authorizationRequired ->
|
||||
router.push(
|
||||
|
|
@ -392,35 +391,28 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun onUpgradeWalletClick() {
|
||||
if (!state.value.isWalletBackedUp) {
|
||||
showMakeBackupAtFirstAlertBS(
|
||||
isUpgradeFlow = true,
|
||||
action = WalletSettingsAnalyticEvents.NoticeBackupFirst.Action.Upgrade,
|
||||
)
|
||||
} else {
|
||||
unlockWalletIfNeedAndProceed {
|
||||
router.push(AppRoute.UpgradeWallet(userWalletId = params.userWalletId))
|
||||
}
|
||||
}
|
||||
router.push(AppRoute.WalletHardwareBackup(userWalletId = params.userWalletId))
|
||||
}
|
||||
|
||||
private fun onBackupClick() {
|
||||
analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonBackup())
|
||||
router.push(AppRoute.WalletBackup(params.userWalletId))
|
||||
router.push(
|
||||
AppRoute.WalletBackup(
|
||||
userWalletId = params.userWalletId,
|
||||
isColdWalletOptionShown = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun onCardSettingsClick() {
|
||||
router.push(AppRoute.CardSettings(params.userWalletId))
|
||||
}
|
||||
|
||||
private fun showMakeBackupAtFirstAlertBS(
|
||||
action: WalletSettingsAnalyticEvents.NoticeBackupFirst.Action,
|
||||
isUpgradeFlow: Boolean,
|
||||
) {
|
||||
private fun showMakeBackupAtFirstAlertBS() {
|
||||
analyticsEventHandler.send(
|
||||
event = WalletSettingsAnalyticEvents.NoticeBackupFirst(
|
||||
source = AnalyticsParam.ScreensSources.WalletSettings.value,
|
||||
action = action,
|
||||
action = WalletSettingsAnalyticEvents.NoticeBackupFirst.Action.AccessCode,
|
||||
),
|
||||
)
|
||||
val message = bottomSheetMessage {
|
||||
|
|
@ -438,14 +430,10 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
router.push(
|
||||
AppRoute.CreateWalletBackup(
|
||||
userWalletId = params.userWalletId,
|
||||
isUpgradeFlow = isUpgradeFlow,
|
||||
isUpgradeFlow = false,
|
||||
shouldSetAccessCode = true,
|
||||
analyticsSource = AnalyticsParam.ScreensSources.WalletSettings.value,
|
||||
analyticsAction = if (isUpgradeFlow) {
|
||||
RecoveryPhraseScreenAction.Upgrade.value
|
||||
} else {
|
||||
RecoveryPhraseScreenAction.AccessCode.value
|
||||
},
|
||||
analyticsAction = RecoveryPhraseScreenAction.AccessCode.value,
|
||||
),
|
||||
)
|
||||
closeBs()
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ import com.tangem.core.ui.components.notifications.Notification
|
|||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||
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.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
|
@ -153,10 +152,6 @@ private fun Content(state: WalletSettingsUM, modifier: Modifier = Modifier) {
|
|||
modifier = itemModifier,
|
||||
model = item,
|
||||
)
|
||||
is WalletSettingsItemUM.UpgradeWallet -> UpgradeWalletBlock(
|
||||
modifier = itemModifier,
|
||||
model = item,
|
||||
)
|
||||
is WalletSettingsAccountsUM.Header -> AccountsHeader(item, itemModifier)
|
||||
is WalletSettingsAccountsUM.Account -> AccountItem(
|
||||
model = item,
|
||||
|
|
@ -211,35 +206,54 @@ private fun CardBlock(model: WalletSettingsItemUM.CardBlock, modifier: Modifier
|
|||
enabled = model.isEnabled,
|
||||
onClick = model.onClick,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
CardImage(model.imageState)
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
text = model.title.resolveReference(),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.caption2,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Text(
|
||||
text = model.text.resolveReference(),
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
Column {
|
||||
Row(
|
||||
modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
CardImage(model.imageState)
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
text = model.title.resolveReference(),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.caption2,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Text(
|
||||
text = model.text.resolveReference(),
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
SecondarySmallButton(
|
||||
config = SmallButtonConfig(
|
||||
isEnabled = model.isEnabled,
|
||||
text = resourceReference(R.string.common_rename),
|
||||
onClick = model.onClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
SecondarySmallButton(
|
||||
config = SmallButtonConfig(
|
||||
isEnabled = model.isEnabled,
|
||||
text = resourceReference(R.string.common_rename),
|
||||
onClick = model.onClick,
|
||||
),
|
||||
)
|
||||
|
||||
if (model.additionalBlock != null) {
|
||||
Column {
|
||||
HorizontalDivider(
|
||||
thickness = TangemTheme.dimens.size0_5,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = TangemTheme.dimens.spacing12),
|
||||
color = TangemTheme.colors.stroke.primary,
|
||||
)
|
||||
|
||||
BlockItem(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
model = model.additionalBlock,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -272,21 +286,6 @@ private fun SwitchBlock(model: WalletSettingsItemUM.WithSwitch, modifier: Modifi
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UpgradeWalletBlock(model: WalletSettingsItemUM.UpgradeWallet, modifier: Modifier = Modifier) {
|
||||
Notification(
|
||||
config = NotificationConfig(
|
||||
title = model.title,
|
||||
subtitle = model.description,
|
||||
iconResId = R.drawable.ic_hardware_backup_36,
|
||||
iconSize = 36.dp,
|
||||
onClick = model.onClick,
|
||||
shouldShowArrowIcon = false,
|
||||
),
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NotificationAlertBlock(model: WalletSettingsItemUM.NotificationPermission, modifier: Modifier = Modifier) {
|
||||
Notification(
|
||||
|
|
@ -480,20 +479,4 @@ private fun Preview_WalletSettingsScreen() {
|
|||
PreviewWalletSettingsComponent().Content(modifier = Modifier.fillMaxSize())
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun Preview_WalletSettingsScreen1() {
|
||||
TangemThemePreview {
|
||||
UpgradeWalletBlock(
|
||||
model = WalletSettingsItemUM.UpgradeWallet(
|
||||
id = "upgrade_wallet",
|
||||
title = stringReference("Upgrade wallet with a hardware backup"),
|
||||
description = stringReference("Keep your crypto safe with Tangem’s best-in-class hardware wallet."),
|
||||
onClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
// endregion Preview
|
||||
|
|
@ -38,17 +38,10 @@ internal class ItemsBuilder @Inject constructor() {
|
|||
onReferralClick: () -> Unit,
|
||||
onManageTokensClick: () -> Unit,
|
||||
onAccessCodeClick: () -> Unit,
|
||||
onUpgradeWalletClick: () -> Unit,
|
||||
onBackupClick: () -> Unit,
|
||||
onCardSettingsClick: () -> Unit,
|
||||
): PersistentList<WalletSettingsItemUM> = persistentListOf<WalletSettingsItemUM>()
|
||||
.add(cardItem)
|
||||
.addAll(
|
||||
buildUpgradeWalletItem(
|
||||
userWallet = userWallet,
|
||||
onUpgradeWalletClick = onUpgradeWalletClick,
|
||||
),
|
||||
)
|
||||
.addAll(buildAccessCodeItem(userWallet, onAccessCodeClick))
|
||||
.addAll(accountsUM)
|
||||
.add(
|
||||
|
|
@ -116,21 +109,6 @@ internal class ItemsBuilder @Inject constructor() {
|
|||
onCheckedChange = onCheckedNFTChange,
|
||||
)
|
||||
|
||||
private fun buildUpgradeWalletItem(
|
||||
userWallet: UserWallet,
|
||||
onUpgradeWalletClick: () -> Unit,
|
||||
): List<WalletSettingsItemUM> = when (userWallet) {
|
||||
is UserWallet.Cold -> emptyList()
|
||||
is UserWallet.Hot -> listOf(
|
||||
WalletSettingsItemUM.UpgradeWallet(
|
||||
id = "upgrade_wallet",
|
||||
title = resourceReference(id = R.string.hw_upgrade_to_cold_banner_title),
|
||||
description = resourceReference(id = R.string.hw_upgrade_to_cold_banner_description),
|
||||
onClick = onUpgradeWalletClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun buildNotificationsPermissionItem() = WalletSettingsItemUM.NotificationPermission(
|
||||
id = "notifications_permission",
|
||||
title = resourceReference(id = R.string.transaction_notifications_warning_title),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.walletsettings.utils
|
|||
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.tangem.core.ui.components.block.model.BlockUM
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
|
@ -24,6 +25,7 @@ internal class WalletCardItemDelegate @AssistedInject constructor(
|
|||
private val getShouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase,
|
||||
private val walletImageFetcher: UserWalletImageFetcher,
|
||||
@Assisted private val dialogNavigation: SlotNavigation<DialogConfig>,
|
||||
@Assisted private val onUpgradeHotWalletClick: () -> Unit,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) {
|
||||
|
||||
|
|
@ -43,10 +45,20 @@ internal class WalletCardItemDelegate @AssistedInject constructor(
|
|||
isEnabled = isRenameAvailable,
|
||||
onClick = { openRenameWalletDialog(wallet) },
|
||||
imageState = imageState,
|
||||
additionalBlock = buildUpgradeToHardwareWalletBlockOrNull(wallet),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
private fun buildUpgradeToHardwareWalletBlockOrNull(wallet: UserWallet): BlockUM? {
|
||||
return BlockUM(
|
||||
text = resourceReference(R.string.upgrade_to_hardware_wallet_button_title),
|
||||
iconRes = null,
|
||||
onClick = onUpgradeHotWalletClick,
|
||||
accentType = BlockUM.AccentType.ACCENT,
|
||||
).takeIf { wallet is UserWallet.Hot }
|
||||
}
|
||||
|
||||
private fun openRenameWalletDialog(userWallet: UserWallet) {
|
||||
val config = DialogConfig.RenameWallet(
|
||||
userWalletId = userWallet.walletId,
|
||||
|
|
@ -57,6 +69,9 @@ internal class WalletCardItemDelegate @AssistedInject constructor(
|
|||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(dialogNavigation: SlotNavigation<DialogConfig>): WalletCardItemDelegate
|
||||
fun create(
|
||||
dialogNavigation: SlotNavigation<DialogConfig>,
|
||||
onUpgradeHotWalletClick: () -> Unit,
|
||||
): WalletCardItemDelegate
|
||||
}
|
||||
}
|
||||
|
|
@ -477,7 +477,16 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
override fun onFinishWalletActivationClick(isBackupExists: Boolean) {
|
||||
analyticsEventHandler.send(MainScreen.ButtonFinalizeActivation())
|
||||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
appRouter.push(WalletActivation(userWalletId, isBackupExists))
|
||||
val route = if (isBackupExists) {
|
||||
WalletActivation(userWalletId = userWalletId, isBackupExists = true)
|
||||
} else {
|
||||
WalletBackup(
|
||||
userWalletId = userWalletId,
|
||||
isColdWalletOptionShown = true,
|
||||
)
|
||||
}
|
||||
|
||||
appRouter.push(route)
|
||||
}
|
||||
|
||||
override fun onAllowPermissions() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.analytics.utils
|
||||
|
||||
import com.tangem.common.routing.AppRoute.WalletActivation
|
||||
import com.tangem.common.routing.AppRoute.WalletBackup
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
|
|
@ -93,7 +93,12 @@ internal class WalletWarningsSingleEventSender @Inject constructor(
|
|||
primaryButton {
|
||||
text = resourceReference(R.string.hw_activation_need_backup)
|
||||
onClick {
|
||||
router.push(WalletActivation(userWallet.walletId, userWallet.backedUp))
|
||||
router.push(
|
||||
WalletBackup(
|
||||
userWalletId = userWalletId,
|
||||
isColdWalletOptionShown = true,
|
||||
),
|
||||
)
|
||||
closeBs()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ android {
|
|||
dependencies {
|
||||
implementation(projects.features.welcome.api)
|
||||
implementation(projects.features.wallet.api)
|
||||
implementation(projects.features.hotWallet.api)
|
||||
|
||||
/** Core */
|
||||
implementation(projects.core.configToggles)
|
||||
|
|
|
|||
|
|
@ -12,14 +12,22 @@ import com.tangem.core.decompose.di.ModelScoped
|
|||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.common.wallets.error.SaveWalletError
|
||||
import com.tangem.domain.common.wallets.error.UnlockWalletError
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.isLocked
|
||||
import com.tangem.domain.settings.CanUseBiometryUseCase
|
||||
import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.domain.wallets.usecase.NonBiometricUnlockWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.features.wallet.utils.UserWalletsFetcher
|
||||
import com.tangem.features.welcome.impl.ui.state.WelcomeUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -40,10 +48,15 @@ internal class WelcomeModel @Inject constructor(
|
|||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val nonBiometricUnlockWalletUseCase: NonBiometricUnlockWalletUseCase,
|
||||
private val canUseBiometryUseCase: CanUseBiometryUseCase,
|
||||
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory,
|
||||
private val saveWalletUseCase: SaveWalletUseCase,
|
||||
private val walletsRepository: WalletsRepository,
|
||||
private val trackingContextProxy: TrackingContextProxy,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
userWalletsFetcherFactory: UserWalletsFetcher.Factory,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val scanCardProcessor: ScanCardProcessor,
|
||||
private val messageSender: UiMessageSender,
|
||||
) : Model() {
|
||||
|
||||
val uiState: StateFlow<WelcomeUM>
|
||||
|
|
@ -168,7 +181,50 @@ internal class WelcomeModel @Inject constructor(
|
|||
|
||||
private fun addWalletClick() {
|
||||
analyticsEventHandler.send(SignIn.ButtonAddWallet(AnalyticsParam.ScreensSources.SignIn))
|
||||
router.push(AppRoute.CreateWalletSelection)
|
||||
if (hotWalletFeatureToggles.isWalletCreationRestrictionEnabled) {
|
||||
scanCard()
|
||||
} else {
|
||||
router.push(AppRoute.CreateWalletSelection)
|
||||
}
|
||||
}
|
||||
|
||||
private fun scanCard() {
|
||||
modelScope.launch {
|
||||
scanCardProcessor.scan(
|
||||
analyticsSource = AnalyticsParam.ScreensSources.SignIn,
|
||||
onWalletNotCreated = {},
|
||||
disclaimerWillShow = { router.pop() },
|
||||
onSuccess = { scanResponse ->
|
||||
val userWallet =
|
||||
coldUserWalletBuilderFactory.create(scanResponse = scanResponse).build() ?: return@scan
|
||||
saveWalletUseCase.invoke(userWallet)
|
||||
.onLeft { error ->
|
||||
if (error is SaveWalletError.WalletAlreadySaved) {
|
||||
userWalletsListRepository.unlock(
|
||||
userWallet.walletId,
|
||||
unlockMethod = UserWalletsListRepository.UnlockMethod.Scan(scanResponse),
|
||||
).onRight {
|
||||
userWalletsListRepository.select(userWallet.walletId)
|
||||
router.replaceAll(AppRoute.Wallet)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onRight {
|
||||
router.replaceAll(AppRoute.Wallet)
|
||||
}
|
||||
},
|
||||
onCancel = {},
|
||||
onFailure = { tangemError ->
|
||||
if (!tangemError.silent) {
|
||||
val message = tangemError.messageResId
|
||||
?.let(::resourceReference)
|
||||
?: stringReference(tangemError.customMessage)
|
||||
|
||||
messageSender.send(SnackbarMessage(message))
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onlyOneHotWalletWithAccessCode(): Boolean {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue