Updated on 2026-08-14
This commit is contained in:
parent
c215778788
commit
d1c77b00cf
14 changed files with 44 additions and 85 deletions
|
|
@ -19,20 +19,20 @@ class ToggleTokenListGroupingUseCase(
|
|||
suspend operator fun invoke(tokenList: TokenList): Either<TokenListSortingError, TokenList> {
|
||||
return withContext(dispatchers.default) {
|
||||
either {
|
||||
ensure(tokenList.totalFiatBalance !is TokenList.FiatBalance.Loading) {
|
||||
TokenListSortingError.TokenListIsLoading
|
||||
}
|
||||
|
||||
when (tokenList) {
|
||||
is TokenList.GroupedByNetwork -> ungroupTokens(tokenList)
|
||||
is TokenList.Ungrouped -> groupTokens(tokenList)
|
||||
is TokenList.NotInitialized -> raise(TokenListSortingError.TokenListIsEmpty)
|
||||
is TokenList.Empty -> raise(TokenListSortingError.TokenListIsEmpty)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Raise<TokenListSortingError>.groupTokens(tokenList: TokenList.Ungrouped): TokenList.GroupedByNetwork {
|
||||
ensure(tokenList.totalFiatBalance !is TokenList.FiatBalance.Loading) {
|
||||
TokenListSortingError.TokenListIsLoading
|
||||
}
|
||||
|
||||
val sortingOperations = TokenListSortingOperations(tokenList)
|
||||
|
||||
return TokenList.GroupedByNetwork(
|
||||
|
|
@ -47,6 +47,10 @@ class ToggleTokenListGroupingUseCase(
|
|||
private fun Raise<TokenListSortingError>.ungroupTokens(
|
||||
tokenList: TokenList.GroupedByNetwork,
|
||||
): TokenList.Ungrouped {
|
||||
ensure(tokenList.totalFiatBalance !is TokenList.FiatBalance.Loading) {
|
||||
TokenListSortingError.TokenListIsLoading
|
||||
}
|
||||
|
||||
val sortingOperations = TokenListSortingOperations(tokenList)
|
||||
|
||||
return TokenList.Ungrouped(
|
||||
|
|
|
|||
|
|
@ -19,14 +19,10 @@ class ToggleTokenListSortingUseCase(
|
|||
suspend operator fun invoke(tokenList: TokenList): Either<TokenListSortingError, TokenList> {
|
||||
return withContext(dispatchers.default) {
|
||||
either {
|
||||
ensure(tokenList.totalFiatBalance !is TokenList.FiatBalance.Loading) {
|
||||
TokenListSortingError.TokenListIsLoading
|
||||
}
|
||||
|
||||
when (tokenList) {
|
||||
is TokenList.GroupedByNetwork -> sortGroupedTokenList(tokenList)
|
||||
is TokenList.Ungrouped -> sortUngroupedTokenList(tokenList)
|
||||
is TokenList.NotInitialized -> raise(TokenListSortingError.TokenListIsEmpty)
|
||||
is TokenList.Empty -> raise(TokenListSortingError.TokenListIsEmpty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +31,10 @@ class ToggleTokenListSortingUseCase(
|
|||
private fun Raise<TokenListSortingError>.sortGroupedTokenList(
|
||||
tokenList: TokenList.GroupedByNetwork,
|
||||
): TokenList.GroupedByNetwork {
|
||||
ensure(tokenList.totalFiatBalance !is TokenList.FiatBalance.Loading) {
|
||||
TokenListSortingError.TokenListIsLoading
|
||||
}
|
||||
|
||||
val operations = getSortingOperations(tokenList)
|
||||
|
||||
return tokenList.copy(
|
||||
|
|
@ -48,6 +48,10 @@ class ToggleTokenListSortingUseCase(
|
|||
private fun Raise<TokenListSortingError>.sortUngroupedTokenList(
|
||||
tokenList: TokenList.Ungrouped,
|
||||
): TokenList.Ungrouped {
|
||||
ensure(tokenList.totalFiatBalance !is TokenList.FiatBalance.Loading) {
|
||||
TokenListSortingError.TokenListIsLoading
|
||||
}
|
||||
|
||||
val operations = getSortingOperations(tokenList)
|
||||
|
||||
return tokenList.copy(
|
||||
|
|
|
|||
|
|
@ -41,8 +41,14 @@ sealed class TokenList {
|
|||
override val sortedBy: SortType,
|
||||
) : TokenList()
|
||||
|
||||
/** Represents a state where the token list is not initialized. */
|
||||
object NotInitialized : TokenList()
|
||||
/** Represents a state where the token list is empty. */
|
||||
object Empty : TokenList() {
|
||||
|
||||
override val totalFiatBalance: FiatBalance = FiatBalance.Loaded(
|
||||
amount = BigDecimal.ZERO,
|
||||
isAllAmountsSummarized = true,
|
||||
)
|
||||
}
|
||||
|
||||
/** Defines the possible sorting criteria for the tokens. */
|
||||
enum class SortType {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ internal class TokenListOperations(
|
|||
|
||||
private fun Raise<Error>.createTokenList(isGrouped: Boolean, isSortedByBalance: Boolean): TokenList {
|
||||
val nonEmptyCurrencies = tokens.toNonEmptyListOrNull()
|
||||
?: return TokenList.NotInitialized
|
||||
?: return TokenList.Empty
|
||||
|
||||
val isAnyTokenLoading = nonEmptyCurrencies.any { it.value is CryptoCurrencyStatus.Loading }
|
||||
val fiatBalanceOperations = TokenListFiatBalanceOperations(nonEmptyCurrencies, isAnyTokenLoading)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ internal class TokenListSortingOperations(
|
|||
currencies = when (tokenList) {
|
||||
is TokenList.GroupedByNetwork -> tokenList.groups.flatMap { it.currencies }
|
||||
is TokenList.Ungrouped -> tokenList.currencies
|
||||
is TokenList.NotInitialized -> emptyList()
|
||||
is TokenList.Empty -> emptyList()
|
||||
},
|
||||
isAnyTokenLoading = isAnyTokenLoading,
|
||||
sortByBalance = sortByBalance,
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ internal class GetTokenListUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `when tokens is empty then not initialized token list should be received`() = runTest {
|
||||
val expectedResult = MockTokenLists.notInitializedTokenList.right()
|
||||
val expectedResult = MockTokenLists.emptyTokenList.right()
|
||||
|
||||
val useCase = getUseCase(tokens = flowOf(emptyList<CryptoCurrency>().right()))
|
||||
|
||||
|
|
|
|||
|
|
@ -12,21 +12,7 @@ import org.junit.Test
|
|||
internal class ToggleTokenListGroupingTest {
|
||||
|
||||
@Test
|
||||
fun `when grouped list is empty then error should be received`() = runTest {
|
||||
// Given
|
||||
val expectedResult = TokenListSortingError.TokenListIsEmpty.left()
|
||||
|
||||
val useCase = getUseCase()
|
||||
|
||||
// When
|
||||
val result = useCase(MockTokenLists.emptyGroupedTokenList)
|
||||
|
||||
// Then
|
||||
assertEquals(expectedResult, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when ungrouped list is empty then error should be received`() = runTest {
|
||||
fun `when list is empty then error should be received`() = runTest {
|
||||
// Given
|
||||
val expectedResult = TokenListSortingError.TokenListIsEmpty.left()
|
||||
|
||||
|
|
@ -67,20 +53,6 @@ internal class ToggleTokenListGroupingTest {
|
|||
assertEquals(expectedResult, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when list is not initialized then error should be received`() = runTest {
|
||||
// Given
|
||||
val expectedResult = TokenListSortingError.TokenListIsLoading.left()
|
||||
|
||||
val useCase = getUseCase()
|
||||
|
||||
// When
|
||||
val result = useCase(MockTokenLists.notInitializedTokenList)
|
||||
|
||||
// Then
|
||||
assertEquals(expectedResult, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when list is ungrouped and sorted then sorted grouped list should be received`() = runTest {
|
||||
// Given
|
||||
|
|
|
|||
|
|
@ -12,42 +12,14 @@ import org.junit.Test
|
|||
internal class ToggleTokenListSortingUseCaseTest {
|
||||
|
||||
@Test
|
||||
fun `when grouped list is not initialized then error should be received`() = runTest {
|
||||
// Given
|
||||
val expectedResult = TokenListSortingError.TokenListIsLoading.left()
|
||||
|
||||
val useCase = getUseCase()
|
||||
|
||||
// When
|
||||
val result = useCase(MockTokenLists.notInitializedTokenList)
|
||||
|
||||
// Then
|
||||
assertEquals(expectedResult, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when grouped list is empty then error should be received`() = runTest {
|
||||
fun `when list is empty then error should be received`() = runTest {
|
||||
// Given
|
||||
val expectedResult = TokenListSortingError.TokenListIsEmpty.left()
|
||||
|
||||
val useCase = getUseCase()
|
||||
|
||||
// When
|
||||
val result = useCase(MockTokenLists.emptyGroupedTokenList)
|
||||
|
||||
// Then
|
||||
assertEquals(expectedResult, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when ungrouped list is empty then error should be received`() = runTest {
|
||||
// Given
|
||||
val expectedResult = TokenListSortingError.TokenListIsEmpty.left()
|
||||
|
||||
val useCase = getUseCase()
|
||||
|
||||
// When
|
||||
val result = useCase(MockTokenLists.emptyUngroupedTokenList)
|
||||
val result = useCase(MockTokenLists.emptyTokenList)
|
||||
|
||||
// Then
|
||||
assertEquals(expectedResult, result)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ internal object MockTokenLists {
|
|||
const val isGrouped = false
|
||||
const val isSortedByBalance = false
|
||||
|
||||
val notInitializedTokenList = TokenList.NotInitialized
|
||||
val emptyTokenList = TokenList.Empty
|
||||
|
||||
val emptyGroupedTokenList = TokenList.GroupedByNetwork(
|
||||
groups = emptyList(),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ internal class CryptoCurrenciesIdsResolver {
|
|||
val currenciesStatuses = when (tokenList) {
|
||||
is TokenList.GroupedByNetwork -> tokenList.groups.flatMap { it.currencies }
|
||||
is TokenList.Ungrouped -> tokenList.currencies
|
||||
is TokenList.NotInitialized,
|
||||
is TokenList.Empty,
|
||||
null,
|
||||
-> return emptyList()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ internal fun TokenList.disableSortingByBalance(): TokenList {
|
|||
return when (this) {
|
||||
is TokenList.GroupedByNetwork -> this.copy(sortedBy = SortType.NONE)
|
||||
is TokenList.Ungrouped -> this.copy(sortedBy = SortType.NONE)
|
||||
is TokenList.NotInitialized -> this
|
||||
is TokenList.Empty -> this
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ internal class TokenListToListStateConverter(
|
|||
return when (value) {
|
||||
is TokenList.GroupedByNetwork -> createListState(value)
|
||||
is TokenList.Ungrouped -> createListState(value)
|
||||
is TokenList.NotInitialized -> createEmptyListState()
|
||||
is TokenList.Empty -> createEmptyListState()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ internal class TokenListToContentItemsConverter(
|
|||
|
||||
override fun convert(value: TokenList): WalletTokensListState {
|
||||
return when (value) {
|
||||
is TokenList.NotInitialized -> WalletTokensListState.Loading()
|
||||
is TokenList.Empty -> WalletTokensListState.Empty
|
||||
is TokenList.GroupedByNetwork -> WalletTokensListState.Content(
|
||||
items = value.mapToMultiCurrencyItems(),
|
||||
organizeTokensButton = value.mapToOrganizeTokensButtonState(),
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
if (cacheState != null) {
|
||||
uiState = stateFactory.getStateWithoutDeletedWallet(cacheState, action)
|
||||
|
||||
if (cacheState.isLoadingState()) {
|
||||
if (cacheState.isLoadingOrEmptyState()) {
|
||||
uiState = stateFactory.getStateAndTriggerEvent(
|
||||
state = uiState,
|
||||
event = WalletEvent.ChangeWallet(action.selectedWalletIndex),
|
||||
|
|
@ -509,7 +509,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
pullToRefreshConfig = cacheState.pullToRefreshConfig.copy(isRefreshing = false),
|
||||
)
|
||||
|
||||
if (cacheState.isLoadingState()) {
|
||||
if (cacheState.isLoadingOrEmptyState()) {
|
||||
getContentItemsUpdates(index)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -904,7 +904,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
.hasNonZeroWallets()
|
||||
}
|
||||
is TokenList.Ungrouped -> tokenList.currencies.hasNonZeroWallets()
|
||||
TokenList.NotInitialized -> false
|
||||
is TokenList.Empty -> false
|
||||
}
|
||||
|
||||
if (hasNonZeroWallets) {
|
||||
|
|
@ -984,7 +984,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
.flatMap(NetworkGroup::currencies)
|
||||
}
|
||||
is TokenList.Ungrouped -> tokenList.currencies
|
||||
is TokenList.NotInitialized -> emptyList()
|
||||
is TokenList.Empty -> emptyList()
|
||||
}
|
||||
} else {
|
||||
listOfNotNull(singleWalletCryptoCurrencyStatus)
|
||||
|
|
@ -1033,7 +1033,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun WalletState.isLoadingState(): Boolean {
|
||||
private fun WalletState.isLoadingOrEmptyState(): Boolean {
|
||||
// Check the base components
|
||||
if (this is WalletState.ContentState &&
|
||||
walletsListConfig.wallets[walletsListConfig.selectedWalletIndex] is WalletCardState.Loading
|
||||
|
|
@ -1044,12 +1044,13 @@ internal class WalletViewModel @Inject constructor(
|
|||
// Check the special components
|
||||
return when (this) {
|
||||
is WalletMultiCurrencyState -> {
|
||||
val isTokensEmpty = tokensListState is WalletTokensListState.Empty
|
||||
val hasLoadingTokens = tokensListState is WalletTokensListState.ContentState &&
|
||||
(tokensListState as WalletTokensListState.ContentState).items
|
||||
.filterIsInstance<WalletTokensListState.TokensListItemState.Token>()
|
||||
.any { it.state is TokenItemState.Loading }
|
||||
|
||||
tokensListState is WalletTokensListState.Loading || hasLoadingTokens
|
||||
isTokensEmpty || tokensListState is WalletTokensListState.Loading || hasLoadingTokens
|
||||
}
|
||||
is WalletSingleCurrencyState -> {
|
||||
this is WalletSingleCurrencyState.Content && marketPriceBlockState is MarketPriceBlockState.Loading
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue