Updated on 2026-08-14

This commit is contained in:
Tangem 2024-07-17 14:38:33 +04:00
commit dfd7076c2e
31 changed files with 345 additions and 648 deletions

View file

@ -1,20 +0,0 @@
package com.tangem.feature.wallet.di
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
import com.tangem.feature.wallet.featuretoggle.WalletFeatureToggles
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal object FeatureTogglesModule {
@Provides
@Singleton
fun provideWalletFeatureToggles(featureTogglesManager: FeatureTogglesManager): WalletFeatureToggles {
return WalletFeatureToggles(featureTogglesManager)
}
}

View file

@ -1,11 +0,0 @@
package com.tangem.feature.wallet.featuretoggle
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
internal class WalletFeatureToggles(
private val featureTogglesManager: FeatureTogglesManager,
) {
val isTokenListLceFlowEnabled: Boolean
get() = featureTogglesManager.isFeatureEnabled("TOKEN_LIST_LCE_ENABLED")
}

View file

@ -13,9 +13,7 @@ import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.ToggleTokenListGroupingUseCase
import com.tangem.domain.tokens.ToggleTokenListSortingUseCase
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.tokens.model.TotalFiatBalance
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.feature.wallet.featuretoggle.WalletFeatureToggles
import com.tangem.feature.wallet.presentation.organizetokens.analytics.PortfolioOrganizeTokensAnalyticsEvent
import com.tangem.feature.wallet.presentation.organizetokens.model.OrganizeTokensListState
import com.tangem.feature.wallet.presentation.organizetokens.model.OrganizeTokensState
@ -42,7 +40,6 @@ internal class OrganizeTokensViewModel @Inject constructor(
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val analyticsEventsHandler: AnalyticsEventHandler,
private val walletFeatureToggles: WalletFeatureToggles,
private val dispatchers: CoroutineDispatcherProvider,
savedStateHandle: SavedStateHandle,
) : ViewModel(), DefaultLifecycleObserver, OrganizeTokensIntents {
@ -173,34 +170,21 @@ internal class OrganizeTokensViewModel @Inject constructor(
}
private suspend fun getTokenList(): TokenList? {
return if (walletFeatureToggles.isTokenListLceFlowEnabled) {
val tokenList = getTokenListUseCase.launchLce(userWalletId)
.transform { maybeTokenList ->
val tokenList = maybeTokenList.getOrElse(
ifLoading = { return@transform },
ifError = { error ->
stateHolder.updateStateWithError(error)
val tokenList = getTokenListUseCase.launch(userWalletId)
.transform { maybeTokenList ->
val tokenList = maybeTokenList.getOrElse(
ifLoading = { return@transform },
ifError = { error ->
stateHolder.updateStateWithError(error)
return@transform
},
)
return@transform
},
)
emit(tokenList)
}
tokenList.firstOrNull()
} else {
val maybeTokenList = getTokenListUseCase.launch(userWalletId)
.first { maybeTokenList ->
maybeTokenList.getOrNull()?.totalFiatBalance !is TotalFiatBalance.Loading
}
maybeTokenList.getOrElse { error ->
stateHolder.updateStateWithError(error)
null
emit(tokenList)
}
}
return tokenList.firstOrNull()
}
private fun bootstrapDragAndDropUpdates() {

View file

@ -1,8 +1,8 @@
package com.tangem.feature.wallet.presentation.wallet.domain
import arrow.core.Either
import com.tangem.domain.common.CardTypesResolver
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.core.lce.Lce
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.promo.PromoBanner
import com.tangem.domain.settings.IsReadyToShowRateAppUseCase
@ -23,7 +23,6 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flow
import javax.inject.Inject
import kotlin.collections.count
@ -47,11 +46,11 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
val promoFlow = flow { emit(promoRepository.getOkxPromoBanner()) }
return combine(
flow = getTokenListUseCase.launch(userWallet.walletId).conflate(),
flow2 = isReadyToShowRateAppUseCase().conflate(),
flow3 = isNeedToBackupUseCase(userWallet.walletId).conflate(),
flow4 = shouldShowSwapPromoWalletUseCase().conflate(),
flow5 = promoFlow.conflate(),
flow = getTokenListUseCase.launch(userWallet.walletId),
flow2 = isReadyToShowRateAppUseCase(),
flow3 = isNeedToBackupUseCase(userWallet.walletId),
flow4 = shouldShowSwapPromoWalletUseCase(),
flow5 = promoFlow,
) { maybeTokenList, isReadyToShowRating, isNeedToBackup, shouldShowPromo, promoBanner ->
readyForRateAppNotification = true
@ -113,7 +112,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
private fun MutableList<WalletNotification>.addInformationalNotifications(
cardTypesResolver: CardTypesResolver,
maybeTokenList: Either<TokenListError, TokenList>,
maybeTokenList: Lce<TokenListError, TokenList>,
clickIntents: WalletClickIntents,
) {
addIf(
@ -125,7 +124,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
}
private fun MutableList<WalletNotification>.addMissingAddressesNotification(
maybeTokenList: Either<TokenListError, TokenList>,
maybeTokenList: Lce<TokenListError, TokenList>,
clickIntents: WalletClickIntents,
) {
val currencies = maybeTokenList.getMissingAddressCurrencies()
@ -141,26 +140,23 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
)
}
private fun Either<TokenListError, TokenList>.getMissingAddressCurrencies(): List<CryptoCurrency> {
return fold(
ifLeft = { emptyList() },
ifRight = { tokenList ->
val currencies = when (tokenList) {
is TokenList.GroupedByNetwork -> tokenList.groups.flatMap(NetworkGroup::currencies)
is TokenList.Ungrouped -> tokenList.currencies
is TokenList.Empty -> emptyList()
}
private fun Lce<TokenListError, TokenList>.getMissingAddressCurrencies(): List<CryptoCurrency> {
val tokenList = getOrNull(isPartialContentAccepted = false) ?: return emptyList()
currencies
.filter { it.value is CryptoCurrencyStatus.MissedDerivation }
.map(CryptoCurrencyStatus::currency)
},
)
val currencies = when (tokenList) {
is TokenList.GroupedByNetwork -> tokenList.groups.flatMap(NetworkGroup::currencies)
is TokenList.Ungrouped -> tokenList.currencies
is TokenList.Empty -> emptyList()
}
return currencies
.filter { it.value is CryptoCurrencyStatus.MissedDerivation }
.map(CryptoCurrencyStatus::currency)
}
private fun MutableList<WalletNotification>.addWarningNotifications(
cardTypesResolver: CardTypesResolver,
tokenList: Either<TokenListError, TokenList>,
tokenList: Lce<TokenListError, TokenList>,
isNeedToBackup: Boolean,
clickIntents: WalletClickIntents,
) {
@ -182,19 +178,16 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
)
}
private fun Either<TokenListError, TokenList>.hasUnreachableNetworks(): Boolean {
return fold(
ifLeft = { false },
ifRight = { tokenList ->
val currencies = when (tokenList) {
is TokenList.GroupedByNetwork -> tokenList.groups.flatMap(NetworkGroup::currencies)
is TokenList.Ungrouped -> tokenList.currencies
is TokenList.Empty -> emptyList()
}
private fun Lce<TokenListError, TokenList>.hasUnreachableNetworks(): Boolean {
val tokenList = getOrNull(isPartialContentAccepted = false) ?: return false
currencies.any { it.value is CryptoCurrencyStatus.Unreachable }
},
)
val currencies = when (tokenList) {
is TokenList.GroupedByNetwork -> tokenList.groups.flatMap(NetworkGroup::currencies)
is TokenList.Ungrouped -> tokenList.currencies
is TokenList.Empty -> emptyList()
}
return currencies.any { it.value is CryptoCurrencyStatus.Unreachable }
}
private fun MutableList<WalletNotification>.addRateTheAppNotification(

View file

@ -5,7 +5,6 @@ import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.featuretoggle.WalletFeatureToggles
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarningsFactory
@ -28,7 +27,6 @@ internal class MultiWalletContentLoader(
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory,
private val walletFeatureToggles: WalletFeatureToggles,
private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase,
) : WalletContentLoader(id = userWallet.walletId) {
@ -42,7 +40,6 @@ internal class MultiWalletContentLoader(
walletWithFundsChecker = walletWithFundsChecker,
getTokenListUseCase = getTokenListUseCase,
getSelectedAppCurrencyUseCase = getSelectedAppCurrencyUseCase,
walletFeatureToggles = walletFeatureToggles,
applyTokenListSortingUseCase = applyTokenListSortingUseCase,
runPolkadotAccountHealthCheckUseCase = runPolkadotAccountHealthCheckUseCase,
),

View file

@ -5,7 +5,6 @@ import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.featuretoggle.WalletFeatureToggles
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarningsFactory
@ -26,7 +25,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
private val walletFeatureToggles: WalletFeatureToggles,
private val runPolkadotAccountHealthCheckUseCase: RunPolkadotAccountHealthCheckUseCase,
) {
@ -42,7 +40,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
getMultiWalletWarningsFactory = getMultiWalletWarningsFactory,
walletWarningsAnalyticsSender = walletWarningsAnalyticsSender,
applyTokenListSortingUseCase = applyTokenListSortingUseCase,
walletFeatureToggles = walletFeatureToggles,
runPolkadotAccountHealthCheckUseCase = runPolkadotAccountHealthCheckUseCase,
)
}

View file

@ -3,7 +3,6 @@ package com.tangem.feature.wallet.presentation.wallet.subscribers
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.core.lce.Lce
import com.tangem.domain.core.lce.LceFlow
import com.tangem.domain.core.utils.toLce
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.RunPolkadotAccountHealthCheckUseCase
@ -12,19 +11,16 @@ import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.tokens.model.TotalFiatBalance
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.featuretoggle.WalletFeatureToggles
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.TokenListAnalyticsSender
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents
import kotlinx.coroutines.flow.map
@Suppress("LongParameterList")
internal class MultiWalletTokenListSubscriber(
private val userWallet: UserWallet,
private val getTokenListUseCase: GetTokenListUseCase,
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
private val walletFeatureToggles: WalletFeatureToggles,
stateHolder: WalletStateController,
clickIntents: WalletClickIntents,
tokenListAnalyticsSender: TokenListAnalyticsSender,
@ -42,11 +38,7 @@ internal class MultiWalletTokenListSubscriber(
) {
override fun tokenListFlow(): LceFlow<TokenListError, TokenList> {
return if (walletFeatureToggles.isTokenListLceFlowEnabled) {
getTokenListUseCase.launchLce(userWallet.walletId)
} else {
getTokenListUseCase.launch(userWallet.walletId).map { it.toLce() }
}
return getTokenListUseCase.launch(userWallet.walletId)
}
override suspend fun onTokenListReceived(maybeTokenList: Lce<TokenListError, TokenList>) {