Updated on 2026-08-14
This commit is contained in:
parent
a44f392d0a
commit
5315e04487
21 changed files with 199 additions and 177 deletions
|
|
@ -247,7 +247,7 @@ internal class DefaultMarketsTokenRepository(
|
|||
|
||||
override suspend fun createCryptoCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
token: TokenMarketParams,
|
||||
token: RawMarketToken,
|
||||
network: TokenMarketInfo.Network,
|
||||
accountIndex: DerivationIndex?,
|
||||
): CryptoCurrency? {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
@ -10,7 +10,7 @@ class GetTokenMarketCryptoCurrency(
|
|||
) {
|
||||
suspend operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
tokenMarketParams: TokenMarketParams,
|
||||
tokenMarketParams: RawMarketToken,
|
||||
network: TokenMarketInfo.Network,
|
||||
accountIndex: DerivationIndex,
|
||||
): CryptoCurrency? {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ interface MarketsTokenRepository {
|
|||
|
||||
suspend fun createCryptoCurrency(
|
||||
userWalletId: UserWalletId,
|
||||
token: TokenMarketParams,
|
||||
token: RawMarketToken,
|
||||
network: TokenMarketInfo.Network,
|
||||
accountIndex: DerivationIndex? = null,
|
||||
): CryptoCurrency?
|
||||
|
|
|
|||
|
|
@ -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<Result>
|
||||
val onAddedTokenClick: Channel<Result>
|
||||
|
||||
val portfolioFetcher: PortfolioFetcher
|
||||
val state: StateFlow<State>
|
||||
|
||||
/**
|
||||
* default is [LaunchMode.DirectAdd]
|
||||
*/
|
||||
fun updateLaunchMode(launchMode: LaunchMode)
|
||||
|
||||
fun setTokenNetworks(networks: List<TokenMarketInfo.Network>)
|
||||
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<TokenMarketInfo.Network>, val token: TokenMarketParams)
|
||||
data class Params(
|
||||
val networks: List<TokenMarketInfo.Network>,
|
||||
val token: RawMarketToken,
|
||||
val launchMode: LaunchMode,
|
||||
)
|
||||
|
||||
data class Result(
|
||||
val wallet: UserWallet,
|
||||
|
|
@ -80,8 +103,10 @@ interface AddToPortfolioManagerInternal {
|
|||
val paramsFlow: SharedFlow<AddToPortfolioManager.Params>
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue