Updated on 2026-08-14
This commit is contained in:
parent
bb7bef8ab7
commit
c4ec5774a3
5 changed files with 284 additions and 226 deletions
|
|
@ -1,112 +1,119 @@
|
|||
package com.tangem.core.ui.components.notifications
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.LocalIndication
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.semantics.Role
|
||||
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.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig.ButtonsState as NotificationButtonsState
|
||||
|
||||
/**
|
||||
* Notification component from Design system.
|
||||
* Use this for Notification with title, subtitle, clickable or not.
|
||||
*
|
||||
* @param state component state
|
||||
* @param config component config
|
||||
* @param modifier modifier
|
||||
* @param iconTint icon tint
|
||||
*
|
||||
* @see <a href = "https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?node-id=1045-807&t=6CVvYDJe0sB7wBKE-0"
|
||||
* >Figma component</a>
|
||||
*/
|
||||
@Composable
|
||||
fun Notification(state: NotificationState, modifier: Modifier = Modifier) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.clip(shape = RoundedCornerShape(size = TangemTheme.dimens.radius18))
|
||||
.background(
|
||||
color = TangemTheme.colors.button.secondary,
|
||||
shape = RoundedCornerShape(size = TangemTheme.dimens.radius18),
|
||||
)
|
||||
.clickable(
|
||||
enabled = when (state) {
|
||||
is NotificationState.Clickable -> true
|
||||
is NotificationState.Simple, is NotificationState.Closable -> false
|
||||
},
|
||||
onClick = if (state is NotificationState.Clickable) {
|
||||
state.onClick
|
||||
} else {
|
||||
{}
|
||||
},
|
||||
),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = TangemTheme.dimens.spacing12, vertical = TangemTheme.dimens.spacing8),
|
||||
fun Notification(config: NotificationConfig, modifier: Modifier = Modifier, iconTint: Color? = null) {
|
||||
BaseContainer(buttonsState = config.buttonsState, modifier = modifier) {
|
||||
Column(
|
||||
modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
|
||||
verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing12),
|
||||
) {
|
||||
NotificationIcon(
|
||||
iconResId = state.iconResId,
|
||||
iconTint = state.tint,
|
||||
modifier = Modifier
|
||||
.size(size = TangemTheme.dimens.size20)
|
||||
.align(alignment = Alignment.CenterStart),
|
||||
MainContent(
|
||||
iconResId = config.iconResId,
|
||||
iconTint = iconTint,
|
||||
title = config.title,
|
||||
subtitle = config.subtitle,
|
||||
)
|
||||
|
||||
NotificationInfoBlock(
|
||||
title = state.title.resolveReference(),
|
||||
subtitle = state.subtitle?.resolveReference(),
|
||||
modifier = Modifier.align(alignment = Alignment.CenterStart),
|
||||
)
|
||||
|
||||
if (state is NotificationState.Closable) {
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.size(size = TangemTheme.dimens.size20)
|
||||
.align(alignment = Alignment.TopEnd),
|
||||
painter = painterResource(id = R.drawable.ic_close_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
)
|
||||
}
|
||||
|
||||
if (state is NotificationState.Clickable) {
|
||||
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,
|
||||
)
|
||||
}
|
||||
Buttons(state = config.buttonsState)
|
||||
}
|
||||
|
||||
CloseableIconButton(
|
||||
onClick = config.onCloseClick,
|
||||
modifier = Modifier.align(alignment = Alignment.TopEnd),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NotificationIcon(@DrawableRes iconResId: Int, iconTint: Color?, modifier: Modifier = Modifier) {
|
||||
if (iconTint != null) {
|
||||
private fun BaseContainer(
|
||||
buttonsState: NotificationConfig.ButtonsState?,
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable BoxScope.() -> Unit,
|
||||
) {
|
||||
val containerColor by rememberUpdatedState(
|
||||
newValue = if (buttonsState != null) {
|
||||
TangemTheme.colors.background.primary
|
||||
} else {
|
||||
TangemTheme.colors.button.disabled
|
||||
},
|
||||
)
|
||||
|
||||
Surface(
|
||||
modifier = modifier
|
||||
.defaultMinSize(minHeight = TangemTheme.dimens.size62)
|
||||
.wrapContentWidth(),
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
color = containerColor,
|
||||
) {
|
||||
Box(content = content)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MainContent(iconResId: Int, iconTint: Color?, title: TextReference, subtitle: TextReference) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing10)) {
|
||||
Icon(
|
||||
iconResId = iconResId,
|
||||
tint = iconTint,
|
||||
modifier = Modifier.align(alignment = Alignment.CenterVertically),
|
||||
)
|
||||
|
||||
TextsBlock(title = title, subtitle = subtitle)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Icon(@DrawableRes iconResId: Int, tint: Color?, modifier: Modifier = Modifier) {
|
||||
if (tint != null) {
|
||||
Icon(
|
||||
painter = painterResource(id = iconResId),
|
||||
contentDescription = null,
|
||||
modifier = modifier,
|
||||
tint = iconTint,
|
||||
tint = tint,
|
||||
)
|
||||
} else {
|
||||
Image(
|
||||
|
|
@ -118,20 +125,107 @@ private fun NotificationIcon(@DrawableRes iconResId: Int, iconTint: Color?, modi
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun NotificationInfoBlock(title: String, subtitle: String?, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier.padding(horizontal = TangemTheme.dimens.spacing30)) {
|
||||
private fun TextsBlock(title: TextReference, subtitle: TextReference) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing2)) {
|
||||
Text(
|
||||
text = title,
|
||||
text = title.resolveReference(),
|
||||
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,
|
||||
Text(
|
||||
text = subtitle.resolveReference(),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.caption,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalAnimationApi::class)
|
||||
@Composable
|
||||
private fun Buttons(state: NotificationButtonsState?) {
|
||||
AnimatedContent(targetState = state, label = "Update the buttons content") { animatedState ->
|
||||
when (animatedState) {
|
||||
is NotificationButtonsState.SecondaryButtonConfig -> SingleSecondaryButton(config = animatedState)
|
||||
is NotificationButtonsState.PrimaryButtonConfig -> SinglePrimaryButton(config = animatedState)
|
||||
is NotificationButtonsState.PairButtonsConfig -> PairButtons(config = animatedState)
|
||||
null -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SingleSecondaryButton(config: NotificationButtonsState.SecondaryButtonConfig) {
|
||||
SecondaryButton(
|
||||
text = config.text.resolveReference(),
|
||||
onClick = config.onClick,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SinglePrimaryButton(config: NotificationButtonsState.PrimaryButtonConfig) {
|
||||
if (config.iconResId != null) {
|
||||
PrimaryButtonIconEnd(
|
||||
text = config.text.resolveReference(),
|
||||
iconResId = config.iconResId,
|
||||
onClick = config.onClick,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
} else {
|
||||
PrimaryButton(
|
||||
text = config.text.resolveReference(),
|
||||
onClick = config.onClick,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PairButtons(config: NotificationButtonsState.PairButtonsConfig) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing8)) {
|
||||
SecondaryButton(
|
||||
text = config.secondaryText.resolveReference(),
|
||||
onClick = config.onSecondaryClick,
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
)
|
||||
|
||||
PrimaryButton(
|
||||
text = config.primaryText.resolveReference(),
|
||||
onClick = config.onPrimaryClick,
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CloseableIconButton(onClick: (() -> Unit)?, modifier: Modifier = Modifier) {
|
||||
AnimatedVisibility(visible = onClick != null, modifier = modifier) {
|
||||
onClick ?: return@AnimatedVisibility
|
||||
|
||||
/*
|
||||
* Implement a custom ripple because the design layout doesn't match the Material Design.
|
||||
* Material Icon has a size 24x24 and Material IconButton has a size 48x48,
|
||||
* but icon from Figma has a size 16x16.
|
||||
*/
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(size = TangemTheme.dimens.size40)
|
||||
.clip(shape = CircleShape)
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = LocalIndication.current,
|
||||
role = Role.Button,
|
||||
onClick = onClick,
|
||||
),
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_close_24),
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.size(size = TangemTheme.dimens.size16)
|
||||
.align(alignment = Alignment.Center),
|
||||
tint = TangemTheme.colors.icon.inactive,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -139,72 +233,77 @@ private fun NotificationInfoBlock(title: String, subtitle: String?, modifier: Mo
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_WarningNotification_Light(
|
||||
@PreviewParameter(NotificationStateProvider::class)
|
||||
state: NotificationState,
|
||||
private fun Preview_Notification_Light(
|
||||
@PreviewParameter(NotificationConfigProvider::class)
|
||||
config: NotificationConfig,
|
||||
) {
|
||||
TangemTheme(isDark = false) {
|
||||
Notification(state)
|
||||
Notification(config)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_WarningNotification_Dark(
|
||||
@PreviewParameter(NotificationStateProvider::class)
|
||||
state: NotificationState,
|
||||
private fun Preview_Notification_Dark(
|
||||
@PreviewParameter(NotificationConfigProvider::class) config: NotificationConfig,
|
||||
) {
|
||||
TangemTheme(isDark = true) {
|
||||
Notification(state)
|
||||
Notification(config)
|
||||
}
|
||||
}
|
||||
|
||||
private class NotificationStateProvider : CollectionPreviewParameterProvider<NotificationState>(
|
||||
private class NotificationConfigProvider : CollectionPreviewParameterProvider<NotificationConfig>(
|
||||
collection = listOf(
|
||||
NotificationState.Simple(
|
||||
title = TextReference.Str(value = "Your wallet hasn’t been backed up"),
|
||||
NotificationConfig(
|
||||
title = TextReference.Str(value = "Development card"),
|
||||
subtitle = TextReference.Str(
|
||||
value = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " +
|
||||
"ut labore et...",
|
||||
value = "The card you scanned is a development card.\nDon’t accept it as a payment.",
|
||||
),
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
),
|
||||
NotificationConfig(
|
||||
title = TextReference.Str(value = "Some networks are unreachable"),
|
||||
subtitle = TextReference.Str(value = "Check your network connection"),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
),
|
||||
NotificationState.Simple(
|
||||
title = TextReference.Str("Your wallet hasn’t been backed up"),
|
||||
subtitle = null,
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
tint = TangemColorPalette.Amaranth,
|
||||
),
|
||||
NotificationState.Clickable(
|
||||
NotificationConfig(
|
||||
title = TextReference.Str(value = "Your wallet hasn’t been backed up"),
|
||||
subtitle = TextReference.Str(
|
||||
value = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " +
|
||||
"ut labore et...",
|
||||
),
|
||||
subtitle = TextReference.Str(value = "To protect your assets, we advise you to carry out this procedure"),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
onClick = {},
|
||||
),
|
||||
NotificationState.Clickable(
|
||||
title = TextReference.Str(value = "Your wallet hasn’t been backed up"),
|
||||
subtitle = null,
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
tint = TangemColorPalette.Amaranth,
|
||||
onClick = {},
|
||||
),
|
||||
NotificationState.Closable(
|
||||
title = TextReference.Str(value = "Your wallet hasn’t been backed up"),
|
||||
subtitle = TextReference.Str(
|
||||
value = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt " +
|
||||
"ut labore et...",
|
||||
buttonsState = NotificationButtonsState.SecondaryButtonConfig(
|
||||
text = TextReference.Str(value = "Start backup process"),
|
||||
onClick = {},
|
||||
),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
onCloseClick = {},
|
||||
),
|
||||
NotificationState.Closable(
|
||||
title = TextReference.Str(value = "Your wallet hasn’t been backed up"),
|
||||
subtitle = null,
|
||||
NotificationConfig(
|
||||
title = TextReference.Str(value = "Some addresses are missing"),
|
||||
subtitle = TextReference.Str(value = "Generate addresses for 2 new networks using your card"),
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
tint = TangemColorPalette.Amaranth,
|
||||
buttonsState = NotificationButtonsState.PrimaryButtonConfig(
|
||||
text = TextReference.Str(value = "Generate addresses"),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
onClick = {},
|
||||
),
|
||||
),
|
||||
NotificationConfig(
|
||||
title = TextReference.Str(value = "Rate the app"),
|
||||
subtitle = TextReference.Str(value = "How do you like Tangem?"),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
buttonsState = NotificationButtonsState.PairButtonsConfig(
|
||||
primaryText = TextReference.Str(value = "Love it!"),
|
||||
onPrimaryClick = {},
|
||||
secondaryText = TextReference.Str(value = "Can be better"),
|
||||
onSecondaryClick = {},
|
||||
),
|
||||
),
|
||||
NotificationConfig(
|
||||
title = TextReference.Str(value = "Note top up"),
|
||||
subtitle = TextReference.Str(value = "To activate card top up it with at least 1 XLM"),
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
buttonsState = NotificationButtonsState.SecondaryButtonConfig(
|
||||
text = TextReference.Str(value = "Top up card"),
|
||||
onClick = {},
|
||||
),
|
||||
onCloseClick = {},
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
package com.tangem.core.ui.components.notifications
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
/**
|
||||
* Notification component state
|
||||
*
|
||||
* @property title title
|
||||
* @property subtitle subtitle
|
||||
* @property iconResId icon resource id
|
||||
* @property buttonsState buttons state
|
||||
* @property onCloseClick lambda be invoked when close button is clicked
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
data class NotificationConfig(
|
||||
val title: TextReference,
|
||||
val subtitle: TextReference,
|
||||
@DrawableRes val iconResId: Int,
|
||||
val buttonsState: ButtonsState? = null,
|
||||
val onCloseClick: (() -> Unit)? = null,
|
||||
) {
|
||||
|
||||
sealed class ButtonsState {
|
||||
|
||||
data class PrimaryButtonConfig(
|
||||
val text: TextReference,
|
||||
@DrawableRes val iconResId: Int? = null,
|
||||
val onClick: () -> Unit,
|
||||
) : ButtonsState()
|
||||
|
||||
data class SecondaryButtonConfig(val text: TextReference, val onClick: () -> Unit) : ButtonsState()
|
||||
|
||||
data class PairButtonsConfig(
|
||||
val primaryText: TextReference,
|
||||
val onPrimaryClick: () -> Unit,
|
||||
val secondaryText: TextReference,
|
||||
val onSecondaryClick: () -> Unit,
|
||||
) : ButtonsState()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
package com.tangem.core.ui.components.notifications
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
/**
|
||||
* 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: TextReference,
|
||||
open val subtitle: TextReference? = 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: TextReference,
|
||||
override val subtitle: TextReference? = 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
|
||||
* @property onClick lambda be invoked when notification component is clicked
|
||||
*/
|
||||
data class Clickable(
|
||||
override val title: TextReference,
|
||||
override val subtitle: TextReference? = null,
|
||||
@DrawableRes override val iconResId: Int,
|
||||
override val tint: Color? = null,
|
||||
val onClick: () -> Unit,
|
||||
) : NotificationState(title, subtitle, iconResId, tint)
|
||||
|
||||
/**
|
||||
* Closable notification state
|
||||
*
|
||||
* @property title title
|
||||
* @property subtitle subtitle
|
||||
* @property iconResId icon resource id
|
||||
* @property tint icon tint
|
||||
* @property onCloseClick lambda be invoked when close button is clicked
|
||||
*/
|
||||
data class Closable(
|
||||
override val title: TextReference,
|
||||
override val subtitle: TextReference? = null,
|
||||
@DrawableRes override val iconResId: Int,
|
||||
override val tint: Color? = null,
|
||||
val onCloseClick: (() -> Unit)? = null,
|
||||
) : NotificationState(title, subtitle, iconResId, tint)
|
||||
}
|
||||
|
|
@ -1,22 +1,21 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.components
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.components.notifications.NotificationState
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.WrappedList
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
|
||||
/**
|
||||
* Wallet notification component state
|
||||
*
|
||||
* @property state state
|
||||
* @property config state
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
// TODO: Finalize notification strings [REDACTED_JIRA]
|
||||
@Immutable
|
||||
sealed class WalletNotification(open val state: NotificationState) {
|
||||
sealed class WalletNotification(open val config: NotificationConfig) {
|
||||
|
||||
/** Clickable notification */
|
||||
sealed interface Clickable {
|
||||
|
|
@ -27,41 +26,37 @@ sealed class WalletNotification(open val state: NotificationState) {
|
|||
|
||||
/** "Development card" notification */
|
||||
object DevCard : WalletNotification(
|
||||
state = NotificationState.Simple(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Res(id = R.string.common_warning),
|
||||
subtitle = TextReference.Res(id = R.string.alert_developer_card),
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
tint = TangemColorPalette.Amaranth,
|
||||
),
|
||||
)
|
||||
|
||||
/** "Test card" notification */
|
||||
object TestCard : WalletNotification(
|
||||
state = NotificationState.Simple(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Res(id = R.string.common_warning),
|
||||
subtitle = TextReference.Res(id = R.string.warning_testnet_card_message),
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
tint = TangemColorPalette.Amaranth,
|
||||
),
|
||||
)
|
||||
|
||||
/** "Demo card" notification */
|
||||
object DemoCard : WalletNotification(
|
||||
state = NotificationState.Simple(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Res(id = R.string.common_warning),
|
||||
subtitle = TextReference.Res(id = R.string.alert_demo_message),
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
tint = TangemColorPalette.Amaranth,
|
||||
),
|
||||
)
|
||||
|
||||
/** "Card verification failed" notification */
|
||||
object CardVerificationFailed : WalletNotification(
|
||||
state = NotificationState.Simple(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Res(id = R.string.warning_failed_to_verify_card_title),
|
||||
subtitle = TextReference.Res(id = R.string.warning_failed_to_verify_card_message),
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
tint = TangemColorPalette.Amaranth,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -71,14 +66,13 @@ sealed class WalletNotification(open val state: NotificationState) {
|
|||
* @param count number of remaining signatures
|
||||
*/
|
||||
class RemainingSignaturesLeft(count: Int) : WalletNotification(
|
||||
state = NotificationState.Simple(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Res(id = R.string.common_warning),
|
||||
subtitle = TextReference.Res(
|
||||
id = R.string.warning_low_signatures_format,
|
||||
formatArgs = WrappedList(data = listOf(count)),
|
||||
),
|
||||
iconResId = R.drawable.ic_alert_circle_24,
|
||||
tint = TangemColorPalette.Amaranth,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -88,11 +82,10 @@ sealed class WalletNotification(open val state: NotificationState) {
|
|||
* @property onClick lambda be invoked when notification's close button is clicked
|
||||
*/
|
||||
data class WarningAlreadySignedHashes(override val onClick: () -> Unit) : Clickable, WalletNotification(
|
||||
state = NotificationState.Closable(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Res(id = R.string.common_warning),
|
||||
subtitle = TextReference.Res(id = R.string.alert_card_signed_transactions),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
tint = null,
|
||||
onCloseClick = onClick,
|
||||
),
|
||||
)
|
||||
|
|
@ -103,15 +96,13 @@ sealed class WalletNotification(open val state: NotificationState) {
|
|||
* @property onClick lambda be invoked when notification is clicked
|
||||
*/
|
||||
data class CriticalWarningAlreadySignedHashes(override val onClick: () -> Unit) : Clickable, WalletNotification(
|
||||
state = NotificationState.Clickable(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Res(
|
||||
id = R.string.warning_important_security_info,
|
||||
formatArgs = WrappedList(listOf("\u26A0")),
|
||||
),
|
||||
subtitle = TextReference.Res(id = R.string.warning_signed_tx_previously),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
onClick = onClick,
|
||||
tint = null,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -121,20 +112,19 @@ sealed class WalletNotification(open val state: NotificationState) {
|
|||
* @property onClick lambda be invoked when notification is clicked
|
||||
*/
|
||||
data class BackupCard(override val onClick: () -> Unit) : Clickable, WalletNotification(
|
||||
state = NotificationState.Clickable(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Str(value = "Backup your card"),
|
||||
subtitle = TextReference.Str(value = ""),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
onClick = onClick,
|
||||
tint = null,
|
||||
),
|
||||
)
|
||||
|
||||
/** "Unreachable networks" notification */
|
||||
object UnreachableNetworks : WalletNotification(
|
||||
state = NotificationState.Simple(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Str(value = "Some networks are unreachable"),
|
||||
subtitle = TextReference.Str(value = ""),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
tint = null,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -144,11 +134,10 @@ sealed class WalletNotification(open val state: NotificationState) {
|
|||
* @property onClick lambda be invoked when notification is clicked
|
||||
*/
|
||||
data class LikeTangemApp(override val onClick: () -> Unit) : Clickable, WalletNotification(
|
||||
state = NotificationState.Clickable(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Str(value = "Like Tangem App?"),
|
||||
subtitle = TextReference.Str(value = ""),
|
||||
iconResId = R.drawable.ic_star_24,
|
||||
onClick = onClick,
|
||||
tint = TangemColorPalette.Tangerine,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -158,10 +147,10 @@ sealed class WalletNotification(open val state: NotificationState) {
|
|||
* @property onClick lambda be invoked when notification is clicked
|
||||
*/
|
||||
data class ScanCard(override val onClick: () -> Unit) : Clickable, WalletNotification(
|
||||
state = NotificationState.Clickable(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Str(value = "Scan your card to continue"),
|
||||
subtitle = TextReference.Str(value = ""),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
onClick = onClick,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -171,10 +160,10 @@ sealed class WalletNotification(open val state: NotificationState) {
|
|||
* @property onClick lambda be invoked when notification is clicked
|
||||
*/
|
||||
data class UnlockWallets(override val onClick: () -> Unit) : Clickable, WalletNotification(
|
||||
state = NotificationState.Clickable(
|
||||
config = NotificationConfig(
|
||||
title = TextReference.Str(value = "Unlock needed"),
|
||||
subtitle = TextReference.Str(value = ""),
|
||||
iconResId = R.drawable.ic_locked_24,
|
||||
onClick = onClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -20,8 +20,8 @@ import kotlinx.collections.immutable.ImmutableList
|
|||
internal fun LazyListScope.notifications(configs: ImmutableList<WalletNotification>, modifier: Modifier = Modifier) {
|
||||
items(
|
||||
items = configs,
|
||||
key = { it.state.title.hashCode() },
|
||||
contentType = { it.state::class.java },
|
||||
itemContent = { Notification(state = it.state, modifier = modifier.animateItemPlacement()) },
|
||||
key = { it.config.title.hashCode() },
|
||||
contentType = { it.config::class.java },
|
||||
itemContent = { Notification(config = it.config, modifier = modifier.animateItemPlacement()) },
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue