Updated on 2026-08-14
This commit is contained in:
parent
c7269fbadb
commit
305758f4be
5 changed files with 102 additions and 97 deletions
|
|
@ -136,12 +136,12 @@ internal class AddToPortfolioModel @Inject constructor(
|
|||
// but its call AddToPortfolioManager.onAddedTokenClick callback
|
||||
!isAvailableToAdd -> {
|
||||
val singleNetwork = portfolio.account.addedMarketNetworks.first()
|
||||
callbackDelegate.onNetworkSelected(singleNetwork)
|
||||
callbackDelegate.onNetworkSelected.send(singleNetwork)
|
||||
}
|
||||
// force select a network, triggers [selectedNetwork]
|
||||
isSingleAvailableNetwork -> {
|
||||
val singleNetwork = portfolio.account.availableToAddNetworks.first()
|
||||
callbackDelegate.onNetworkSelected(singleNetwork)
|
||||
callbackDelegate.onNetworkSelected.send(singleNetwork)
|
||||
}
|
||||
// it's important to control root screen, UI depends on it(close/arrow icon)
|
||||
isSinglePortfolio -> navigation.replaceAll(routeToNetworkSelector(portfolio))
|
||||
|
|
@ -352,7 +352,7 @@ internal class AddToPortfolioModel @Inject constructor(
|
|||
val isSingleAvailableNetwork = portfolio.account.isSingleNetwork
|
||||
if (isSingleAvailableNetwork) {
|
||||
val singleNetwork = portfolio.account.availableToAddNetworks.first()
|
||||
callbackDelegate.onNetworkSelected(singleNetwork)
|
||||
callbackDelegate.onNetworkSelected.send(singleNetwork)
|
||||
} else {
|
||||
navigation.pushNew(routeToNetworkSelector(portfolio))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,15 +33,14 @@ import com.tangem.core.ui.extensions.stringResourceSafe
|
|||
import com.tangem.core.ui.res.LocalMainBottomSheetColor
|
||||
import com.tangem.core.ui.res.LocalRedesignEnabled
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioComponent
|
||||
import com.tangem.domain.models.earn.PreselectedEarnType
|
||||
import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioComponent
|
||||
import com.tangem.features.feed.components.feed.FeedBottomSheetRoute
|
||||
import kotlinx.serialization.Serializable
|
||||
import com.tangem.features.feed.model.earn.EarnModel
|
||||
import com.tangem.features.feed.model.earn.analytics.EarnSource
|
||||
import com.tangem.features.feed.ui.components.FeedSearchBar
|
||||
import com.tangem.features.feed.ui.earn.EarnContent
|
||||
import dev.chrisbanes.haze.HazeProgressive
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
internal class DefaultEarnComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
|
|
@ -130,17 +129,12 @@ internal class DefaultEarnComponent(
|
|||
componentContext: ComponentContext,
|
||||
): ComposableBottomSheetComponent = when (config) {
|
||||
is FeedBottomSheetRoute.AddToPortfolio -> {
|
||||
val manager = checkNotNull(earnModel.currentAddToPortfolioManager) {
|
||||
"currentAddToPortfolioManager must be set before activating AddToPortfolio slot"
|
||||
}
|
||||
addToPortfolioComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = AddToPortfolioComponent.Params(
|
||||
addToPortfolioManager = when {
|
||||
config.source == EarnSource.BEST_OPPORTUNITIES_SOURCE.value ->
|
||||
earnModel.addBestOpportunitiesPortfolioManager
|
||||
config.source == EarnSource.MOSTLY_USED_SOURCE.value ->
|
||||
earnModel.addMostlyUsedPortfolioManager
|
||||
else -> error("Unknown source: ${config.source}")
|
||||
},
|
||||
),
|
||||
params = AddToPortfolioComponent.Params(addToPortfolioManager = manager),
|
||||
)
|
||||
}
|
||||
is FeedBottomSheetRoute.NetworkFilter -> EarnNetworkFilterComponent(
|
||||
|
|
|
|||
|
|
@ -98,11 +98,12 @@ internal class DefaultFeedComponent(
|
|||
componentContext: ComponentContext,
|
||||
): ComposableBottomSheetComponent = when (config) {
|
||||
is FeedBottomSheetRoute.AddToPortfolio -> {
|
||||
val manager = checkNotNull(feedComponentModel.currentAddToPortfolioManager) {
|
||||
"currentAddToPortfolioManager must be set before activating AddToPortfolio slot"
|
||||
}
|
||||
addToPortfolioComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = AddToPortfolioComponent.Params(
|
||||
addToPortfolioManager = feedComponentModel.addToPortfolioManager,
|
||||
),
|
||||
params = AddToPortfolioComponent.Params(addToPortfolioManager = manager),
|
||||
)
|
||||
}
|
||||
is FeedBottomSheetRoute.NetworkFilter -> EmptyComposableBottomSheetComponent
|
||||
|
|
|
|||
|
|
@ -22,8 +22,9 @@ import com.tangem.domain.markets.TokenMarketInfo
|
|||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.earn.EarnNetworks
|
||||
import com.tangem.domain.models.earn.EarnTokenWithCurrency
|
||||
import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager
|
||||
import com.tangem.domain.models.earn.PreselectedEarnType
|
||||
import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager
|
||||
import com.tangem.features.commonfeatures.api.addtoportfolio.AddToPortfolioManager.AnalyticsParams.Companion.CategoryEarn
|
||||
import com.tangem.features.feed.components.earn.DefaultEarnComponent
|
||||
import com.tangem.features.feed.components.earn.EarnNetworkFilterComponent
|
||||
import com.tangem.features.feed.components.earn.EarnTypeFilterComponent
|
||||
|
|
@ -44,8 +45,8 @@ import com.tangem.features.feed.ui.earn.state.EarnFilterTypeUM
|
|||
import com.tangem.features.feed.ui.earn.state.EarnUM
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
|
|
@ -85,24 +86,13 @@ internal class EarnModel @Inject constructor(
|
|||
dispatchers = dispatchers,
|
||||
)
|
||||
|
||||
val addBestOpportunitiesPortfolioManager: AddToPortfolioManager = addToPortfolioManagerFactory.create(
|
||||
scope = modelScope,
|
||||
settings = AddToPortfolioManager.Settings.Earn,
|
||||
analyticsParams = AddToPortfolioManager.AnalyticsParams(source = EarnSource.BEST_OPPORTUNITIES_SOURCE.value),
|
||||
).apply {
|
||||
updateLaunchMode(AddToPortfolioManager.LaunchMode.Preselected)
|
||||
}
|
||||
|
||||
val addMostlyUsedPortfolioManager: AddToPortfolioManager = addToPortfolioManagerFactory.create(
|
||||
scope = modelScope,
|
||||
settings = AddToPortfolioManager.Settings.Earn,
|
||||
analyticsParams = AddToPortfolioManager.AnalyticsParams(source = EarnSource.MOSTLY_USED_SOURCE.value),
|
||||
).apply {
|
||||
updateLaunchMode(AddToPortfolioManager.LaunchMode.Preselected)
|
||||
}
|
||||
|
||||
val bottomSheetNavigation: SlotNavigation<FeedBottomSheetRoute> = SlotNavigation()
|
||||
|
||||
var currentAddToPortfolioManager: AddToPortfolioManager? = null
|
||||
private set
|
||||
|
||||
private var currentAddToPortfolioManagerScope: CoroutineScope? = null
|
||||
|
||||
val state: StateFlow<EarnUM>
|
||||
get() = stateController.uiState
|
||||
|
||||
|
|
@ -114,30 +104,6 @@ internal class EarnModel @Inject constructor(
|
|||
subscribeOnNetworks()
|
||||
subscribeOnBatchFlow()
|
||||
subscribeToMostlyUsed()
|
||||
|
||||
addBestOpportunitiesPortfolioManager.onDismiss.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.launchIn(modelScope)
|
||||
addBestOpportunitiesPortfolioManager.onSuccessAdded.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.onEach(::openCurrencyDetails)
|
||||
.launchIn(modelScope)
|
||||
addBestOpportunitiesPortfolioManager.onAddedTokenClick.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.onEach(::openCurrencyDetails)
|
||||
.launchIn(modelScope)
|
||||
|
||||
addMostlyUsedPortfolioManager.onDismiss.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.launchIn(modelScope)
|
||||
addMostlyUsedPortfolioManager.onSuccessAdded.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.onEach(::openCurrencyDetails)
|
||||
.launchIn(modelScope)
|
||||
addMostlyUsedPortfolioManager.onAddedTokenClick.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.onEach(::openCurrencyDetails)
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun openCurrencyDetails(result: AddToPortfolioManager.Result) {
|
||||
|
|
@ -354,17 +320,44 @@ internal class EarnModel @Inject constructor(
|
|||
contractAddress = earnTokenWithCurrency.earnToken.tokenAddress,
|
||||
decimalCount = earnTokenWithCurrency.earnToken.decimalCount,
|
||||
)
|
||||
when (source) {
|
||||
EarnSource.BEST_OPPORTUNITIES_SOURCE -> addBestOpportunitiesPortfolioManager.apply {
|
||||
val manager = createAddToPortfolioManager(source = source).apply {
|
||||
setTokenParams(token)
|
||||
setTokenNetworks(listOf(network))
|
||||
}
|
||||
EarnSource.MOSTLY_USED_SOURCE -> addMostlyUsedPortfolioManager.apply {
|
||||
setTokenParams(token)
|
||||
setTokenNetworks(listOf(network))
|
||||
currentAddToPortfolioManager = manager
|
||||
// Drop the slot through null so the same-source repeat click still recreates the child.
|
||||
bottomSheetNavigation.dismiss()
|
||||
bottomSheetNavigation.activate(FeedBottomSheetRoute.AddToPortfolio(source = source.value))
|
||||
}
|
||||
|
||||
private fun createAddToPortfolioManager(source: EarnSource): AddToPortfolioManager {
|
||||
currentAddToPortfolioManagerScope?.cancel()
|
||||
val managerScope = CoroutineScope(
|
||||
modelScope.coroutineContext + SupervisorJob(modelScope.coroutineContext.job),
|
||||
)
|
||||
currentAddToPortfolioManagerScope = managerScope
|
||||
|
||||
val manager = addToPortfolioManagerFactory.create(
|
||||
scope = managerScope,
|
||||
settings = AddToPortfolioManager.Settings.Earn,
|
||||
analyticsParams = AddToPortfolioManager.AnalyticsParams(source = source.value, category = CategoryEarn),
|
||||
).apply {
|
||||
updateLaunchMode(AddToPortfolioManager.LaunchMode.Preselected)
|
||||
}
|
||||
bottomSheetNavigation.activate(FeedBottomSheetRoute.AddToPortfolio(source.value))
|
||||
|
||||
manager.onDismiss.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.launchIn(managerScope)
|
||||
manager.onSuccessAdded.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.onEach(::openCurrencyDetails)
|
||||
.launchIn(managerScope)
|
||||
manager.onAddedTokenClick.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.onEach(::openCurrencyDetails)
|
||||
.launchIn(managerScope)
|
||||
|
||||
return manager
|
||||
}
|
||||
|
||||
private fun onTypeFilterOptionSelected(type: EarnFilterType) {
|
||||
|
|
|
|||
|
|
@ -41,10 +41,8 @@ import com.tangem.utils.Provider
|
|||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentHashMap
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.DateTimeZone
|
||||
import javax.inject.Inject
|
||||
|
|
@ -62,7 +60,7 @@ internal class FeedComponentModel @Inject constructor(
|
|||
private val getTopEarnTokensUseCase: GetTopEarnTokensUseCase,
|
||||
private val appRouter: AppRouter,
|
||||
private val designFeatureToggles: DesignFeatureToggles,
|
||||
addToPortfolioManagerFactory: AddToPortfolioManager.Factory,
|
||||
private val addToPortfolioManagerFactory: AddToPortfolioManager.Factory,
|
||||
getTopFiveMarketTokenUseCase: GetTopFiveMarketTokenUseCase,
|
||||
getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
paramsContainer: ParamsContainer,
|
||||
|
|
@ -87,16 +85,13 @@ internal class FeedComponentModel @Inject constructor(
|
|||
dispatchers = dispatchers,
|
||||
)
|
||||
|
||||
val addToPortfolioManager: AddToPortfolioManager = addToPortfolioManagerFactory.create(
|
||||
scope = modelScope,
|
||||
settings = AddToPortfolioManager.Settings.Earn,
|
||||
analyticsParams = AddToPortfolioManager.AnalyticsParams(source = AnalyticsParam.ScreensSources.Markets.value),
|
||||
).apply {
|
||||
updateLaunchMode(AddToPortfolioManager.LaunchMode.Preselected)
|
||||
}
|
||||
|
||||
val bottomSheetNavigation: SlotNavigation<FeedBottomSheetRoute> = SlotNavigation()
|
||||
|
||||
var currentAddToPortfolioManager: AddToPortfolioManager? = null
|
||||
private set
|
||||
|
||||
private var currentAddToPortfolioManagerScope: CoroutineScope? = null
|
||||
|
||||
val state: StateFlow<FeedListUM>
|
||||
get() = stateController.uiState
|
||||
|
||||
|
|
@ -110,18 +105,6 @@ internal class FeedComponentModel @Inject constructor(
|
|||
fetchCharts()
|
||||
subscribeOnCurrencyUpdate()
|
||||
subscribeOnDataState()
|
||||
|
||||
addToPortfolioManager.onDismiss.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.launchIn(modelScope)
|
||||
addToPortfolioManager.onSuccessAdded.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.onEach(::openCurrencyDetails)
|
||||
.launchIn(modelScope)
|
||||
addToPortfolioManager.onAddedTokenClick.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.onEach(::openCurrencyDetails)
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun openCurrencyDetails(result: AddToPortfolioManager.Result) {
|
||||
|
|
@ -431,12 +414,46 @@ internal class FeedComponentModel @Inject constructor(
|
|||
contractAddress = earnTokenWithCurrency.earnToken.tokenAddress,
|
||||
decimalCount = earnTokenWithCurrency.earnToken.decimalCount,
|
||||
)
|
||||
val route = FeedBottomSheetRoute.AddToPortfolio(AnalyticsParam.ScreensSources.Markets.value)
|
||||
addToPortfolioManager.apply {
|
||||
val manager = createAddToPortfolioManager().apply {
|
||||
setTokenParams(token)
|
||||
setTokenNetworks(listOf(network))
|
||||
}
|
||||
bottomSheetNavigation.activate(route)
|
||||
currentAddToPortfolioManager = manager
|
||||
// Drop the slot through null so the same-source repeat click still recreates the child.
|
||||
bottomSheetNavigation.dismiss()
|
||||
bottomSheetNavigation.activate(FeedBottomSheetRoute.AddToPortfolio(AnalyticsParam.ScreensSources.Markets.value))
|
||||
}
|
||||
|
||||
private fun createAddToPortfolioManager(): AddToPortfolioManager {
|
||||
currentAddToPortfolioManagerScope?.cancel()
|
||||
val managerScope = CoroutineScope(
|
||||
modelScope.coroutineContext + SupervisorJob(modelScope.coroutineContext.job),
|
||||
)
|
||||
currentAddToPortfolioManagerScope = managerScope
|
||||
|
||||
val manager = addToPortfolioManagerFactory.create(
|
||||
scope = managerScope,
|
||||
settings = AddToPortfolioManager.Settings.Earn,
|
||||
analyticsParams = AddToPortfolioManager.AnalyticsParams(
|
||||
source = AnalyticsParam.ScreensSources.Markets.value,
|
||||
),
|
||||
).apply {
|
||||
updateLaunchMode(AddToPortfolioManager.LaunchMode.Preselected)
|
||||
}
|
||||
|
||||
manager.onDismiss.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.launchIn(managerScope)
|
||||
manager.onSuccessAdded.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.onEach(::openCurrencyDetails)
|
||||
.launchIn(managerScope)
|
||||
manager.onAddedTokenClick.receiveAsFlow()
|
||||
.onEach { bottomSheetNavigation.dismiss() }
|
||||
.onEach(::openCurrencyDetails)
|
||||
.launchIn(managerScope)
|
||||
|
||||
return manager
|
||||
}
|
||||
|
||||
private fun handleEarnPageOpenClicked() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue