From 269a6d1d57aceb5b9c4fb34f8425638eeaf6915c Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 9 Oct 2025 12:50:16 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/common/ui/account/AccountLabel.kt | 53 +++++++++++++++++ core/res/src/main/res/values-de/strings.xml | 5 ++ core/res/src/main/res/values-es/strings.xml | 5 ++ core/res/src/main/res/values-fr/strings.xml | 7 ++- core/res/src/main/res/values-ja/strings.xml | 16 ++++++ core/res/src/main/res/values-ru/strings.xml | 1 + .../src/main/res/values-uk-rUA/strings.xml | 1 + core/res/src/main/res/values/strings.xml | 8 +++ .../ui/components/tokenlist/TokenListItem.kt | 4 +- .../tokenlist/state/TokensListItemUM.kt | 7 ++- .../LoadingAccountTokenItemConverter.kt | 2 +- .../SetNoAvailablePairsTransformerV2.kt | 2 +- .../onramp/swap/entity/ExchangeCardUM.kt | 26 +++++++-- .../transformer/SelectFromTokenTransformer.kt | 6 ++ .../transformer/SelectToTokenTransformer.kt | 10 +++- .../swap/entity/utils/ExchangeCardUMExt.kt | 23 +++++++- .../swap/model/SwapSelectTokensModel.kt | 32 ++++++++++- .../features/onramp/swap/ui/ExchangeCard.kt | 57 ++++++++++++++----- .../UpdateAccountTokenItemConverter.kt | 2 +- .../common/preview/WalletScreenPreviewData.kt | 9 +-- .../converter/TokenListStateConverter.kt | 4 +- 21 files changed, 240 insertions(+), 40 deletions(-) create mode 100644 common/ui/src/main/java/com/tangem/common/ui/account/AccountLabel.kt diff --git a/common/ui/src/main/java/com/tangem/common/ui/account/AccountLabel.kt b/common/ui/src/main/java/com/tangem/common/ui/account/AccountLabel.kt new file mode 100644 index 0000000000..51f13b848f --- /dev/null +++ b/common/ui/src/main/java/com/tangem/common/ui/account/AccountLabel.kt @@ -0,0 +1,53 @@ +package com.tangem.common.ui.account + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +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.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.components.account.AccountIconSize +import com.tangem.core.ui.extensions.TextReference +import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.res.TangemTheme + +/** + * Displays account name with icon + * + * @param name account name + * @param icon portfolio account icon model + * @param iconSize portfolio account icon size + * @param nameStyle account name style + * @param nameColor account name color + * @see AccountIcon + */ +@Composable +fun AccountLabel( + name: TextReference, + icon: CryptoPortfolioIconUM, + iconSize: AccountIconSize, + modifier: Modifier = Modifier, + nameStyle: TextStyle = TangemTheme.typography.subtitle2, + nameColor: Color = TangemTheme.colors.text.tertiary, +) { + Row( + modifier = modifier, + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp), + ) { + AccountIcon( + name = name, + icon = icon, + size = iconSize, + ) + Text( + text = name.resolveReference(), + style = nameStyle, + color = nameColor, + maxLines = 1, + ) + } +} \ No newline at end of file diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index 36849c64d9..2817667d7e 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -320,6 +320,7 @@ Tangem Wallet Allgemeine Geschäftsbedingungen Nutzungsbedingungen + An Heute %d Token @@ -1304,8 +1305,12 @@ Verwende %s oder scanne eine Karte oder Ring, um Zugriff auf deine Wallet zu erhalten. Verbindung fehlgeschlagen: Diese dApp verwendet Wallet Connect Version 1.0, die nicht unterstützt wird. Bitte stelle sicher, dass die dApp Wallet Connect Version 2.0 unterstützt, um eine erfolgreiche Verbindung herzustellen. Bleib auf dem Laufenden mit den neuesten Funktionen und Neuigkeiten + Echtzeit-Warnungen für Transaktionen, Umtausch und wichtige Aktualisierungen. + Transaktionswarnungen Genehmigung für Transaktionen anfordern Sei der Erste, der von neuen Aktionen erfährt + Frühzeitiger Zugriff auf neue Funktionen und exklusive Angebote. + Updates zu Funktionen und Neuigkeiten Möchtest du Push-Benachrichtigungen verwenden? Neues Wallet hinzufügen Möchtest Du diese Wallet wirklich entfernen? diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index 36b3355615..af4f17bfca 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -258,6 +258,7 @@ Intercambiar términos y condiciones Condiciones de uso + A Hoy %d token @@ -1204,8 +1205,12 @@ Use %s o escanee una tarjeta/anillo para tener acceso a su billetera Error de conexión: Esta dApp utiliza la versión 1.0 de Wallet Connect, que no es compatible. Asegúrese de que la dApp sea compatible con la versión 2.0 de Wallet Connect para conectarse correctamente. Manténgase actualizado con las últimas funciones y noticias + Alertas en tiempo real de transacciones, intercambios y actualizaciones críticas. + Alertas de transacciones Recibir notificaciones de las transacciones entrantes Sea el primero en enterarte de nuevas promociones + Acceso anticipado a nuevas funciones y ofertas exclusivas. + Actualizaciones de características y noticias ¿Quiere utilizar\nnotificaciones push? Agregar una nueva billetera ¿Estás seguro de que deseas olvidar esta billetera? diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index 47bac750bc..503724daf0 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -235,6 +235,7 @@ Échanger termes et conditions Conditions d\'utilisation + À Aujourd\'hui %d jeton @@ -1106,7 +1107,7 @@ Échanger ce montant de jetons sélectionnés aura un impact significatif sur les prix et réduira votre résultat. Fonds insuffisants Donner l\'autorisation - Échangez + Échanger Vous recevez Choisir le jeton non disponible @@ -1177,8 +1178,12 @@ Utilisez %s ou scannez une carte/bague pour avoir accès à votre portefeuille Échec de la connexion : Cette dApp utilise Wallet Connect version1.0, qui n\'est pas prise en charge. Veuillez vous assurer que la dApp prend en charge Wallet Connect version2.0 pour réussir la connexion. Restez à jour avec les dernières fonctionnalités et actualités + Alertes en temps réel pour les transactions, les échanges et les mises à jour importantes. + Alertes de transaction Recevez des notifications des transactions entrantes Soyez le premier informé des nouvelles promotions + Accès anticipé à de nouvelles fonctionnalités et à des offres exclusives. + Actualités et mises à jour Souhaitez-vous utiliser les\nnotifications push? Ajouter un nouveau portefeuille Êtes-vous sûr de vouloir supprimer ce portefeuille ? diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 48e34783ae..d76ede5115 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -33,6 +33,7 @@ アカウントを追加 保存 アカウント名 + アカウント名はすでに存在しています アカウント 新しいアカウント アカウントを追加 @@ -323,6 +324,7 @@ Tangem 利用規約 利用規約 + 宛先 今日 %d トークン @@ -885,6 +887,7 @@ %s分 以下が手に入ります。 + サービスは外部プロバイダーによって提供されます。 \nTangemは責任を負いません。 この画面を閉じて、トークンの詳細画面で取引状況を確認できます。 最大 経由 @@ -1094,6 +1097,7 @@ ステーキングアカウントとは、ステーキングされたSOLが保管される特別なアカウントです。トークンをバリデーターに委任し、取引の検証に参加して報酬を受け取る際に作成されます。ステーキングアカウントの作成には少額の手数料がかかりますが、ステーキング完了後に返金されます。 年率 ステーキングに参加することで得られる年間収益率。 + APYは、バリデータのパフォーマンスに基づいた年間利回りを示します。 APR APY 報酬は毎日自動的にステーキング残高に蓄積されます。 @@ -1254,6 +1258,10 @@ 受け取る トークンを選択 利用不可 + データの読み込みに失敗しました。しばらくしてからもう一度お試しください。 + 非表示 + 表示 + カードの詳細 アカウントを作成してカードを発行 Tangem Pay ステータスを表示 @@ -1266,6 +1274,7 @@ カードの詳細は保護されており、アプリ内で完全に制御できます。 内蔵セキュリティ 無料のCryptoカード\nを数分で入手しましょう + Tangem Pay これは私のウォレットです 残高非表示 残高表示 @@ -1293,6 +1302,7 @@ %%image%% %1$sネットワーク上のトークン %1$s ( %2$s ) トークンは%3$sネットワークの主要通貨であり、このネットワーク上の他のトークンがリストにある限り、非表示にすることはできません。 %sを非表示にできません + QRコードを表示 このトークンは、2月%2$s-%3$s の間、%1$s のサービス手数料で別のトークンと交換できます。 Changellyでスワップ、手数料%s 今すぐスワップ @@ -1661,6 +1671,7 @@ 承認を確定する 資産残高に関するテキスト [プレースホルダー] あなたの%sはAaveに預けられています + チャートを読み込めません・・ 受け取った金額%1$s %2$sはAaveに入金されませんでした。 %1$s%% を獲得 利用可能 @@ -1678,6 +1689,7 @@ 最大手数料 手数料ポリシー ネットワーク手数料が現在高すぎます。設定した上限を下回るまで待機しています。 + 過去のリターン ここに説明を入力してください。1〜3行が理想的です。[プレースホルダー] トークン承認が必要 ネットワーク接続を確認してください @@ -1708,6 +1720,7 @@ 収益を停止する オフにすると、Aaveから資金が引き出され、ウォレットの%sに戻され、報酬の獲得が停止されます。 出金金額からネットワーク手数料が差し引かれます。 + 供給APR APY あなたの資産を眠らせない — 残高を運用して利息を得ましょう。 保有資産から報酬を得る @@ -1716,4 +1729,7 @@ 自動 取引のネットワーク手数料をカバーするために、 %1$s %2$sを入金してください %s手数料を支払えません + 利息サービスは現在利用できません。しばらくしてから再度お試しください。 + 収益は利用できません + チャートを読み込めません・・ diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 88c15e79d0..d3729cd4c9 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -250,6 +250,7 @@ Обменять условия участия Условиями использования + На Сегодня %d токен diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml index 6946a0d572..e832ab378e 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -233,6 +233,7 @@ Обмін умови участі Умовами використання + До Сьогодні %d токен diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index db57bd8a71..9987d7f342 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -179,6 +179,7 @@ Accept Access denied Accounts + Activate Add Add to portfolio Add token @@ -253,6 +254,7 @@ Speed and fee Finish Free + From Synchronize addresses Get started Go to provider @@ -331,6 +333,7 @@ Tangem Wallet terms and conditions Terms of Use + To Today %d token @@ -1112,6 +1115,9 @@ This will remove the wallet from the application. The wallet itself can be added again. Name Put your token to work + A network fee is a small payment to process and confirm your transaction on the blockchain. + To start staking, your TON account must be activated with a self-transaction of 1 TON. The funds stay in your wallet — this step only enables your account for staking. + Account activation The amount to stake must be at least %s Staking amount will be rounded to %1$s TRX due to network rules. Unstaking amount will be rounded to %1$s TRX due to network rules. @@ -1178,6 +1184,8 @@ Reinvests your earned rewards in your staked amount, increasing potential earnings. Restake lets you move your funds from one validator to another without the need to unstake You’re about to stake your entire balance. We recommend leaving a small amount to cover network fees for unstaking or claiming rewards. + To start staking, your TON account must be activated with a self-transaction of 1 TON. The funds stay in your wallet — this step only enables your account for staking. + Account activation To start staking in TON, first send a small transaction to your own address — this will activate your wallet. Up to 0.2 TON may be required in addition to the network fee to complete the transaction. Any unused amount will be refunded. 0.2 TON is required to proceed with this operation, in addition to the network fee. Please top up your balance. diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/TokenListItem.kt b/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/TokenListItem.kt index 989637b8eb..fa775ca36c 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/TokenListItem.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/TokenListItem.kt @@ -60,10 +60,10 @@ fun TokenListItem(state: TokensListItemUM, isBalanceHidden: Boolean, modifier: M @Composable fun PortfolioListItem(state: TokensListItemUM.Portfolio, isBalanceHidden: Boolean, modifier: Modifier = Modifier) { if (state.isExpanded) { - ExpandedPortfolioHeader(state = state.state, isCollapsable = state.isCollapsable, modifier = modifier) + ExpandedPortfolioHeader(state = state.tokenItemUM, isCollapsable = state.isCollapsable, modifier = modifier) } else { TokenItem( - state = state.state, + state = state.tokenItemUM, isBalanceHidden = isBalanceHidden, modifier = modifier, ) diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/state/TokensListItemUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/state/TokensListItemUM.kt index 23b2ef9da6..7797159dc1 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/state/TokensListItemUM.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/tokenlist/state/TokensListItemUM.kt @@ -4,6 +4,7 @@ import androidx.compose.runtime.Immutable import com.tangem.core.ui.components.fields.entity.SearchBarUM import com.tangem.core.ui.components.token.state.TokenItemState import com.tangem.core.ui.extensions.TextReference +import kotlinx.collections.immutable.ImmutableList /** Tokens list item state */ @Immutable @@ -41,12 +42,12 @@ sealed interface TokensListItemUM { } data class Portfolio( - val state: TokenItemState, + val tokenItemUM: TokenItemState, val isExpanded: Boolean, val isCollapsable: Boolean, - val tokens: List, + val tokens: ImmutableList, ) : TokensListItemUM { - override val id: String = state.id + override val id: String = tokenItemUM.id } data class Text(override val id: Any, val text: TextReference) : TokensListItemUM diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/entity/converters/LoadingAccountTokenItemConverter.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/entity/converters/LoadingAccountTokenItemConverter.kt index 8d9c2042a9..9489858928 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/entity/converters/LoadingAccountTokenItemConverter.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/entity/converters/LoadingAccountTokenItemConverter.kt @@ -16,7 +16,7 @@ internal class LoadingAccountTokenItemConverter( val (account, currencies) = value return TokensListItemUM.Portfolio( - state = AccountCryptoPortfolioItemStateConverter( + tokenItemUM = AccountCryptoPortfolioItemStateConverter( appCurrency = appCurrency, account = account, onItemClick = null, diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/entity/transformers/SetNoAvailablePairsTransformerV2.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/entity/transformers/SetNoAvailablePairsTransformerV2.kt index 669604724c..9ee61d4ba9 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/entity/transformers/SetNoAvailablePairsTransformerV2.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/availablepairs/entity/transformers/SetNoAvailablePairsTransformerV2.kt @@ -33,7 +33,7 @@ internal class SetNoAvailablePairsTransformerV2( TokenListUMData.AccountList( tokensList = accountList.map { (account, cryptoCurrencies) -> TokensListItemUM.Portfolio( - state = AccountCryptoPortfolioItemStateConverter( + tokenItemUM = AccountCryptoPortfolioItemStateConverter( appCurrency = appCurrency, account = account, onItemClick = null, diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/ExchangeCardUM.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/ExchangeCardUM.kt index 817e7218ba..0b159c1423 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/ExchangeCardUM.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/ExchangeCardUM.kt @@ -1,5 +1,7 @@ package com.tangem.features.onramp.swap.entity +import androidx.compose.runtime.Immutable +import com.tangem.common.ui.account.CryptoPortfolioIconUM import com.tangem.core.ui.components.token.state.TokenItemState import com.tangem.core.ui.extensions.TextReference @@ -11,7 +13,7 @@ import com.tangem.core.ui.extensions.TextReference internal sealed interface ExchangeCardUM { /** Title reference */ - val titleReference: TextReference + val titleUM: TitleUM /** Remove button UI model */ val removeButtonUM: RemoveButtonUM? @@ -19,11 +21,11 @@ internal sealed interface ExchangeCardUM { /** * Empty state * - * @property titleReference title reference + * @property titleUM title reference * @property subtitleReference empty token subtitle reference */ data class Empty( - override val titleReference: TextReference, + override val titleUM: TitleUM, val subtitleReference: TextReference, ) : ExchangeCardUM { @@ -33,15 +35,29 @@ internal sealed interface ExchangeCardUM { /** * Filled * - * @property titleReference title reference + * @property titleUM title reference * @property removeButtonUM remove button UI model * @property tokenItemState token item state */ data class Filled( - override val titleReference: TextReference, + override val titleUM: TitleUM, override val removeButtonUM: RemoveButtonUM?, val tokenItemState: TokenItemState, ) : ExchangeCardUM data class RemoveButtonUM(val onClick: () -> Unit) + + @Immutable + sealed interface TitleUM { + + data class Text( + val title: TextReference, + ) : TitleUM + + data class Account( + val prefixText: TextReference, + val name: TextReference, + val icon: CryptoPortfolioIconUM, + ) : TitleUM + } } \ No newline at end of file diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/SelectFromTokenTransformer.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/SelectFromTokenTransformer.kt index 08c088f59e..036c81e855 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/SelectFromTokenTransformer.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/SelectFromTokenTransformer.kt @@ -1,6 +1,7 @@ package com.tangem.features.onramp.swap.entity.transformer import com.tangem.core.ui.components.token.state.TokenItemState +import com.tangem.domain.models.account.Account import com.tangem.features.onramp.swap.entity.ExchangeCardUM import com.tangem.features.onramp.swap.entity.SwapSelectTokensUM import com.tangem.features.onramp.swap.entity.SwapSelectTokensUMTransformer @@ -17,6 +18,8 @@ import com.tangem.features.onramp.swap.entity.utils.toFilled internal class SelectFromTokenTransformer( private val selectedTokenItemState: TokenItemState, private val onRemoveClick: () -> Unit, + private val account: Account.CryptoPortfolio, + private val isAccountsMode: Boolean, ) : SwapSelectTokensUMTransformer { override fun transform(prevState: SwapSelectTokensUM): SwapSelectTokensUM { @@ -24,6 +27,9 @@ internal class SelectFromTokenTransformer( exchangeFrom = prevState.exchangeFrom.toFilled( selectedTokenItemState = selectedTokenItemState, removeButtonUM = ExchangeCardUM.RemoveButtonUM(onClick = onRemoveClick), + account = account, + isAccountsMode = isAccountsMode, + isFromCurrency = true, ), ) } diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/SelectToTokenTransformer.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/SelectToTokenTransformer.kt index 433b28f5ff..f8798e8f75 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/SelectToTokenTransformer.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/transformer/SelectToTokenTransformer.kt @@ -1,6 +1,7 @@ package com.tangem.features.onramp.swap.entity.transformer import com.tangem.core.ui.components.token.state.TokenItemState +import com.tangem.domain.models.account.Account import com.tangem.features.onramp.swap.entity.ExchangeCardUM import com.tangem.features.onramp.swap.entity.SwapSelectTokensUM import com.tangem.features.onramp.swap.entity.SwapSelectTokensUMTransformer @@ -15,12 +16,19 @@ import com.tangem.features.onramp.swap.entity.utils.toFilled */ internal class SelectToTokenTransformer( private val selectedTokenItemState: TokenItemState, + private val isAccountsMode: Boolean, + private val account: Account.CryptoPortfolio, ) : SwapSelectTokensUMTransformer { override fun transform(prevState: SwapSelectTokensUM): SwapSelectTokensUM { return prevState.copy( exchangeFrom = prevState.exchangeFrom.hideRemoveButton(), - exchangeTo = prevState.exchangeTo.toFilled(selectedTokenItemState = selectedTokenItemState), + exchangeTo = prevState.exchangeTo.toFilled( + selectedTokenItemState = selectedTokenItemState, + isAccountsMode = isAccountsMode, + account = account, + isFromCurrency = false, + ), ) } diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/utils/ExchangeCardUMExt.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/utils/ExchangeCardUMExt.kt index 6daf403437..04615a8b92 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/utils/ExchangeCardUMExt.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/entity/utils/ExchangeCardUMExt.kt @@ -1,14 +1,16 @@ package com.tangem.features.onramp.swap.entity.utils +import com.tangem.common.ui.account.toUM import com.tangem.core.ui.components.token.state.TokenItemState import com.tangem.core.ui.extensions.resourceReference +import com.tangem.domain.models.account.Account import com.tangem.features.onramp.impl.R import com.tangem.features.onramp.swap.entity.ExchangeCardUM /** Create empty exchange "from" card */ internal fun createEmptyExchangeFrom(): ExchangeCardUM.Empty { return ExchangeCardUM.Empty( - titleReference = resourceReference(id = R.string.swapping_from_title), + titleUM = ExchangeCardUM.TitleUM.Text(resourceReference(id = R.string.swapping_from_title)), subtitleReference = resourceReference(id = R.string.action_buttons_you_want_to_swap), ) } @@ -16,7 +18,7 @@ internal fun createEmptyExchangeFrom(): ExchangeCardUM.Empty { /** Create empty exchange "to" card */ internal fun createEmptyExchangeTo(): ExchangeCardUM.Empty { return ExchangeCardUM.Empty( - titleReference = resourceReference(id = R.string.swapping_to_title), + titleUM = ExchangeCardUM.TitleUM.Text(resourceReference(id = R.string.swapping_to_title)), subtitleReference = resourceReference(id = R.string.action_buttons_you_want_to_receive), ) } @@ -29,10 +31,25 @@ internal fun createEmptyExchangeTo(): ExchangeCardUM.Empty { */ internal fun ExchangeCardUM.toFilled( selectedTokenItemState: TokenItemState, + account: Account.CryptoPortfolio, + isAccountsMode: Boolean, + isFromCurrency: Boolean, removeButtonUM: ExchangeCardUM.RemoveButtonUM? = null, ): ExchangeCardUM.Filled { return ExchangeCardUM.Filled( - titleReference = titleReference, + titleUM = if (isAccountsMode) { + ExchangeCardUM.TitleUM.Account( + prefixText = if (isFromCurrency) { + resourceReference(R.string.common_from) + } else { + resourceReference(R.string.common_to) + }, + name = account.accountName.toUM().value, + icon = account.icon.toUM(), + ) + } else { + titleUM + }, tokenItemState = selectedTokenItemState, removeButtonUM = removeButtonUM, ) diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/model/SwapSelectTokensModel.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/model/SwapSelectTokensModel.kt index 5472e0e61c..e0e2d8e657 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/model/SwapSelectTokensModel.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/model/SwapSelectTokensModel.kt @@ -8,7 +8,9 @@ import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.decompose.navigation.Router import com.tangem.core.ui.components.token.state.TokenItemState +import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase +import com.tangem.domain.models.account.Account import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.features.onramp.component.SwapSelectTokensComponent import com.tangem.features.onramp.swap.entity.SwapSelectTokensController @@ -32,6 +34,7 @@ internal class SwapSelectTokensModel @Inject constructor( private val router: Router, private val analyticsEventHandler: AnalyticsEventHandler, private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase, + private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase, ) : Model() { val state: StateFlow = controller.state @@ -43,9 +46,12 @@ internal class SwapSelectTokensModel @Inject constructor( private val params = paramsContainer.require() + private var isAccountsMode: Boolean = false + init { controller.update { it.copy(onBackClick = ::onBackClick) } + subscribeOnAccountsMode() subscribeOnBalanceHidingSettings() } @@ -66,6 +72,11 @@ internal class SwapSelectTokensModel @Inject constructor( transformer = SelectFromTokenTransformer( selectedTokenItemState = selectedTokenItemState, onRemoveClick = ::onRemoveFromTokenClick, + isAccountsMode = isAccountsMode, + account = Account.CryptoPortfolio.createMainAccount( + userWalletId = params.userWalletId, + cryptoCurrencies = setOf(status.currency), + ), // todo account from from cryptocurrency ), ) } @@ -84,7 +95,16 @@ internal class SwapSelectTokensModel @Inject constructor( modelScope.launch { _toCurrencyStatus.value = status - controller.update(transformer = SelectToTokenTransformer(selectedTokenItemState)) + controller.update( + transformer = SelectToTokenTransformer( + selectedTokenItemState = selectedTokenItemState, + isAccountsMode = isAccountsMode, + account = Account.CryptoPortfolio.createMainAccount( + userWalletId = params.userWalletId, + cryptoCurrencies = setOf(status.currency), + ), // todo account from from cryptocurrency + ), + ) // require some delay to show state with selected "from" and "to" tokens delay(timeMillis = 500) @@ -119,6 +139,16 @@ internal class SwapSelectTokensModel @Inject constructor( .launchIn(modelScope) } + private fun subscribeOnAccountsMode() { + isAccountsModeEnabledUseCase() + .distinctUntilChanged() + .onEach { + isAccountsMode = it + } + .flowOn(dispatchers.default) + .launchIn(modelScope) + } + private fun onBackClick() { analyticsEventHandler.send( event = MainScreenAnalyticsEvent.ButtonClose(source = AnalyticsParam.ScreensSources.Swap), diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/ExchangeCard.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/ExchangeCard.kt index da3b5ead84..4ee9b3eb0e 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/ExchangeCard.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/swap/ui/ExchangeCard.kt @@ -14,11 +14,14 @@ 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 import androidx.compose.ui.text.style.TextOverflow 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.common.ui.account.AccountLabel +import com.tangem.core.ui.components.account.AccountIconSize import com.tangem.core.ui.components.currency.icon.CurrencyIconState import com.tangem.core.ui.components.marketprice.PriceChangeType import com.tangem.core.ui.components.rows.NetworkTitle @@ -46,13 +49,14 @@ internal fun ExchangeCard(state: ExchangeCardUM, isBalanceHidden: Boolean, modif modifier = modifier .fillMaxWidth() .heightIn(min = 116.dp) - .background( - color = TangemTheme.colors.background.primary, - shape = TangemTheme.shapes.roundedCornersXMedium, - ), + .clip(TangemTheme.shapes.roundedCornersXMedium) + .background(TangemTheme.colors.background.primary), verticalArrangement = Arrangement.SpaceBetween, ) { - Title(titleReference = state.titleReference, removeButtonUM = state.removeButtonUM) + Title( + titleUM = state.titleUM, + removeButtonUM = state.removeButtonUM, + ) AnimatedContent( targetState = state, @@ -73,16 +77,39 @@ internal fun ExchangeCard(state: ExchangeCardUM, isBalanceHidden: Boolean, modif } @Composable -private fun Title(titleReference: TextReference, removeButtonUM: ExchangeCardUM.RemoveButtonUM?) { +private fun Title(titleUM: ExchangeCardUM.TitleUM, removeButtonUM: ExchangeCardUM.RemoveButtonUM?) { NetworkTitle( title = { - Text( - text = titleReference.resolveReference(), - color = TangemTheme.colors.text.tertiary, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - style = TangemTheme.typography.subtitle2, - ) + AnimatedContent( + titleUM, + ) { currentState -> + when (currentState) { + is ExchangeCardUM.TitleUM.Account -> Row( + horizontalArrangement = Arrangement.spacedBy(6.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = currentState.prefixText.resolveReference(), + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.tertiary, + ) + AccountLabel( + name = currentState.name, + icon = currentState.icon, + iconSize = AccountIconSize.ExtraSmall, + nameStyle = TangemTheme.typography.subtitle2, + nameColor = TangemTheme.colors.text.tertiary, + ) + } + is ExchangeCardUM.TitleUM.Text -> Text( + text = currentState.title.resolveReference(), + color = TangemTheme.colors.text.tertiary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + style = TangemTheme.typography.subtitle2, + ) + } + } }, action = { RemoveButton(state = removeButtonUM) }, ) @@ -153,7 +180,7 @@ private class ExchangeCardUMProvider : PreviewParameterProvider override val values: Sequence = sequenceOf( ExchangeCardUM.Empty( - titleReference = resourceReference(id = R.string.swapping_from_title), + titleUM = ExchangeCardUM.TitleUM.Text(resourceReference(id = R.string.swapping_from_title)), subtitleReference = resourceReference(id = R.string.action_buttons_you_want_to_swap), ), createFilled(removeButtonUM = null), @@ -162,7 +189,7 @@ private class ExchangeCardUMProvider : PreviewParameterProvider private fun createFilled(removeButtonUM: ExchangeCardUM.RemoveButtonUM?): ExchangeCardUM.Filled { return ExchangeCardUM.Filled( - titleReference = resourceReference(id = R.string.swapping_from_title), + titleUM = ExchangeCardUM.TitleUM.Text(resourceReference(id = R.string.swapping_from_title)), removeButtonUM = removeButtonUM, tokenItemState = TokenItemState.Content( id = "1", diff --git a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/entity/transformer/UpdateAccountTokenItemConverter.kt b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/entity/transformer/UpdateAccountTokenItemConverter.kt index 2389d1aec9..f90f1e9794 100644 --- a/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/entity/transformer/UpdateAccountTokenItemConverter.kt +++ b/features/onramp/impl/src/main/kotlin/com/tangem/features/onramp/tokenlist/entity/transformer/UpdateAccountTokenItemConverter.kt @@ -26,7 +26,7 @@ internal class UpdateAccountTokenItemConverter( override fun convert(value: AccountAvailabilityUM): TokensListItemUM.Portfolio { return TokensListItemUM.Portfolio( - state = AccountCryptoPortfolioItemStateConverter( + tokenItemUM = AccountCryptoPortfolioItemStateConverter( appCurrency = appCurrency, account = value.account, onItemClick = null, diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt index 37319208bd..50569e441a 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/preview/WalletScreenPreviewData.kt @@ -19,6 +19,7 @@ import com.tangem.feature.wallet.presentation.common.WalletPreviewData.topBarCon import com.tangem.feature.wallet.presentation.wallet.state.model.* import com.tangem.utils.StringsSigns.DASH_SIGN import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toPersistentList internal object WalletScreenPreviewData { private val tokenItemState = TokenItemState.Content( @@ -86,17 +87,17 @@ internal object WalletScreenPreviewData { private val portfolioContentState = WalletTokensListState.ContentState.PortfolioContent( items = persistentListOf( TokensListItemUM.Portfolio( - tokens = textContentTokensState.items.filterIsInstance(), + tokens = textContentTokensState.items.filterIsInstance().toPersistentList(), isExpanded = false, isCollapsable = true, - state = AccountItemPreviewData.accountItem + tokenItemUM = AccountItemPreviewData.accountItem .copy(iconState = AccountItemPreviewData.accountLetterIcon), ), TokensListItemUM.Portfolio( - tokens = textContentTokensState.items.filterIsInstance(), + tokens = textContentTokensState.items.filterIsInstance().toPersistentList(), isExpanded = true, isCollapsable = true, - state = AccountItemPreviewData.accountItem, + tokenItemUM = AccountItemPreviewData.accountItem, ), ), organizeTokensButtonConfig = WalletTokensListState.OrganizeTokensButtonConfig( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenListStateConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenListStateConverter.kt index 07afba9a94..8cbaeee5da 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenListStateConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TokenListStateConverter.kt @@ -112,10 +112,10 @@ internal class TokenListStateConverter( is WalletTokensListState.Empty -> listOf() } return TokensListItemUM.Portfolio( - state = accountItem, + tokenItemUM = accountItem, isExpanded = isExtend, isCollapsable = true, - tokens = items.filterIsInstance(), + tokens = items.filterIsInstance().toPersistentList(), ) }