Updated on 2026-08-14
This commit is contained in:
parent
03691635a2
commit
e2b489f0b9
20 changed files with 144 additions and 637 deletions
|
|
@ -17,8 +17,6 @@ import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||||
import com.tangem.datasource.api.tangemTech.models.account.toUserTokensResponse
|
import com.tangem.datasource.api.tangemTech.models.account.toUserTokensResponse
|
||||||
import com.tangem.datasource.appcurrency.AppCurrencyResponseStore
|
import com.tangem.datasource.appcurrency.AppCurrencyResponseStore
|
||||||
import com.tangem.datasource.exchangeservice.hotcrypto.HotCryptoResponseStore
|
import com.tangem.datasource.exchangeservice.hotcrypto.HotCryptoResponseStore
|
||||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.card.common.extensions.canHandleBlockchain
|
import com.tangem.domain.card.common.extensions.canHandleBlockchain
|
||||||
import com.tangem.domain.card.common.extensions.canHandleToken
|
import com.tangem.domain.card.common.extensions.canHandleToken
|
||||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||||
|
|
@ -43,7 +41,6 @@ import timber.log.Timber
|
||||||
*
|
*
|
||||||
* @property excludedBlockchains excluded blockchains
|
* @property excludedBlockchains excluded blockchains
|
||||||
* @property hotCryptoResponseStore store of `HotCryptoResponse`
|
* @property hotCryptoResponseStore store of `HotCryptoResponse`
|
||||||
* @property userWalletsStore store of `UserWallet`
|
|
||||||
* @property tangemTechApi tangem tech api
|
* @property tangemTechApi tangem tech api
|
||||||
* @property appCurrencyResponseStore store of current app currency
|
* @property appCurrencyResponseStore store of current app currency
|
||||||
* @property dispatchers dispatchers
|
* @property dispatchers dispatchers
|
||||||
|
|
@ -59,8 +56,6 @@ internal class DefaultHotCryptoRepository(
|
||||||
private val userWalletsListRepository: UserWalletsListRepository,
|
private val userWalletsListRepository: UserWalletsListRepository,
|
||||||
private val tangemTechApi: TangemTechApi,
|
private val tangemTechApi: TangemTechApi,
|
||||||
private val appCurrencyResponseStore: AppCurrencyResponseStore,
|
private val appCurrencyResponseStore: AppCurrencyResponseStore,
|
||||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
private val userTokensResponseStore: UserTokensResponseStore,
|
|
||||||
private val walletAccountsFetcher: WalletAccountsFetcher,
|
private val walletAccountsFetcher: WalletAccountsFetcher,
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||||
|
|
@ -106,12 +101,8 @@ internal class DefaultHotCryptoRepository(
|
||||||
private fun getWalletsWithTokensFlow(): Flow<Map<UserWallet, List<UserTokensResponse.Token>>> {
|
private fun getWalletsWithTokensFlow(): Flow<Map<UserWallet, List<UserTokensResponse.Token>>> {
|
||||||
return userWalletsListRepository.loadAndGet().flatMapLatest { userWallets ->
|
return userWalletsListRepository.loadAndGet().flatMapLatest { userWallets ->
|
||||||
val flows = userWallets.map { userWallet ->
|
val flows = userWallets.map { userWallet ->
|
||||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
walletAccountsFetcher.get(userWalletId = userWallet.walletId).map { it.toUserTokensResponse() }
|
||||||
walletAccountsFetcher.get(userWalletId = userWallet.walletId).map { it.toUserTokensResponse() }
|
.map { userWallet to it.tokens }
|
||||||
} else {
|
|
||||||
userTokensResponseStore.get(userWalletId = userWallet.walletId)
|
|
||||||
}
|
|
||||||
.map { userWallet to it?.tokens.orEmpty() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
combine(flows) { it.toMap() }
|
combine(flows) { it.toMap() }
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,6 @@ import com.tangem.datasource.local.onramp.quotes.OnrampQuotesStore
|
||||||
import com.tangem.datasource.local.onramp.sepa.OnrampCurrentCountryByIPStore
|
import com.tangem.datasource.local.onramp.sepa.OnrampCurrentCountryByIPStore
|
||||||
import com.tangem.datasource.local.onramp.sepa.OnrampSepaAvailabilityStore
|
import com.tangem.datasource.local.onramp.sepa.OnrampSepaAvailabilityStore
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||||
import com.tangem.domain.onramp.repositories.*
|
import com.tangem.domain.onramp.repositories.*
|
||||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||||
|
|
@ -110,8 +108,6 @@ internal object OnrampDataModule {
|
||||||
appCurrencyResponseStore: AppCurrencyResponseStore,
|
appCurrencyResponseStore: AppCurrencyResponseStore,
|
||||||
dispatchers: CoroutineDispatcherProvider,
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
analyticsEventHandler: AnalyticsEventHandler,
|
analyticsEventHandler: AnalyticsEventHandler,
|
||||||
userTokensResponseStore: UserTokensResponseStore,
|
|
||||||
accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
walletAccountsFetcher: WalletAccountsFetcher,
|
walletAccountsFetcher: WalletAccountsFetcher,
|
||||||
): HotCryptoRepository {
|
): HotCryptoRepository {
|
||||||
return DefaultHotCryptoRepository(
|
return DefaultHotCryptoRepository(
|
||||||
|
|
@ -122,8 +118,6 @@ internal object OnrampDataModule {
|
||||||
appCurrencyResponseStore = appCurrencyResponseStore,
|
appCurrencyResponseStore = appCurrencyResponseStore,
|
||||||
dispatchers = dispatchers,
|
dispatchers = dispatchers,
|
||||||
analyticsEventHandler = analyticsEventHandler,
|
analyticsEventHandler = analyticsEventHandler,
|
||||||
userTokensResponseStore = userTokensResponseStore,
|
|
||||||
accountsFeatureToggles = accountsFeatureToggles,
|
|
||||||
walletAccountsFetcher = walletAccountsFetcher,
|
walletAccountsFetcher = walletAccountsFetcher,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import com.tangem.data.walletconnect.utils.WcNetworksConverter
|
||||||
import com.tangem.data.walletconnect.utils.WcScope
|
import com.tangem.data.walletconnect.utils.WcScope
|
||||||
import com.tangem.datasource.di.SdkMoshi
|
import com.tangem.datasource.di.SdkMoshi
|
||||||
import com.tangem.datasource.local.walletconnect.WalletConnectStore
|
import com.tangem.datasource.local.walletconnect.WalletConnectStore
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||||
import com.tangem.domain.account.supplier.MultiAccountListSupplier
|
import com.tangem.domain.account.supplier.MultiAccountListSupplier
|
||||||
import com.tangem.domain.account.supplier.SingleAccountSupplier
|
import com.tangem.domain.account.supplier.SingleAccountSupplier
|
||||||
|
|
@ -95,7 +94,6 @@ internal object WalletConnectDataModule {
|
||||||
getWallets: GetWalletsUseCase,
|
getWallets: GetWalletsUseCase,
|
||||||
wcNetworksConverter: WcNetworksConverter,
|
wcNetworksConverter: WcNetworksConverter,
|
||||||
analytics: AnalyticsEventHandler,
|
analytics: AnalyticsEventHandler,
|
||||||
accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
wcScope: WcScope,
|
wcScope: WcScope,
|
||||||
): DefaultWcSessionsManager {
|
): DefaultWcSessionsManager {
|
||||||
return DefaultWcSessionsManager(
|
return DefaultWcSessionsManager(
|
||||||
|
|
@ -104,7 +102,6 @@ internal object WalletConnectDataModule {
|
||||||
getWallets = getWallets,
|
getWallets = getWallets,
|
||||||
wcNetworksConverter = wcNetworksConverter,
|
wcNetworksConverter = wcNetworksConverter,
|
||||||
analytics = analytics,
|
analytics = analytics,
|
||||||
accountsFeatureToggles = accountsFeatureToggles,
|
|
||||||
scope = wcScope,
|
scope = wcScope,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import com.reown.walletkit.client.Wallet
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
import com.tangem.data.walletconnect.utils.WC_TAG
|
import com.tangem.data.walletconnect.utils.WC_TAG
|
||||||
import com.tangem.data.walletconnect.utils.getDappOriginUrl
|
import com.tangem.data.walletconnect.utils.getDappOriginUrl
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.blockaid.BlockAidVerifier
|
import com.tangem.domain.blockaid.BlockAidVerifier
|
||||||
import com.tangem.domain.walletconnect.WcAnalyticEvents
|
import com.tangem.domain.walletconnect.WcAnalyticEvents
|
||||||
import com.tangem.domain.walletconnect.model.*
|
import com.tangem.domain.walletconnect.model.*
|
||||||
|
|
@ -35,7 +34,6 @@ internal class DefaultWcPairUseCase @AssistedInject constructor(
|
||||||
private val sdkDelegate: WcPairSdkDelegate,
|
private val sdkDelegate: WcPairSdkDelegate,
|
||||||
private val blockAidVerifier: BlockAidVerifier,
|
private val blockAidVerifier: BlockAidVerifier,
|
||||||
private val analytics: AnalyticsEventHandler,
|
private val analytics: AnalyticsEventHandler,
|
||||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
@Assisted private val pairRequest: WcPairRequest,
|
@Assisted private val pairRequest: WcPairRequest,
|
||||||
) : WcPairUseCase {
|
) : WcPairUseCase {
|
||||||
|
|
||||||
|
|
@ -128,7 +126,7 @@ internal class DefaultWcPairUseCase @AssistedInject constructor(
|
||||||
pendingSessionForSave = pendingSessionForSave,
|
pendingSessionForSave = pendingSessionForSave,
|
||||||
sessionForApprove = sessionForApprove,
|
sessionForApprove = sessionForApprove,
|
||||||
sdkSessionProposal = sdkSessionProposal,
|
sdkSessionProposal = sdkSessionProposal,
|
||||||
).map { settledSession ->
|
).map { _ ->
|
||||||
analytics.send(
|
analytics.send(
|
||||||
WcAnalyticEvents.DAppConnected(
|
WcAnalyticEvents.DAppConnected(
|
||||||
sessionProposal = proposalState.dAppSession,
|
sessionProposal = proposalState.dAppSession,
|
||||||
|
|
@ -198,11 +196,7 @@ internal class DefaultWcPairUseCase @AssistedInject constructor(
|
||||||
verifyContext: Wallet.Model.VerifyContext,
|
verifyContext: Wallet.Model.VerifyContext,
|
||||||
): Either<WcPairError, WcPairState.Proposal> = runCatching {
|
): Either<WcPairError, WcPairState.Proposal> = runCatching {
|
||||||
val proposalNetwork = associateNetworksDelegate.associate(sessionProposal)
|
val proposalNetwork = associateNetworksDelegate.associate(sessionProposal)
|
||||||
val proposalAccountNetwork = if (accountsFeatureToggles.isFeatureEnabled) {
|
val proposalAccountNetwork = associateNetworksDelegate.associateAccounts(sessionProposal)
|
||||||
associateNetworksDelegate.associateAccounts(sessionProposal)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
val verificationInfo = when {
|
val verificationInfo = when {
|
||||||
verifyContext.validation == Wallet.Model.Validation.INVALID -> CheckDAppResult.UNSAFE
|
verifyContext.validation == Wallet.Model.Validation.INVALID -> CheckDAppResult.UNSAFE
|
||||||
verifyContext.isScam == true -> CheckDAppResult.UNSAFE
|
verifyContext.isScam == true -> CheckDAppResult.UNSAFE
|
||||||
|
|
@ -211,7 +205,7 @@ internal class DefaultWcPairUseCase @AssistedInject constructor(
|
||||||
CheckDAppResult.FAILED_TO_VERIFY
|
CheckDAppResult.FAILED_TO_VERIFY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val requestedNetworks = (proposalAccountNetwork ?: proposalNetwork)
|
val requestedNetworks = proposalAccountNetwork
|
||||||
.values.map { it.available.plus(it.required) }.flatten().toSet()
|
.values.map { it.available.plus(it.required) }.flatten().toSet()
|
||||||
analytics.send(
|
analytics.send(
|
||||||
WcAnalyticEvents.PairRequested(
|
WcAnalyticEvents.PairRequested(
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import com.reown.walletkit.client.WalletKit
|
||||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||||
import com.tangem.data.walletconnect.utils.*
|
import com.tangem.data.walletconnect.utils.*
|
||||||
import com.tangem.datasource.local.walletconnect.WalletConnectStore
|
import com.tangem.datasource.local.walletconnect.WalletConnectStore
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.models.account.Account
|
import com.tangem.domain.models.account.Account
|
||||||
import com.tangem.domain.models.account.AccountId
|
import com.tangem.domain.models.account.AccountId
|
||||||
import com.tangem.domain.models.wallet.UserWallet
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
|
|
@ -34,7 +33,6 @@ internal class DefaultWcSessionsManager(
|
||||||
private val dispatchers: CoroutineDispatcherProvider,
|
private val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val wcNetworksConverter: WcNetworksConverter,
|
private val wcNetworksConverter: WcNetworksConverter,
|
||||||
private val analytics: AnalyticsEventHandler,
|
private val analytics: AnalyticsEventHandler,
|
||||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
private val scope: WcScope,
|
private val scope: WcScope,
|
||||||
) : WcSessionsManager, WcSdkObserver {
|
) : WcSessionsManager, WcSdkObserver {
|
||||||
|
|
||||||
|
|
@ -57,7 +55,6 @@ internal class DefaultWcSessionsManager(
|
||||||
.flowOn(dispatchers.io)
|
.flowOn(dispatchers.io)
|
||||||
|
|
||||||
private suspend fun migrateToAccountSession(inStore: Set<WcSessionDTO>): Boolean {
|
private suspend fun migrateToAccountSession(inStore: Set<WcSessionDTO>): Boolean {
|
||||||
if (!accountsFeatureToggles.isFeatureEnabled) return false
|
|
||||||
if (oneTimeMigration.value) return false
|
if (oneTimeMigration.value) return false
|
||||||
|
|
||||||
var someMigrated = false
|
var someMigrated = false
|
||||||
|
|
@ -118,9 +115,7 @@ internal class DefaultWcSessionsManager(
|
||||||
val wallet = wallets.find { it.walletId == storeSession.walletId } ?: return@mapNotNull null
|
val wallet = wallets.find { it.walletId == storeSession.walletId } ?: return@mapNotNull null
|
||||||
val sdkSession = inSdk.find { it.topic == storeSession.topic } ?: return@mapNotNull null
|
val sdkSession = inSdk.find { it.topic == storeSession.topic } ?: return@mapNotNull null
|
||||||
val account = storeSession.accountId?.let { wcNetworksConverter.getAccount(it) } as? Account.CryptoPortfolio
|
val account = storeSession.accountId?.let { wcNetworksConverter.getAccount(it) } as? Account.CryptoPortfolio
|
||||||
if (accountsFeatureToggles.isFeatureEnabled && account == null) {
|
?: return@mapNotNull null
|
||||||
return@mapNotNull null
|
|
||||||
}
|
|
||||||
val networks = wcNetworksConverter.findWalletNetworks(wallet, account, sdkSession)
|
val networks = wcNetworksConverter.findWalletNetworks(wallet, account, sdkSession)
|
||||||
val originUrl = storeSession.url ?: sdkSession.metaData?.url ?: ""
|
val originUrl = storeSession.url ?: sdkSession.metaData?.url ?: ""
|
||||||
WcSession(
|
WcSession(
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import com.tangem.data.walletconnect.pair.CaipNamespaceDelegate
|
||||||
import com.tangem.data.walletconnect.pair.DefaultWcPairUseCase
|
import com.tangem.data.walletconnect.pair.DefaultWcPairUseCase
|
||||||
import com.tangem.data.walletconnect.pair.WcPairSdkDelegate
|
import com.tangem.data.walletconnect.pair.WcPairSdkDelegate
|
||||||
import com.tangem.data.walletconnect.utils.WcSdkSessionConverter
|
import com.tangem.data.walletconnect.utils.WcSdkSessionConverter
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.blockaid.BlockAidVerifier
|
import com.tangem.domain.blockaid.BlockAidVerifier
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import com.tangem.domain.walletconnect.model.WcPairError
|
import com.tangem.domain.walletconnect.model.WcPairError
|
||||||
|
|
@ -37,7 +36,6 @@ internal class DefaultWcPairUseCaseTest {
|
||||||
private val analytics: AnalyticsEventHandler = mockk<AnalyticsEventHandler>(relaxed = true)
|
private val analytics: AnalyticsEventHandler = mockk<AnalyticsEventHandler>(relaxed = true)
|
||||||
private val sdkDelegate: WcPairSdkDelegate = mockk<WcPairSdkDelegate>()
|
private val sdkDelegate: WcPairSdkDelegate = mockk<WcPairSdkDelegate>()
|
||||||
private val blockAidVerifier: BlockAidVerifier = mockk<BlockAidVerifier>()
|
private val blockAidVerifier: BlockAidVerifier = mockk<BlockAidVerifier>()
|
||||||
private val accountsFeatureToggles = mockk<AccountsFeatureToggles>()
|
|
||||||
|
|
||||||
private val url = "testUrl"
|
private val url = "testUrl"
|
||||||
private val source = WcPairRequest.Source.QR
|
private val source = WcPairRequest.Source.QR
|
||||||
|
|
@ -117,14 +115,13 @@ internal class DefaultWcPairUseCaseTest {
|
||||||
sdkDelegate = sdkDelegate,
|
sdkDelegate = sdkDelegate,
|
||||||
blockAidVerifier = blockAidVerifier,
|
blockAidVerifier = blockAidVerifier,
|
||||||
analytics = analytics,
|
analytics = analytics,
|
||||||
accountsFeatureToggles = accountsFeatureToggles,
|
|
||||||
pairRequest = WcPairRequest(userWalletId = UserWalletId(""), uri = url, source = source),
|
pairRequest = WcPairRequest(userWalletId = UserWalletId(""), uri = url, source = source),
|
||||||
)
|
)
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
coEvery { associateNetworksDelegate.associate(sdkProposal) } returns mapOf()
|
coEvery { associateNetworksDelegate.associate(sdkProposal) } returns mapOf()
|
||||||
coEvery { accountsFeatureToggles.isFeatureEnabled } returns false
|
coEvery { associateNetworksDelegate.associateAccounts(sdkProposal) } returns mapOf()
|
||||||
coEvery {
|
coEvery {
|
||||||
caipNamespaceDelegate.associate(
|
caipNamespaceDelegate.associate(
|
||||||
sessionProposal = sdkProposal,
|
sessionProposal = sdkProposal,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" ?>
|
|
||||||
<SmellBaseline>
|
|
||||||
<ManuallySuppressedIssues/>
|
|
||||||
<CurrentIssues/>
|
|
||||||
</SmellBaseline>
|
|
||||||
|
|
@ -31,7 +31,6 @@ import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.features.account.PortfolioSelectorComponent
|
import com.tangem.features.account.PortfolioSelectorComponent
|
||||||
import com.tangem.features.onramp.hottokens.model.HotCryptoModel
|
import com.tangem.features.onramp.hottokens.model.HotCryptoModel
|
||||||
import com.tangem.features.onramp.hottokens.portfolio.OnrampAddToPortfolioComponent
|
import com.tangem.features.onramp.hottokens.portfolio.OnrampAddToPortfolioComponent
|
||||||
|
|
@ -48,38 +47,29 @@ internal class DefaultHotCryptoComponent @AssistedInject constructor(
|
||||||
@Assisted context: AppComponentContext,
|
@Assisted context: AppComponentContext,
|
||||||
@Assisted private val params: HotCryptoComponent.Params,
|
@Assisted private val params: HotCryptoComponent.Params,
|
||||||
private val onrampAddToPortfolioComponentFactory: OnrampAddToPortfolioComponent.Factory,
|
private val onrampAddToPortfolioComponentFactory: OnrampAddToPortfolioComponent.Factory,
|
||||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
portfolioSelectorComponentFactory: PortfolioSelectorComponent.Factory,
|
portfolioSelectorComponentFactory: PortfolioSelectorComponent.Factory,
|
||||||
addTokenComponentFactory: OnrampAddTokenComponent.Factory,
|
addTokenComponentFactory: OnrampAddTokenComponent.Factory,
|
||||||
) : HotCryptoComponent, AppComponentContext by context {
|
) : HotCryptoComponent, AppComponentContext by context {
|
||||||
|
|
||||||
private val model: HotCryptoModel = getOrCreateModel(params)
|
private val model: HotCryptoModel = getOrCreateModel(params)
|
||||||
|
|
||||||
private val portfolioSelectorComponent: PortfolioSelectorComponent? by lazy {
|
private val portfolioSelectorComponent: PortfolioSelectorComponent by lazy {
|
||||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
portfolioSelectorComponentFactory.create(
|
||||||
portfolioSelectorComponentFactory.create(
|
context = child("portfolioSelectorComponent"),
|
||||||
context = child("portfolioSelectorComponent"),
|
params = PortfolioSelectorComponent.Params(
|
||||||
params = PortfolioSelectorComponent.Params(
|
portfolioFetcher = model.portfolioFetcher,
|
||||||
portfolioFetcher = requireNotNull(model.portfolioFetcher),
|
controller = model.portfolioSelectorController,
|
||||||
controller = model.portfolioSelectorController,
|
),
|
||||||
),
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private val addTokenComponent: OnrampAddTokenComponent? by lazy {
|
private val addTokenComponent: OnrampAddTokenComponent by lazy {
|
||||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
addTokenComponentFactory.create(
|
||||||
addTokenComponentFactory.create(
|
context = child("addTokenComponent"),
|
||||||
context = child("addTokenComponent"),
|
params = OnrampAddTokenComponent.Params(
|
||||||
params = OnrampAddTokenComponent.Params(
|
callbacks = model,
|
||||||
callbacks = model,
|
tokenToAdd = model.hotCryptoToAddDataFlow,
|
||||||
tokenToAdd = model.hotCryptoToAddDataFlow,
|
),
|
||||||
),
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val bottomSheetSlot = childSlot(
|
private val bottomSheetSlot = childSlot(
|
||||||
|
|
@ -106,9 +96,7 @@ internal class DefaultHotCryptoComponent @AssistedInject constructor(
|
||||||
HotCrypto(state, modifier)
|
HotCrypto(state, modifier)
|
||||||
|
|
||||||
bottomSheet.child?.instance?.BottomSheet()
|
bottomSheet.child?.instance?.BottomSheet()
|
||||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
AddHotCryptoBottomSheet()
|
||||||
AddHotCryptoBottomSheet()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -133,7 +121,7 @@ internal class DefaultHotCryptoComponent @AssistedInject constructor(
|
||||||
content = TangemBottomSheetConfigContent.Empty,
|
content = TangemBottomSheetConfigContent.Empty,
|
||||||
),
|
),
|
||||||
containerColor = TangemTheme.colors.background.tertiary,
|
containerColor = TangemTheme.colors.background.tertiary,
|
||||||
title = { state ->
|
title = { _ ->
|
||||||
AnimatedContent(targetState = contentStack.value) { stack ->
|
AnimatedContent(targetState = contentStack.value) { stack ->
|
||||||
BottomSheetTitle(
|
BottomSheetTitle(
|
||||||
stack = stack,
|
stack = stack,
|
||||||
|
|
@ -142,7 +130,7 @@ internal class DefaultHotCryptoComponent @AssistedInject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
content = { state ->
|
content = { _ ->
|
||||||
AnimatedContent(targetState = contentStack.value) { stack ->
|
AnimatedContent(targetState = contentStack.value) { stack ->
|
||||||
val paddingModifier = Modifier.padding(
|
val paddingModifier = Modifier.padding(
|
||||||
start = 16.dp,
|
start = 16.dp,
|
||||||
|
|
@ -221,8 +209,8 @@ internal class DefaultHotCryptoComponent @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun contentChild(config: OnrampAddTokenRoute): ComposableContentComponent = when (config) {
|
private fun contentChild(config: OnrampAddTokenRoute): ComposableContentComponent = when (config) {
|
||||||
OnrampAddTokenRoute.AddToken -> requireNotNull(addTokenComponent)
|
OnrampAddTokenRoute.AddToken -> addTokenComponent
|
||||||
OnrampAddTokenRoute.PortfolioSelector -> requireNotNull(portfolioSelectorComponent)
|
OnrampAddTokenRoute.PortfolioSelector -> portfolioSelectorComponent
|
||||||
OnrampAddTokenRoute.Empty -> ComposableContentComponent.EMPTY
|
OnrampAddTokenRoute.Empty -> ComposableContentComponent.EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package com.tangem.features.onramp.hottokens.model
|
package com.tangem.features.onramp.hottokens.model
|
||||||
|
|
||||||
import arrow.core.getOrElse
|
|
||||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||||
import com.arkivanov.decompose.router.slot.activate
|
|
||||||
import com.arkivanov.decompose.router.slot.dismiss
|
|
||||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||||
import com.arkivanov.decompose.router.stack.popToFirst
|
import com.arkivanov.decompose.router.stack.popToFirst
|
||||||
import com.arkivanov.decompose.router.stack.pushNew
|
import com.arkivanov.decompose.router.stack.pushNew
|
||||||
|
|
@ -13,7 +10,6 @@ import com.tangem.blockchainsdk.utils.toCoinId
|
||||||
import com.tangem.core.decompose.di.ModelScoped
|
import com.tangem.core.decompose.di.ModelScoped
|
||||||
import com.tangem.core.decompose.model.Model
|
import com.tangem.core.decompose.model.Model
|
||||||
import com.tangem.core.decompose.model.ParamsContainer
|
import com.tangem.core.decompose.model.ParamsContainer
|
||||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
|
||||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.data.common.currency.getCoinId
|
import com.tangem.data.common.currency.getCoinId
|
||||||
|
|
@ -21,17 +17,11 @@ import com.tangem.data.common.currency.getTokenId
|
||||||
import com.tangem.data.common.currency.isCustomCoin
|
import com.tangem.data.common.currency.isCustomCoin
|
||||||
import com.tangem.data.common.currency.isCustomToken
|
import com.tangem.data.common.currency.isCustomToken
|
||||||
import com.tangem.data.common.network.NetworkFactory
|
import com.tangem.data.common.network.NetworkFactory
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
|
||||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
|
||||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
|
||||||
import com.tangem.domain.models.account.AccountStatus
|
import com.tangem.domain.models.account.AccountStatus
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.models.wallet.UserWallet
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
import com.tangem.domain.onramp.GetHotCryptoUseCase
|
|
||||||
import com.tangem.domain.onramp.model.HotCryptoCurrency
|
import com.tangem.domain.onramp.model.HotCryptoCurrency
|
||||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
|
||||||
import com.tangem.features.account.PortfolioFetcher
|
import com.tangem.features.account.PortfolioFetcher
|
||||||
import com.tangem.features.account.PortfolioSelectorController
|
import com.tangem.features.account.PortfolioSelectorController
|
||||||
import com.tangem.features.onramp.hottokens.HotCryptoComponent
|
import com.tangem.features.onramp.hottokens.HotCryptoComponent
|
||||||
|
|
@ -51,7 +41,6 @@ import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.channels.BufferOverflow
|
import kotlinx.coroutines.channels.BufferOverflow
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
@ -59,9 +48,6 @@ import javax.inject.Inject
|
||||||
* Hot crypto model
|
* Hot crypto model
|
||||||
*
|
*
|
||||||
* @param paramsContainer params container
|
* @param paramsContainer params container
|
||||||
* @param getHotCryptoUseCase use case for getting hot crypto
|
|
||||||
* @param getSelectedAppCurrencyUseCase use case for getting selected app currency
|
|
||||||
* @property getCryptoCurrencyStatusSyncUseCase use case for getting crypto currency status by id
|
|
||||||
* @property dispatchers dispatchers
|
* @property dispatchers dispatchers
|
||||||
*
|
*
|
||||||
[REDACTED_AUTHOR]
|
[REDACTED_AUTHOR]
|
||||||
|
|
@ -70,22 +56,17 @@ import javax.inject.Inject
|
||||||
@ModelScoped
|
@ModelScoped
|
||||||
internal class HotCryptoModel @Inject constructor(
|
internal class HotCryptoModel @Inject constructor(
|
||||||
paramsContainer: ParamsContainer,
|
paramsContainer: ParamsContainer,
|
||||||
private val getHotCryptoUseCase: GetHotCryptoUseCase,
|
|
||||||
private val callbackDelegate: HotCryptoModelCallbackDelegate,
|
private val callbackDelegate: HotCryptoModelCallbackDelegate,
|
||||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
|
||||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val hotCryptoPortfolioDataLoader: HotCryptoPortfolioDataLoader,
|
private val hotCryptoPortfolioDataLoader: HotCryptoPortfolioDataLoader,
|
||||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
|
||||||
val portfolioSelectorController: PortfolioSelectorController,
|
val portfolioSelectorController: PortfolioSelectorController,
|
||||||
private val networkFactory: NetworkFactory,
|
private val networkFactory: NetworkFactory,
|
||||||
private val portfolioFetcherFactory: PortfolioFetcher.Factory,
|
portfolioFetcherFactory: PortfolioFetcher.Factory,
|
||||||
) : Model(), OnrampAddTokenComponent.Callbacks by callbackDelegate {
|
) : Model(), OnrampAddTokenComponent.Callbacks by callbackDelegate {
|
||||||
|
|
||||||
val bottomSheetNavigation: SlotNavigation<OnrampAddToPortfolioBSConfig> = SlotNavigation()
|
val bottomSheetNavigation: SlotNavigation<OnrampAddToPortfolioBSConfig> = SlotNavigation()
|
||||||
|
|
||||||
val portfolioFetcher: PortfolioFetcher?
|
val portfolioFetcher: PortfolioFetcher
|
||||||
val bottomSheetNavigationV2 = StackNavigation<OnrampAddTokenRoute>()
|
val bottomSheetNavigationV2 = StackNavigation<OnrampAddTokenRoute>()
|
||||||
private val addHotCryptoJob = JobHolder()
|
private val addHotCryptoJob = JobHolder()
|
||||||
val hotCryptoToAddDataFlow: MutableSharedFlow<AddHotCryptoData> = MutableSharedFlow(
|
val hotCryptoToAddDataFlow: MutableSharedFlow<AddHotCryptoData> = MutableSharedFlow(
|
||||||
|
|
@ -99,53 +80,30 @@ internal class HotCryptoModel @Inject constructor(
|
||||||
private val params: HotCryptoComponent.Params = paramsContainer.require()
|
private val params: HotCryptoComponent.Params = paramsContainer.require()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
portfolioFetcher = portfolioFetcherFactory.create(
|
||||||
portfolioFetcher = portfolioFetcherFactory.create(
|
mode = PortfolioFetcher.Mode.Wallet(params.userWalletId),
|
||||||
mode = PortfolioFetcher.Mode.Wallet(params.userWalletId),
|
scope = modelScope,
|
||||||
scope = modelScope,
|
)
|
||||||
)
|
combineData()
|
||||||
combineData()
|
|
||||||
} else {
|
|
||||||
portfolioFetcher = null
|
|
||||||
combineDataOld()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun combineData() {
|
private fun combineData() {
|
||||||
combine(
|
hotCryptoPortfolioDataLoader.loadPortfolioData(params.userWalletId)
|
||||||
flow = hotCryptoPortfolioDataLoader.loadPortfolioData(params.userWalletId),
|
.map { data ->
|
||||||
flow2 = isAccountsModeEnabledUseCase.invoke(),
|
|
||||||
transform = { data, isAccountMode ->
|
|
||||||
HotTokenItemStateConverter(
|
HotTokenItemStateConverter(
|
||||||
appCurrency = data.appCurrency,
|
appCurrency = data.appCurrency,
|
||||||
onItemClick = { tokenItemState, hotCryptoCurrency ->
|
onItemClick = { _, hotCryptoCurrency ->
|
||||||
startAddTokenFlow(currency = hotCryptoCurrency, hotCryptoPortfolioData = data)
|
startAddTokenFlow(currency = hotCryptoCurrency, hotCryptoPortfolioData = data)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.convertList(data.allHotCrypto)
|
.convertList(data.allHotCrypto)
|
||||||
.map(TokensListItemUM::Token)
|
.map(TokensListItemUM::Token)
|
||||||
},
|
}
|
||||||
)
|
|
||||||
.onEach { items -> state.update { HotCryptoUM(items = it.buildItems(items)) } }
|
.onEach { items -> state.update { HotCryptoUM(items = it.buildItems(items)) } }
|
||||||
.flowOn(dispatchers.default)
|
.flowOn(dispatchers.default)
|
||||||
.launchIn(modelScope)
|
.launchIn(modelScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun combineDataOld() {
|
|
||||||
combine(
|
|
||||||
flow = getSelectedAppCurrencyUseCase().map { it.getOrElse { AppCurrency.Default } },
|
|
||||||
flow2 = getHotCryptoUseCase(params.userWalletId),
|
|
||||||
) { appCurrency, currencies ->
|
|
||||||
HotTokenItemStateConverter(appCurrency = appCurrency, onItemClick = ::onTokenClick)
|
|
||||||
.convertList(currencies)
|
|
||||||
.map(TokensListItemUM::Token)
|
|
||||||
}
|
|
||||||
.onEach { items ->
|
|
||||||
state.update { HotCryptoUM(items = it.buildItems(items)) }
|
|
||||||
}
|
|
||||||
.launchIn(modelScope)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun HotCryptoUM.buildItems(items: List<TokensListItemUM.Token>): ImmutableList<TokensListItemUM> =
|
private fun HotCryptoUM.buildItems(items: List<TokensListItemUM.Token>): ImmutableList<TokensListItemUM> =
|
||||||
buildList {
|
buildList {
|
||||||
if (items.isNotEmpty()) {
|
if (items.isNotEmpty()) {
|
||||||
|
|
@ -163,16 +121,6 @@ internal class HotCryptoModel @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onTokenClick(tokenItemState: TokenItemState, currency: HotCryptoCurrency) {
|
|
||||||
bottomSheetNavigation.activate(
|
|
||||||
configuration = OnrampAddToPortfolioBSConfig.AddToPortfolio(
|
|
||||||
cryptoCurrency = currency.cryptoCurrency,
|
|
||||||
currencyIconState = tokenItemState.iconState,
|
|
||||||
onSuccessAdding = ::onSuccessAdding,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startAddTokenFlow(currency: HotCryptoCurrency, hotCryptoPortfolioData: HotCryptoPortfolioData) {
|
private fun startAddTokenFlow(currency: HotCryptoCurrency, hotCryptoPortfolioData: HotCryptoPortfolioData) {
|
||||||
hotCryptoToAddDataFlow.resetReplayCache()
|
hotCryptoToAddDataFlow.resetReplayCache()
|
||||||
fun closeNavigationFlow() = bottomSheetNavigationV2.replaceAll(OnrampAddTokenRoute.Empty)
|
fun closeNavigationFlow() = bottomSheetNavigationV2.replaceAll(OnrampAddTokenRoute.Empty)
|
||||||
|
|
@ -200,7 +148,7 @@ internal class HotCryptoModel @Inject constructor(
|
||||||
bottomSheetNavigationV2.replaceAll(OnrampAddTokenRoute.PortfolioSelector)
|
bottomSheetNavigationV2.replaceAll(OnrampAddTokenRoute.PortfolioSelector)
|
||||||
|
|
||||||
val tokenToAddStateFlow = portfolioSelectorController
|
val tokenToAddStateFlow = portfolioSelectorController
|
||||||
.selectedAccountWithData(requireNotNull(portfolioFetcher))
|
.selectedAccountWithData(portfolioFetcher)
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
.map { (_, selectedAccount) ->
|
.map { (_, selectedAccount) ->
|
||||||
val cryptoCurrency = updateCryptoCurrency(
|
val cryptoCurrency = updateCryptoCurrency(
|
||||||
|
|
@ -246,20 +194,6 @@ internal class HotCryptoModel @Inject constructor(
|
||||||
.saveIn(addHotCryptoJob)
|
.saveIn(addHotCryptoJob)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onSuccessAdding(id: CryptoCurrency.ID) {
|
|
||||||
modelScope.launch {
|
|
||||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWalletSync(
|
|
||||||
userWalletId = params.userWalletId,
|
|
||||||
cryptoCurrencyId = id,
|
|
||||||
)
|
|
||||||
.onRight { status ->
|
|
||||||
bottomSheetNavigation.dismiss()
|
|
||||||
params.onTokenClick(status)
|
|
||||||
}
|
|
||||||
.onLeft { Timber.d("Unable to get CryptoCurrencyStatus[$id]: $it") }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupPortfolioSelector(hotCrypto: HotCryptoCurrency, hotCryptoPortfolioData: HotCryptoPortfolioData) {
|
private fun setupPortfolioSelector(hotCrypto: HotCryptoCurrency, hotCryptoPortfolioData: HotCryptoPortfolioData) {
|
||||||
portfolioSelectorController.selectAccount(null)
|
portfolioSelectorController.selectAccount(null)
|
||||||
portfolioSelectorController.isEnabled.value = isEnabled@{ _, accountStatus ->
|
portfolioSelectorController.isEnabled.value = isEnabled@{ _, accountStatus ->
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,64 @@
|
||||||
package com.tangem.features.onramp.swap.availablepairs.entity.transformers
|
package com.tangem.features.onramp.swap.availablepairs.entity.transformers
|
||||||
|
|
||||||
|
import com.tangem.common.ui.account.AccountCryptoPortfolioItemStateConverter
|
||||||
|
import com.tangem.common.ui.account.TokensListPortfolioItemConverter
|
||||||
import com.tangem.common.ui.notifications.NotificationUM
|
import com.tangem.common.ui.notifications.NotificationUM
|
||||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
|
import com.tangem.domain.models.TotalFiatBalance
|
||||||
|
import com.tangem.domain.models.account.Account
|
||||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||||
|
import com.tangem.features.onramp.tokenlist.entity.TokenListUMData
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
||||||
import com.tangem.features.onramp.tokenlist.entity.utils.OnrampTokenItemStateConverterFactory
|
import com.tangem.features.onramp.tokenlist.entity.utils.OnrampTokenItemStateConverterFactory
|
||||||
import com.tangem.features.onramp.tokenlist.entity.utils.addHeader
|
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
import kotlinx.collections.immutable.toPersistentList
|
||||||
|
|
||||||
/**
|
|
||||||
[REDACTED_AUTHOR]
|
|
||||||
*/
|
|
||||||
internal class SetNoAvailablePairsTransformer(
|
internal class SetNoAvailablePairsTransformer(
|
||||||
private val appCurrency: AppCurrency,
|
private val appCurrency: AppCurrency,
|
||||||
private val unavailableStatuses: List<CryptoCurrencyStatus>,
|
private val accountList: Map<Account.CryptoPortfolio, List<CryptoCurrencyStatus>>,
|
||||||
private val isBalanceHidden: Boolean,
|
private val isBalanceHidden: Boolean,
|
||||||
private val unavailableTokensHeaderReference: TextReference,
|
private val isAccountsMode: Boolean,
|
||||||
|
private val unavailableErrorText: TextReference,
|
||||||
) : TokenListUMTransformer {
|
) : TokenListUMTransformer {
|
||||||
|
private val unavailableConverter = OnrampTokenItemStateConverterFactory
|
||||||
|
.createUnavailableItemConverterV2(appCurrency = appCurrency, unavailableErrorText = unavailableErrorText)
|
||||||
|
|
||||||
override fun transform(prevState: TokenListUM): TokenListUM {
|
override fun transform(prevState: TokenListUM): TokenListUM {
|
||||||
val unavailableItems = OnrampTokenItemStateConverterFactory.createUnavailableItemConverter(appCurrency)
|
val totalTokensCount = accountList.values.sumOf { it.size }
|
||||||
.convertList(unavailableStatuses)
|
|
||||||
.map(TokensListItemUM::Token)
|
|
||||||
|
|
||||||
return prevState.copy(
|
return prevState.copy(
|
||||||
availableItems = persistentListOf(),
|
availableItems = persistentListOf(),
|
||||||
unavailableItems = unavailableItems.addHeader(textReference = unavailableTokensHeaderReference),
|
unavailableItems = persistentListOf(),
|
||||||
|
tokensListData = if (isAccountsMode) {
|
||||||
|
TokenListUMData.AccountList(
|
||||||
|
tokensList = accountList.map { (account, cryptoCurrencies) ->
|
||||||
|
TokensListPortfolioItemConverter(
|
||||||
|
tokenItemUM = AccountCryptoPortfolioItemStateConverter(
|
||||||
|
appCurrency = appCurrency,
|
||||||
|
account = account,
|
||||||
|
onItemClick = null,
|
||||||
|
).convert(TotalFiatBalance.Failed),
|
||||||
|
isExpanded = true,
|
||||||
|
isCollapsable = false,
|
||||||
|
tokens = unavailableConverter.convertList(cryptoCurrencies)
|
||||||
|
.map(TokensListItemUM::Token)
|
||||||
|
.toPersistentList(),
|
||||||
|
).convert(Unit)
|
||||||
|
}.toPersistentList(),
|
||||||
|
totalTokensCount = totalTokensCount,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
TokenListUMData.TokenList(
|
||||||
|
tokensList = accountList.flatMap { (_, cryptoCurrencies) ->
|
||||||
|
unavailableConverter.convertList(cryptoCurrencies)
|
||||||
|
.map(TokensListItemUM::Token)
|
||||||
|
}.toPersistentList(),
|
||||||
|
totalTokensCount = totalTokensCount,
|
||||||
|
)
|
||||||
|
},
|
||||||
isBalanceHidden = isBalanceHidden,
|
isBalanceHidden = isBalanceHidden,
|
||||||
warning = NotificationUM.Warning.SwapNoAvailablePair,
|
warning = NotificationUM.Warning.SwapNoAvailablePair,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
package com.tangem.features.onramp.swap.availablepairs.entity.transformers
|
|
||||||
|
|
||||||
import com.tangem.common.ui.account.AccountCryptoPortfolioItemStateConverter
|
|
||||||
import com.tangem.common.ui.account.TokensListPortfolioItemConverter
|
|
||||||
import com.tangem.common.ui.notifications.NotificationUM
|
|
||||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
|
||||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
|
||||||
import com.tangem.domain.models.TotalFiatBalance
|
|
||||||
import com.tangem.domain.models.account.Account
|
|
||||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMData
|
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
|
||||||
import com.tangem.features.onramp.tokenlist.entity.utils.OnrampTokenItemStateConverterFactory
|
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
|
||||||
import kotlinx.collections.immutable.toPersistentList
|
|
||||||
|
|
||||||
internal class SetNoAvailablePairsTransformerV2(
|
|
||||||
private val appCurrency: AppCurrency,
|
|
||||||
private val accountList: Map<Account.CryptoPortfolio, List<CryptoCurrencyStatus>>,
|
|
||||||
private val isBalanceHidden: Boolean,
|
|
||||||
private val isAccountsMode: Boolean,
|
|
||||||
private val unavailableErrorText: TextReference,
|
|
||||||
) : TokenListUMTransformer {
|
|
||||||
private val unavailableConverter = OnrampTokenItemStateConverterFactory
|
|
||||||
.createUnavailableItemConverterV2(appCurrency = appCurrency, unavailableErrorText = unavailableErrorText)
|
|
||||||
|
|
||||||
override fun transform(prevState: TokenListUM): TokenListUM {
|
|
||||||
val totalTokensCount = accountList.values.sumOf { it.size }
|
|
||||||
|
|
||||||
return prevState.copy(
|
|
||||||
availableItems = persistentListOf(),
|
|
||||||
unavailableItems = persistentListOf(),
|
|
||||||
tokensListData = if (isAccountsMode) {
|
|
||||||
TokenListUMData.AccountList(
|
|
||||||
tokensList = accountList.map { (account, cryptoCurrencies) ->
|
|
||||||
TokensListPortfolioItemConverter(
|
|
||||||
tokenItemUM = AccountCryptoPortfolioItemStateConverter(
|
|
||||||
appCurrency = appCurrency,
|
|
||||||
account = account,
|
|
||||||
onItemClick = null,
|
|
||||||
).convert(TotalFiatBalance.Failed),
|
|
||||||
isExpanded = true,
|
|
||||||
isCollapsable = false,
|
|
||||||
tokens = unavailableConverter.convertList(cryptoCurrencies)
|
|
||||||
.map(TokensListItemUM::Token)
|
|
||||||
.toPersistentList(),
|
|
||||||
).convert(Unit)
|
|
||||||
}.toPersistentList(),
|
|
||||||
totalTokensCount = totalTokensCount,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TokenListUMData.TokenList(
|
|
||||||
tokensList = accountList.flatMap { (_, cryptoCurrencies) ->
|
|
||||||
unavailableConverter.convertList(cryptoCurrencies)
|
|
||||||
.map(TokensListItemUM::Token)
|
|
||||||
}.toPersistentList(),
|
|
||||||
totalTokensCount = totalTokensCount,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
isBalanceHidden = isBalanceHidden,
|
|
||||||
warning = NotificationUM.Warning.SwapNoAvailablePair,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -13,10 +13,7 @@ import com.tangem.core.decompose.model.ParamsContainer
|
||||||
import com.tangem.core.ui.components.fields.InputManager
|
import com.tangem.core.ui.components.fields.InputManager
|
||||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.extensions.capitalize
|
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.extensions.wrappedList
|
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
||||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||||
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
|
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
|
||||||
|
|
@ -26,7 +23,6 @@ import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||||
import com.tangem.domain.card.common.extensions.hotWalletExcludedBlockchains
|
import com.tangem.domain.card.common.extensions.hotWalletExcludedBlockchains
|
||||||
import com.tangem.domain.core.lce.Lce
|
import com.tangem.domain.core.lce.Lce
|
||||||
import com.tangem.domain.core.utils.getOrElse
|
|
||||||
import com.tangem.domain.core.utils.lceContent
|
import com.tangem.domain.core.utils.lceContent
|
||||||
import com.tangem.domain.core.utils.lceError
|
import com.tangem.domain.core.utils.lceError
|
||||||
import com.tangem.domain.core.utils.lceLoading
|
import com.tangem.domain.core.utils.lceLoading
|
||||||
|
|
@ -41,7 +37,6 @@ import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.models.tokenlist.TokenList
|
import com.tangem.domain.models.tokenlist.TokenList
|
||||||
import com.tangem.domain.models.wallet.UserWallet
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
import com.tangem.domain.tokens.GetTokenListUseCase
|
|
||||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||||
import com.tangem.feature.swap.domain.GetAvailablePairsUseCase
|
import com.tangem.feature.swap.domain.GetAvailablePairsUseCase
|
||||||
import com.tangem.feature.swap.domain.models.domain.LeastTokenInfo
|
import com.tangem.feature.swap.domain.models.domain.LeastTokenInfo
|
||||||
|
|
@ -51,9 +46,7 @@ import com.tangem.features.feed.components.market.details.portfolio.add.AddToPor
|
||||||
import com.tangem.features.onramp.impl.R
|
import com.tangem.features.onramp.impl.R
|
||||||
import com.tangem.features.onramp.swap.availablepairs.AvailableSwapPairsComponent
|
import com.tangem.features.onramp.swap.availablepairs.AvailableSwapPairsComponent
|
||||||
import com.tangem.features.onramp.swap.availablepairs.entity.transformers.SetErrorWarningTransformer
|
import com.tangem.features.onramp.swap.availablepairs.entity.transformers.SetErrorWarningTransformer
|
||||||
import com.tangem.features.onramp.swap.availablepairs.entity.transformers.SetLoadingTokenItemsTransformer
|
|
||||||
import com.tangem.features.onramp.swap.availablepairs.entity.transformers.SetNoAvailablePairsTransformer
|
import com.tangem.features.onramp.swap.availablepairs.entity.transformers.SetNoAvailablePairsTransformer
|
||||||
import com.tangem.features.onramp.swap.availablepairs.entity.transformers.SetNoAvailablePairsTransformerV2
|
|
||||||
import com.tangem.features.onramp.swap.availablepairs.market.SwapMarketsListBatchFlowManager
|
import com.tangem.features.onramp.swap.availablepairs.market.SwapMarketsListBatchFlowManager
|
||||||
import com.tangem.features.onramp.swap.availablepairs.market.state.SwapMarketState
|
import com.tangem.features.onramp.swap.availablepairs.market.state.SwapMarketState
|
||||||
import com.tangem.features.onramp.swap.entity.AccountAvailabilityUM
|
import com.tangem.features.onramp.swap.entity.AccountAvailabilityUM
|
||||||
|
|
@ -61,7 +54,9 @@ import com.tangem.features.onramp.swap.entity.AccountCurrencyUM
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMController
|
import com.tangem.features.onramp.tokenlist.entity.TokenListUMController
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
||||||
import com.tangem.features.onramp.tokenlist.entity.transformer.*
|
import com.tangem.features.onramp.tokenlist.entity.transformer.SetLoadingAccountTokenListTransformer
|
||||||
|
import com.tangem.features.onramp.tokenlist.entity.transformer.SetNothingToFoundStateTransformer
|
||||||
|
import com.tangem.features.onramp.tokenlist.entity.transformer.UpdateAccountTokenListTransformer
|
||||||
import com.tangem.features.onramp.tokenlist.entity.utils.OnrampTokenItemStateConverterFactory
|
import com.tangem.features.onramp.tokenlist.entity.utils.OnrampTokenItemStateConverterFactory
|
||||||
import com.tangem.features.onramp.utils.ClearSearchBarTransformer
|
import com.tangem.features.onramp.utils.ClearSearchBarTransformer
|
||||||
import com.tangem.features.onramp.utils.UpdateSearchBarActiveStateTransformer
|
import com.tangem.features.onramp.utils.UpdateSearchBarActiveStateTransformer
|
||||||
|
|
@ -87,7 +82,6 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
paramsContainer: ParamsContainer,
|
paramsContainer: ParamsContainer,
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||||
private val getTokenListUseCase: GetTokenListUseCase,
|
|
||||||
private val tokenListUMController: TokenListUMController,
|
private val tokenListUMController: TokenListUMController,
|
||||||
private val searchManager: InputManager,
|
private val searchManager: InputManager,
|
||||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||||
|
|
@ -95,7 +89,6 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
private val getAvailablePairsUseCase: GetAvailablePairsUseCase,
|
private val getAvailablePairsUseCase: GetAvailablePairsUseCase,
|
||||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
private val getMarketsTokenListFlowUseCase: GetMarketsTokenListFlowUseCase,
|
private val getMarketsTokenListFlowUseCase: GetMarketsTokenListFlowUseCase,
|
||||||
private val addToPortfolioManagerFactory: AddToPortfolioManager.Factory,
|
private val addToPortfolioManagerFactory: AddToPortfolioManager.Factory,
|
||||||
private val excludedBlockchains: ExcludedBlockchains,
|
private val excludedBlockchains: ExcludedBlockchains,
|
||||||
|
|
@ -120,7 +113,6 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
}
|
}
|
||||||
private val addToPortfolioJobHolder = JobHolder()
|
private val addToPortfolioJobHolder = JobHolder()
|
||||||
|
|
||||||
private val tokenListFlow = getTokenListUseCaseFlow()
|
|
||||||
private val accountListFlow = getAccountListUseCaseFlow()
|
private val accountListFlow = getAccountListUseCaseFlow()
|
||||||
private val availablePairsByNetworkFlow = MutableStateFlow<Map<LeastTokenInfo, AvailablePairsState>>(emptyMap())
|
private val availablePairsByNetworkFlow = MutableStateFlow<Map<LeastTokenInfo, AvailablePairsState>>(emptyMap())
|
||||||
|
|
||||||
|
|
@ -157,11 +149,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
private val visibleDefaultMarketItemIds = MutableStateFlow<List<CryptoCurrency.RawID>>(emptyList())
|
private val visibleDefaultMarketItemIds = MutableStateFlow<List<CryptoCurrency.RawID>>(emptyList())
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
subscribeOnUpdateState()
|
||||||
subscribeOnUpdateStateV2()
|
|
||||||
} else {
|
|
||||||
subscribeOnUpdateState()
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeSearchBarCallbacks()
|
initializeSearchBarCallbacks()
|
||||||
subscribeOnSelectedStatusChange()
|
subscribeOnSelectedStatusChange()
|
||||||
|
|
@ -173,18 +161,6 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTokenListUseCaseFlow(): SharedFlow<List<CryptoCurrencyStatus>> {
|
|
||||||
return getTokenListUseCase.launch(userWalletId = params.userWalletId)
|
|
||||||
.distinctUntilChanged()
|
|
||||||
.map { maybeTokenList ->
|
|
||||||
maybeTokenList.getOrElse(
|
|
||||||
ifLoading = { it ?: TokenList.Empty },
|
|
||||||
ifError = { TokenList.Empty },
|
|
||||||
).flattenCurrencies()
|
|
||||||
}
|
|
||||||
.shareIn(scope = modelScope, started = SharingStarted.Eagerly, replay = 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAccountListUseCaseFlow(): SharedFlow<List<AccountStatus>> {
|
private fun getAccountListUseCaseFlow(): SharedFlow<List<AccountStatus>> {
|
||||||
return singleAccountStatusListSupplier(SingleAccountStatusListProducer.Params(params.userWalletId))
|
return singleAccountStatusListSupplier(SingleAccountStatusListProducer.Params(params.userWalletId))
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
|
|
@ -214,42 +190,6 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun subscribeOnUpdateState() {
|
private fun subscribeOnUpdateState() {
|
||||||
combine(
|
|
||||||
flow = tokenListFlow,
|
|
||||||
flow2 = getAppCurrencyAndBalanceHidingFlow(),
|
|
||||||
flow3 = params.selectedStatus,
|
|
||||||
flow4 = searchManager.query,
|
|
||||||
flow5 = availablePairsByNetworkFlow
|
|
||||||
.map { it[params.selectedStatus.value?.toLeastTokenInfo()] }
|
|
||||||
.distinctUntilChanged(),
|
|
||||||
) { currencies, appCurrencyAndBalanceHiding, selectedStatus, query, availablePairsState ->
|
|
||||||
availablePairsState?.fold(
|
|
||||||
ifLoading = { SetLoadingTokenItemsTransformer(currencies) },
|
|
||||||
ifContent = { pairs ->
|
|
||||||
handleContentState(
|
|
||||||
appCurrencyAndBalanceHiding = appCurrencyAndBalanceHiding,
|
|
||||||
currencies = currencies,
|
|
||||||
selectedStatus = selectedStatus,
|
|
||||||
query = query,
|
|
||||||
availablePairs = pairs,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
ifError = { throwable ->
|
|
||||||
handleErrorState(
|
|
||||||
cause = throwable,
|
|
||||||
networkInfo = params.selectedStatus.value?.toLeastTokenInfo(),
|
|
||||||
currencies = currencies,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
?: SetLoadingTokenItemsTransformer(currencies)
|
|
||||||
}
|
|
||||||
.onEach(tokenListUMController::update)
|
|
||||||
.flowOn(dispatchers.main)
|
|
||||||
.launchIn(modelScope)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun subscribeOnUpdateStateV2() {
|
|
||||||
combine(
|
combine(
|
||||||
flow = getAccountsAndModeFlow(),
|
flow = getAccountsAndModeFlow(),
|
||||||
flow2 = getAppCurrencyAndBalanceHidingFlow(),
|
flow2 = getAppCurrencyAndBalanceHidingFlow(),
|
||||||
|
|
@ -269,7 +209,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
ifContent = { pairs ->
|
ifContent = { pairs ->
|
||||||
handleContentStateV2(
|
handleContentState(
|
||||||
appCurrencyAndBalanceHiding = appCurrencyAndBalanceHiding,
|
appCurrencyAndBalanceHiding = appCurrencyAndBalanceHiding,
|
||||||
accountList = accountList,
|
accountList = accountList,
|
||||||
selectedStatus = selectedStatus,
|
selectedStatus = selectedStatus,
|
||||||
|
|
@ -279,7 +219,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
ifError = { throwable ->
|
ifError = { throwable ->
|
||||||
handleErrorStateV2(
|
handleErrorState(
|
||||||
cause = throwable,
|
cause = throwable,
|
||||||
networkInfo = params.selectedStatus.value?.toLeastTokenInfo(),
|
networkInfo = params.selectedStatus.value?.toLeastTokenInfo(),
|
||||||
accountList = accountList,
|
accountList = accountList,
|
||||||
|
|
@ -297,52 +237,6 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleContentState(
|
private fun handleContentState(
|
||||||
appCurrencyAndBalanceHiding: Pair<AppCurrency, Boolean>,
|
|
||||||
currencies: List<CryptoCurrencyStatus>,
|
|
||||||
selectedStatus: CryptoCurrencyStatus?,
|
|
||||||
query: String,
|
|
||||||
availablePairs: List<SwapPairLeast>,
|
|
||||||
): TokenListUMTransformer {
|
|
||||||
val (appCurrency, isBalanceHidden) = appCurrencyAndBalanceHiding
|
|
||||||
|
|
||||||
if (availablePairs.isEmpty()) {
|
|
||||||
return SetNoAvailablePairsTransformer(
|
|
||||||
appCurrency = appCurrency,
|
|
||||||
unavailableStatuses = currencies,
|
|
||||||
isBalanceHidden = isBalanceHidden,
|
|
||||||
unavailableTokensHeaderReference = resourceReference(
|
|
||||||
id = R.string.tokens_list_unavailable_to_swap_header,
|
|
||||||
wrappedList(selectedStatus?.currency?.name?.capitalize().orEmpty()),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val filterByQueryTokenList = currencies
|
|
||||||
.filter { it.currency != selectedStatus?.currency }
|
|
||||||
.filterByQuery(query = query)
|
|
||||||
|
|
||||||
return if (query.isNotEmpty() && filterByQueryTokenList.isEmpty()) {
|
|
||||||
SetNothingToFoundStateTransformer(
|
|
||||||
isBalanceHidden = isBalanceHidden,
|
|
||||||
emptySearchMessageReference = resourceReference(
|
|
||||||
id = R.string.action_buttons_swap_empty_search_message,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
UpdateTokenItemsTransformer(
|
|
||||||
appCurrency = appCurrency,
|
|
||||||
onItemClick = ::onPortfolioTokenClick,
|
|
||||||
statuses = filterByQueryTokenList.filterByAvailability(availablePairs = availablePairs),
|
|
||||||
isBalanceHidden = isBalanceHidden,
|
|
||||||
unavailableTokensHeaderReference = resourceReference(
|
|
||||||
id = R.string.tokens_list_unavailable_to_swap_header,
|
|
||||||
wrappedList(selectedStatus?.currency?.name?.capitalize().orEmpty()),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleContentStateV2(
|
|
||||||
appCurrencyAndBalanceHiding: Pair<AppCurrency, Boolean>,
|
appCurrencyAndBalanceHiding: Pair<AppCurrency, Boolean>,
|
||||||
accountList: List<AccountStatus>,
|
accountList: List<AccountStatus>,
|
||||||
selectedStatus: CryptoCurrencyStatus?,
|
selectedStatus: CryptoCurrencyStatus?,
|
||||||
|
|
@ -371,7 +265,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
.filterValues { it.isNotEmpty() }
|
.filterValues { it.isNotEmpty() }
|
||||||
|
|
||||||
if (availablePairs.isEmpty()) {
|
if (availablePairs.isEmpty()) {
|
||||||
return SetNoAvailablePairsTransformerV2(
|
return SetNoAvailablePairsTransformer(
|
||||||
appCurrency = appCurrency,
|
appCurrency = appCurrency,
|
||||||
accountList = filterByQueryAccountList,
|
accountList = filterByQueryAccountList,
|
||||||
unavailableErrorText = resourceReference(R.string.tokens_list_unavailable_to_swap_source_header),
|
unavailableErrorText = resourceReference(R.string.tokens_list_unavailable_to_swap_source_header),
|
||||||
|
|
@ -381,7 +275,7 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (query.isNotEmpty() && filterByQueryAccountList.isEmpty()) {
|
return if (query.isNotEmpty() && filterByQueryAccountList.isEmpty()) {
|
||||||
SetNothingToFoundStateTransformerV2(
|
SetNothingToFoundStateTransformer(
|
||||||
isBalanceHidden = isBalanceHidden,
|
isBalanceHidden = isBalanceHidden,
|
||||||
emptySearchMessageReference = resourceReference(
|
emptySearchMessageReference = resourceReference(
|
||||||
id = R.string.action_buttons_swap_empty_search_message,
|
id = R.string.action_buttons_swap_empty_search_message,
|
||||||
|
|
@ -400,23 +294,6 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleErrorState(
|
private fun handleErrorState(
|
||||||
cause: Throwable,
|
|
||||||
networkInfo: LeastTokenInfo?,
|
|
||||||
currencies: List<CryptoCurrencyStatus>,
|
|
||||||
): SetErrorWarningTransformer {
|
|
||||||
return SetErrorWarningTransformer(
|
|
||||||
cause = cause,
|
|
||||||
onRefresh = {
|
|
||||||
modelScope.launch {
|
|
||||||
if (networkInfo != null) {
|
|
||||||
updateAvailablePairs(networkInfo, currencies)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleErrorStateV2(
|
|
||||||
cause: Throwable,
|
cause: Throwable,
|
||||||
networkInfo: LeastTokenInfo?,
|
networkInfo: LeastTokenInfo?,
|
||||||
accountList: List<AccountStatus>,
|
accountList: List<AccountStatus>,
|
||||||
|
|
@ -450,19 +327,14 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
val isAlreadyLoaded = availablePairsByNetworkFlow.value[networkInfo]?.isContent() == true
|
val isAlreadyLoaded = availablePairsByNetworkFlow.value[networkInfo]?.isContent() == true
|
||||||
if (isAlreadyLoaded) return@collectLatest
|
if (isAlreadyLoaded) return@collectLatest
|
||||||
|
|
||||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
val accountList = accountListFlow.firstOrNull() ?: return@collectLatest
|
||||||
val accountList = accountListFlow.firstOrNull() ?: return@collectLatest
|
updateAvailablePairs(
|
||||||
updateAvailablePairs(
|
networkInfo = networkInfo,
|
||||||
networkInfo = networkInfo,
|
statuses = accountList.filterCryptoPortfolio()
|
||||||
statuses = accountList.filterCryptoPortfolio()
|
.flatMap { accountStatus ->
|
||||||
.flatMap { accountStatus ->
|
accountStatus.flattenCurrencies()
|
||||||
accountStatus.flattenCurrencies()
|
}.toSet().toList(),
|
||||||
}.toSet().toList(),
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val statuses = tokenListFlow.firstOrNull() ?: return@collectLatest
|
|
||||||
updateAvailablePairs(networkInfo = networkInfo, statuses = statuses)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -540,19 +412,6 @@ internal class AvailableSwapPairsModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<CryptoCurrencyStatus>.filterByAvailability(
|
|
||||||
availablePairs: List<SwapPairLeast>,
|
|
||||||
): Map<Boolean, List<CryptoCurrencyStatus>> {
|
|
||||||
return groupBy { status ->
|
|
||||||
val isAvailable = availablePairs.map(SwapPairLeast::to).contains(status.toLeastTokenInfo())
|
|
||||||
|
|
||||||
isAvailable &&
|
|
||||||
status.value !is CryptoCurrencyStatus.MissedDerivation &&
|
|
||||||
status.value !is CryptoCurrencyStatus.Unreachable &&
|
|
||||||
!status.currency.isCustom
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Map<Account.CryptoPortfolio, List<CryptoCurrencyStatus>>.filterByAvailability(
|
private fun Map<Account.CryptoPortfolio, List<CryptoCurrencyStatus>>.filterByAvailability(
|
||||||
availablePairs: List<SwapPairLeast>,
|
availablePairs: List<SwapPairLeast>,
|
||||||
): List<AccountAvailabilityUM> {
|
): List<AccountAvailabilityUM> {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import com.tangem.core.decompose.model.Model
|
||||||
import com.tangem.core.decompose.model.ParamsContainer
|
import com.tangem.core.decompose.model.ParamsContainer
|
||||||
import com.tangem.core.decompose.navigation.Router
|
import com.tangem.core.decompose.navigation.Router
|
||||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
|
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
|
||||||
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
||||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||||
|
|
@ -37,7 +36,6 @@ internal class SwapSelectTokensModel @Inject constructor(
|
||||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||||
private val getAccountCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
private val getAccountCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
val state: StateFlow<SwapSelectTokensUM> = controller.state
|
val state: StateFlow<SwapSelectTokensUM> = controller.state
|
||||||
|
|
@ -77,14 +75,10 @@ internal class SwapSelectTokensModel @Inject constructor(
|
||||||
selectedTokenItemState = selectedTokenItemState,
|
selectedTokenItemState = selectedTokenItemState,
|
||||||
onRemoveClick = ::onRemoveFromTokenClick,
|
onRemoveClick = ::onRemoveFromTokenClick,
|
||||||
isAccountsMode = isAccountsMode,
|
isAccountsMode = isAccountsMode,
|
||||||
account = if (accountsFeatureToggles.isFeatureEnabled) {
|
account = getAccountCurrencyStatusUseCase.invokeSync(
|
||||||
getAccountCurrencyStatusUseCase.invokeSync(
|
userWalletId = params.userWalletId,
|
||||||
userWalletId = params.userWalletId,
|
currency = status.currency,
|
||||||
currency = status.currency,
|
).getOrNull()?.account,
|
||||||
).getOrNull()?.account
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -108,14 +102,10 @@ internal class SwapSelectTokensModel @Inject constructor(
|
||||||
transformer = SelectToTokenTransformer(
|
transformer = SelectToTokenTransformer(
|
||||||
selectedTokenItemState = selectedTokenItemState,
|
selectedTokenItemState = selectedTokenItemState,
|
||||||
isAccountsMode = isAccountsMode,
|
isAccountsMode = isAccountsMode,
|
||||||
account = if (accountsFeatureToggles.isFeatureEnabled) {
|
account = getAccountCurrencyStatusUseCase.invokeSync(
|
||||||
getAccountCurrencyStatusUseCase.invokeSync(
|
userWalletId = params.userWalletId,
|
||||||
userWalletId = params.userWalletId,
|
currency = status.currency,
|
||||||
currency = status.currency,
|
).getOrNull()?.account,
|
||||||
).getOrNull()?.account
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@ package com.tangem.features.onramp.tokenlist.entity.transformer
|
||||||
|
|
||||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
|
||||||
import com.tangem.features.onramp.impl.R
|
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMData
|
import com.tangem.features.onramp.tokenlist.entity.TokenListUMData
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
||||||
|
|
@ -16,22 +14,18 @@ internal class SetNothingToFoundStateTransformer(
|
||||||
|
|
||||||
override fun transform(prevState: TokenListUM): TokenListUM {
|
override fun transform(prevState: TokenListUM): TokenListUM {
|
||||||
return prevState.copy(
|
return prevState.copy(
|
||||||
availableItems = persistentListOf(
|
availableItems = persistentListOf(),
|
||||||
createGroupTitle(
|
|
||||||
textReference = resourceReference(id = R.string.exchange_tokens_available_tokens_header),
|
|
||||||
),
|
|
||||||
TokensListItemUM.Text(
|
|
||||||
id = emptySearchMessageReference.hashCode(),
|
|
||||||
text = emptySearchMessageReference,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
unavailableItems = persistentListOf(),
|
unavailableItems = persistentListOf(),
|
||||||
tokensListData = TokenListUMData.EmptyList,
|
tokensListData = TokenListUMData.TokenList(
|
||||||
|
tokensList = persistentListOf(
|
||||||
|
TokensListItemUM.Text(
|
||||||
|
id = emptySearchMessageReference.hashCode(),
|
||||||
|
text = emptySearchMessageReference,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
totalTokensCount = 0,
|
||||||
|
),
|
||||||
isBalanceHidden = isBalanceHidden,
|
isBalanceHidden = isBalanceHidden,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createGroupTitle(textReference: TextReference): TokensListItemUM.GroupTitle {
|
|
||||||
return TokensListItemUM.GroupTitle(id = textReference.hashCode(), text = textReference)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
package com.tangem.features.onramp.tokenlist.entity.transformer
|
|
||||||
|
|
||||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMData
|
|
||||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUMTransformer
|
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
|
||||||
|
|
||||||
internal class SetNothingToFoundStateTransformerV2(
|
|
||||||
private val isBalanceHidden: Boolean,
|
|
||||||
private val emptySearchMessageReference: TextReference,
|
|
||||||
) : TokenListUMTransformer {
|
|
||||||
|
|
||||||
override fun transform(prevState: TokenListUM): TokenListUM {
|
|
||||||
return prevState.copy(
|
|
||||||
availableItems = persistentListOf(),
|
|
||||||
unavailableItems = persistentListOf(),
|
|
||||||
tokensListData = TokenListUMData.TokenList(
|
|
||||||
tokensList = persistentListOf(
|
|
||||||
TokensListItemUM.Text(
|
|
||||||
id = emptySearchMessageReference.hashCode(),
|
|
||||||
text = emptySearchMessageReference,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
totalTokensCount = 0,
|
|
||||||
),
|
|
||||||
isBalanceHidden = isBalanceHidden,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -8,7 +8,6 @@ import com.tangem.core.ui.components.fields.InputManager
|
||||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.account.models.AccountStatusList
|
import com.tangem.domain.account.models.AccountStatusList
|
||||||
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
import com.tangem.domain.account.status.producer.SingleAccountStatusListProducer
|
||||||
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||||
|
|
@ -16,19 +15,14 @@ import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
||||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||||
import com.tangem.domain.core.lce.Lce
|
|
||||||
import com.tangem.domain.core.utils.getOrElse
|
|
||||||
import com.tangem.domain.exchange.RampStateManager
|
import com.tangem.domain.exchange.RampStateManager
|
||||||
import com.tangem.domain.models.TotalFiatBalance
|
import com.tangem.domain.models.TotalFiatBalance
|
||||||
import com.tangem.domain.models.account.Account
|
import com.tangem.domain.models.account.Account
|
||||||
import com.tangem.domain.models.account.AccountStatus
|
import com.tangem.domain.models.account.AccountStatus
|
||||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||||
import com.tangem.domain.models.tokenlist.TokenList
|
|
||||||
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
||||||
import com.tangem.domain.settings.usercountry.models.UserCountry
|
import com.tangem.domain.settings.usercountry.models.UserCountry
|
||||||
import com.tangem.domain.tokens.GetAssetRequirementsUseCase
|
import com.tangem.domain.tokens.GetAssetRequirementsUseCase
|
||||||
import com.tangem.domain.tokens.GetTokenListUseCase
|
|
||||||
import com.tangem.domain.tokens.error.TokenListError
|
|
||||||
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
|
import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason
|
||||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||||
import com.tangem.features.onramp.impl.R
|
import com.tangem.features.onramp.impl.R
|
||||||
|
|
@ -36,7 +30,9 @@ import com.tangem.features.onramp.swap.entity.AccountAvailabilityUM
|
||||||
import com.tangem.features.onramp.swap.entity.AccountCurrencyUM
|
import com.tangem.features.onramp.swap.entity.AccountCurrencyUM
|
||||||
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
||||||
import com.tangem.features.onramp.tokenlist.entity.*
|
import com.tangem.features.onramp.tokenlist.entity.*
|
||||||
import com.tangem.features.onramp.tokenlist.entity.transformer.*
|
import com.tangem.features.onramp.tokenlist.entity.transformer.SetLoadingAccountTokenListTransformer
|
||||||
|
import com.tangem.features.onramp.tokenlist.entity.transformer.SetNothingToFoundStateTransformer
|
||||||
|
import com.tangem.features.onramp.tokenlist.entity.transformer.UpdateAccountTokenListTransformer
|
||||||
import com.tangem.features.onramp.utils.ClearSearchBarTransformer
|
import com.tangem.features.onramp.utils.ClearSearchBarTransformer
|
||||||
import com.tangem.features.onramp.utils.UpdateSearchBarActiveStateTransformer
|
import com.tangem.features.onramp.utils.UpdateSearchBarActiveStateTransformer
|
||||||
import com.tangem.features.onramp.utils.UpdateSearchBarCallbacksTransformer
|
import com.tangem.features.onramp.utils.UpdateSearchBarCallbacksTransformer
|
||||||
|
|
@ -60,12 +56,10 @@ internal class OnrampTokenListModel @Inject constructor(
|
||||||
private val searchManager: InputManager,
|
private val searchManager: InputManager,
|
||||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||||
private val getTokenListUseCase: GetTokenListUseCase,
|
|
||||||
private val getWalletsUseCase: GetWalletsUseCase,
|
private val getWalletsUseCase: GetWalletsUseCase,
|
||||||
private val rampStateManager: RampStateManager,
|
private val rampStateManager: RampStateManager,
|
||||||
private val getUserCountryUseCase: GetUserCountryUseCase,
|
private val getUserCountryUseCase: GetUserCountryUseCase,
|
||||||
private val getAssetRequirementsUseCase: GetAssetRequirementsUseCase,
|
private val getAssetRequirementsUseCase: GetAssetRequirementsUseCase,
|
||||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
private val singleAccountStatusListSupplier: SingleAccountStatusListSupplier,
|
||||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
@ -84,68 +78,10 @@ internal class OnrampTokenListModel @Inject constructor(
|
||||||
onActiveChange = ::onSearchBarActiveChange,
|
onActiveChange = ::onSearchBarActiveChange,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
subscribeOnUpdateState()
|
||||||
subscribeOnUpdateStateV2()
|
|
||||||
} else {
|
|
||||||
subscribeOnUpdateState()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun subscribeOnUpdateState() {
|
private fun subscribeOnUpdateState() {
|
||||||
combine(
|
|
||||||
flow = getTokenListUseCase.launch(userWalletId = params.userWalletId).distinctUntilChanged(),
|
|
||||||
flow2 = getSelectedAppCurrencyUseCase().map { it.getOrElse { AppCurrency.Default } }.distinctUntilChanged(),
|
|
||||||
flow3 = getBalanceHidingSettingsUseCase().map { it.isBalanceHidden }.distinctUntilChanged(),
|
|
||||||
flow4 = searchManager.query,
|
|
||||||
flow5 = hasRestrictionForSellFlow(),
|
|
||||||
) { maybeTokenList, appCurrency, isBalanceHidden, query, hasRestrictionForSell ->
|
|
||||||
val currencies = maybeTokenList.getOrElse(
|
|
||||||
ifLoading = { it ?: TokenList.Empty },
|
|
||||||
ifError = { TokenList.Empty },
|
|
||||||
)
|
|
||||||
.flattenCurrencies()
|
|
||||||
|
|
||||||
val filterByQueryTokenList = currencies
|
|
||||||
.filterByQuery(query = query)
|
|
||||||
|
|
||||||
if (query.isNotEmpty() && filterByQueryTokenList.isEmpty()) {
|
|
||||||
SetNothingToFoundStateTransformer(
|
|
||||||
isBalanceHidden = isBalanceHidden,
|
|
||||||
emptySearchMessageReference = getEmptySearchMessageReference(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val isInsufficientBalanceForSell = if (params.filterOperation == OnrampOperation.SELL) {
|
|
||||||
maybeTokenList.isInsufficientBalanceForSell()
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateTokenItemsTransformer(
|
|
||||||
appCurrency = appCurrency,
|
|
||||||
onItemClick = ::onTokenClick,
|
|
||||||
statuses = filterByQueryTokenList.let { statuses ->
|
|
||||||
if (hasRestrictionForSell || isInsufficientBalanceForSell) {
|
|
||||||
mapOf(false to statuses)
|
|
||||||
} else {
|
|
||||||
statuses.filterByAvailability()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isBalanceHidden = isBalanceHidden,
|
|
||||||
unavailableTokensHeaderReference = getUnavailableTokensHeaderReference(),
|
|
||||||
warning = when {
|
|
||||||
hasRestrictionForSell -> NotificationUM.Warning.SellingRegionalRestriction
|
|
||||||
isInsufficientBalanceForSell -> NotificationUM.Warning.InsufficientBalanceForSelling
|
|
||||||
else -> null
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onEach(::updateTokenListUM)
|
|
||||||
.flowOn(dispatchers.main)
|
|
||||||
.launchIn(modelScope)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun subscribeOnUpdateStateV2() {
|
|
||||||
combine(
|
combine(
|
||||||
flow = singleAccountStatusListSupplier(
|
flow = singleAccountStatusListSupplier(
|
||||||
SingleAccountStatusListProducer.Params(params.userWalletId),
|
SingleAccountStatusListProducer.Params(params.userWalletId),
|
||||||
|
|
@ -160,7 +96,7 @@ internal class OnrampTokenListModel @Inject constructor(
|
||||||
|
|
||||||
if (query.isNotEmpty() && filterByQueryAccountList.isEmpty()) {
|
if (query.isNotEmpty() && filterByQueryAccountList.isEmpty()) {
|
||||||
updateTokenListUM(
|
updateTokenListUM(
|
||||||
SetNothingToFoundStateTransformerV2(
|
SetNothingToFoundStateTransformer(
|
||||||
isBalanceHidden = isBalanceHidden,
|
isBalanceHidden = isBalanceHidden,
|
||||||
emptySearchMessageReference = getEmptySearchMessageReference(),
|
emptySearchMessageReference = getEmptySearchMessageReference(),
|
||||||
),
|
),
|
||||||
|
|
@ -211,16 +147,6 @@ internal class OnrampTokenListModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Lce<TokenListError, TokenList>.isInsufficientBalanceForSell(): Boolean {
|
|
||||||
return if (params.filterOperation == OnrampOperation.SELL) {
|
|
||||||
isContent {
|
|
||||||
(it.totalFiatBalance as? TotalFiatBalance.Loaded)?.amount?.isZero() == true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun AccountStatusList.isInsufficientBalanceForSell(): Boolean {
|
private fun AccountStatusList.isInsufficientBalanceForSell(): Boolean {
|
||||||
return if (params.filterOperation == OnrampOperation.SELL) {
|
return if (params.filterOperation == OnrampOperation.SELL) {
|
||||||
(totalFiatBalance as? TotalFiatBalance.Loaded)?.amount?.isZero() == true
|
(totalFiatBalance as? TotalFiatBalance.Loaded)?.amount?.isZero() == true
|
||||||
|
|
@ -268,13 +194,8 @@ internal class OnrampTokenListModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isFirstInitialization(prevState: TokenListUM, newState: TokenListUM): Boolean {
|
private fun isFirstInitialization(prevState: TokenListUM, newState: TokenListUM): Boolean {
|
||||||
return if (accountsFeatureToggles.isFeatureEnabled) {
|
return prevState.tokensListData == TokenListUMData.EmptyList &&
|
||||||
prevState.tokensListData == TokenListUMData.EmptyList &&
|
newState.tokensListData != TokenListUMData.EmptyList
|
||||||
newState.tokensListData != TokenListUMData.EmptyList
|
|
||||||
} else {
|
|
||||||
prevState.availableItems.isEmpty() && prevState.unavailableItems.isEmpty() &&
|
|
||||||
(newState.availableItems.isNotEmpty() || newState.unavailableItems.isNotEmpty())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onTokenClick(tokenItemState: TokenItemState, status: CryptoCurrencyStatus) {
|
private fun onTokenClick(tokenItemState: TokenItemState, status: CryptoCurrencyStatus) {
|
||||||
|
|
@ -333,41 +254,6 @@ internal class OnrampTokenListModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun List<CryptoCurrencyStatus>.filterByAvailability(): Map<Boolean, List<CryptoCurrencyStatus>> {
|
|
||||||
return coroutineScope {
|
|
||||||
map { status ->
|
|
||||||
async {
|
|
||||||
val isOperationAvailable = checkAvailabilityByOperation(status = status)
|
|
||||||
val isNotMissedDerivation = status.value !is CryptoCurrencyStatus.MissedDerivation
|
|
||||||
val isNotLoading = status.value !is CryptoCurrencyStatus.Loading
|
|
||||||
|
|
||||||
val requirements = getAssetRequirementsUseCase(
|
|
||||||
userWalletId = userWallet.walletId,
|
|
||||||
currency = status.currency,
|
|
||||||
).getOrNull()
|
|
||||||
|
|
||||||
val isAvailableForBuy = rampStateManager.checkAssetRequirements(requirements)
|
|
||||||
val isNotUnreachable = status.value !is CryptoCurrencyStatus.Unreachable
|
|
||||||
|
|
||||||
val isAvailable = when (params.filterOperation) {
|
|
||||||
OnrampOperation.BUY -> {
|
|
||||||
isAvailableForBuy
|
|
||||||
} // unreachable state is available for Buy operation
|
|
||||||
OnrampOperation.SELL -> isNotUnreachable
|
|
||||||
OnrampOperation.SWAP -> {
|
|
||||||
isNotUnreachable && isAvailableForBuy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
status to (isOperationAvailable && isNotMissedDerivation && isNotLoading && isAvailable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.awaitAll()
|
|
||||||
.groupBy(Pair<CryptoCurrencyStatus, Boolean>::second)
|
|
||||||
.mapValues { it.value.map(Pair<CryptoCurrencyStatus, Boolean>::first) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun AccountCryptoList.filterByAvailability(): List<AccountAvailabilityUM> {
|
private suspend fun AccountCryptoList.filterByAvailability(): List<AccountAvailabilityUM> {
|
||||||
return coroutineScope {
|
return coroutineScope {
|
||||||
map { (account, currencies) ->
|
map { (account, currencies) ->
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,10 @@
|
||||||
<ID>MultilineLambdaItParameter:WcSwitchNetworkModel.kt$WcSwitchNetworkModel${ if (it.isExistInWcSession) { router.pop() } else { showErrorDialog(HandleMethodError.RequiredNetwork(it.network.name)) } }</ID>
|
<ID>MultilineLambdaItParameter:WcSwitchNetworkModel.kt$WcSwitchNetworkModel${ if (it.isExistInWcSession) { router.pop() } else { showErrorDialog(HandleMethodError.RequiredNetwork(it.network.name)) } }</ID>
|
||||||
<ID>NamedArguments:WcAddEthereumChainModalBottomSheetContent.kt$WcAddEthereumChainModalBottomSheetContent(state, {}, {}, {})</ID>
|
<ID>NamedArguments:WcAddEthereumChainModalBottomSheetContent.kt$WcAddEthereumChainModalBottomSheetContent(state, {}, {}, {})</ID>
|
||||||
<ID>NamedArguments:WcAlertsFactory.kt$WcAlertsFactory$createMaliciousDAppAlert(alertType.description, alertType.onClick, alertType.iconType, alertType.iconBgType)</ID>
|
<ID>NamedArguments:WcAlertsFactory.kt$WcAlertsFactory$createMaliciousDAppAlert(alertType.description, alertType.onClick, alertType.iconType, alertType.iconBgType)</ID>
|
||||||
<ID>NamedArguments:WcPairModel.kt$WcPairModel$handlePairState( pairState, portfolios, selected, isAccountMode, )</ID>
|
|
||||||
<ID>NamedArguments:WcSendTransactionModel.kt$WcSendTransactionModel$buildUiState(securityCheck, useCase, signState, isApprovalMethod)</ID>
|
<ID>NamedArguments:WcSendTransactionModel.kt$WcSendTransactionModel$buildUiState(securityCheck, useCase, signState, isApprovalMethod)</ID>
|
||||||
<ID>NestedScopeFunctions:WcSendAndReceiveBlockAidUiConverter.kt$WcSendAndReceiveBlockAidUiConverter$let { spendAllowanceUMConverter.convert( WcSpendAllowanceUMConverter.Input( approvedAmount = it, onLearnMoreClick = value.onApproveLearnMoreClick, ), ) }</ID>
|
<ID>NestedScopeFunctions:WcSendAndReceiveBlockAidUiConverter.kt$WcSendAndReceiveBlockAidUiConverter$let { spendAllowanceUMConverter.convert( WcSpendAllowanceUMConverter.Input( approvedAmount = it, onLearnMoreClick = value.onApproveLearnMoreClick, ), ) }</ID>
|
||||||
<ID>NoNameShadowing:WcNavigationUtils.kt$model</ID>
|
<ID>NoNameShadowing:WcNavigationUtils.kt$model</ID>
|
||||||
<ID>NullCheckOnMutableProperty:WcCommonTransactionComponentDelegate.kt$WcCommonTransactionComponentDelegate$if (contentStack != null) { val content by contentStack!!.subscribeAsState() BackHandler(onBack = ::onChildBack) content.active.instance.BottomSheet() }</ID>
|
<ID>NullCheckOnMutableProperty:WcCommonTransactionComponentDelegate.kt$WcCommonTransactionComponentDelegate$if (contentStack != null) { val content by contentStack!!.subscribeAsState() BackHandler(onBack = ::onChildBack) content.active.instance.BottomSheet() }</ID>
|
||||||
<ID>NullableBooleanCheck:WcPairModel.kt$WcPairModel$isAccountMode ?: false</ID>
|
|
||||||
<ID>NullableToStringCall:WcEstimatedWalletChangeUMConverter.kt$WcEstimatedWalletChangeUMConverter$${value.sign}</ID>
|
<ID>NullableToStringCall:WcEstimatedWalletChangeUMConverter.kt$WcEstimatedWalletChangeUMConverter$${value.sign}</ID>
|
||||||
<ID>ReusedModifierInstance:DefaultWalletConnectEntryComponent.kt$DefaultWalletConnectEntryComponent$Content(modifier = modifier)</ID>
|
<ID>ReusedModifierInstance:DefaultWalletConnectEntryComponent.kt$DefaultWalletConnectEntryComponent$Content(modifier = modifier)</ID>
|
||||||
<ID>ReusedModifierInstance:WcAppInfoBS.kt$Box( modifier = modifier .padding(start = 48.dp) .border( width = 2.dp, color = TangemTheme.colors.background.action, shape = CircleShape, ) .padding(2.dp) .background(color = TangemTheme.colors.background.action) .size(20.dp) .clip(CircleShape) .background(color = TangemTheme.colors.icon.primary1.copy(alpha = 0.1F)), ) { Text( modifier = Modifier.align(Alignment.Center), text = "+$remainingCount", style = TangemTheme.typography.overline, color = TangemTheme.colors.text.secondary, ) }</ID>
|
<ID>ReusedModifierInstance:WcAppInfoBS.kt$Box( modifier = modifier .padding(start = 48.dp) .border( width = 2.dp, color = TangemTheme.colors.background.action, shape = CircleShape, ) .padding(2.dp) .background(color = TangemTheme.colors.background.action) .size(20.dp) .clip(CircleShape) .background(color = TangemTheme.colors.icon.primary1.copy(alpha = 0.1F)), ) { Text( modifier = Modifier.align(Alignment.Center), text = "+$remainingCount", style = TangemTheme.typography.overline, color = TangemTheme.colors.text.secondary, ) }</ID>
|
||||||
|
|
@ -46,7 +44,6 @@
|
||||||
<ID>UnsafeCallOnNullableType:WcPairComponent.kt$WcPairComponent$model.portfolioFetcher!!</ID>
|
<ID>UnsafeCallOnNullableType:WcPairComponent.kt$WcPairComponent$model.portfolioFetcher!!</ID>
|
||||||
<ID>UnsafeCallOnNullableType:WcSignTransactionComponent.kt$WcSignTransactionComponent$content!!</ID>
|
<ID>UnsafeCallOnNullableType:WcSignTransactionComponent.kt$WcSignTransactionComponent$content!!</ID>
|
||||||
<ID>UnsafeCallOnNullableType:WcTransactionRequestInfoComponent.kt$WcTransactionRequestInfoComponent$content!!</ID>
|
<ID>UnsafeCallOnNullableType:WcTransactionRequestInfoComponent.kt$WcTransactionRequestInfoComponent$content!!</ID>
|
||||||
<ID>UseEmptyCounterpart:WcPairModel.kt$WcPairModel$setOf<Network>()</ID>
|
|
||||||
<ID>UseOrEmpty:WcSpendAllowanceUMConverter.kt$WcSpendAllowanceUMConverter$value.approvedAmount.amount?.currencySymbol ?: ""</ID>
|
<ID>UseOrEmpty:WcSpendAllowanceUMConverter.kt$WcSpendAllowanceUMConverter$value.approvedAmount.amount?.currencySymbol ?: ""</ID>
|
||||||
<ID>UseOrEmpty:WcTransactionCheckErrorItem.kt$notification.text?.resolveReference() ?: ""</ID>
|
<ID>UseOrEmpty:WcTransactionCheckErrorItem.kt$notification.text?.resolveReference() ?: ""</ID>
|
||||||
</CurrentIssues>
|
</CurrentIssues>
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,9 @@ import com.tangem.core.decompose.navigation.inner.InnerRouter
|
||||||
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUMV2
|
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUMV2
|
||||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||||
import com.tangem.domain.walletconnect.model.WcPairRequest
|
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
|
import com.tangem.domain.walletconnect.model.WcPairRequest
|
||||||
import com.tangem.features.account.PortfolioSelectorComponent
|
import com.tangem.features.account.PortfolioSelectorComponent
|
||||||
import com.tangem.features.walletconnect.connections.components.WcSelectNetworksComponent.*
|
|
||||||
import com.tangem.features.walletconnect.connections.components.WcSelectWalletComponent.*
|
|
||||||
import com.tangem.features.walletconnect.connections.model.WcPairModel
|
import com.tangem.features.walletconnect.connections.model.WcPairModel
|
||||||
import com.tangem.features.walletconnect.connections.routes.WcAppInfoRoutes
|
import com.tangem.features.walletconnect.connections.routes.WcAppInfoRoutes
|
||||||
import com.tangem.features.walletconnect.connections.routes.WcAppInfoRoutes.Alert
|
import com.tangem.features.walletconnect.connections.routes.WcAppInfoRoutes.Alert
|
||||||
|
|
@ -115,7 +113,7 @@ internal class WcPairComponent(
|
||||||
WcAppInfoRoutes.PortfolioSelector -> portfolioSelectorComponentFactory.create(
|
WcAppInfoRoutes.PortfolioSelector -> portfolioSelectorComponentFactory.create(
|
||||||
context = appComponentContext,
|
context = appComponentContext,
|
||||||
params = PortfolioSelectorComponent.Params(
|
params = PortfolioSelectorComponent.Params(
|
||||||
portfolioFetcher = model.portfolioFetcher!!,
|
portfolioFetcher = model.portfolioFetcher,
|
||||||
bsCallback = model.portfolioSelectorCallback,
|
bsCallback = model.portfolioSelectorCallback,
|
||||||
controller = model.selectorController,
|
controller = model.selectorController,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import com.tangem.core.ui.message.DialogMessage
|
||||||
import com.tangem.core.ui.message.EventMessageAction
|
import com.tangem.core.ui.message.EventMessageAction
|
||||||
import com.tangem.core.ui.message.SnackbarMessage
|
import com.tangem.core.ui.message.SnackbarMessage
|
||||||
import com.tangem.core.ui.res.TangemTheme
|
import com.tangem.core.ui.res.TangemTheme
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.account.supplier.MultiAccountListSupplier
|
import com.tangem.domain.account.supplier.MultiAccountListSupplier
|
||||||
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
||||||
import com.tangem.domain.qrscanning.models.QrResultSource
|
import com.tangem.domain.qrscanning.models.QrResultSource
|
||||||
|
|
@ -55,7 +54,6 @@ internal class WcConnectionsModel @Inject constructor(
|
||||||
private val wcDisconnectUseCase: WcDisconnectUseCase,
|
private val wcDisconnectUseCase: WcDisconnectUseCase,
|
||||||
private val multiAccountListSupplier: MultiAccountListSupplier,
|
private val multiAccountListSupplier: MultiAccountListSupplier,
|
||||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||||
accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
private val wcPairService: WcPairService,
|
private val wcPairService: WcPairService,
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
analytics: AnalyticsEventHandler,
|
analytics: AnalyticsEventHandler,
|
||||||
|
|
@ -70,11 +68,7 @@ internal class WcConnectionsModel @Inject constructor(
|
||||||
init {
|
init {
|
||||||
analytics.send(WcAnalyticEvents.ScreenOpened())
|
analytics.send(WcAnalyticEvents.ScreenOpened())
|
||||||
listenQrUpdates()
|
listenQrUpdates()
|
||||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
listenWcSessions()
|
||||||
listenWcSessions()
|
|
||||||
} else {
|
|
||||||
listenWcSessionsOld()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun listenQrUpdates() {
|
private fun listenQrUpdates() {
|
||||||
|
|
@ -98,21 +92,6 @@ internal class WcConnectionsModel @Inject constructor(
|
||||||
.launchIn(modelScope)
|
.launchIn(modelScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun listenWcSessionsOld() {
|
|
||||||
wcSessionsUseCase.invoke()
|
|
||||||
.conflate()
|
|
||||||
.distinctUntilChanged()
|
|
||||||
.onEach { sessionsMap ->
|
|
||||||
uiState.update(
|
|
||||||
WcSessionsTransformer(
|
|
||||||
sessionsMap = sessionsMap,
|
|
||||||
openAppInfoModal = ::openAppInfoModal,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.launchIn(modelScope)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun listenWcSessions() {
|
private fun listenWcSessions() {
|
||||||
combine(
|
combine(
|
||||||
flow = wcSessionsUseCase.invoke().distinctUntilChanged(),
|
flow = wcSessionsUseCase.invoke().distinctUntilChanged(),
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import com.tangem.core.ui.extensions.stringReference
|
||||||
import com.tangem.core.ui.extensions.wrappedList
|
import com.tangem.core.ui.extensions.wrappedList
|
||||||
import com.tangem.core.ui.message.SnackbarMessage
|
import com.tangem.core.ui.message.SnackbarMessage
|
||||||
import com.tangem.core.ui.message.ToastMessage
|
import com.tangem.core.ui.message.ToastMessage
|
||||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
|
||||||
import com.tangem.domain.account.producer.SingleAccountListProducer
|
import com.tangem.domain.account.producer.SingleAccountListProducer
|
||||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||||
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
||||||
|
|
@ -75,7 +74,6 @@ internal class WcPairModel @Inject constructor(
|
||||||
private val messageSender: UiMessageSender,
|
private val messageSender: UiMessageSender,
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val analytics: AnalyticsEventHandler,
|
private val analytics: AnalyticsEventHandler,
|
||||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
|
||||||
val selectorController: PortfolioSelectorController,
|
val selectorController: PortfolioSelectorController,
|
||||||
private val singleAccountListSupplier: SingleAccountListSupplier,
|
private val singleAccountListSupplier: SingleAccountListSupplier,
|
||||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||||
|
|
@ -95,7 +93,10 @@ internal class WcPairModel @Inject constructor(
|
||||||
)
|
)
|
||||||
|
|
||||||
val stackNavigation = StackNavigation<WcAppInfoRoutes>()
|
val stackNavigation = StackNavigation<WcAppInfoRoutes>()
|
||||||
val portfolioFetcher: PortfolioFetcher?
|
val portfolioFetcher: PortfolioFetcher = portfolioFetcherFactory.create(
|
||||||
|
mode = PortfolioFetcher.Mode.All(isOnlyMultiCurrency = true),
|
||||||
|
scope = modelScope,
|
||||||
|
)
|
||||||
val portfolioSelectorCallback = object : PortfolioSelectorComponent.BottomSheetCallback {
|
val portfolioSelectorCallback = object : PortfolioSelectorComponent.BottomSheetCallback {
|
||||||
override val onDismiss: () -> Unit = { stackNavigation.pop() }
|
override val onDismiss: () -> Unit = { stackNavigation.pop() }
|
||||||
override val onBack: () -> Unit = { stackNavigation.pop() }
|
override val onBack: () -> Unit = { stackNavigation.pop() }
|
||||||
|
|
@ -110,32 +111,23 @@ internal class WcPairModel @Inject constructor(
|
||||||
)
|
)
|
||||||
private var proposalNetwork by Delegates.notNull<WcSessionProposal.ProposalNetwork>()
|
private var proposalNetwork by Delegates.notNull<WcSessionProposal.ProposalNetwork>()
|
||||||
private var sessionProposal by Delegates.notNull<WcSessionProposal>()
|
private var sessionProposal by Delegates.notNull<WcSessionProposal>()
|
||||||
private var additionallyEnabledNetworks = setOf<Network>()
|
private var additionallyEnabledNetworks = emptySet<Network>()
|
||||||
private val dAppVerifiedStateConverter = WcDAppVerifiedStateConverter(onVerifiedClick = ::showVerifiedAlert)
|
private val dAppVerifiedStateConverter = WcDAppVerifiedStateConverter(onVerifiedClick = ::showVerifiedAlert)
|
||||||
|
|
||||||
val appInfoUiState: StateFlow<WcAppInfoUM>
|
val appInfoUiState: StateFlow<WcAppInfoUM>
|
||||||
field = MutableStateFlow<WcAppInfoUM>(createLoadingState())
|
field = MutableStateFlow<WcAppInfoUM>(createLoadingState())
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
modelScope.launch {
|
||||||
portfolioFetcher = portfolioFetcherFactory.create(
|
val params = SingleAccountListProducer.Params(params.userWalletId)
|
||||||
mode = PortfolioFetcher.Mode.All(isOnlyMultiCurrency = true),
|
val accountList = singleAccountListSupplier.getSyncOrNull(params)
|
||||||
scope = modelScope,
|
if (accountList == null) {
|
||||||
)
|
router.pop()
|
||||||
modelScope.launch {
|
return@launch
|
||||||
val params = SingleAccountListProducer.Params(params.userWalletId)
|
|
||||||
val accountList = singleAccountListSupplier.getSyncOrNull(params)
|
|
||||||
if (accountList == null) {
|
|
||||||
router.pop()
|
|
||||||
return@launch
|
|
||||||
}
|
|
||||||
val firstAccount = accountList.accounts.first()
|
|
||||||
selectorController.selectAccount(firstAccount.accountId)
|
|
||||||
combineFlows(portfolioFetcher)
|
|
||||||
}
|
}
|
||||||
} else {
|
val firstAccount = accountList.accounts.first()
|
||||||
portfolioFetcher = null
|
selectorController.selectAccount(firstAccount.accountId)
|
||||||
loadDAppInfo()
|
combineFlows(portfolioFetcher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,22 +143,16 @@ internal class WcPairModel @Inject constructor(
|
||||||
flow4 = isAccountsModeEnabledUseCase(),
|
flow4 = isAccountsModeEnabledUseCase(),
|
||||||
transform = { portfolios, selected, pairState, isAccountMode ->
|
transform = { portfolios, selected, pairState, isAccountMode ->
|
||||||
handlePairState(
|
handlePairState(
|
||||||
pairState,
|
pairState = pairState,
|
||||||
portfolios,
|
portfolios = portfolios,
|
||||||
selected,
|
selected = selected,
|
||||||
isAccountMode,
|
isAccountMode = isAccountMode,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.launchIn(modelScope)
|
.launchIn(modelScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadDAppInfo() {
|
|
||||||
wcPairUseCase()
|
|
||||||
.onEach { pairState -> handlePairState(pairState) }
|
|
||||||
.launchIn(modelScope)
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun handlePairState(
|
private suspend fun handlePairState(
|
||||||
pairState: WcPairState,
|
pairState: WcPairState,
|
||||||
portfolios: PortfolioFetcher.Data? = null,
|
portfolios: PortfolioFetcher.Data? = null,
|
||||||
|
|
@ -193,7 +179,7 @@ internal class WcPairModel @Inject constructor(
|
||||||
)
|
)
|
||||||
processError(pairState.error)
|
processError(pairState.error)
|
||||||
}
|
}
|
||||||
is WcPairState.Loading -> appInfoUiState.update { createLoadingState(isAccountMode ?: false) }
|
is WcPairState.Loading -> appInfoUiState.update { createLoadingState(isAccountMode == true) }
|
||||||
is WcPairState.Proposal -> handleProposalState(
|
is WcPairState.Proposal -> handleProposalState(
|
||||||
pairState = pairState,
|
pairState = pairState,
|
||||||
portfolios = portfolios,
|
portfolios = portfolios,
|
||||||
|
|
@ -225,7 +211,7 @@ internal class WcPairModel @Inject constructor(
|
||||||
} else {
|
} else {
|
||||||
val portfolioSelectRow = tryToCreatePortfolioSelectRow(selected, portfolios)
|
val portfolioSelectRow = tryToCreatePortfolioSelectRow(selected, portfolios)
|
||||||
if (proposalAccountNetwork != null) {
|
if (proposalAccountNetwork != null) {
|
||||||
selectorController.isEnabled.value = { wallet, account ->
|
selectorController.isEnabled.value = { _, account ->
|
||||||
proposalAccountNetwork.contains(account.account.accountId)
|
proposalAccountNetwork.contains(account.account.accountId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue