Updated on 2026-08-14

This commit is contained in:
Tangem 2024-06-24 17:51:56 +04:00
parent 164030dc9c
commit 04761c45e4
13 changed files with 418 additions and 2 deletions

View file

@ -0,0 +1,24 @@
package com.tangem.feature.walletsettings.component.preview
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.input.TextFieldValue
import com.tangem.feature.walletsettings.component.RenameWalletComponent
import com.tangem.feature.walletsettings.entity.RenameWalletUM
import com.tangem.feature.walletsettings.ui.RenameWalletDialog
internal class PreviewRenameWalletComponent : RenameWalletComponent {
private val previewState = RenameWalletUM(
walletNameValue = TextFieldValue(text = "My Wallet"),
isNameCorrect = false,
updateValue = {},
onConfirm = {},
)
override val doOnDismiss: () -> Unit = {}
@Composable
override fun Dialog() {
RenameWalletDialog(model = previewState, onDismiss = {})
}
}

View file

@ -0,0 +1,32 @@
package com.tangem.feature.walletsettings.component.preview
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.tangem.core.decompose.navigation.DummyRouter
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
import com.tangem.feature.walletsettings.entity.WalletSettingsUM
import com.tangem.feature.walletsettings.ui.WalletSettingsScreen
import com.tangem.feature.walletsettings.utils.ItemsBuilder
internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
private val previewState = WalletSettingsUM(
popBack = {},
items = ItemsBuilder(
router = DummyRouter(),
).buildItems(
walletName = "My wallet",
renameWallet = {},
forgetWallet = {},
),
)
@Composable
override fun Content(modifier: Modifier) {
WalletSettingsScreen(
modifier = modifier,
state = previewState,
dialog = {},
)
}
}

View file

@ -0,0 +1,14 @@
package com.tangem.feature.walletsettings.entity
import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.serialization.Serializable
@Serializable
internal sealed interface DialogConfig {
@Serializable
data class RenameWallet(
val userWalletId: UserWalletId,
val currentName: String,
) : DialogConfig
}

View file

@ -0,0 +1,12 @@
package com.tangem.feature.walletsettings.entity
import androidx.compose.runtime.Immutable
import androidx.compose.ui.text.input.TextFieldValue
@Immutable
internal data class RenameWalletUM(
val walletNameValue: TextFieldValue,
val isNameCorrect: Boolean,
val updateValue: (value: TextFieldValue) -> Unit,
val onConfirm: () -> Unit,
)

View file

@ -0,0 +1,25 @@
package com.tangem.feature.walletsettings.entity
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.block.model.BlockUM
import com.tangem.core.ui.extensions.TextReference
import kotlinx.collections.immutable.ImmutableList
@Immutable
internal sealed class WalletSettingsItemUM {
abstract val id: String
data class WithItems(
override val id: String,
val description: TextReference,
val blocks: ImmutableList<BlockUM>,
) : WalletSettingsItemUM()
data class WithText(
override val id: String,
val title: TextReference,
val text: TextReference,
val onClick: () -> Unit,
) : WalletSettingsItemUM()
}

View file

@ -0,0 +1,10 @@
package com.tangem.feature.walletsettings.entity
import androidx.compose.runtime.Immutable
import kotlinx.collections.immutable.PersistentList
@Immutable
internal data class WalletSettingsUM(
val popBack: () -> Unit,
val items: PersistentList<WalletSettingsItemUM>,
)

View file

