Updated on 2026-08-14
This commit is contained in:
parent
646349ff69
commit
f467cbacd0
14 changed files with 786 additions and 310 deletions
|
|
@ -1,305 +1,23 @@
|
|||
package com.tangem.core.ui.components.bottomsheets.message
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.fastForEach
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUM.Button.IconOrder
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButton
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
|
||||
import com.tangem.core.ui.components.icons.HighlightedIcon
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveAnnotatedReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.WarningBottomSheetTestTags
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import com.tangem.core.ui.res.LocalRedesignEnabled
|
||||
|
||||
@Composable
|
||||
fun MessageBottomSheet(state: MessageBottomSheetUM, onDismissRequest: () -> Unit) {
|
||||
val stateWithOnDismiss = remember(state) {
|
||||
state.copy(
|
||||
onDismissRequest = {
|
||||
state.onDismissRequest.invoke()
|
||||
onDismissRequest()
|
||||
},
|
||||
)
|
||||
if (LocalRedesignEnabled.current) {
|
||||
MessageBottomSheetV2(state, onDismissRequest)
|
||||
} else {
|
||||
MessageBottomSheetV1(state, onDismissRequest)
|
||||
}
|
||||
|
||||
val config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
content = stateWithOnDismiss,
|
||||
onDismissRequest = stateWithOnDismiss.onDismissRequest,
|
||||
)
|
||||
|
||||
TangemModalBottomSheet(
|
||||
config = config,
|
||||
title = {
|
||||
TangemModalBottomSheetTitle(
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = stateWithOnDismiss.onDismissRequest,
|
||||
)
|
||||
},
|
||||
content = { content: MessageBottomSheetUM -> MessageBottomSheetContent(content) },
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MessageBottomSheetContent(state: MessageBottomSheetUM, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
state.elements.fastForEach { element ->
|
||||
when (element) {
|
||||
is MessageBottomSheetUM.InfoBlock -> {
|
||||
ContentContainer(
|
||||
modifier = Modifier
|
||||
.heightIn(min = TangemTheme.dimens.size180)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.padding(bottom = 32.dp),
|
||||
state = element,
|
||||
)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
ButtonsContainer(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
closeScope = state.closeScope,
|
||||
buttons = state.elements.filterIsInstance<MessageBottomSheetUM.Button>().toPersistentList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ContentContainer(state: MessageBottomSheetUM.InfoBlock, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
BottomSheetIconContainer(state.icon, state.iconImage)
|
||||
state.title?.let { title ->
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = TangemTheme.dimens.spacing24)
|
||||
.testTag(WarningBottomSheetTestTags.TITLE),
|
||||
text = title.resolveReference(),
|
||||
style = TangemTheme.typography.h3,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
state.body?.let { body ->
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = TangemTheme.dimens.spacing8)
|
||||
.testTag(WarningBottomSheetTestTags.MESSAGE),
|
||||
text = body.resolveAnnotatedReference(),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
state.chip?.let { chip ->
|
||||
BottomSheetChip(
|
||||
modifier = Modifier.padding(top = TangemTheme.dimens.spacing16),
|
||||
chip = chip,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomSheetIconContainer(
|
||||
icon: MessageBottomSheetUM.Icon?,
|
||||
iconImage: MessageBottomSheetUM.IconImage?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
if (icon != null) {
|
||||
BottomSheetIcon(icon, modifier)
|
||||
} else if (iconImage != null) {
|
||||
Image(
|
||||
modifier = modifier
|
||||
.size(TangemTheme.dimens.size56)
|
||||
.clip(CircleShape),
|
||||
painter = painterResource(id = iconImage.res),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomSheetIcon(icon: MessageBottomSheetUM.Icon, modifier: Modifier = Modifier) {
|
||||
val tint = when (icon.type) {
|
||||
MessageBottomSheetUM.Icon.Type.Unspecified -> Color.Unspecified
|
||||
MessageBottomSheetUM.Icon.Type.Accent -> TangemTheme.colors.icon.accent
|
||||
MessageBottomSheetUM.Icon.Type.Informative -> TangemTheme.colors.icon.informative
|
||||
MessageBottomSheetUM.Icon.Type.Attention -> TangemTheme.colors.icon.attention
|
||||
MessageBottomSheetUM.Icon.Type.Warning -> TangemTheme.colors.icon.warning
|
||||
}
|
||||
|
||||
val backgroundColor = when (icon.backgroundType) {
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Unspecified -> TangemTheme.colors.icon.informative
|
||||
MessageBottomSheetUM.Icon.BackgroundType.SameAsTint -> tint
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Accent -> TangemTheme.colors.icon.accent
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Informative -> TangemTheme.colors.icon.informative
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Attention -> TangemTheme.colors.icon.attention
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Warning -> TangemTheme.colors.icon.warning
|
||||
}
|
||||
|
||||
HighlightedIcon(
|
||||
modifier = modifier,
|
||||
icon = icon.res,
|
||||
iconTint = tint,
|
||||
backgroundColor = backgroundColor,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomSheetChip(chip: MessageBottomSheetUM.Chip, modifier: Modifier = Modifier) {
|
||||
val color = when (chip.type) {
|
||||
MessageBottomSheetUM.Chip.Type.Unspecified -> TangemTheme.colors.text.primary1
|
||||
MessageBottomSheetUM.Chip.Type.Warning -> TangemTheme.colors.text.warning
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = modifier
|
||||
.background(
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius16),
|
||||
color = color.copy(alpha = 0.1F),
|
||||
)
|
||||
.padding(vertical = TangemTheme.dimens.spacing4, horizontal = TangemTheme.dimens.spacing12),
|
||||
text = chip.text.resolveReference(),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun ButtonsContainer(
|
||||
buttons: ImmutableList<MessageBottomSheetUM.Button>,
|
||||
closeScope: MessageBottomSheetUM.CloseScope,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.padding(all = TangemTheme.dimens.spacing16),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
buttons.fastForEach { button ->
|
||||
val icon = button.icon?.let { iconResId ->
|
||||
when (button.iconOrder) {
|
||||
IconOrder.Start -> TangemButtonIconPosition.Start(iconResId)
|
||||
IconOrder.End -> TangemButtonIconPosition.End(iconResId)
|
||||
}
|
||||
} ?: TangemButtonIconPosition.None
|
||||
|
||||
TangemButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag(
|
||||
if (button.isPrimary) {
|
||||
WarningBottomSheetTestTags.BUTTON_PRIMARY
|
||||
} else {
|
||||
WarningBottomSheetTestTags.BUTTON_SECONDARY
|
||||
},
|
||||
),
|
||||
text = button.text?.resolveReference().orEmpty(),
|
||||
icon = icon,
|
||||
onClick = { button.onClick?.invoke(closeScope) },
|
||||
colors = if (button.isPrimary) {
|
||||
TangemButtonsDefaults.primaryButtonColors
|
||||
} else {
|
||||
TangemButtonsDefaults.secondaryButtonColors
|
||||
},
|
||||
enabled = true,
|
||||
showProgress = false,
|
||||
textStyle = TangemTheme.typography.subtitle1,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
TangemThemePreview {
|
||||
MessageBottomSheet(
|
||||
messageBottomSheetUM {
|
||||
infoBlock {
|
||||
icon(R.drawable.img_knight_shield_32) {
|
||||
type = MessageBottomSheetUM.Icon.Type.Attention
|
||||
backgroundType = MessageBottomSheetUM.Icon.BackgroundType.SameAsTint
|
||||
}
|
||||
title = TextReference.Str("Title Title Title")
|
||||
body = TextReference.Str("Body")
|
||||
chip(text = TextReference.Str("Some chip information"))
|
||||
}
|
||||
primaryButton {
|
||||
text = TextReference.Str("Test")
|
||||
icon = R.drawable.ic_tangem_24
|
||||
}
|
||||
secondaryButton {
|
||||
icon = R.drawable.ic_tangem_24
|
||||
text = TextReference.Str("asdasd")
|
||||
onClick {
|
||||
closeBs()
|
||||
}
|
||||
}
|
||||
},
|
||||
onDismissRequest = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun Preview2() {
|
||||
TangemThemePreview {
|
||||
MessageBottomSheet(
|
||||
messageBottomSheetUM {
|
||||
infoBlock {
|
||||
iconImage = MessageBottomSheetUM.IconImage(R.drawable.img_visa_notification)
|
||||
title = TextReference.Str("Title Title Title")
|
||||
body = TextReference.Str("Body")
|
||||
chip(text = TextReference.Str("Some chip information"))
|
||||
}
|
||||
primaryButton {
|
||||
text = TextReference.Str("Test")
|
||||
icon = R.drawable.ic_tangem_24
|
||||
}
|
||||
secondaryButton {
|
||||
icon = R.drawable.ic_tangem_24
|
||||
text = TextReference.Str("asdasd")
|
||||
onClick {
|
||||
closeBs()
|
||||
}
|
||||
}
|
||||
},
|
||||
onDismissRequest = {},
|
||||
)
|
||||
if (LocalRedesignEnabled.current) {
|
||||
MessageBottomSheetContentV2(state, modifier)
|
||||
} else {
|
||||
MessageBottomSheetContentV1(state, modifier)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.core.ui.components.bottomsheets.message
|
|||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
|
@ -41,6 +42,21 @@ data class MessageBottomSheetUM(
|
|||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
data class Vector(
|
||||
val imageVector: ImageVector,
|
||||
var type: Type = Type.Unspecified,
|
||||
var backgroundType: BackgroundType = BackgroundType.Unspecified,
|
||||
) : Element {
|
||||
enum class Type {
|
||||
Unspecified, Accent, Informative, Attention, Warning,
|
||||
}
|
||||
|
||||
enum class BackgroundType {
|
||||
Unspecified, SameAsTint, Accent, Informative, Attention, Warning,
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
data class IconImage(@DrawableRes internal var res: Int) : Element
|
||||
|
||||
|
|
@ -58,6 +74,7 @@ data class MessageBottomSheetUM(
|
|||
data class InfoBlock(
|
||||
internal var icon: Icon? = null,
|
||||
internal var iconImage: IconImage? = null,
|
||||
internal var vector: Vector? = null,
|
||||
internal var chip: Chip? = null,
|
||||
var title: TextReference? = null,
|
||||
var body: TextReference? = null,
|
||||
|
|
@ -111,6 +128,12 @@ fun MessageBottomSheetUM.InfoBlock.icon(@DrawableRes res: Int, init: MessageBott
|
|||
icon = MessageBottomSheetUM.Icon(res).apply(init)
|
||||
}
|
||||
|
||||
@Suppress("NestedScopeFunctions")
|
||||
fun MessageBottomSheetUM.InfoBlock.vector(imageVector: ImageVector, init: MessageBottomSheetUM.Vector.() -> Unit = {}) =
|
||||
apply {
|
||||
vector = MessageBottomSheetUM.Vector(imageVector).apply(init)
|
||||
}
|
||||
|
||||
fun MessageBottomSheetUM.InfoBlock.iconImage(@DrawableRes res: Int) = apply {
|
||||
iconImage = MessageBottomSheetUM.IconImage(res)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,305 @@
|
|||
package com.tangem.core.ui.components.bottomsheets.message
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.fastForEach
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUM.Button.IconOrder
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButton
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
|
||||
import com.tangem.core.ui.components.icons.HighlightedIcon
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveAnnotatedReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.WarningBottomSheetTestTags
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
||||
@Composable
|
||||
fun MessageBottomSheetV1(state: MessageBottomSheetUM, onDismissRequest: () -> Unit) {
|
||||
val stateWithOnDismiss = remember(state) {
|
||||
state.copy(
|
||||
onDismissRequest = {
|
||||
state.onDismissRequest.invoke()
|
||||
onDismissRequest()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
val config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
content = stateWithOnDismiss,
|
||||
onDismissRequest = stateWithOnDismiss.onDismissRequest,
|
||||
)
|
||||
|
||||
TangemModalBottomSheet(
|
||||
config = config,
|
||||
title = {
|
||||
TangemModalBottomSheetTitle(
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = stateWithOnDismiss.onDismissRequest,
|
||||
)
|
||||
},
|
||||
content = { content: MessageBottomSheetUM -> MessageBottomSheetContent(content) },
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MessageBottomSheetContentV1(state: MessageBottomSheetUM, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
state.elements.fastForEach { element ->
|
||||
when (element) {
|
||||
is MessageBottomSheetUM.InfoBlock -> {
|
||||
ContentContainer(
|
||||
modifier = Modifier
|
||||
.heightIn(min = TangemTheme.dimens.size180)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.padding(bottom = 32.dp),
|
||||
state = element,
|
||||
)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
ButtonsContainer(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
closeScope = state.closeScope,
|
||||
buttons = state.elements.filterIsInstance<MessageBottomSheetUM.Button>().toPersistentList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ContentContainer(state: MessageBottomSheetUM.InfoBlock, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
BottomSheetIconContainer(state.icon, state.iconImage)
|
||||
state.title?.let { title ->
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = TangemTheme.dimens.spacing24)
|
||||
.testTag(WarningBottomSheetTestTags.TITLE),
|
||||
text = title.resolveReference(),
|
||||
style = TangemTheme.typography.h3,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
state.body?.let { body ->
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = TangemTheme.dimens.spacing8)
|
||||
.testTag(WarningBottomSheetTestTags.MESSAGE),
|
||||
text = body.resolveAnnotatedReference(),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
state.chip?.let { chip ->
|
||||
BottomSheetChip(
|
||||
modifier = Modifier.padding(top = TangemTheme.dimens.spacing16),
|
||||
chip = chip,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomSheetIconContainer(
|
||||
icon: MessageBottomSheetUM.Icon?,
|
||||
iconImage: MessageBottomSheetUM.IconImage?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
if (icon != null) {
|
||||
BottomSheetIcon(icon, modifier)
|
||||
} else if (iconImage != null) {
|
||||
Image(
|
||||
modifier = modifier
|
||||
.size(TangemTheme.dimens.size56)
|
||||
.clip(CircleShape),
|
||||
painter = painterResource(id = iconImage.res),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomSheetIcon(icon: MessageBottomSheetUM.Icon, modifier: Modifier = Modifier) {
|
||||
val tint = when (icon.type) {
|
||||
MessageBottomSheetUM.Icon.Type.Unspecified -> Color.Unspecified
|
||||
MessageBottomSheetUM.Icon.Type.Accent -> TangemTheme.colors.icon.accent
|
||||
MessageBottomSheetUM.Icon.Type.Informative -> TangemTheme.colors.icon.informative
|
||||
MessageBottomSheetUM.Icon.Type.Attention -> TangemTheme.colors.icon.attention
|
||||
MessageBottomSheetUM.Icon.Type.Warning -> TangemTheme.colors.icon.warning
|
||||
}
|
||||
|
||||
val backgroundColor = when (icon.backgroundType) {
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Unspecified -> TangemTheme.colors.icon.informative
|
||||
MessageBottomSheetUM.Icon.BackgroundType.SameAsTint -> tint
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Accent -> TangemTheme.colors.icon.accent
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Informative -> TangemTheme.colors.icon.informative
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Attention -> TangemTheme.colors.icon.attention
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Warning -> TangemTheme.colors.icon.warning
|
||||
}
|
||||
|
||||
HighlightedIcon(
|
||||
modifier = modifier,
|
||||
icon = icon.res,
|
||||
iconTint = tint,
|
||||
backgroundColor = backgroundColor,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomSheetChip(chip: MessageBottomSheetUM.Chip, modifier: Modifier = Modifier) {
|
||||
val color = when (chip.type) {
|
||||
MessageBottomSheetUM.Chip.Type.Unspecified -> TangemTheme.colors.text.primary1
|
||||
MessageBottomSheetUM.Chip.Type.Warning -> TangemTheme.colors.text.warning
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = modifier
|
||||
.background(
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius16),
|
||||
color = color.copy(alpha = 0.1F),
|
||||
)
|
||||
.padding(vertical = TangemTheme.dimens.spacing4, horizontal = TangemTheme.dimens.spacing12),
|
||||
text = chip.text.resolveReference(),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun ButtonsContainer(
|
||||
buttons: ImmutableList<MessageBottomSheetUM.Button>,
|
||||
closeScope: MessageBottomSheetUM.CloseScope,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.padding(all = TangemTheme.dimens.spacing16),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
buttons.fastForEach { button ->
|
||||
val icon = button.icon?.let { iconResId ->
|
||||
when (button.iconOrder) {
|
||||
IconOrder.Start -> TangemButtonIconPosition.Start(iconResId)
|
||||
IconOrder.End -> TangemButtonIconPosition.End(iconResId)
|
||||
}
|
||||
} ?: TangemButtonIconPosition.None
|
||||
|
||||
TangemButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag(
|
||||
if (button.isPrimary) {
|
||||
WarningBottomSheetTestTags.BUTTON_PRIMARY
|
||||
} else {
|
||||
WarningBottomSheetTestTags.BUTTON_SECONDARY
|
||||
},
|
||||
),
|
||||
text = button.text?.resolveReference().orEmpty(),
|
||||
icon = icon,
|
||||
onClick = { button.onClick?.invoke(closeScope) },
|
||||
colors = if (button.isPrimary) {
|
||||
TangemButtonsDefaults.primaryButtonColors
|
||||
} else {
|
||||
TangemButtonsDefaults.secondaryButtonColors
|
||||
},
|
||||
enabled = true,
|
||||
showProgress = false,
|
||||
textStyle = TangemTheme.typography.subtitle1,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
TangemThemePreview {
|
||||
MessageBottomSheet(
|
||||
messageBottomSheetUM {
|
||||
infoBlock {
|
||||
icon(R.drawable.img_knight_shield_32) {
|
||||
type = MessageBottomSheetUM.Icon.Type.Attention
|
||||
backgroundType = MessageBottomSheetUM.Icon.BackgroundType.SameAsTint
|
||||
}
|
||||
title = TextReference.Str("Title Title Title")
|
||||
body = TextReference.Str("Body")
|
||||
chip(text = TextReference.Str("Some chip information"))
|
||||
}
|
||||
primaryButton {
|
||||
text = TextReference.Str("Test")
|
||||
icon = R.drawable.ic_tangem_24
|
||||
}
|
||||
secondaryButton {
|
||||
icon = R.drawable.ic_tangem_24
|
||||
text = TextReference.Str("asdasd")
|
||||
onClick {
|
||||
closeBs()
|
||||
}
|
||||
}
|
||||
},
|
||||
onDismissRequest = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun Preview2() {
|
||||
TangemThemePreview {
|
||||
MessageBottomSheetV1(
|
||||
messageBottomSheetUM {
|
||||
infoBlock {
|
||||
iconImage = MessageBottomSheetUM.IconImage(R.drawable.img_visa_notification)
|
||||
title = TextReference.Str("Title Title Title")
|
||||
body = TextReference.Str("Body")
|
||||
chip(text = TextReference.Str("Some chip information"))
|
||||
}
|
||||
primaryButton {
|
||||
text = TextReference.Str("Test")
|
||||
icon = R.drawable.ic_tangem_24
|
||||
}
|
||||
secondaryButton {
|
||||
icon = R.drawable.ic_tangem_24
|
||||
text = TextReference.Str("asdasd")
|
||||
onClick {
|
||||
closeBs()
|
||||
}
|
||||
}
|
||||
},
|
||||
onDismissRequest = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,369 @@
|
|||
package com.tangem.core.ui.components.bottomsheets.message
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.fastForEach
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetType
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
import com.tangem.core.ui.ds.topbar.TangemTopBar
|
||||
import com.tangem.core.ui.ds.topbar.TangemTopBarType
|
||||
import com.tangem.core.ui.ds2.button.TangemButton
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveAnnotatedReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.ui.test.WarningBottomSheetTestTags
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
||||
@Composable
|
||||
fun MessageBottomSheetV2(state: MessageBottomSheetUM, onDismissRequest: () -> Unit) {
|
||||
val stateWithOnDismiss = remember(state) {
|
||||
state.copy(
|
||||
onDismissRequest = {
|
||||
state.onDismissRequest.invoke()
|
||||
onDismissRequest()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
val config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
content = stateWithOnDismiss,
|
||||
onDismissRequest = stateWithOnDismiss.onDismissRequest,
|
||||
)
|
||||
|
||||
TangemBottomSheet(
|
||||
config = config,
|
||||
type = TangemBottomSheetType.Modal,
|
||||
containerColor = TangemTheme.colors3.bg.secondary,
|
||||
title = {
|
||||
TangemTopBar(
|
||||
type = TangemTopBarType.BottomSheet,
|
||||
endContent = {
|
||||
TangemButton(
|
||||
iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_24),
|
||||
onClick = stateWithOnDismiss.onDismissRequest,
|
||||
size = TangemButton.Size.X11,
|
||||
variant = TangemButton.Variant.Material,
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
content = { content: MessageBottomSheetUM ->
|
||||
MessageBottomSheetContent(
|
||||
modifier = Modifier.padding(vertical = TangemTheme.dimens2.x4),
|
||||
state = content,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MessageBottomSheetContentV2(state: MessageBottomSheetUM, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
state.elements.fastForEach { element ->
|
||||
when (element) {
|
||||
is MessageBottomSheetUM.InfoBlock -> {
|
||||
ContentContainer(
|
||||
modifier = Modifier
|
||||
.heightIn(min = TangemTheme.dimens.size180)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.padding(bottom = 32.dp),
|
||||
state = element,
|
||||
)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
ButtonsContainer(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
closeScope = state.closeScope,
|
||||
buttons = state.elements.filterIsInstance<MessageBottomSheetUM.Button>().toPersistentList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ContentContainer(state: MessageBottomSheetUM.InfoBlock, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
BottomSheetIconContainer(state.icon, state.iconImage, state.vector)
|
||||
state.title?.let { title ->
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = TangemTheme.dimens2.x8)
|
||||
.testTag(WarningBottomSheetTestTags.TITLE),
|
||||
text = title.resolveReference(),
|
||||
style = TangemTheme.typography3.heading.small,
|
||||
color = TangemTheme.colors3.text.primary,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
state.body?.let { body ->
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = TangemTheme.dimens2.x2)
|
||||
.testTag(WarningBottomSheetTestTags.MESSAGE),
|
||||
text = body.resolveAnnotatedReference(),
|
||||
style = TangemTheme.typography3.subheading.medium,
|
||||
color = TangemTheme.colors3.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
state.chip?.let { chip ->
|
||||
BottomSheetChip(
|
||||
modifier = Modifier.padding(top = TangemTheme.dimens2.x4),
|
||||
chip = chip,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomSheetIconContainer(
|
||||
icon: MessageBottomSheetUM.Icon?,
|
||||
iconImage: MessageBottomSheetUM.IconImage?,
|
||||
vector: MessageBottomSheetUM.Vector?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
if (icon != null) {
|
||||
BottomSheetIcon(icon, modifier)
|
||||
} else if (iconImage != null) {
|
||||
Image(
|
||||
modifier = modifier
|
||||
.size(TangemTheme.dimens2.x20)
|
||||
.clip(CircleShape),
|
||||
painter = painterResource(id = iconImage.res),
|
||||
contentDescription = null,
|
||||
)
|
||||
} else if (vector != null) {
|
||||
BottomSheetVector(vector, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomSheetIcon(icon: MessageBottomSheetUM.Icon, modifier: Modifier = Modifier) {
|
||||
val tint = when (icon.type) {
|
||||
MessageBottomSheetUM.Icon.Type.Unspecified -> Color.Unspecified
|
||||
MessageBottomSheetUM.Icon.Type.Accent -> TangemTheme.colors3.icon.status.info
|
||||
MessageBottomSheetUM.Icon.Type.Informative -> TangemTheme.colors3.icon.status.info
|
||||
MessageBottomSheetUM.Icon.Type.Attention -> TangemTheme.colors3.icon.status.warning
|
||||
MessageBottomSheetUM.Icon.Type.Warning -> TangemTheme.colors3.icon.status.error
|
||||
}
|
||||
|
||||
val backgroundColor = when (icon.backgroundType) {
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Unspecified -> Color.Unspecified
|
||||
MessageBottomSheetUM.Icon.BackgroundType.SameAsTint -> tint
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Accent -> TangemTheme.colors3.bg.status.infoSubtle
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Informative -> TangemTheme.colors3.bg.status.infoSubtle
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Attention -> TangemTheme.colors3.bg.status.warningSubtle
|
||||
MessageBottomSheetUM.Icon.BackgroundType.Warning -> TangemTheme.colors3.bg.status.errorSubtle
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(TangemTheme.dimens2.x20)
|
||||
.clip(CircleShape)
|
||||
.background(backgroundColor)
|
||||
.testTag(WarningBottomSheetTestTags.ICON),
|
||||
contentAlignment = Alignment.Center,
|
||||
content = {
|
||||
Icon(
|
||||
modifier = Modifier.size(28.dp),
|
||||
painter = painterResource(icon.res),
|
||||
contentDescription = null,
|
||||
tint = tint,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomSheetVector(vector: MessageBottomSheetUM.Vector, modifier: Modifier = Modifier) {
|
||||
val tint = when (vector.type) {
|
||||
MessageBottomSheetUM.Vector.Type.Unspecified -> Color.Unspecified
|
||||
MessageBottomSheetUM.Vector.Type.Accent -> TangemTheme.colors3.icon.status.info
|
||||
MessageBottomSheetUM.Vector.Type.Informative -> TangemTheme.colors3.icon.status.info
|
||||
MessageBottomSheetUM.Vector.Type.Attention -> TangemTheme.colors3.icon.status.warning
|
||||
MessageBottomSheetUM.Vector.Type.Warning -> TangemTheme.colors3.icon.status.error
|
||||
}
|
||||
|
||||
val backgroundColor = when (vector.backgroundType) {
|
||||
MessageBottomSheetUM.Vector.BackgroundType.Unspecified -> Color.Unspecified
|
||||
MessageBottomSheetUM.Vector.BackgroundType.SameAsTint -> tint
|
||||
MessageBottomSheetUM.Vector.BackgroundType.Accent -> TangemTheme.colors3.bg.status.infoSubtle
|
||||
MessageBottomSheetUM.Vector.BackgroundType.Informative -> TangemTheme.colors3.bg.status.infoSubtle
|
||||
MessageBottomSheetUM.Vector.BackgroundType.Attention -> TangemTheme.colors3.bg.status.warningSubtle
|
||||
MessageBottomSheetUM.Vector.BackgroundType.Warning -> TangemTheme.colors3.bg.status.errorSubtle
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(TangemTheme.dimens2.x20)
|
||||
.clip(CircleShape)
|
||||
.background(backgroundColor)
|
||||
.testTag(WarningBottomSheetTestTags.ICON),
|
||||
contentAlignment = Alignment.Center,
|
||||
content = {
|
||||
Icon(
|
||||
modifier = Modifier.size(28.dp),
|
||||
imageVector = vector.imageVector,
|
||||
contentDescription = null,
|
||||
tint = tint,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomSheetChip(chip: MessageBottomSheetUM.Chip, modifier: Modifier = Modifier) {
|
||||
val color = when (chip.type) {
|
||||
MessageBottomSheetUM.Chip.Type.Unspecified -> TangemTheme.colors.text.primary1
|
||||
MessageBottomSheetUM.Chip.Type.Warning -> TangemTheme.colors.text.warning
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = modifier
|
||||
.background(
|
||||
shape = RoundedCornerShape(TangemTheme.dimens.radius16),
|
||||
color = color.copy(alpha = 0.1F),
|
||||
)
|
||||
.padding(vertical = TangemTheme.dimens.spacing4, horizontal = TangemTheme.dimens.spacing12),
|
||||
text = chip.text.resolveReference(),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun ButtonsContainer(
|
||||
buttons: ImmutableList<MessageBottomSheetUM.Button>,
|
||||
closeScope: MessageBottomSheetUM.CloseScope,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.padding(all = TangemTheme.dimens2.x4),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x2),
|
||||
) {
|
||||
buttons.fastForEach { button ->
|
||||
TangemButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag(
|
||||
if (button.isPrimary) {
|
||||
WarningBottomSheetTestTags.BUTTON_PRIMARY
|
||||
} else {
|
||||
WarningBottomSheetTestTags.BUTTON_SECONDARY
|
||||
},
|
||||
),
|
||||
onClick = { button.onClick?.invoke(closeScope) },
|
||||
text = button.text ?: TextReference.EMPTY,
|
||||
iconStart = if (button.iconOrder == MessageBottomSheetUM.Button.IconOrder.Start) {
|
||||
button.icon?.let(TangemIconUM::Icon)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
iconEnd = if (button.iconOrder == MessageBottomSheetUM.Button.IconOrder.End) {
|
||||
button.icon?.let(TangemIconUM::Icon)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
variant = if (button.isPrimary) {
|
||||
TangemButton.Variant.Primary
|
||||
} else {
|
||||
TangemButton.Variant.Secondary
|
||||
},
|
||||
size = TangemButton.Size.X12,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
TangemThemePreviewRedesign {
|
||||
MessageBottomSheet(
|
||||
messageBottomSheetUM {
|
||||
infoBlock {
|
||||
icon(R.drawable.img_knight_shield_32) {
|
||||
type = MessageBottomSheetUM.Icon.Type.Attention
|
||||
backgroundType = MessageBottomSheetUM.Icon.BackgroundType.SameAsTint
|
||||
}
|
||||
title = TextReference.Str("Title Title Title")
|
||||
body = TextReference.Str("Body")
|
||||
chip(text = TextReference.Str("Some chip information"))
|
||||
}
|
||||
primaryButton {
|
||||
text = TextReference.Str("Test")
|
||||
icon = R.drawable.ic_tangem_24
|
||||
}
|
||||
secondaryButton {
|
||||
icon = R.drawable.ic_tangem_24
|
||||
text = TextReference.Str("asdasd")
|
||||
onClick {
|
||||
closeBs()
|
||||
}
|
||||
}
|
||||
},
|
||||
onDismissRequest = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun Preview2() {
|
||||
TangemThemePreviewRedesign {
|
||||
MessageBottomSheet(
|
||||
messageBottomSheetUM {
|
||||
infoBlock {
|
||||
iconImage = MessageBottomSheetUM.IconImage(R.drawable.img_visa_notification)
|
||||
title = TextReference.Str("Title Title Title")
|
||||
body = TextReference.Str("Body")
|
||||
chip(text = TextReference.Str("Some chip information"))
|
||||
}
|
||||
primaryButton {
|
||||
text = TextReference.Str("Test")
|
||||
icon = R.drawable.ic_tangem_24
|
||||
}
|
||||
secondaryButton {
|
||||
icon = R.drawable.ic_tangem_24
|
||||
text = TextReference.Str("asdasd")
|
||||
onClick {
|
||||
closeBs()
|
||||
}
|
||||
}
|
||||
},
|
||||
onDismissRequest = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ private fun lightThemeColors2(): TangemColors2 {
|
|||
primary = TangemColorPalette.Dark6,
|
||||
primaryInverted = TangemColorPalette.White,
|
||||
secondary = TangemColorPalette.Dark2,
|
||||
tertiary = TangemColorPalette.Dark3,
|
||||
tertiary = TangemColorPalette.Dark1,
|
||||
quaternary = TangemColorPalette.Light4,
|
||||
primaryInvertedConstant = TangemColorPalette.White,
|
||||
tertiaryConstant = TangemColorPalette.Dark1,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ internal class TangemPayDetailsStateFactory(
|
|||
isTangemPayDeactivated: Boolean,
|
||||
cardNumberEnd: String,
|
||||
isReissuing: Boolean,
|
||||
isFrozen: Boolean,
|
||||
): TangemPayDetailsUM {
|
||||
return TangemPayDetailsUM(
|
||||
topBarConfig = TangemPayDetailsTopBarConfig(
|
||||
|
|
@ -49,6 +50,7 @@ internal class TangemPayDetailsStateFactory(
|
|||
lastDigits = cardNumberEnd,
|
||||
onClick = {},
|
||||
isReissuing = isReissuing,
|
||||
isFrozen = isFrozen,
|
||||
),
|
||||
),
|
||||
onAddCardClick = intents::onAddCardClick,
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ internal sealed class TangemPayDetailsBalanceBlockState {
|
|||
val lastDigits: String,
|
||||
val onClick: () -> Unit,
|
||||
val isReissuing: Boolean,
|
||||
val isFrozen: Boolean,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -293,9 +293,15 @@ internal class TangemPayCardPageModel @Inject constructor(
|
|||
if (frozenStateJobHolder.isActive) return
|
||||
|
||||
val message = if (isFrozen) {
|
||||
TangemPayMessagesFactory.createUnfreezeCardMessage(onUnfreezeClicked = ::unfreezeCard)
|
||||
TangemPayMessagesFactory.createUnfreezeCardMessage(
|
||||
onUnfreezeClicked = ::unfreezeCard,
|
||||
isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled,
|
||||
)
|
||||
} else {
|
||||
TangemPayMessagesFactory.createFreezeCardMessage(onFreezeClicked = ::freezeCard)
|
||||
TangemPayMessagesFactory.createFreezeCardMessage(
|
||||
onFreezeClicked = ::freezeCard,
|
||||
isRedesignEnabled = tangemPayFeatureToggles.isRedesignEnabled,
|
||||
)
|
||||
}
|
||||
uiMessageSender.send(message)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
isTangemPayDeactivated = isTangemPayDeactivated,
|
||||
cardNumberEnd = initialCard?.lastDigits.orEmpty(),
|
||||
isReissuing = initialCard == null || initialCard.state != TangemPayCardState.Active,
|
||||
isFrozen = initialCard?.frozenState == TangemPayCardFrozenState.Frozen,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.tangempay.model.transformers
|
||||
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import com.tangem.domain.models.pay.TangemPayCardFrozenState
|
||||
import com.tangem.domain.models.pay.TangemPayCardState
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsBalanceBlockState
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
|
||||
|
|
@ -17,6 +18,7 @@ internal class TangemPayCardDataTransformer(
|
|||
lastDigits = card.lastDigits,
|
||||
onClick = onCardClick,
|
||||
isReissuing = card.state != TangemPayCardState.Active,
|
||||
isFrozen = card.frozenState == TangemPayCardFrozenState.Frozen,
|
||||
)
|
||||
val cardsBlockState = prevState.balanceBlockState.cardsBlockState?.copy(
|
||||
cards = persistentListOf(updatedCard),
|
||||
|
|
|
|||
|
|
@ -460,8 +460,18 @@ internal class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<T
|
|||
isBalanceFlickering = false,
|
||||
cardsBlockState = TangemPayDetailsBalanceBlockState.CardsBlockState(
|
||||
cards = persistentListOf(
|
||||
TangemPayDetailsBalanceBlockState.Card(lastDigits = "1234", onClick = {}, isReissuing = false),
|
||||
TangemPayDetailsBalanceBlockState.Card(lastDigits = "3456", onClick = {}, isReissuing = false),
|
||||
TangemPayDetailsBalanceBlockState.Card(
|
||||
lastDigits = "1234",
|
||||
onClick = {},
|
||||
isReissuing = false,
|
||||
isFrozen = false,
|
||||
),
|
||||
TangemPayDetailsBalanceBlockState.Card(
|
||||
lastDigits = "3456",
|
||||
onClick = {},
|
||||
isReissuing = false,
|
||||
isFrozen = false,
|
||||
),
|
||||
),
|
||||
onAddCardClick = {},
|
||||
),
|
||||
|
|
@ -490,6 +500,7 @@ internal class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<T
|
|||
lastDigits = "1234",
|
||||
onClick = {},
|
||||
isReissuing = true,
|
||||
isFrozen = false,
|
||||
),
|
||||
),
|
||||
onAddCardClick = {},
|
||||
|
|
|
|||
|
|
@ -340,6 +340,7 @@ private fun CardsBlock(
|
|||
isReissuing = item.isReissuing,
|
||||
lastDigits = item.lastDigits,
|
||||
onClick = item.onClick,
|
||||
isFrozen = item.isFrozen,
|
||||
)
|
||||
SpacerW(TangemTheme.dimens2.x2)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
|||
import com.tangem.core.ui.res.generated.icons.Icons
|
||||
import com.tangem.core.ui.res.generated.icons.ic_clock_12
|
||||
import com.tangem.core.ui.res.generated.icons.ic_cloud_12_filled
|
||||
import com.tangem.core.ui.res.generated.icons.ic_snowflake_16
|
||||
import com.tangem.core.ui.test.TangemPayTestTags
|
||||
|
||||
private const val DEFAULT_CARD_BG = 0xFF1C1F29
|
||||
|
|
@ -42,6 +43,7 @@ internal fun TangemPayCardView(
|
|||
isReissuing: Boolean,
|
||||
lastDigits: String,
|
||||
onClick: () -> Unit,
|
||||
isFrozen: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
CardBackground(
|
||||
|
|
@ -64,10 +66,10 @@ internal fun TangemPayCardView(
|
|||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(TangemTheme.dimens2.x3),
|
||||
imageVector = if (isReissuing) {
|
||||
Icons.ic_clock_12
|
||||
} else {
|
||||
Icons.ic_cloud_12_filled
|
||||
imageVector = when {
|
||||
isFrozen -> Icons.ic_snowflake_16
|
||||
isReissuing -> Icons.ic_clock_12
|
||||
else -> Icons.ic_cloud_12_filled
|
||||
},
|
||||
tint = TangemTheme.colors3.icon.staticDark,
|
||||
contentDescription = null,
|
||||
|
|
@ -191,11 +193,13 @@ private fun CardBackgroundPreview() {
|
|||
content = {},
|
||||
)
|
||||
SpacerH(TangemTheme.dimens2.x4)
|
||||
TangemPayCardView(isReissuing = false, onClick = {}, lastDigits = "1234")
|
||||
TangemPayCardView(isReissuing = false, onClick = {}, lastDigits = "1234", isFrozen = false)
|
||||
SpacerH(TangemTheme.dimens2.x4)
|
||||
TangemPayCardView(isReissuing = true, onClick = {}, lastDigits = "")
|
||||
TangemPayCardView(isReissuing = true, onClick = {}, lastDigits = "", isFrozen = false)
|
||||
SpacerH(TangemTheme.dimens2.x4)
|
||||
TangemPayAddCardView(onClick = {})
|
||||
SpacerH(TangemTheme.dimens2.x4)
|
||||
TangemPayCardView(isReissuing = false, onClick = {}, lastDigits = "1234", isFrozen = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,9 @@ import com.tangem.core.ui.extensions.TextReference
|
|||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.BottomSheetMessage
|
||||
import com.tangem.core.ui.message.bottomSheetMessage
|
||||
import com.tangem.core.ui.res.generated.icons.Icons
|
||||
import com.tangem.core.ui.res.generated.icons.ic_snowflake_20
|
||||
import com.tangem.core.ui.res.generated.icons.ic_sun_20
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsErrorType
|
||||
|
||||
internal object TangemPayMessagesFactory {
|
||||
|
|
@ -55,16 +58,31 @@ internal object TangemPayMessagesFactory {
|
|||
}
|
||||
}
|
||||
|
||||
fun createFreezeCardMessage(onFreezeClicked: () -> Unit): BottomSheetMessage {
|
||||
fun createFreezeCardMessage(isRedesignEnabled: Boolean, onFreezeClicked: () -> Unit): BottomSheetMessage {
|
||||
return bottomSheetMessage {
|
||||
infoBlock {
|
||||
icon(R.drawable.ic_snow_24) {
|
||||
type = MessageBottomSheetUM.Icon.Type.Accent
|
||||
backgroundType = MessageBottomSheetUM.Icon.BackgroundType.Accent
|
||||
if (isRedesignEnabled) {
|
||||
vector(Icons.ic_snowflake_20) {
|
||||
type = MessageBottomSheetUM.Vector.Type.Informative
|
||||
backgroundType = MessageBottomSheetUM.Vector.BackgroundType.Informative
|
||||
}
|
||||
} else {
|
||||
icon(R.drawable.ic_snow_24) {
|
||||
type = MessageBottomSheetUM.Icon.Type.Accent
|
||||
backgroundType = MessageBottomSheetUM.Icon.BackgroundType.Accent
|
||||
}
|
||||
}
|
||||
title = TextReference.Res(R.string.tangem_pay_freeze_card_alert_title)
|
||||
body = TextReference.Res(R.string.tangem_pay_freeze_card_alert_body)
|
||||
}
|
||||
if (isRedesignEnabled) {
|
||||
secondaryButton {
|
||||
text = resourceReference(R.string.common_cancel)
|
||||
onClick {
|
||||
closeBs()
|
||||
}
|
||||
}
|
||||
}
|
||||
primaryButton {
|
||||
text = resourceReference(R.string.tangem_pay_freeze_card_freeze)
|
||||
onClick {
|
||||
|
|
@ -75,16 +93,31 @@ internal object TangemPayMessagesFactory {
|
|||
}
|
||||
}
|
||||
|
||||
fun createUnfreezeCardMessage(onUnfreezeClicked: () -> Unit): BottomSheetMessage {
|
||||
fun createUnfreezeCardMessage(isRedesignEnabled: Boolean, onUnfreezeClicked: () -> Unit): BottomSheetMessage {
|
||||
return bottomSheetMessage {
|
||||
infoBlock {
|
||||
icon(R.drawable.ic_snow_24) {
|
||||
type = MessageBottomSheetUM.Icon.Type.Accent
|
||||
backgroundType = MessageBottomSheetUM.Icon.BackgroundType.Accent
|
||||
if (isRedesignEnabled) {
|
||||
vector(Icons.ic_sun_20) {
|
||||
type = MessageBottomSheetUM.Vector.Type.Attention
|
||||
backgroundType = MessageBottomSheetUM.Vector.BackgroundType.Attention
|
||||
}
|
||||
} else {
|
||||
icon(R.drawable.ic_snow_24) {
|
||||
type = MessageBottomSheetUM.Icon.Type.Accent
|
||||
backgroundType = MessageBottomSheetUM.Icon.BackgroundType.Accent
|
||||
}
|
||||
}
|
||||
title = TextReference.Res(R.string.tangem_pay_unfreeze_card_alert_title)
|
||||
body = TextReference.Res(R.string.tangem_pay_unfreeze_card_alert_body)
|
||||
}
|
||||
if (isRedesignEnabled) {
|
||||
secondaryButton {
|
||||
text = resourceReference(R.string.common_cancel)
|
||||
onClick {
|
||||
closeBs()
|
||||
}
|
||||
}
|
||||
}
|
||||
primaryButton {
|
||||
text = resourceReference(R.string.tangempay_card_details_unfreeze_card)
|
||||
onClick {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue