diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/Notifications.kt b/core/ui/src/main/java/com/tangem/core/ui/components/Notifications.kt
deleted file mode 100644
index e70f571b18..0000000000
--- a/core/ui/src/main/java/com/tangem/core/ui/components/Notifications.kt
+++ /dev/null
@@ -1,202 +0,0 @@
-package com.tangem.core.ui.components
-
-import androidx.annotation.DrawableRes
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.*
-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.res.painterResource
-import androidx.compose.ui.tooling.preview.Preview
-import com.tangem.core.ui.R
-import com.tangem.core.ui.res.TangemTheme
-
-/**
- * Closable notification with custom icon
- * Child of parent component
- * @see Figma component
- *
- * Use to show banner with custom icon and possibility to close
- * i.e. Feedback notification
- *
- * @param title notification title
- * @param icon drawable res on icon
- * @param iconColor icon color
- * @param onClick callback on click
- * @param onCloseClick callback on close icon click
- */
-@Composable
-fun ClosableNotification(
- title: String,
- @DrawableRes icon: Int,
- iconColor: Color,
- onClick: (() -> Unit),
- onCloseClick: (() -> Unit),
-) {
- NotificationCardTemplate(onClick) {
- Icon(
- modifier = Modifier
- .size(TangemTheme.dimens.size20)
- .align(Alignment.CenterStart),
- painter = painterResource(id = icon),
- tint = iconColor,
- contentDescription = null,
- )
- Text(
- modifier = Modifier
- .padding(horizontal = TangemTheme.dimens.spacing28)
- .align(Alignment.CenterStart),
- text = title,
- color = TangemTheme.colors.text.primary1,
- style = TangemTheme.typography.subtitle2,
- )
- Icon(
- modifier = Modifier
- .size(TangemTheme.dimens.size20)
- .align(Alignment.CenterEnd)
- .clickable(onClick = onCloseClick),
- painter = painterResource(id = R.drawable.ic_close_24),
- contentDescription = null,
- tint = TangemTheme.colors.icon.informative,
- )
- }
-}
-
-/**
- * Notification component from Design system
- * There are few states for this component, but only one parent, see link below
- *
- * Use this for Notification with title, subtitle, clickable or not
- *
- * @param title notification title
- * @param subtitle notification subtitle
- * @param onClick click on notification, if its null then no chevron icon
- *
- * @see Figma component
- */
-@Composable
-fun WarningNotification(title: String, subtitle: String?, onClick: (() -> Unit)?) {
- NotificationCardTemplate(onClick) {
- Image(
- modifier = Modifier
- .size(TangemTheme.dimens.size20)
- .align(Alignment.CenterStart),
- painter = painterResource(id = R.drawable.img_attention_20),
- contentDescription = null,
- )
- Column(
- modifier = Modifier
- .padding(horizontal = TangemTheme.dimens.spacing28)
- .align(Alignment.CenterStart),
- ) {
- Text(
- text = title,
- color = TangemTheme.colors.text.primary1,
- style = TangemTheme.typography.subtitle2,
- )
- if (!subtitle.isNullOrEmpty()) {
- SpacerH2()
- Text(
- text = subtitle,
- color = TangemTheme.colors.text.tertiary,
- style = TangemTheme.typography.caption,
- )
- }
- }
- if (onClick != null) {
- Icon(
- modifier = Modifier
- .size(TangemTheme.dimens.size20)
- .align(Alignment.CenterEnd),
- painter = painterResource(id = R.drawable.ic_chevron_right_24),
- contentDescription = null,
- tint = TangemTheme.colors.icon.informative,
- )
- }
- }
-}
-
-@OptIn(ExperimentalMaterialApi::class)
-@Composable
-private fun NotificationCardTemplate(onClick: (() -> Unit)? = null, content: @Composable BoxScope.() -> Unit) {
- Surface(
- color = TangemTheme.colors.button.secondary,
- shape = RoundedCornerShape(TangemTheme.dimens.radius18),
- onClick = onClick ?: {},
- enabled = onClick != null,
- ) {
- Box(
- Modifier
- .padding(
- horizontal = TangemTheme.dimens.spacing12,
- vertical = TangemTheme.dimens.spacing8,
- )
- .wrapContentSize(),
- ) {
- content()
- }
- }
-}
-
-// region Preview
-
-@Composable
-private fun WarningNotificationPreview() {
- Column(modifier = Modifier.fillMaxWidth()) {
- WarningNotification(
- title = "Your wallet hasn’t been backed up",
- subtitle = "Lorem ipsum dolor sit amet, consectetur " +
- "adipiscing elit, sed do eiusmod tempor incididunt ut labore et...",
- onClick = {},
- )
- SpacerH32()
- WarningNotification(
- title = "Your wallet hasn’t been backed up",
- subtitle = null,
- onClick = {},
- )
- SpacerH32()
- WarningNotification(
- title = "Your wallet hasn’t been backed up",
- subtitle = "Lorem ipsum dolor sit amet, consectetur " +
- "adipiscing elit, sed do eiusmod tempor incididunt ut labore et...",
- onClick = null,
- )
- SpacerH32()
- WarningNotification(
- title = "Your wallet hasn’t been backed up",
- subtitle = null,
- onClick = null,
- )
- SpacerH32()
- ClosableNotification(
- title = "Like tangem app?",
- icon = R.drawable.ic_star_24,
- iconColor = TangemTheme.colors.icon.attention,
- onClick = {},
- onCloseClick = {},
- )
- }
-}
-
-@Preview(showBackground = true)
-@Composable
-private fun Preview_WarningNotification_InLightTheme() {
- TangemTheme(isDark = false) {
- WarningNotificationPreview()
- }
-}
-
-@Preview(showBackground = true)
-@Composable
-private fun Preview_WarningNotification_InDarkTheme() {
- TangemTheme(isDark = true) {
- WarningNotificationPreview()
- }
-}
-
-// endregion Preview
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt
new file mode 100644
index 0000000000..db338c9721
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt
@@ -0,0 +1,171 @@
+package com.tangem.core.ui.components.notifications
+
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Surface
+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.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
+import com.tangem.core.ui.R
+import com.tangem.core.ui.components.SpacerH2
+import com.tangem.core.ui.res.TangemColorPalette
+import com.tangem.core.ui.res.TangemTheme
+
+/**
+ * Notification component from Design system.
+ * Use this for Notification with title, subtitle, clickable or not.
+ *
+ * @param state component state
+ * @param modifier modifier
+ *
+ * @see Figma component
+ */
+@Composable
+fun Notification(state: NotificationState, modifier: Modifier = Modifier) {
+ Surface(
+ onClick = if (state is NotificationState.Action) {
+ state.onClick
+ } else {
+ {}
+ },
+ modifier = modifier,
+ enabled = when (state) {
+ is NotificationState.Simple -> false
+ is NotificationState.Action -> true
+ },
+ shape = RoundedCornerShape(TangemTheme.dimens.radius18),
+ color = TangemTheme.colors.button.secondary,
+ ) {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = TangemTheme.dimens.spacing12, vertical = TangemTheme.dimens.spacing8),
+ ) {
+ NotificationIcon(
+ iconResId = state.iconResId,
+ iconTint = state.tint,
+ modifier = Modifier
+ .size(size = TangemTheme.dimens.size20)
+ .align(alignment = Alignment.CenterStart),
+ )
+
+ NotificationInfoBlock(
+ title = state.title,
+ subtitle = state.subtitle,
+ modifier = Modifier.align(alignment = Alignment.CenterStart),
+ )
+
+ if (state is NotificationState.Action) {
+ Icon(
+ modifier = Modifier
+ .size(size = TangemTheme.dimens.size20)
+ .align(alignment = Alignment.CenterEnd),
+ painter = painterResource(id = R.drawable.ic_chevron_right_24),
+ contentDescription = null,
+ tint = TangemTheme.colors.icon.informative,
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun NotificationIcon(@DrawableRes iconResId: Int, iconTint: Color?, modifier: Modifier = Modifier) {
+ if (iconTint != null) {
+ Icon(
+ painter = painterResource(id = iconResId),
+ contentDescription = null,
+ modifier = modifier,
+ tint = iconTint,
+ )
+ } else {
+ Image(
+ painter = painterResource(id = iconResId),
+ contentDescription = null,
+ modifier = modifier,
+ )
+ }
+}
+
+@Composable
+private fun NotificationInfoBlock(title: String, subtitle: String?, modifier: Modifier = Modifier) {
+ Column(modifier = modifier.padding(horizontal = TangemTheme.dimens.spacing30)) {
+ Text(
+ text = title,
+ color = TangemTheme.colors.text.primary1,
+ style = TangemTheme.typography.body2,
+ )
+
+ if (!subtitle.isNullOrEmpty()) {
+ SpacerH2()
+ Text(
+ text = subtitle,
+ color = TangemTheme.colors.text.tertiary,
+ style = TangemTheme.typography.caption,
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun Preview_WarningNotification_Light(
+ @PreviewParameter(NotificationStateProvider::class)
+ state: NotificationState,
+) {
+ TangemTheme(isDark = false) {
+ Notification(state)
+ }
+}
+
+@Preview
+@Composable
+private fun Preview_WarningNotification_Dark(
+ @PreviewParameter(NotificationStateProvider::class)
+ state: NotificationState,
+) {
+ TangemTheme(isDark = true) {
+ Notification(state)
+ }
+}
+
+private class NotificationStateProvider : CollectionPreviewParameterProvider(
+ collection = listOf(
+ NotificationState.Simple(
+ title = "Your wallet hasn’t been backed up",
+ subtitle = "Lorem ipsum dolor sit amet, consectetur " +
+ "adipiscing elit, sed do eiusmod tempor incididunt ut labore et...",
+ iconResId = R.drawable.img_attention_20,
+ ),
+ NotificationState.Simple(
+ title = "Your wallet hasn’t been backed up",
+ subtitle = null,
+ iconResId = R.drawable.ic_alert_circle_24,
+ tint = TangemColorPalette.Amaranth,
+ ),
+ NotificationState.Action(
+ title = "Your wallet hasn’t been backed up",
+ subtitle = "Lorem ipsum dolor sit amet, consectetur " +
+ "adipiscing elit, sed do eiusmod tempor incididunt ut labore et...",
+ iconResId = R.drawable.img_attention_20,
+ onClick = {},
+ ),
+ NotificationState.Action(
+ title = "Your wallet hasn’t been backed up",
+ subtitle = null,
+ iconResId = R.drawable.ic_alert_circle_24,
+ tint = TangemColorPalette.Amaranth,
+ onClick = {},
+ ),
+ ),
+)
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/notifications/NotificationState.kt b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/NotificationState.kt
new file mode 100644
index 0000000000..065fa1e125
--- /dev/null
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/NotificationState.kt
@@ -0,0 +1,54 @@
+package com.tangem.core.ui.components.notifications
+
+import androidx.annotation.DrawableRes
+import androidx.compose.ui.graphics.Color
+
+/**
+ * Notification component state
+ *
+ * @property title title
+ * @property subtitle subtitle
+ * @property iconResId icon resource id
+ * @property tint icon tint
+ *
+[REDACTED_AUTHOR]
+ */
+sealed class NotificationState(
+ open val title: String,
+ open val subtitle: String? = null,
+ @DrawableRes open val iconResId: Int,
+ open val tint: Color? = null,
+) {
+
+ /**
+ * Simple notification state. Non clickable.
+ *
+ * @property title title
+ * @property subtitle subtitle
+ * @property iconResId icon resource id
+ * @property tint icon tint
+ */
+ data class Simple(
+ override val title: String,
+ override val subtitle: String? = null,
+ @DrawableRes override val iconResId: Int,
+ override val tint: Color? = null,
+ ) : NotificationState(title, subtitle, iconResId, tint)
+
+ /**
+ * Clickable notification state
+ *
+ * @property title title
+ * @property subtitle subtitle
+ * @property iconResId icon resource id
+ * @property tint icon tint
+ * @param onClick lambda be invoked when notification component is clicked
+ */
+ data class Action(
+ override val title: String,
+ override val subtitle: String? = null,
+ @DrawableRes override val iconResId: Int,
+ override val tint: Color? = null,
+ val onClick: () -> Unit,
+ ) : NotificationState(title, subtitle, iconResId, tint)
+}
\ No newline at end of file
diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt
index 421c82c9e1..8c85ac6339 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemDimens.kt
@@ -76,6 +76,7 @@ data class TangemDimens internal constructor(
val size200: Dp = 200.dp,
// endregion Size
// region Spacing
+ val spacing0: Dp = 0.dp,
val spacing0_5: Dp = 0.5.dp,
val spacing2: Dp = 2.dp,
val spacing4: Dp = 4.dp,
@@ -91,6 +92,7 @@ data class TangemDimens internal constructor(
val spacing24: Dp = 24.dp,
val spacing26: Dp = 26.dp,
val spacing28: Dp = 28.dp,
+ val spacing30: Dp = 30.dp,
val spacing32: Dp = 32.dp,
val spacing34: Dp = 34.dp,
val spacing36: Dp = 34.dp,
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt
index 410256fd11..2bfde4eaaa 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt
@@ -7,10 +7,7 @@ import com.tangem.feature.wallet.presentation.common.state.TokenItemState.TokenO
import com.tangem.feature.wallet.presentation.organizetokens.DraggableItem
import com.tangem.feature.wallet.presentation.organizetokens.OrganizeTokensListState
import com.tangem.feature.wallet.presentation.organizetokens.OrganizeTokensStateHolder
-import com.tangem.feature.wallet.presentation.wallet.state.WalletCardState
-import com.tangem.feature.wallet.presentation.wallet.state.WalletContentItemState
-import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
-import com.tangem.feature.wallet.presentation.wallet.state.WalletTopBarConfig
+import com.tangem.feature.wallet.presentation.wallet.state.*
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList
import java.util.UUID
@@ -220,6 +217,12 @@ internal object WalletPreviewData {
),
),
),
+ notifications = persistentListOf(
+ WalletNotification.UnreachableNetworks,
+ WalletNotification.LikeTangemApp(onClick = {}),
+ WalletNotification.NeedToBackup(onClick = {}),
+ WalletNotification.ScanCard(onClick = {}),
+ ),
onOrganizeTokensClick = {},
)
@@ -252,5 +255,11 @@ internal object WalletPreviewData {
),
),
),
+ notifications = persistentListOf(
+ WalletNotification.UnreachableNetworks,
+ WalletNotification.LikeTangemApp(onClick = {}),
+ WalletNotification.NeedToBackup(onClick = {}),
+ WalletNotification.ScanCard(onClick = {}),
+ ),
)
}
\ No newline at end of file
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletNotification.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletNotification.kt
new file mode 100644
index 0000000000..39e760dd4f
--- /dev/null
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletNotification.kt
@@ -0,0 +1,65 @@
+package com.tangem.feature.wallet.presentation.wallet.state
+
+import com.tangem.core.ui.components.notifications.NotificationState
+import com.tangem.core.ui.res.TangemColorPalette
+import com.tangem.feature.wallet.impl.R
+
+/**
+ * Wallet notification component state
+ *
+ * @property state state
+ *
+[REDACTED_AUTHOR]
+ */
+sealed class WalletNotification(open val state: NotificationState) {
+
+ /**
+ * "Backup the card" notification
+ *
+ * @property onClick lambda be invoked when notification is clicked
+ */
+ data class NeedToBackup(val onClick: () -> Unit) : WalletNotification(
+ state = NotificationState.Action(
+ title = "Backup your card",
+ iconResId = R.drawable.ic_alert_circle_24,
+ onClick = onClick,
+ tint = TangemColorPalette.Amaranth,
+ ),
+ )
+
+ /** "Unreachable networks" notification */
+ object UnreachableNetworks : WalletNotification(
+ state = NotificationState.Simple(
+ title = "Some networks are unreachable",
+ iconResId = R.drawable.img_attention_20,
+ tint = null,
+ ),
+ )
+
+ /**
+ * "Like Tangem App" notification
+ *
+ * @property onClick lambda be invoked when notification is clicked
+ */
+ data class LikeTangemApp(val onClick: () -> Unit) : WalletNotification(
+ state = NotificationState.Action(
+ title = "Like Tangem App?",
+ iconResId = R.drawable.ic_star_24,
+ onClick = onClick,
+ tint = TangemColorPalette.Tangerine,
+ ),
+ )
+
+ /**
+ * "Scan the card" notification
+ *
+ * @property onClick lambda be invoked when notification is clicked
+ */
+ data class ScanCard(val onClick: () -> Unit) : WalletNotification(
+ state = NotificationState.Action(
+ title = "Scan your card to continue",
+ iconResId = R.drawable.ic_tangem_24,
+ onClick = onClick,
+ ),
+ )
+}
\ No newline at end of file
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt
index bfc07128cf..a10b91ab37 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/WalletStateHolder.kt
@@ -10,6 +10,7 @@ import kotlinx.collections.immutable.ImmutableList
* @property selectedWallet selected wallet
* @property wallets list of wallets states
* @property contentItems content items
+ * @property notifications notifications
*
[REDACTED_AUTHOR]
*/
@@ -19,16 +20,19 @@ internal sealed class WalletStateHolder(
open val selectedWallet: WalletCardState,
open val wallets: ImmutableList,
open val contentItems: ImmutableList,
+ open val notifications: ImmutableList,
) {
/**
* Multi currency wallet content state
*
- * @property onBackClick lambda be invoked when back button is clicked
- * @property topBarConfig top bar config
- * @property selectedWallet selected wallet
- * @property wallets list of wallets states
- * @property contentItems content items
+ * @property onBackClick lambda be invoked when back button is clicked
+ * @property topBarConfig top bar config
+ * @property selectedWallet selected wallet
+ * @property wallets list of wallets states
+ * @property contentItems content items
+ * @property notifications notifications
+ * @property onOrganizeTokensClick lambda be invoked when organize tokens button is clicked
*/
data class MultiCurrencyContent(
override val onBackClick: () -> Unit,
@@ -36,8 +40,9 @@ internal sealed class WalletStateHolder(
override val selectedWallet: WalletCardState,
override val wallets: ImmutableList,
override val contentItems: ImmutableList,
+ override val notifications: ImmutableList,
val onOrganizeTokensClick: () -> Unit,
- ) : WalletStateHolder(onBackClick, topBarConfig, selectedWallet, wallets, contentItems)
+ ) : WalletStateHolder(onBackClick, topBarConfig, selectedWallet, wallets, contentItems, notifications)
/**
* Single currency wallet content state
@@ -47,6 +52,7 @@ internal sealed class WalletStateHolder(
* @property selectedWallet selected wallet
* @property wallets list of wallets states
* @property contentItems content items
+ * @property notifications notifications
*/
data class SingleCurrencyContent(
override val onBackClick: () -> Unit,
@@ -54,5 +60,6 @@ internal sealed class WalletStateHolder(
override val selectedWallet: WalletCardState,
override val wallets: ImmutableList,
override val contentItems: ImmutableList,
- ) : WalletStateHolder(onBackClick, topBarConfig, selectedWallet, wallets, contentItems)
+ override val notifications: ImmutableList,
+ ) : WalletStateHolder(onBackClick, topBarConfig, selectedWallet, wallets, contentItems, notifications)
}
\ No newline at end of file