Updated on 2026-08-14
This commit is contained in:
parent
a44f392d0a
commit
5315e04487
21 changed files with 199 additions and 177 deletions
|
|
@ -45,7 +45,7 @@ internal class AddTokenComponent @AssistedInject constructor(
|
|||
}
|
||||
|
||||
data class Params(
|
||||
val eventBuilder: Flow<PortfolioAnalyticsEvent.EventBuilder>,
|
||||
val eventBuilder: PortfolioAnalyticsEvent.EventBuilder,
|
||||
val selectedPortfolio: Flow<SelectedPortfolio>,
|
||||
val selectedNetwork: Flow<SelectedNetwork>,
|
||||
val callbacks: Callbacks,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ internal class TokenActionsComponent @AssistedInject constructor(
|
|||
)
|
||||
|
||||
data class Params(
|
||||
val eventBuilder: Flow<PortfolioAnalyticsEvent.EventBuilder>,
|
||||
val eventBuilder: PortfolioAnalyticsEvent.EventBuilder,
|
||||
val data: Flow<CryptoCurrencyData>,
|
||||
val callbacks: Callbacks,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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<String, String> = 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<String>) = 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)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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<UserWalletId, PortfolioFetcher.PortfolioBalance>,
|
||||
availableNetworks: Set<TokenMarketInfo.Network>,
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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<TokenMarketInfo.Network>,
|
||||
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<TokenMarketInfo.Network>,
|
||||
tokenParams: TokenMarketParams,
|
||||
tokenParams: RawMarketToken,
|
||||
): TokenMarketInfo.Network? {
|
||||
val availableOrdered = orderedNetworks.filter { candidate ->
|
||||
account.availableToAddNetworks.any { it.networkId == candidate.networkId }
|
||||
|
|
|
|||
|
|
@ -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<CryptoCurrencyData> = replayMutableSharedFlow()
|
||||
|
||||
val addToPortfolioManager: AddToPortfolioManager = params.addToPortfolioManager
|
||||
val portfolioFetcher: PortfolioFetcher = addToPortfolioManager.portfolioFetcher
|
||||
val eventBuilder: MutableSharedFlow<PortfolioAnalyticsEvent.EventBuilder> = 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<AddToPortfolioManager.State.Ready>()
|
||||
.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<TokenMarketInfo.Network>,
|
||||
tokenParams: TokenMarketParams,
|
||||
tokenParams: RawMarketToken,
|
||||
): Flow<Unit> {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<TokenActionsComponent.Params>()
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<Unit> = Channel()
|
||||
override val onSuccessAdded: Channel<AddToPortfolioManager.Result> = Channel()
|
||||
override val onAddedTokenClick: Channel<AddToPortfolioManager.Result> = Channel()
|
||||
override val onSuccessAdded: Channel<Result> = Channel()
|
||||
override val onAddedTokenClick: Channel<Result> = 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<AddToPortfolioManager.State> =
|
||||
MutableStateFlow(AddToPortfolioManager.State.Loading)
|
||||
override val state: MutableStateFlow<State> = 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<TokenMarketInfo.Network>? = null, token: TokenMarketParams? = null) {
|
||||
override fun updateLaunchMode(launchMode: LaunchMode) {
|
||||
updateInternal(launchMode = launchMode)
|
||||
}
|
||||
|
||||
private fun updateInternal(
|
||||
networks: List<TokenMarketInfo.Network>? = 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<AddToPortfolioManager.State> = combine(
|
||||
private fun buildFlow(): Flow<State> = 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<TokenMarketInfo.Network>? = null,
|
||||
val token: TokenMarketParams? = null,
|
||||
val token: RawMarketToken? = null,
|
||||
)
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue