Updated on 2026-08-14

This commit is contained in:
Tangem 2024-08-01 15:21:44 +04:00
parent 6e67390a0d
commit 2aea20e597
12 changed files with 828 additions and 1 deletions

View file

@ -3,6 +3,7 @@ package com.tangem.core.ui.components
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.ime
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.platform.LocalDensity
@ -14,11 +15,15 @@ sealed interface Keyboard {
data class Opened(override val height: Dp) : Keyboard
object Closed : Keyboard {
data object Closed : Keyboard {
override val height: Dp = 0.dp
}
}
val Keyboard.isOpened: Boolean
@Stable
get() = this is Keyboard.Opened
/**
* Allows to subscribe to a soft keyboard to detect when it's open/closed
*/

View file

@ -0,0 +1,19 @@
package com.tangem.features.managetokens.component
import androidx.compose.foundation.lazy.LazyListScope
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.wallets.models.UserWalletId
internal interface CustomTokenFormComponent {
fun content(scope: LazyListScope)
data class Params(
val userWalletId: UserWalletId,
val networkId: Network.ID,
)
interface Factory {
fun create(params: Params): CustomTokenFormComponent
}
}

View file

@ -0,0 +1,20 @@
package com.tangem.features.managetokens.component
import androidx.compose.foundation.lazy.LazyListScope
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.managetokens.entity.SelectedNetworkUM
internal interface CustomTokenNetworkSelectorComponent {
fun content(scope: LazyListScope)
data class Params(
val userWalletId: UserWalletId,
val selectedNetwork: SelectedNetworkUM?,
val onNetworkSelected: (SelectedNetworkUM) -> Unit,
)
interface Factory {
fun create(params: Params): CustomTokenNetworkSelectorComponent
}
}

View file

@ -0,0 +1,81 @@
package com.tangem.features.managetokens.component.preview
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.managetokens.component.AddCustomTokenComponent
import com.tangem.features.managetokens.component.CustomTokenNetworkSelectorComponent
import com.tangem.features.managetokens.entity.AddCustomTokenButtonUM
import com.tangem.features.managetokens.entity.AddCustomTokenUM
import com.tangem.features.managetokens.entity.ClickableFieldUM
import com.tangem.features.managetokens.entity.SelectedNetworkUM
import com.tangem.features.managetokens.impl.R
import com.tangem.features.managetokens.ui.AddCustomTokenBottomSheet
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
internal class PreviewAddCustomTokenComponent(
initialState: AddCustomTokenUM = AddCustomTokenUM.NetworkSelector(),
) : AddCustomTokenComponent {
private val userWalletId = UserWalletId(stringValue = "321")
private val previewState: MutableStateFlow<AddCustomTokenUM> = MutableStateFlow(initialState)
@Composable
override fun BottomSheet(isVisible: Boolean, onDismiss: () -> Unit) {
val state by previewState.collectAsStateWithLifecycle()
val config = TangemBottomSheetConfig(
isShow = isVisible,
onDismissRequest = onDismiss,
content = state,
)
AddCustomTokenBottomSheet(
config = config,
content = {
when (val s = state) {
is AddCustomTokenUM.Form -> {
PreviewCustomTokenFormComponent(
networkName = ClickableFieldUM(
label = resourceReference(R.string.custom_token_network_input_title),
value = stringReference(s.selectedNetwork.name),
onClick = { showNetworkSelector(s.selectedNetwork) },
),
).content(this)
}
is AddCustomTokenUM.NetworkSelector -> {
PreviewCustomTokenNetworkSelectorComponent(
params = CustomTokenNetworkSelectorComponent.Params(
userWalletId = userWalletId,
selectedNetwork = s.selectedNetwork,
onNetworkSelected = ::showForm,
),
networksSize = 20,
).content(this)
}
}
},
)
}
private fun showNetworkSelector(selectedNetwork: SelectedNetworkUM) {
previewState.update { AddCustomTokenUM.NetworkSelector(selectedNetwork) }
}
private fun showForm(network: SelectedNetworkUM) {
previewState.update {
AddCustomTokenUM.Form(
selectedNetwork = network,
addTokenButton = AddCustomTokenButtonUM.Visible(
isEnabled = false,
onClick = {},
),
)
}
}
}

View file

@ -0,0 +1,81 @@
package com.tangem.features.managetokens.component.preview
import androidx.compose.foundation.lazy.LazyListScope
import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.features.managetokens.component.CustomTokenFormComponent
import com.tangem.features.managetokens.entity.ClickableFieldUM
import com.tangem.features.managetokens.entity.CustomTokenFormUM
import com.tangem.features.managetokens.entity.TextInputFieldUM
import com.tangem.features.managetokens.impl.R
import com.tangem.features.managetokens.ui.customTokenFormContent
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
internal class PreviewCustomTokenFormComponent(
networkName: ClickableFieldUM = ClickableFieldUM(
label = resourceReference(R.string.custom_token_network_input_title),
value = stringReference(value = "Ethereum"),
onClick = {},
),
derivationPath: ClickableFieldUM = ClickableFieldUM(
label = resourceReference(R.string.custom_token_derivation_path),
value = stringReference(value = "Default"),
onClick = {},
),
canAddToken: Boolean = false,
contractAddress: TextInputFieldUM = TextInputFieldUM(
label = resourceReference(R.string.custom_token_contract_address_input_title),
placeholder = stringReference(value = "0x000000000000000000000000000"),
value = "",
onValueChange = {},
),
tokenName: TextInputFieldUM = TextInputFieldUM(
label = resourceReference(R.string.custom_token_name_input_title),
placeholder = stringReference(value = "E.g. USD Coin"),
value = "",
onValueChange = {},
),
tokenSymbol: TextInputFieldUM = TextInputFieldUM(
label = resourceReference(R.string.custom_token_token_symbol_input_title),
placeholder = stringReference(value = "E.g. USDC"),
value = "",
onValueChange = {},
),
tokenDecimals: TextInputFieldUM = TextInputFieldUM(
label = resourceReference(R.string.custom_token_decimals_input_title),
placeholder = stringReference(value = "8"),
value = "",
onValueChange = {},
),
notifications: ImmutableList<CustomTokenFormUM.NotificationUM> = persistentListOf(
CustomTokenFormUM.NotificationUM(
id = "1",
config = NotificationConfig(
title = stringReference(value = "Note that tokens can be created by anyone"),
subtitle = stringReference(value = "Be aware of adding scam tokens, they can cost nothing"),
iconResId = R.drawable.img_attention_20,
),
),
),
) : CustomTokenFormComponent {
private val previewState = CustomTokenFormUM(
networkName = networkName,
contractAddress = contractAddress,
tokenName = tokenName,
tokenSymbol = tokenSymbol,
tokenDecimals = tokenDecimals,
derivationPath = derivationPath,
notifications = notifications,
canAddToken = canAddToken,
onDerivationPathClick = {},
onNetworkClick = {},
onAddClick = {},
)
override fun content(scope: LazyListScope) {
scope.customTokenFormContent(model = previewState)
}
}

View file

@ -0,0 +1,49 @@
package com.tangem.features.managetokens.component.preview
import androidx.compose.foundation.lazy.LazyListScope
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.managetokens.component.CustomTokenNetworkSelectorComponent
import com.tangem.features.managetokens.entity.CurrencyNetworkUM
import com.tangem.features.managetokens.entity.CustomTokenNetworkSelectorUM
import com.tangem.features.managetokens.entity.SelectedNetworkUM
import com.tangem.features.managetokens.impl.R
import com.tangem.features.managetokens.ui.customTokenNetworkSelectorContent
import kotlinx.collections.immutable.toImmutableList
internal class PreviewCustomTokenNetworkSelectorComponent(
private val params: CustomTokenNetworkSelectorComponent.Params = CustomTokenNetworkSelectorComponent.Params(
userWalletId = UserWalletId(stringValue = "321"),
selectedNetwork = null,
onNetworkSelected = {},
),
networksSize: Int = 5,
) : CustomTokenNetworkSelectorComponent {
private val previewNetworks = List(size = networksSize) { networkIndex ->
val n = SelectedNetworkUM(
id = Network.ID(networkIndex.toString()),
name = "Network $networkIndex",
)
CurrencyNetworkUM(
id = n.id,
name = n.name,
type = "N$networkIndex",
iconResId = R.drawable.ic_eth_16,
isMainNetwork = false,
isSelected = n.id == params.selectedNetwork?.id,
onSelectedStateChange = { params.onNetworkSelected(n) },
)
}.toImmutableList()
private val previewState = CustomTokenNetworkSelectorUM(
networks = previewNetworks,
)
override fun content(scope: LazyListScope) {
scope.customTokenNetworkSelectorContent(
model = previewState,
)
}
}

View file

@ -0,0 +1,50 @@
package com.tangem.features.managetokens.entity
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.domain.tokens.model.Network
@Immutable
internal sealed class AddCustomTokenUM : TangemBottomSheetConfigContent {
abstract val selectedNetwork: SelectedNetworkUM?
abstract val addTokenButton: AddCustomTokenButtonUM
data class NetworkSelector(
override val selectedNetwork: SelectedNetworkUM? = null,
) : AddCustomTokenUM() {
override val addTokenButton: AddCustomTokenButtonUM = AddCustomTokenButtonUM.Hidden
}
data class Form(
override val selectedNetwork: SelectedNetworkUM,
override val addTokenButton: AddCustomTokenButtonUM.Visible,
) : AddCustomTokenUM()
}
@Immutable
internal data class SelectedNetworkUM(
val id: Network.ID,
val name: String,
)
@Immutable
internal sealed class AddCustomTokenButtonUM {
open val onClick: () -> Unit = {}
open val isEnabled: Boolean = false
val isVisible: Boolean
get() = this is Visible
data object Hidden : AddCustomTokenButtonUM() {
override val onClick: () -> Unit = {}
}
data class Visible(
override val isEnabled: Boolean,
override val onClick: () -> Unit,
) : AddCustomTokenButtonUM()
}

View file

@ -0,0 +1,44 @@
package com.tangem.features.managetokens.entity
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.TextReference
import kotlinx.collections.immutable.ImmutableList
@Immutable
internal data class CustomTokenFormUM(
val networkName: ClickableFieldUM,
val contractAddress: TextInputFieldUM,
val tokenName: TextInputFieldUM,
val tokenSymbol: TextInputFieldUM,
val tokenDecimals: TextInputFieldUM,
val derivationPath: ClickableFieldUM,
val notifications: ImmutableList<NotificationUM>,
val canAddToken: Boolean,
val onNetworkClick: () -> Unit,
val onDerivationPathClick: () -> Unit,
val onAddClick: () -> Unit,
) {
@Immutable
data class NotificationUM(
val id: String,
val config: NotificationConfig,
)
}
@Immutable
internal data class TextInputFieldUM(
val label: TextReference,
val placeholder: TextReference,
val value: String,
val onValueChange: (String) -> Unit,
val error: TextReference? = null,
)
@Immutable
internal data class ClickableFieldUM(
val label: TextReference,
val value: TextReference,
val onClick: () -> Unit,
)

View file

@ -0,0 +1,9 @@
package com.tangem.features.managetokens.entity
import androidx.compose.runtime.Immutable
import kotlinx.collections.immutable.ImmutableList
@Immutable
internal data class CustomTokenNetworkSelectorUM(
val networks: ImmutableList<CurrencyNetworkUM>,
)

View file

@ -0,0 +1,148 @@
package com.tangem.features.managetokens.ui
import android.content.res.Configuration
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.material3.FabPosition
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.isOpened
import com.tangem.core.ui.components.keyboardAsState
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.domain.tokens.model.Network
import com.tangem.features.managetokens.component.AddCustomTokenComponent
import com.tangem.features.managetokens.component.preview.PreviewAddCustomTokenComponent
import com.tangem.features.managetokens.entity.AddCustomTokenButtonUM
import com.tangem.features.managetokens.entity.AddCustomTokenUM
import com.tangem.features.managetokens.entity.SelectedNetworkUM
import com.tangem.features.managetokens.impl.R
@Composable
internal fun AddCustomTokenBottomSheet(config: TangemBottomSheetConfig, content: LazyListScope.() -> Unit) {
TangemBottomSheet(
config = config,
titleText = resourceReference(R.string.add_custom_token_title),
containerColor = TangemTheme.colors.background.secondary,
content = { model: AddCustomTokenUM ->
Content(
model = model,
content = content,
)
},
)
}
@Composable
private fun Content(model: AddCustomTokenUM, content: LazyListScope.() -> Unit, modifier: Modifier = Modifier) {
val density = LocalDensity.current
val keyboardState by keyboardAsState()
var fabHeight by remember { mutableStateOf(0.dp) }
Scaffold(
modifier = modifier.imePadding(),
containerColor = TangemTheme.colors.background.secondary,
floatingActionButtonPosition = FabPosition.Center,
floatingActionButton = {
AnimatedVisibility(
modifier = Modifier.onSizeChanged {
fabHeight = with(density) { it.height.toDp() }
},
visible = model.addTokenButton.isVisible && !keyboardState.isOpened,
enter = fadeIn(),
exit = fadeOut(),
label = "Add button visibility",
) {
PrimaryButton(
modifier = Modifier
.padding(bottom = TangemTheme.dimens.spacing16)
.padding(horizontal = TangemTheme.dimens.spacing16)
.fillMaxWidth(),
text = stringResource(id = R.string.custom_token_add_token),
enabled = model.addTokenButton.isEnabled,
onClick = model.addTokenButton.onClick,
)
}
},
) { paddingValues ->
LazyColumn(
modifier = Modifier.padding(paddingValues),
contentPadding = PaddingValues(
start = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing16,
bottom = TangemTheme.dimens.spacing32 + fabHeight,
),
) {
item {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = TangemTheme.dimens.spacing16),
contentAlignment = Alignment.Center,
) {
Text(
modifier = Modifier.fillMaxWidth(fraction = 0.7f),
text = stringResource(id = R.string.custom_token_subtitle),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.secondary,
textAlign = TextAlign.Center,
)
}
}
content()
}
}
}
// region Preview
@Composable
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun Preview_AddCustomTokenBottomSheet(
@PreviewParameter(AddCustomTokenComponentPreviewProvider::class) component: AddCustomTokenComponent,
) {
TangemThemePreview {
component.BottomSheet(isVisible = true, onDismiss = {})
}
}
private class AddCustomTokenComponentPreviewProvider : PreviewParameterProvider<AddCustomTokenComponent> {
override val values: Sequence<AddCustomTokenComponent>
get() = sequenceOf(
PreviewAddCustomTokenComponent(),
PreviewAddCustomTokenComponent(
initialState = AddCustomTokenUM.Form(
selectedNetwork = SelectedNetworkUM(
id = Network.ID(value = "1"),
name = "Ethereum",
),
addTokenButton = AddCustomTokenButtonUM.Visible(
isEnabled = false,
onClick = {},
),
),
),
)
}
// endregion Preview

