Updated on 2026-08-14
This commit is contained in:
parent
d1191ec881
commit
96e28b2d1f
6 changed files with 112 additions and 21 deletions
|
|
@ -136,4 +136,24 @@ internal object AccountStatusUseCaseModule {
|
|||
parallelUpdatingScope = CoroutineScope(SupervisorJob() + dispatchers.default),
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideToggleTokenListSortingUseCaseV2(
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): ToggleTokenListSortingUseCaseV2 {
|
||||
return ToggleTokenListSortingUseCaseV2(
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideToggleTokenListGroupingUseCaseV2(
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): ToggleTokenListGroupingUseCaseV2 {
|
||||
return ToggleTokenListGroupingUseCaseV2(
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import arrow.core.Either
|
|||
import arrow.core.raise.ensure
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.core.utils.eitherOn
|
||||
import com.tangem.domain.models.TokensGroupType
|
||||
import com.tangem.domain.models.TotalFiatBalance
|
||||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.tokenlist.TokenList
|
||||
|
|
@ -42,11 +43,18 @@ class ToggleTokenListGroupingUseCaseV2(
|
|||
TokenListSortingError.TokenListIsLoading
|
||||
}
|
||||
|
||||
accountStatusList.copy(
|
||||
accountStatuses = accountStatusList.accountStatuses.map { account ->
|
||||
if (account !is AccountStatus.CryptoPortfolio) return@map account
|
||||
val updatedAccountList = accountStatusList.accountStatuses.map { account ->
|
||||
if (account !is AccountStatus.CryptoPortfolio) return@map account
|
||||
|
||||
account.copy(tokenList = account.tokenList.reverseGroupType())
|
||||
account.copy(tokenList = account.tokenList.reverseGroupType())
|
||||
}
|
||||
|
||||
accountStatusList.copy(
|
||||
accountStatuses = updatedAccountList,
|
||||
groupType = when (updatedAccountList.firstOrNull()?.getCryptoTokenList()) {
|
||||
is TokenList.GroupedByNetwork -> TokensGroupType.NETWORK
|
||||
is TokenList.Ungrouped -> TokensGroupType.NONE
|
||||
else -> accountStatusList.groupType
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class ToggleTokenListGroupingUseCaseV2Test {
|
|||
currencies = listOf(mockk(relaxed = true)),
|
||||
)
|
||||
|
||||
val accountStatusList = createAccountStatusList(tokenList)
|
||||
val accountStatusList = createAccountStatusList(tokenList, TokensGroupType.NONE)
|
||||
|
||||
// Act
|
||||
val actual = useCase(accountStatusList)
|
||||
|
|
@ -86,7 +86,7 @@ class ToggleTokenListGroupingUseCaseV2Test {
|
|||
sortedBy = TokensSortType.BALANCE,
|
||||
)
|
||||
|
||||
val accountStatusList = createAccountStatusList(tokenList)
|
||||
val accountStatusList = createAccountStatusList(tokenList, TokensGroupType.NONE)
|
||||
|
||||
val updatedTokenList = createGroupedByNetwork(
|
||||
statuses = listOf(
|
||||
|
|
@ -101,7 +101,7 @@ class ToggleTokenListGroupingUseCaseV2Test {
|
|||
val actual = useCase(accountStatusList)
|
||||
|
||||
// Assert
|
||||
val expected = createAccountStatusList(updatedTokenList).right()
|
||||
val expected = createAccountStatusList(updatedTokenList, TokensGroupType.NETWORK).right()
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
}
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ class ToggleTokenListGroupingUseCaseV2Test {
|
|||
),
|
||||
)
|
||||
|
||||
val accountStatusList = createAccountStatusList(tokenList)
|
||||
val accountStatusList = createAccountStatusList(tokenList, TokensGroupType.NONE)
|
||||
|
||||
val updatedTokenList = createGroupedByNetwork(
|
||||
statuses = listOf(
|
||||
|
|
@ -130,7 +130,7 @@ class ToggleTokenListGroupingUseCaseV2Test {
|
|||
val actual = useCase(accountStatusList)
|
||||
|
||||
// Assert
|
||||
val expected = createAccountStatusList(updatedTokenList).right()
|
||||
val expected = createAccountStatusList(updatedTokenList, TokensGroupType.NETWORK).right()
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ class ToggleTokenListGroupingUseCaseV2Test {
|
|||
sortedBy = TokensSortType.BALANCE,
|
||||
)
|
||||
|
||||
val accountStatusList = createAccountStatusList(tokenList)
|
||||
val accountStatusList = createAccountStatusList(tokenList, TokensGroupType.NETWORK)
|
||||
|
||||
val updatedTokenList = createUngrouped(
|
||||
statuses = listOf(
|
||||
|
|
@ -161,7 +161,7 @@ class ToggleTokenListGroupingUseCaseV2Test {
|
|||
val actual = useCase(accountStatusList)
|
||||
|
||||
// Assert
|
||||
val expected = createAccountStatusList(updatedTokenList).right()
|
||||
val expected = createAccountStatusList(updatedTokenList, TokensGroupType.NONE).right()
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
}
|
||||
|
||||
|
|
@ -176,7 +176,7 @@ class ToggleTokenListGroupingUseCaseV2Test {
|
|||
),
|
||||
)
|
||||
|
||||
val accountStatusList = createAccountStatusList(tokenList)
|
||||
val accountStatusList = createAccountStatusList(tokenList, TokensGroupType.NETWORK)
|
||||
|
||||
val updatedTokenList = createUngrouped(
|
||||
statuses = listOf(
|
||||
|
|
@ -190,11 +190,11 @@ class ToggleTokenListGroupingUseCaseV2Test {
|
|||
val actual = useCase(accountStatusList)
|
||||
|
||||
// Assert
|
||||
val expected = createAccountStatusList(updatedTokenList).right()
|
||||
val expected = createAccountStatusList(updatedTokenList, TokensGroupType.NONE).right()
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
}
|
||||
|
||||
private fun createAccountStatusList(tokenList: TokenList): AccountStatusList {
|
||||
private fun createAccountStatusList(tokenList: TokenList, groupType: TokensGroupType): AccountStatusList {
|
||||
val accountStatus = AccountStatus.CryptoPortfolio(
|
||||
account = Account.CryptoPortfolio.createMainAccount(userWalletId),
|
||||
tokenList = tokenList,
|
||||
|
|
@ -207,7 +207,7 @@ class ToggleTokenListGroupingUseCaseV2Test {
|
|||
totalAccounts = 1,
|
||||
totalFiatBalance = tokenList.totalFiatBalance,
|
||||
sortType = tokenList.sortedBy,
|
||||
groupType = TokensGroupType.NONE,
|
||||
groupType = groupType,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,9 @@ import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|||
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.status.usecase.ApplyTokenListSortingUseCaseV2
|
||||
import com.tangem.domain.account.status.usecase.ToggleTokenListGroupingUseCaseV2
|
||||
import com.tangem.domain.account.status.usecase.ToggleTokenListSortingUseCaseV2
|
||||
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
|
|
@ -55,6 +58,9 @@ internal class OrganizeTokensModel @Inject constructor(
|
|||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||
private val toggleTokenListGroupingUseCaseV2: ToggleTokenListGroupingUseCaseV2,
|
||||
private val toggleTokenListSortingUseCaseV2: ToggleTokenListSortingUseCaseV2,
|
||||
private val applyTokenListSortingUseCaseV2: ApplyTokenListSortingUseCaseV2,
|
||||
) : Model(), OrganizeTokensIntents {
|
||||
|
||||
private val selectedAppCurrencyFlow = createSelectedAppCurrencyFlow()
|
||||
|
|
@ -82,6 +88,8 @@ internal class OrganizeTokensModel @Inject constructor(
|
|||
private var cachedTokenList: TokenList? = null
|
||||
private var cachedAccountStatusList: AccountStatusList? = null
|
||||
|
||||
private var isAccountsModeEnabled: Boolean = false
|
||||
|
||||
val uiState: StateFlow<OrganizeTokensState> = stateHolder.stateFlow
|
||||
|
||||
val onBack = MutableSharedFlow<Unit>()
|
||||
|
|
@ -112,7 +120,13 @@ internal class OrganizeTokensModel @Inject constructor(
|
|||
analyticsEventsHandler.send(PortfolioOrganizeTokensAnalyticsEvent.ByBalance)
|
||||
|
||||
modelScope.launch {
|
||||
// todo account token list sorting
|
||||
toggleTokenListSortingUseCaseV2(list).fold(
|
||||
ifLeft = stateHolder::updateStateWithError,
|
||||
ifRight = {
|
||||
stateHolder.updateStateAfterTokenListSortingV2(it, isAccountsModeEnabled)
|
||||
cachedAccountStatusList = it
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val list = cachedTokenList ?: return
|
||||
|
|
@ -134,10 +148,18 @@ internal class OrganizeTokensModel @Inject constructor(
|
|||
|
||||
override fun onGroupClick() {
|
||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
||||
cachedAccountStatusList ?: return
|
||||
val list = cachedAccountStatusList ?: return
|
||||
|
||||
analyticsEventsHandler.send(PortfolioOrganizeTokensAnalyticsEvent.Group)
|
||||
|
||||
modelScope.launch {
|
||||
// todo account token list grouping
|
||||
toggleTokenListGroupingUseCaseV2(list).fold(
|
||||
ifLeft = stateHolder::updateStateWithError,
|
||||
ifRight = {
|
||||
stateHolder.updateStateAfterTokenListSortingV2(it, isAccountsModeEnabled)
|
||||
cachedAccountStatusList = it
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val list = cachedTokenList ?: return
|
||||
|
|
@ -172,8 +194,11 @@ internal class OrganizeTokensModel @Inject constructor(
|
|||
isSortedByBalance = isSortedByBalance,
|
||||
)
|
||||
|
||||
// val sorted = resolver.resolveV2(tokensListUM, cachedAccountStatusList)
|
||||
TODO("Implement account token list sorting")
|
||||
applyTokenListSortingUseCaseV2(
|
||||
sortedTokensIdsByAccount = resolver.resolveV2(tokensListUM, cachedAccountStatusList),
|
||||
isGroupedByNetwork = isGroupedByNetwork,
|
||||
isSortedByBalance = isSortedByBalance,
|
||||
)
|
||||
} else {
|
||||
val listState = uiState.value.itemsState
|
||||
|
||||
|
|
@ -215,7 +240,7 @@ internal class OrganizeTokensModel @Inject constructor(
|
|||
SingleAccountStatusListProducer.Params(userWalletId),
|
||||
) ?: return@launch
|
||||
|
||||
val isAccountsModeEnabled = isAccountsModeEnabledUseCase.invokeSync()
|
||||
isAccountsModeEnabled = isAccountsModeEnabledUseCase.invokeSync()
|
||||
|
||||
stateHolder.updateStateWithAccountList(
|
||||
accountStatusList = accountList,
|
||||
|
|
|
|||
|
|
@ -79,6 +79,18 @@ internal class OrganizeTokensStateHolder(
|
|||
}
|
||||
}
|
||||
|
||||
fun updateStateAfterTokenListSortingV2(accountStatusList: AccountStatusList, isAccountsModeEnabled: Boolean) {
|
||||
updateState {
|
||||
TokenListToStateConverterV2(
|
||||
accountStatusList = accountStatusList,
|
||||
isAccountsMode = isAccountsModeEnabled,
|
||||
appCurrency = appCurrencyProvider(),
|
||||
).transform(this).copy(
|
||||
scrollListToTop = triggeredEvent(Unit, ::consumeScrollListToTopEvent),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateStateToDisplayProgress() {
|
||||
updateState { inProgressStateConverter.convert(value = this) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
package com.tangem.feature.wallet.presentation.organizetokens.utils
|
||||
|
||||
import com.tangem.domain.account.models.AccountStatusList
|
||||
import com.tangem.domain.account.status.model.AccountCryptoCurrencies
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.tokenlist.TokenList
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.model.OrganizeTokensListState
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.model.OrganizeTokensListUM
|
||||
|
||||
internal class CryptoCurrenciesIdsResolver {
|
||||
|
||||
|
|
@ -29,4 +33,26 @@ internal class CryptoCurrenciesIdsResolver {
|
|||
currencyStatus?.currency?.id
|
||||
}
|
||||
}
|
||||
|
||||
fun resolveV2(tokensListUM: OrganizeTokensListUM, accountStatusList: AccountStatusList?): AccountCryptoCurrencies {
|
||||
val draggableTokens = when (tokensListUM) {
|
||||
OrganizeTokensListUM.EmptyList -> return emptyMap()
|
||||
is OrganizeTokensListUM.AccountList,
|
||||
is OrganizeTokensListUM.TokensList,
|
||||
-> tokensListUM.items.filterIsInstance<DraggableItem.Token>()
|
||||
}
|
||||
|
||||
return accountStatusList?.accountStatuses
|
||||
?.filter { it.getCryptoTokenList() != TokenList.Empty }
|
||||
?.associate { accountStatus ->
|
||||
val currencies = accountStatus.flattenCurrencies()
|
||||
accountStatus.account as Account.CryptoPortfolio to draggableTokens
|
||||
.asSequence()
|
||||
.filter { it.accountId == accountStatus.account.accountId.value }
|
||||
.mapNotNull { sortedToken ->
|
||||
currencies.firstOrNull { it.currency.id.value == sortedToken.id }?.currency
|
||||
}
|
||||
.toList()
|
||||
} ?: emptyMap()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue