Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-10 16:15:18 +04:00
parent 11511d36dd
commit 28b4c29bef
27 changed files with 278 additions and 84 deletions

View file

@ -1,5 +1,6 @@
package com.tangem.features.account.archived
import com.tangem.common.ui.account.toUM
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
@ -50,7 +51,7 @@ internal class ArchivedAccountListModel @Inject constructor(
title = resourceReference(R.string.account_archived_recover_dialog_title),
message = resourceReference(
id = R.string.account_archived_recover_dialog_description,
formatArgs = wrappedList(account.accountName.value),
formatArgs = wrappedList(account.accountName.toUM().value),
),
firstActionBuilder = { firstAction },
secondActionBuilder = { secondAction },

View file

@ -1,6 +1,8 @@
package com.tangem.features.account.createedit
import com.tangem.common.ui.account.AccountNameUM
import com.tangem.common.ui.account.toDomain
import com.tangem.common.ui.account.toUM
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
import com.tangem.core.decompose.di.ModelScoped
@ -16,7 +18,6 @@ import com.tangem.core.ui.utils.showErrorDialog
import com.tangem.domain.account.usecase.AddCryptoPortfolioUseCase
import com.tangem.domain.account.usecase.GetUnoccupiedAccountIndexUseCase
import com.tangem.domain.account.usecase.UpdateCryptoPortfolioUseCase
import com.tangem.domain.models.account.AccountName
import com.tangem.domain.models.account.CryptoPortfolioIcon
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.wallet.UserWalletId
@ -92,7 +93,7 @@ internal class AccountCreateEditModel @Inject constructor(
private suspend fun createNewCryptoPortfolio(params: AccountCreateEditComponent.Params.Create) {
val state = uiState.value
val name = AccountName(value = state.account.name).getOrNull() ?: return
val name = state.account.name.toDomain().getOrNull() ?: return
val icon = state.account.portfolioIcon.toDomain()
val index = state.account.derivationInfo.index ?: return
val derivationIndex = DerivationIndex(value = index).getOrNull() ?: return
@ -107,7 +108,7 @@ internal class AccountCreateEditModel @Inject constructor(
private suspend fun editCryptoPortfolio(params: AccountCreateEditComponent.Params.Edit) {
val state = uiState.value
val name = AccountName(state.account.name).getOrNull() ?: return
val name = state.account.name.toDomain().getOrNull() ?: return
val icon = state.account.portfolioIcon.toDomain()
val isNewName = name != params.account.accountName
val isNewIcon = icon != params.account.portfolioIcon
@ -132,18 +133,20 @@ internal class AccountCreateEditModel @Inject constructor(
.validateNewState()
}
private fun onNameChange(name: String) {
private fun onNameChange(name: AccountNameUM) {
uiState.value = uiState.value
.updateName(name)
.validateNewState()
}
private fun AccountCreateEditUM.validateNewState(): AccountCreateEditUM {
val isValidName = AccountName(this.account.name).isRight()
val isValidName = this.account.name.toDomain().isRight()
val isAvailableForConfirm = when (params) {
is AccountCreateEditComponent.Params.Create -> isValidName
is AccountCreateEditComponent.Params.Edit -> {
val isNewName = this.account.name != params.account.accountName.value
val oldName = params.account.accountName.toUM()
val isNewName = this.account.name != oldName
val isNewIcon = this.account.portfolioIcon != params.account.portfolioIcon
isValidName && (isNewName || isNewIcon)
}

View file

@ -1,5 +1,6 @@
package com.tangem.features.account.createedit.entity
import com.tangem.common.ui.account.AccountNameUM
import com.tangem.common.ui.account.CryptoPortfolioIconUM
import com.tangem.core.ui.extensions.TextReference
import com.tangem.domain.models.account.CryptoPortfolioIcon
@ -15,11 +16,11 @@ internal data class AccountCreateEditUM(
) {
data class Account(
val name: String,
val name: AccountNameUM,
val portfolioIcon: CryptoPortfolioIconUM,
val derivationInfo: DerivationInfo,
val inputPlaceholder: TextReference,
val onNameChange: (String) -> Unit,
val onNameChange: (AccountNameUM) -> Unit,
)
sealed interface DerivationInfo {

View file

@ -1,5 +1,6 @@
package com.tangem.features.account.createedit.entity
import com.tangem.common.ui.account.AccountNameUM
import com.tangem.common.ui.account.toUM
import com.tangem.core.res.R
import com.tangem.core.ui.extensions.TextReference
@ -24,17 +25,17 @@ internal class AccountCreateEditUMBuilder(
is AccountCreateEditComponent.Params.Edit -> resourceReference(R.string.account_form_title_edit)
}
fun initAccountUM(onNameChange: (String) -> Unit): AccountCreateEditUM.Account {
fun initAccountUM(onNameChange: (AccountNameUM) -> Unit): AccountCreateEditUM.Account {
return when (params) {
is AccountCreateEditComponent.Params.Create -> AccountCreateEditUM.Account(
name = "",
name = AccountNameUM.Custom(raw = ""),
portfolioIcon = createIcon,
derivationInfo = AccountCreateEditUM.DerivationInfo.Empty,
inputPlaceholder = resourceReference(R.string.account_form_placeholder_new_account),
onNameChange = onNameChange,
)
is AccountCreateEditComponent.Params.Edit -> AccountCreateEditUM.Account(
name = params.account.accountName.value,
name = params.account.accountName.toUM(),
portfolioIcon = params.account.portfolioIcon.toUM(),
derivationInfo = createAccountDerivationInfo(
index = (params.account as Account.CryptoPortfolio).derivationIndex.value,
@ -108,7 +109,7 @@ internal class AccountCreateEditUMBuilder(
)
}
fun AccountCreateEditUM.updateName(name: String): AccountCreateEditUM {
fun AccountCreateEditUM.updateName(name: AccountNameUM): AccountCreateEditUM {
return this.copy(account = this.account.copy(name = name))
}

View file

@ -13,6 +13,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -24,11 +25,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.tangem.common.ui.R
import com.tangem.common.ui.account.AccountIcon
import com.tangem.common.ui.account.AccountIconPreviewData
import com.tangem.common.ui.account.AccountIconSize
import com.tangem.common.ui.account.getResId
import com.tangem.common.ui.account.getUiColor
import com.tangem.common.ui.account.*
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.SpacerH
import com.tangem.core.ui.components.SpacerH24
@ -43,7 +40,6 @@ import com.tangem.features.account.createedit.entity.AccountCreateEditUM
import com.tangem.features.account.createedit.entity.AccountCreateEditUM.Account
import kotlinx.collections.immutable.toImmutableList
@Suppress("LongMethod", "MagicNumber")
@Composable
internal fun AccountCreateEditContent(state: AccountCreateEditUM, modifier: Modifier = Modifier) {
Column(
@ -65,7 +61,6 @@ internal fun AccountCreateEditContent(state: AccountCreateEditUM, modifier: Modi
modifier = Modifier
.padding(horizontal = 16.dp)
.weight(1f),
) {
AccountSummary(state.account)
SpacerH24()
@ -103,7 +98,7 @@ private fun AccountSummary(account: Account) {
Spacer(modifier = Modifier.height(24.dp))
AccountIcon(
name = stringReference(account.name),
name = account.name.value,
icon = account.portfolioIcon,
size = AccountIconSize.Large,
)
@ -116,13 +111,27 @@ private fun AccountSummary(account: Account) {
)
Spacer(modifier = Modifier.height(2.dp))
val wasDefault = remember { account.name is AccountNameUM.DefaultMain }
val defaultAccountName = AccountNameUM.DefaultMain.value.resolveReference()
AutoSizeTextField(
centered = true,
textStyle = TangemTheme.typography.head,
placeholder = account.inputPlaceholder,
value = account.name,
value = account.name.value.resolveReference(),
singleLine = true,
onValueChange = account.onNameChange,
onValueChange = {
/*
* If the user had the default main account name and enters the same name during renaming,
* we should use the default value instead of custom to avoid breaking the name validation process.
*/
val newName = if (wasDefault && it == defaultAccountName) {
AccountNameUM.DefaultMain
} else {
AccountNameUM.Custom(raw = it)
}
account.onNameChange(newName)
},
)
SpacerH(20.dp)
}
@ -279,7 +288,7 @@ private class PreviewStateProvider : CollectionPreviewParameterProvider<AccountC
title = stringReference("Add account"),
onCloseClick = {},
account = Account(
name = "",
name = AccountNameUM.DefaultMain,
portfolioIcon = portfolioIcon,
inputPlaceholder = resourceReference(R.string.account_form_placeholder_new_account),
onNameChange = {},
@ -313,7 +322,7 @@ private class PreviewStateProvider : CollectionPreviewParameterProvider<AccountC
onCloseClick = {},
account = Account(
portfolioIcon = portfolioIcon,
name = accountName,
name = AccountNameUM.Custom(raw = accountName),
inputPlaceholder = resourceReference(R.string.account_form_placeholder_edit_account),
onNameChange = {},
derivationInfo = AccountCreateEditUM.DerivationInfo.Content(

View file

@ -74,7 +74,7 @@ internal class AccountDetailsModel @Inject constructor(
private fun getInitialState(): AccountDetailsUM {
return AccountDetailsUM(
accountName = params.account.accountName.value,
accountName = params.account.accountName.toUM().value,
accountIcon = params.account.portfolioIcon.toUM(),
onCloseClick = { router.pop() },
onAccountEditClick = ::onEditAccountClick,

View file

@ -1,9 +1,10 @@
package com.tangem.features.account.details.entity
import com.tangem.common.ui.account.CryptoPortfolioIconUM
import com.tangem.core.ui.extensions.TextReference
internal data class AccountDetailsUM(
val accountName: String,
val accountName: TextReference,
val accountIcon: CryptoPortfolioIconUM,
val onCloseClick: () -> Unit,
val onAccountEditClick: () -> Unit,

View file

@ -143,7 +143,7 @@ private fun AccountRow(state: AccountDetailsUM) {
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
) {
AccountRow(
title = stringReference(state.accountName),
title = state.accountName,
subtitle = resourceReference(R.string.account_form_name),
icon = state.accountIcon,
modifier = Modifier.weight(1f),
@ -177,7 +177,7 @@ private class PreviewStateProvider : CollectionPreviewParameterProvider<AccountD
onAccountEditClick = {},
onManageTokensClick = {},
onArchiveAccountClick = {},
accountName = accountName,
accountName = stringReference(value = accountName),
accountIcon = portfolioIcon,
)
add(first)

View file

@ -8,7 +8,6 @@ import com.tangem.core.decompose.ui.UiMessageSender
import com.tangem.core.ui.components.block.model.BlockUM
import com.tangem.core.ui.extensions.pluralReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.message.DialogMessage
import com.tangem.core.ui.message.EventMessageAction
@ -59,7 +58,7 @@ internal class AccountItemsDelegate @Inject constructor(
private fun Account.CryptoPortfolio.mapCryptoPortfolio(): WalletSettingsAccountsUM {
return WalletSettingsAccountsUM.Account(
id = accountId.value,
accountName = stringReference(accountName.value),
accountName = accountName.toUM().value,
accountIconUM = icon.toUM(),
tokensInfo = pluralReference(
R.plurals.common_tokens_count,