Updated on 2026-08-14

This commit is contained in:
Tangem 2023-10-26 11:20:16 +04:00
commit f047db3304
7 changed files with 267 additions and 11 deletions

View file

@ -114,6 +114,32 @@ fun PrimaryButtonIconEnd(
)
}
/**
* [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?type=design&node-id=68%3A20&mode=design&t=YXX8vqJcB9jn0wPp-1)
* */
@Composable
fun PrimaryButtonIconEndTwoLines(
text: String,
@DrawableRes iconResId: Int,
onClick: () -> Unit,
modifier: Modifier = Modifier,
showProgress: Boolean = false,
enabled: Boolean = true,
additionalText: String? = null,
) {
TangemButton(
modifier = modifier,
text = text,
icon = TangemButtonIconPosition.End(iconResId),
onClick = onClick,
colors = TangemButtonsDefaults.primaryButtonColors,
enabled = enabled,
showProgress = showProgress,
additionalText = additionalText,
size = TangemButtonSize.TwoLines,
)
}
/**
* [Show in Figma](https://www.figma.com/file/14ISV23YB1yVW1uNVwqrKv/Android?node-id=233%3A258&t=TmfD6UBHPg9uYfev-4)
* */
@ -261,6 +287,13 @@ private fun PrimaryButtonSample() {
enabled = false,
onClick = { },
)
PrimaryButtonIconEndTwoLines(
modifier = Modifier.fillMaxWidth(),
text = "Manage tokens",
iconResId = R.drawable.ic_tangem_24,
onClick = { },
additionalText = "Manage these tokens",
)
PrimaryButtonIconStart(
modifier = Modifier.fillMaxWidth(),
text = "Manage tokens",

View file

@ -26,6 +26,7 @@ fun TangemButton(
showProgress: Boolean,
enabled: Boolean,
modifier: Modifier = Modifier,
additionalText: String? = null,
size: TangemButtonSize = TangemButtonSize.Default,
elevation: ButtonElevation = TangemButtonsDefaults.elevation,
textStyle: TextStyle = TangemTheme.typography.button,
@ -73,6 +74,20 @@ fun TangemButton(
contentDescription = null,
)
},
additionalText = {
if (additionalText != null) {
Text(
modifier = Modifier
.fillMaxWidth(),
text = additionalText,
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.disabled,
textAlign = TextAlign.Center,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
},
)
}
}
@ -86,18 +101,27 @@ private inline fun RowScope.ButtonContentContainer(
progressIndicator: @Composable RowScope.() -> Unit,
text: @Composable RowScope.() -> Unit,
icon: @Composable RowScope.(Int) -> Unit,
additionalText: @Composable () -> Unit,
) {
if (showProgress) {
progressIndicator()
} else {
if (buttonIcon is TangemButtonIconPosition.Start) {
icon(buttonIcon.iconResId)
Spacer(modifier = Modifier.requiredWidth(iconPadding))
}
text()
if (buttonIcon is TangemButtonIconPosition.End) {
Spacer(modifier = Modifier.requiredWidth(iconPadding))
icon(buttonIcon.iconResId)
Column {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
) {
if (buttonIcon is TangemButtonIconPosition.Start) {
icon(buttonIcon.iconResId)
Spacer(modifier = Modifier.requiredWidth(iconPadding))
}
text()
if (buttonIcon is TangemButtonIconPosition.End) {
Spacer(modifier = Modifier.requiredWidth(iconPadding))
icon(buttonIcon.iconResId)
}
}
additionalText()
}
}
}

View file

