Updated on 2026-08-14

This commit is contained in:
Tangem 2023-01-13 22:35:37 +04:00
parent 76f955568e
commit fc8fcfce19
17 changed files with 395 additions and 133 deletions

View file

@ -0,0 +1,143 @@
package com.tangem.core.ui.components
import androidx.compose.foundation.layout.padding
import androidx.compose.material.AlertDialog
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.R
import com.tangem.core.ui.res.TangemTheme
/**
* Simple alert dialog with a message and 'OK' button
*
* @param message message to show
* @param title title to show (no title if null)
* @param confirmButton title and action for confirm button
* @param dismissButton title and action for dismiss button (no dismiss button if null)
* @param onDismissDialog action to perform when dialog is closed
*
* @see <a href = "https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?node-id=48%3A30&t=izDPAJnDbJTTC0Fp-1"
* >Figma component</a>
*/
@Composable
fun BasicDialog(
modifier: Modifier = Modifier,
message: String,
title: String? = null,
confirmButton: DialogButton,
dismissButton: DialogButton? = null,
onDismissDialog: () -> Unit,
) {
AlertDialog(
text = {
Text(
text = message,
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.secondary,
)
},
title = if (title != null) {
{
Text(
text = title,
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
)
}
} else {
null
},
onDismissRequest = onDismissDialog,
confirmButton = {
TextButton(
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
text = confirmButton.title ?: stringResource(id = R.string.common_ok),
onClick = confirmButton.onClick,
)
},
dismissButton = {
if (dismissButton != null) {
TextButton(
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
text = dismissButton.title ?: stringResource(id = R.string.common_cancel),
onClick = dismissButton.onClick,
)
}
},
shape = TangemTheme.shapes.roundedCornersLarge,
modifier = modifier
.padding(TangemTheme.dimens.spacing24),
)
}
data class DialogButton(
val title: String? = null,
val onClick: () -> Unit,
)
@Composable
fun SimpleOkDialog(
modifier: Modifier = Modifier,
message: String,
onDismissDialog: () -> Unit,
) {
BasicDialog(
modifier = modifier,
message = message,
confirmButton = DialogButton(onClick = onDismissDialog),
onDismissDialog = onDismissDialog,
)
}
// region Preview
@Composable
private fun SimpleOkDialogPreview() = SimpleOkDialog(
message = "All protected passwords will be deleted from the " +
"secure storage, you must enter the wallet password to work with the app.",
) {}
@Composable
private fun BasicDialogPreview() = BasicDialog(
message = "All protected passwords will be deleted from the secure storage, you must enter the wallet password to work with the app",
title = "Attention",
confirmButton = DialogButton {},
dismissButton = DialogButton {},
) {}
@Preview(showBackground = true)
@Composable
fun Preview_SimpleOkDialog_InLightTheme() {
TangemTheme(isDark = false) {
SimpleOkDialogPreview()
}
}
@Preview(showBackground = true)
@Composable
fun Preview_BasicDialog_InLightTheme() {
TangemTheme(isDark = false) {
BasicDialogPreview()
}
}
@Preview(showBackground = true)
@Composable
fun Preview_SimpleOkDialog_InDarkTheme() {
TangemTheme(isDark = true) {
SimpleOkDialogPreview()
}
}
@Preview(showBackground = true)
@Composable
fun Preview_BasicDialog_InDarkTheme() {
TangemTheme(isDark = true) {
BasicDialogPreview()
}
}
// endregion Preview

View file

