Updated on 2026-08-14
This commit is contained in:
parent
4aa267c951
commit
0548571089
41 changed files with 573 additions and 347 deletions
|
|
@ -45,4 +45,14 @@ object EarnDomainModule {
|
|||
fun provideGetEarnTokensBatchFlowUseCase(repository: EarnRepository): GetEarnTokensBatchFlowUseCase {
|
||||
return GetEarnTokensBatchFlowUseCase(repository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideGetEarnFilterUseCase(repository: EarnRepository): GetEarnFilterUseCase {
|
||||
return GetEarnFilterUseCase(repository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideSetEarnFilterUseCase(repository: EarnRepository): SetEarnFilterUseCase {
|
||||
return SetEarnFilterUseCase(repository)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.data.earn.datastore
|
||||
|
||||
import com.tangem.datasource.local.datastore.RuntimeStateStore
|
||||
import com.tangem.domain.earn.model.EarnFilter
|
||||
import com.tangem.domain.earn.model.EarnFilterNetwork
|
||||
import com.tangem.domain.earn.model.EarnFilterType
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
internal class EarnFilterStore @Inject constructor() :
|
||||
RuntimeStateStore<EarnFilter> by RuntimeStateStore(
|
||||
defaultValue = EarnFilter(
|
||||
earnFilterNetwork = EarnFilterNetwork.AllNetworks(isSelected = true),
|
||||
earnFilterType = EarnFilterType.ALL,
|
||||
),
|
||||
)
|
||||
|
|
@ -6,7 +6,7 @@ import javax.inject.Inject
|
|||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class EarnNetworksStore @Inject constructor() :
|
||||
internal class EarnNetworksStore @Inject constructor() :
|
||||
RuntimeStateStore<EarnNetworks?> by RuntimeStateStore(
|
||||
defaultValue = null,
|
||||
)
|
||||
|
|
@ -6,7 +6,7 @@ import javax.inject.Inject
|
|||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class EarnTopTokensStore @Inject constructor() :
|
||||
internal class EarnTopTokensStore @Inject constructor() :
|
||||
RuntimeStateStore<EarnTopToken?> by RuntimeStateStore(
|
||||
defaultValue = null,
|
||||
)
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.data.earn.di
|
|||
|
||||
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
||||
import com.tangem.data.earn.DefaultEarnErrorResolver
|
||||
import com.tangem.data.earn.datastore.EarnFilterStore
|
||||
import com.tangem.data.earn.datastore.EarnNetworksStore
|
||||
import com.tangem.data.earn.datastore.EarnTopTokensStore
|
||||
import com.tangem.data.earn.repository.DefaultEarnRepository
|
||||
|
|
@ -31,6 +32,7 @@ internal object EarnDataModule {
|
|||
userWalletsListRepository: UserWalletsListRepository,
|
||||
earnNetworksStore: EarnNetworksStore,
|
||||
earnTopTokensStore: EarnTopTokensStore,
|
||||
earnFilterStore: EarnFilterStore,
|
||||
earnErrorResolver: EarnErrorResolver,
|
||||
excludedBlockchains: ExcludedBlockchains,
|
||||
): EarnRepository {
|
||||
|
|
@ -42,6 +44,7 @@ internal object EarnDataModule {
|
|||
earnTopTokensStore = earnTopTokensStore,
|
||||
earnErrorResolver = earnErrorResolver,
|
||||
excludedBlockchains = excludedBlockchains,
|
||||
earnFilterStore = earnFilterStore,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
|||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.data.common.currency.CryptoCurrencyFactory
|
||||
import com.tangem.data.earn.converter.EarnTokenConverter
|
||||
import com.tangem.data.earn.datastore.EarnFilterStore
|
||||
import com.tangem.data.earn.datastore.EarnNetworksStore
|
||||
import com.tangem.data.earn.datastore.EarnTopTokensStore
|
||||
import com.tangem.data.earn.repository.batch.EarnTokensBatchFetcher
|
||||
|
|
@ -14,6 +15,7 @@ import com.tangem.datasource.api.tangemTech.TangemTechApi
|
|||
import com.tangem.datasource.api.tangemTech.models.EarnResponse
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.earn.EarnErrorResolver
|
||||
import com.tangem.domain.earn.model.EarnFilter
|
||||
import com.tangem.domain.earn.model.EarnTokensBatchFlow
|
||||
import com.tangem.domain.earn.model.EarnTokensBatchingContext
|
||||
import com.tangem.domain.earn.repository.EarnRepository
|
||||
|
|
@ -38,6 +40,7 @@ internal class DefaultEarnRepository(
|
|||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val earnNetworksStore: EarnNetworksStore,
|
||||
private val earnTopTokensStore: EarnTopTokensStore,
|
||||
private val earnFilterStore: EarnFilterStore,
|
||||
private val earnErrorResolver: EarnErrorResolver,
|
||||
private val excludedBlockchains: ExcludedBlockchains,
|
||||
) : EarnRepository {
|
||||
|
|
@ -123,6 +126,14 @@ internal class DefaultEarnRepository(
|
|||
return earnTopTokensStore.get()
|
||||
}
|
||||
|
||||
override fun observeEarnFilter(): Flow<EarnFilter> {
|
||||
return earnFilterStore.get()
|
||||
}
|
||||
|
||||
override suspend fun setEarnFilter(filter: EarnFilter) {
|
||||
earnFilterStore.store(filter)
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal const val FIRST_PAGE = 1
|
||||
private const val INITIAL_BATCH_KEY = 0
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
package com.tangem.domain.earn.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class EarnFilter(
|
||||
val earnFilterNetwork: EarnFilterNetwork,
|
||||
val earnFilterType: EarnFilterType,
|
||||
)
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.domain.earn.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
sealed interface EarnFilterNetwork {
|
||||
|
||||
val isSelected: Boolean
|
||||
|
||||
@Serializable
|
||||
data class AllNetworks(
|
||||
override val isSelected: Boolean,
|
||||
) : EarnFilterNetwork
|
||||
|
||||
@Serializable
|
||||
data class MyNetworks(
|
||||
override val isSelected: Boolean,
|
||||
) : EarnFilterNetwork
|
||||
|
||||
@Serializable
|
||||
data class Specific(
|
||||
override val isSelected: Boolean,
|
||||
val id: String,
|
||||
val symbol: String,
|
||||
val fullName: String,
|
||||
) : EarnFilterNetwork
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.domain.earn.model
|
||||
|
||||
enum class EarnFilterType {
|
||||
ALL,
|
||||
STAKING,
|
||||
YIELD,
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.domain.earn.repository
|
||||
|
||||
import com.tangem.domain.earn.model.EarnFilter
|
||||
import com.tangem.domain.earn.model.EarnTokensBatchFlow
|
||||
import com.tangem.domain.earn.model.EarnTokensBatchingContext
|
||||
import com.tangem.domain.models.earn.EarnNetworks
|
||||
|
|
@ -23,4 +24,8 @@ interface EarnRepository {
|
|||
suspend fun fetchTopEarnTokens(limit: Int)
|
||||
|
||||
fun observeTopEarnTokens(): Flow<EarnTopToken?>
|
||||
|
||||
fun observeEarnFilter(): Flow<EarnFilter>
|
||||
|
||||
suspend fun setEarnFilter(filter: EarnFilter)
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.domain.earn.usecase
|
||||
|
||||
import com.tangem.domain.earn.model.EarnFilter
|
||||
import com.tangem.domain.earn.repository.EarnRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class GetEarnFilterUseCase(private val repository: EarnRepository) {
|
||||
|
||||
operator fun invoke(): Flow<EarnFilter> {
|
||||
return repository.observeEarnFilter()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.domain.earn.usecase
|
||||
|
||||
import com.tangem.domain.earn.model.EarnFilter
|
||||
import com.tangem.domain.earn.repository.EarnRepository
|
||||
|
||||
class SetEarnFilterUseCase(private val repository: EarnRepository) {
|
||||
|
||||
suspend operator fun invoke(filter: EarnFilter) {
|
||||
repository.setEarnFilter(filter)
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
|||
import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.LocalMainBottomSheetColor
|
||||
import com.tangem.features.feed.components.feed.FeedPortfolioRoute
|
||||
import com.tangem.features.feed.components.feed.FeedBottomSheetRoute
|
||||
import com.tangem.features.feed.components.market.details.portfolio.add.AddToPortfolioPreselectedDataComponent
|
||||
import com.tangem.features.feed.model.earn.EarnModel
|
||||
import com.tangem.features.feed.ui.earn.EarnContent
|
||||
|
|
@ -35,7 +35,7 @@ internal class DefaultEarnComponent(
|
|||
|
||||
private val bottomSheetSlot = childSlot(
|
||||
source = earnModel.bottomSheetNavigation,
|
||||
serializer = FeedPortfolioRoute.serializer(),
|
||||
serializer = null,
|
||||
handleBackButton = false,
|
||||
childFactory = ::bottomSheetChild,
|
||||
)
|
||||
|
|
@ -68,10 +68,10 @@ internal class DefaultEarnComponent(
|
|||
}
|
||||
|
||||
private fun bottomSheetChild(
|
||||
config: FeedPortfolioRoute,
|
||||
config: FeedBottomSheetRoute,
|
||||
componentContext: ComponentContext,
|
||||
): ComposableBottomSheetComponent = when (config) {
|
||||
is FeedPortfolioRoute.AddToPortfolio -> {
|
||||
is FeedBottomSheetRoute.AddToPortfolio -> {
|
||||
addToPortfolioComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = AddToPortfolioPreselectedDataComponent.Params(
|
||||
|
|
@ -80,6 +80,14 @@ internal class DefaultEarnComponent(
|
|||
),
|
||||
)
|
||||
}
|
||||
is FeedBottomSheetRoute.NetworkFilter -> EarnNetworkFilterComponent(
|
||||
context = childByContext(componentContext),
|
||||
params = config.params,
|
||||
)
|
||||
is FeedBottomSheetRoute.TypeFilter -> EarnTypeFilterComponent(
|
||||
context = childByContext(componentContext),
|
||||
params = config.params,
|
||||
)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
package com.tangem.features.feed.components.earn
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.domain.earn.model.EarnFilterNetwork
|
||||
import com.tangem.features.feed.model.earn.filters.EarnNetworkFilterModel
|
||||
import com.tangem.features.feed.ui.earn.components.EarnFilterByNetworkBottomSheet
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
internal class EarnNetworkFilterComponent @AssistedInject constructor(
|
||||
@Assisted context: AppComponentContext,
|
||||
@Assisted private val params: Params,
|
||||
) : AppComponentContext by context, ComposableBottomSheetComponent {
|
||||
|
||||
private val model = getOrCreateModel<EarnNetworkFilterModel, Params>(params = params)
|
||||
|
||||
override fun dismiss() {
|
||||
params.onDismiss()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun BottomSheet() {
|
||||
val state = model.state.collectAsStateWithLifecycle()
|
||||
EarnFilterByNetworkBottomSheet(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = ::dismiss,
|
||||
content = state.value,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
data class Params(
|
||||
val allFilters: List<EarnFilterNetwork>,
|
||||
val onFilterSelected: (EarnFilterNetwork) -> Unit,
|
||||
val onDismiss: () -> Unit,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.tangem.features.feed.components.earn
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.domain.earn.model.EarnFilterType
|
||||
import com.tangem.features.feed.model.earn.filters.EarnTypeFilterModel
|
||||
import com.tangem.features.feed.ui.earn.components.EarnFilterByTypeBottomSheet
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
internal class EarnTypeFilterComponent @AssistedInject constructor(
|
||||
@Assisted context: AppComponentContext,
|
||||
@Assisted private val params: Params,
|
||||
) : AppComponentContext by context, ComposableBottomSheetComponent {
|
||||
|
||||
private val model = getOrCreateModel<EarnTypeFilterModel, Params>(params = params)
|
||||
|
||||
override fun dismiss() {
|
||||
params.onDismiss()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun BottomSheet() {
|
||||
val state = model.state.collectAsStateWithLifecycle()
|
||||
|
||||
EarnFilterByTypeBottomSheet(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = ::dismiss,
|
||||
content = state.value,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
data class Params(
|
||||
val selectedFilter: EarnFilterType,
|
||||
val onFilterSelected: (EarnFilterType) -> Unit,
|
||||
val onDismiss: () -> Unit,
|
||||
)
|
||||
}
|
||||
|
|
@ -15,7 +15,9 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
|||
import com.tangem.core.ui.components.bottomsheets.state.BottomSheetState
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.core.ui.decompose.ComposableModularBottomSheetContentComponent
|
||||
import com.tangem.core.ui.decompose.EmptyComposableBottomSheetComponent
|
||||
import com.tangem.features.feed.components.market.details.portfolio.add.AddToPortfolioPreselectedDataComponent
|
||||
import com.tangem.features.feed.components.market.details.portfolio.add.AddToPortfolioPreselectedDataComponent.Params
|
||||
import com.tangem.features.feed.model.feed.FeedComponentModel
|
||||
import com.tangem.features.feed.model.feed.FeedModelClickIntents
|
||||
import com.tangem.features.feed.ui.feed.FeedList
|
||||
|
|
@ -31,7 +33,7 @@ internal class DefaultFeedComponent(
|
|||
|
||||
private val bottomSheetSlot = childSlot(
|
||||
source = feedComponentModel.bottomSheetNavigation,
|
||||
serializer = FeedPortfolioRoute.serializer(),
|
||||
serializer = null,
|
||||
handleBackButton = false,
|
||||
childFactory = ::bottomSheetChild,
|
||||
)
|
||||
|
|
@ -64,18 +66,20 @@ internal class DefaultFeedComponent(
|
|||
}
|
||||
|
||||
private fun bottomSheetChild(
|
||||
config: FeedPortfolioRoute,
|
||||
config: FeedBottomSheetRoute,
|
||||
componentContext: ComponentContext,
|
||||
): ComposableBottomSheetComponent = when (config) {
|
||||
is FeedPortfolioRoute.AddToPortfolio -> {
|
||||
is FeedBottomSheetRoute.AddToPortfolio -> {
|
||||
addToPortfolioComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = AddToPortfolioPreselectedDataComponent.Params(
|
||||
params = Params(
|
||||
tokenToAdd = config.tokenToAdd,
|
||||
callback = feedComponentModel.addToPortfolioCallback,
|
||||
),
|
||||
)
|
||||
}
|
||||
is FeedBottomSheetRoute.NetworkFilter -> EmptyComposableBottomSheetComponent
|
||||
is FeedBottomSheetRoute.TypeFilter -> EmptyComposableBottomSheetComponent
|
||||
}
|
||||
|
||||
data class FeedParams(val feedClickIntents: FeedModelClickIntents)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.features.feed.components.feed
|
||||
|
||||
import com.tangem.features.feed.components.earn.EarnNetworkFilterComponent
|
||||
import com.tangem.features.feed.components.earn.EarnTypeFilterComponent
|
||||
import com.tangem.features.feed.components.market.details.portfolio.add.AddToPortfolioPreselectedDataComponent
|
||||
|
||||
internal sealed interface FeedBottomSheetRoute {
|
||||
|
||||
data class AddToPortfolio(val tokenToAdd: AddToPortfolioPreselectedDataComponent.TokenToAdd) : FeedBottomSheetRoute
|
||||
|
||||
data class NetworkFilter(val params: EarnNetworkFilterComponent.Params) : FeedBottomSheetRoute
|
||||
|
||||
data class TypeFilter(val params: EarnTypeFilterComponent.Params) : FeedBottomSheetRoute
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package com.tangem.features.feed.components.feed
|
||||
|
||||
import com.tangem.features.feed.components.market.details.portfolio.add.AddToPortfolioPreselectedDataComponent
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
sealed interface FeedPortfolioRoute {
|
||||
|
||||
@Serializable
|
||||
data class AddToPortfolio(val tokenToAdd: AddToPortfolioPreselectedDataComponent.TokenToAdd) : FeedPortfolioRoute
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ import com.tangem.core.decompose.di.ModelComponent
|
|||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.features.feed.model.FeedEntryModel
|
||||
import com.tangem.features.feed.model.earn.EarnModel
|
||||
import com.tangem.features.feed.model.earn.filters.EarnNetworkFilterModel
|
||||
import com.tangem.features.feed.model.earn.filters.EarnTypeFilterModel
|
||||
import com.tangem.features.feed.model.feed.FeedComponentModel
|
||||
import com.tangem.features.feed.model.market.details.MarketsTokenDetailsModel
|
||||
import com.tangem.features.feed.model.market.list.MarketsListModel
|
||||
|
|
@ -53,4 +55,14 @@ internal interface ModelModule {
|
|||
@IntoMap
|
||||
@ClassKey(FeedEntryModel::class)
|
||||
fun provideFeedEntryModel(model: FeedEntryModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(EarnNetworkFilterModel::class)
|
||||
fun provideEarnNetworkFilterModel(model: EarnNetworkFilterModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(EarnTypeFilterModel::class)
|
||||
fun provideEarnTypeFilterModel(model: EarnTypeFilterModel): Model
|
||||
}
|
||||
|
|
@ -5,14 +5,14 @@ import arrow.core.Either
|
|||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.arkivanov.decompose.router.slot.dismiss
|
||||
import com.tangem.common.R
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.earn.model.EarnFilter
|
||||
import com.tangem.domain.earn.model.EarnFilterNetwork
|
||||
import com.tangem.domain.earn.model.EarnFilterType
|
||||
import com.tangem.domain.earn.usecase.*
|
||||
import com.tangem.domain.markets.TokenMarketInfo
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
|
|
@ -20,17 +20,26 @@ import com.tangem.domain.models.earn.EarnNetworks
|
|||
import com.tangem.domain.models.earn.EarnTokenWithCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.feed.components.earn.DefaultEarnComponent
|
||||
import com.tangem.features.feed.components.feed.FeedPortfolioRoute
|
||||
import com.tangem.features.feed.components.earn.EarnNetworkFilterComponent
|
||||
import com.tangem.features.feed.components.earn.EarnTypeFilterComponent
|
||||
import com.tangem.features.feed.components.feed.FeedBottomSheetRoute
|
||||
import com.tangem.features.feed.components.market.details.portfolio.add.AddToPortfolioPreselectedDataComponent
|
||||
import com.tangem.features.feed.model.earn.filters.state.EarnFilterNetworkConverter
|
||||
import com.tangem.features.feed.model.earn.filters.state.EarnFilterNetworkUMConverter
|
||||
import com.tangem.features.feed.model.earn.filters.state.EarnFilterTypeConverter
|
||||
import com.tangem.features.feed.model.earn.filters.state.EarnFilterTypeUMConverter
|
||||
import com.tangem.features.feed.model.earn.state.EarnStateController
|
||||
import com.tangem.features.feed.model.earn.state.converter.EarnNetworksConverter
|
||||
import com.tangem.features.feed.model.earn.state.transformers.*
|
||||
import com.tangem.features.feed.model.earn.state.transformers.EarnFilterSelectedStateTransformer
|
||||
import com.tangem.features.feed.model.earn.state.transformers.UpdateBestOpportunitiesStateTransformer
|
||||
import com.tangem.features.feed.model.earn.state.transformers.UpdateEarnUMInitialStateTransformer
|
||||
import com.tangem.features.feed.model.earn.state.transformers.UpdateMostlyUsedStateTransformer
|
||||
import com.tangem.features.feed.model.earn.statemanager.EarnListBatchFlowManager
|
||||
import com.tangem.features.feed.model.earn.statemanager.EarnListStateManager
|
||||
import com.tangem.features.feed.ui.earn.state.*
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterNetworkUM
|
||||
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.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
|
@ -46,13 +55,14 @@ internal class EarnModel @Inject constructor(
|
|||
private val getEarnTokensBatchFlowUseCase: GetEarnTokensBatchFlowUseCase,
|
||||
private val getTopEarnTokensUseCase: GetTopEarnTokensUseCase,
|
||||
private val fetchTopEarnTokensUseCase: FetchTopEarnTokensUseCase,
|
||||
private val getEarnFilterUseCase: GetEarnFilterUseCase,
|
||||
private val setEarnFilterUseCase: SetEarnFilterUseCase,
|
||||
private val appRouter: AppRouter,
|
||||
private val stateController: EarnStateController,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<DefaultEarnComponent.Params>()
|
||||
private val earnNetworks = MutableStateFlow<EarnNetworks>(Either.Right(emptyList()))
|
||||
private val earnNetworksConverter: EarnNetworksConverter by lazy { EarnNetworksConverter() }
|
||||
private val earnListConfigProvider = Provider {
|
||||
createEarnTokensListConfig(
|
||||
selectedTypeFilter = stateController.value.selectedTypeFilter,
|
||||
|
|
@ -61,17 +71,15 @@ internal class EarnModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private val batchFlowManager by lazy {
|
||||
EarnListBatchFlowManager(
|
||||
getEarnTokensBatchFlowUseCase = getEarnTokensBatchFlowUseCase,
|
||||
configProvider = earnListConfigProvider,
|
||||
onItemClick = ::onEarnTokenClick,
|
||||
modelScope = modelScope,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
private val batchFlowManager = EarnListBatchFlowManager(
|
||||
getEarnTokensBatchFlowUseCase = getEarnTokensBatchFlowUseCase,
|
||||
configProvider = earnListConfigProvider,
|
||||
onItemClick = ::onEarnTokenClick,
|
||||
modelScope = modelScope,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
|
||||
val bottomSheetNavigation: SlotNavigation<FeedPortfolioRoute> = SlotNavigation()
|
||||
val bottomSheetNavigation: SlotNavigation<FeedBottomSheetRoute> = SlotNavigation()
|
||||
|
||||
val addToPortfolioCallback = object : AddToPortfolioPreselectedDataComponent.Callback {
|
||||
override fun onDismiss() = bottomSheetNavigation.dismiss()
|
||||
|
|
@ -93,6 +101,7 @@ internal class EarnModel @Inject constructor(
|
|||
updateInitialState()
|
||||
fetchEarnNetworks()
|
||||
fetchTopEarnTokens()
|
||||
subscribeOnStoredFilters()
|
||||
subscribeOnNetworks()
|
||||
subscribeOnBatchFlow()
|
||||
subscribeToMostlyUsed()
|
||||
|
|
@ -117,9 +126,7 @@ internal class EarnModel @Inject constructor(
|
|||
)
|
||||
}.onEach { bestOpportunitiesState ->
|
||||
stateController.update(UpdateBestOpportunitiesStateTransformer(bestOpportunitiesState))
|
||||
}
|
||||
.onStart { batchFlowManager.reload() }
|
||||
.launchIn(modelScope)
|
||||
}.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun subscribeToMostlyUsed() {
|
||||
|
|
@ -142,6 +149,23 @@ internal class EarnModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun subscribeOnStoredFilters() {
|
||||
modelScope.launch(dispatchers.default) {
|
||||
getEarnFilterUseCase()
|
||||
.collect { filter ->
|
||||
val typeFilterUM = EarnFilterTypeConverter().convert(filter.earnFilterType)
|
||||
val networkFilterUM = EarnFilterNetworkConverter().convert(filter.earnFilterNetwork)
|
||||
stateController.update(
|
||||
EarnFilterSelectedStateTransformer(
|
||||
filterType = typeFilterUM,
|
||||
filterNetwork = networkFilterUM,
|
||||
),
|
||||
)
|
||||
batchFlowManager.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchTopEarnTokens() {
|
||||
modelScope.launch(dispatchers.default) {
|
||||
fetchTopEarnTokensUseCase()
|
||||
|
|
@ -154,142 +178,73 @@ internal class EarnModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun createTypeFilterBottomSheetConfig(
|
||||
selectedOption: EarnFilterTypeUM,
|
||||
isShown: Boolean = false,
|
||||
): TangemBottomSheetConfig {
|
||||
return TangemBottomSheetConfig(
|
||||
isShown = isShown,
|
||||
onDismissRequest = ::hideTypeFilterBottomSheet,
|
||||
content = EarnFilterByTypeBottomSheetContentUM(
|
||||
selectedOption = selectedOption,
|
||||
onOptionClick = ::onTypeFilterOptionSelected,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createNetworkFilterBottomSheetConfig(
|
||||
selectedNetwork: EarnFilterNetworkUM,
|
||||
isShown: Boolean = false,
|
||||
): TangemBottomSheetConfig {
|
||||
val filters = buildList {
|
||||
add(
|
||||
EarnFilterNetworkUM.AllNetworks(
|
||||
text = TextReference.Res(R.string.earn_filter_all_networks),
|
||||
isSelected = false,
|
||||
),
|
||||
)
|
||||
add(
|
||||
EarnFilterNetworkUM.MyNetworks(
|
||||
text = TextReference.Res(R.string.earn_filter_my_networks),
|
||||
isSelected = false,
|
||||
),
|
||||
)
|
||||
earnNetworks.value.onRight { networks ->
|
||||
addAll(networks.map(earnNetworksConverter::convert))
|
||||
}
|
||||
}
|
||||
|
||||
val updatedNetworks = filters.map { filter ->
|
||||
val shouldBeSelected = when (filter) {
|
||||
is EarnFilterNetworkUM.AllNetworks -> selectedNetwork is EarnFilterNetworkUM.AllNetworks
|
||||
is EarnFilterNetworkUM.MyNetworks -> selectedNetwork is EarnFilterNetworkUM.MyNetworks
|
||||
is EarnFilterNetworkUM.Network ->
|
||||
selectedNetwork is EarnFilterNetworkUM.Network && filter.id == selectedNetwork.id
|
||||
}
|
||||
|
||||
if (filter.isSelected != shouldBeSelected) {
|
||||
when (filter) {
|
||||
is EarnFilterNetworkUM.AllNetworks -> filter.copy(isSelected = shouldBeSelected)
|
||||
is EarnFilterNetworkUM.MyNetworks -> filter.copy(isSelected = shouldBeSelected)
|
||||
is EarnFilterNetworkUM.Network -> filter.copy(isSelected = shouldBeSelected)
|
||||
}
|
||||
} else {
|
||||
filter
|
||||
}
|
||||
}
|
||||
|
||||
return TangemBottomSheetConfig(
|
||||
isShown = isShown,
|
||||
onDismissRequest = ::hideNetworkFilterBottomSheet,
|
||||
content = EarnFilterByNetworkBottomSheetContentUM(
|
||||
selectedNetwork = selectedNetwork,
|
||||
networks = persistentListOf(*updatedNetworks.toTypedArray()),
|
||||
onOptionClick = ::onNetworkFilterOptionSelected,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/* start of clicks area */
|
||||
private fun onTypeFilterClick() {
|
||||
stateController.update(
|
||||
EarnTypeFilterStateTransformer(
|
||||
shouldShow = true,
|
||||
filterByTypeBottomSheetConfig = ::createTypeFilterBottomSheetConfig,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun hideTypeFilterBottomSheet() {
|
||||
stateController.update(
|
||||
EarnTypeFilterStateTransformer(
|
||||
shouldShow = false,
|
||||
filterByTypeBottomSheetConfig = ::createTypeFilterBottomSheetConfig,
|
||||
val currentState = state.value
|
||||
bottomSheetNavigation.activate(
|
||||
FeedBottomSheetRoute.TypeFilter(
|
||||
params = EarnTypeFilterComponent.Params(
|
||||
selectedFilter = EarnFilterTypeUMConverter().convert(currentState.selectedTypeFilter),
|
||||
onFilterSelected = ::onTypeFilterOptionSelected,
|
||||
onDismiss = { bottomSheetNavigation.dismiss() },
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun onNetworkFilterClick() {
|
||||
stateController.update(
|
||||
EarnNetworkFilterStateTransformer(
|
||||
shouldShow = true,
|
||||
filterByNetworkBottomSheetConfig = ::createNetworkFilterBottomSheetConfig,
|
||||
bottomSheetNavigation.activate(
|
||||
FeedBottomSheetRoute.NetworkFilter(
|
||||
params = EarnNetworkFilterComponent.Params(
|
||||
allFilters = createNetworkFilters(),
|
||||
onFilterSelected = ::onNetworkFilterOptionSelected,
|
||||
onDismiss = { bottomSheetNavigation.dismiss() },
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun hideNetworkFilterBottomSheet() {
|
||||
stateController.update(
|
||||
EarnNetworkFilterStateTransformer(
|
||||
shouldShow = false,
|
||||
filterByNetworkBottomSheetConfig = ::createNetworkFilterBottomSheetConfig,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun onTypeFilterOptionSelected(type: EarnFilterTypeUM) {
|
||||
stateController.update(
|
||||
EarnTypeFilterSelectedStateTransformer(
|
||||
filter = type,
|
||||
filterByTypeBottomSheetConfig = ::createTypeFilterBottomSheetConfig,
|
||||
),
|
||||
)
|
||||
batchFlowManager.reload()
|
||||
}
|
||||
|
||||
private fun onNetworkFilterOptionSelected(network: EarnFilterNetworkUM) {
|
||||
stateController.update(
|
||||
EarnNetworkFilterSelectedStateTransformer(
|
||||
filter = network,
|
||||
filterByNetworkBottomSheetConfig = ::createNetworkFilterBottomSheetConfig,
|
||||
),
|
||||
)
|
||||
batchFlowManager.reload()
|
||||
private fun createNetworkFilters(): List<EarnFilterNetwork> {
|
||||
val selectedFilter = state.value.selectedNetworkFilter
|
||||
return buildList {
|
||||
add(
|
||||
EarnFilterNetwork.AllNetworks(
|
||||
isSelected = selectedFilter is EarnFilterNetworkUM.AllNetworks,
|
||||
),
|
||||
)
|
||||
add(
|
||||
EarnFilterNetwork.MyNetworks(
|
||||
isSelected = selectedFilter is EarnFilterNetworkUM.MyNetworks,
|
||||
),
|
||||
)
|
||||
earnNetworks.value.onRight { networks ->
|
||||
networks.mapTo(this) { network ->
|
||||
EarnFilterNetwork.Specific(
|
||||
id = network.networkId,
|
||||
isSelected = selectedFilter is EarnFilterNetworkUM.Network &&
|
||||
selectedFilter.id == network.networkId,
|
||||
symbol = network.symbol,
|
||||
fullName = network.fullName,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onClearFiltersClick() {
|
||||
stateController.update(
|
||||
ClearEarnUMFilterStateTransformer(
|
||||
filterByTypeBottomSheetConfig = ::createTypeFilterBottomSheetConfig,
|
||||
filterByNetworkBottomSheetConfig = ::createNetworkFilterBottomSheetConfig,
|
||||
),
|
||||
)
|
||||
batchFlowManager.reload()
|
||||
modelScope.launch(dispatchers.default) {
|
||||
setEarnFilterUseCase(
|
||||
EarnFilter(
|
||||
earnFilterNetwork = EarnFilterNetwork.AllNetworks(isSelected = true),
|
||||
earnFilterType = EarnFilterType.ALL,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onEarnTokenClick(earnTokenWithCurrency: EarnTokenWithCurrency) {
|
||||
bottomSheetNavigation.activate(
|
||||
FeedPortfolioRoute.AddToPortfolio(
|
||||
FeedBottomSheetRoute.AddToPortfolio(
|
||||
tokenToAdd = AddToPortfolioPreselectedDataComponent.TokenToAdd(
|
||||
network = TokenMarketInfo.Network(
|
||||
networkId = earnTokenWithCurrency.earnToken.networkId,
|
||||
|
|
@ -304,6 +259,30 @@ internal class EarnModel @Inject constructor(
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun onTypeFilterOptionSelected(type: EarnFilterType) {
|
||||
modelScope.launch(dispatchers.default) {
|
||||
setEarnFilterUseCase(
|
||||
EarnFilter(
|
||||
earnFilterNetwork = EarnFilterNetworkUMConverter().convert(state.value.selectedNetworkFilter),
|
||||
earnFilterType = type,
|
||||
),
|
||||
)
|
||||
bottomSheetNavigation.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun onNetworkFilterOptionSelected(filter: EarnFilterNetwork) {
|
||||
modelScope.launch(dispatchers.default) {
|
||||
setEarnFilterUseCase(
|
||||
EarnFilter(
|
||||
earnFilterNetwork = filter,
|
||||
earnFilterType = EarnFilterTypeUMConverter().convert(state.value.selectedTypeFilter),
|
||||
),
|
||||
)
|
||||
}
|
||||
bottomSheetNavigation.dismiss()
|
||||
}
|
||||
/* end of clicks area */
|
||||
|
||||
private fun updateInitialState() {
|
||||
|
|
@ -311,10 +290,6 @@ internal class EarnModel @Inject constructor(
|
|||
UpdateEarnUMInitialStateTransformer(
|
||||
onBackClick = params.onBackClick,
|
||||
onNetworkFilterClick = ::onNetworkFilterClick,
|
||||
filterByTypeBottomSheetConfig = createTypeFilterBottomSheetConfig(state.value.selectedTypeFilter),
|
||||
filterByNetworkBottomSheetConfig = createNetworkFilterBottomSheetConfig(
|
||||
selectedNetwork = state.value.selectedNetworkFilter,
|
||||
),
|
||||
onTypeFilterClick = ::onTypeFilterClick,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package com.tangem.features.feed.model.earn.filters
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.features.feed.components.earn.EarnNetworkFilterComponent
|
||||
import com.tangem.features.feed.model.earn.filters.state.EarnFilterNetworkUMConverter
|
||||
import com.tangem.features.feed.model.earn.filters.state.EarnFilterNetworkConverter
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterByNetworkBottomSheetContentUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class EarnNetworkFilterModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<EarnNetworkFilterComponent.Params>()
|
||||
|
||||
private val _state = MutableStateFlow(configureInitialState())
|
||||
val state = _state.asStateFlow()
|
||||
|
||||
private fun configureInitialState(): EarnFilterByNetworkBottomSheetContentUM {
|
||||
return EarnFilterByNetworkBottomSheetContentUM(
|
||||
networks = params.allFilters
|
||||
.map { EarnFilterNetworkConverter().convert(it) }
|
||||
.toPersistentList(),
|
||||
onOptionClick = { filterUM -> params.onFilterSelected(EarnFilterNetworkUMConverter().convert(filterUM)) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.tangem.features.feed.model.earn.filters
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.features.feed.components.earn.EarnTypeFilterComponent
|
||||
import com.tangem.features.feed.model.earn.filters.state.EarnFilterTypeConverter
|
||||
import com.tangem.features.feed.model.earn.filters.state.EarnFilterTypeUMConverter
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterByTypeBottomSheetContentUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class EarnTypeFilterModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<EarnTypeFilterComponent.Params>()
|
||||
|
||||
private val _state = MutableStateFlow(configureInitialState())
|
||||
val state = _state.asStateFlow()
|
||||
|
||||
private fun configureInitialState(): EarnFilterByTypeBottomSheetContentUM {
|
||||
return EarnFilterByTypeBottomSheetContentUM(
|
||||
selectedOption = EarnFilterTypeConverter().convert(params.selectedFilter),
|
||||
onOptionClick = { filterTypeUM ->
|
||||
params.onFilterSelected(EarnFilterTypeUMConverter().convert(filterTypeUM))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.tangem.features.feed.model.earn.filters.state
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.core.ui.extensions.getActiveIconRes
|
||||
import com.tangem.domain.earn.model.EarnFilterNetwork
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterNetworkUM
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
internal class EarnFilterNetworkConverter : Converter<EarnFilterNetwork, EarnFilterNetworkUM> {
|
||||
|
||||
override fun convert(value: EarnFilterNetwork): EarnFilterNetworkUM {
|
||||
return when (value) {
|
||||
is EarnFilterNetwork.AllNetworks -> {
|
||||
EarnFilterNetworkUM.AllNetworks(isSelected = value.isSelected)
|
||||
}
|
||||
is EarnFilterNetwork.MyNetworks -> {
|
||||
EarnFilterNetworkUM.MyNetworks(isSelected = value.isSelected)
|
||||
}
|
||||
is EarnFilterNetwork.Specific -> {
|
||||
EarnFilterNetworkUM.Network(
|
||||
id = value.id,
|
||||
text = value.fullName,
|
||||
symbol = value.symbol,
|
||||
iconRes = getActiveIconRes(Blockchain.fromNetworkId(value.id)?.id.orEmpty()),
|
||||
isSelected = value.isSelected,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.features.feed.model.earn.filters.state
|
||||
|
||||
import com.tangem.domain.earn.model.EarnFilterNetwork
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterNetworkUM
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
internal class EarnFilterNetworkUMConverter : Converter<EarnFilterNetworkUM, EarnFilterNetwork> {
|
||||
|
||||
override fun convert(value: EarnFilterNetworkUM): EarnFilterNetwork {
|
||||
return when (value) {
|
||||
is EarnFilterNetworkUM.AllNetworks -> EarnFilterNetwork.AllNetworks(isSelected = value.isSelected)
|
||||
is EarnFilterNetworkUM.MyNetworks -> EarnFilterNetwork.MyNetworks(isSelected = value.isSelected)
|
||||
is EarnFilterNetworkUM.Network -> EarnFilterNetwork.Specific(
|
||||
isSelected = value.isSelected,
|
||||
id = value.id,
|
||||
symbol = value.symbol,
|
||||
fullName = value.text,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.features.feed.model.earn.filters.state
|
||||
|
||||
import com.tangem.domain.earn.model.EarnFilterType
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterTypeUM
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
internal class EarnFilterTypeConverter : Converter<EarnFilterType, EarnFilterTypeUM> {
|
||||
override fun convert(value: EarnFilterType): EarnFilterTypeUM {
|
||||
return when (value) {
|
||||
EarnFilterType.ALL -> EarnFilterTypeUM.All
|
||||
EarnFilterType.STAKING -> EarnFilterTypeUM.Staking
|
||||
EarnFilterType.YIELD -> EarnFilterTypeUM.YieldMode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.features.feed.model.earn.filters.state
|
||||
|
||||
import com.tangem.domain.earn.model.EarnFilterType
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterTypeUM
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
internal class EarnFilterTypeUMConverter : Converter<EarnFilterTypeUM, EarnFilterType> {
|
||||
|
||||
override fun convert(value: EarnFilterTypeUM): EarnFilterType {
|
||||
return when (value) {
|
||||
EarnFilterTypeUM.All -> EarnFilterType.ALL
|
||||
EarnFilterTypeUM.Staking -> EarnFilterType.STAKING
|
||||
EarnFilterTypeUM.YieldMode -> EarnFilterType.YIELD
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,6 @@
|
|||
package com.tangem.features.feed.model.earn.state
|
||||
|
||||
import com.tangem.common.R
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.features.feed.model.earn.state.transformers.EarnUMTransformer
|
||||
import com.tangem.features.feed.ui.earn.state.*
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -34,12 +31,7 @@ internal class EarnStateController @Inject constructor() {
|
|||
mostlyUsed = EarnListUM.Loading,
|
||||
bestOpportunities = EarnBestOpportunitiesUM.Loading,
|
||||
selectedTypeFilter = EarnFilterTypeUM.All,
|
||||
selectedNetworkFilter = EarnFilterNetworkUM.AllNetworks(
|
||||
text = TextReference.Res(R.string.earn_filter_all_networks),
|
||||
isSelected = true,
|
||||
),
|
||||
filterByTypeBottomSheet = TangemBottomSheetConfig.Empty,
|
||||
filterByNetworkBottomSheet = TangemBottomSheetConfig.Empty,
|
||||
selectedNetworkFilter = EarnFilterNetworkUM.AllNetworks(isSelected = true),
|
||||
onBackClick = {},
|
||||
onNetworkFilterClick = {},
|
||||
onTypeFilterClick = {},
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
package com.tangem.features.feed.model.earn.state.converter
|
||||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchainsdk.utils.fromNetworkId
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.getActiveIconRes
|
||||
import com.tangem.domain.models.earn.EarnNetwork
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterNetworkUM
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
internal class EarnNetworksConverter : Converter<EarnNetwork, EarnFilterNetworkUM.Network> {
|
||||
|
||||
override fun convert(value: EarnNetwork): EarnFilterNetworkUM.Network {
|
||||
return EarnFilterNetworkUM.Network(
|
||||
id = value.networkId,
|
||||
text = TextReference.Str(value.fullName),
|
||||
symbol = TextReference.Str(value.symbol),
|
||||
iconRes = getActiveIconRes(Blockchain.fromNetworkId(value.networkId)?.id.orEmpty()),
|
||||
isSelected = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
package com.tangem.features.feed.model.earn.state.transformers
|
||||
|
||||
import com.tangem.common.R
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterNetworkUM
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterTypeUM
|
||||
import com.tangem.features.feed.ui.earn.state.EarnUM
|
||||
|
||||
internal class ClearEarnUMFilterStateTransformer(
|
||||
private val filterByTypeBottomSheetConfig: (EarnFilterTypeUM, Boolean) -> TangemBottomSheetConfig,
|
||||
private val filterByNetworkBottomSheetConfig: (EarnFilterNetworkUM, Boolean) -> TangemBottomSheetConfig,
|
||||
) : EarnUMTransformer {
|
||||
|
||||
override fun transform(prevState: EarnUM): EarnUM {
|
||||
val defaultNetworksFilter = EarnFilterNetworkUM.AllNetworks(
|
||||
text = TextReference.Res(R.string.earn_filter_all_networks),
|
||||
isSelected = true,
|
||||
)
|
||||
|
||||
return prevState.copy(
|
||||
selectedTypeFilter = EarnFilterTypeUM.All,
|
||||
selectedNetworkFilter = defaultNetworksFilter,
|
||||
filterByTypeBottomSheet = filterByTypeBottomSheetConfig(EarnFilterTypeUM.All, false),
|
||||
filterByNetworkBottomSheet = filterByNetworkBottomSheetConfig(defaultNetworksFilter, false),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.features.feed.model.earn.state.transformers
|
||||
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterNetworkUM
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterTypeUM
|
||||
import com.tangem.features.feed.ui.earn.state.EarnUM
|
||||
|
||||
internal class EarnFilterSelectedStateTransformer(
|
||||
private val filterType: EarnFilterTypeUM,
|
||||
private val filterNetwork: EarnFilterNetworkUM,
|
||||
) : EarnUMTransformer {
|
||||
|
||||
override fun transform(prevState: EarnUM): EarnUM {
|
||||
return prevState.copy(
|
||||
selectedTypeFilter = filterType,
|
||||
selectedNetworkFilter = filterNetwork,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,13 @@
|
|||
package com.tangem.features.feed.model.earn.state.transformers
|
||||
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterNetworkUM
|
||||
import com.tangem.features.feed.ui.earn.state.EarnUM
|
||||
|
||||
internal class EarnNetworkFilterSelectedStateTransformer(
|
||||
private val filter: EarnFilterNetworkUM,
|
||||
private val filterByNetworkBottomSheetConfig: (EarnFilterNetworkUM, Boolean) -> TangemBottomSheetConfig,
|
||||
) : EarnUMTransformer {
|
||||
|
||||
override fun transform(prevState: EarnUM): EarnUM {
|
||||
return prevState.copy(
|
||||
selectedNetworkFilter = filter,
|
||||
filterByNetworkBottomSheet = filterByNetworkBottomSheetConfig(filter, false),
|
||||
)
|
||||
return prevState.copy(selectedNetworkFilter = filter)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package com.tangem.features.feed.model.earn.state.transformers
|
||||
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterNetworkUM
|
||||
import com.tangem.features.feed.ui.earn.state.EarnUM
|
||||
|
||||
internal class EarnNetworkFilterStateTransformer(
|
||||
private val shouldShow: Boolean,
|
||||
private val filterByNetworkBottomSheetConfig: (EarnFilterNetworkUM, Boolean) -> TangemBottomSheetConfig,
|
||||
) : EarnUMTransformer {
|
||||
|
||||
override fun transform(prevState: EarnUM): EarnUM {
|
||||
return if (shouldShow) {
|
||||
prevState.copy(
|
||||
filterByNetworkBottomSheet = filterByNetworkBottomSheetConfig(prevState.selectedNetworkFilter, true),
|
||||
)
|
||||
} else {
|
||||
prevState.copy(filterByNetworkBottomSheet = prevState.filterByNetworkBottomSheet.copy(isShown = false))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
package com.tangem.features.feed.model.earn.state.transformers
|
||||
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterTypeUM
|
||||
import com.tangem.features.feed.ui.earn.state.EarnUM
|
||||
|
||||
internal class EarnTypeFilterSelectedStateTransformer(
|
||||
private val filter: EarnFilterTypeUM,
|
||||
private val filterByTypeBottomSheetConfig: (EarnFilterTypeUM, Boolean) -> TangemBottomSheetConfig,
|
||||
) : EarnUMTransformer {
|
||||
|
||||
override fun transform(prevState: EarnUM): EarnUM {
|
||||
return prevState.copy(
|
||||
selectedTypeFilter = filter,
|
||||
filterByTypeBottomSheet = filterByTypeBottomSheetConfig(filter, false),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package com.tangem.features.feed.model.earn.state.transformers
|
||||
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.features.feed.ui.earn.state.EarnFilterTypeUM
|
||||
import com.tangem.features.feed.ui.earn.state.EarnUM
|
||||
|
||||
internal class EarnTypeFilterStateTransformer(
|
||||
private val shouldShow: Boolean,
|
||||
private val filterByTypeBottomSheetConfig: (EarnFilterTypeUM, Boolean) -> TangemBottomSheetConfig,
|
||||
) : EarnUMTransformer {
|
||||
|
||||
override fun transform(prevState: EarnUM): EarnUM {
|
||||
return if (shouldShow) {
|
||||
prevState.copy(
|
||||
filterByTypeBottomSheet = filterByTypeBottomSheetConfig(prevState.selectedTypeFilter, true),
|
||||
)
|
||||
} else {
|
||||
prevState.copy(filterByTypeBottomSheet = prevState.filterByTypeBottomSheet.copy(isShown = false))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,9 @@
|
|||
package com.tangem.features.feed.model.earn.state.transformers
|
||||
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.features.feed.ui.earn.state.EarnUM
|
||||
|
||||
internal class UpdateEarnUMInitialStateTransformer(
|
||||
private val onBackClick: () -> Unit,
|
||||
private val filterByTypeBottomSheetConfig: TangemBottomSheetConfig,
|
||||
private val filterByNetworkBottomSheetConfig: TangemBottomSheetConfig,
|
||||
private val onNetworkFilterClick: () -> Unit,
|
||||
private val onTypeFilterClick: () -> Unit,
|
||||
) : EarnUMTransformer {
|
||||
|
|
@ -14,8 +11,6 @@ internal class UpdateEarnUMInitialStateTransformer(
|
|||
override fun transform(prevState: EarnUM): EarnUM {
|
||||
return prevState.copy(
|
||||
onBackClick = onBackClick,
|
||||
filterByNetworkBottomSheet = filterByNetworkBottomSheetConfig,
|
||||
filterByTypeBottomSheet = filterByTypeBottomSheetConfig,
|
||||
onNetworkFilterClick = onNetworkFilterClick,
|
||||
onTypeFilterClick = onTypeFilterClick,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
import com.tangem.domain.news.usecase.FetchTrendingNewsUseCase
|
||||
import com.tangem.domain.news.usecase.ManageTrendingNewsUseCase
|
||||
import com.tangem.features.feed.components.feed.DefaultFeedComponent
|
||||
import com.tangem.features.feed.components.feed.FeedPortfolioRoute
|
||||
import com.tangem.features.feed.components.feed.FeedBottomSheetRoute
|
||||
import com.tangem.features.feed.components.market.details.portfolio.add.AddToPortfolioPreselectedDataComponent
|
||||
import com.tangem.features.feed.entry.featuretoggle.FeedFeatureToggle
|
||||
import com.tangem.features.feed.impl.R
|
||||
|
|
@ -89,7 +89,7 @@ internal class FeedComponentModel @Inject constructor(
|
|||
dispatchers = dispatchers,
|
||||
)
|
||||
|
||||
val bottomSheetNavigation: SlotNavigation<FeedPortfolioRoute> = SlotNavigation()
|
||||
val bottomSheetNavigation: SlotNavigation<FeedBottomSheetRoute> = SlotNavigation()
|
||||
|
||||
val addToPortfolioCallback = object : AddToPortfolioPreselectedDataComponent.Callback {
|
||||
override fun onDismiss() = bottomSheetNavigation.dismiss()
|
||||
|
|
@ -398,7 +398,7 @@ internal class FeedComponentModel @Inject constructor(
|
|||
|
||||
private fun handleEarnTokenClick(earnTokenWithCurrency: EarnTokenWithCurrency) {
|
||||
bottomSheetNavigation.activate(
|
||||
FeedPortfolioRoute.AddToPortfolio(
|
||||
FeedBottomSheetRoute.AddToPortfolio(
|
||||
tokenToAdd = AddToPortfolioPreselectedDataComponent.TokenToAdd(
|
||||
network = TokenMarketInfo.Network(
|
||||
networkId = earnTokenWithCurrency.earnToken.networkId,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.*
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.buttons.SecondarySmallButton
|
||||
import com.tangem.core.ui.components.buttons.SmallButtonConfig
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
|
||||
|
|
@ -37,7 +36,9 @@ import com.tangem.core.ui.res.LocalMainBottomSheetColor
|
|||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.feed.ui.earn.components.*
|
||||
import com.tangem.features.feed.ui.earn.components.EarnItemPlaceholder
|
||||
import com.tangem.features.feed.ui.earn.components.EarnListItem
|
||||
import com.tangem.features.feed.ui.earn.components.MostlyUsedPlaceholder
|
||||
import com.tangem.features.feed.ui.earn.state.*
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
|
|
@ -50,9 +51,6 @@ internal fun EarnContent(state: EarnUM, modifier: Modifier = Modifier) {
|
|||
val bottomBarHeight = with(density) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||
val listState = rememberLazyListState()
|
||||
|
||||
EarnFilterByTypeBottomSheet(config = state.filterByTypeBottomSheet)
|
||||
EarnFilterByNetworkBottomSheet(config = state.filterByNetworkBottomSheet)
|
||||
|
||||
if (state.bestOpportunities is EarnBestOpportunitiesUM.Content) {
|
||||
PaginationHandler(
|
||||
listState = listState,
|
||||
|
|
@ -89,7 +87,11 @@ internal fun EarnContent(state: EarnUM, modifier: Modifier = Modifier) {
|
|||
SpacerH(12.dp)
|
||||
BestOpportunitiesFilters(
|
||||
state = state.bestOpportunities,
|
||||
selectedNetworkFilterText = state.selectedNetworkFilterText,
|
||||
selectedNetworkFilterText = when (state.selectedNetworkFilter) {
|
||||
is EarnFilterNetworkUM.AllNetworks -> TextReference.Res(R.string.earn_filter_all_networks)
|
||||
is EarnFilterNetworkUM.MyNetworks -> TextReference.Res(R.string.earn_filter_my_networks)
|
||||
is EarnFilterNetworkUM.Network -> TextReference.Str(state.selectedNetworkFilter.text)
|
||||
},
|
||||
selectedTypeFilterText = state.selectedTypeFilterText,
|
||||
onNetworkFilterClick = state.onNetworkFilterClick,
|
||||
onTypeFilterClick = state.onTypeFilterClick,
|
||||
|
|
@ -573,12 +575,7 @@ private fun previewEarnUM(
|
|||
mostlyUsed = mostlyUsed,
|
||||
bestOpportunities = bestOpportunities,
|
||||
selectedTypeFilter = EarnFilterTypeUM.All,
|
||||
selectedNetworkFilter = EarnFilterNetworkUM.AllNetworks(
|
||||
text = resourceReference(R.string.earn_filter_all_networks),
|
||||
isSelected = true,
|
||||
),
|
||||
filterByTypeBottomSheet = TangemBottomSheetConfig.Empty,
|
||||
filterByNetworkBottomSheet = TangemBottomSheetConfig.Empty,
|
||||
selectedNetworkFilter = EarnFilterNetworkUM.AllNetworks(isSelected = true),
|
||||
onBackClick = {},
|
||||
onNetworkFilterClick = {},
|
||||
onTypeFilterClick = {},
|
||||
|
|
|
|||
|
|
@ -28,9 +28,8 @@ import com.tangem.core.ui.components.inputrow.inner.DividerContainer
|
|||
import com.tangem.core.ui.components.rows.RowContentContainer
|
||||
import com.tangem.core.ui.components.rows.RowText
|
||||
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
|
@ -106,7 +105,11 @@ private fun LazyListScope.allMyNetworksList(
|
|||
showDivider = index != allMyNetworks.lastIndex,
|
||||
) {
|
||||
InputRowChecked(
|
||||
text = item.text,
|
||||
text = when (item) {
|
||||
is EarnFilterNetworkUM.AllNetworks -> TextReference.Res(R.string.earn_filter_all_networks)
|
||||
is EarnFilterNetworkUM.MyNetworks -> TextReference.Res(R.string.earn_filter_my_networks)
|
||||
is EarnFilterNetworkUM.Network -> TextReference.Str(item.text)
|
||||
},
|
||||
checked = item.isSelected,
|
||||
)
|
||||
}
|
||||
|
|
@ -170,13 +173,13 @@ private fun LazyListScope.specificNetworksList(
|
|||
Image(
|
||||
modifier = Modifier.size(22.dp),
|
||||
imageVector = ImageVector.vectorResource(item.iconRes),
|
||||
contentDescription = item.symbol.resolveReference(),
|
||||
contentDescription = item.symbol,
|
||||
)
|
||||
},
|
||||
text = {
|
||||
RowText(
|
||||
mainText = item.text.resolveReference(),
|
||||
secondText = item.symbol.resolveReference(),
|
||||
mainText = item.text,
|
||||
secondText = item.symbol,
|
||||
accentMainText = true,
|
||||
accentSecondText = false,
|
||||
)
|
||||
|
|
@ -208,30 +211,20 @@ private fun Preview() {
|
|||
isShown = true,
|
||||
onDismissRequest = {},
|
||||
content = EarnFilterByNetworkBottomSheetContentUM(
|
||||
selectedNetwork = EarnFilterNetworkUM.AllNetworks(
|
||||
text = resourceReference(R.string.earn_filter_all_networks),
|
||||
isSelected = true,
|
||||
),
|
||||
networks = persistentListOf(
|
||||
EarnFilterNetworkUM.AllNetworks(
|
||||
text = resourceReference(R.string.earn_filter_all_networks),
|
||||
isSelected = true,
|
||||
),
|
||||
EarnFilterNetworkUM.MyNetworks(
|
||||
text = stringReference("My network"),
|
||||
isSelected = false,
|
||||
),
|
||||
EarnFilterNetworkUM.AllNetworks(isSelected = true),
|
||||
EarnFilterNetworkUM.MyNetworks(isSelected = false),
|
||||
EarnFilterNetworkUM.Network(
|
||||
id = "ethereum",
|
||||
text = stringReference("Ethereum"),
|
||||
symbol = stringReference("ETH"),
|
||||
text = "Ethereum",
|
||||
symbol = "ETH",
|
||||
iconRes = R.drawable.img_btc_22,
|
||||
isSelected = false,
|
||||
),
|
||||
EarnFilterNetworkUM.Network(
|
||||
id = "polygon",
|
||||
text = stringReference("Polygon"),
|
||||
symbol = stringReference("MATIC"),
|
||||
text = "Polygon",
|
||||
symbol = "MATIC",
|
||||
iconRes = R.drawable.img_btc_22,
|
||||
isSelected = false,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
|||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
internal data class EarnFilterByNetworkBottomSheetContentUM(
|
||||
val selectedNetwork: EarnFilterNetworkUM,
|
||||
val networks: ImmutableList<EarnFilterNetworkUM>,
|
||||
val onOptionClick: (EarnFilterNetworkUM) -> Unit,
|
||||
) : TangemBottomSheetConfigContent
|
||||
|
|
@ -1,29 +1,25 @@
|
|||
package com.tangem.features.feed.ui.earn.state
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
@Immutable
|
||||
internal sealed class EarnFilterNetworkUM {
|
||||
|
||||
abstract val text: TextReference
|
||||
abstract val isSelected: Boolean
|
||||
|
||||
data class AllNetworks(
|
||||
override val text: TextReference,
|
||||
override val isSelected: Boolean,
|
||||
) : EarnFilterNetworkUM()
|
||||
|
||||
data class MyNetworks(
|
||||
override val text: TextReference,
|
||||
override val isSelected: Boolean,
|
||||
) : EarnFilterNetworkUM()
|
||||
|
||||
data class Network(
|
||||
val id: String,
|
||||
override val text: TextReference,
|
||||
val symbol: TextReference,
|
||||
val iconRes: Int,
|
||||
override val isSelected: Boolean,
|
||||
val id: String,
|
||||
val text: String,
|
||||
val symbol: String,
|
||||
val iconRes: Int,
|
||||
) : EarnFilterNetworkUM()
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.features.feed.ui.earn.state
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
@Immutable
|
||||
|
|
@ -10,16 +9,11 @@ internal data class EarnUM(
|
|||
val bestOpportunities: EarnBestOpportunitiesUM,
|
||||
val selectedTypeFilter: EarnFilterTypeUM,
|
||||
val selectedNetworkFilter: EarnFilterNetworkUM,
|
||||
val filterByTypeBottomSheet: TangemBottomSheetConfig,
|
||||
val filterByNetworkBottomSheet: TangemBottomSheetConfig,
|
||||
val onBackClick: () -> Unit,
|
||||
val onNetworkFilterClick: () -> Unit,
|
||||
val onTypeFilterClick: () -> Unit,
|
||||
) {
|
||||
|
||||
val selectedNetworkFilterText: TextReference
|
||||
get() = selectedNetworkFilter.text
|
||||
|
||||
val selectedTypeFilterText: TextReference
|
||||
get() = selectedTypeFilter.text
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue