Updated on 2026-08-14
This commit is contained in:
parent
dbdffaa974
commit
8509912947
15 changed files with 402 additions and 57 deletions
|
|
@ -171,6 +171,24 @@ internal object TokensDomainModule {
|
|||
return FetchCardTokenListUseCase(currenciesRepository, networksRepository, quotesRepository, stakingRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesGetCryptoCurrencyStatusSyncUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
dispatcherProvider: CoroutineDispatcherProvider,
|
||||
quotesRepository: QuotesRepository,
|
||||
networksRepository: NetworksRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
): GetCryptoCurrencyStatusSyncUseCase {
|
||||
return GetCryptoCurrencyStatusSyncUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
networksRepository = networksRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetCryptoCurrencyUseCase(currenciesRepository: CurrenciesRepository): GetCryptoCurrencyUseCase {
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ private fun Modifier.tokenClickable(state: TokenItemState): Modifier = composed
|
|||
/**
|
||||
* IMPORTANT! All margins that used between children setup like as children paddings.
|
||||
*/
|
||||
@Suppress("LongMethod")
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||
@Composable
|
||||
private fun CustomContainer(state: TokenItemState, modifier: Modifier = Modifier, content: @Composable () -> Unit) {
|
||||
val density = LocalDensity.current
|
||||
|
|
@ -215,20 +215,24 @@ private fun CustomContainer(state: TokenItemState, modifier: Modifier = Modifier
|
|||
is TokenItemState.Loading,
|
||||
is TokenItemState.Locked,
|
||||
-> {
|
||||
fiatAmount = measurables.measureFiatAmount(
|
||||
state = state,
|
||||
maxWidth = layoutWidth - icon.width - titleMinWidth,
|
||||
defaultConstraints = constraints,
|
||||
)
|
||||
if (state.fiatAmountState != null) {
|
||||
fiatAmount = measurables.measureFiatAmount(
|
||||
state = state,
|
||||
maxWidth = layoutWidth - icon.width - titleMinWidth,
|
||||
defaultConstraints = constraints,
|
||||
)
|
||||
}
|
||||
|
||||
cryptoAmount = measurables.measureCryptoAmount(
|
||||
state = state,
|
||||
maxWidth = layoutWidth - icon.width - priceChangeMinWidth,
|
||||
defaultConstraints = constraints,
|
||||
)
|
||||
if (state.subtitle2State != null) {
|
||||
cryptoAmount = measurables.measureCryptoAmount(
|
||||
state = state,
|
||||
maxWidth = layoutWidth - icon.width - priceChangeMinWidth,
|
||||
defaultConstraints = constraints,
|
||||
)
|
||||
}
|
||||
|
||||
firstRowRemainingFreeSpace = layoutWidth - icon.width - fiatAmount.width
|
||||
secondRowRemainingFreeSpace = layoutWidth - icon.width - cryptoAmount.width
|
||||
firstRowRemainingFreeSpace = layoutWidth - icon.width - (fiatAmount?.width ?: 0)
|
||||
secondRowRemainingFreeSpace = layoutWidth - icon.width - (cryptoAmount?.width ?: 0)
|
||||
}
|
||||
is TokenItemState.Draggable -> {
|
||||
cryptoAmount = measurables.measureCryptoAmount(
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ sealed class TokenItemState {
|
|||
* @property titleState token title
|
||||
* @property subtitleState token subtitle
|
||||
* @property fiatAmountState token fiat amount
|
||||
* @property subtitle2State token crypto amount
|
||||
* @property subtitle2State token subtitle 2 (example, token crypto amount)
|
||||
* @property onItemClick callback which will be called when an item is clicked
|
||||
* @property onItemLongClick callback which will be called when an item is long clicked
|
||||
*/
|
||||
|
|
@ -91,8 +91,8 @@ sealed class TokenItemState {
|
|||
override val iconState: CurrencyIconState,
|
||||
override val titleState: TitleState,
|
||||
override val subtitleState: SubtitleState,
|
||||
override val fiatAmountState: FiatAmountState,
|
||||
override val subtitle2State: Subtitle2State,
|
||||
override val fiatAmountState: FiatAmountState?,
|
||||
override val subtitle2State: Subtitle2State?,
|
||||
override val onItemClick: ((TokenItemState) -> Unit)?,
|
||||
override val onItemLongClick: ((TokenItemState) -> Unit)?,
|
||||
) : TokenItemState()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
package com.tangem.features.onramp.hottokens
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.arkivanov.decompose.ComponentContext
|
||||
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
|
||||
import com.arkivanov.decompose.router.slot.childSlot
|
||||
import com.arkivanov.decompose.router.slot.dismiss
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.childByContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.features.onramp.hottokens.model.HotCryptoModel
|
||||
import com.tangem.features.onramp.hottokens.portfolio.OnrampAddToPortfolioComponent
|
||||
import com.tangem.features.onramp.hottokens.portfolio.entity.OnrampAddToPortfolioBSConfig
|
||||
import com.tangem.features.onramp.hottokens.ui.HotCrypto
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
internal class DefaultHotCryptoComponent @AssistedInject constructor(
|
||||
@Assisted context: AppComponentContext,
|
||||
@Assisted private val params: HotCryptoComponent.Params,
|
||||
private val onrampAddToPortfolioComponentFactory: OnrampAddToPortfolioComponent.Factory,
|
||||
) : HotCryptoComponent, AppComponentContext by context {
|
||||
|
||||
private val model: HotCryptoModel = getOrCreateModel(params)
|
||||
|
||||
private val bottomSheetSlot = childSlot(
|
||||
source = model.bottomSheetNavigation,
|
||||
serializer = null,
|
||||
handleBackButton = false,
|
||||
childFactory = ::bottomSheetChild,
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state = model.state.collectAsStateWithLifecycle()
|
||||
val bottomSheet by bottomSheetSlot.subscribeAsState()
|
||||
|
||||
HotCrypto(state, modifier)
|
||||
|
||||
bottomSheet.child?.instance?.BottomSheet()
|
||||
}
|
||||
|
||||
private fun bottomSheetChild(
|
||||
config: OnrampAddToPortfolioBSConfig,
|
||||
componentContext: ComponentContext,
|
||||
): ComposableBottomSheetComponent {
|
||||
return when (config) {
|
||||
is OnrampAddToPortfolioBSConfig.AddToPortfolio -> {
|
||||
onrampAddToPortfolioComponentFactory.create(
|
||||
context = childByContext(componentContext),
|
||||
params = OnrampAddToPortfolioComponent.Params(
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrency = config.cryptoCurrency,
|
||||
currencyIconState = config.currencyIconState,
|
||||
onSuccessAdding = config.onSuccessAdding,
|
||||
onDismiss = model.bottomSheetNavigation::dismiss,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : HotCryptoComponent.Factory {
|
||||
override fun create(context: AppComponentContext, params: HotCryptoComponent.Params): DefaultHotCryptoComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.features.onramp.hottokens
|
||||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
/**
|
||||
* Hot crypto component
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal interface HotCryptoComponent : ComposableContentComponent {
|
||||
|
||||
/**
|
||||
* Params
|
||||
*
|
||||
* @property userWalletId user wallet id
|
||||
* @property onTokenClick lambda be invoked when token item is clicked
|
||||
*/
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val onTokenClick: (CryptoCurrencyStatus) -> Unit,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, HotCryptoComponent>
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package com.tangem.features.onramp.hottokens.converter
|
||||
|
||||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||
import com.tangem.core.ui.components.marketprice.utils.PriceChangeConverter
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.core.ui.format.bigdecimal.percent
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.onramp.model.HotCryptoCurrency
|
||||
import com.tangem.utils.converter.Converter
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
* Token item state converter from [HotCryptoCurrency] to [TokenItemState]
|
||||
*
|
||||
* @property appCurrency app currency
|
||||
* @property onItemClick callback is invoked when item is clicked
|
||||
*/
|
||||
internal class HotTokenItemStateConverter(
|
||||
private val appCurrency: AppCurrency,
|
||||
private val onItemClick: (TokenItemState, HotCryptoCurrency) -> Unit,
|
||||
) : Converter<HotCryptoCurrency, TokenItemState> {
|
||||
|
||||
override fun convert(value: HotCryptoCurrency): TokenItemState {
|
||||
return TokenItemState.Content(
|
||||
id = value.cryptoCurrency.id.value,
|
||||
iconState = CryptoCurrencyToIconStateConverter().convert(value.cryptoCurrency),
|
||||
titleState = TokenItemState.TitleState.Content(text = stringReference(value.cryptoCurrency.name)),
|
||||
subtitleState = value.getCryptoPriceState(appCurrency),
|
||||
fiatAmountState = null,
|
||||
subtitle2State = null,
|
||||
onItemClick = onItemClick.let { onItemClick -> { onItemClick(it, value) } },
|
||||
onItemLongClick = null,
|
||||
)
|
||||
}
|
||||
|
||||
private fun HotCryptoCurrency.getCryptoPriceState(appCurrency: AppCurrency): TokenItemState.SubtitleState {
|
||||
return TokenItemState.SubtitleState.CryptoPriceContent(
|
||||
price = fiatRate.getFormattedCryptoPrice(appCurrency),
|
||||
priceChangePercent = priceChange.format { percent() },
|
||||
type = priceChange.getPriceChangeType(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun BigDecimal.getFormattedCryptoPrice(appCurrency: AppCurrency): String {
|
||||
return format {
|
||||
fiat(fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol)
|
||||
}
|
||||
}
|
||||
|
||||
private fun BigDecimal.getPriceChangeType(): PriceChangeType {
|
||||
return PriceChangeConverter.fromBigDecimal(value = this)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.features.onramp.hottokens.di
|
||||
|
||||
import com.tangem.features.onramp.hottokens.DefaultHotCryptoComponent
|
||||
import com.tangem.features.onramp.hottokens.HotCryptoComponent
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface HotCryptoComponentModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindHotCryptoComponentFactory(factory: DefaultHotCryptoComponent.Factory): HotCryptoComponent.Factory
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.features.onramp.hottokens.di
|
||||
|
||||
import com.tangem.core.decompose.di.DecomposeComponent
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.features.onramp.hottokens.model.HotCryptoModel
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.multibindings.ClassKey
|
||||
import dagger.multibindings.IntoMap
|
||||
|
||||
@Module
|
||||
@InstallIn(DecomposeComponent::class)
|
||||
internal interface HotCryptoModelModule {
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(HotCryptoModel::class)
|
||||
fun bindHotCryptoModel(model: HotCryptoModel): Model
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.features.onramp.hottokens.entity
|
||||
|
||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
/**
|
||||
* Hot crypto UM
|
||||
*
|
||||
* @property items items
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal data class HotCryptoUM(val items: ImmutableList<TokensListItemUM>)
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
package com.tangem.features.onramp.hottokens.model
|
||||
|
||||
import arrow.core.getOrElse
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.arkivanov.decompose.router.slot.dismiss
|
||||
import com.tangem.core.decompose.di.ComponentScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.onramp.GetHotCryptoUseCase
|
||||
import com.tangem.domain.onramp.model.HotCryptoCurrency
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.features.onramp.hottokens.HotCryptoComponent
|
||||
import com.tangem.features.onramp.hottokens.converter.HotTokenItemStateConverter
|
||||
import com.tangem.features.onramp.hottokens.entity.HotCryptoUM
|
||||
import com.tangem.features.onramp.hottokens.portfolio.entity.OnrampAddToPortfolioBSConfig
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Hot crypto model
|
||||
*
|
||||
* @param paramsContainer params container
|
||||
* @param getHotCryptoUseCase use case for getting hot crypto
|
||||
* @param getSelectedAppCurrencyUseCase use case for getting selected app currency
|
||||
* @property getCryptoCurrencyStatusSyncUseCase use case for getting crypto currency status by id
|
||||
* @property dispatchers dispatchers
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@ComponentScoped
|
||||
internal class HotCryptoModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
getHotCryptoUseCase: GetHotCryptoUseCase,
|
||||
getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getCryptoCurrencyStatusSyncUseCase: GetCryptoCurrencyStatusSyncUseCase,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
) : Model() {
|
||||
|
||||
val bottomSheetNavigation: SlotNavigation<OnrampAddToPortfolioBSConfig> = SlotNavigation()
|
||||
|
||||
val state: StateFlow<HotCryptoUM> get() = _state
|
||||
private val _state = MutableStateFlow(value = HotCryptoUM(items = persistentListOf()))
|
||||
|
||||
private val params: HotCryptoComponent.Params = paramsContainer.require()
|
||||
|
||||
init {
|
||||
combine(
|
||||
flow = getSelectedAppCurrencyUseCase().map { it.getOrElse { AppCurrency.Default } },
|
||||
flow2 = getHotCryptoUseCase(params.userWalletId),
|
||||
) { appCurrency, currencies ->
|
||||
HotTokenItemStateConverter(appCurrency = appCurrency, onItemClick = ::onTokenClick)
|
||||
.convertList(currencies)
|
||||
.map(TokensListItemUM::Token)
|
||||
}
|
||||
.onEach { items ->
|
||||
_state.update {
|
||||
HotCryptoUM(
|
||||
items = buildList {
|
||||
if (items.isNotEmpty()) {
|
||||
add(it.getOrCreateGroupTitle())
|
||||
}
|
||||
|
||||
addAll(items)
|
||||
}
|
||||
.toImmutableList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun HotCryptoUM.getOrCreateGroupTitle(): TokensListItemUM {
|
||||
return items.firstOrNull()
|
||||
.takeIf { it is TokensListItemUM.GroupTitle }
|
||||
?: TokensListItemUM.GroupTitle(
|
||||
id = R.string.tokens_list_hot_crypto_header,
|
||||
text = resourceReference(id = R.string.tokens_list_hot_crypto_header),
|
||||
)
|
||||
}
|
||||
|
||||
private fun onTokenClick(tokenItemState: TokenItemState, currency: HotCryptoCurrency) {
|
||||
bottomSheetNavigation.activate(
|
||||
configuration = OnrampAddToPortfolioBSConfig.AddToPortfolio(
|
||||
cryptoCurrency = currency.cryptoCurrency,
|
||||
currencyIconState = tokenItemState.iconState,
|
||||
onSuccessAdding = ::onSuccessAdding,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun onSuccessAdding(id: CryptoCurrency.ID) {
|
||||
modelScope.launch {
|
||||
getCryptoCurrencyStatusSyncUseCase(userWalletId = params.userWalletId, cryptoCurrencyId = id)
|
||||
.onRight {
|
||||
bottomSheetNavigation.dismiss()
|
||||
params.onTokenClick(it)
|
||||
}
|
||||
.onLeft { Timber.d("Unable to get CryptoCurrencyStatus[$id]: $it") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ interface OnrampAddToPortfolioComponent : ComposableBottomSheetComponent {
|
|||
val userWalletId: UserWalletId,
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val currencyIconState: CurrencyIconState,
|
||||
val onSuccessAdding: () -> Unit,
|
||||
val onSuccessAdding: (CryptoCurrency.ID) -> Unit,
|
||||
val onDismiss: () -> Unit,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@ internal sealed class OnrampAddToPortfolioBSConfig {
|
|||
data class AddToPortfolio(
|
||||
val cryptoCurrency: CryptoCurrency,
|
||||
val currencyIconState: CurrencyIconState,
|
||||
val onSuccessAdding: () -> Unit,
|
||||
val onSuccessAdding: (CryptoCurrency.ID) -> Unit,
|
||||
) : OnrampAddToPortfolioBSConfig()
|
||||
}
|
||||
|
|
@ -33,11 +33,11 @@ internal class OnrampAddToPortfolioModel @Inject constructor(
|
|||
private val addCryptoCurrenciesUseCase: AddCryptoCurrenciesUseCase,
|
||||
) : Model() {
|
||||
|
||||
private val params: OnrampAddToPortfolioComponent.Params = paramsContainer.require()
|
||||
|
||||
val state: StateFlow<OnrampAddToPortfolioUM> get() = _state
|
||||
private val _state = MutableStateFlow(value = getInitialState())
|
||||
|
||||
private val params: OnrampAddToPortfolioComponent.Params = paramsContainer.require()
|
||||
|
||||
private fun getInitialState(): OnrampAddToPortfolioUM {
|
||||
return OnrampAddToPortfolioUM(
|
||||
currencyName = params.cryptoCurrency.name,
|
||||
|
|
@ -57,7 +57,7 @@ internal class OnrampAddToPortfolioModel @Inject constructor(
|
|||
userWalletId = params.userWalletId,
|
||||
currencies = listOfNotNull(params.cryptoCurrency),
|
||||
)
|
||||
.onRight { params.onSuccessAdding() }
|
||||
.onRight { params.onSuccessAdding(params.cryptoCurrency.id) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.features.onramp.hottokens.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.util.fastForEachIndexed
|
||||
import com.tangem.core.ui.components.tokenlist.TokenListItem
|
||||
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.onramp.hottokens.entity.HotCryptoUM
|
||||
|
||||
/**
|
||||
* Hot crypto
|
||||
*
|
||||
* @param state state
|
||||
* @param modifier modifier
|
||||
*/
|
||||
@Composable
|
||||
internal fun HotCrypto(state: State<HotCryptoUM>, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
state.value.items.fastForEachIndexed { index, item ->
|
||||
key(item.id) {
|
||||
TokenListItem(
|
||||
state = item,
|
||||
isBalanceHidden = false, // because token doesn't contain balance info
|
||||
modifier = Modifier.roundedShapeItemDecoration(
|
||||
currentIndex = index,
|
||||
lastIndex = state.value.items.lastIndex,
|
||||
addDefaultPadding = false,
|
||||
backgroundColor = TangemTheme.colors.background.primary,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
package com.tangem.feature.swap.di
|
||||
|
||||
import com.tangem.domain.staking.repositories.StakingRepository
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.tokens.repository.NetworksRepository
|
||||
import com.tangem.domain.tokens.repository.QuotesRepository
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.components.ViewModelComponent
|
||||
import dagger.hilt.android.scopes.ViewModelScoped
|
||||
|
||||
@Module
|
||||
@InstallIn(ViewModelComponent::class)
|
||||
class SwapPresentationModule {
|
||||
|
||||
@ViewModelScoped
|
||||
@Provides
|
||||
fun providesGetCryptoCurrenciesUseCase(
|
||||
currenciesRepository: CurrenciesRepository,
|
||||
dispatcherProvider: CoroutineDispatcherProvider,
|
||||
quotesRepository: QuotesRepository,
|
||||
networksRepository: NetworksRepository,
|
||||
stakingRepository: StakingRepository,
|
||||
): GetCryptoCurrencyStatusSyncUseCase {
|
||||
return GetCryptoCurrencyStatusSyncUseCase(
|
||||
currenciesRepository = currenciesRepository,
|
||||
quotesRepository = quotesRepository,
|
||||
networksRepository = networksRepository,
|
||||
stakingRepository = stakingRepository,
|
||||
dispatchers = dispatcherProvider,
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue