Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-10 13:08:08 +03:00
parent f19c2a9fd5
commit ece1122e14
4 changed files with 81 additions and 38 deletions

View file

@ -71,7 +71,10 @@ internal enum class TransactionStateType {
@Immutable
internal sealed interface TransactionDetailUM {
data object Loading : TransactionDetailUM
data class Content(val card: TextReference) : TransactionDetailUM
data class Content(
val cardNumber: TextReference?,
val cardName: TextReference?,
) : TransactionDetailUM
data class Error(val onRefreshClick: () -> Unit) : TransactionDetailUM
}

View file

@ -297,19 +297,18 @@ internal object TangemPayTxHistoryDetailsConverterV2 :
return when (transactionLoadState) {
TransactionLoadState.Loading -> TransactionDetailUM.Loading
TransactionLoadState.Error -> TransactionDetailUM.Error(onRefreshClick = onCardRefreshClick)
TransactionLoadState.Loaded -> spend.extractCardValue()?.let(TransactionDetailUM::Content)
TransactionLoadState.Loaded -> spend.extractCardDetail()
}
}
private fun TangemPayTxHistoryItem.Spend.extractCardValue(): TextReference? {
private fun TangemPayTxHistoryItem.Spend.extractCardDetail(): TransactionDetailUM.Content? {
val name = cardName?.takeIf { it.isNotEmpty() }
val last4 = cardNumberLast4?.takeIf { it.isNotEmpty() }
return when {
name != null && last4 != null -> stringReference("$name *$last4")
last4 != null -> stringReference("*$last4")
name != null -> stringReference(name)
else -> null
}
if (name == null && last4 == null) return null
return TransactionDetailUM.Content(
cardNumber = last4?.let { stringReference("*$it") },
cardName = name?.let(::stringReference),
)
}
private fun Input.extractButtonState(): ButtonState {

View file

@ -231,62 +231,58 @@ private fun TransactionDetailsBlock(state: TangemPayTxHistoryDetailsUMV2, modifi
when (val detail = state.detail) {
null -> Unit
TransactionDetailUM.Loading -> CardRowShimmer()
is TransactionDetailUM.Content -> CardRow(value = detail.card)
is TransactionDetailUM.Content -> CardRow(content = detail)
is TransactionDetailUM.Error -> CardRowError(onRefreshClick = detail.onRefreshClick)
}
TangemRow(
divider = state.mcc != null,
contentLead = TangemRowContentLead.Start,
contentLead = TangemRowContentLead.End,
titleSlot = {
TangemRowText(
text = resourceReference(R.string.tangem_pay_transaction_details_category),
role = TangemRowTextRole.Title,
)
},
valueSlot = {
TangemRowText(
text = state.transactionCategory,
role = TangemRowTextRole.Value,
)
},
valueSlot = { DetailRowValue(text = state.transactionCategory) },
)
if (state.mcc != null) {
TangemRow(
contentLead = TangemRowContentLead.Start,
contentLead = TangemRowContentLead.End,
titleSlot = {
TangemRowText(
text = resourceReference(R.string.tangem_pay_transaction_details_mcc),
role = TangemRowTextRole.Title,
)
},
valueSlot = {
TangemRowText(
text = state.mcc,
role = TangemRowTextRole.Value,
)
},
valueSlot = { DetailRowValue(text = state.mcc) },
)
}
}
}
@Composable
private fun CardRow(value: TextReference, modifier: Modifier = Modifier) {
private fun CardRow(content: TransactionDetailUM.Content, modifier: Modifier = Modifier) {
val cardNumber = content.cardNumber
val cardName = content.cardName
TangemRow(
modifier = modifier,
divider = true,
contentLead = TangemRowContentLead.Start,
contentLead = TangemRowContentLead.End,
titleSlot = {
TangemRowText(
text = resourceReference(R.string.tangempay_common_card),
role = TangemRowTextRole.Title,
)
},
valueSlot = {
TangemRowText(
text = value,
role = TangemRowTextRole.Value,
)
valueSlot = if (cardNumber != null) {
{ DetailRowValue(text = cardNumber) }
} else {
null
},
subvalueSlot = if (cardName != null) {
{ DetailRowSubvalue(text = cardName) }
} else {
null
},
)
}
@ -296,7 +292,7 @@ private fun CardRowShimmer(modifier: Modifier = Modifier) {
TangemRow(
modifier = modifier,
divider = true,
contentLead = TangemRowContentLead.Start,
contentLead = TangemRowContentLead.End,
titleSlot = {
TangemShimmer(style = TangemTheme.typography3.body.medium)
},
@ -308,7 +304,7 @@ private fun CardRowError(onRefreshClick: () -> Unit, modifier: Modifier = Modifi
TangemRow(
modifier = modifier,
divider = true,
contentLead = TangemRowContentLead.Start,
contentLead = TangemRowContentLead.End,
verticalAlignment = TangemRowVerticalAlignment.Center,
titleSlot = {
TangemRowText(
@ -343,6 +339,32 @@ private fun CardRowError(onRefreshClick: () -> Unit, modifier: Modifier = Modifi
)
}
@Composable
private fun DetailRowValue(text: TextReference, modifier: Modifier = Modifier) {
Text(
modifier = modifier,
text = text.resolveReference(),
color = TangemTheme.colors3.text.secondary,
style = TangemTheme.typography3.body.medium,
textAlign = TextAlign.End,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
@Composable
private fun DetailRowSubvalue(text: TextReference, modifier: Modifier = Modifier) {
Text(
modifier = modifier,
text = text.resolveReference(),
color = TangemTheme.colors3.text.secondary,
style = TangemTheme.typography3.caption.medium,
textAlign = TextAlign.End,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
@Preview(device = Devices.PIXEL_7_PRO)
@Preview(device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@ -363,7 +385,10 @@ private class TangemPayTxHistoryDetailsUMProviderV2 :
subtitle = stringReference("12 June 2026, 12:40"),
iconState = TangemIconUM.Icon(iconRes = R.drawable.ic_category_24),
transactionTitle = stringReference("Starbucks"),
detail = TransactionDetailUM.Content(stringReference("Basic card *9092")),
detail = TransactionDetailUM.Content(
cardNumber = stringReference("*9092"),
cardName = stringReference("Basic card"),
),
transactionCategory = stringReference("Food and drinks"),
mcc = stringReference("5814"),
transactionAmount = "-$5.86",
@ -385,7 +410,10 @@ private class TangemPayTxHistoryDetailsUMProviderV2 :
subtitle = stringReference("12 June 2026, 12:40"),
iconState = TangemIconUM.Icon(iconRes = R.drawable.ic_category_24),
transactionTitle = stringReference("NuCaloric"),
detail = TransactionDetailUM.Content(stringReference("Basic card *9092")),
detail = TransactionDetailUM.Content(
cardNumber = stringReference("*9092"),
cardName = stringReference("Basic card"),
),
transactionCategory = stringReference("Groceries"),
mcc = stringReference("0000"),
transactionAmount = "-$820.52",
@ -408,7 +436,10 @@ private class TangemPayTxHistoryDetailsUMProviderV2 :
subtitle = stringReference("12 June 2026, 12:40"),
iconState = TangemIconUM.Icon(iconRes = R.drawable.ic_category_24),
transactionTitle = stringReference("Starbucks"),
detail = TransactionDetailUM.Content(stringReference("Basic card *9092")),
detail = TransactionDetailUM.Content(
cardNumber = stringReference("*9092"),
cardName = stringReference("Basic card"),
),
transactionCategory = stringReference("Food and drinks"),
mcc = null,
transactionAmount = "-$5.86",

View file

@ -86,7 +86,12 @@ internal class TangemPayTxHistoryDetailsModelTest {
// Assert
assertThat(model.uiState.value.redesign.detail)
.isEqualTo(TransactionDetailUM.Content(stringReference("Loaded card *4321")))
.isEqualTo(
TransactionDetailUM.Content(
cardNumber = stringReference("*4321"),
cardName = stringReference("Loaded card"),
),
)
model.onDestroy()
}
@ -140,7 +145,12 @@ internal class TangemPayTxHistoryDetailsModelTest {
// Assert
assertThat(model.uiState.value.redesign.detail)
.isEqualTo(TransactionDetailUM.Content(stringReference("Loaded card *4321")))
.isEqualTo(
TransactionDetailUM.Content(
cardNumber = stringReference("*4321"),
cardName = stringReference("Loaded card"),
),
)
coVerify(exactly = 2) { repository.getTransaction(any(), any()) }
model.onDestroy()
}