Updated on 2026-08-14

This commit is contained in:
Tangem 2025-11-11 11:18:49 +04:00
parent 6d049b8d70
commit b83cd6c17d
4 changed files with 48 additions and 21 deletions

View file

@ -10,12 +10,11 @@ import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.TotalFiatBalance
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.converter.Converter
class AccountPortfolioItemUMConverter(
private val onClick: (AccountId) -> Unit,
private val onClick: () -> Unit,
private val appCurrency: AppCurrency? = null,
private val accountBalance: TotalFiatBalance? = null,
private val isBalanceHidden: Boolean = false,
@ -26,14 +25,14 @@ class AccountPortfolioItemUMConverter(
override fun convert(value: Account): UserWalletItemUM {
return with(value) {
UserWalletItemUM(
id = UserWalletId(value.accountId.value),
name = value.accountName.toUM().value,
information = getInfo(value),
id = UserWalletId(accountId.value),
name = accountName.toUM().value,
information = getInfo(account = this),
balance = getBalanceInfo(),
isEnabled = isEnabled,
endIcon = endIcon,
onClick = { onClick(value.accountId) },
imageState = getImageState(value),
onClick = onClick,
imageState = getImageState(account = this),
)
}
}

View file

@ -43,6 +43,7 @@ import com.tangem.feature.walletsettings.component.WalletSettingsComponent
import com.tangem.feature.walletsettings.entity.*
import com.tangem.feature.walletsettings.impl.R
import com.tangem.feature.walletsettings.utils.AccountItemsDelegate
import com.tangem.feature.walletsettings.utils.AccountListSortingSaver
import com.tangem.feature.walletsettings.utils.ItemsBuilder
import com.tangem.feature.walletsettings.utils.WalletCardItemDelegate
import com.tangem.features.pushnotifications.api.analytics.PushNotificationAnalyticEvents
@ -85,6 +86,7 @@ internal class WalletSettingsModel @Inject constructor(
private val dismissUpgradeWalletNotificationUseCase: DismissUpgradeWalletNotificationUseCase,
private val unlockHotWalletContextualUseCase: UnlockHotWalletContextualUseCase,
private val accountsFeatureToggles: AccountsFeatureToggles,
private val accountListSortingSaver: AccountListSortingSaver,
) : Model() {
val params: WalletSettingsComponent.Params = paramsContainer.require()
@ -114,8 +116,12 @@ internal class WalletSettingsModel @Inject constructor(
}
fun combineUI(wallet: UserWallet) = combine(
flow = getWalletNFTEnabledUseCase.invoke(params.userWalletId),
flow2 = getWalletNotificationsEnabledUseCase(params.userWalletId),
flow = getWalletNFTEnabledUseCase.invoke(params.userWalletId)
.distinctUntilChanged()
.conflate(),
flow2 = getWalletNotificationsEnabledUseCase(params.userWalletId)
.distinctUntilChanged()
.conflate(),
flow3 = isUpgradeWalletNotificationEnabledUseCase(params.userWalletId),
flow4 = walletCardItemDelegate.cardItemFlow(wallet),
flow5 = accountItemsDelegate.loadAccount(),
@ -438,7 +444,14 @@ internal class WalletSettingsModel @Inject constructor(
}
private fun onAccountDragStopped() {
// TODO() Implement saving the new order of accounts
val accountIds = state.value.items.mapNotNull {
val id = (it as? WalletSettingsAccountsUM.Account)?.state?.id
?: return@mapNotNull null
AccountId.forCryptoPortfolio(userWalletId = params.userWalletId, value = id.stringValue).getOrNull()
}
accountListSortingSaver.save(accountIds = accountIds)
}
@Suppress("LongMethod")

View file

@ -14,13 +14,13 @@ import com.tangem.core.ui.message.EventMessageAction
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
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
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
@ -42,21 +42,23 @@ internal class AccountItemsDelegate @Inject constructor(
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
private val accountListSortingSaver: AccountListSortingSaver,
private val accountsFeatureToggles: AccountsFeatureToggles,
) {
val userWalletId = paramsContainer.require<WalletSettingsComponent.Params>().userWalletId
private val userWalletId = paramsContainer.require<WalletSettingsComponent.Params>().userWalletId
fun loadAccount(): Flow<List<WalletSettingsAccountsUM>> {
if (!accountsFeatureToggles.isFeatureEnabled) return flowOf(emptyList())
val params = SingleAccountStatusListProducer.Params(userWalletId)
return combine(
flow = singleAccountStatusListSupplier(params),
flow = singleAccountStatusListSupplier(userWalletId),
flow2 = getSelectedAppCurrencyUseCase.invokeOrDefault(),
flow3 = getBalanceHidingSettingsUseCase.isBalanceHidden(),
flow4 = isAccountsModeEnabledUseCase(),
) { accountStatusList, appCurrency, isBalanceHidden, isAccountsMode ->
buildUiList(accountStatusList, appCurrency, isBalanceHidden, isAccountsMode)
}
flow5 = accountListSortingSaver.accountsOrderFlow,
transform = ::buildUiList,
)
}
private fun buildUiList(
@ -64,6 +66,7 @@ internal class AccountItemsDelegate @Inject constructor(
appCurrency: AppCurrency,
isBalanceHidden: Boolean,
isAccountsMode: Boolean,
accountsOrder: List<AccountId>?,
): List<WalletSettingsAccountsUM> = buildList {
fun AccountStatus.CryptoPortfolio.mapCryptoPortfolio(): WalletSettingsAccountsUM {
val accountItemUM = AccountPortfolioItemUMConverter(
@ -86,7 +89,7 @@ internal class AccountItemsDelegate @Inject constructor(
).let(::add)
if (isAccountsMode) {
addAll(accounts.map(::mapAccount))
addAll(accounts.map(::mapAccount).applySortingOrder(order = accountsOrder))
}
val addAccountEnabled = accounts.size < AccountList.MAX_ACCOUNTS_COUNT
@ -116,6 +119,15 @@ internal class AccountItemsDelegate @Inject constructor(
).let(::add)
}
private fun List<WalletSettingsAccountsUM>.applySortingOrder(
order: List<AccountId>?,
): List<WalletSettingsAccountsUM> {
if (order == null) return this
val positionByAccountId = order.withIndex().associate { it.value.value to it.index }
return this.sortedBy { positionByAccountId[it.id] ?: Int.MAX_VALUE }
}
private fun openAccountDetails(account: Account) {
router.push(AppRoute.AccountDetails(account))
}

View file

@ -27,11 +27,14 @@ internal class AccountListSortingSaver @Inject constructor(
dispatchers: CoroutineDispatcherProvider,
) {
/** Flow to hold the account IDs for sorting, with an initial null value. */
val accountsOrderFlow: StateFlow<List<AccountId>?>
private field = MutableStateFlow<List<AccountId>?>(value = null)
private val coroutineScope = CoroutineScope(SupervisorJob() + dispatchers.io)
private val applySortingFlow = MutableStateFlow<List<AccountId>?>(value = null)
init {
applySortingFlow
accountsOrderFlow
.filterNotNull()
.debounce { 3.seconds }
.onEach { accountIds ->
@ -48,6 +51,6 @@ internal class AccountListSortingSaver @Inject constructor(
* @param accountIds List of AccountId representing the desired order.
*/
fun save(accountIds: List<AccountId>) {
applySortingFlow.value = accountIds
accountsOrderFlow.value = accountIds
}
}