@ -1,5 +1,7 @@
package com.tangem.core.ui.components
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@ -18,6 +20,7 @@ import androidx.compose.material.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.res.stringResource
import androidx.compose.ui.text.style.TextAlign
@ -26,25 +29,37 @@ import com.tangem.core.ui.R
import com.tangem.core.ui.res.TangemTheme
/**
* Screen for showing success
* Screen for showing result
*
* @param successMessage
* @param resultMessage message to show
* @param title title to show
* @param resultColor color which will tint the round icon of the result
* @param icon icon to show in the middle of the round icon
* @param secondaryButtonIcon icon to show in the secondary button
* @param secondaryButtonText label of the secondary button
* @param onSecondaryButtonClick action on clicking secondary button
* @param onButtonClick action on clicking "Done" button
*
* @see <a href = "https://www.figma.com/file/Vs6SkVsFnUPsSCNwlnVf5U/Android-%E2%80%93-UI?node-id=1123%3A3863&t=wwR84h5IsMaMsDhq-1"
* >Figma component</a>
*/
@Composable
fun SuccessScreenContent(
fun ResultScreenContent(
modifier: Modifier = Modifier,
successMessage: String,
resultMessage: String,
@StringRes title: Int = R.string.common_success,
resultColor: Color = TangemTheme.colors.icon.accent,
@DrawableRes icon: Int = R.drawable.ic_check_24,
@DrawableRes secondaryButtonIcon: Int? = null,
@StringRes secondaryButtonText: Int? = null,
onSecondaryButtonClick: (() -> Unit)? = null,
onButtonClick: () -> Unit,
) {
Column(
modifier = modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.background(TangemTheme.colors.background.primary)
.background(TangemTheme.colors.background.secondary)
.padding(
horizontal = TangemTheme.dimens.spacing16,
vertical = TangemTheme.dimens.spacing32,
@ -53,10 +68,10 @@ fun SuccessScreenContent(
verticalArrangement = Arrangement.Center,
) {
SpacerHHalf()
SuccessImage()
SuccessImage(resultColor = resultColor, icon = icon)
SpacerH50()
Text(
text = stringResource(id = R.string.common_success),
text = stringResource(id = title),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
@ -64,15 +79,25 @@ fun SuccessScreenContent(
)
SpacerH12()
Text(
text = successMessage,
text = resultMessage,
style = TangemTheme.typography.subtitle1,
color = TangemTheme.colors.text.secondary,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth(),
)
SpacerHHalf()
if (onSecondaryButtonClick != null && secondaryButtonText != null) {
SecondaryButtonForResultScreen(
secondaryButtonText = secondaryButtonText,
secondaryButtonIcon = secondaryButtonIcon,
onSecondaryButtonClick = onSecondaryButtonClick,
modifier = Modifier
.fillMaxWidth(),
)
SpacerH12()
}
PrimaryButton(
text = stringResource(id = R.string.common_done),
text = stringResource(id = R.string.common_close),
modifier = Modifier
.fillMaxWidth(),
onClick = { onButtonClick() },
@ -81,11 +106,15 @@ fun SuccessScreenContent(
}
@Composable
fun SuccessImage() {
fun SuccessImage(
resultColor: Color,
@DrawableRes icon: Int,
) {
Box(
modifier = Modifier
.background(
color = TangemTheme.colors.icon.accent.copy(alpha = 0.2f),
color = (resultColor)
.copy(alpha = 0.2f),
shape = CircleShape,
),
contentAlignment = Alignment.Center,
@ -94,7 +123,7 @@ fun SuccessImage() {
modifier = Modifier
.padding(TangemTheme.dimens.spacing24)
.background(
color = TangemTheme.colors.icon.accent,
color = resultColor,
shape = CircleShape,
)
.height(TangemTheme.dimens.size93)
@ -102,7 +131,7 @@ fun SuccessImage() {
contentAlignment = Alignment.Center,
) {
Icon(
painter = painterResource(id = R.drawable.ic_check_24),
painter = painterResource(id = icon),
contentDescription = null,
tint = TangemTheme.colors.icon.primary2,
modifier = Modifier.size(TangemTheme.dimens.size40),
@ -111,12 +140,37 @@ fun SuccessImage() {
}
}
@Composable
private fun SecondaryButtonForResultScreen(
modifier: Modifier = Modifier,
@StringRes secondaryButtonText: Int,
@DrawableRes secondaryButtonIcon: Int? = null,
onSecondaryButtonClick: (() -> Unit),
) {
if (secondaryButtonIcon != null) {
SecondaryButtonIconLeft(
text = stringResource(id = secondaryButtonText),
icon = painterResource(id = secondaryButtonIcon),
onClick = onSecondaryButtonClick,
modifier = modifier,
)
} else {
SecondaryButton(
text = stringResource(id = secondaryButtonText),
onClick = onSecondaryButtonClick,
modifier = modifier,
)
}
}
// region preview
@Composable
private fun SuccessScreenPreview() {
SuccessScreenContent(
successMessage = "Swap of 1 000 DAI to 1 131,46 MATIC",
ResultScreenContent(
resultMessage = "Swap of 1 000 DAI to 1 131,46 MATIC",
secondaryButtonText = R.string.swapping_success_view_explorer_button_title,
onSecondaryButtonClick = {},
onButtonClick = {},
)
}

View file

@ -28,6 +28,7 @@ fun WarningCard(
modifier: Modifier = Modifier,
title: String,
description: String,
icon: @Composable (() -> Unit)? = null,
) {
WarningCardSurface(
modifier = modifier,
@ -35,6 +36,7 @@ fun WarningCard(
WarningBody(
title = title,
description = description,
icon = icon,
)
},
)
@ -55,12 +57,13 @@ fun ClickableWarningCard(
modifier: Modifier = Modifier,
title: String,
description: String,
icon: @Composable (() -> Unit)? = null,
onClick: () -> Unit,
) {
WarningCardSurface(
modifier = modifier,
content = {
WarningBody(title = title, description = description) {
WarningBody(title = title, description = description, icon = icon) {
SpacerW12()
Icon(
painter = painterResource(id = R.drawable.ic_chevron_right_24),
@ -88,12 +91,13 @@ fun RefreshableWaringCard(
modifier: Modifier = Modifier,
title: String,
description: String,
icon: @Composable (() -> Unit)? = null,
onClick: () -> Unit,
) {
WarningCardSurface(
modifier = modifier,
content = {
WarningBody(title = title, description = description) {
WarningBody(title = title, description = description, icon = icon) {
SpacerW12()
Icon(
painter = painterResource(id = R.drawable.ic_refresh_24),
@ -113,6 +117,7 @@ private fun WarningBody(
modifier: Modifier = Modifier,
title: String,
description: String,
icon: @Composable (() -> Unit)? = null,
additionalContent: @Composable () -> Unit = {},
) {
IconWithTitleAndDescription(
@ -120,7 +125,7 @@ private fun WarningBody(
title = title,
description = description,
additionalContent = additionalContent,
icon = {
icon = icon ?: {
Image(
painter = painterResource(id = R.drawable.img_attention_20),
contentDescription = null,

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000000"
android:pathData="M5,17.59L15.59,7H9V5H19V15H17V8.41L6.41,19L5,17.59Z" />
</vector>