Updated on 2026-08-14
This commit is contained in:
parent
bd33dadcfe
commit
5a62376bfa
18 changed files with 194 additions and 163 deletions
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.features.account.archived
|
||||
|
||||
import com.tangem.common.ui.account.toUM
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
||||
import com.tangem.core.decompose.model.Model
|
||||
|
|
@ -15,11 +14,8 @@ import com.tangem.core.ui.message.EventMessageAction
|
|||
import com.tangem.core.ui.message.ToastMessage
|
||||
import com.tangem.core.ui.utils.showErrorDialog
|
||||
import com.tangem.domain.account.models.AccountList
|
||||
import com.tangem.domain.account.models.ArchivedAccount
|
||||
import com.tangem.domain.account.usecase.ArchivedAccountList
|
||||
import com.tangem.domain.account.usecase.GetArchivedAccountsUseCase
|
||||
import com.tangem.domain.account.usecase.RecoverCryptoPortfolioUseCase
|
||||
import com.tangem.domain.core.lce.Lce
|
||||
import com.tangem.domain.models.account.AccountId
|
||||
import com.tangem.features.account.ArchivedAccountListComponent
|
||||
import com.tangem.features.account.archived.entity.AccountArchivedUM
|
||||
|
|
@ -30,6 +26,7 @@ import com.tangem.utils.coroutines.JobHolder
|
|||
import com.tangem.utils.coroutines.saveIn
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -61,25 +58,32 @@ internal class ArchivedAccountListModel @Inject constructor(
|
|||
.conflate()
|
||||
.distinctUntilChanged()
|
||||
.onEach { lce ->
|
||||
val newState = when (lce) {
|
||||
is Lce.Content<ArchivedAccountList> -> umBuilder.mapContent(
|
||||
accounts = lce.content,
|
||||
onCloseClick = onCloseClick,
|
||||
confirmRecoverDialog = { confirmRecoverDialog(it) },
|
||||
)
|
||||
is Lce.Error<Throwable> -> umBuilder.mapError(
|
||||
throwable = lce.error,
|
||||
onCloseClick = onCloseClick,
|
||||
getArchivedAccounts = { getArchivedAccounts() },
|
||||
)
|
||||
is Lce.Loading<ArchivedAccountList> -> lce.partialContent?.let { content ->
|
||||
val newState = lce.fold(
|
||||
ifLoading = { content ->
|
||||
content ?: return@fold null
|
||||
|
||||
umBuilder.mapContent(
|
||||
accounts = content,
|
||||
onCloseClick = onCloseClick,
|
||||
confirmRecoverDialog = { confirmRecoverDialog(it) },
|
||||
onRecoverClick = { recoverCryptoPortfolio(accountId = it.accountId) },
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
ifContent = { content ->
|
||||
umBuilder.mapContent(
|
||||
accounts = content,
|
||||
onCloseClick = onCloseClick,
|
||||
onRecoverClick = { recoverCryptoPortfolio(accountId = it.accountId) },
|
||||
)
|
||||
},
|
||||
ifError = { error ->
|
||||
umBuilder.mapError(
|
||||
throwable = error,
|
||||
onCloseClick = onCloseClick,
|
||||
getArchivedAccounts = { getArchivedAccounts() },
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
newState?.let { _uiState.value = newState }
|
||||
}
|
||||
.flowOn(dispatchers.default)
|
||||
|
|
@ -87,30 +91,10 @@ internal class ArchivedAccountListModel @Inject constructor(
|
|||
.saveIn(getArchivedAccountsJob)
|
||||
}
|
||||
|
||||
private fun confirmRecoverDialog(account: ArchivedAccount) {
|
||||
val secondAction = EventMessageAction(
|
||||
title = resourceReference(R.string.common_cancel),
|
||||
onClick = {},
|
||||
)
|
||||
val firstAction = EventMessageAction(
|
||||
title = resourceReference(R.string.account_archived_recover),
|
||||
onClick = { recoverCryptoPortfolio(account.accountId) },
|
||||
)
|
||||
messageSender.send(
|
||||
DialogMessage(
|
||||
title = resourceReference(R.string.account_archived_recover_dialog_title),
|
||||
message = resourceReference(
|
||||
id = R.string.account_archived_recover_dialog_description,
|
||||
formatArgs = wrappedList(account.name.toUM().value),
|
||||
),
|
||||
firstActionBuilder = { firstAction },
|
||||
secondActionBuilder = { secondAction },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun recoverCryptoPortfolio(accountId: AccountId) = modelScope.launch(dispatchers.default) {
|
||||
recoverCryptoPortfolioUseCase(accountId)
|
||||
private fun recoverCryptoPortfolio(accountId: AccountId) = modelScope.launch {
|
||||
withContext(dispatchers.default) {
|
||||
recoverCryptoPortfolioUseCase(accountId)
|
||||
}
|
||||
.onLeft(::handleRecoverError)
|
||||
.onRight {
|
||||
showSuccessRecoverMessage()
|
||||
|
|
@ -122,8 +106,22 @@ internal class ArchivedAccountListModel @Inject constructor(
|
|||
if (error is RecoverCryptoPortfolioUseCase.Error.AccountListRequirementsNotMet &&
|
||||
error.cause is AccountList.Error.ExceedsMaxAccountsCount
|
||||
) {
|
||||
// TODO("account") show alert that max accounts count reached
|
||||
// https://www.figma.com/design/09KKG4ZVuFDZhj8WLv5rGJ/%F0%9F%9A%A7-App-experience?node-id=24765-180563&t=vk6TCy4MkYol1cPb-4
|
||||
val firstAction = EventMessageAction(
|
||||
title = resourceReference(R.string.common_got_it),
|
||||
onClick = { },
|
||||
)
|
||||
|
||||
messageSender.send(
|
||||
DialogMessage(
|
||||
title = resourceReference(R.string.account_recover_limit_dialog_title),
|
||||
message = resourceReference(
|
||||
id = R.string.account_recover_limit_dialog_description,
|
||||
formatArgs = wrappedList(AccountList.MAX_ACCOUNTS_COUNT.toString()),
|
||||
),
|
||||
firstActionBuilder = { firstAction },
|
||||
),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,15 +15,15 @@ internal class AccountArchivedUMBuilder @Inject constructor() {
|
|||
fun mapContent(
|
||||
accounts: ArchivedAccountList,
|
||||
onCloseClick: () -> Unit,
|
||||
confirmRecoverDialog: (account: ArchivedAccount) -> Unit,
|
||||
onRecoverClick: (account: ArchivedAccount) -> Unit,
|
||||
) = AccountArchivedUM.Content(
|
||||
onCloseClick = onCloseClick,
|
||||
accounts = accounts
|
||||
.map { account -> account.mapArchivedAccountUM(confirmRecoverDialog) }
|
||||
.map { account -> account.mapArchivedAccountUM(onRecoverClick) }
|
||||
.toImmutableList(),
|
||||
)
|
||||
|
||||
fun ArchivedAccount.mapArchivedAccountUM(confirmRecoverDialog: (account: ArchivedAccount) -> Unit) =
|
||||
private fun ArchivedAccount.mapArchivedAccountUM(onRecoverClick: (account: ArchivedAccount) -> Unit) =
|
||||
ArchivedAccountUM(
|
||||
accountId = accountId.value,
|
||||
accountName = name.toUM().value,
|
||||
|
|
@ -38,7 +38,7 @@ internal class AccountArchivedUMBuilder @Inject constructor() {
|
|||
count = networksCount,
|
||||
formatArgs = wrappedList(networksCount),
|
||||
),
|
||||
onClick = { confirmRecoverDialog(this) },
|
||||
onClick = { onRecoverClick(this) },
|
||||
)
|
||||
|
||||
fun mapError(
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
|
|||
onReferralClick = {},
|
||||
isManageTokensAvailable = true,
|
||||
isNotificationsEnabled = true,
|
||||
isNotificationsFeatureEnabled = true,
|
||||
onCheckedNotificationsChanged = {},
|
||||
onNotificationsDescriptionClick = {},
|
||||
isNotificationsPermissionGranted = false,
|
||||
|
|
|
|||
|
|
@ -48,11 +48,13 @@ import com.tangem.hot.sdk.model.HotWalletId
|
|||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
@ModelScoped
|
||||
internal class WalletSettingsModel @Inject constructor(
|
||||
|
|
@ -128,11 +130,11 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun combineUI(wallet: UserWallet) = combine(
|
||||
getWalletNFTEnabledUseCase.invoke(params.userWalletId),
|
||||
getWalletNotificationsEnabledUseCase(params.userWalletId),
|
||||
isUpgradeWalletNotificationEnabledUseCase(params.userWalletId),
|
||||
walletCardItemDelegate.cardItemFlow(wallet),
|
||||
accountItemsDelegate.loadAccount(),
|
||||
flow = getWalletNFTEnabledUseCase.invoke(params.userWalletId),
|
||||
flow2 = getWalletNotificationsEnabledUseCase(params.userWalletId),
|
||||
flow3 = isUpgradeWalletNotificationEnabledUseCase(params.userWalletId),
|
||||
flow4 = walletCardItemDelegate.cardItemFlow(wallet),
|
||||
flow5 = accountItemsDelegate.loadAccount(),
|
||||
) { nftEnabled, notificationsEnabled, isUpgradeNotificationEnabled, cardItem, accountList ->
|
||||
val isWalletBackedUp = when (wallet) {
|
||||
is UserWallet.Hot -> wallet.backedUp
|
||||
|
|
@ -145,7 +147,6 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
cardItem = cardItem,
|
||||
isNFTEnabled = nftEnabled,
|
||||
isNotificationsEnabled = notificationsEnabled,
|
||||
isNotificationsFeatureEnabled = true,
|
||||
isNotificationsPermissionGranted = isNotificationsPermissionGranted(),
|
||||
isUpgradeNotificationEnabled = isUpgradeNotificationEnabled,
|
||||
accountList = accountList,
|
||||
|
|
@ -180,7 +181,6 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
userWallet: UserWallet,
|
||||
cardItem: WalletSettingsItemUM.CardBlock,
|
||||
isNFTEnabled: Boolean,
|
||||
isNotificationsFeatureEnabled: Boolean,
|
||||
isNotificationsEnabled: Boolean,
|
||||
isNotificationsPermissionGranted: Boolean,
|
||||
isUpgradeNotificationEnabled: Boolean,
|
||||
|
|
@ -202,7 +202,11 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
is UserWallet.Cold -> userWallet.scanResponse.card.backupStatus == CardDTO.BackupStatus.NoBackup
|
||||
is UserWallet.Hot -> false
|
||||
},
|
||||
isManageTokensAvailable = !accountsFeatureEnabled && isMultiCurrency,
|
||||
isManageTokensAvailable = if (accountsFeatureEnabled) {
|
||||
isMultiCurrency && accountList.count { it is WalletSettingsAccountsUM.Account } == 0
|
||||
} else {
|
||||
isMultiCurrency
|
||||
},
|
||||
isNFTFeatureEnabled = isMultiCurrency,
|
||||
isNFTEnabled = isNFTEnabled,
|
||||
onCheckedNFTChange = ::onCheckedNFTChange,
|
||||
|
|
@ -217,7 +221,6 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
},
|
||||
onReferralClick = { onReferralClick(userWallet) },
|
||||
isNotificationsEnabled = isNotificationsEnabled,
|
||||
isNotificationsFeatureEnabled = isNotificationsFeatureEnabled,
|
||||
isNotificationsPermissionGranted = isNotificationsPermissionGranted,
|
||||
onCheckedNotificationsChanged = ::onCheckedNotificationsChange,
|
||||
onNotificationsDescriptionClick = ::onNotificationsDescriptionClick,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import com.tangem.domain.account.models.AccountList
|
|||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
|
|
@ -40,6 +41,7 @@ internal class AccountItemsDelegate @Inject constructor(
|
|||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
) {
|
||||
val userWalletId = paramsContainer.require<WalletSettingsComponent.Params>().userWalletId
|
||||
|
|
@ -51,8 +53,9 @@ internal class AccountItemsDelegate @Inject constructor(
|
|||
flow = singleAccountStatusListSupplier(params),
|
||||
flow2 = getSelectedAppCurrencyUseCase.invokeOrDefault(),
|
||||
flow3 = getBalanceHidingSettingsUseCase.isBalanceHidden(),
|
||||
) { accountStatusList, appCurrency, isBalanceHidden ->
|
||||
buildUiList(accountStatusList, appCurrency, isBalanceHidden)
|
||||
flow4 = isAccountsModeEnabledUseCase(),
|
||||
) { accountStatusList, appCurrency, isBalanceHidden, isAccountsMode ->
|
||||
buildUiList(accountStatusList, appCurrency, isBalanceHidden, isAccountsMode)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,6 +63,7 @@ internal class AccountItemsDelegate @Inject constructor(
|
|||
accountStatusList: AccountStatusList,
|
||||
appCurrency: AppCurrency,
|
||||
isBalanceHidden: Boolean,
|
||||
isAccountsMode: Boolean,
|
||||
): List<WalletSettingsAccountsUM> = buildList {
|
||||
fun AccountStatus.CryptoPortfolio.mapCryptoPortfolio(): WalletSettingsAccountsUM {
|
||||
val accountItemUM = AccountPortfolioItemUMConverter(
|
||||
|
|
@ -81,7 +85,9 @@ internal class AccountItemsDelegate @Inject constructor(
|
|||
text = resourceReference(R.string.common_accounts),
|
||||
).let(::add)
|
||||
|
||||
addAll(accounts.map(::mapAccount))
|
||||
if (isAccountsMode) {
|
||||
addAll(accounts.map(::mapAccount))
|
||||
}
|
||||
|
||||
val addAccountEnabled = accounts.size < AccountList.MAX_ACCOUNTS_COUNT
|
||||
val showDescription = accounts.size > 1
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ internal class ItemsBuilder @Inject constructor(
|
|||
isNFTFeatureEnabled: Boolean,
|
||||
isNFTEnabled: Boolean,
|
||||
onCheckedNFTChange: (Boolean) -> Unit,
|
||||
isNotificationsFeatureEnabled: Boolean,
|
||||
isNotificationsEnabled: Boolean,
|
||||
isNotificationsPermissionGranted: Boolean,
|
||||
onCheckedNotificationsChanged: (Boolean) -> Unit,
|
||||
|
|
@ -74,7 +73,6 @@ internal class ItemsBuilder @Inject constructor(
|
|||
)
|
||||
.addAll(
|
||||
buildNotificationItems(
|
||||
isNotificationsFeatureEnabled = isNotificationsFeatureEnabled,
|
||||
isNotificationsPermissionGranted = isNotificationsPermissionGranted,
|
||||
isNotificationsEnabled = isNotificationsEnabled,
|
||||
onCheckedNotificationsChanged = onCheckedNotificationsChanged,
|
||||
|
|
@ -103,13 +101,11 @@ internal class ItemsBuilder @Inject constructor(
|
|||
}
|
||||
|
||||
private fun buildNotificationItems(
|
||||
isNotificationsFeatureEnabled: Boolean,
|
||||
isNotificationsPermissionGranted: Boolean,
|
||||
isNotificationsEnabled: Boolean,
|
||||
onCheckedNotificationsChanged: (Boolean) -> Unit,
|
||||
onNotificationsDescriptionClick: () -> Unit,
|
||||
): List<WalletSettingsItemUM> {
|
||||
if (!isNotificationsFeatureEnabled) return emptyList()
|
||||
return buildList {
|
||||
if (!isNotificationsPermissionGranted) {
|
||||
add(buildNotificationsPermissionItem())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue