Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-07 20:04:35 +05:00
parent 1d47d83d70
commit 6178034e71
20 changed files with 401 additions and 160 deletions

View file

@ -13,9 +13,9 @@ internal data class AddExistingWalletImportUM(
val onPassphraseInfoClick: () -> Unit,
val wordsErrorText: TextReference?,
val invalidWords: ImmutableList<String>,
val createWalletEnabled: Boolean,
val createWalletProgress: Boolean,
val createWalletClick: () -> Unit,
val importWalletEnabled: Boolean,
val importWalletProgress: Boolean,
val importWalletClick: () -> Unit,
val suggestionsList: ImmutableList<String>,
val onSuggestionClick: (String) -> Unit,
val infoBottomSheetConfig: TangemBottomSheetConfig,

View file

@ -55,7 +55,7 @@ internal class AddExistingWalletImportModel @Inject constructor(
private fun importWallet(mnemonic: Mnemonic, passphrase: String?) {
modelScope.launch {
uiState.update {
it.copy(createWalletProgress = true)
it.copy(importWalletProgress = true)
}
runCatching {
@ -68,7 +68,7 @@ internal class AddExistingWalletImportModel @Inject constructor(
Timber.e(it)
uiState.update {
it.copy(createWalletProgress = false)
it.copy(importWalletProgress = false)
}
}
}

View file

@ -35,8 +35,8 @@ internal class ImportSeedPhraseUiStateBuilder(
passPhrase = TextFieldValue(""),
wordsErrorText = null,
invalidWords = persistentListOf(),
createWalletEnabled = false,
createWalletProgress = false,
importWalletEnabled = false,
importWalletProgress = false,
suggestionsList = persistentListOf(),
wordsChange = {
launchInterceptWords(wordsField = it)
@ -50,7 +50,7 @@ internal class ImportSeedPhraseUiStateBuilder(
updateUiState { state -> state.copy(passPhrase = it) }
},
onPassphraseInfoClick = ::showInfoBS,
createWalletClick = ::onCreateWallet,
importWalletClick = ::onCreateWallet,
onSuggestionClick = { word -> addSuggestedWord(word) },
readyToImport = false,
infoBottomSheetConfig = TangemBottomSheetConfig.Empty,
@ -115,7 +115,7 @@ internal class ImportSeedPhraseUiStateBuilder(
updateUiState {
it.copy(
createWalletEnabled = false,
importWalletEnabled = false,
wordsErrorText = null,
)
}
@ -130,7 +130,7 @@ internal class ImportSeedPhraseUiStateBuilder(
it.copy(
invalidWords = invalidWords.toImmutableList(),
wordsErrorText = resourceReference(R.string.onboarding_seed_mnemonic_wrong_words),
createWalletEnabled = false,
importWalletEnabled = false,
)
}
return
@ -143,7 +143,7 @@ internal class ImportSeedPhraseUiStateBuilder(
it.copy(
invalidWords = emptyList<String>().toImmutableList(),
wordsErrorText = null,
createWalletEnabled = true,
importWalletEnabled = true,
)
}
readyToImport(true)
@ -154,13 +154,13 @@ internal class ImportSeedPhraseUiStateBuilder(
updateUiState {
it.copy(
wordsErrorText = resourceReference(R.string.onboarding_seed_mnemonic_invalid_checksum),
createWalletEnabled = false,
importWalletEnabled = false,
)
}
} else {
updateUiState {
it.copy(
createWalletEnabled = false,
importWalletEnabled = false,
wordsErrorText = null,
)
}

View file

@ -96,9 +96,9 @@ internal fun AddExistingWalletImportContent(state: AddExistingWalletImportUM, mo
.padding(16.dp)
.fillMaxWidth(),
text = stringResourceSafe(id = R.string.common_import),
enabled = state.createWalletEnabled,
showProgress = state.createWalletProgress,
onClick = state.createWalletClick,
enabled = state.importWalletEnabled,
showProgress = state.importWalletProgress,
onClick = state.importWalletClick,
)
}
@ -228,9 +228,9 @@ private fun PreviewAddExistingWalletImportContent() {
onPassphraseInfoClick = {},
wordsErrorText = null,
invalidWords = persistentListOf(),
createWalletEnabled = false,
createWalletProgress = false,
createWalletClick = {},
importWalletEnabled = false,
importWalletProgress = false,
importWalletClick = {},
suggestionsList = persistentListOf(),
onSuggestionClick = {},
infoBottomSheetConfig = TangemBottomSheetConfig.Empty,

View file

@ -17,7 +17,7 @@ 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
private const val DISABLED_COLORS_ALPHA = 0.5f
@Suppress("LongParameterList")
@Composable

View file

@ -111,6 +111,9 @@ internal class ManualBackupCheckModel @Inject constructor(
}
callbacks.onCompleteClick()
}
uiState.update {
it.copy(completeButtonProgress = false)
}
}.onFailure {
Timber.e(it)

View file

@ -1,9 +1,11 @@
package com.tangem.features.hotwallet.walletbackup.entity
import com.tangem.core.ui.components.label.entity.LabelUM
internal data class WalletBackupUM(
val onBackClick: () -> Unit,
val recoveryPhraseStatus: BackupStatus,
val googleDriveStatus: BackupStatus,
val recoveryPhraseStatus: LabelUM?,
val googleDriveStatus: LabelUM?,
val onRecoveryPhraseClick: () -> Unit,
val onGoogleDriveClick: () -> Unit,
)

View file

@ -4,9 +4,13 @@ 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.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.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.*
@ -26,8 +30,14 @@ internal class WalletBackupModel @Inject constructor(
field = MutableStateFlow(
WalletBackupUM(
onBackClick = { router.pop() },
recoveryPhraseStatus = BackupStatus.NoBackup,
googleDriveStatus = BackupStatus.ComingSoon,
recoveryPhraseStatus = LabelUM(
text = resourceReference(R.string.hw_backup_no_backup),
style = LabelStyle.WARNING,
),
googleDriveStatus = LabelUM(
text = resourceReference(R.string.common_coming_soon),
style = LabelStyle.REGULAR,
),
onRecoveryPhraseClick = { },
onGoogleDriveClick = { },
),
@ -37,18 +47,38 @@ internal class WalletBackupModel @Inject constructor(
getWalletUseCase.invokeFlow(params.userWalletId)
.map { it.getOrNull() }
.distinctUntilChanged()
.filterNotNull()
.onEach {
updateBackupStatuses()
updateBackupStatuses(it)
}
.launchIn(modelScope)
}
private fun updateBackupStatuses() {
private fun updateBackupStatuses(userWallet: UserWallet) {
uiState.update { currentState ->
currentState.copy(
recoveryPhraseStatus = BackupStatus.NoBackup,
googleDriveStatus = BackupStatus.ComingSoon,
)
if (userWallet is UserWallet.Hot) {
currentState.updateBackupStatusesHotWallet(userWallet)
} else {
currentState
}
}
}
private fun WalletBackupUM.updateBackupStatusesHotWallet(userWallet: UserWallet.Hot): WalletBackupUM = copy(
recoveryPhraseStatus = if (userWallet.backedUp) {
LabelUM(
text = resourceReference(R.string.common_done),
style = LabelStyle.ACCENT,
)
} else {
LabelUM(
text = resourceReference(R.string.hw_backup_no_backup),
style = LabelStyle.WARNING,
)
},
googleDriveStatus = LabelUM(
text = resourceReference(R.string.common_coming_soon),
style = LabelStyle.REGULAR,
),
)
}

View file

@ -1,20 +1,14 @@
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
@ -28,7 +22,10 @@ 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
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.resourceReference
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -54,7 +51,7 @@ internal fun WalletBackupContent(state: WalletBackupUM, modifier: Modifier = Mod
title = stringResourceSafe(R.string.hw_backup_seed_title),
description = stringResourceSafe(R.string.hw_backup_seed_description),
badge = {
BackupStatusBadge(status = state.recoveryPhraseStatus)
state.recoveryPhraseStatus?.let { Label(it) }
},
onClick = state.onRecoveryPhraseClick,
enabled = true,
@ -66,7 +63,7 @@ internal fun WalletBackupContent(state: WalletBackupUM, modifier: Modifier = Mod
title = stringResourceSafe(R.string.hw_backup_google_drive_title),
description = stringResourceSafe(R.string.hw_backup_google_drive_description),
badge = {
BackupStatusBadge(status = state.googleDriveStatus)
state.googleDriveStatus?.let { Label(it) }
},
onClick = state.onGoogleDriveClick,
enabled = state.googleDriveStatus != BackupStatus.ComingSoon,
@ -76,49 +73,6 @@ internal fun WalletBackupContent(state: WalletBackupUM, modifier: Modifier = Mod
}
}
@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
@ -131,22 +85,40 @@ private fun WalletBackupContentPreview(@PreviewParameter(WalletBackupUMProvider:
private class WalletBackupUMProvider : CollectionPreviewParameterProvider<WalletBackupUM>(
collection = listOf(
WalletBackupUM(
recoveryPhraseStatus = BackupStatus.NoBackup,
googleDriveStatus = BackupStatus.ComingSoon,
recoveryPhraseStatus = LabelUM(
text = resourceReference(R.string.hw_backup_no_backup),
style = LabelStyle.WARNING,
),
googleDriveStatus = LabelUM(
text = resourceReference(R.string.common_coming_soon),
style = LabelStyle.REGULAR,
),
onBackClick = {},
onRecoveryPhraseClick = {},
onGoogleDriveClick = {},
),
WalletBackupUM(
recoveryPhraseStatus = BackupStatus.NoBackup,
googleDriveStatus = BackupStatus.NoBackup,
recoveryPhraseStatus = LabelUM(
text = resourceReference(R.string.hw_backup_no_backup),
style = LabelStyle.WARNING,
),
googleDriveStatus = LabelUM(
text = resourceReference(R.string.hw_backup_no_backup),
style = LabelStyle.WARNING,
),
onBackClick = {},
onRecoveryPhraseClick = {},
onGoogleDriveClick = {},
),
WalletBackupUM(
recoveryPhraseStatus = BackupStatus.Done,
googleDriveStatus = BackupStatus.Done,
recoveryPhraseStatus = LabelUM(
text = resourceReference(R.string.common_done),
style = LabelStyle.ACCENT,
),
googleDriveStatus = LabelUM(
text = resourceReference(R.string.common_done),
style = LabelStyle.ACCENT,
),
onBackClick = {},
onRecoveryPhraseClick = {},
onGoogleDriveClick = {},

View file

@ -65,4 +65,7 @@ dependencies {
implementation(deps.kotlin.immutable.collections)
implementation(deps.timber)
implementation(deps.reKotlin)
/** Tangem libraries */
implementation(tangemDeps.hot.core)
}

View file

@ -4,11 +4,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.tangem.core.analytics.DummyAnalyticsEventHandler
import com.tangem.core.decompose.navigation.DummyRouter
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
import com.tangem.feature.walletsettings.entity.WalletSettingsUM
import com.tangem.feature.walletsettings.ui.WalletSettingsScreen
import com.tangem.feature.walletsettings.utils.ItemsBuilder
import com.tangem.hot.sdk.model.HotWalletId
internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
@ -18,7 +20,13 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
router = DummyRouter(),
analyticsEventHandler = DummyAnalyticsEventHandler(),
).buildItems(
userWalletId = UserWalletId("011"),
userWallet = UserWallet.Hot(
walletId = UserWalletId("011"),
name = "My Wallet",
hotWalletId = HotWalletId("", HotWalletId.AuthType.NoPassword),
wallets = null,
backedUp = false,
),
userWalletName = "My Wallet",
isReferralAvailable = true,
isLinkMoreCardsAvailable = true,
@ -36,7 +44,7 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
onCheckedNotificationsChanged = {},
onNotificationsDescriptionClick = {},
isNotificationsPermissionGranted = false,
isHotWalletEnabled = false,
onAccessCodeClick = {},
),
requestPushNotificationsPermission = false,
onPushNotificationPermissionGranted = {},

View file

@ -31,8 +31,6 @@ import com.tangem.domain.notifications.repository.NotificationsRepository
import com.tangem.domain.notifications.toggles.NotificationsFeatureToggles
import com.tangem.domain.settings.repositories.PermissionRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.isMultiCurrency
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.wallets.usecase.*
import com.tangem.feature.walletsettings.analytics.Settings
import com.tangem.feature.walletsettings.analytics.WalletSettingsAnalyticEvents
@ -43,7 +41,6 @@ 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
@ -75,7 +72,6 @@ internal class WalletSettingsModel @Inject constructor(
private val setNotificationsEnabledUseCase: SetNotificationsEnabledUseCase,
private val settingsManager: SettingsManager,
private val permissionsRepository: PermissionRepository,
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
private val notificationsRepository: NotificationsRepository,
private val getIsHuaweiDeviceWithoutGoogleServicesUseCase: GetIsHuaweiDeviceWithoutGoogleServicesUseCase,
) : Model() {
@ -100,7 +96,6 @@ internal class WalletSettingsModel @Inject constructor(
getWalletNotificationsEnabledUseCase(params.userWalletId),
) { maybeWallet, nftEnabled, notificationsEnabled ->
val wallet = maybeWallet.getOrNull() ?: return@combine
wallet.requireColdWallet() // TODO [REDACTED_TASK_KEY] [Hot Wallet] Wallet Settings
val isRenameWalletAvailable = getShouldSaveUserWalletsSyncUseCase()
val isNeedShowNotifications = notificationsToggles.isNotificationsEnabled &&
!getIsHuaweiDeviceWithoutGoogleServicesUseCase()
@ -114,7 +109,6 @@ internal class WalletSettingsModel @Inject constructor(
isNotificationsEnabled = notificationsEnabled,
isNotificationsFeatureEnabled = isNeedShowNotifications,
isNotificationsPermissionGranted = isNotificationsPermissionGranted(),
isHotWalletEnabled = hotWalletFeatureToggles.isHotWalletEnabled,
),
)
}
@ -133,51 +127,65 @@ internal class WalletSettingsModel @Inject constructor(
}
private fun buildItems(
userWallet: UserWallet.Cold,
userWallet: UserWallet,
dialogNavigation: SlotNavigation<DialogConfig>,
isRenameWalletAvailable: Boolean,
isNFTEnabled: Boolean,
isNotificationsFeatureEnabled: Boolean,
isNotificationsEnabled: Boolean,
isNotificationsPermissionGranted: Boolean,
isHotWalletEnabled: Boolean,
): PersistentList<WalletSettingsItemUM> = itemsBuilder.buildItems(
userWalletId = userWallet.walletId,
userWalletName = userWallet.name,
isReferralAvailable = userWallet.cardTypesResolver.isTangemWallet(),
isLinkMoreCardsAvailable = userWallet.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup,
isManageTokensAvailable = userWallet.isMultiCurrency,
isRenameWalletAvailable = isRenameWalletAvailable,
renameWallet = { openRenameWalletDialog(userWallet, dialogNavigation) },
isNFTFeatureEnabled = userWallet.isMultiCurrency,
isNFTEnabled = isNFTEnabled,
onCheckedNFTChange = ::onCheckedNFTChange,
forgetWallet = {
val message = DialogMessage(
message = resourceReference(R.string.user_wallet_list_delete_prompt),
firstActionBuilder = {
EventMessageAction(
title = resourceReference(R.string.common_delete),
warning = true,
onClick = ::forgetWallet,
)
},
secondActionBuilder = { cancelAction() },
)
): PersistentList<WalletSettingsItemUM> {
val isMultiCurrency = when (userWallet) {
is UserWallet.Cold -> userWallet.isMultiCurrency
is UserWallet.Hot -> true
}
return itemsBuilder.buildItems(
userWallet = userWallet,
userWalletName = userWallet.name,
isReferralAvailable = when (userWallet) {
is UserWallet.Cold -> userWallet.cardTypesResolver.isTangemWallet()
is UserWallet.Hot -> false
},
isLinkMoreCardsAvailable = when (userWallet) {
is UserWallet.Cold -> userWallet.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup
is UserWallet.Hot -> false
},
isManageTokensAvailable = isMultiCurrency,
isRenameWalletAvailable = isRenameWalletAvailable,
renameWallet = { openRenameWalletDialog(userWallet, dialogNavigation) },
isNFTFeatureEnabled = isMultiCurrency,
isNFTEnabled = isNFTEnabled,
onCheckedNFTChange = ::onCheckedNFTChange,
forgetWallet = {
val message = DialogMessage(
message = resourceReference(R.string.user_wallet_list_delete_prompt),
firstActionBuilder = {
EventMessageAction(
title = resourceReference(R.string.common_delete),
warning = true,
onClick = ::forgetWallet,
)
},
secondActionBuilder = { cancelAction() },
)
messageSender.send(message)
},
onLinkMoreCardsClick = {
onLinkMoreCardsClick(scanResponse = userWallet.scanResponse)
},
onReferralClick = { onReferralClick(userWallet) },
isNotificationsEnabled = isNotificationsEnabled,
isNotificationsFeatureEnabled = isNotificationsFeatureEnabled,
isNotificationsPermissionGranted = isNotificationsPermissionGranted,
onCheckedNotificationsChanged = ::onCheckedNotificationsChange,
onNotificationsDescriptionClick = ::onNotificationsDescriptionClick,
isHotWalletEnabled = isHotWalletEnabled,
)
messageSender.send(message)
},
onLinkMoreCardsClick = {
when (userWallet) {
is UserWallet.Cold -> onLinkMoreCardsClick(scanResponse = userWallet.scanResponse)
is UserWallet.Hot -> Unit
}
},
onReferralClick = { onReferralClick(userWallet) },
isNotificationsEnabled = isNotificationsEnabled,
isNotificationsFeatureEnabled = isNotificationsFeatureEnabled,
isNotificationsPermissionGranted = isNotificationsPermissionGranted,
onCheckedNotificationsChanged = ::onCheckedNotificationsChange,
onNotificationsDescriptionClick = ::onNotificationsDescriptionClick,
onAccessCodeClick = ::onAccessCodeClick,
)
}
private fun openRenameWalletDialog(userWallet: UserWallet, dialogNavigation: SlotNavigation<DialogConfig>) {
val config = DialogConfig.RenameWallet(
@ -320,4 +328,8 @@ internal class WalletSettingsModel @Inject constructor(
router.push(AppRoute.ReferralProgram(userWallet.walletId))
}
}
private fun onAccessCodeClick() {
// TODO [REDACTED_TASK_KEY]
}
}

View file

@ -6,12 +6,15 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.ui.components.block.model.BlockUM
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.core.ui.extensions.stringReference
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.feature.walletsettings.analytics.Settings
import com.tangem.feature.walletsettings.entity.WalletSettingsItemUM
import com.tangem.feature.walletsettings.impl.R
import com.tangem.hot.sdk.model.HotWalletId
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
@ -25,7 +28,7 @@ internal class ItemsBuilder @Inject constructor(
@Suppress("LongParameterList")
fun buildItems(
userWalletId: UserWalletId,
userWallet: UserWallet,
userWalletName: String,
isLinkMoreCardsAvailable: Boolean,
isReferralAvailable: Boolean,
@ -43,25 +46,18 @@ internal class ItemsBuilder @Inject constructor(
renameWallet: () -> Unit,
onLinkMoreCardsClick: () -> Unit,
onReferralClick: () -> Unit,
isHotWalletEnabled: Boolean,
onAccessCodeClick: () -> Unit,
): PersistentList<WalletSettingsItemUM> = persistentListOf<WalletSettingsItemUM>()
.add(buildNameItem(userWalletName, isRenameWalletAvailable, renameWallet))
.run {
if (isNFTFeatureEnabled) {
add(buildNFTItem(isNFTEnabled, onCheckedNFTChange))
} else {
this
}
}
.addAll(buildAccessCodeItem(userWallet, onAccessCodeClick))
.add(
buildCardItem(
userWalletId = userWalletId,
userWallet = userWallet,
isLinkMoreCardsAvailable = isLinkMoreCardsAvailable,
isReferralAvailable = isReferralAvailable,
isManageTokensAvailable = isManageTokensAvailable,
onLinkMoreCardsClick = onLinkMoreCardsClick,
onReferralClick = onReferralClick,
isHotWalletEnabled = isHotWalletEnabled,
),
)
.addAll(
@ -73,8 +69,27 @@ internal class ItemsBuilder @Inject constructor(
onNotificationsDescriptionClick = onNotificationsDescriptionClick,
),
)
.addAll(
buildNFTItems(
isNFTFeatureEnabled = isNFTFeatureEnabled,
isNFTEnabled = isNFTEnabled,
onCheckedNFTChange = onCheckedNFTChange,
),
)
.add(buildForgetItem(forgetWallet))
private fun buildNFTItems(
isNFTFeatureEnabled: Boolean,
isNFTEnabled: Boolean,
onCheckedNFTChange: (Boolean) -> Unit,
): List<WalletSettingsItemUM> {
return if (isNFTFeatureEnabled) {
listOf(buildNFTItem(isNFTEnabled, onCheckedNFTChange))
} else {
emptyList()
}
}
private fun buildNotificationItems(
isNotificationsFeatureEnabled: Boolean,
isNotificationsPermissionGranted: Boolean,
@ -133,17 +148,35 @@ internal class ItemsBuilder @Inject constructor(
@Suppress("LongParameterList")
private fun buildCardItem(
userWalletId: UserWalletId,
userWallet: UserWallet,
isLinkMoreCardsAvailable: Boolean,
isReferralAvailable: Boolean,
isManageTokensAvailable: Boolean,
onLinkMoreCardsClick: () -> Unit,
onReferralClick: () -> Unit,
isHotWalletEnabled: Boolean,
) = WalletSettingsItemUM.WithItems(
id = "card",
description = resourceReference(R.string.settings_card_settings_footer),
blocks = buildList {
val userWalletId = userWallet.walletId
val isHotWallet = userWallet is UserWallet.Hot
if (isHotWallet) {
val hasBackup = userWallet.backedUp
BlockUM(
text = resourceReference(R.string.common_backup),
iconRes = R.drawable.ic_more_cards_24,
onClick = { router.push(AppRoute.WalletBackup(userWalletId)) },
label = if (hasBackup) {
null
} else {
LabelUM(
text = resourceReference(R.string.hw_backup_no_backup),
style = LabelStyle.WARNING,
)
},
).let(::add)
}
if (isManageTokensAvailable) {
BlockUM(
text = resourceReference(R.string.add_tokens_title),
@ -163,17 +196,11 @@ internal class ItemsBuilder @Inject constructor(
).let(::add)
}
BlockUM(
text = resourceReference(R.string.card_settings_title),
iconRes = R.drawable.ic_card_settings_24,
onClick = { router.push(AppRoute.CardSettings(userWalletId)) },
).let(::add)
if (isHotWalletEnabled) {
if (!isHotWallet) {
BlockUM(
text = resourceReference(R.string.common_backup),
iconRes = R.drawable.ic_more_cards_24,
onClick = { router.push(AppRoute.WalletBackup(userWalletId)) },
text = resourceReference(R.string.card_settings_title),
iconRes = R.drawable.ic_card_settings_24,
onClick = { router.push(AppRoute.CardSettings(userWalletId)) },
).let(::add)
}
@ -199,4 +226,36 @@ internal class ItemsBuilder @Inject constructor(
),
),
)
private fun buildAccessCodeItem(userWallet: UserWallet, onItemClick: () -> Unit): List<WalletSettingsItemUM> {
return when (userWallet) {
is UserWallet.Cold -> emptyList()
is UserWallet.Hot -> buildHotWalletAccessCodeItem(userWallet, onItemClick)
}
}
private fun buildHotWalletAccessCodeItem(
userWallet: UserWallet.Hot,
onItemClick: () -> Unit,
): List<WalletSettingsItemUM> {
val isCodeSet = userWallet.hotWalletId.authType != HotWalletId.AuthType.NoPassword
return listOf(
WalletSettingsItemUM.WithItems(
id = "access_code",
description = resourceReference(R.string.wallet_settings_access_code_description),
blocks = persistentListOf(
BlockUM(
text = if (isCodeSet) {
resourceReference(R.string.wallet_settings_change_access_code_title)
} else {
resourceReference(R.string.wallet_settings_set_access_code_title)
},
iconRes = R.drawable.ic_lock_24,
onClick = onItemClick,
accentType = BlockUM.AccentType.ACCENT,
),
),
),
)
}
}