Updated on 2026-08-14

This commit is contained in:
Tangem 2024-12-11 14:16:39 +04:00
parent 724b7df243
commit da1707a5ea
9 changed files with 135 additions and 146 deletions

View file

@ -8,7 +8,6 @@ import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.fields.SearchBar
import com.tangem.core.ui.components.token.TokenItem
import com.tangem.core.ui.components.tokenlist.internal.GroupTitleItem
import com.tangem.core.ui.components.tokenlist.internal.NetworkTitleItem
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
@ -25,9 +24,6 @@ import com.tangem.core.ui.res.TangemTheme
@Composable
fun TokenListItem(state: TokensListItemUM, isBalanceHidden: Boolean, modifier: Modifier = Modifier) {
when (state) {
is TokensListItemUM.NetworkGroupTitle -> {
NetworkTitleItem(networkName = state.name.resolveReference(), modifier = modifier)
}
is TokensListItemUM.GroupTitle -> {
GroupTitleItem(state, modifier)
}

View file

@ -1,12 +1,32 @@
package com.tangem.core.ui.components.tokenlist.internal
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.R
import com.tangem.core.ui.components.rows.NetworkTitle
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import org.burnoutcrew.reorderable.ReorderableLazyListState
import org.burnoutcrew.reorderable.detectReorder
import org.burnoutcrew.reorderable.rememberReorderableLazyListState
/**
* Group title item
@ -18,14 +38,90 @@ import com.tangem.core.ui.res.TangemTheme
*/
@Composable
fun GroupTitleItem(state: TokensListItemUM.GroupTitle, modifier: Modifier = Modifier) {
BaseGroupTitleItem(text = state.text, modifier = modifier)
}
/**
* Draggable network group item
*
* @param state state
* @param reorderableTokenListState reorderable token list state
* @param modifier modifier
*/
@Composable
fun DraggableGroupTitleItem(
state: TokensListItemUM.GroupTitle,
reorderableTokenListState: ReorderableLazyListState,
modifier: Modifier = Modifier,
) {
BaseGroupTitleItem(
text = state.text,
modifier = modifier,
action = { DraggableIcon(reorderableTokenListState = reorderableTokenListState) },
)
}
@Composable
private fun BaseGroupTitleItem(
text: TextReference,
modifier: Modifier = Modifier,
action: (@Composable BoxScope.() -> Unit)? = null,
) {
NetworkTitle(
title = {
Text(
text = state.text.resolveReference(),
text = text.resolveReference(),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
)
},
modifier = modifier,
action = action,
)
}
}
@Composable
private fun DraggableIcon(reorderableTokenListState: ReorderableLazyListState) {
Box(
modifier = Modifier.detectReorder(reorderableTokenListState),
contentAlignment = Alignment.Center,
) {
Icon(
painter = rememberVectorPainter(
image = ImageVector.vectorResource(id = R.drawable.ic_group_drop_24),
),
contentDescription = null,
tint = TangemTheme.colors.icon.informative,
)
}
}
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun NetworkTitleItemPreview(@PreviewParameter(GroupTitleItemProvider::class) isDraggable: Boolean) {
TangemThemePreview {
val state = TokensListItemUM.GroupTitle(
id = 1,
text = resourceReference(
id = R.string.wallet_network_group_title,
formatArgs = wrappedList(resourceReference(id = R.string.main_tokens)),
),
)
if (isDraggable) {
DraggableGroupTitleItem(
state = state,
reorderableTokenListState = rememberReorderableLazyListState(onMove = { _, _ -> }),
modifier = Modifier.background(color = TangemTheme.colors.background.primary),
)
} else {
GroupTitleItem(
state = state,
modifier = Modifier.background(color = TangemTheme.colors.background.primary),
)
}
}
}
private object GroupTitleItemProvider : CollectionPreviewParameterProvider<Boolean>(collection = listOf(true, false))

View file

@ -1,113 +0,0 @@
package com.tangem.core.ui.components.tokenlist.internal
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.R
import com.tangem.core.ui.components.rows.NetworkTitle
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import org.burnoutcrew.reorderable.ReorderableLazyListState
import org.burnoutcrew.reorderable.detectReorder
import org.burnoutcrew.reorderable.rememberReorderableLazyListState
/**
* Network title item
*
* @param networkName network name
* @param modifier modifier
*/
@Composable
internal fun NetworkTitleItem(networkName: String, modifier: Modifier = Modifier) {
BaseNetworkTitleItem(networkName = networkName, modifier = modifier)
}
/**
* Draggable network title item
*
* @param networkName network name
* @param reorderableTokenListState reorderable token list state
* @param modifier modifier
*/
@Composable
fun DraggableNetworkTitleItem(
networkName: String,
reorderableTokenListState: ReorderableLazyListState,
modifier: Modifier = Modifier,
) {
BaseNetworkTitleItem(
networkName = networkName,
modifier = modifier,
action = { DraggableIcon(reorderableTokenListState = reorderableTokenListState) },
)
}
@Composable
private fun BaseNetworkTitleItem(
networkName: String,
modifier: Modifier = Modifier,
action: (@Composable BoxScope.() -> Unit)? = null,
) {
NetworkTitle(
title = {
Text(
text = stringResourceSafe(id = R.string.wallet_network_group_title, networkName),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
)
},
modifier = modifier,
action = action,
)
}
@Composable
private fun DraggableIcon(reorderableTokenListState: ReorderableLazyListState) {
Box(
modifier = Modifier.detectReorder(reorderableTokenListState),
contentAlignment = Alignment.Center,
) {
Icon(
painter = rememberVectorPainter(
image = ImageVector.vectorResource(id = R.drawable.ic_group_drop_24),
),
contentDescription = null,
tint = TangemTheme.colors.icon.informative,
)
}
}
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun NetworkTitleItemPreview(@PreviewParameter(NetworkTitleItemProvider::class) isDraggable: Boolean) {
TangemThemePreview {
if (isDraggable) {
DraggableNetworkTitleItem(
networkName = "Ethereum",
reorderableTokenListState = rememberReorderableLazyListState(onMove = { _, _ -> }),
modifier = Modifier.background(color = TangemTheme.colors.background.primary),
)
} else {
NetworkTitleItem(
networkName = "Ethereum",
modifier = Modifier.background(color = TangemTheme.colors.background.primary),
)
}
}
}
private object NetworkTitleItemProvider : CollectionPreviewParameterProvider<Boolean>(collection = listOf(true, false))

View file

@ -23,15 +23,6 @@ sealed interface TokensListItemUM {
val searchBarUM: SearchBarUM,
) : TokensListItemUM
/**
* Network group title
*
* @property id id
* @property name network group name
*/
@Deprecated("Use GroupTitle instead") // TODO: [REDACTED_JIRA]
data class NetworkGroupTitle(override val id: Int, val name: TextReference) : TokensListItemUM
/**
* Group title
*

View file

@ -33,15 +33,9 @@ internal object WalletScreenPreviewData {
private val textContentTokensState = WalletTokensListState.ContentState.Content(
items = persistentListOf(
TokensListItemUM.NetworkGroupTitle(
id = 1,
name = stringReference("Bitcoin"),
),
TokensListItemUM.GroupTitle(id = 1, text = stringReference("Network Bitcoin")),
TokensListItemUM.Token(state = tokenItemState),
TokensListItemUM.NetworkGroupTitle(
id = 2,
name = stringReference("Ethereum"),
),
TokensListItemUM.GroupTitle(id = 2, text = stringReference("Network Ethereum")),
TokensListItemUM.Token(
state = tokenItemState.copy(
id = "2",

View file

@ -31,7 +31,7 @@ import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
import com.tangem.core.ui.components.buttons.actions.RoundedActionButton
import com.tangem.core.ui.components.token.TokenItem
import com.tangem.core.ui.components.tokenlist.internal.DraggableNetworkTitleItem
import com.tangem.core.ui.components.tokenlist.internal.DraggableGroupTitleItem
import com.tangem.core.ui.event.EventEffect
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringResourceSafe
@ -176,10 +176,10 @@ private fun LazyItemScope.DraggableItem(
val modifierWithBackground = itemModifier.background(color = TangemTheme.colors.background.primary)
when (item) {
is DraggableItem.GroupHeader -> DraggableNetworkTitleItem(
modifier = modifierWithBackground,
networkName = item.networkName,
is DraggableItem.GroupHeader -> DraggableGroupTitleItem(
state = item.groupTitle,
reorderableTokenListState = reorderableState,
modifier = modifierWithBackground,
)
is DraggableItem.Token -> TokenItem(
modifier = modifierWithBackground,

View file

@ -2,6 +2,10 @@ package com.tangem.feature.wallet.presentation.organizetokens.model
import androidx.compose.runtime.Immutable
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.core.ui.extensions.wrappedList
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem.RoundingMode
/**
@ -30,7 +34,16 @@ internal sealed class DraggableItem {
val networkName: String,
override val roundingMode: RoundingMode = RoundingMode.None,
override val showShadow: Boolean = false,
) : DraggableItem()
) : DraggableItem() {
val groupTitle = TokensListItemUM.GroupTitle(
id = id,
text = resourceReference(
id = R.string.wallet_network_group_title,
formatArgs = wrappedList(networkName),
),
)
}
/**
* Item for token.

View file

@ -3,7 +3,8 @@ package com.tangem.feature.wallet.presentation.wallet.state.model
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.token.state.TokenItemState
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.feature.wallet.impl.R
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@ -30,7 +31,13 @@ internal sealed class WalletTokensListState {
data object Locked : ContentState() {
override val items = persistentListOf(
TokensListItemUM.NetworkGroupTitle(id = 42, name = TextReference.Res(id = R.string.main_tokens)),
TokensListItemUM.GroupTitle(
id = 42,
text = resourceReference(
id = R.string.wallet_network_group_title,
formatArgs = wrappedList(resourceReference(id = R.string.main_tokens)),
),
),
TokensListItemUM.Token(state = TokenItemState.Locked(id = "Locked#1")),
)
override val organizeTokensButtonConfig = null

View file

@ -2,7 +2,8 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers.convert
import com.tangem.common.ui.tokens.TokenItemStateConverter
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
@ -10,6 +11,7 @@ import com.tangem.domain.tokens.model.NetworkGroup
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.tokens.model.TotalFiatBalance
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState
import com.tangem.feature.wallet.presentation.wallet.viewmodels.intents.WalletClickIntents
import com.tangem.utils.converter.Converter
@ -60,9 +62,12 @@ internal class TokenListStateConverter(
}
private fun MutableList<TokensListItemUM>.addGroup(group: NetworkGroup): List<TokensListItemUM> {
val groupTitle = TokensListItemUM.NetworkGroupTitle(
val groupTitle = TokensListItemUM.GroupTitle(
id = group.network.hashCode(),
name = stringReference(group.network.name),
text = resourceReference(
id = R.string.wallet_network_group_title,
formatArgs = wrappedList(group.network.name),
),
)
add(groupTitle)