Updated on 2026-08-14
This commit is contained in:
parent
99dfa2a392
commit
e511e84508
12 changed files with 238 additions and 92 deletions
|
|
@ -0,0 +1,26 @@
|
|||
package com.tangem.core.ui.decompose
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Modifier
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@Stable
|
||||
interface ComposableListContentComponent<T> {
|
||||
|
||||
val uiState: StateFlow<T>
|
||||
|
||||
fun LazyListScope.content(uiState: T, modifier: Modifier)
|
||||
|
||||
companion object {
|
||||
val EMPTY = EmptyComposableListContentComponent
|
||||
}
|
||||
}
|
||||
|
||||
object EmptyComposableListContentComponent : ComposableListContentComponent<Unit> {
|
||||
override val uiState: StateFlow<Unit> = MutableStateFlow(Unit)
|
||||
|
||||
override fun LazyListScope.content(uiState: Unit, modifier: Modifier) { /* no-op */
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.onramp.selecttoken
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
|
|
@ -41,11 +42,13 @@ internal class DefaultOnrampOperationComponent @AssistedInject constructor(
|
|||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state = model.state.collectAsStateWithLifecycle()
|
||||
val state by model.state.collectAsStateWithLifecycle()
|
||||
val onrampTokenListState by onrampTokenListComponent.uiState.collectAsStateWithLifecycle()
|
||||
|
||||
OnrampSelectToken(
|
||||
state = state.value,
|
||||
state = state,
|
||||
onrampTokenListComponent = onrampTokenListComponent,
|
||||
onrampTokenListState = onrampTokenListState,
|
||||
hotCryptoComponent = hotCryptoComponent,
|
||||
modifier = modifier,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,12 +21,14 @@ import com.tangem.features.onramp.hottokens.HotCryptoComponent
|
|||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.selecttoken.entity.OnrampOperationUM
|
||||
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
internal fun OnrampSelectToken(
|
||||
state: OnrampOperationUM,
|
||||
onrampTokenListComponent: OnrampTokenListComponent,
|
||||
onrampTokenListState: TokenListUM,
|
||||
hotCryptoComponent: HotCryptoComponent?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
|
@ -50,8 +52,9 @@ internal fun OnrampSelectToken(
|
|||
)
|
||||
}
|
||||
|
||||
item(key = "token_list", contentType = "token_list") {
|
||||
onrampTokenListComponent.Content(
|
||||
with(onrampTokenListComponent) {
|
||||
content(
|
||||
uiState = onrampTokenListState,
|
||||
modifier = Modifier
|
||||
.padding(top = 8.dp)
|
||||
.padding(horizontal = 16.dp)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.onramp.swap
|
|||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
|
|
@ -54,12 +55,16 @@ internal class DefaultSwapSelectTokensComponent @AssistedInject constructor(
|
|||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state = model.state.collectAsStateWithLifecycle()
|
||||
val state by model.state.collectAsStateWithLifecycle()
|
||||
val fromTokensState by selectFromTokenListComponent.uiState.collectAsStateWithLifecycle()
|
||||
val toTokensState by selectToTokenListComponent.uiState.collectAsStateWithLifecycle()
|
||||
|
||||
SwapSelectTokens(
|
||||
state = state.value,
|
||||
state = state,
|
||||
selectFromTokenListComponent = selectFromTokenListComponent,
|
||||
selectFromTokenListState = fromTokensState,
|
||||
selectToTokenListComponent = selectToTokenListComponent,
|
||||
selectToTokenListState = toTokensState,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,15 @@ package com.tangem.features.onramp.swap.availablepairs
|
|||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.decompose.ComposableListContentComponent
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
/** Token list component that present list of available tokens for swap */
|
||||
@Stable
|
||||
internal interface AvailableSwapPairsComponent : ComposableContentComponent {
|
||||
internal interface AvailableSwapPairsComponent : ComposableListContentComponent<TokenListUM> {
|
||||
|
||||
/** Component factory */
|
||||
interface Factory : ComponentFactory<Params, AvailableSwapPairsComponent>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
package com.tangem.features.onramp.swap.availablepairs
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.features.onramp.swap.availablepairs.model.AvailableSwapPairsModel
|
||||
import com.tangem.features.onramp.tokenlist.ui.TokenList
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
import com.tangem.features.onramp.tokenlist.ui.onrampTokenList
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@Stable
|
||||
internal class DefaultAvailableSwapPairsComponent @AssistedInject constructor(
|
||||
|
|
@ -21,11 +21,11 @@ internal class DefaultAvailableSwapPairsComponent @AssistedInject constructor(
|
|||
|
||||
private val model: AvailableSwapPairsModel = getOrCreateModel(params)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.state.collectAsStateWithLifecycle()
|
||||
override val uiState: StateFlow<TokenListUM>
|
||||
get() = model.state
|
||||
|
||||
TokenList(state = state, modifier = modifier)
|
||||
override fun LazyListScope.content(uiState: TokenListUM, modifier: Modifier) {
|
||||
onrampTokenList(state = uiState)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import androidx.compose.runtime.LaunchedEffect
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
|
@ -23,6 +24,7 @@ import com.tangem.features.onramp.swap.availablepairs.AvailableSwapPairsComponen
|
|||
import com.tangem.features.onramp.swap.entity.ExchangeCardUM
|
||||
import com.tangem.features.onramp.swap.entity.SwapSelectTokensUM
|
||||
import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
|
||||
/**
|
||||
* Swap select tokens
|
||||
|
|
@ -39,7 +41,9 @@ import com.tangem.features.onramp.tokenlist.OnrampTokenListComponent
|
|||
internal fun SwapSelectTokens(
|
||||
state: SwapSelectTokensUM,
|
||||
selectFromTokenListComponent: OnrampTokenListComponent,
|
||||
selectFromTokenListState: TokenListUM,
|
||||
selectToTokenListComponent: AvailableSwapPairsComponent,
|
||||
selectToTokenListState: TokenListUM,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
BackHandler(onBack = state.onBackClick)
|
||||
|
|
@ -77,33 +81,33 @@ internal fun SwapSelectTokens(
|
|||
}
|
||||
|
||||
if (state.exchangeFrom is ExchangeCardUM.Empty) {
|
||||
item(key = "select_from", contentType = "select_from") {
|
||||
selectFromTokenListComponent.Content(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.animateItem(),
|
||||
with(selectFromTokenListComponent) {
|
||||
content(
|
||||
uiState = selectFromTokenListState,
|
||||
modifier = Modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (state.exchangeFrom is ExchangeCardUM.Filled) {
|
||||
item(key = "exchange_to", contentType = "exchange_to") {
|
||||
ExchangeCard(
|
||||
state = state.exchangeTo,
|
||||
isBalanceHidden = state.isBalanceHidden,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(bottom = 12.dp)
|
||||
.animateItem(),
|
||||
)
|
||||
if (selectToTokenListState.warning != NotificationUM.Warning.SwapNoAvailablePair) {
|
||||
ExchangeCard(
|
||||
state = state.exchangeTo,
|
||||
isBalanceHidden = state.isBalanceHidden,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(bottom = 12.dp)
|
||||
.animateItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (state.exchangeTo is ExchangeCardUM.Empty) {
|
||||
item(key = "select_to", contentType = "select_to") {
|
||||
selectToTokenListComponent.Content(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.animateItem(),
|
||||
with(selectToTokenListComponent) {
|
||||
content(
|
||||
uiState = selectToTokenListState,
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
package com.tangem.features.onramp.tokenlist
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
import com.tangem.features.onramp.tokenlist.model.OnrampTokenListModel
|
||||
import com.tangem.features.onramp.tokenlist.ui.TokenList
|
||||
import com.tangem.features.onramp.tokenlist.ui.onrampTokenList
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@Stable
|
||||
internal class DefaultOnrampTokenListComponent @AssistedInject constructor(
|
||||
|
|
@ -21,11 +21,11 @@ internal class DefaultOnrampTokenListComponent @AssistedInject constructor(
|
|||
|
||||
private val model: OnrampTokenListModel = getOrCreateModel(params)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.state.collectAsStateWithLifecycle()
|
||||
override val uiState: StateFlow<TokenListUM>
|
||||
get() = model.state
|
||||
|
||||
TokenList(state = state, modifier = modifier)
|
||||
override fun LazyListScope.content(uiState: TokenListUM, modifier: Modifier) {
|
||||
onrampTokenList(state = uiState)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
|
|
|
|||
|
|
@ -3,14 +3,15 @@ package com.tangem.features.onramp.tokenlist
|
|||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.decompose.ComposableListContentComponent
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.onramp.tokenlist.entity.OnrampOperation
|
||||
import com.tangem.features.onramp.tokenlist.entity.TokenListUM
|
||||
|
||||
/** Token list component that present list of token for multi-currency wallet */
|
||||
@Stable
|
||||
internal interface OnrampTokenListComponent : ComposableContentComponent {
|
||||
internal interface OnrampTokenListComponent : ComposableListContentComponent<TokenListUM> {
|
||||
|
||||
/** Component factory */
|
||||
interface Factory : ComponentFactory<Params, OnrampTokenListComponent>
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ internal class SetNothingToFoundStateTransformer(
|
|||
id = emptySearchMessageReference.hashCode(),
|
||||
text = emptySearchMessageReference,
|
||||
).let(::add)
|
||||
}
|
||||
.toImmutableList(),
|
||||
}.toImmutableList(),
|
||||
unavailableItems = persistentListOf(),
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.getFormatte
|
|||
import com.tangem.common.ui.tokens.TokenItemStateConverter.Companion.isFlickering
|
||||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
|
|
@ -21,7 +22,13 @@ internal object OnrampTokenItemStateConverterFactory {
|
|||
): TokenItemStateConverter {
|
||||
return TokenItemStateConverter(
|
||||
appCurrency = appCurrency,
|
||||
subtitleStateProvider = { createSubtitleState(status = it, isAvailable = true) },
|
||||
subtitleStateProvider = {
|
||||
createSubtitleState(
|
||||
status = it,
|
||||
isAvailable = true,
|
||||
text = stringReference(value = it.currency.symbol),
|
||||
)
|
||||
},
|
||||
subtitle2StateProvider = ::createSubtitle2State,
|
||||
fiatAmountStateProvider = {
|
||||
createFiatAmountStateProvider(status = it, appCurrency = appCurrency, isAvailable = true)
|
||||
|
|
@ -40,7 +47,13 @@ internal object OnrampTokenItemStateConverterFactory {
|
|||
isAvailable = false,
|
||||
)
|
||||
},
|
||||
subtitleStateProvider = { createSubtitleState(status = it, isAvailable = false) },
|
||||
subtitleStateProvider = {
|
||||
createSubtitleState(
|
||||
status = it,
|
||||
text = stringReference(value = it.currency.symbol),
|
||||
isAvailable = false,
|
||||
)
|
||||
},
|
||||
subtitle2StateProvider = ::createSubtitle2State,
|
||||
fiatAmountStateProvider = {
|
||||
createFiatAmountStateProvider(status = it, appCurrency = appCurrency, isAvailable = false)
|
||||
|
|
@ -48,12 +61,43 @@ internal object OnrampTokenItemStateConverterFactory {
|
|||
)
|
||||
}
|
||||
|
||||
private fun createSubtitleState(status: CryptoCurrencyStatus, isAvailable: Boolean): TokenItemState.SubtitleState {
|
||||
fun createUnavailableItemConverterV2(
|
||||
appCurrency: AppCurrency,
|
||||
unavailableErrorText: TextReference,
|
||||
): TokenItemStateConverter {
|
||||
return TokenItemStateConverter(
|
||||
appCurrency = appCurrency,
|
||||
iconStateProvider = { CryptoCurrencyToIconStateConverter(isAvailable = false).convert(it) },
|
||||
titleStateProvider = {
|
||||
TokenItemState.TitleState.Content(
|
||||
text = stringReference(value = it.currency.name),
|
||||
isAvailable = false,
|
||||
)
|
||||
},
|
||||
subtitleStateProvider = {
|
||||
createSubtitleState(
|
||||
status = it,
|
||||
isAvailable = false,
|
||||
text = unavailableErrorText,
|
||||
)
|
||||
},
|
||||
subtitle2StateProvider = ::createSubtitle2State,
|
||||
fiatAmountStateProvider = {
|
||||
createFiatAmountStateProvider(status = it, appCurrency = appCurrency, isAvailable = false)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun createSubtitleState(
|
||||
status: CryptoCurrencyStatus,
|
||||
isAvailable: Boolean,
|
||||
text: TextReference,
|
||||
): TokenItemState.SubtitleState {
|
||||
return when (status.value) {
|
||||
CryptoCurrencyStatus.Loading -> TokenItemState.SubtitleState.Loading
|
||||
else -> {
|
||||
TokenItemState.SubtitleState.TextContent(
|
||||
value = stringReference(value = status.currency.symbol),
|
||||
value = text,
|
||||
isAvailable = isAvailable,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,27 +3,28 @@ package com.tangem.features.onramp.tokenlist.ui
|
|||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.fastForEachIndexed
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.components.SpacerH12
|
||||
import com.tangem.core.ui.components.fields.SearchBar
|
||||
import com.tangem.core.ui.components.fields.TangemSearchBarDefaults
|
||||
import com.tangem.core.ui.components.fields.entity.SearchBarUM
|
||||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.components.tokenlist.PortfolioListItem
|
||||
import com.tangem.core.ui.components.tokenlist.PortfolioTokensListItem
|
||||
import com.tangem.core.ui.components.tokenlist.TokenListItem
|
||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
|
||||
import com.tangem.core.ui.extensions.conditional
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.BuyTokenScreenTestTags
|
||||
|
|
@ -36,17 +37,21 @@ import kotlinx.collections.immutable.ImmutableList
|
|||
* Token list
|
||||
*
|
||||
* @param state state
|
||||
* @param modifier modifier
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
internal fun TokenList(state: TokenListUM, modifier: Modifier = Modifier) {
|
||||
Column(modifier) {
|
||||
if (state.warning == null) {
|
||||
SearchBar(searchBarUM = state.searchBarUM)
|
||||
} else {
|
||||
AnimatedContent(targetState = state.warning, label = "") { warning ->
|
||||
internal fun LazyListScope.onrampTokenList(state: TokenListUM) {
|
||||
val itemModifier = Modifier.padding(horizontal = 16.dp)
|
||||
|
||||
if (state.warning == null) {
|
||||
searchBarItem(searchBarUM = state.searchBarUM, modifier = itemModifier)
|
||||
} else {
|
||||
item("NotificationsKey") {
|
||||
AnimatedContent(
|
||||
targetState = state.warning,
|
||||
label = "",
|
||||
modifier = itemModifier,
|
||||
) { warning ->
|
||||
when (warning) {
|
||||
is NotificationUM.Warning.OnrampErrorNotification -> {
|
||||
Notification(
|
||||
|
|
@ -60,31 +65,29 @@ internal fun TokenList(state: TokenListUM, modifier: Modifier = Modifier) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state.availableItems.isNotEmpty()) {
|
||||
SpacerH12()
|
||||
ItemsBlock(items = state.availableItems, isBalanceHidden = state.isBalanceHidden)
|
||||
}
|
||||
tokensList(items = state.availableItems, isBalanceHidden = state.isBalanceHidden)
|
||||
|
||||
if (state.unavailableItems.isNotEmpty()) {
|
||||
SpacerH12()
|
||||
ItemsBlock(items = state.unavailableItems, isBalanceHidden = state.isBalanceHidden)
|
||||
}
|
||||
tokensList(items = state.unavailableItems, isBalanceHidden = state.isBalanceHidden)
|
||||
}
|
||||
|
||||
private fun LazyListScope.searchBarItem(searchBarUM: SearchBarUM, modifier: Modifier = Modifier) {
|
||||
item("SearchKey") {
|
||||
SearchBar(
|
||||
state = searchBarUM,
|
||||
colors = TangemSearchBarDefaults.secondaryTextFieldColors,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SearchBar(searchBarUM: SearchBarUM) {
|
||||
SearchBar(
|
||||
state = searchBarUM,
|
||||
colors = TangemSearchBarDefaults.secondaryTextFieldColors,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ItemsBlock(items: ImmutableList<TokensListItemUM>, isBalanceHidden: Boolean) {
|
||||
items.fastForEachIndexed { index, item ->
|
||||
key(item.id) {
|
||||
private fun LazyListScope.tokensList(items: ImmutableList<TokensListItemUM>, isBalanceHidden: Boolean) {
|
||||
itemsIndexed(
|
||||
items = items,
|
||||
key = { _, item -> item.id },
|
||||
contentType = { _, item -> item::class.java },
|
||||
itemContent = { index, item ->
|
||||
TokenListItem(
|
||||
state = item,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
|
|
@ -92,13 +95,70 @@ private fun ItemsBlock(items: ImmutableList<TokensListItemUM>, isBalanceHidden:
|
|||
.roundedShapeItemDecoration(
|
||||
currentIndex = index,
|
||||
lastIndex = items.lastIndex,
|
||||
addDefaultPadding = false,
|
||||
backgroundColor = TangemTheme.colors.background.primary,
|
||||
)
|
||||
.testTag(BuyTokenScreenTestTags.LAZY_LIST_ITEM)
|
||||
.semantics { lazyListItemPosition = index },
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
internal fun LazyListScope.portfolioTokensList(portfolio: TokensListItemUM.Portfolio, isBalanceHidden: Boolean) {
|
||||
val tokens = portfolio.tokens
|
||||
val isExpanded = portfolio.isExpanded
|
||||
|
||||
portfolioItem(
|
||||
portfolio = portfolio,
|
||||
modifier = Modifier.padding(top = 8.dp),
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
)
|
||||
if (!isExpanded) return
|
||||
itemsIndexed(
|
||||
items = tokens,
|
||||
key = { _, item -> item.id },
|
||||
contentType = { _, item -> item::class.java },
|
||||
itemContent = { tokenIndex, token ->
|
||||
val indexWithHeader = tokenIndex.inc()
|
||||
PortfolioTokensListItem(
|
||||
state = token,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
modifier = Modifier
|
||||
.animateItem()
|
||||
.roundedShapeItemDecoration(
|
||||
currentIndex = indexWithHeader,
|
||||
lastIndex = tokens.lastIndex.inc(),
|
||||
backgroundColor = TangemTheme.colors.background.primary,
|
||||
)
|
||||
.conditional(tokenIndex == tokens.lastIndex) {
|
||||
Modifier.padding(bottom = 8.dp)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun LazyListScope.portfolioItem(
|
||||
portfolio: TokensListItemUM.Portfolio,
|
||||
modifier: Modifier,
|
||||
isBalanceHidden: Boolean,
|
||||
) {
|
||||
item(
|
||||
key = "account-${portfolio.id}",
|
||||
contentType = "account",
|
||||
) {
|
||||
PortfolioListItem(
|
||||
state = portfolio,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
modifier = Modifier
|
||||
.animateItem()
|
||||
.roundedShapeItemDecoration(
|
||||
currentIndex = 0,
|
||||
lastIndex = portfolio.tokens.lastIndex.inc(),
|
||||
backgroundColor = TangemTheme.colors.background.primary,
|
||||
)
|
||||
.then(modifier),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,12 +167,12 @@ private fun ItemsBlock(items: ImmutableList<TokensListItemUM>, isBalanceHidden:
|
|||
@Composable
|
||||
private fun Preview_TokenList(@PreviewParameter(PreviewTokenListUMProvider::class) state: TokenListUM) {
|
||||
TangemThemePreview {
|
||||
TokenList(
|
||||
state = state,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(color = TangemTheme.colors.background.secondary)
|
||||
.padding(16.dp),
|
||||
)
|
||||
LazyColumn(
|
||||
modifier = Modifier.background(color = TangemTheme.colors.background.secondary),
|
||||
) {
|
||||
onrampTokenList(
|
||||
state = state,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue