diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 3871825936..26d5547fcb 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -2197,6 +2197,8 @@
Missing backup
This card has been previously used for transactions. If received from an untrusted source, consider withdrawing all funds. If it\'s your card, no action is required.
Card has already signed transactions
+ Will be updated as soon as possible
+ Missing some token balances
Your review keeps us motivated to make Tangem Wallet even better
Enjoying Tangem?
You must associate your token before receiving tokens
diff --git a/core/ui/src/main/res/drawable/ic_error_sync_default_32.xml b/core/ui/src/main/res/drawable/ic_error_sync_default_32.xml
new file mode 100644
index 0000000000..f1ec26b229
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_error_sync_default_32.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_warning_default_32.xml b/core/ui/src/main/res/drawable/ic_warning_default_32.xml
new file mode 100644
index 0000000000..49ca5427e6
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_warning_default_32.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateNotificationsTransformer.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateNotificationsTransformer.kt
index 49918ddbca..c292623e56 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateNotificationsTransformer.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateNotificationsTransformer.kt
@@ -1,5 +1,6 @@
package com.tangem.feature.tokendetails.presentation.tokendetails.state.transformer
+import com.tangem.blockchain.common.Blockchain
import com.tangem.core.ui.R
import com.tangem.core.ui.ds.button.TangemButtonType
import com.tangem.core.ui.ds.image.TangemIconUM
@@ -10,6 +11,8 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
+import com.tangem.core.ui.format.bigdecimal.shorted
+import com.tangem.core.ui.res.TangemTheme
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
import com.tangem.domain.tokens.model.warnings.DynamicAddressesWarnings
@@ -17,30 +20,36 @@ import com.tangem.domain.tokens.model.warnings.HederaWarnings
import com.tangem.domain.tokens.model.warnings.KaspaWarnings
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsUM
+import com.tangem.utils.logging.TangemLogger
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
+import java.math.BigDecimal
import com.tangem.core.res.R as CoreResR
+@Suppress("LargeClass")
internal class UpdateNotificationsTransformer(
private val warnings: Set,
private val clickIntents: TokenDetailsClickIntents,
) : Transformer {
override fun transform(prevState: TokenDetailsUM): TokenDetailsUM {
- val notifications = warnings.mapNotNull(::mapWarning).toImmutableList()
+ val notifications = warnings.map(::mapWarning).toImmutableList()
return prevState.copy(notifications = notifications)
}
- @Suppress("LongMethod")
- private fun mapWarning(warning: CryptoCurrencyWarning): TangemMessageUM? {
+ @Suppress("LongMethod", "CyclomaticComplexMethod")
+ private fun mapWarning(warning: CryptoCurrencyWarning): TangemMessageUM {
return when (warning) {
is CryptoCurrencyWarning.SomeNetworksUnreachable -> TangemMessageUM(
id = "networks_unreachable",
title = resourceReference(CoreResR.string.warning_network_unreachable_title),
subtitle = resourceReference(CoreResR.string.warning_network_unreachable_message),
messageEffect = TangemMessageEffect.None,
- iconUM = TangemIconUM.Icon(R.drawable.ic_attention_default_24),
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_attention_default_24,
+ tintReference = { TangemTheme.colors2.graphic.status.attention },
+ ),
)
is CryptoCurrencyWarning.BalanceNotEnoughForFee -> createFeeWarning(
FeeWarningParams(
@@ -50,6 +59,7 @@ internal class UpdateNotificationsTransformer(
feeCurrencyName = warning.coinCurrency.name,
feeCurrencySymbol = warning.coinCurrency.symbol,
buyCurrency = warning.coinCurrency,
+ iconResId = R.drawable.ic_attention_default_24,
),
)
is CryptoCurrencyWarning.CustomTokenNotEnoughForFee -> createFeeWarning(
@@ -60,6 +70,7 @@ internal class UpdateNotificationsTransformer(
feeCurrencyName = warning.feeCurrencyName,
feeCurrencySymbol = warning.feeCurrencySymbol,
buyCurrency = warning.feeCurrency,
+ iconResId = R.drawable.ic_attention_default_24,
),
)
is CryptoCurrencyWarning.BeaconChainShutdown -> TangemMessageUM(
@@ -67,18 +78,24 @@ internal class UpdateNotificationsTransformer(
title = resourceReference(CoreResR.string.warning_beacon_chain_retirement_title),
subtitle = resourceReference(CoreResR.string.warning_beacon_chain_retirement_content),
messageEffect = TangemMessageEffect.None,
- iconUM = TangemIconUM.Icon(R.drawable.ic_attention_default_24),
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_attention_default_24,
+ tintReference = { TangemTheme.colors2.graphic.status.attention },
+ ),
)
is HederaWarnings.AssociateWarning -> TangemMessageUM(
id = "hedera_associate",
title = resourceReference(CoreResR.string.warning_hedera_missing_token_association_title),
subtitle = resourceReference(CoreResR.string.warning_hedera_missing_token_association_message_brief),
messageEffect = TangemMessageEffect.None,
- iconUM = TangemIconUM.Icon(R.drawable.ic_attention_default_24),
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_attention_default_24,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primary },
+ ),
buttonsUM = persistentListOf(
TangemMessageButtonUM(
text = resourceReference(CoreResR.string.warning_hedera_missing_token_association_button_title),
- type = TangemButtonType.Primary,
+ type = TangemButtonType.PrimaryInverse,
onClick = clickIntents::onAssociateClick,
),
),
@@ -94,11 +111,14 @@ internal class UpdateNotificationsTransformer(
),
),
messageEffect = TangemMessageEffect.None,
- iconUM = TangemIconUM.Icon(R.drawable.ic_attention_default_24),
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_attention_default_24,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primary },
+ ),
buttonsUM = persistentListOf(
TangemMessageButtonUM(
text = resourceReference(CoreResR.string.warning_hedera_missing_token_association_button_title),
- type = TangemButtonType.Primary,
+ type = TangemButtonType.PrimaryInverse,
onClick = clickIntents::onAssociateClick,
),
),
@@ -114,11 +134,14 @@ internal class UpdateNotificationsTransformer(
),
),
messageEffect = TangemMessageEffect.None,
- iconUM = TangemIconUM.Icon(R.drawable.ic_attention_default_24),
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_attention_default_24,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primary },
+ ),
buttonsUM = persistentListOf(
TangemMessageButtonUM(
text = resourceReference(CoreResR.string.warning_token_trustline_button_title),
- type = TangemButtonType.Primary,
+ type = TangemButtonType.PrimaryInverse,
onClick = clickIntents::onOpenTrustlineClick,
),
),
@@ -133,34 +156,51 @@ internal class UpdateNotificationsTransformer(
warning.currencySymbol,
),
),
- messageEffect = TangemMessageEffect.None,
- iconUM = TangemIconUM.Icon(R.drawable.ic_attention_default_24),
+ messageEffect = TangemMessageEffect.Warning,
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_attention_default_24,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primary },
+ ),
buttonsUM = persistentListOf(
+ TangemMessageButtonUM(
+ text = resourceReference(CoreResR.string.common_cancel),
+ type = TangemButtonType.Secondary,
+ onClick = clickIntents::onDismissIncompleteTransactionClick,
+ ),
TangemMessageButtonUM(
text = resourceReference(CoreResR.string.alert_button_try_again),
type = TangemButtonType.Primary,
+ tangemIconUM = TangemIconUM.Icon(
+ R.drawable.ic_tangem_24,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primaryInverted },
+ ),
onClick = clickIntents::onRetryIncompleteTransactionClick,
),
),
- onCloseClick = clickIntents::onDismissIncompleteTransactionClick,
)
is CryptoCurrencyWarning.MigrationMaticToPol -> TangemMessageUM(
id = "migration_matic_pol",
title = resourceReference(CoreResR.string.warning_matic_migration_title),
subtitle = resourceReference(CoreResR.string.warning_matic_migration_message),
messageEffect = TangemMessageEffect.None,
- iconUM = TangemIconUM.Icon(R.drawable.ic_attention_default_24),
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_attention_default_24,
+ tintReference = { TangemTheme.colors2.graphic.status.attention },
+ ),
)
is CryptoCurrencyWarning.MigrationClore -> TangemMessageUM(
id = "migration_clore",
title = resourceReference(CoreResR.string.warning_clore_migration_title),
subtitle = resourceReference(CoreResR.string.warning_clore_migration_description),
- messageEffect = TangemMessageEffect.None,
- iconUM = TangemIconUM.Icon(R.drawable.ic_attention_default_24),
+ messageEffect = TangemMessageEffect.Warning,
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_attention_default_24,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primary },
+ ),
buttonsUM = persistentListOf(
TangemMessageButtonUM(
text = resourceReference(CoreResR.string.warning_clore_migration_button),
- type = TangemButtonType.Primary,
+ type = TangemButtonType.PrimaryInverse,
onClick = clickIntents::onCloreMigrationClick,
),
),
@@ -170,23 +210,114 @@ internal class UpdateNotificationsTransformer(
title = resourceReference(CoreResR.string.dynamic_addresses_notification_funds_found_title),
subtitle = resourceReference(CoreResR.string.dynamic_addresses_notification_funds_found_description),
messageEffect = TangemMessageEffect.None,
- iconUM = TangemIconUM.Icon(R.drawable.ic_attention_default_24),
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_attention_default_24,
+ tintReference = { TangemTheme.colors2.graphic.status.attention },
+ ),
buttonsUM = persistentListOf(
TangemMessageButtonUM(
text = resourceReference(CoreResR.string.common_learn_more),
- type = TangemButtonType.Primary,
+ type = TangemButtonType.PrimaryInverse,
onClick = clickIntents::onDynamicAddressesFundsFoundLearnMoreClick,
),
),
)
- // Non-warning types — skip for redesign
- is CryptoCurrencyWarning.ExistentialDeposit,
- is CryptoCurrencyWarning.Rent,
- is CryptoCurrencyWarning.SomeNetworksNoAccount,
- is CryptoCurrencyWarning.TopUpWithoutReserve,
- is CryptoCurrencyWarning.FeeResourceInfo,
- is CryptoCurrencyWarning.UsedOutdatedDataWarning,
- -> null
+ is CryptoCurrencyWarning.ExistentialDeposit -> TangemMessageUM(
+ id = "existential_deposit",
+ title = resourceReference(CoreResR.string.warning_existential_deposit_title),
+ subtitle = resourceReference(
+ CoreResR.string.warning_existential_deposit_message,
+ wrappedList(warning.currencyName, warning.edStringValueWithSymbol),
+ ),
+ messageEffect = TangemMessageEffect.None,
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_warning_default_32,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primary },
+ ),
+ )
+ is CryptoCurrencyWarning.Rent -> TangemMessageUM(
+ id = "rent_info",
+ title = resourceReference(CoreResR.string.warning_rent_fee_title),
+ subtitle = resourceReference(
+ CoreResR.string.warning_solana_rent_fee_message,
+ wrappedList(
+ warning.rent,
+ warning.exemptionAmount.format { crypto(warning.cryptoCurrency) },
+ ),
+ ),
+ messageEffect = TangemMessageEffect.None,
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_warning_default_32,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primary },
+ ),
+ buttonsUM = persistentListOf(
+ TangemMessageButtonUM(
+ text = resourceReference(CoreResR.string.common_later),
+ type = TangemButtonType.Secondary,
+ onClick = clickIntents::onCloseRentInfoNotification,
+ ),
+ ),
+ )
+ is CryptoCurrencyWarning.SomeNetworksNoAccount -> TangemMessageUM(
+ id = "networks_no_account",
+ title = resourceReference(CoreResR.string.warning_no_account_title),
+ subtitle = resourceReference(
+ CoreResR.string.no_account_generic,
+ wrappedList(
+ warning.amountCurrency.network.name,
+ warning.amountToCreateAccount.format {
+ crypto(symbol = "", decimals = warning.amountCurrency.decimals)
+ }.trim(),
+ warning.amountCurrency.network.currencySymbol,
+ ),
+ ),
+ messageEffect = TangemMessageEffect.None,
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_warning_default_32,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primary },
+ ),
+ )
+ is CryptoCurrencyWarning.TopUpWithoutReserve -> TangemMessageUM(
+ id = "top_up_without_reserve",
+ title = resourceReference(CoreResR.string.warning_no_account_title),
+ subtitle = resourceReference(CoreResR.string.no_account_send_to_create),
+ messageEffect = TangemMessageEffect.None,
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_warning_default_32,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primary },
+ ),
+ )
+ is CryptoCurrencyWarning.FeeResourceInfo -> TangemMessageUM(
+ id = "fee_resource_info",
+ title = resourceReference(CoreResR.string.koinos_mana_level_title),
+ subtitle = resourceReference(
+ CoreResR.string.koinos_mana_level_description,
+ wrappedList(
+ formatMana(warning.amount),
+ warning.maxAmount?.let(::formatMana) ?: run {
+ TangemLogger.e(
+ "FeeResource maxAmount cannot be null in Koinos. Check KoinosWalletManager",
+ )
+ ""
+ },
+ ),
+ ),
+ messageEffect = TangemMessageEffect.None,
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_warning_default_32,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primary },
+ ),
+ )
+ is CryptoCurrencyWarning.UsedOutdatedDataWarning -> TangemMessageUM(
+ id = "used_outdated_data",
+ title = resourceReference(CoreResR.string.warning_outdated_data_title),
+ subtitle = resourceReference(CoreResR.string.warning_outdated_data_message),
+ messageEffect = TangemMessageEffect.None,
+ iconUM = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_error_sync_default_32,
+ tintReference = { TangemTheme.colors2.graphic.status.attention },
+ ),
+ )
}
}
@@ -198,7 +329,7 @@ internal class UpdateNotificationsTransformer(
CoreResR.string.common_buy_currency,
wrappedList(params.feeCurrencySymbol),
),
- type = TangemButtonType.Primary,
+ type = TangemButtonType.PrimaryInverse,
onClick = { clickIntents.onBuyCoinClick(params.buyCurrency) },
),
)
@@ -223,17 +354,25 @@ internal class UpdateNotificationsTransformer(
),
),
messageEffect = TangemMessageEffect.None,
- iconUM = TangemIconUM.Icon(R.drawable.ic_attention_default_24),
+ iconUM = TangemIconUM.Icon(
+ iconRes = params.iconResId,
+ tintReference = { TangemTheme.colors2.graphic.neutral.primary },
+ ),
buttonsUM = buttons,
)
}
- private data class FeeWarningParams(
- val id: String,
- val currency: CryptoCurrency,
- val networkName: String,
- val feeCurrencyName: String,
- val feeCurrencySymbol: String,
- val buyCurrency: CryptoCurrency?,
- )
-}
\ No newline at end of file
+ private fun formatMana(amount: BigDecimal): String {
+ return amount.format { crypto(symbol = "", decimals = Blockchain.Koinos.decimals()).shorted() }
+ }
+}
+
+private data class FeeWarningParams(
+ val id: String,
+ val currency: CryptoCurrency,
+ val networkName: String,
+ val feeCurrencyName: String,
+ val feeCurrencySymbol: String,
+ val buyCurrency: CryptoCurrency?,
+ val iconResId: Int,
+)
\ No newline at end of file
diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/TokenDetailsScreen.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/TokenDetailsScreen.kt
index 87a2b542dd..08b7dced0e 100644
--- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/TokenDetailsScreen.kt
+++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/ui/TokenDetailsScreen.kt
@@ -45,7 +45,6 @@ import com.tangem.core.ui.components.haze.hazeSourceTangem
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.themedColor
-import com.tangem.core.ui.res.LocalRootBackgroundColor
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreviewRedesign
import com.tangem.domain.models.account.CryptoPortfolioIcon
@@ -86,14 +85,14 @@ internal fun TokenDetailsScreen(
val statusBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getTop(this).toDp() }
val topBarTotalHeight = TopBarHeight + statusBarHeight
- val rootBackground by LocalRootBackgroundColor.current
+ val rootBackground = TangemTheme.colors2.surface.level2
var marketBlockHeight by remember { mutableStateOf(0.dp) }
val effectiveBottomPadding = marketBlockHeight + TangemTheme.dimens2.x4
Box(
modifier = modifier
.fillMaxSize()
- .background(TangemTheme.colors2.surface.level2),
+ .background(rootBackground),
) {
Box(
modifier = Modifier
diff --git a/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateNotificationsTransformerTest.kt b/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateNotificationsTransformerTest.kt
index 19d4cea5ca..b87755d855 100644
--- a/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateNotificationsTransformerTest.kt
+++ b/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateNotificationsTransformerTest.kt
@@ -223,7 +223,7 @@ class UpdateNotificationsTransformerTest {
}
@Test
- fun `GIVEN KaspaIncompleteTransaction WHEN transform THEN notification with button and close is created`() {
+ fun `GIVEN KaspaIncompleteTransaction WHEN transform THEN notification with cancel and try again buttons is created`() {
// GIVEN
val currency: CryptoCurrency = mockk(relaxed = true)
val transformer = createTransformer(
@@ -243,16 +243,17 @@ class UpdateNotificationsTransformerTest {
// THEN
assertThat(result.notifications).hasSize(1)
assertThat(result.notifications.first().id).isEqualTo("kaspa_incomplete")
- assertThat(result.notifications.first().buttonsUM).hasSize(1)
- assertThat(result.notifications.first().onCloseClick).isNotNull()
+ assertThat(result.notifications.first().buttonsUM).hasSize(2)
+ assertThat(result.notifications.first().onCloseClick).isNull()
+ assertThat(result.notifications.first().messageEffect).isEqualTo(TangemMessageEffect.Warning)
}
// endregion
- // region Skipped warnings
+ // region Newly added warnings
@Test
- fun `GIVEN ExistentialDeposit WHEN transform THEN notification is skipped`() {
+ fun `GIVEN ExistentialDeposit WHEN transform THEN notification with id existential_deposit is created`() {
// GIVEN
val transformer = createTransformer(
warnings = setOf(
@@ -267,11 +268,13 @@ class UpdateNotificationsTransformerTest {
val result = transformer.transform(initialState())
// THEN
- assertThat(result.notifications).isEmpty()
+ assertThat(result.notifications).hasSize(1)
+ assertThat(result.notifications.first().id).isEqualTo("existential_deposit")
+ assertThat(result.notifications.first().buttonsUM).isEmpty()
}
@Test
- fun `GIVEN Rent WHEN transform THEN notification is skipped`() {
+ fun `GIVEN Rent WHEN transform THEN notification with id rent_info and later button is created`() {
// GIVEN
val transformer = createTransformer(
warnings = setOf(
@@ -287,11 +290,120 @@ class UpdateNotificationsTransformerTest {
val result = transformer.transform(initialState())
// THEN
- assertThat(result.notifications).isEmpty()
+ assertThat(result.notifications).hasSize(1)
+ assertThat(result.notifications.first().id).isEqualTo("rent_info")
+ assertThat(result.notifications.first().onCloseClick).isNull()
+ assertThat(result.notifications.first().buttonsUM).hasSize(1)
}
@Test
- fun `GIVEN UsedOutdatedDataWarning WHEN transform THEN notification is skipped`() {
+ fun `GIVEN Rent WHEN later clicked THEN onCloseRentInfoNotification is called`() {
+ // GIVEN
+ val transformer = createTransformer(
+ warnings = setOf(
+ CryptoCurrencyWarning.Rent(
+ rent = BigDecimal("0.00001"),
+ exemptionAmount = BigDecimal("0.01"),
+ cryptoCurrency = mockk(relaxed = true),
+ ),
+ ),
+ )
+
+ // WHEN
+ val result = transformer.transform(initialState())
+ result.notifications.first().buttonsUM.first().onClick()
+
+ // THEN
+ verify(exactly = 1) { clickIntents.onCloseRentInfoNotification() }
+ }
+
+ @Test
+ fun `GIVEN SomeNetworksNoAccount WHEN transform THEN notification with id networks_no_account is created`() {
+ // GIVEN
+ val amountCurrency: CryptoCurrency = mockk(relaxed = true) {
+ io.mockk.every { decimals } returns 7
+ io.mockk.every { network } returns mockk(relaxed = true) {
+ io.mockk.every { name } returns "Stellar"
+ io.mockk.every { currencySymbol } returns "XLM"
+ }
+ }
+ val transformer = createTransformer(
+ warnings = setOf(
+ CryptoCurrencyWarning.SomeNetworksNoAccount(
+ amountToCreateAccount = BigDecimal("1.0"),
+ amountCurrency = amountCurrency,
+ ),
+ ),
+ )
+
+ // WHEN
+ val result = transformer.transform(initialState())
+
+ // THEN
+ assertThat(result.notifications).hasSize(1)
+ assertThat(result.notifications.first().id).isEqualTo("networks_no_account")
+ assertThat(result.notifications.first().buttonsUM).isEmpty()
+ }
+
+ @Test
+ fun `GIVEN TopUpWithoutReserve WHEN transform THEN notification with id top_up_without_reserve is created`() {
+ // GIVEN
+ val transformer = createTransformer(
+ warnings = setOf(CryptoCurrencyWarning.TopUpWithoutReserve),
+ )
+
+ // WHEN
+ val result = transformer.transform(initialState())
+
+ // THEN
+ assertThat(result.notifications).hasSize(1)
+ assertThat(result.notifications.first().id).isEqualTo("top_up_without_reserve")
+ assertThat(result.notifications.first().buttonsUM).isEmpty()
+ }
+
+ @Test
+ fun `GIVEN FeeResourceInfo WHEN transform THEN notification with id fee_resource_info is created`() {
+ // GIVEN
+ val transformer = createTransformer(
+ warnings = setOf(
+ CryptoCurrencyWarning.FeeResourceInfo(
+ amount = BigDecimal("50.0"),
+ maxAmount = BigDecimal("100.0"),
+ ),
+ ),
+ )
+
+ // WHEN
+ val result = transformer.transform(initialState())
+
+ // THEN
+ assertThat(result.notifications).hasSize(1)
+ assertThat(result.notifications.first().id).isEqualTo("fee_resource_info")
+ assertThat(result.notifications.first().buttonsUM).isEmpty()
+ }
+
+ @Test
+ fun `GIVEN FeeResourceInfo with null maxAmount WHEN transform THEN notification is still created`() {
+ // GIVEN
+ val transformer = createTransformer(
+ warnings = setOf(
+ CryptoCurrencyWarning.FeeResourceInfo(
+ amount = BigDecimal("50.0"),
+ maxAmount = null,
+ ),
+ ),
+ )
+
+ // WHEN
+ val result = transformer.transform(initialState())
+
+ // THEN
+ assertThat(result.notifications).hasSize(1)
+ assertThat(result.notifications.first().id).isEqualTo("fee_resource_info")
+ }
+
+ @Test
+ fun `GIVEN UsedOutdatedDataWarning WHEN transform THEN notification with id used_outdated_data is created`() {
// GIVEN
val transformer = createTransformer(
warnings = setOf(CryptoCurrencyWarning.UsedOutdatedDataWarning),
@@ -301,7 +413,8 @@ class UpdateNotificationsTransformerTest {
val result = transformer.transform(initialState())
// THEN
- assertThat(result.notifications).isEmpty()
+ assertThat(result.notifications).hasSize(1)
+ assertThat(result.notifications.first().id).isEqualTo("used_outdated_data")
}
// endregion
@@ -309,7 +422,7 @@ class UpdateNotificationsTransformerTest {
// region Message effect
@Test
- fun `GIVEN any mapped warning WHEN transform THEN messageEffect is None`() {
+ fun `GIVEN SomeNetworksUnreachable WHEN transform THEN messageEffect is None`() {
// GIVEN
val transformer = createTransformer(
warnings = setOf(CryptoCurrencyWarning.SomeNetworksUnreachable),
@@ -322,6 +435,20 @@ class UpdateNotificationsTransformerTest {
assertThat(result.notifications.first().messageEffect).isEqualTo(TangemMessageEffect.None)
}
+ @Test
+ fun `GIVEN MigrationClore WHEN transform THEN messageEffect is Warning`() {
+ // GIVEN
+ val transformer = createTransformer(
+ warnings = setOf(CryptoCurrencyWarning.MigrationClore),
+ )
+
+ // WHEN
+ val result = transformer.transform(initialState())
+
+ // THEN
+ assertThat(result.notifications.first().messageEffect).isEqualTo(TangemMessageEffect.Warning)
+ }
+
// endregion
// region Icon
@@ -345,7 +472,7 @@ class UpdateNotificationsTransformerTest {
// region Multiple warnings
@Test
- fun `GIVEN multiple warnings with some skipped WHEN transform THEN only mapped warnings are in notifications`() {
+ fun `GIVEN multiple warnings WHEN transform THEN all are mapped to notifications`() {
// GIVEN
val transformer = createTransformer(
warnings = setOf(
@@ -360,10 +487,12 @@ class UpdateNotificationsTransformerTest {
val result = transformer.transform(initialState())
// THEN
- assertThat(result.notifications).hasSize(2)
+ assertThat(result.notifications).hasSize(4)
assertThat(result.notifications.map { it.id }).containsExactly(
"networks_unreachable",
"beacon_chain_shutdown",
+ "used_outdated_data",
+ "top_up_without_reserve",
)
}
@@ -410,7 +539,29 @@ class UpdateNotificationsTransformerTest {
}
@Test
- fun `GIVEN KaspaIncompleteTransaction WHEN retry clicked THEN onRetryIncompleteTransactionClick is called`() {
+ fun `GIVEN KaspaIncompleteTransaction WHEN try again clicked THEN onRetryIncompleteTransactionClick is called`() {
+ // GIVEN
+ val transformer = createTransformer(
+ warnings = setOf(
+ KaspaWarnings.IncompleteTransaction(
+ currency = mockk(relaxed = true),
+ amount = BigDecimal("100"),
+ currencySymbol = "KAS",
+ currencyDecimals = 8,
+ ),
+ ),
+ )
+
+ // WHEN
+ val result = transformer.transform(initialState())
+ result.notifications.first().buttonsUM[1].onClick()
+
+ // THEN
+ verify(exactly = 1) { clickIntents.onRetryIncompleteTransactionClick() }
+ }
+
+ @Test
+ fun `GIVEN KaspaIncompleteTransaction WHEN cancel clicked THEN onDismissIncompleteTransactionClick is called`() {
// GIVEN
val transformer = createTransformer(
warnings = setOf(
@@ -427,28 +578,6 @@ class UpdateNotificationsTransformerTest {
val result = transformer.transform(initialState())
result.notifications.first().buttonsUM.first().onClick()
- // THEN
- verify(exactly = 1) { clickIntents.onRetryIncompleteTransactionClick() }
- }
-
- @Test
- fun `GIVEN KaspaIncompleteTransaction WHEN close clicked THEN onDismissIncompleteTransactionClick is called`() {
- // GIVEN
- val transformer = createTransformer(
- warnings = setOf(
- KaspaWarnings.IncompleteTransaction(
- currency = mockk(relaxed = true),
- amount = BigDecimal("100"),
- currencySymbol = "KAS",
- currencyDecimals = 8,
- ),
- ),
- )
-
- // WHEN
- val result = transformer.transform(initialState())
- result.notifications.first().onCloseClick!!.invoke()
-
// THEN
verify(exactly = 1) { clickIntents.onDismissIncompleteTransactionClick() }
}
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotificationUM.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotificationUM.kt
index aa6679cd47..5a0df5c3ec 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotificationUM.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/model/WalletNotificationUM.kt
@@ -50,8 +50,8 @@ internal sealed class WalletNotificationUM(val messageUM: TangemMessageUM, val t
data object UsedOutdatedData : WalletNotificationUM(
messageUM = TangemMessageUM(
id = "UsedOutdatedDataNotification",
- title = stringReference("Missing some token balances"), // todo redesign main lokalise
- subtitle = stringReference("Will be updated as soon as possible"), // todo redesign main lokalise
+ title = resourceReference(com.tangem.core.res.R.string.warning_outdated_data_title),
+ subtitle = resourceReference(com.tangem.core.res.R.string.warning_outdated_data_message),
iconUM = TangemIconUM.Icon(
iconRes = R.drawable.ic_error_sync_default_24,
tintReference = { TangemTheme.colors2.graphic.status.attention },
diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/converter/YieldSupplyToEarnBlockConverter.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/converter/YieldSupplyToEarnBlockConverter.kt
index dd93e5a6aa..2dbde67434 100644
--- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/converter/YieldSupplyToEarnBlockConverter.kt
+++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/converter/YieldSupplyToEarnBlockConverter.kt
@@ -54,11 +54,7 @@ internal class YieldSupplyToEarnBlockConverter : Converter