@ -14,12 +14,13 @@ enum class TangemButtonSize {
Selector,
Action,
RoundedAction,
TwoLines,
}
@Composable
@ReadOnlyComposable
internal fun TangemButtonSize.toHeightDp(): Dp = when (this) {
TangemButtonSize.Default -> TangemTheme.dimens.size48
TangemButtonSize.Default, TangemButtonSize.TwoLines -> TangemTheme.dimens.size48
TangemButtonSize.Text -> TangemTheme.dimens.size40
TangemButtonSize.Selector -> TangemTheme.dimens.size24
TangemButtonSize.Action,
@ -34,13 +35,14 @@ internal fun TangemButtonSize.toShape(): Shape = when (this) {
TangemButtonSize.Text -> TangemTheme.shapes.roundedCornersSmall
TangemButtonSize.Selector -> TangemTheme.shapes.roundedCornersSmall
TangemButtonSize.Action -> TangemTheme.shapes.roundedCornersMedium
TangemButtonSize.TwoLines -> TangemTheme.shapes.roundedCornersXMedium
TangemButtonSize.RoundedAction -> TangemTheme.shapes.roundedCornersLarge
}
@Composable
@ReadOnlyComposable
internal fun TangemButtonSize.toIconPadding(): Dp = when (this) {
TangemButtonSize.Default -> TangemTheme.dimens.spacing4
TangemButtonSize.Default, TangemButtonSize.TwoLines -> TangemTheme.dimens.spacing4
TangemButtonSize.Text -> TangemTheme.dimens.spacing8
TangemButtonSize.Selector -> 0.dp
TangemButtonSize.Action,
@ -80,6 +82,12 @@ internal fun TangemButtonSize.toContentPadding(icon: TangemButtonIconPosition):
start = horizontalPadding.first,
end = horizontalPadding.second,
)
TangemButtonSize.TwoLines -> PaddingValues(
top = TangemTheme.dimens.spacing6,
bottom = TangemTheme.dimens.spacing6,
start = horizontalPadding.first,
end = horizontalPadding.second,
)
}
}
@ -87,7 +95,8 @@ internal fun TangemButtonSize.toContentPadding(icon: TangemButtonIconPosition):
@ReadOnlyComposable
internal fun TangemButtonSize.toHorizontalContentPadding(icon: TangemButtonIconPosition): Pair<Dp, Dp> {
return when (this) {
TangemButtonSize.Default -> TangemTheme.dimens.spacing32 to TangemTheme.dimens.spacing32
TangemButtonSize.Default, TangemButtonSize.TwoLines ->
TangemTheme.dimens.spacing32 to TangemTheme.dimens.spacing32
TangemButtonSize.Text -> when (icon) {
is TangemButtonIconPosition.None -> TangemTheme.dimens.spacing16 to TangemTheme.dimens.spacing16
is TangemButtonIconPosition.Start -> TangemTheme.dimens.spacing14 to TangemTheme.dimens.spacing16

View file

@ -28,6 +28,7 @@ data class NotificationConfig(
data class PrimaryButtonConfig(
val text: TextReference,
val additionalText: TextReference? = null,
@DrawableRes val iconResId: Int? = null,
val onClick: () -> Unit,
) : ButtonsState()

View file

@ -0,0 +1,35 @@
package com.tangem.managetokens.presentation.managetokens.state
import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.pluralReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.features.managetokens.impl.R
data class DerivationNotificationState(
val totalNeeded: Int,
val missingAddressesCount: Int,
val onGenerateClick: () -> Unit,
) {
val config = NotificationConfig(
title = resourceReference(id = R.string.warning_missing_derivation_title),
subtitle = pluralReference(
id = R.plurals.warning_missing_derivation_message,
count = totalNeeded,
formatArgs = wrappedList(totalNeeded),
),
iconResId = R.drawable.ic_alert_circle_24,
buttonsState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
text = resourceReference(id = R.string.common_generate_addresses),
iconResId = R.drawable.ic_tangem_24,
onClick = onGenerateClick,
// TODO: enable when we find how to use this type of strings with plurals on Localise
// Task: [REDACTED_JIRA]
// additionalText = pluralReference(
// id = R.plurals.manage_tokens_number_of_wallets,
// count = totalNeeded,
// formatArgs = wrappedList(missingAddressesCount, totalNeeded)
// )
),
)
}

View file

@ -0,0 +1,11 @@
package com.tangem.managetokens.presentation.managetokens.state.previewdata
import com.tangem.managetokens.presentation.managetokens.state.DerivationNotificationState
object DerivationNotificationStatePreviewData {
val state = DerivationNotificationState(
totalNeeded = 3,
missingAddressesCount = 2,
onGenerateClick = {},
)
}

View file

@ -0,0 +1,143 @@
package com.tangem.managetokens.presentation.managetokens.ui.components
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.material.Card
import androidx.compose.material.Icon
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 com.tangem.core.ui.components.PrimaryButtonIconEndTwoLines
import com.tangem.core.ui.components.SpacerW
import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.managetokens.impl.R
import com.tangem.managetokens.presentation.managetokens.state.previewdata.DerivationNotificationStatePreviewData
@Composable
internal fun DerivationNotification(config: NotificationConfig, modifier: Modifier = Modifier) {
BaseContainer(
modifier = modifier,
) {
Column(
modifier = Modifier.padding(all = TangemTheme.dimens.spacing16),
verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing16),
) {
MainContent(
iconResId = config.iconResId,
iconTint = TangemTheme.colors.icon.accent,
title = config.title,
subtitle = config.subtitle,
)
val buttonConfig = config.buttonsState
if (buttonConfig is NotificationConfig.ButtonsState.PrimaryButtonConfig) {
PrimaryButtonIconEndTwoLines(
text = buttonConfig.text.resolveReference(),
iconResId = buttonConfig.iconResId ?: R.drawable.ic_tangem_24,
onClick = buttonConfig.onClick,
modifier = Modifier
.fillMaxWidth(),
additionalText = buttonConfig.additionalText?.resolveReference(),
)
}
}
}
}
@Composable
private fun BaseContainer(modifier: Modifier = Modifier, content: @Composable BoxScope.() -> Unit) {
Card(
modifier = modifier
.defaultMinSize(minHeight = TangemTheme.dimens.size62)
.fillMaxWidth(),
shape = RoundedCornerShape(
topStart = TangemTheme.dimens.radius16,
topEnd = TangemTheme.dimens.radius16,
),
elevation = TangemTheme.dimens.elevation12,
backgroundColor = TangemTheme.colors.background.action,
) {
Box(content = content)
}
}
@Composable
private fun MainContent(iconResId: Int, iconTint: Color, title: TextReference, subtitle: TextReference) {
Row {
NotificationIcon(iconResId = iconResId, iconTint = iconTint)
SpacerW(width = TangemTheme.dimens.spacing10)
TextsBlock(title = title, subtitle = subtitle)
}
}
@Composable
private fun RowScope.NotificationIcon(iconResId: Int, iconTint: Color) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.align(alignment = Alignment.CenterVertically),
) {
Box(
modifier = Modifier
.size(TangemTheme.dimens.size36)
.background(
color = iconTint.copy(alpha = 0.12f),
shape = CircleShape,
),
)
Box(
modifier = Modifier
.size(TangemTheme.dimens.size16)
.background(
color = TangemTheme.colors.background.action,
shape = CircleShape,
),
)
Icon(
painter = painterResource(id = iconResId),
contentDescription = null,
tint = iconTint,
)
}
}
@Composable
private fun TextsBlock(title: TextReference, subtitle: TextReference) {
Column(verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing2)) {
Text(
text = title.resolveReference(),
color = TangemTheme.colors.text.primary1,
style = TangemTheme.typography.button,
)
Text(
text = subtitle.resolveReference(),
color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.caption2,
)
}
}
@Preview
@Composable
private fun Preview_ManageTokensScreen_LightTheme() {
TangemTheme(isDark = false) {
DerivationNotification(DerivationNotificationStatePreviewData.state.config)
}
}
@Preview
@Composable
private fun Preview_ManageTokensScreen_DarkTheme() {
TangemTheme(isDark = true) {
DerivationNotification(DerivationNotificationStatePreviewData.state.config)
}
}