Updated on 2026-08-14

This commit is contained in:
Tangem 2024-09-09 16:57:58 +03:00
parent c08f69995b
commit 42d67bedb0
6 changed files with 219 additions and 175 deletions

View file

@ -16,6 +16,7 @@ import com.tangem.core.ui.R
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
import com.tangem.core.ui.components.rows.NetworkTitle
import com.tangem.core.ui.components.text.TooltipText
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
@ -27,7 +28,6 @@ import kotlinx.collections.immutable.persistentListOf
@Immutable
class InformationBlockContentScope(val scope: BoxScope) : BoxScope by scope
// TODO: [REDACTED_JIRA]
@Composable
fun InformationBlock(
title: @Composable BoxScope.() -> Unit,
@ -43,49 +43,7 @@ fun InformationBlock(
.background(color = TangemTheme.colors.background.action),
horizontalAlignment = Alignment.Start,
) {
val minHeight = if (action == null) TangemTheme.dimens.size36 else TangemTheme.dimens.size40
val padding = if (action == null) {
PaddingValues(
start = TangemTheme.dimens.spacing12,
top = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing12,
bottom = TangemTheme.dimens.spacing4,
)
} else {
PaddingValues(
start = TangemTheme.dimens.spacing12,
top = TangemTheme.dimens.spacing11,
end = TangemTheme.dimens.spacing12,
bottom = TangemTheme.dimens.spacing5,
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.heightIn(min = minHeight)
.padding(paddingValues = padding),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Box(
modifier = Modifier
.weight(weight = 1f)
.heightIn(min = TangemTheme.dimens.size20),
contentAlignment = Alignment.CenterStart,
content = title,
)
if (action != null) {
Spacer(modifier = Modifier.size(TangemTheme.dimens.spacing8))
Box(
modifier = Modifier
.weight(weight = 1f)
.heightIn(min = TangemTheme.dimens.size24),
contentAlignment = Alignment.CenterEnd,
content = action,
)
}
}
NetworkTitle(title = title, action = action)
if (content != null) {
Box(

View file

@ -0,0 +1,103 @@
package com.tangem.core.ui.components.rows
import android.content.res.Configuration
import androidx.compose.foundation.layout.*
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.res.painterResource
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.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
/**
* Network title component. [title] and [action] composables are placed horizontally
*
* @param title title composable in [BoxScope]
* @param modifier modifier
* @param action optional action composable in [BoxScope]
*
* @see <a href = "https://www.figma.com/design/14ISV23YB1yVW1uNVwqrKv/Android?node-id=2760-2854&t=rupZfuJYbBYDidJv-4"
* >Figma component</a>
*
[REDACTED_AUTHOR]
*/
@Composable
fun NetworkTitle(
title: @Composable BoxScope.() -> Unit,
modifier: Modifier = Modifier,
action: (@Composable BoxScope.() -> Unit)? = null,
) {
val minHeight = if (action == null) TangemTheme.dimens.size36 else TangemTheme.dimens.size40
val padding = if (action == null) {
PaddingValues(
start = TangemTheme.dimens.spacing12,
top = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing12,
bottom = TangemTheme.dimens.spacing4,
)
} else {
PaddingValues(
start = TangemTheme.dimens.spacing12,
top = TangemTheme.dimens.spacing11,
end = TangemTheme.dimens.spacing12,
bottom = TangemTheme.dimens.spacing5,
)
}
Row(
modifier = modifier
.fillMaxWidth()
.heightIn(min = minHeight)
.padding(paddingValues = padding),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
) {
Box(
modifier = Modifier
.weight(weight = 1f)
.heightIn(min = TangemTheme.dimens.size20),
contentAlignment = Alignment.CenterStart,
content = title,
)
if (action != null) {
Spacer(modifier = Modifier.size(TangemTheme.dimens.spacing8))
Box(
modifier = Modifier
.weight(weight = 1f)
.heightIn(min = TangemTheme.dimens.size24),
contentAlignment = Alignment.CenterEnd,
content = action,
)
}
}
}
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun NetworkTitlePreview(@PreviewParameter(NetworkTitleIconVisibilityProvider::class) isIconVisible: Boolean) {
TangemThemePreview {
NetworkTitle(
title = { Text(text = "Network") },
action = {
if (isIconVisible) {
Icon(
painter = painterResource(id = R.drawable.ic_group_drop_24),
tint = TangemTheme.colors.icon.informative,
contentDescription = null,
)
}
},
)
}
}
private object NetworkTitleIconVisibilityProvider : CollectionPreviewParameterProvider<Boolean>(listOf(true, false))

View file

@ -1,124 +0,0 @@
package com.tangem.feature.wallet.presentation.common.component
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
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.res.painterResource
import androidx.compose.ui.res.stringResource
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.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.feature.wallet.impl.R
import org.burnoutcrew.reorderable.ReorderableLazyListState
import org.burnoutcrew.reorderable.detectReorder
@Composable
internal fun NetworkGroupItem(networkName: String, modifier: Modifier = Modifier) {
InternalNetworkGroupItem(modifier = modifier, networkName = networkName)
}
@Composable
internal fun DraggableNetworkGroupItem(
networkName: String,
modifier: Modifier = Modifier,
reorderableTokenListState: ReorderableLazyListState? = null,
) {
InternalNetworkGroupItem(
modifier = modifier,
networkName = networkName,
endIcon = {
Box(
modifier = Modifier
.size(TangemTheme.dimens.size32)
.let {
if (reorderableTokenListState != null) {
it.detectReorder(reorderableTokenListState)
} else {
it
}
},
contentAlignment = Alignment.Center,
) {
Icon(
painter = painterResource(id = R.drawable.ic_group_drop_24),
tint = TangemTheme.colors.icon.informative,
contentDescription = null,
)
}
},
)
}
// TODO: [REDACTED_JIRA]
@Composable
private fun InternalNetworkGroupItem(
networkName: String,
modifier: Modifier = Modifier,
endIcon: @Composable (RowScope.() -> Unit)? = null,
) {
val minHeight = if (endIcon == null) TangemTheme.dimens.size36 else TangemTheme.dimens.size40
val padding = if (endIcon == null) {
PaddingValues(
start = TangemTheme.dimens.spacing12,
top = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing12,
bottom = TangemTheme.dimens.spacing4,
)
} else {
PaddingValues(
start = TangemTheme.dimens.spacing12,
top = TangemTheme.dimens.spacing11,
end = TangemTheme.dimens.spacing12,
bottom = TangemTheme.dimens.spacing5,
)
}
Row(
modifier = modifier
.background(TangemTheme.colors.background.primary)
.fillMaxWidth()
.heightIn(min = minHeight)
.padding(paddingValues = padding),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
) {
Text(
text = stringResource(id = R.string.wallet_network_group_title, networkName),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
)
if (endIcon != null) endIcon()
}
}
// region Preview
@Composable
private fun NetworkGroupItemSample(isDraggable: Boolean) {
if (isDraggable) {
DraggableNetworkGroupItem(networkName = "Ethereum")
} else {
NetworkGroupItem(networkName = "Ethereum")
}
}
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun NetworkGroupItemPreview(@PreviewParameter(NetworkGroupProvider::class) isDraggable: Boolean) {
TangemThemePreview {
NetworkGroupItemSample(isDraggable)
}
}
private class NetworkGroupProvider : CollectionPreviewParameterProvider<Boolean>(
collection = listOf(true, false),
)
// endregion Preview

View file

@ -0,0 +1,103 @@
package com.tangem.feature.wallet.presentation.common.component
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.foundation.layout.size
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.stringResource
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.components.rows.NetworkTitle
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.feature.wallet.impl.R
import org.burnoutcrew.reorderable.ReorderableLazyListState
import org.burnoutcrew.reorderable.detectReorder
import org.burnoutcrew.reorderable.rememberReorderableLazyListState
@Composable
internal fun NetworkTitleItem(networkName: String, modifier: Modifier = Modifier) {
BaseNetworkTitleItem(networkName = networkName, modifier = modifier)
}
@Composable
internal 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 = stringResource(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
.size(TangemTheme.dimens.size32)
.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

@ -39,7 +39,7 @@ import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.utils.WindowInsetsZero
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
import com.tangem.feature.wallet.presentation.common.component.DraggableNetworkGroupItem
import com.tangem.feature.wallet.presentation.common.component.DraggableNetworkTitleItem
import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem
import com.tangem.feature.wallet.presentation.organizetokens.model.OrganizeTokensListState
import com.tangem.feature.wallet.presentation.organizetokens.model.OrganizeTokensState
@ -173,14 +173,16 @@ private fun LazyItemScope.DraggableItem(
) { isItemDragging ->
isDragging = isItemDragging
val modifierWithBackground = itemModifier.background(color = TangemTheme.colors.background.primary)
when (item) {
is DraggableItem.GroupHeader -> DraggableNetworkGroupItem(
modifier = itemModifier,
is DraggableItem.GroupHeader -> DraggableNetworkTitleItem(
modifier = modifierWithBackground,
networkName = item.networkName,
reorderableTokenListState = reorderableState,
)
is DraggableItem.Token -> TokenItem(
modifier = itemModifier.background(color = TangemTheme.colors.background.primary),
modifier = modifierWithBackground,
state = item.tokenItemState,
reorderableTokenListState = reorderableState,
isBalanceHidden = isBalanceHidden,

View file

@ -6,7 +6,7 @@ import androidx.compose.ui.Modifier
import com.tangem.core.ui.components.token.TokenItem
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.wallet.presentation.common.component.NetworkGroupItem
import com.tangem.feature.wallet.presentation.common.component.NetworkTitleItem
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletTokensListState.TokensListItemState
/**
@ -23,15 +23,17 @@ internal fun MultiCurrencyContentItem(
isBalanceHidden: Boolean,
modifier: Modifier = Modifier,
) {
val modifierWithBackground = modifier.background(color = TangemTheme.colors.background.primary)
when (state) {
is TokensListItemState.NetworkGroupTitle -> {
NetworkGroupItem(networkName = state.name.resolveReference(), modifier = modifier)
NetworkTitleItem(networkName = state.name.resolveReference(), modifier = modifierWithBackground)
}
is TokensListItemState.Token -> {
TokenItem(
state = state.state,
isBalanceHidden = isBalanceHidden,
modifier = modifier.background(color = TangemTheme.colors.background.primary),
modifier = modifierWithBackground,
)
}
}