@ -0,0 +1,53 @@
package com.tangem.feature.walletsettings.ui
import android.content.res.Configuration
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.components.AdditionalTextInputDialogParams
import com.tangem.core.ui.components.DialogButton
import com.tangem.core.ui.components.TextInputDialog
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.feature.walletsettings.component.preview.PreviewRenameWalletComponent
import com.tangem.feature.walletsettings.entity.RenameWalletUM
import com.tangem.feature.walletsettings.impl.R
@Composable
internal fun RenameWalletDialog(model: RenameWalletUM, onDismiss: () -> Unit) {
val value by rememberUpdatedState(newValue = model.walletNameValue)
TextInputDialog(
title = stringResource(id = R.string.user_wallet_list_rename_popup_title),
fieldValue = value,
confirmButton = DialogButton(
title = stringResource(id = R.string.common_ok),
enabled = model.isNameCorrect,
onClick = {
model.onConfirm()
onDismiss()
},
),
dismissButton = DialogButton(
title = stringResource(id = R.string.common_cancel),
onClick = onDismiss,
),
onDismissDialog = onDismiss,
onValueChange = model.updateValue,
textFieldParams = AdditionalTextInputDialogParams(
label = stringResource(id = R.string.user_wallet_list_rename_popup_placeholder),
),
)
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun Preview_RenameWalletDialog() {
TangemThemePreview {
PreviewRenameWalletComponent().Dialog()
}
}
// endregion Preview

View file

@ -0,0 +1,171 @@
package com.tangem.feature.walletsettings.ui
import android.content.res.Configuration
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.components.appbar.models.TopAppBarMedium
import com.tangem.core.ui.components.block.BlockCard
import com.tangem.core.ui.components.block.BlockItem
import com.tangem.core.ui.components.snackbar.TangemSnackbarHost
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.LocalSnackbarHostState
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.feature.walletsettings.component.preview.PreviewWalletSettingsComponent
import com.tangem.feature.walletsettings.entity.WalletSettingsItemUM
import com.tangem.feature.walletsettings.entity.WalletSettingsUM
import com.tangem.feature.walletsettings.impl.R
@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun WalletSettingsScreen(
state: WalletSettingsUM,
dialog: @Composable () -> Unit,
modifier: Modifier = Modifier,
) {
val backgroundColor = TangemTheme.colors.background.secondary
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
BackHandler(onBack = state.popBack)
Scaffold(
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
containerColor = backgroundColor,
snackbarHost = {
TangemSnackbarHost(
modifier = Modifier.padding(all = TangemTheme.dimens.spacing16),
hostState = LocalSnackbarHostState.current,
)
},
topBar = {
TopAppBarMedium(
title = resourceReference(R.string.wallet_settings_title),
scrollBehavior = scrollBehavior,
onBackClick = state.popBack,
)
},
content = { paddingValues ->
Content(
modifier = Modifier.padding(paddingValues),
state = state,
)
dialog()
},
)
}
@Composable
private fun Content(state: WalletSettingsUM, modifier: Modifier = Modifier) {
LazyColumn(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
contentPadding = PaddingValues(
top = TangemTheme.dimens.spacing16,
bottom = TangemTheme.dimens.spacing16,
),
) {
items(
items = state.items,
key = WalletSettingsItemUM::id,
) { item ->
val itemModifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16)
when (item) {
is WalletSettingsItemUM.WithItems -> ItemsBlock(
modifier = itemModifier,
model = item,
)
is WalletSettingsItemUM.WithText -> TextBlock(
modifier = itemModifier,
model = item,
)
}
}
}
}
@Composable
private fun ItemsBlock(model: WalletSettingsItemUM.WithItems, modifier: Modifier = Modifier) {
Column(
modifier = modifier,
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
) {
Column(
modifier = Modifier
.fillMaxWidth()
.background(
shape = TangemTheme.shapes.roundedCornersXMedium,
color = TangemTheme.colors.background.primary,
),
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.Top,
) {
model.blocks.forEach { block ->
BlockItem(model = block)
}
}
Text(
modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing12),
text = model.description.resolveReference(),
color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.caption2,
)
}
}
@Composable
private fun TextBlock(model: WalletSettingsItemUM.WithText, modifier: Modifier = Modifier) {
BlockCard(
modifier = modifier.fillMaxWidth(),
onClick = model.onClick,
) {
Column(
modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
) {
Text(
text = model.title.resolveReference(),
color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.subtitle2,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text(
text = model.text.resolveReference(),
color = TangemTheme.colors.text.primary1,
style = TangemTheme.typography.body1,
overflow = TextOverflow.Ellipsis,
)
}
}
}
// region Preview
@Composable
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun Preview_WalletSettingsScreen() {
TangemThemePreview {
PreviewWalletSettingsComponent().Content(modifier = Modifier.fillMaxSize())
}
}
// endregion Preview

View file

@ -0,0 +1,65 @@
package com.tangem.feature.walletsettings.utils
import com.tangem.common.routing.AppRoute
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.ui.components.block.model.BlockUM
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.feature.walletsettings.entity.WalletSettingsItemUM
import com.tangem.feature.walletsettings.impl.R
import kotlinx.collections.immutable.persistentListOf
import javax.inject.Inject
@ComponentScoped
internal class ItemsBuilder @Inject constructor(
private val router: Router,
) {
fun buildItems(walletName: String, forgetWallet: () -> Unit, renameWallet: () -> Unit) = persistentListOf(
buildNameItem(walletName, renameWallet),
buildCardItem(),
buildForgetItem(forgetWallet),
)
private fun buildNameItem(walletName: String, renameWallet: () -> Unit) = WalletSettingsItemUM.WithText(
id = "wallet_name",
title = resourceReference(id = R.string.settings_wallet_name_title),
text = stringReference(walletName),
onClick = renameWallet,
)
private fun buildCardItem() = WalletSettingsItemUM.WithItems(
id = "card",
blocks = buildCardBlocks(),
description = resourceReference(R.string.settings_card_settings_footer),
)
private fun buildCardBlocks() = persistentListOf(
BlockUM(
text = resourceReference(R.string.card_settings_title),
iconRes = R.drawable.ic_card_settings_24,
onClick = { router.push(AppRoute.CardSettings) },
),
BlockUM(
text = resourceReference(R.string.referral_title),
iconRes = R.drawable.ic_add_friends_24,
onClick = { router.push(AppRoute.ReferralProgram) },
),
)
private fun buildForgetItem(forgetWallet: () -> Unit) = WalletSettingsItemUM.WithItems(
id = "forget",
blocks = buildForgetBlocks(forgetWallet),
description = resourceReference(R.string.settings_forget_wallet_footer),
)
private fun buildForgetBlocks(forgetWallet: () -> Unit) = persistentListOf(
BlockUM(
text = resourceReference(R.string.settings_forget_wallet),
iconRes = R.drawable.ic_card_foget_24,
onClick = forgetWallet,
accentType = BlockUM.AccentType.WARNING,
),
)
}