Updated on 2026-08-14

This commit is contained in:
Tangem 2024-02-13 18:56:17 +03:00
parent 2e4d60e72c
commit 8da3529141
5 changed files with 64 additions and 20 deletions

View file

@ -1,9 +1,7 @@
package com.tangem.feature.wallet.presentation.wallet.domain
import arrow.core.Either
import com.tangem.common.extensions.isZero
import com.tangem.domain.settings.SetWalletWithFundsFoundUseCase
import com.tangem.domain.tokens.error.TokenListError
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.NetworkGroup
import com.tangem.domain.tokens.model.TokenList
@ -13,9 +11,7 @@ internal class WalletWithFundsChecker @Inject constructor(
private val setWalletWithFundsFoundUseCase: SetWalletWithFundsFoundUseCase,
) {
suspend fun check(maybeTokenList: Either<TokenListError, TokenList>) {
val tokenList = (maybeTokenList as? Either.Right)?.value ?: return
suspend fun check(tokenList: TokenList) {
val hasNonZeroWallets = when (tokenList) {
is TokenList.GroupedByNetwork -> {
tokenList.groups

View file

@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
@ -25,6 +26,7 @@ internal class MultiWalletContentLoader(
private val walletWithFundsChecker: WalletWithFundsChecker,
private val getTokenListUseCase: GetTokenListUseCase,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory,
private val reduxStateHolder: ReduxStateHolder,
) : WalletContentLoader(id = userWallet.walletId) {
@ -39,6 +41,7 @@ internal class MultiWalletContentLoader(
walletWithFundsChecker = walletWithFundsChecker,
getTokenListUseCase = getTokenListUseCase,
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
applyTokenListSortingUseCase = applyTokenListSortingUseCase,
),
MultiWalletWarningsSubscriber(
userWalletId = userWallet.walletId,

View file

@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
@ -22,6 +23,7 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory,
private val getTokenListUseCase: GetTokenListUseCase,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
private val reduxStateHolder: ReduxStateHolder,
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
) {
@ -38,6 +40,7 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
getMultiWalletWarningsFactory = getMultiWalletWarningsFactory,
reduxStateHolder = reduxStateHolder,
walletWarningsAnalyticsSender = walletWarningsAnalyticsSender,
applyTokenListSortingUseCase = applyTokenListSortingUseCase,
)
}
}

View file

@ -18,6 +18,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
internal typealias MaybeTokenListFlow = Flow<Either<TokenListError, TokenList>>
@ -33,35 +34,48 @@ internal abstract class BasicTokenListSubscriber(
protected abstract fun tokenListFlow(): MaybeTokenListFlow
protected open suspend fun onTokenListReceived(tokenList: TokenList) { /* no-op */
}
override fun create(coroutineScope: CoroutineScope): Flow<*> {
return combine(
flow = tokenListFlow()
.onEach {
.onEach { maybeTokenList ->
val displayedState = stateHolder.getWalletStateIfSelected(userWallet.walletId)
tokenListAnalyticsSender.send(displayedState, userWallet, it.getOrElse { return@onEach })
tokenListAnalyticsSender.send(
displayedUiState = displayedState,
userWallet = userWallet,
tokenList = maybeTokenList.getOrElse { return@onEach },
)
}
.distinctUntilChanged(),
flow2 = getSelectedAppCurrencyUseCase().distinctUntilChanged(),
transform = { maybeTokenList, maybeAppCurrency ->
updateContent(maybeTokenList, maybeAppCurrency.getOrElse { AppCurrency.Default })
walletWithFundsChecker.check(maybeTokenList)
val tokenList = maybeTokenList.getOrElse { e ->
Timber.e("Failed to load token list: $e")
SetTokenListErrorTransformer(userWallet.walletId, e)
return@combine
}
val appCurrency = maybeAppCurrency.getOrElse { e ->
Timber.e("Failed to load app currency: $e")
AppCurrency.Default
}
updateContent(tokenList, appCurrency)
walletWithFundsChecker.check(tokenList)
onTokenListReceived(tokenList)
},
)
}
private fun updateContent(maybeTokenList: Either<TokenListError, TokenList>, appCurrency: AppCurrency) {
private fun updateContent(tokenList: TokenList, appCurrency: AppCurrency) {
stateHolder.update(
maybeTokenList.fold(
ifLeft = { SetTokenListErrorTransformer(userWalletId = userWallet.walletId, error = it) },
ifRight = {
SetTokenListTransformer(
tokenList = it,
userWallet = userWallet,
appCurrency = appCurrency,
clickIntents = clickIntents,
)
},
SetTokenListTransformer(
tokenList = tokenList,
userWallet = userWallet,
appCurrency = appCurrency,
clickIntents = clickIntents,
),
)
}

View file

@ -1,7 +1,9 @@
package com.tangem.feature.wallet.presentation.wallet.subscribers
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
@ -12,6 +14,7 @@ import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletCl
internal class MultiWalletTokenListSubscriber(
private val userWallet: UserWallet,
private val getTokenListUseCase: GetTokenListUseCase,
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
stateHolder: WalletStateController,
clickIntents: WalletClickIntents,
tokenListAnalyticsSender: TokenListAnalyticsSender,
@ -27,4 +30,29 @@ internal class MultiWalletTokenListSubscriber(
) {
override fun tokenListFlow(): MaybeTokenListFlow = getTokenListUseCase(userWallet.walletId)
override suspend fun onTokenListReceived(tokenList: TokenList) {
updateSortingIfNeeded(tokenList)
}
private suspend fun updateSortingIfNeeded(tokenList: TokenList) {
if (tokenList.totalFiatBalance is TokenList.FiatBalance.Loading ||
tokenList.sortedBy == TokenList.SortType.NONE
) {
return
}
applyTokenListSortingUseCase(
userWalletId = userWallet.walletId,
sortedTokensIds = when (tokenList) {
is TokenList.GroupedByNetwork -> tokenList.groups.flatMap { group ->
group.currencies.map { it.currency.id }
}
is TokenList.Ungrouped -> tokenList.currencies.map { it.currency.id }
is TokenList.Empty -> return
},
isGroupedByNetwork = tokenList is TokenList.GroupedByNetwork,
isSortedByBalance = true,
)
}
}