Updated on 2026-08-14

This commit is contained in:
Tangem 2025-04-15 13:15:00 +03:00
commit 784161880d
5 changed files with 44 additions and 29 deletions

View file

@ -146,4 +146,10 @@ sealed class Lce<out E : Any, out C : Any> {
ifContent = { predicate(it) },
ifError = { false },
)
fun onError(action: (error: E) -> Unit): Lce<E, C> {
if (this is Error) action(this.error)
return this
}
}

View file

@ -73,8 +73,6 @@ class CachedCurrenciesStatusesOperations(
): LceFlow<TokenListError, List<CryptoCurrencyStatus>> = lceFlow {
val prevStatuses = MutableStateFlow(value = emptyList<CryptoCurrencyStatus>())
val isUpdating = MutableStateFlow(value = true)
val nonEmptyCurrencies = currenciesFlow.mapNotNull { it.getOrNull() }.firstOrNull()?.toNonEmptyListOrNull()
if (!isFetchingStarted(userWalletId) && nonEmptyCurrencies != null) {
@ -84,7 +82,7 @@ class CachedCurrenciesStatusesOperations(
val (networks, currenciesIds) = getIds(nonEmptyCurrencies)
fetchComponents(userWalletId, networks, currenciesIds, nonEmptyCurrencies)
}
.invokeOnCompletion { isUpdating.value = false }
.invokeOnCompletion { setFetchFinished(userWalletId) }
}
currenciesFlow.flatMapLatest { maybeCurrencies ->
@ -143,14 +141,18 @@ class CachedCurrenciesStatusesOperations(
fetchComponents(userWalletId, networks, currenciesIds, currencies)
}
.invokeOnCompletion { isUpdating.value = false }
.invokeOnCompletion { setFetchFinished(userWalletId) }
}
combine(
flow = getQuotes(currenciesIds),
flow2 = getNetworksStatuses(userWalletId, networks),
flow3 = getYieldBalances(userWalletId, currencies),
flow4 = isUpdating,
flow4 = fetchingState.map {
val state = it[userWalletId] ?: return@map false
!state.isFinished()
},
transform = ::createCurrenciesStatuses,
)
.distinctUntilChanged()
@ -419,20 +421,35 @@ class CachedCurrenciesStatusesOperations(
}
private fun isFetchingStarted(userWalletId: UserWalletId): Boolean {
return fetchingState.value[userWalletId] ?: false
return fetchingState.value[userWalletId]?.let { it.isStarted() || it.isFinished() } ?: false
}
private fun setFetchStarted(userWalletId: UserWalletId) {
fetchingState.update {
it.toMutableMap().apply {
put(key = userWalletId, value = true)
put(key = userWalletId, value = FetchingState.STARTED)
}
}
}
private fun setFetchFinished(userWalletId: UserWalletId) {
fetchingState.update {
it.toMutableMap().apply {
put(key = userWalletId, value = FetchingState.FINISHED)
}
}
}
enum class FetchingState {
STARTED, FINISHED;
fun isStarted() = this == STARTED
fun isFinished() = this == FINISHED
}
companion object {
internal const val RETRY_DELAY = 2000L
private val fetchingState = MutableStateFlow(value = emptyMap<UserWalletId, Boolean>())
private val fetchingState = MutableStateFlow(value = emptyMap<UserWalletId, FetchingState>())
}
}

View file

@ -32,8 +32,6 @@ internal class OrganizeTokensComponent(
override fun Content(modifier: Modifier) {
val uiState by model.uiState.collectAsStateWithLifecycle()
OrganizeTokensScreen(
state = uiState,
)
OrganizeTokensScreen(state = uiState)
}
}

View file

@ -10,11 +10,12 @@ import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.core.utils.getOrElse
import com.tangem.domain.core.lce.Lce
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.ToggleTokenListGroupingUseCase
import com.tangem.domain.tokens.ToggleTokenListSortingUseCase
import com.tangem.domain.tokens.error.TokenListError
import com.tangem.domain.tokens.model.TokenList
import com.tangem.feature.wallet.child.organizetokens.OrganizeTokensComponent
import com.tangem.feature.wallet.presentation.organizetokens.OrganizeTokensIntents
@ -36,13 +37,13 @@ import javax.inject.Inject
@ModelScoped
internal class OrganizeTokensModel @Inject constructor(
paramsContainer: ParamsContainer,
getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
override val dispatchers: CoroutineDispatcherProvider,
private val getTokenListUseCase: GetTokenListUseCase,
private val toggleTokenListGroupingUseCase: ToggleTokenListGroupingUseCase,
private val toggleTokenListSortingUseCase: ToggleTokenListSortingUseCase,
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val analyticsEventsHandler: AnalyticsEventHandler,
) : Model(), OrganizeTokensIntents {
@ -167,21 +168,14 @@ internal class OrganizeTokensModel @Inject constructor(
}
private suspend fun getTokenList(): TokenList? {
val tokenList = getTokenListUseCase.launch(userWalletId)
.transform { maybeTokenList ->
val tokenList = maybeTokenList.getOrElse(
ifLoading = { return@transform },
ifError = { error ->
stateHolder.updateStateWithError(error)
val maybeTokenList = getTokenListUseCase.launch(userWalletId)
.filterNot(Lce<TokenListError, TokenList>::isLoading)
.firstOrNull()
?: return null
return@transform
},
)
emit(tokenList)
}
return tokenList.firstOrNull()
return maybeTokenList
.onError(stateHolder::updateStateWithError)
.getOrNull(isPartialContentAccepted = false)
}
private fun bootstrapDragAndDropUpdates() {

View file

@ -16,8 +16,8 @@ import com.tangem.domain.wallets.models.SeedPhraseNotificationsStatus
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
import com.tangem.domain.wallets.usecase.SeedPhraseNotificationUseCase
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.Flow
@ -179,7 +179,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
}
private fun Lce<TokenListError, TokenList>.getMissingAddressCurrencies(): List<CryptoCurrency> {
val tokenList = getOrNull(isPartialContentAccepted = false) ?: return emptyList()
val tokenList = getOrNull(isPartialContentAccepted = true) ?: return emptyList()
return tokenList
.flattenCurrencies()