From b83cd6c17df0739fab1e589ffe6534a70213db35 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 11 Nov 2025 11:18:49 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../AccountPortfolioItemUMConverter.kt | 13 ++++----- .../model/WalletSettingsModel.kt | 19 +++++++++++-- .../utils/AccountItemsDelegate.kt | 28 +++++++++++++------ .../utils/AccountListSortingSaver.kt | 9 ++++-- 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/common/ui/src/main/java/com/tangem/common/ui/account/AccountPortfolioItemUMConverter.kt b/common/ui/src/main/java/com/tangem/common/ui/account/AccountPortfolioItemUMConverter.kt index e270e01789..ef26a51eef 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/account/AccountPortfolioItemUMConverter.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/account/AccountPortfolioItemUMConverter.kt @@ -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), ) } } diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt index f207f3a7e3..390895141b 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt @@ -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") diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/AccountItemsDelegate.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/AccountItemsDelegate.kt index 2c0cd637d0..8d868805a3 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/AccountItemsDelegate.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/AccountItemsDelegate.kt @@ -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().userWalletId + + private val userWalletId = paramsContainer.require().userWalletId fun loadAccount(): Flow> { 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?, ): List = 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.applySortingOrder( + order: List?, + ): List { + 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)) } diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/AccountListSortingSaver.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/AccountListSortingSaver.kt index f790aa8797..1f86f48958 100644 --- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/AccountListSortingSaver.kt +++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/AccountListSortingSaver.kt @@ -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?> + private field = MutableStateFlow?>(value = null) + private val coroutineScope = CoroutineScope(SupervisorJob() + dispatchers.io) - private val applySortingFlow = MutableStateFlow?>(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) { - applySortingFlow.value = accountIds + accountsOrderFlow.value = accountIds } } \ No newline at end of file