[#1162] Finish expandable trx item UI state
- Closes #1162 - Closes #1237 - Closes #1078 - This removes unused DangerousButton component and its related resources - It fixes the Collapse button vector icon - It brings send_failed and receive_failed states into the trx item UI - It adds the fee part of the expandable item - Its follow-up is #1047 - Changelog updated
This commit is contained in:
parent
c8a14f0375
commit
2c45ab642b
|
@ -21,7 +21,7 @@ directly impact users rather than highlighting other key architectural updates.*
|
|||
submission
|
||||
|
||||
### Changed
|
||||
- The Transaction History UI has been incorporated into the Account screen and partly reworked according to the
|
||||
- The Transaction History UI has been incorporated into the Account screen and completely reworked according to the
|
||||
design guidelines
|
||||
- Reworked Send screens flow and their look (e.g., Send Failure screen is now a modal dialog instead of a separate
|
||||
screen)
|
||||
|
|
|
@ -57,7 +57,6 @@ private fun ButtonComposablePreview() {
|
|||
TertiaryButton(onClick = { }, text = "Tertiary")
|
||||
TertiaryButton(onClick = { }, text = "Tertiary", enabled = false)
|
||||
NavigationButton(onClick = { }, text = "Navigation")
|
||||
DangerousButton(onClick = { }, text = "Dangerous")
|
||||
@Suppress("MagicNumber")
|
||||
Row {
|
||||
PrimaryButton(onClick = { }, text = "Button 1", modifier = Modifier.weight(0.5f))
|
||||
|
@ -292,38 +291,6 @@ fun TertiaryButton(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DangerousButton(
|
||||
onClick: () -> Unit,
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
outerPaddingValues: PaddingValues =
|
||||
PaddingValues(
|
||||
horizontal = ZcashTheme.dimens.spacingNone,
|
||||
vertical = ZcashTheme.dimens.spacingSmall
|
||||
),
|
||||
) {
|
||||
Button(
|
||||
shape = RectangleShape,
|
||||
onClick = onClick,
|
||||
modifier =
|
||||
modifier.then(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(outerPaddingValues)
|
||||
.defaultMinSize(ZcashTheme.dimens.buttonWidth, ZcashTheme.dimens.buttonHeight)
|
||||
),
|
||||
colors = buttonColors(containerColor = ZcashTheme.colors.dangerous)
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
text = text,
|
||||
color = ZcashTheme.colors.onDangerous
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
fun Modifier.shadow(
|
||||
contentColor: Color = Color.Black,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
package co.electriccoin.zcash.ui.design.component
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.basicMarquee
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
|
@ -232,9 +233,9 @@ fun Tiny(
|
|||
@Suppress("LongParameterList")
|
||||
fun TextWithIcon(
|
||||
text: String,
|
||||
imageVector: ImageVector,
|
||||
iconVector: ImageVector,
|
||||
modifier: Modifier = Modifier,
|
||||
imageContentDescription: String? = null,
|
||||
iconContentDescription: String? = null,
|
||||
maxLines: Int = Int.MAX_VALUE,
|
||||
overflow: TextOverflow = TextOverflow.Clip,
|
||||
textAlign: TextAlign = TextAlign.Start,
|
||||
|
@ -248,9 +249,9 @@ fun TextWithIcon(
|
|||
.then(modifier),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
imageVector = imageVector,
|
||||
contentDescription = imageContentDescription
|
||||
Image(
|
||||
imageVector = iconVector,
|
||||
contentDescription = iconContentDescription
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.padding(3.dp))
|
||||
|
|
|
@ -30,8 +30,6 @@ data class ExtendedColors(
|
|||
val layoutStroke: Color,
|
||||
val overlay: Color,
|
||||
val highlight: Color,
|
||||
val dangerous: Color,
|
||||
val onDangerous: Color,
|
||||
val reference: Color,
|
||||
val disabledButtonColor: Color,
|
||||
val disabledButtonTextColor: Color,
|
||||
|
@ -47,7 +45,7 @@ data class ExtendedColors(
|
|||
val radioButtonColor: Color,
|
||||
val radioButtonTextColor: Color,
|
||||
val historyBackgroundColor: Color,
|
||||
val historySendColor: Color,
|
||||
val historyRedColor: Color,
|
||||
) {
|
||||
@Composable
|
||||
fun surfaceGradient() =
|
||||
|
|
|
@ -61,9 +61,6 @@ internal object Dark {
|
|||
val overlay = Color(0x22000000)
|
||||
val highlight = Color(0xFFFFD800)
|
||||
|
||||
val dangerous = Color(0xFFFF0B0B)
|
||||
val onDangerous = Color(0xFFFFFFFF)
|
||||
|
||||
val reference = Color(0xFFFFFFFF)
|
||||
|
||||
val disabledButtonColor = Color(0xFFB7B7B7)
|
||||
|
@ -72,7 +69,7 @@ internal object Dark {
|
|||
val buttonShadowColor = Color(0xFFFFFFFF)
|
||||
|
||||
val historyBackgroundColor = Color(0xFFF6F6F6)
|
||||
val historySendColor = Color(0xFFF40202)
|
||||
val historyRedColor = Color(0xFFF40202)
|
||||
}
|
||||
|
||||
internal object Light {
|
||||
|
@ -122,9 +119,6 @@ internal object Light {
|
|||
val overlay = Color(0x22000000)
|
||||
val highlight = Color(0xFFFFD800)
|
||||
|
||||
val dangerous = Color(0xFFFF0B0B)
|
||||
val onDangerous = Color(0xFFFFFFFF)
|
||||
|
||||
val reference = Color(0xFF000000)
|
||||
|
||||
val disabledButtonColor = Color(0xFFB7B7B7)
|
||||
|
@ -132,7 +126,7 @@ internal object Light {
|
|||
val buttonShadowColor = Color(0xFF000000)
|
||||
|
||||
val historyBackgroundColor = Color(0xFFF6F6F6)
|
||||
val historySendColor = Color(0xFFF40202)
|
||||
val historyRedColor = Color(0xFFF40202)
|
||||
}
|
||||
|
||||
internal val DarkColorPalette =
|
||||
|
@ -183,8 +177,6 @@ internal val DarkExtendedColorPalette =
|
|||
layoutStroke = Dark.layoutStroke,
|
||||
overlay = Dark.overlay,
|
||||
highlight = Dark.highlight,
|
||||
dangerous = Dark.dangerous,
|
||||
onDangerous = Dark.onDangerous,
|
||||
disabledButtonTextColor = Dark.disabledButtonTextColor,
|
||||
disabledButtonColor = Dark.disabledButtonColor,
|
||||
reference = Dark.reference,
|
||||
|
@ -200,7 +192,7 @@ internal val DarkExtendedColorPalette =
|
|||
radioButtonColor = Dark.radioButtonColor,
|
||||
radioButtonTextColor = Dark.radioButtonTextColor,
|
||||
historyBackgroundColor = Dark.historyBackgroundColor,
|
||||
historySendColor = Dark.historySendColor,
|
||||
historyRedColor = Dark.historyRedColor,
|
||||
)
|
||||
|
||||
internal val LightExtendedColorPalette =
|
||||
|
@ -227,8 +219,6 @@ internal val LightExtendedColorPalette =
|
|||
layoutStroke = Light.layoutStroke,
|
||||
overlay = Light.overlay,
|
||||
highlight = Light.highlight,
|
||||
dangerous = Light.dangerous,
|
||||
onDangerous = Light.onDangerous,
|
||||
disabledButtonTextColor = Light.disabledButtonTextColor,
|
||||
disabledButtonColor = Light.disabledButtonColor,
|
||||
reference = Light.reference,
|
||||
|
@ -244,7 +234,7 @@ internal val LightExtendedColorPalette =
|
|||
radioButtonColor = Light.radioButtonColor,
|
||||
radioButtonTextColor = Light.radioButtonTextColor,
|
||||
historyBackgroundColor = Light.historyBackgroundColor,
|
||||
historySendColor = Light.historySendColor,
|
||||
historyRedColor = Light.historyRedColor,
|
||||
)
|
||||
|
||||
@Suppress("CompositionLocalAllowlist")
|
||||
|
@ -273,8 +263,6 @@ internal val LocalExtendedColors =
|
|||
layoutStroke = Color.Unspecified,
|
||||
overlay = Color.Unspecified,
|
||||
highlight = Color.Unspecified,
|
||||
dangerous = Color.Unspecified,
|
||||
onDangerous = Color.Unspecified,
|
||||
disabledButtonTextColor = Color.Unspecified,
|
||||
disabledButtonColor = Color.Unspecified,
|
||||
reference = Color.Unspecified,
|
||||
|
@ -290,6 +278,6 @@ internal val LocalExtendedColors =
|
|||
radioButtonColor = Color.Unspecified,
|
||||
radioButtonTextColor = Color.Unspecified,
|
||||
historyBackgroundColor = Color.Unspecified,
|
||||
historySendColor = Color.Unspecified,
|
||||
historyRedColor = Color.Unspecified,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -165,6 +165,9 @@ data class TransactionItemTextStyles(
|
|||
val content: TextStyle,
|
||||
val contentMedium: TextStyle,
|
||||
val contentUnderline: TextStyle,
|
||||
val contentLineThrough: TextStyle,
|
||||
val feeFirstPart: TextStyle,
|
||||
val feeSecondPart: TextStyle,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
|
@ -342,6 +345,21 @@ val LocalExtendedTypography =
|
|||
fontStyle = FontStyle.Italic,
|
||||
textDecoration = TextDecoration.Underline
|
||||
),
|
||||
contentLineThrough =
|
||||
PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 13.sp,
|
||||
textDecoration = TextDecoration.LineThrough
|
||||
),
|
||||
feeFirstPart =
|
||||
PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
),
|
||||
feeSecondPart =
|
||||
PrimaryTypography.bodySmall.copy(
|
||||
fontSize = 8.sp,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ import cash.z.ecc.android.sdk.model.FirstClassByteArray
|
|||
import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||
import cash.z.ecc.android.sdk.model.TransactionRecipient
|
||||
import cash.z.ecc.android.sdk.model.TransactionState
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.model.toZecString
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.design.component.CircularMidProgressIndicator
|
||||
|
@ -55,6 +56,7 @@ import co.electriccoin.zcash.ui.screen.account.fixture.TransactionsFixture
|
|||
import co.electriccoin.zcash.ui.screen.account.model.TransactionUi
|
||||
import co.electriccoin.zcash.ui.screen.account.model.TransactionUiState
|
||||
import co.electriccoin.zcash.ui.screen.account.model.TrxItemState
|
||||
import co.electriccoin.zcash.ui.screen.send.view.DEFAULT_LESS_THAN_FEE
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import java.text.DateFormat
|
||||
|
@ -214,7 +216,7 @@ private fun HistoryItem(
|
|||
TransactionExtendedState.SEND_FAILED -> {
|
||||
typeText = stringResource(id = R.string.account_history_item_send_failed)
|
||||
typeIcon = ImageVector.vectorResource(R.drawable.ic_trx_send_icon)
|
||||
textColor = ZcashTheme.colors.dangerous
|
||||
textColor = ZcashTheme.colors.historyRedColor
|
||||
textStyle = ZcashTheme.extendedTypography.transactionItemStyles.titleFailed
|
||||
}
|
||||
|
||||
|
@ -233,7 +235,7 @@ private fun HistoryItem(
|
|||
TransactionExtendedState.RECEIVE_FAILED -> {
|
||||
typeText = stringResource(id = R.string.account_history_item_receive_failed)
|
||||
typeIcon = ImageVector.vectorResource(R.drawable.ic_trx_receive_icon)
|
||||
textColor = ZcashTheme.colors.dangerous
|
||||
textColor = ZcashTheme.colors.historyRedColor
|
||||
textStyle = ZcashTheme.extendedTypography.transactionItemStyles.titleFailed
|
||||
}
|
||||
}
|
||||
|
@ -338,19 +340,31 @@ private fun HistoryItemCollapsedMainPart(
|
|||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
val valueTextStyle: TextStyle
|
||||
val valueTextColor: Color
|
||||
if (transaction.overview.getExtendedState().isFailed()) {
|
||||
valueTextStyle = ZcashTheme.extendedTypography.transactionItemStyles.contentLineThrough
|
||||
valueTextColor = ZcashTheme.colors.historyRedColor
|
||||
} else {
|
||||
valueTextStyle = ZcashTheme.extendedTypography.transactionItemStyles.valueFirstPart
|
||||
valueTextColor =
|
||||
if (transaction.overview.isSentTransaction) {
|
||||
ZcashTheme.colors.historyRedColor
|
||||
} else {
|
||||
ZcashTheme.colors.textCommon
|
||||
}
|
||||
}
|
||||
|
||||
// TODO [#1047]: Representing Zatoshi amount
|
||||
// TODO [#1047]: https://github.com/Electric-Coin-Company/zashi-android/issues/1047
|
||||
StyledBalance(
|
||||
balanceString = transaction.overview.netValue.toZecString(),
|
||||
textStyles =
|
||||
Pair(
|
||||
first = ZcashTheme.extendedTypography.transactionItemStyles.valueFirstPart,
|
||||
first = valueTextStyle,
|
||||
second = ZcashTheme.extendedTypography.transactionItemStyles.valueSecondPart
|
||||
),
|
||||
textColor =
|
||||
if (transaction.overview.isSentTransaction) {
|
||||
ZcashTheme.colors.historySendColor
|
||||
} else {
|
||||
ZcashTheme.colors.textCommon
|
||||
},
|
||||
textColor = valueTextColor,
|
||||
prefix =
|
||||
if (transaction.overview.isSentTransaction) {
|
||||
stringResource(id = R.string.account_history_item_sent_prefix)
|
||||
|
@ -446,7 +460,7 @@ private fun HistoryItemExpandedAddressPart(
|
|||
text = stringResource(id = R.string.account_history_item_tap_to_copy),
|
||||
style = ZcashTheme.extendedTypography.transactionItemStyles.content,
|
||||
color = ZcashTheme.colors.textDescription,
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_trx_copy),
|
||||
iconVector = ImageVector.vectorResource(R.drawable.ic_trx_copy),
|
||||
modifier =
|
||||
Modifier
|
||||
.clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner))
|
||||
|
@ -488,7 +502,11 @@ private fun HistoryItemExpandedPart(
|
|||
) {
|
||||
Column(modifier = modifier) {
|
||||
if (transaction.messages.containsValidMemo()) {
|
||||
HistoryItemMessagePart(transaction.messages!!.toPersistentList(), onAction)
|
||||
HistoryItemMessagePart(
|
||||
messages = transaction.messages!!.toPersistentList(),
|
||||
state = transaction.overview.getExtendedState(),
|
||||
onAction = onAction
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(ZcashTheme.dimens.spacingDefault))
|
||||
}
|
||||
|
@ -500,11 +518,15 @@ private fun HistoryItemExpandedPart(
|
|||
|
||||
Spacer(modifier = (Modifier.height(ZcashTheme.dimens.spacingDefault)))
|
||||
|
||||
HistoryItemTransactionFeePart(fee = transaction.overview.feePaid)
|
||||
|
||||
Spacer(modifier = (Modifier.height(ZcashTheme.dimens.spacingLarge)))
|
||||
|
||||
TextWithIcon(
|
||||
text = stringResource(id = R.string.account_history_item_collapse_transaction),
|
||||
style = ZcashTheme.extendedTypography.transactionItemStyles.contentUnderline,
|
||||
color = ZcashTheme.colors.textDescription,
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.ic_trx_collapse),
|
||||
iconVector = ImageVector.vectorResource(id = R.drawable.ic_trx_collapse),
|
||||
modifier =
|
||||
Modifier
|
||||
.clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner))
|
||||
|
@ -567,7 +589,7 @@ private fun HistoryItemTransactionIdPart(
|
|||
text = stringResource(id = R.string.account_history_item_tap_to_copy),
|
||||
style = ZcashTheme.extendedTypography.transactionItemStyles.content,
|
||||
color = ZcashTheme.colors.textDescription,
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_trx_copy),
|
||||
iconVector = ImageVector.vectorResource(R.drawable.ic_trx_copy),
|
||||
modifier =
|
||||
Modifier
|
||||
.clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner))
|
||||
|
@ -618,13 +640,66 @@ private fun HistoryItemTransactionIdPart(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun HistoryItemMessagePart(
|
||||
messages: ImmutableList<String>,
|
||||
onAction: (TrxItemAction) -> Unit,
|
||||
private fun HistoryItemTransactionFeePart(
|
||||
fee: Zatoshi?,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.account_history_item_transaction_fee),
|
||||
style = ZcashTheme.extendedTypography.transactionItemStyles.content,
|
||||
color = ZcashTheme.colors.textDescription,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(ZcashTheme.dimens.spacingSmall))
|
||||
|
||||
if (fee == null) {
|
||||
Text(
|
||||
text =
|
||||
stringResource(
|
||||
id = R.string.account_history_item_transaction_fee_typical,
|
||||
Zatoshi(DEFAULT_LESS_THAN_FEE).toZecString()
|
||||
),
|
||||
style = ZcashTheme.extendedTypography.transactionItemStyles.feeFirstPart,
|
||||
color = ZcashTheme.colors.textDescription,
|
||||
)
|
||||
} else {
|
||||
// TODO [#1047]: Representing Zatoshi amount
|
||||
// TODO [#1047]: https://github.com/Electric-Coin-Company/zashi-android/issues/1047
|
||||
StyledBalance(
|
||||
balanceString = fee.toZecString(),
|
||||
textStyles =
|
||||
Pair(
|
||||
first = ZcashTheme.extendedTypography.transactionItemStyles.feeFirstPart,
|
||||
second = ZcashTheme.extendedTypography.transactionItemStyles.feeSecondPart
|
||||
),
|
||||
textColor = ZcashTheme.colors.textDescription
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HistoryItemMessagePart(
|
||||
messages: ImmutableList<String>,
|
||||
state: TransactionExtendedState,
|
||||
onAction: (TrxItemAction) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
// TODO [#1315]: Proper more messages in transaction displaying
|
||||
// TODO [#1315]: https://github.com/Electric-Coin-Company/zashi-android/issues/1315
|
||||
val composedMessage = messages.joinToString(separator = "\n\n")
|
||||
|
||||
val textStyle: TextStyle
|
||||
val textColor: Color
|
||||
if (state.isFailed()) {
|
||||
textStyle = ZcashTheme.extendedTypography.transactionItemStyles.contentLineThrough
|
||||
textColor = ZcashTheme.colors.historyRedColor
|
||||
} else {
|
||||
textStyle = ZcashTheme.extendedTypography.transactionItemStyles.content
|
||||
textColor = ZcashTheme.colors.textCommon
|
||||
}
|
||||
|
||||
Column(modifier = modifier.then(Modifier.fillMaxWidth())) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.account_history_item_message),
|
||||
|
@ -642,8 +717,8 @@ private fun HistoryItemMessagePart(
|
|||
) {
|
||||
Text(
|
||||
text = composedMessage,
|
||||
style = ZcashTheme.extendedTypography.transactionItemStyles.content,
|
||||
color = ZcashTheme.colors.textCommon,
|
||||
style = textStyle,
|
||||
color = textColor,
|
||||
modifier = Modifier.padding(all = ZcashTheme.dimens.spacingMid)
|
||||
)
|
||||
}
|
||||
|
@ -654,7 +729,7 @@ private fun HistoryItemMessagePart(
|
|||
text = stringResource(id = R.string.account_history_item_tap_to_copy),
|
||||
style = ZcashTheme.extendedTypography.transactionItemStyles.content,
|
||||
color = ZcashTheme.colors.textDescription,
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_trx_copy),
|
||||
iconVector = ImageVector.vectorResource(R.drawable.ic_trx_copy),
|
||||
modifier =
|
||||
Modifier
|
||||
.clip(RoundedCornerShape(ZcashTheme.dimens.regularRippleEffectCorner))
|
||||
|
@ -683,7 +758,9 @@ internal enum class TransactionExtendedState {
|
|||
SEND_FAILED,
|
||||
RECEIVED,
|
||||
RECEIVING,
|
||||
RECEIVE_FAILED,
|
||||
RECEIVE_FAILED;
|
||||
|
||||
fun isFailed(): Boolean = this == SEND_FAILED || this == RECEIVE_FAILED
|
||||
}
|
||||
|
||||
private fun TransactionOverview.getExtendedState(): TransactionExtendedState {
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
<string name="account_history_item_message">Message</string>
|
||||
<string name="account_history_item_collapse_transaction">Collapse transaction</string>
|
||||
<string name="account_history_item_transaction_id">Transaction ID</string>
|
||||
<string name="account_history_item_transaction_fee">Transaction Fee</string>
|
||||
<string name="account_history_item_transaction_fee_typical">Typical Fee < <xliff:g id="fee_amount"
|
||||
example="0.001">%1$s</xliff:g></string>
|
||||
|
||||
<string name="account_history_memo_clipboard_tag">Transaction message</string>
|
||||
<string name="account_history_id_clipboard_tag">Transaction ID</string>
|
||||
|
|
Loading…
Reference in New Issue