diff --git a/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt b/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt index 799793848c..95992352f7 100644 --- a/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt +++ b/data/markets/src/main/java/com/tangem/data/markets/DefaultMarketsTokenRepository.kt @@ -247,7 +247,7 @@ internal class DefaultMarketsTokenRepository( override suspend fun createCryptoCurrency( userWalletId: UserWalletId, - token: TokenMarketParams, + token: RawMarketToken, network: TokenMarketInfo.Network, accountIndex: DerivationIndex?, ): CryptoCurrency? { diff --git a/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/RawMarketToken.kt b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/RawMarketToken.kt new file mode 100644 index 0000000000..26a5c74947 --- /dev/null +++ b/domain/markets/models/src/main/kotlin/com/tangem/domain/markets/RawMarketToken.kt @@ -0,0 +1,12 @@ +package com.tangem.domain.markets + +import com.tangem.domain.models.currency.CryptoCurrency + +/** + * minimal token info for add-to-portfolio flow + */ +data class RawMarketToken( + val id: CryptoCurrency.RawID, + val name: String, + val symbol: String, +) \ No newline at end of file diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenMarketCryptoCurrency.kt b/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenMarketCryptoCurrency.kt index 4cdd14d937..46eee09ba2 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenMarketCryptoCurrency.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/GetTokenMarketCryptoCurrency.kt @@ -10,7 +10,7 @@ class GetTokenMarketCryptoCurrency( ) { suspend operator fun invoke( userWalletId: UserWalletId, - tokenMarketParams: TokenMarketParams, + tokenMarketParams: RawMarketToken, network: TokenMarketInfo.Network, accountIndex: DerivationIndex, ): CryptoCurrency? { diff --git a/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt b/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt index acf2b29ff1..16d5ce98ea 100644 --- a/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt +++ b/domain/markets/src/main/java/com/tangem/domain/markets/repositories/MarketsTokenRepository.kt @@ -42,7 +42,7 @@ interface MarketsTokenRepository { suspend fun createCryptoCurrency( userWalletId: UserWalletId, - token: TokenMarketParams, + token: RawMarketToken, network: TokenMarketInfo.Network, accountIndex: DerivationIndex? = null, ): CryptoCurrency? diff --git a/features/common-features/api/src/main/java/com/tangem/features/commonfeatures/api/addtoportfolio/AddToPortfolioManager.kt b/features/common-features/api/src/main/java/com/tangem/features/commonfeatures/api/addtoportfolio/AddToPortfolioManager.kt index 70e41a3756..5b53e9abc2 100644 --- a/features/common-features/api/src/main/java/com/tangem/features/commonfeatures/api/addtoportfolio/AddToPortfolioManager.kt +++ b/features/common-features/api/src/main/java/com/tangem/features/commonfeatures/api/addtoportfolio/AddToPortfolioManager.kt @@ -1,13 +1,13 @@ package com.tangem.features.commonfeatures.api.addtoportfolio +import com.tangem.domain.markets.RawMarketToken import com.tangem.domain.markets.TokenMarketInfo import com.tangem.domain.markets.TokenMarketParams import com.tangem.domain.models.account.AccountStatus -import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.wallet.UserWallet -import com.tangem.features.commonfeatures.api.portfolioselector.PortfolioFetcher import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager.AnalyticsParams +import com.tangem.features.commonfeatures.api.portfolioselector.PortfolioFetcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.SharedFlow @@ -21,11 +21,22 @@ interface AddToPortfolioManager : AddToPortfolioManagerInternal { val onSuccessAdded: Channel val onAddedTokenClick: Channel - val portfolioFetcher: PortfolioFetcher val state: StateFlow + /** + * default is [LaunchMode.DirectAdd] + */ + fun updateLaunchMode(launchMode: LaunchMode) + fun setTokenNetworks(networks: List) - fun setTokenParams(token: TokenMarketParams) + fun setTokenParams(token: RawMarketToken) + fun setTokenParams(token: TokenMarketParams) = setTokenParams( + RawMarketToken( + id = token.id, + name = token.name, + symbol = token.symbol, + ), + ) sealed interface State { data object Loading : State @@ -36,7 +47,15 @@ interface AddToPortfolioManager : AddToPortfolioManagerInternal { } @Serializable - data class AnalyticsParams(val source: String?) + data class AnalyticsParams( + val source: String?, + val category: String = CategoryDefault, + ) { + companion object { + const val CategoryDefault = "Markets / Chart" + const val CategoryEarn = "Earn" + } + } interface Factory { fun create(scope: CoroutineScope, settings: Settings, analyticsParams: AnalyticsParams): AddToPortfolioManager @@ -44,7 +63,8 @@ interface AddToPortfolioManager : AddToPortfolioManagerInternal { sealed interface LaunchMode { data object DirectAdd : LaunchMode - data class ViaUserPortfolio(val rawCurrencyId: CryptoCurrency.RawID) : LaunchMode + data object Preselected : LaunchMode + data object ViaUserPortfolio : LaunchMode } /** @@ -52,7 +72,6 @@ interface AddToPortfolioManager : AddToPortfolioManagerInternal { */ data class Settings( val shouldSkipTokenActionsScreen: Boolean = false, - val launchMode: LaunchMode = LaunchMode.DirectAdd, ) { companion object { val DefaultMarket = Settings(shouldSkipTokenActionsScreen = false) @@ -64,7 +83,11 @@ interface AddToPortfolioManager : AddToPortfolioManagerInternal { * Mutable parameters * Updates may trigger reload [State] */ - data class Params(val networks: List, val token: TokenMarketParams) + data class Params( + val networks: List, + val token: RawMarketToken, + val launchMode: LaunchMode, + ) data class Result( val wallet: UserWallet, @@ -80,8 +103,10 @@ interface AddToPortfolioManagerInternal { val paramsFlow: SharedFlow val settings: AddToPortfolioManager.Settings val analyticsParams: AnalyticsParams + val portfolioFetcher: PortfolioFetcher - suspend fun token(): TokenMarketParams = paramsFlow.first().token + suspend fun params(): AddToPortfolioManager.Params = paramsFlow.first() + suspend fun token(): RawMarketToken = params().token fun onDismiss() fun onSuccessAdded(result: AddToPortfolioManager.Result) diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/AddTokenComponent.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/AddTokenComponent.kt index 59f8f27bd1..0530a497f3 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/AddTokenComponent.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/AddTokenComponent.kt @@ -45,7 +45,7 @@ internal class AddTokenComponent @AssistedInject constructor( } data class Params( - val eventBuilder: Flow, + val eventBuilder: PortfolioAnalyticsEvent.EventBuilder, val selectedPortfolio: Flow, val selectedNetwork: Flow, val callbacks: Callbacks, diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/DefaultAddToPortfolioComponent.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/DefaultAddToPortfolioComponent.kt index 214ba365f5..189c551c95 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/DefaultAddToPortfolioComponent.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/DefaultAddToPortfolioComponent.kt @@ -12,7 +12,6 @@ import com.tangem.core.decompose.context.childByContext import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioComponent -import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager import com.tangem.features.commonfeatures.api.portfolioselector.PortfolioSelectorComponent import com.tangem.features.commonfeatures.impl.addtoportfolio.model.AddToPortfolioModel import com.tangem.features.commonfeatures.impl.addtoportfolio.model.AddToPortfolioRoutes @@ -37,29 +36,33 @@ internal class DefaultAddToPortfolioComponent @AssistedInject constructor( private val portfolioSelectorComponent: PortfolioSelectorComponent = portfolioSelectorComponentFactory.create( context = child("portfolioSelectorComponent"), params = PortfolioSelectorComponent.Params( - portfolioFetcher = model.portfolioFetcher, + portfolioFetcher = model.addToPortfolioManager.portfolioFetcher, controller = model.portfolioSelectorController, ), ) - private val addTokenComponent: AddTokenComponent = addTokenComponentFactory.create( - context = child("addTokenComponent"), - params = AddTokenComponent.Params( - eventBuilder = model.eventBuilder, - callbacks = model, - selectedPortfolio = model.selectedPortfolio, - selectedNetwork = model.selectedNetwork, - ), - ) + private val addTokenComponent: AddTokenComponent by lazy { + addTokenComponentFactory.create( + context = child("addTokenComponent"), + params = AddTokenComponent.Params( + eventBuilder = model.eventBuilder, + callbacks = model, + selectedPortfolio = model.selectedPortfolio, + selectedNetwork = model.selectedNetwork, + ), + ) + } - private val tokenActionsComponent: TokenActionsComponent = tokenActionsComponentFactory.create( - context = child("tokenActionsComponent"), - params = TokenActionsComponent.Params( - eventBuilder = model.eventBuilder, - callbacks = model, - data = model.tokenActionsData, - ), - ) + private val tokenActionsComponent: TokenActionsComponent by lazy { + tokenActionsComponentFactory.create( + context = child("tokenActionsComponent"), + params = TokenActionsComponent.Params( + eventBuilder = model.eventBuilder, + callbacks = model, + data = model.tokenActionsData, + ), + ) + } private val childStack = childStack( key = "addToPortfolioStack", @@ -106,16 +109,13 @@ internal class DefaultAddToPortfolioComponent @AssistedInject constructor( } private fun createUserPortfolioComponent(componentContext: ComponentContext): ComposableContentComponent { - return when (model.addToPortfolioManager.settings.launchMode) { - AddToPortfolioManager.LaunchMode.DirectAdd -> ComposableContentComponent.EMPTY - is AddToPortfolioManager.LaunchMode.ViaUserPortfolio -> userPortfolioComponentFactory.create( - context = childByContext(componentContext), - params = UserPortfolioComponent.Params( - uiState = model.userPortfolioStateController.uiState, - callbacks = model, - ), - ) - } + return userPortfolioComponentFactory.create( + context = childByContext(componentContext), + params = UserPortfolioComponent.Params( + uiState = model.userPortfolioStateController.uiState, + callbacks = model, + ), + ) } @AssistedFactory diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/DefaultAddToPortfolioPreselectedDataComponent.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/DefaultAddToPortfolioPreselectedDataComponent.kt index bb72f99975..103f0d4ee0 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/DefaultAddToPortfolioPreselectedDataComponent.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/DefaultAddToPortfolioPreselectedDataComponent.kt @@ -16,7 +16,6 @@ import com.tangem.features.commonfeatures.impl.addtoportfolio.model.AddToPortfol import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject -import kotlinx.coroutines.flow.flowOf internal class DefaultAddToPortfolioPreselectedDataComponent @AssistedInject constructor( @Assisted context: AppComponentContext, @@ -38,7 +37,7 @@ internal class DefaultAddToPortfolioPreselectedDataComponent @AssistedInject con private val addTokenComponent: AddTokenComponent = addTokenComponentFactory.create( context = child("addTokenComponent"), params = AddTokenComponent.Params( - eventBuilder = flowOf(model.eventBuilder), + eventBuilder = model.eventBuilder, callbacks = model, selectedPortfolio = model.selectedPortfolio, selectedNetwork = model.selectedNetwork, diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/TokenActionsComponent.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/TokenActionsComponent.kt index c4bce69e42..30cd1227fc 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/TokenActionsComponent.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/TokenActionsComponent.kt @@ -72,7 +72,7 @@ internal class TokenActionsComponent @AssistedInject constructor( ) data class Params( - val eventBuilder: Flow, + val eventBuilder: PortfolioAnalyticsEvent.EventBuilder, val data: Flow, val callbacks: Callbacks, ) diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/analytics/PortfolioAnalyticsEvent.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/analytics/PortfolioAnalyticsEvent.kt index 6f72186a1b..925cf4831b 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/analytics/PortfolioAnalyticsEvent.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/analytics/PortfolioAnalyticsEvent.kt @@ -2,34 +2,41 @@ package com.tangem.features.commonfeatures.impl.addtoportfolio.analytics import com.tangem.common.ui.markets.action.TokenActionsBSContentUM import com.tangem.core.analytics.models.AnalyticsEvent +import com.tangem.core.analytics.models.AnalyticsParam -// todo swap unify with EarnAnalyticsEvent, AddToPortfolioFlow internal class PortfolioAnalyticsEvent( event: String, params: Map = emptyMap(), -) : AnalyticsEvent(category = "Markets / Chart", event = event, params = params) { + category: String, +) : AnalyticsEvent(category = category, event = event, params = params) { data class EventBuilder( val tokenSymbol: String, val source: String?, + val category: String, ) { fun popupToChooseAccount() = PortfolioAnalyticsEvent( event = "Choose Account Opened", + category = category, params = buildMap { - if (source != null) put("Source", source) + if (source != null) put(AnalyticsParam.SOURCE, source) }, ) - fun popupToConfirm() = PortfolioAnalyticsEvent( + fun popupToConfirm(blockchain: String) = PortfolioAnalyticsEvent( event = "Add Token Screen Opened", + category = category, params = buildMap { - if (source != null) put("Source", source) + put(AnalyticsParam.TOKEN_PARAM, tokenSymbol) + put(AnalyticsParam.BLOCKCHAIN, blockchain) + if (source != null) put(AnalyticsParam.SOURCE, source) }, ) fun addToNotMainAccount() = PortfolioAnalyticsEvent( event = "Button - Add To Account", + category = category, params = buildMap { if (source != null) put("Source", source) }, @@ -37,6 +44,7 @@ internal class PortfolioAnalyticsEvent( fun addButtonClick() = PortfolioAnalyticsEvent( event = "Button - Add Token", + category = category, params = buildMap { if (source != null) put("Source", source) }, @@ -44,6 +52,7 @@ internal class PortfolioAnalyticsEvent( fun addToPortfolioWalletChanged() = PortfolioAnalyticsEvent( event = "Wallet Selected", + category = category, params = buildMap { if (source != null) put("Source", source) }, @@ -51,6 +60,7 @@ internal class PortfolioAnalyticsEvent( fun addToPortfolioContinue(blockchainNames: List) = PortfolioAnalyticsEvent( event = "Token Network Selected", + category = category, params = buildMap { put("Count", blockchainNames.size.toString()) put("Token", tokenSymbol) @@ -61,9 +71,10 @@ internal class PortfolioAnalyticsEvent( fun tokenAdded(blockchainName: String) = PortfolioAnalyticsEvent( event = "Token Added", + category = category, params = buildMap { - put("Token", tokenSymbol) - put("Blockchain", blockchainName) + put(AnalyticsParam.TOKEN_PARAM, tokenSymbol) + put(AnalyticsParam.BLOCKCHAIN, blockchainName) if (source != null) put("Source", source) }, ) @@ -76,6 +87,7 @@ internal class PortfolioAnalyticsEvent( TokenActionsBSContentUM.Action.Stake -> "Popup Get token - Button Stake" else -> "error" }, + category = category, params = buildMap { if (source != null) put("Source", source) }, @@ -83,6 +95,7 @@ internal class PortfolioAnalyticsEvent( fun getTokenLater() = PortfolioAnalyticsEvent( event = "Popup Get token - Button Later", + category = category, params = buildMap { if (source != null) put("Source", source) }, diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/converter/AvailableToAddDataConverter.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/converter/AvailableToAddDataConverter.kt index fd5664787d..ed829bd5c3 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/converter/AvailableToAddDataConverter.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/converter/AvailableToAddDataConverter.kt @@ -3,8 +3,8 @@ package com.tangem.features.commonfeatures.impl.addtoportfolio.converter import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase import com.tangem.domain.markets.FilterAvailableNetworksForWalletUseCase import com.tangem.domain.markets.GetTokenMarketCryptoCurrency +import com.tangem.domain.markets.RawMarketToken import com.tangem.domain.markets.TokenMarketInfo -import com.tangem.domain.markets.TokenMarketParams import com.tangem.domain.models.account.Account import com.tangem.domain.models.account.AccountId import com.tangem.domain.models.account.AccountStatus @@ -27,7 +27,7 @@ internal class AvailableToAddDataConverter @Inject constructor( suspend fun convert( balances: Map, availableNetworks: Set, - marketParams: TokenMarketParams, + marketParams: RawMarketToken, ): AvailableToAddData { suspend fun AccountStatus.CryptoPortfolio.getAvailableToAddAccount(wallet: UserWallet): AvailableToAddAccount? { val currencies = availableNetworks @@ -103,7 +103,7 @@ internal class AvailableToAddDataConverter @Inject constructor( private suspend fun createCryptoCurrency( userWallet: UserWallet, network: TokenMarketInfo.Network, - marketParams: TokenMarketParams, + marketParams: RawMarketToken, account: Account.CryptoPortfolio, ): CryptoCurrency? { return getTokenMarketCryptoCurrency( diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioInitialSelectionResolver.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioInitialSelectionResolver.kt index 8db0647303..dd8d751766 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioInitialSelectionResolver.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioInitialSelectionResolver.kt @@ -2,8 +2,8 @@ package com.tangem.features.commonfeatures.impl.addtoportfolio.model import arrow.core.getOrElse import com.tangem.domain.markets.GetTokenMarketCryptoCurrency +import com.tangem.domain.markets.RawMarketToken import com.tangem.domain.markets.TokenMarketInfo -import com.tangem.domain.markets.TokenMarketParams import com.tangem.domain.models.account.AccountId import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase @@ -21,7 +21,7 @@ internal class AddToPortfolioInitialSelectionResolver @Inject constructor( availableToAddData: AvailableToAddData, orderedNetworks: List, selectedWallet: UserWallet?, - tokenParams: TokenMarketParams, + tokenParams: RawMarketToken, accountToAdd: AvailableToAddAccount? = null, ): InitialSelection? { if (availableToAddData.availableToAddWallets.isEmpty()) return null @@ -85,7 +85,7 @@ internal class AddToPortfolioInitialSelectionResolver @Inject constructor( userWallet: UserWallet, account: AvailableToAddAccount, orderedNetworks: List, - tokenParams: TokenMarketParams, + tokenParams: RawMarketToken, ): TokenMarketInfo.Network? { val availableOrdered = orderedNetworks.filter { candidate -> account.availableToAddNetworks.any { it.networkId == candidate.networkId } diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioModel.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioModel.kt index 7754a0d1ea..9c2305f233 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioModel.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioModel.kt @@ -17,8 +17,8 @@ import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.message.ToastMessage import com.tangem.domain.account.status.usecase.GetCryptoCurrencyActionsUseCaseV2 import com.tangem.domain.markets.GetTokenMarketCryptoCurrency +import com.tangem.domain.markets.RawMarketToken import com.tangem.domain.markets.TokenMarketInfo -import com.tangem.domain.markets.TokenMarketParams import com.tangem.domain.models.account.filterCryptoPortfolio import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus @@ -26,7 +26,6 @@ import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.isMultiCurrency import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase import com.tangem.features.commonfeatures.api.addtoportfolio.* -import com.tangem.features.commonfeatures.api.portfolioselector.PortfolioFetcher import com.tangem.features.commonfeatures.api.portfolioselector.PortfolioSelectorController import com.tangem.features.commonfeatures.impl.R import com.tangem.features.commonfeatures.impl.addtoportfolio.AddTokenComponent @@ -78,8 +77,18 @@ internal class AddToPortfolioModel @Inject constructor( val tokenActionsData: MutableSharedFlow = replayMutableSharedFlow() val addToPortfolioManager: AddToPortfolioManager = params.addToPortfolioManager - val portfolioFetcher: PortfolioFetcher = addToPortfolioManager.portfolioFetcher - val eventBuilder: MutableSharedFlow = replayMutableSharedFlow() + + val paramsSnapshot: AddToPortfolioManager.Params by lazy { + addToPortfolioManager.paramsFlow.replayCache.first() + } + val eventBuilder: PortfolioAnalyticsEvent.EventBuilder by lazy { + val tokenMarketParams = paramsSnapshot.token + PortfolioAnalyticsEvent.EventBuilder( + tokenSymbol = tokenMarketParams.symbol, + source = addToPortfolioManager.analyticsParams.source, + category = addToPortfolioManager.analyticsParams.category, + ) + } val userPortfolioStateController = userPortfolioStateControllerFactory.create( modelScope = modelScope, @@ -120,12 +129,6 @@ internal class AddToPortfolioModel @Inject constructor( .distinctUntilChanged() .stateIn(this) val isAccountMode = portfolioSelectorController.isAccountModeSync() - val tokenMarketParams = addToPortfolioManager.paramsFlow.first().token - val eb = PortfolioAnalyticsEvent.EventBuilder( - tokenSymbol = tokenMarketParams.symbol, - source = addToPortfolioManager.analyticsParams.source, - ) - eventBuilder.tryEmit(eb) // use snapshot data, looks like we don’t need to remap at runtime val data = featureDataFlow.value @@ -172,11 +175,12 @@ internal class AddToPortfolioModel @Inject constructor( ) // suspend until all required data is selected - allRequireForAdd.first() + val firstPair = allRequireForAdd.first() // line of navigation to AddToken screen is finished; cancel the job, select a new root screen firstPartOfNavigation.cancel() - analyticsEventHandler.send(event = eventBuilder.first().popupToConfirm()) + val selectedNetworkName = firstPair.first.cryptoCurrency.network.name + analyticsEventHandler.send(event = eventBuilder.popupToConfirm(selectedNetworkName)) navigation.replaceAll(AddToPortfolioRoutes.AddToken) var middleNavigationJob: Job? = null @@ -204,6 +208,10 @@ internal class AddToPortfolioModel @Inject constructor( val addedToken = callbackDelegate.onTokenAdded.receiveAsFlow().first() middleNavigationJob?.cancel() val selectedPortfolio = selectedPortfolio.first() + analyticsEventHandler.send(eventBuilder.tokenAdded(addedToken.currency.network.name)) + if (!selectedPortfolio.account.account.account.isMainAccount) { + analyticsEventHandler.send(eventBuilder.addToNotMainAccount()) + } val result = AddToPortfolioManager.Result( wallet = selectedPortfolio.userWallet, account = selectedPortfolio.account.account, @@ -225,6 +233,7 @@ internal class AddToPortfolioModel @Inject constructor( } callbackDelegate.onLaterClick.receiveAsFlow().first() + analyticsEventHandler.send(eventBuilder.getTokenLater()) finishSuccessFlow(result) } .catch { throwable -> @@ -247,29 +256,22 @@ internal class AddToPortfolioModel @Inject constructor( channel.close() } - val tokenMarketParams = addToPortfolioManager.paramsFlow.first().token - val eb = PortfolioAnalyticsEvent.EventBuilder( - tokenSymbol = tokenMarketParams.symbol, - source = addToPortfolioManager.analyticsParams.source, - ) - eventBuilder.tryEmit(eb) + val tokenMarketParams = paramsSnapshot.token - val launchMode = addToPortfolioManager.settings.launchMode + val launchMode = paramsSnapshot.launchMode val initialData = featureData .filterIsInstance() .map { it.availableToAddData } .first() if (launchMode is AddToPortfolioManager.LaunchMode.ViaUserPortfolio && - initialData.hasAnyAddedCurrency(launchMode.rawCurrencyId) + initialData.hasAnyAddedCurrency(tokenMarketParams.id) ) { // suspend, must prepare UM before navigate to UserPortfolio - userPortfolioStateController.updateAndWaitNotNullState(initialData, launchMode.rawCurrencyId) + userPortfolioStateController.updateAndWaitNotNullState(initialData, tokenMarketParams.id) navigation.replaceAll(AddToPortfolioRoutes.UserPortfolio) callbackDelegate.onContinueFromUserPortfolio.receiveAsFlow().first() } - - val paramsSnapshot = addToPortfolioManager.paramsFlow.first() val selection = selectionResolver.resolve( availableToAddData = initialData, orderedNetworks = paramsSnapshot.networks, @@ -297,7 +299,8 @@ internal class AddToPortfolioModel @Inject constructor( selectedPortfolio.emit(firstSelectedPortfolio) selectedNetwork.emit(firstSelectedNetwork) - analyticsEventHandler.send(event = eventBuilder.first().popupToConfirm()) + val selectedNetworkName = firstSelectedNetwork.cryptoCurrency.network.name + analyticsEventHandler.send(event = eventBuilder.popupToConfirm(selectedNetworkName)) navigation.replaceAll(AddToPortfolioRoutes.AddToken) var middleNavigationJob: Job? = null @@ -349,6 +352,7 @@ internal class AddToPortfolioModel @Inject constructor( .launchIn(this) callbackDelegate.onLaterClick.receiveAsFlow().first() + analyticsEventHandler.send(eventBuilder.getTokenLater()) finishSuccessFlow(result) } .catch { throwable -> @@ -358,9 +362,9 @@ internal class AddToPortfolioModel @Inject constructor( .launchIn(modelScope) } - private suspend fun logAccountSelector(isAccountMode: Boolean) { + private fun logAccountSelector(isAccountMode: Boolean) { if (isAccountMode) { - analyticsEventHandler.send(eventBuilder.first().popupToChooseAccount()) + analyticsEventHandler.send(eventBuilder.popupToChooseAccount()) } } @@ -402,7 +406,7 @@ internal class AddToPortfolioModel @Inject constructor( private fun changePortfolioNavigationNewFlow( data: AvailableToAddData, orderedNetworks: List, - tokenParams: TokenMarketParams, + tokenParams: RawMarketToken, ): Flow { return setupPortfolioFlow(data) // drop first selected portfolio or any selected before @@ -473,7 +477,7 @@ internal class AddToPortfolioModel @Inject constructor( data.availableToAddWallets[selectedAccountId.userWalletId] ?: return@combine null val availableToAddAccount = availableToAddWallets.availableToAddAccounts[selectedAccountId] ?: return@combine null - if (!isAccountMode) analyticsEventHandler.send(eventBuilder.first().addToPortfolioWalletChanged()) + if (!isAccountMode) analyticsEventHandler.send(eventBuilder.addToPortfolioWalletChanged()) SelectedPortfolio( isAccountMode = isAccountMode, userWallet = availableToAddWallets.userWallet, diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioPreselectedDataModel.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioPreselectedDataModel.kt index a2a388b7b2..d1e84ecc71 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioPreselectedDataModel.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioPreselectedDataModel.kt @@ -12,8 +12,8 @@ import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.message.ToastMessage import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase import com.tangem.domain.markets.GetTokenMarketCryptoCurrency +import com.tangem.domain.markets.RawMarketToken import com.tangem.domain.markets.TokenMarketInfo -import com.tangem.domain.markets.TokenMarketParams import com.tangem.domain.models.account.AccountStatus import com.tangem.domain.models.account.filterCryptoPortfolio import com.tangem.domain.models.currency.CryptoCurrency @@ -31,7 +31,6 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.logging.TangemLogger import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.* -import java.math.BigDecimal import javax.inject.Inject import kotlin.collections.mapNotNull @@ -66,6 +65,7 @@ internal class AddToPortfolioPreselectedDataModel @Inject constructor( val eventBuilder = PortfolioAnalyticsEvent.EventBuilder( tokenSymbol = params.tokenToAdd.symbol, source = AnalyticsParam.ScreensSources.Markets.value, + category = AnalyticsParam.ScreensSources.Markets.value, ) init { @@ -149,17 +149,10 @@ internal class AddToPortfolioPreselectedDataModel @Inject constructor( } private fun minimalTokenMarketParams() = with(params.tokenToAdd) { - TokenMarketParams( + RawMarketToken( id = id, name = name, symbol = symbol, - tokenQuotes = TokenMarketParams.Quotes( - currentPrice = BigDecimal.ZERO, - h24Percent = null, - weekPercent = null, - monthPercent = null, - ), - imageUrl = null, ) } diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddTokenModel.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddTokenModel.kt index ad1eee5632..7b7facbc0e 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddTokenModel.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddTokenModel.kt @@ -85,7 +85,7 @@ internal class AddTokenModel @Inject constructor( uiState.value = um.toggleProgress(true) val blockchainNames = listOf(selectedNetwork.selectedNetwork) .mapNotNull { BlockchainUtils.getNetworkInfo(it.networkId)?.name } - val analyticsEventBuilder = params.eventBuilder.first() + val analyticsEventBuilder = params.eventBuilder analyticsEventHandler.send(analyticsEventBuilder.addToPortfolioContinue(blockchainNames)) analyticsEventHandler.send(analyticsEventBuilder.addButtonClick()) @@ -105,14 +105,6 @@ internal class AddTokenModel @Inject constructor( if (status == null) { processError(error = null) } else { - if (!account.isMainAccount) { - analyticsEventHandler.send(analyticsEventBuilder.addToNotMainAccount()) - } - - analyticsEventHandler.send( - event = analyticsEventBuilder.tokenAdded(status.status.currency.network.name), - ) - params.callbacks.onTokenAdded(status.status) } uiState.value = um.toggleProgress(false) diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/TokenActionsModel.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/TokenActionsModel.kt index 7d2aaadc8c..9619c92763 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/TokenActionsModel.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/TokenActionsModel.kt @@ -64,7 +64,6 @@ internal class TokenActionsModel @Inject constructor( uiBuilder.build( cryptoCurrencyData = cryptoCurrencyData, tokenActionsHandler = tokenActionsHandler, - eventBuilder = analyticsEventBuilder.first(), appCurrency = currentAppCurrency.value, isBalanceHidden = isBalanceHidden, ) @@ -76,7 +75,7 @@ internal class TokenActionsModel @Inject constructor( ) private fun handledQuickAction(handledAction: TokenActionsHandler.HandledQuickAction) = modelScope.launch { - val event = analyticsEventBuilder.first().getTokenActionClick(actionUM = handledAction.action) + val event = analyticsEventBuilder.getTokenActionClick(actionUM = handledAction.action) analyticsEventHandler.send(event) val isReceive = handledAction.action == TokenActionsBSContentUM.Action.Receive if (!isReceive) return@launch diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/TokenActionsUiBuilder.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/TokenActionsUiBuilder.kt index f461212f82..d1f169a0ae 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/TokenActionsUiBuilder.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/TokenActionsUiBuilder.kt @@ -8,7 +8,6 @@ import com.tangem.common.ui.components.currency.icon.converter.CryptoCurrencyToI import com.tangem.common.ui.markets.action.CryptoCurrencyData import com.tangem.common.ui.markets.action.QuickActionsConverter.quickActions import com.tangem.common.ui.markets.action.TokenActionsHandler -import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.ui.DesignFeatureToggles @@ -25,7 +24,6 @@ import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.features.commonfeatures.impl.addtoportfolio.TokenActionsComponent -import com.tangem.features.commonfeatures.impl.addtoportfolio.analytics.PortfolioAnalyticsEvent import com.tangem.features.commonfeatures.impl.addtoportfolio.ui.state.TokenActionsUM import java.math.BigDecimal import javax.inject.Inject @@ -33,7 +31,6 @@ import javax.inject.Inject @ModelScoped internal class TokenActionsUiBuilder @Inject constructor( paramsContainer: ParamsContainer, - private val analyticsEventHandler: AnalyticsEventHandler, private val designFeatureToggles: DesignFeatureToggles, ) { private val params = paramsContainer.require() @@ -41,7 +38,6 @@ internal class TokenActionsUiBuilder @Inject constructor( fun build( cryptoCurrencyData: CryptoCurrencyData, tokenActionsHandler: TokenActionsHandler, - eventBuilder: PortfolioAnalyticsEvent.EventBuilder, appCurrency: AppCurrency, isBalanceHidden: Boolean, ): TokenActionsUM { @@ -49,7 +45,6 @@ internal class TokenActionsUiBuilder @Inject constructor( buildV2( cryptoCurrencyData = cryptoCurrencyData, tokenActionsHandler = tokenActionsHandler, - eventBuilder = eventBuilder, appCurrency = appCurrency, isBalanceHidden = isBalanceHidden, ) @@ -57,7 +52,6 @@ internal class TokenActionsUiBuilder @Inject constructor( buildV1( cryptoCurrencyData = cryptoCurrencyData, tokenActionsHandler = tokenActionsHandler, - eventBuilder = eventBuilder, ) } } @@ -65,7 +59,6 @@ internal class TokenActionsUiBuilder @Inject constructor( private fun buildV1( cryptoCurrencyData: CryptoCurrencyData, tokenActionsHandler: TokenActionsHandler, - eventBuilder: PortfolioAnalyticsEvent.EventBuilder, ): TokenActionsUM { val status = cryptoCurrencyData.status val tokenUM = TokenItemState.Content( @@ -86,7 +79,6 @@ internal class TokenActionsUiBuilder @Inject constructor( isRedesignEnabled = false, ), onLaterClick = { - analyticsEventHandler.send(eventBuilder.getTokenLater()) params.callbacks.onLaterClick() }, ) @@ -95,7 +87,6 @@ internal class TokenActionsUiBuilder @Inject constructor( private fun buildV2( cryptoCurrencyData: CryptoCurrencyData, tokenActionsHandler: TokenActionsHandler, - eventBuilder: PortfolioAnalyticsEvent.EventBuilder, appCurrency: AppCurrency, isBalanceHidden: Boolean, ): TokenActionsUM { @@ -118,7 +109,6 @@ internal class TokenActionsUiBuilder @Inject constructor( isRedesignEnabled = true, ), onLaterClick = { - analyticsEventHandler.send(eventBuilder.getTokenLater()) params.callbacks.onLaterClick() }, isBalancesHidden = isBalanceHidden, diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/ui/DefaultAddToPortfolioManager.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/ui/DefaultAddToPortfolioManager.kt index 7eb7d23e9c..7b833e9e32 100644 --- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/ui/DefaultAddToPortfolioManager.kt +++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/addtoportfolio/ui/DefaultAddToPortfolioManager.kt @@ -1,11 +1,10 @@ package com.tangem.features.commonfeatures.impl.addtoportfolio.ui +import com.tangem.domain.markets.RawMarketToken import com.tangem.domain.markets.TokenMarketInfo -import com.tangem.domain.markets.TokenMarketParams -import com.tangem.features.commonfeatures.api.portfolioselector.PortfolioFetcher import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager -import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager.AnalyticsParams -import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager.Settings +import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager.* +import com.tangem.features.commonfeatures.api.portfolioselector.PortfolioFetcher import com.tangem.features.commonfeatures.impl.addtoportfolio.converter.AvailableToAddDataConverter import com.tangem.utils.coroutines.CoroutineDispatcherProvider import dagger.assisted.Assisted @@ -25,8 +24,8 @@ internal class DefaultAddToPortfolioManager @AssistedInject constructor( ) : AddToPortfolioManager { override val onDismiss: Channel = Channel() - override val onSuccessAdded: Channel = Channel() - override val onAddedTokenClick: Channel = Channel() + override val onSuccessAdded: Channel = Channel() + override val onAddedTokenClick: Channel = Channel() override val portfolioFetcher: PortfolioFetcher = portfolioFetcherFactory.create( mode = PortfolioFetcher.Mode.All(isOnlyMultiCurrency = true), @@ -37,17 +36,17 @@ internal class DefaultAddToPortfolioManager @AssistedInject constructor( override val paramsFlow = internalParamsFlow .transform { internalParams -> - val fullParams = AddToPortfolioManager.Params( + val fullParams = Params( networks = internalParams.networks ?: return@transform, token = internalParams.token ?: return@transform, + launchMode = internalParams.launchMode, ) emit(fullParams) } .distinctUntilChanged() .shareIn(scope = scope, started = SharingStarted.Eagerly, replay = 1) - override val state: MutableStateFlow = - MutableStateFlow(AddToPortfolioManager.State.Loading) + override val state: MutableStateFlow = MutableStateFlow(State.Loading) init { buildFlow() @@ -60,11 +59,11 @@ internal class DefaultAddToPortfolioManager @AssistedInject constructor( onDismiss.trySend(Unit) } - override fun onSuccessAdded(result: AddToPortfolioManager.Result) { + override fun onSuccessAdded(result: Result) { onSuccessAdded.trySend(result) } - override fun onAddedTokenClick(result: AddToPortfolioManager.Result) { + override fun onAddedTokenClick(result: Result) { onAddedTokenClick.trySend(result) } @@ -72,23 +71,32 @@ internal class DefaultAddToPortfolioManager @AssistedInject constructor( updateInternal(networks = networks) } - override fun setTokenParams(token: TokenMarketParams) { + override fun setTokenParams(token: RawMarketToken) { updateInternal(token = token) } - private fun updateInternal(networks: List? = null, token: TokenMarketParams? = null) { + override fun updateLaunchMode(launchMode: LaunchMode) { + updateInternal(launchMode = launchMode) + } + + private fun updateInternal( + networks: List? = null, + token: RawMarketToken? = null, + launchMode: LaunchMode? = null, + ) { internalParamsFlow.update { prev -> val newParams = ParamsInternal( networks = networks ?: prev.networks, token = token ?: prev.token, + launchMode = launchMode ?: prev.launchMode, ) - val shouldReload = prev.networks != newParams.networks || prev.token != newParams.token - if (shouldReload) state.update { AddToPortfolioManager.State.Loading } + val shouldReload = newParams != prev + if (shouldReload) state.update { State.Loading } return@update newParams } } - private fun buildFlow(): Flow = combine( + private fun buildFlow(): Flow = combine( flow = portfolioFetcher.data.map { it.balances }.distinctUntilChanged(), flow2 = paramsFlow, ) { balances, (availableNetworks, token) -> @@ -97,7 +105,7 @@ internal class DefaultAddToPortfolioManager @AssistedInject constructor( availableNetworks = availableNetworks.toSet(), marketParams = token, ) - AddToPortfolioManager.State.Ready(data) + State.Ready(data) } @AssistedFactory @@ -110,7 +118,8 @@ internal class DefaultAddToPortfolioManager @AssistedInject constructor( } private data class ParamsInternal( + val launchMode: LaunchMode = LaunchMode.DirectAdd, val networks: List? = null, - val token: TokenMarketParams? = null, + val token: RawMarketToken? = null, ) } \ No newline at end of file diff --git a/features/common-features/impl/src/test/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioInitialSelectionResolverTest.kt b/features/common-features/impl/src/test/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioInitialSelectionResolverTest.kt index 34c14e1224..3e6307f8ed 100644 --- a/features/common-features/impl/src/test/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioInitialSelectionResolverTest.kt +++ b/features/common-features/impl/src/test/java/com/tangem/features/commonfeatures/impl/addtoportfolio/model/AddToPortfolioInitialSelectionResolverTest.kt @@ -4,8 +4,8 @@ import arrow.core.left import arrow.core.right import com.google.common.truth.Truth import com.tangem.domain.markets.GetTokenMarketCryptoCurrency +import com.tangem.domain.markets.RawMarketToken import com.tangem.domain.markets.TokenMarketInfo -import com.tangem.domain.markets.TokenMarketParams import com.tangem.domain.models.account.AccountId import com.tangem.domain.models.account.DerivationIndex import com.tangem.domain.models.currency.CryptoCurrency @@ -31,7 +31,7 @@ class AddToPortfolioInitialSelectionResolverTest { private val getTokenMarketCryptoCurrency: GetTokenMarketCryptoCurrency = mockk() private val networkHasDerivationUseCase: NetworkHasDerivationUseCase = mockk() - private val tokenParams: TokenMarketParams = mockk() + private val tokenParams: RawMarketToken = mockk() private lateinit var resolver: AddToPortfolioInitialSelectionResolver diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt index 0e521d801a..cb37e92734 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/components/market/details/DefaultMarketsTokenDetailsComponent.kt @@ -99,7 +99,7 @@ internal class DefaultMarketsTokenDetailsComponent( } override fun openAddToPortfolioViaUserPortfolio(rawCurrencyId: CryptoCurrency.RawID) { - model.openAddToPortfolioViaUserPortfolio(rawCurrencyId) + model.openAddToPortfolioViaUserPortfolio() } }, ) @@ -149,10 +149,9 @@ internal class DefaultMarketsTokenDetailsComponent( @Suppress("UNUSED_PARAMETER") config: AddToPortfolioSlotRoute, componentContext: ComponentContext, ): ComposableBottomSheetComponent { - val manager = model.addToPortfolioManagerOrNull() ?: return ComposableBottomSheetComponent.EMPTY return addToPortfolioComponentFactory.create( context = childByContext(componentContext), - params = AddToPortfolioComponent.Params(addToPortfolioManager = manager), + params = AddToPortfolioComponent.Params(addToPortfolioManager = model.addToPortfolioManager), ) } diff --git a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt index 2916584e41..2c3c85e529 100644 --- a/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt +++ b/features/feed/impl/src/main/kotlin/com/tangem/features/feed/model/market/details/MarketsTokenDetailsModel.kt @@ -40,7 +40,6 @@ import com.tangem.domain.card.common.extensions.hotWalletExcludedBlockchains import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.markets.* -import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.news.model.NewsListConfig import com.tangem.domain.news.usecase.GetNewsUseCase @@ -72,7 +71,6 @@ import com.tangem.utils.coroutines.saveIn import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch @@ -238,8 +236,13 @@ internal class MarketsTokenDetailsModel @Inject constructor( private val isAddToPortfolioAvailable: Boolean = params.shouldShowPortfolio && designFeatureToggles.isRedesignEnabled - private var addToPortfolioManager: AddToPortfolioManager? = null - private var addToPortfolioListenersJob: Job? = null + val addToPortfolioManager: AddToPortfolioManager = addToPortfolioManagerFactory.create( + scope = modelScope, + settings = AddToPortfolioManager.Settings( + shouldSkipTokenActionsScreen = false, + ), + analyticsParams = AddToPortfolioManager.AnalyticsParams(params.analyticsParams?.source), + ) val state = MutableStateFlow( MarketsTokenDetailsUM( @@ -329,7 +332,7 @@ internal class MarketsTokenDetailsModel @Inject constructor( modelScope.launch { networksState.collect { tokenNetworkState -> - val manager = addToPortfolioManager ?: return@collect + val manager = addToPortfolioManager when (tokenNetworkState) { is TokenNetworksState.NetworksAvailable -> manager.setTokenNetworks(tokenNetworkState.networks) TokenNetworksState.NoNetworksAvailable -> manager.setTokenNetworks(emptyList()) @@ -337,6 +340,18 @@ internal class MarketsTokenDetailsModel @Inject constructor( } } } + addToPortfolioManager.onDismiss.receiveAsFlow() + .onEach { addToPortfolioSheetNavigation.dismiss() } + .launchIn(modelScope) + addToPortfolioManager.onSuccessAdded.receiveAsFlow() + .onEach { addToPortfolioSheetNavigation.dismiss() } + .launchIn(modelScope) + addToPortfolioManager.onAddedTokenClick.receiveAsFlow() + .onEach { result -> + addToPortfolioSheetNavigation.dismiss() + openTokenDetails(result) + } + .launchIn(modelScope) } fun openAddToPortfolio() { @@ -345,9 +360,9 @@ internal class MarketsTokenDetailsModel @Inject constructor( addToPortfolioSheetNavigation.activate(AddToPortfolioSlotRoute) } - fun openAddToPortfolioViaUserPortfolio(rawCurrencyId: CryptoCurrency.RawID) { + fun openAddToPortfolioViaUserPortfolio() { if (!isAddToPortfolioAvailable) return - prepareAddToPortfolioManager(AddToPortfolioManager.LaunchMode.ViaUserPortfolio(rawCurrencyId)) + prepareAddToPortfolioManager(AddToPortfolioManager.LaunchMode.ViaUserPortfolio) addToPortfolioSheetNavigation.activate(AddToPortfolioSlotRoute) } @@ -360,43 +375,15 @@ internal class MarketsTokenDetailsModel @Inject constructor( ) } - fun addToPortfolioManagerOrNull(): AddToPortfolioManager? = addToPortfolioManager - private fun prepareAddToPortfolioManager(launchMode: AddToPortfolioManager.LaunchMode) { - addToPortfolioListenersJob?.cancel() - val manager = addToPortfolioManagerFactory.create( - scope = modelScope, - settings = AddToPortfolioManager.Settings( - shouldSkipTokenActionsScreen = false, - launchMode = launchMode, - ), - analyticsParams = AddToPortfolioManager.AnalyticsParams(params.analyticsParams?.source), - ) + val manager = addToPortfolioManager manager.setTokenParams(params.token) + manager.updateLaunchMode(launchMode) when (val network = networksState.value) { is TokenNetworksState.NetworksAvailable -> manager.setTokenNetworks(network.networks) TokenNetworksState.NoNetworksAvailable -> manager.setTokenNetworks(emptyList()) else -> Unit } - addToPortfolioManager = manager - addToPortfolioListenersJob = modelScope.launch { - launch { - manager.onDismiss.receiveAsFlow().collect { - addToPortfolioSheetNavigation.dismiss() - } - } - launch { - manager.onSuccessAdded.receiveAsFlow().collect { - addToPortfolioSheetNavigation.dismiss() - } - } - launch { - manager.onAddedTokenClick.receiveAsFlow().collect { result -> - addToPortfolioSheetNavigation.dismiss() - openTokenDetails(result) - } - } - } } private fun initialLoad() {