View file

@ -0,0 +1,196 @@
package com.tangem.features.managetokens.ui
import android.content.res.Configuration
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.tangem.core.ui.components.block.information.InformationBlock
import com.tangem.core.ui.components.fields.SimpleTextField
import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.managetokens.component.preview.PreviewCustomTokenFormComponent
import com.tangem.features.managetokens.entity.ClickableFieldUM
import com.tangem.features.managetokens.entity.CustomTokenFormUM
import com.tangem.features.managetokens.entity.TextInputFieldUM
internal fun LazyListScope.customTokenFormContent(model: CustomTokenFormUM) {
item {
ClickableField(
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
model = model.networkName,
)
}
item {
Column(
modifier = Modifier
.padding(bottom = TangemTheme.dimens.spacing12)
.background(
color = TangemTheme.colors.background.action,
shape = TangemTheme.shapes.roundedCornersXMedium,
),
) {
TextField(
model = model.contractAddress,
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Next,
),
)
TextField(
model = model.tokenName,
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Next,
),
)
TextField(
model = model.tokenSymbol,
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Next,
),
)
TextField(
model = model.tokenDecimals,
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Decimal,
imeAction = ImeAction.Next,
),
)
}
}
item {
ClickableField(
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
model = model.derivationPath,
)
}
items(
items = model.notifications,
key = { it.id },
) { notification ->
Notification(
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
config = notification.config,
containerColor = TangemTheme.colors.button.disabled,
)
}
}
@Composable
private fun TextField(
model: TextInputFieldUM,
modifier: Modifier = Modifier,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
) {
InformationBlock(
modifier = modifier,
title = {
val color by animateColorAsState(
targetValue = if (model.error != null) {
TangemTheme.colors.text.warning
} else {
TangemTheme.colors.text.tertiary
},
label = "Field label color",
)
Text(
text = (model.error ?: model.label).resolveReference(),
style = TangemTheme.typography.subtitle2,
color = color,
)
},
content = {
SimpleTextField(
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
value = model.value,
onValueChange = model.onValueChange,
readOnly = false,
placeholder = model.placeholder,
singleLine = true,
keyboardOptions = keyboardOptions,
keyboardActions = keyboardActions,
)
},
)
}
@Composable
private fun ClickableField(model: ClickableFieldUM, modifier: Modifier = Modifier) {
InformationBlock(
modifier = modifier
.clip(TangemTheme.shapes.roundedCornersXMedium)
.clickable(onClick = model.onClick),
title = {
Text(
text = model.label.resolveReference(),
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
)
},
content = {
Text(
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
text = model.value.resolveReference(),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.primary1,
)
},
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun Preview_CustomTokenFormContent(
@PreviewParameter(PreviewCustomTokenFormComponentProvider::class)
component: PreviewCustomTokenFormComponent,
) {
TangemThemePreview {
LazyColumn(
modifier = Modifier.background(color = TangemTheme.colors.background.secondary),
) { component.content(scope = this) }
}
}
private class PreviewCustomTokenFormComponentProvider :
PreviewParameterProvider<PreviewCustomTokenFormComponent> {
override val values: Sequence<PreviewCustomTokenFormComponent>
get() = sequenceOf(
PreviewCustomTokenFormComponent(),
PreviewCustomTokenFormComponent(
contractAddress = TextInputFieldUM(
label = stringReference("Contract address"),
value = "0x1234567890",
error = stringReference("Contract address is invalid"),
placeholder = stringReference("0x1234567890"),
onValueChange = {},
),
),
)
}
// endregion Preview

View file

@ -0,0 +1,125 @@
package com.tangem.features.managetokens.ui
import android.content.res.Configuration
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.components.rows.ChainRow
import com.tangem.core.ui.components.rows.model.ChainRowUM
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.managetokens.component.preview.PreviewCustomTokenNetworkSelectorComponent
import com.tangem.features.managetokens.entity.CurrencyNetworkUM
import com.tangem.features.managetokens.entity.CustomTokenNetworkSelectorUM
import com.tangem.features.managetokens.impl.R
internal fun LazyListScope.customTokenNetworkSelectorContent(model: CustomTokenNetworkSelectorUM) {
val lastIndex = model.networks.lastIndex
item {
Box(
modifier = Modifier
.fillMaxWidth()
.heightIn(min = TangemTheme.dimens.size36)
.background(
color = TangemTheme.colors.background.primary,
shape = TangemTheme.shapes.bottomSheet,
),
) {
Text(
modifier = Modifier
.padding(
top = TangemTheme.dimens.spacing12,
bottom = TangemTheme.dimens.spacing6,
)
.padding(horizontal = TangemTheme.dimens.spacing12),
text = "Choose network",
style = TangemTheme.typography.subtitle2,
color = TangemTheme.colors.text.tertiary,
)
}
}
itemsIndexed(
items = model.networks,
key = { _, item -> item.id.value },
) { index, item ->
NetworkItem(
modifier = Modifier
.fillMaxWidth()
.clip(
shape = if (index == lastIndex) {
RoundedCornerShape(
bottomStart = TangemTheme.dimens.radius16,
bottomEnd = TangemTheme.dimens.radius16,
)
} else {
RectangleShape
},
)
.background(color = TangemTheme.colors.background.primary)
.clickable(onClick = { item.onSelectedStateChange(true) })
.padding(horizontal = TangemTheme.dimens.spacing4),
model = item,
)
}
}
@Composable
private fun NetworkItem(model: CurrencyNetworkUM, modifier: Modifier = Modifier) {
ChainRow(
modifier = modifier,
model = with(model) {
ChainRowUM(
name = name,
type = type,
icon = CurrencyIconState.CoinIcon(
url = null,
fallbackResId = model.iconResId,
isGrayscale = false,
showCustomBadge = false,
),
showCustom = false,
)
},
action = {
AnimatedVisibility(
modifier = Modifier.size(TangemTheme.dimens.size24),
visible = model.isSelected,
) {
Icon(
painter = painterResource(id = R.drawable.ic_check_24),
tint = TangemTheme.colors.icon.accent,
contentDescription = null,
)
}
},
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun Preview_CustomTokenNetworkSelectorContent() {
TangemThemePreview {
LazyColumn {
PreviewCustomTokenNetworkSelectorComponent().content(this)
}
}
}
// endregion Preview