Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-22 18:24:36 +05:00
parent 68d3a813e2
commit f5d9dab282
17 changed files with 439 additions and 61 deletions

View file

@ -8,6 +8,7 @@ import com.tangem.feature.referral.api.ReferralComponent
import com.tangem.feature.stories.api.StoriesComponent
import com.tangem.feature.usedesk.api.UsedeskComponent
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
import com.tangem.features.hotwallet.WalletBackupComponent
import com.tangem.features.createwalletselection.CreateWalletSelectionComponent
import com.tangem.features.details.component.DetailsComponent
import com.tangem.features.disclaimer.api.components.DisclaimerComponent
@ -51,6 +52,7 @@ import com.tangem.features.walletconnect.components.WalletConnectEntryComponent
internal class ChildFactory @Inject constructor(
private val detailsComponentFactory: DetailsComponent.Factory,
private val walletSettingsComponentFactory: WalletSettingsComponent.Factory,
private val walletBackupComponentFactory: WalletBackupComponent.Factory,
private val disclaimerComponentFactory: DisclaimerComponent.Factory,
private val manageTokensComponentFactory: ManageTokensComponent.Factory,
private val marketsTokenDetailsComponentFactory: MarketsTokenDetailsComponent.Factory,
@ -141,6 +143,15 @@ internal class ChildFactory @Inject constructor(
componentFactory = walletSettingsComponentFactory,
)
}
is AppRoute.WalletBackup -> {
createComponentChild(
context = context,
params = WalletBackupComponent.Params(
userWalletId = route.userWalletId,
),
componentFactory = walletBackupComponentFactory,
)
}
is AppRoute.MarketsTokenDetails -> {
createComponentChild(
context = context,

View file

@ -191,6 +191,11 @@ sealed class AppRoute(val path: String) : Route {
val userWalletId: UserWalletId,
) : AppRoute(path = "/wallet_settings/${userWalletId.stringValue}")
@Serializable
data class WalletBackup(
val userWalletId: UserWalletId,
) : AppRoute(path = "/wallet_backup/${userWalletId.stringValue}")
@Serializable
data object Markets : AppRoute(path = "/markets")

View file

@ -425,8 +425,8 @@
<string name="hw_activation_need_description">To complete setup, back up your wallet and secure app access with a Access Code.</string>
<string name="hw_activation_need_finish">Finish Now</string>
<string name="hw_activation_need_title">Finish Wallet Activation</string>
<string name="hw_backup_icloud_description">Recover an existing wallet stored in your iCloud backup</string>
<string name="hw_backup_icloud_title">iCloud backup</string>
<string name="hw_backup_google_drive_description">Recover an existing wallet stored in your Google Drive backup</string>
<string name="hw_backup_google_drive_title">Google Drive Backup</string>
<string name="hw_backup_need_action">Go to backup</string>
<string name="hw_backup_need_description">To secure your wallet with a Access Code, complete the backup first.</string>
<string name="hw_backup_need_title">Finish Backup First</string>

View file

@ -155,7 +155,7 @@ private fun WalletBlock(
Row {
Text(
modifier = Modifier
.weight(1f)
.weight(1f, fill = false)
.padding(end = 8.dp),
text = title,
style = TangemTheme.typography.subtitle1,

View file

@ -12,6 +12,7 @@ dependencies {
/* Project - Domain */
implementation(projects.domain.models)
implementation(projects.domain.wallets.models)
/* Project - Core */
implementation(projects.core.decompose)

View file

@ -0,0 +1,14 @@
package com.tangem.features.hotwallet
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.wallets.models.UserWalletId
interface WalletBackupComponent : ComposableContentComponent {
data class Params(
val userWalletId: UserWalletId,
)
interface Factory : ComponentFactory<Params, WalletBackupComponent>
}

View file

@ -3,27 +3,27 @@ package com.tangem.features.hotwallet.addexistingwallet.start.ui
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.material3.ExperimentalMaterial3Api
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.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.appbar.TangemTopAppBar
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
import com.tangem.core.ui.components.buttons.common.TangemButtonSize
import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
import com.tangem.core.ui.extensions.clickableSingle
import com.tangem.core.ui.extensions.conditional
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.hotwallet.addexistingwallet.start.entity.AddExistingWalletStartUM
import com.tangem.core.ui.R
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.features.hotwallet.common.ui.OptionBlock
@Suppress("LongMethod")
@OptIn(ExperimentalMaterial3Api::class)
@ -62,6 +62,7 @@ internal fun AddExistingWalletStartContent(state: AddExistingWalletStartUM, modi
OptionBlock(
modifier = Modifier
.padding(top = 24.dp),
backgroundColor = TangemTheme.colors.background.secondary,
title = stringResourceSafe(R.string.wallet_import_seed_title),
description = stringResourceSafe(R.string.wallet_import_seed_description),
badge = null,
@ -69,6 +70,7 @@ internal fun AddExistingWalletStartContent(state: AddExistingWalletStartUM, modi
enabled = true,
)
OptionBlock(
backgroundColor = TangemTheme.colors.background.secondary,
title = stringResourceSafe(R.string.wallet_import_scan_title),
description = stringResourceSafe(R.string.wallet_import_scan_description),
badge = {
@ -85,6 +87,7 @@ internal fun AddExistingWalletStartContent(state: AddExistingWalletStartUM, modi
enabled = true,
)
OptionBlock(
backgroundColor = TangemTheme.colors.background.secondary,
title = stringResourceSafe(R.string.wallet_import_google_drive_title),
description = stringResourceSafe(R.string.wallet_import_google_drive_description),
badge = {
@ -114,58 +117,6 @@ internal fun AddExistingWalletStartContent(state: AddExistingWalletStartUM, modi
}
}
@Composable
private fun OptionBlock(
title: String,
description: String,
badge: (@Composable () -> Unit)?,
onClick: (() -> Unit)?,
enabled: Boolean,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier
.fillMaxWidth()
.padding(top = 8.dp)
.clip(TangemTheme.shapes.roundedCornersXMedium)
.background(
color = TangemTheme.colors.background.secondary,
shape = TangemTheme.shapes.roundedCornersXMedium,
)
.conditional(onClick != null) {
onClick?.let { clickableSingle(onClick = it) } ?: Modifier
}
.padding(16.dp),
) {
Row {
Text(
modifier = Modifier
.weight(1f, fill = false)
.padding(end = 4.dp),
text = title,
style = TangemTheme.typography.subtitle1,
color = if (enabled) {
TangemTheme.colors.text.primary1
} else {
TangemTheme.colors.text.secondary
},
)
badge?.invoke()
}
Text(
modifier = Modifier
.padding(top = 4.dp),
text = description,
style = TangemTheme.typography.body2,
color = if (enabled) {
TangemTheme.colors.text.tertiary
} else {
TangemTheme.colors.text.disabled
},
)
}
}
@Composable
private fun BuyTangemWalletBlock(onScanClick: () -> Unit, modifier: Modifier = Modifier) {
Row(

View file

@ -0,0 +1,88 @@
package com.tangem.features.hotwallet.common.ui
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.extensions.clickableSingle
import com.tangem.core.ui.extensions.conditional
import com.tangem.core.ui.res.TangemTheme
internal const val DISABLED_COLORS_ALPHA = 0.5f
@Suppress("LongParameterList")
@Composable
internal fun OptionBlock(
title: String,
description: String,
badge: (@Composable () -> Unit)?,
onClick: (() -> Unit)?,
enabled: Boolean,
backgroundColor: Color,
modifier: Modifier = Modifier,
) {
val backgroundColor by animateColorAsState(
targetValue = if (enabled) {
backgroundColor
} else {
backgroundColor.copy(alpha = DISABLED_COLORS_ALPHA)
},
)
val titleColor by animateColorAsState(
targetValue = if (enabled) {
TangemTheme.colors.text.primary1
} else {
TangemTheme.colors.text.primary1.copy(alpha = DISABLED_COLORS_ALPHA)
},
)
val descriptionColor by animateColorAsState(
targetValue = if (enabled) {
TangemTheme.colors.text.tertiary
} else {
TangemTheme.colors.text.tertiary.copy(alpha = DISABLED_COLORS_ALPHA)
},
)
Column(
modifier = modifier
.fillMaxWidth()
.padding(top = 8.dp)
.clip(TangemTheme.shapes.roundedCornersXMedium)
.background(
color = backgroundColor,
shape = TangemTheme.shapes.roundedCornersXMedium,
)
.conditional(onClick != null) {
onClick?.let { clickableSingle(onClick = it) } ?: Modifier
}
.padding(16.dp),
) {
Row {
Text(
modifier = Modifier
.weight(1f, fill = false)
.padding(end = 4.dp),
text = title,
style = TangemTheme.typography.subtitle1,
color = titleColor,
)
badge?.invoke()
}
Text(
modifier = Modifier
.padding(top = 4.dp),
text = description,
style = TangemTheme.typography.body2,
color = descriptionColor,
)
}
}

View file

@ -0,0 +1,39 @@
package com.tangem.features.hotwallet.walletbackup.component
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.features.hotwallet.WalletBackupComponent
import com.tangem.features.hotwallet.walletbackup.model.WalletBackupModel
import com.tangem.features.hotwallet.walletbackup.ui.WalletBackupContent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
internal class DefaultWalletBackupComponent @AssistedInject constructor(
@Assisted private val context: AppComponentContext,
@Assisted private val params: WalletBackupComponent.Params,
) : WalletBackupComponent, AppComponentContext by context {
private val model: WalletBackupModel = getOrCreateModel(params)
@Composable
override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle()
WalletBackupContent(
state = state,
modifier = modifier,
)
}
@AssistedFactory
interface Factory : WalletBackupComponent.Factory {
override fun create(
context: AppComponentContext,
params: WalletBackupComponent.Params,
): DefaultWalletBackupComponent
}
}

View file

@ -0,0 +1,27 @@
package com.tangem.features.hotwallet.walletbackup.di
import com.tangem.core.decompose.model.Model
import com.tangem.features.hotwallet.WalletBackupComponent
import com.tangem.features.hotwallet.walletbackup.component.DefaultWalletBackupComponent
import com.tangem.features.hotwallet.walletbackup.model.WalletBackupModel
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal interface WalletBackupModule {
@Binds
@IntoMap
@ClassKey(WalletBackupModel::class)
fun bindWalletBackupModel(model: WalletBackupModel): Model
@Binds
@Singleton
fun bindWalletBackupComponentFactory(factory: DefaultWalletBackupComponent.Factory): WalletBackupComponent.Factory
}

View file

@ -0,0 +1,15 @@
package com.tangem.features.hotwallet.walletbackup.entity
internal data class WalletBackupUM(
val onBackClick: () -> Unit,
val recoveryPhraseStatus: BackupStatus,
val googleDriveStatus: BackupStatus,
val onRecoveryPhraseClick: () -> Unit,
val onGoogleDriveClick: () -> Unit,
)
internal sealed class BackupStatus {
object Done : BackupStatus()
object ComingSoon : BackupStatus()
object NoBackup : BackupStatus()
}

View file

@ -0,0 +1,54 @@
package com.tangem.features.hotwallet.walletbackup.model
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.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.features.hotwallet.WalletBackupComponent
import com.tangem.features.hotwallet.walletbackup.entity.BackupStatus
import com.tangem.features.hotwallet.walletbackup.entity.WalletBackupUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.*
import javax.inject.Inject
@ModelScoped
internal class WalletBackupModel @Inject constructor(
paramsContainer: ParamsContainer,
getWalletUseCase: GetUserWalletUseCase,
private val router: Router,
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
private val params: WalletBackupComponent.Params = paramsContainer.require()
val uiState: StateFlow<WalletBackupUM>
field = MutableStateFlow(
WalletBackupUM(
onBackClick = { router.pop() },
recoveryPhraseStatus = BackupStatus.NoBackup,
googleDriveStatus = BackupStatus.ComingSoon,
onRecoveryPhraseClick = { },
onGoogleDriveClick = { },
),
)
init {
getWalletUseCase.invokeFlow(params.userWalletId)
.map { it.getOrNull() }
.distinctUntilChanged()
.onEach {
updateBackupStatuses()
}
.launchIn(modelScope)
}
private fun updateBackupStatuses() {
uiState.update { currentState ->
currentState.copy(
recoveryPhraseStatus = BackupStatus.NoBackup,
googleDriveStatus = BackupStatus.ComingSoon,
)
}
}
}

View file

@ -0,0 +1,155 @@
package com.tangem.features.hotwallet.walletbackup.ui
import android.content.res.Configuration
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
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.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.hotwallet.walletbackup.entity.BackupStatus
import com.tangem.features.hotwallet.walletbackup.entity.WalletBackupUM
import com.tangem.features.hotwallet.common.ui.OptionBlock
import com.tangem.core.ui.R
import com.tangem.features.hotwallet.common.ui.DISABLED_COLORS_ALPHA
@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun WalletBackupContent(state: WalletBackupUM, modifier: Modifier = Modifier) {
Column(
modifier = modifier
.background(TangemTheme.colors.background.secondary)
.fillMaxSize()
.systemBarsPadding(),
) {
AppBarWithBackButton(
text = stringResourceSafe(R.string.common_backup),
onBackClick = state.onBackClick,
)
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp),
) {
OptionBlock(
modifier = Modifier.fillMaxWidth(),
title = stringResourceSafe(R.string.hw_backup_seed_title),
description = stringResourceSafe(R.string.hw_backup_seed_description),
badge = {
BackupStatusBadge(status = state.recoveryPhraseStatus)
},
onClick = state.onRecoveryPhraseClick,
enabled = true,
backgroundColor = TangemTheme.colors.background.primary,
)
OptionBlock(
modifier = Modifier.fillMaxWidth(),
title = stringResourceSafe(R.string.hw_backup_google_drive_title),
description = stringResourceSafe(R.string.hw_backup_google_drive_description),
badge = {
BackupStatusBadge(status = state.googleDriveStatus)
},
onClick = state.onGoogleDriveClick,
enabled = state.googleDriveStatus != BackupStatus.ComingSoon,
backgroundColor = TangemTheme.colors.background.primary,
)
}
}
}
@Composable
private fun BackupStatusBadge(status: BackupStatus, modifier: Modifier = Modifier) {
val text = when (status) {
BackupStatus.Done -> stringResourceSafe(R.string.common_done)
BackupStatus.ComingSoon -> stringResourceSafe(R.string.common_coming_soon)
BackupStatus.NoBackup -> stringResourceSafe(R.string.hw_backup_no_backup)
}
val backgroundColor by animateColorAsState(
targetValue = when (status) {
BackupStatus.Done -> TangemTheme.colors.text.accent.copy(alpha = 0.1f)
BackupStatus.ComingSoon -> TangemTheme.colors.control.unchecked.copy(DISABLED_COLORS_ALPHA)
BackupStatus.NoBackup -> TangemTheme.colors.text.warning.copy(alpha = 0.1f)
},
)
val textColor by animateColorAsState(
targetValue = when (status) {
BackupStatus.Done -> TangemTheme.colors.text.accent
BackupStatus.ComingSoon -> TangemTheme.colors.text.secondary.copy(DISABLED_COLORS_ALPHA)
BackupStatus.NoBackup -> TangemTheme.colors.text.warning
},
)
AnimatedContent(targetState = text) { text ->
Box(
modifier = modifier
.padding(horizontal = 4.dp)
.background(
color = backgroundColor,
shape = TangemTheme.shapes.roundedCorners8,
)
.padding(horizontal = 8.dp, vertical = 4.dp),
) {
Text(
text = text,
style = TangemTheme.typography.caption1,
color = textColor,
)
}
}
}
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun WalletBackupContentPreview(@PreviewParameter(WalletBackupUMProvider::class) state: WalletBackupUM) {
TangemThemePreview {
WalletBackupContent(state)
}
}
private class WalletBackupUMProvider : CollectionPreviewParameterProvider<WalletBackupUM>(
collection = listOf(
WalletBackupUM(
recoveryPhraseStatus = BackupStatus.NoBackup,
googleDriveStatus = BackupStatus.ComingSoon,
onBackClick = {},
onRecoveryPhraseClick = {},
onGoogleDriveClick = {},
),
WalletBackupUM(
recoveryPhraseStatus = BackupStatus.NoBackup,
googleDriveStatus = BackupStatus.NoBackup,
onBackClick = {},
onRecoveryPhraseClick = {},
onGoogleDriveClick = {},
),
WalletBackupUM(
recoveryPhraseStatus = BackupStatus.Done,
googleDriveStatus = BackupStatus.Done,
onBackClick = {},
onRecoveryPhraseClick = {},
onGoogleDriveClick = {},
),
),
)

View file

@ -19,6 +19,7 @@ dependencies {
implementation(projects.features.nft.api)
implementation(projects.features.onboardingV2.api)
implementation(projects.features.pushNotifications.api)
implementation(projects.features.hotWallet.api)
/* Project - Core */
implementation(projects.core.decompose)

View file

@ -36,6 +36,7 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
onCheckedNotificationsChanged = {},
onNotificationsDescriptionClick = {},
isNotificationsPermissionGranted = false,
isHotWalletEnabled = false,
),
requestPushNotificationsPermission = false,
onPushNotificationPermissionGranted = {},

View file

@ -41,6 +41,7 @@ import com.tangem.feature.walletsettings.entity.WalletSettingsItemUM
import com.tangem.feature.walletsettings.entity.WalletSettingsUM
import com.tangem.feature.walletsettings.impl.R
import com.tangem.feature.walletsettings.utils.ItemsBuilder
import com.tangem.features.hotwallet.HotWalletFeatureToggles
import com.tangem.features.pushnotifications.api.analytics.PushNotificationAnalyticEvents
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.collections.immutable.PersistentList
@ -72,6 +73,7 @@ internal class WalletSettingsModel @Inject constructor(
private val setNotificationsEnabledUseCase: SetNotificationsEnabledUseCase,
private val settingsManager: SettingsManager,
private val permissionsRepository: PermissionRepository,
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
) : Model() {
val params: WalletSettingsComponent.Params = paramsContainer.require()
@ -105,6 +107,7 @@ internal class WalletSettingsModel @Inject constructor(
isNotificationsEnabled = notificationsEnabled,
isNotificationsFeatureEnabled = notificationsToggles.isNotificationsEnabled,
isNotificationsPermissionGranted = isNotificationsPermissionGranted(),
isHotWalletEnabled = hotWalletFeatureToggles.isHotWalletEnabled,
),
)
}
@ -130,6 +133,7 @@ internal class WalletSettingsModel @Inject constructor(
isNotificationsFeatureEnabled: Boolean,
isNotificationsEnabled: Boolean,
isNotificationsPermissionGranted: Boolean,
isHotWalletEnabled: Boolean,
): PersistentList<WalletSettingsItemUM> = itemsBuilder.buildItems(
userWalletId = userWallet.walletId,
userWalletName = userWallet.name,
@ -167,6 +171,7 @@ internal class WalletSettingsModel @Inject constructor(
isNotificationsPermissionGranted = isNotificationsPermissionGranted,
onCheckedNotificationsChanged = ::onCheckedNotificationsChange,
onNotificationsDescriptionClick = ::onNotificationsDescriptionClick,
isHotWalletEnabled = isHotWalletEnabled,
)
private fun openRenameWalletDialog(userWallet: UserWallet, dialogNavigation: SlotNavigation<DialogConfig>) {

View file

@ -43,6 +43,7 @@ internal class ItemsBuilder @Inject constructor(
renameWallet: () -> Unit,
onLinkMoreCardsClick: () -> Unit,
onReferralClick: () -> Unit,
isHotWalletEnabled: Boolean,
): PersistentList<WalletSettingsItemUM> = persistentListOf<WalletSettingsItemUM>()
.add(buildNameItem(userWalletName, isRenameWalletAvailable, renameWallet))
.run {
@ -60,6 +61,7 @@ internal class ItemsBuilder @Inject constructor(
isManageTokensAvailable = isManageTokensAvailable,
onLinkMoreCardsClick = onLinkMoreCardsClick,
onReferralClick = onReferralClick,
isHotWalletEnabled = isHotWalletEnabled,
),
)
.addAll(
@ -137,6 +139,7 @@ internal class ItemsBuilder @Inject constructor(
isManageTokensAvailable: Boolean,
onLinkMoreCardsClick: () -> Unit,
onReferralClick: () -> Unit,
isHotWalletEnabled: Boolean,
) = WalletSettingsItemUM.WithItems(
id = "card",
description = resourceReference(R.string.settings_card_settings_footer),
@ -166,6 +169,14 @@ internal class ItemsBuilder @Inject constructor(
onClick = { router.push(AppRoute.CardSettings(userWalletId)) },
).let(::add)
if (isHotWalletEnabled) {
BlockUM(
text = resourceReference(R.string.common_backup),
iconRes = R.drawable.ic_more_cards_24,
onClick = { router.push(AppRoute.WalletBackup(userWalletId)) },
).let(::add)
}
if (isReferralAvailable) {
BlockUM(
text = resourceReference(R.string.details_referral_title),