Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-30 20:40:06 +05:00
parent 2ea3f2ca9d
commit 211507774f
11 changed files with 247 additions and 113 deletions

View file

@ -1326,6 +1326,7 @@
<string name="tangem_pay_explore_transaction">Explore transaction</string>
<string name="tangem_pay_fee_subtitle">Service fees</string>
<string name="tangem_pay_fee_title">Fee</string>
<string name="tangem_pay_get_help">Get Help</string>
<string name="tangem_pay_status_completed">Completed</string>
<string name="tangem_pay_status_declined">Declined</string>
<string name="tangem_pay_status_pending">Pending</string>

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:autoMirrored="true"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="#1E1E1E"
android:pathData="M10,2C14.165,2 17.587,5.183 17.965,9.25C17.988,9.497 18,9.747 18,10C18,10.253 17.988,10.503 17.965,10.75C17.587,14.817 14.165,18 10,18C5.835,18 2.413,14.817 2.035,10.75C2.012,10.503 2,10.253 2,10C2,9.747 2.012,9.497 2.035,9.25C2.413,5.183 5.835,2 10,2ZM3.543,10.75C3.838,13.319 5.631,15.431 8.026,16.193C7.196,14.975 6.622,13.01 6.518,10.75H3.543ZM13.482,10.75C13.378,13.011 12.803,14.975 11.973,16.193C14.368,15.431 16.162,13.319 16.457,10.75H13.482ZM8.02,10.75C8.101,12.335 8.433,13.701 8.885,14.669C9.463,15.908 9.962,16 10,16C10.038,16 10.537,15.908 11.115,14.669C11.567,13.701 11.899,12.335 11.981,10.75H8.02ZM8.026,3.806C5.631,4.568 3.838,6.681 3.543,9.25H6.518C6.622,6.989 7.196,5.024 8.026,3.806ZM10,4C9.962,4 9.463,4.092 8.885,5.331C8.433,6.299 8.101,7.665 8.02,9.25H11.981C11.899,7.665 11.567,6.299 11.115,5.331C10.537,4.092 10.038,4 10,4ZM11.973,3.806C12.804,5.024 13.378,6.989 13.482,9.25H16.457C16.162,6.681 14.368,4.568 11.973,3.806Z" />
</vector>

View file

@ -10,14 +10,16 @@ import java.util.Currency
internal class TangemPayTxHistoryItemConverter(moshi: Moshi) :
Converter<TangemPayTxHistoryResponse.Transaction, TangemPayTxHistoryItem?> {
private val spendAdapter = moshi.adapter(TangemPayTxHistoryResponse.Spend::class.java)
private val paymentAdapter = moshi.adapter(TangemPayTxHistoryResponse.Payment::class.java)
private val feeAdapter = moshi.adapter(TangemPayTxHistoryResponse.Fee::class.java)
private val spendAdapter by lazy { moshi.adapter(TangemPayTxHistoryResponse.Spend::class.java) }
private val paymentAdapter by lazy { moshi.adapter(TangemPayTxHistoryResponse.Payment::class.java) }
private val feeAdapter by lazy { moshi.adapter(TangemPayTxHistoryResponse.Fee::class.java) }
private val collateralAdapter by lazy { moshi.adapter(TangemPayTxHistoryResponse.Collateral::class.java) }
override fun convert(value: TangemPayTxHistoryResponse.Transaction): TangemPayTxHistoryItem? {
return value.spend?.let { convertSpend(id = value.id, spend = it) }
?: value.payment?.let { convertPayment(id = value.id, payment = it) }
?: value.fee?.let { convertFee(id = value.id, fee = it) }
?: value.collateral?.let { convertCollateral(id = value.id, collateral = it) }
?: run {
Timber.wtf("unknown type of transaction: $value")
null
@ -63,4 +65,22 @@ internal class TangemPayTxHistoryItemConverter(moshi: Moshi) :
amount = fee.amount,
)
}
private fun convertCollateral(
id: String,
collateral: TangemPayTxHistoryResponse.Collateral,
): TangemPayTxHistoryItem.Collateral? {
val date = collateral.postedAt ?: return run {
Timber.e("Collateral transaction postedAt is null: $collateral")
return@run null
}
return TangemPayTxHistoryItem.Collateral(
id = id,
jsonRepresentation = collateralAdapter.toJson(collateral),
date = date,
currency = Currency.getInstance("usd"),
amount = collateral.amount,
transactionHash = collateral.transactionHash,
)
}
}

View file

@ -47,6 +47,16 @@ sealed class TangemPayTxHistoryItem {
override val currency: SerializedCurrency,
) : TangemPayTxHistoryItem()
@Serializable
data class Collateral(
override val id: String,
override val jsonRepresentation: String,
override val date: SerializedDateTime,
override val amount: SerializedBigDecimal,
override val currency: SerializedCurrency,
val transactionHash: String,
) : TangemPayTxHistoryItem()
enum class Status {
PENDING,
RESERVED,

View file

@ -2,8 +2,11 @@ package com.tangem.features.tangempay.components.txHistory
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import com.tangem.core.ui.extensions.ImageReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.themedColor
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayTransactionState
import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
import com.tangem.features.tangempay.ui.tangemPayTxHistoryItems
@ -33,47 +36,47 @@ internal class PreviewTangemPayTxHistoryComponent(txHistoryUM: TangemPayTxHistor
id = "signiferumque",
onClick = {},
amount = "-4.99 USD",
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
time = "16:41",
title = stringReference("StarbucksStarbucksStarbucksStarbucks"),
subtitle = stringReference("Food&Drinks"),
iconUrl = null,
icon = ImageReference.Res(R.drawable.ic_category_24),
),
),
TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
transaction = TangemPayTransactionState.Content.Payment(
id = "signiferumque",
amount = "-126.20 USD",
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
time = "12:04",
onClick = {},
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
isIncome = false,
icon = ImageReference.Res(R.drawable.ic_arrow_up_24),
),
),
TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
transaction = TangemPayTransactionState.Content.Payment(
id = "signiferumque",
amount = "+126.20 USD",
amountColor = { TangemTheme.colors.text.accent },
amountColor = themedColor { TangemTheme.colors.text.accent },
time = "12:04",
onClick = {},
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
isIncome = true,
icon = ImageReference.Res(R.drawable.ic_arrow_down_24),
),
),
TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
transaction = TangemPayTransactionState.Content.Spend(
id = "signiferumque",
amount = "-126.20 USD",
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
time = "12:04",
onClick = {},
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
iconUrl = null,
icon = ImageReference.Res(R.drawable.ic_category_24),
),
),
TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle(title = "Yesterday", itemKey = "Yesterday"),
@ -81,96 +84,96 @@ internal class PreviewTangemPayTxHistoryComponent(txHistoryUM: TangemPayTxHistor
transaction = TangemPayTransactionState.Content.Spend(
id = "signiferumque",
amount = "-4.99 USD",
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
time = "21:41",
onClick = {},
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
iconUrl = null,
icon = ImageReference.Res(R.drawable.ic_category_24),
),
),
TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
transaction = TangemPayTransactionState.Content.Spend(
id = "signiferumque",
amount = "-126.20 USD",
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
time = "10:04",
onClick = {},
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
iconUrl = null,
icon = ImageReference.Res(R.drawable.ic_category_24),
),
),
TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
transaction = TangemPayTransactionState.Content.Spend(
id = "signiferumque",
amount = "-4.99 USD",
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
time = "19:41",
onClick = {},
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
iconUrl = null,
icon = ImageReference.Res(R.drawable.ic_category_24),
),
),
TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
transaction = TangemPayTransactionState.Content.Spend(
id = "signiferumque",
amount = "-126.20 USD",
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
time = "18:04",
onClick = {},
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
iconUrl = null,
icon = ImageReference.Res(R.drawable.ic_category_24),
),
),
TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
transaction = TangemPayTransactionState.Content.Spend(
id = "signiferumque",
amount = "-4.99 USD",
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
time = "17:41",
onClick = {},
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
iconUrl = null,
icon = ImageReference.Res(R.drawable.ic_category_24),
),
),
TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
transaction = TangemPayTransactionState.Content.Spend(
id = "signiferumque",
amount = "-126.20 USD",
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
time = "16:04",
onClick = {},
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
iconUrl = null,
icon = ImageReference.Res(R.drawable.ic_category_24),
),
),
TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
transaction = TangemPayTransactionState.Content.Spend(
id = "signiferumque",
amount = "-4.99 USD",
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
time = "15:41",
onClick = {},
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
iconUrl = null,
icon = ImageReference.Res(R.drawable.ic_category_24),
),
),
TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
transaction = TangemPayTransactionState.Content.Spend(
id = "signiferumque",
amount = "-126.20 USD",
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
time = "14:04",
onClick = {},
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
iconUrl = null,
icon = ImageReference.Res(R.drawable.ic_category_24),
),
),
),

View file

@ -1,7 +1,7 @@
package com.tangem.features.tangempay.entity
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import com.tangem.core.ui.extensions.ColorReference
import com.tangem.core.ui.extensions.ImageReference
import com.tangem.core.ui.extensions.TextReference
internal sealed interface TangemPayTransactionState {
@ -14,40 +14,53 @@ internal sealed interface TangemPayTransactionState {
val onClick: () -> Unit
val amount: String
val amountColor: @Composable (() -> Color)
val amountColor: ColorReference
val title: TextReference
val subtitle: TextReference
val icon: ImageReference
val time: String
data class Spend(
override val id: String,
override val onClick: () -> Unit,
override val amount: String,
override val amountColor: @Composable (() -> Color),
override val amountColor: ColorReference,
override val title: TextReference,
override val subtitle: TextReference,
override val icon: ImageReference,
override val time: String,
val iconUrl: String?,
) : Content
data class Payment(
override val id: String,
override val onClick: () -> Unit,
override val amount: String,
override val amountColor: @Composable (() -> Color),
override val amountColor: ColorReference,
override val title: TextReference,
override val subtitle: TextReference,
override val icon: ImageReference,
override val time: String,
val isIncome: Boolean,
) : Content
data class Fee(
override val id: String,
override val onClick: () -> Unit,
override val amount: String,
override val amountColor: @Composable (() -> Color),
override val amountColor: ColorReference,
override val title: TextReference,
override val subtitle: TextReference,
override val icon: ImageReference,
override val time: String,
) : Content
data class Collateral(
override val id: String,
override val onClick: () -> Unit,
override val amount: String,
override val amountColor: ColorReference,
override val title: TextReference,
override val subtitle: TextReference,
override val icon: ImageReference,
override val time: String,
) : Content
}

View file

@ -5,6 +5,7 @@ import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.ColorReference
import com.tangem.core.ui.extensions.ImageReference
import com.tangem.core.ui.extensions.TextReference
import kotlinx.collections.immutable.ImmutableList
internal data class TangemPayTxHistoryDetailsUM(
val title: TextReference,
@ -15,9 +16,9 @@ internal data class TangemPayTxHistoryDetailsUM(
val transactionAmountColor: ColorReference,
val labelState: LabelUM?,
val notification: NotificationConfig?,
val buttonState: ButtonState,
val buttons: ImmutableList<ButtonState>,
val dismiss: () -> Unit,
) {
data class ButtonState(val text: TextReference, val onClick: () -> Unit)
data class ButtonState(val text: TextReference, val onClick: () -> Unit, val startIcon: ImageReference.Res? = null)
}

View file

@ -11,9 +11,12 @@ import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM.ButtonState
import com.tangem.utils.StringsSigns
import com.tangem.utils.converter.Converter
import com.tangem.utils.extensions.isPositive
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
internal object TangemPayTxHistoryDetailsConverter :
Converter<TangemPayTxHistoryDetailsConverter.Input, TangemPayTxHistoryDetailsUM> {
@ -30,7 +33,7 @@ internal object TangemPayTxHistoryDetailsConverter :
transactionAmountColor = value.item.extractAmountColor(),
labelState = value.item.extractLabel(),
notification = value.item.extractNotification(),
buttonState = value.extractButtonState(),
buttons = value.extractButtonsState(),
dismiss = value.onDismiss,
)
}
@ -44,6 +47,7 @@ internal object TangemPayTxHistoryDetailsConverter :
private fun TangemPayTxHistoryItem.extractIcon(): ImageReference {
return when (this) {
is TangemPayTxHistoryItem.Collateral -> ImageReference.Res(R.drawable.ic_arrow_down_24)
is TangemPayTxHistoryItem.Fee -> ImageReference.Res(R.drawable.ic_percent_24)
is TangemPayTxHistoryItem.Payment -> {
if (this.amount.isPositive()) {
@ -72,6 +76,7 @@ internal object TangemPayTxHistoryDetailsConverter :
} else {
resourceReference(R.string.tangem_pay_withdrawal)
}
is TangemPayTxHistoryItem.Collateral -> resourceReference(R.string.tangem_pay_deposit)
}
}
@ -80,6 +85,7 @@ internal object TangemPayTxHistoryDetailsConverter :
is TangemPayTxHistoryItem.Fee -> resourceReference(R.string.tangem_pay_fee_subtitle)
is TangemPayTxHistoryItem.Payment -> resourceReference(R.string.common_transfer)
is TangemPayTxHistoryItem.Spend -> stringReference(this.enrichedMerchantCategory ?: this.merchantCategory)
is TangemPayTxHistoryItem.Collateral -> resourceReference(R.string.common_transfer)
}
}
@ -96,7 +102,9 @@ internal object TangemPayTxHistoryDetailsConverter :
}
StringsSigns.MINUS + amount
}
is TangemPayTxHistoryItem.Payment -> {
is TangemPayTxHistoryItem.Payment,
is TangemPayTxHistoryItem.Collateral,
-> {
val amount = this.amount.format {
fiat(
fiatCurrencyCode = this@extractAmount.currency.currencyCode,
@ -124,6 +132,7 @@ internal object TangemPayTxHistoryDetailsConverter :
TangemTheme.colors.text.primary1
}
}
is TangemPayTxHistoryItem.Collateral -> themedColor { TangemTheme.colors.text.accent }
}
}
@ -131,6 +140,7 @@ internal object TangemPayTxHistoryDetailsConverter :
return when (this) {
is TangemPayTxHistoryItem.Fee,
is TangemPayTxHistoryItem.Payment,
is TangemPayTxHistoryItem.Collateral,
-> null
is TangemPayTxHistoryItem.Spend -> when (this.status) {
TangemPayTxHistoryItem.Status.COMPLETED -> LabelUM(
@ -156,6 +166,7 @@ internal object TangemPayTxHistoryDetailsConverter :
private fun TangemPayTxHistoryItem.extractNotification(): NotificationConfig? {
return when (this) {
is TangemPayTxHistoryItem.Payment -> null
is TangemPayTxHistoryItem.Collateral -> null
is TangemPayTxHistoryItem.Fee -> NotificationConfig(
title = resourceReference(R.string.tangem_pay_transaction_fee_notification_text),
subtitle = TextReference.EMPTY,
@ -176,19 +187,36 @@ internal object TangemPayTxHistoryDetailsConverter :
}
}
private fun Input.extractButtonState(): TangemPayTxHistoryDetailsUM.ButtonState {
private fun Input.extractButtonsState(): ImmutableList<ButtonState> {
return when (this.item) {
is TangemPayTxHistoryItem.Fee -> TangemPayTxHistoryDetailsUM.ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = this.onDisputeClick,
is TangemPayTxHistoryItem.Fee -> persistentListOf(
ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = this.onDisputeClick,
),
)
is TangemPayTxHistoryItem.Spend -> TangemPayTxHistoryDetailsUM.ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = this.onDisputeClick,
is TangemPayTxHistoryItem.Spend -> persistentListOf(
ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = this.onDisputeClick,
),
)
is TangemPayTxHistoryItem.Payment -> TangemPayTxHistoryDetailsUM.ButtonState(
text = resourceReference(R.string.tangem_pay_explore_transaction),
onClick = { this.onExplorerClick(this.item.transactionHash) },
is TangemPayTxHistoryItem.Payment -> persistentListOf(
ButtonState(
text = resourceReference(R.string.tangem_pay_explore_transaction),
onClick = { this.onExplorerClick(this.item.transactionHash) },
),
)
is TangemPayTxHistoryItem.Collateral -> persistentListOf(
ButtonState(
text = resourceReference(R.string.tangem_pay_explore_transaction),
startIcon = ImageReference.Res(R.drawable.ic_explore_20),
onClick = { this.onExplorerClick(this.item.transactionHash) },
),
ButtonState(
text = resourceReference(R.string.tangem_pay_get_help),
onClick = this.onDisputeClick,
),
)
}
}

View file

@ -1,11 +1,15 @@
package com.tangem.features.tangempay.model.transformers
import com.tangem.core.ui.extensions.ImageReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.themedColor
import com.tangem.core.ui.format.bigdecimal.fiat
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayTransactionState
import com.tangem.features.tangempay.utils.TangemPayTxHistoryUiActions
import com.tangem.utils.StringsSigns
@ -22,6 +26,7 @@ internal class TangemPayTxHistoryItemsConverter(
is TangemPayTxHistoryItem.Spend -> convertSpend(spend = value)
is TangemPayTxHistoryItem.Payment -> convertPayment(payment = value)
is TangemPayTxHistoryItem.Fee -> convertFee(fee = value)
is TangemPayTxHistoryItem.Collateral -> convertCollateral(collateral = value)
}
}
@ -38,7 +43,7 @@ internal class TangemPayTxHistoryItemsConverter(
id = spend.id,
onClick = { txHistoryUiActions.onTransactionClick(spend) },
amount = amount,
amountColor = {
amountColor = themedColor {
when (spend.status) {
TangemPayTxHistoryItem.Status.DECLINED -> TangemTheme.colors.text.warning
else -> TangemTheme.colors.text.primary1
@ -47,14 +52,16 @@ internal class TangemPayTxHistoryItemsConverter(
title = stringReference(spend.enrichedMerchantName ?: spend.merchantName),
subtitle = stringReference(spend.enrichedMerchantCategory ?: spend.merchantCategory),
time = DateTimeFormatters.formatDate(localDate, DateTimeFormatters.timeFormatter),
iconUrl = spend.enrichedMerchantIconUrl,
icon = spend.enrichedMerchantIconUrl?.let(ImageReference::Url)
?: ImageReference.Res(R.drawable.ic_category_24),
)
}
private fun convertPayment(payment: TangemPayTxHistoryItem.Payment): TangemPayTransactionState.Content.Payment {
val isIncome = payment.amount.isPositive()
val amountPrefix = when {
payment.amount.isZero() -> ""
payment.amount.isPositive() -> StringsSigns.PLUS
isIncome -> StringsSigns.PLUS
else -> StringsSigns.MINUS
}
val amount = amountPrefix + payment.amount.format {
@ -65,17 +72,13 @@ internal class TangemPayTxHistoryItemsConverter(
id = payment.id,
onClick = { txHistoryUiActions.onTransactionClick(payment) },
amount = amount,
amountColor = {
if (payment.amount.isPositive()) {
TangemTheme.colors.text.accent
} else {
TangemTheme.colors.text.primary1
}
amountColor = themedColor {
if (payment.amount.isPositive()) TangemTheme.colors.text.accent else TangemTheme.colors.text.primary1
},
title = stringReference(title),
subtitle = stringReference("Transfers"),
time = DateTimeFormatters.formatDate(payment.date, DateTimeFormatters.timeFormatter),
isIncome = payment.amount.isPositive(),
icon = ImageReference.Res(if (isIncome) R.drawable.ic_arrow_down_24 else R.drawable.ic_arrow_up_24),
)
}
@ -87,10 +90,29 @@ internal class TangemPayTxHistoryItemsConverter(
id = fee.id,
onClick = { txHistoryUiActions.onTransactionClick(fee) },
amount = amount,
amountColor = { TangemTheme.colors.text.primary1 },
amountColor = themedColor { TangemTheme.colors.text.primary1 },
title = stringReference("Fee"),
subtitle = stringReference("Service fees"),
icon = ImageReference.Res(R.drawable.ic_percent_24),
time = DateTimeFormatters.formatDate(fee.date, DateTimeFormatters.timeFormatter),
)
}
private fun convertCollateral(
collateral: TangemPayTxHistoryItem.Collateral,
): TangemPayTransactionState.Content.Collateral {
val amount = StringsSigns.MINUS + collateral.amount.format {
fiat(fiatCurrencyCode = collateral.currency.currencyCode, fiatCurrencySymbol = collateral.currency.symbol)
}
return TangemPayTransactionState.Content.Collateral(
id = collateral.id,
onClick = { txHistoryUiActions.onTransactionClick(collateral) },
amount = amount,
amountColor = themedColor { TangemTheme.colors.text.accent },
title = resourceReference(R.string.tangem_pay_deposit),
subtitle = resourceReference(R.string.common_transfer),
icon = ImageReference.Res(R.drawable.ic_arrow_down_24),
time = DateTimeFormatters.formatDate(collateral.date, DateTimeFormatters.timeFormatter),
)
}
}

View file

@ -28,6 +28,7 @@ import com.tangem.core.ui.components.buttons.actions.ActionButton
import com.tangem.core.ui.components.list.InfiniteListHandler
import com.tangem.core.ui.components.transactions.TxHistoryGroupTitle
import com.tangem.core.ui.decorations.roundedShapeItemDecoration
import com.tangem.core.ui.extensions.ImageReference
import com.tangem.core.ui.extensions.orMaskWithStars
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringResourceSafe
@ -256,27 +257,14 @@ private fun TangemPayTransaction(
@Composable
private fun Icon(state: TangemPayTransactionState, modifier: Modifier = Modifier) {
when (state) {
is TangemPayTransactionState.Content.Spend -> {
if (state.iconUrl != null) {
RemoteIcon(modifier = modifier, url = state.iconUrl)
} else {
LocalStaticIcon(
modifier = modifier,
id = R.drawable.ic_category_24,
iconSize = TangemTheme.dimens.size20,
)
}
is TangemPayTransactionState.Content -> when (val iconReference = state.icon) {
is ImageReference.Url -> RemoteIcon(modifier = modifier, url = iconReference.url)
is ImageReference.Res -> LocalStaticIcon(
modifier = modifier,
id = iconReference.resId,
iconSize = TangemTheme.dimens.size20,
)
}
is TangemPayTransactionState.Content.Fee -> LocalStaticIcon(
modifier = modifier,
id = R.drawable.ic_percent_24,
iconSize = TangemTheme.dimens.size20,
)
is TangemPayTransactionState.Content.Payment -> LocalStaticIcon(
modifier = modifier,
id = if (state.isIncome) R.drawable.ic_arrow_down_24 else R.drawable.ic_arrow_up_24,
iconSize = TangemTheme.dimens.size20,
)
is TangemPayTransactionState.Loading -> CircleShimmer(modifier = modifier)
}
}
@ -330,7 +318,7 @@ private fun Amount(state: TangemPayTransactionState, isBalanceHidden: Boolean, m
text = state.amount.orMaskWithStars(isBalanceHidden),
modifier = modifier,
textAlign = TextAlign.End,
color = state.amountColor(),
color = state.amountColor.resolveReference(),
style = TangemTheme.typography.body2,
)
}

View file

@ -1,10 +1,7 @@
package com.tangem.features.tangempay.ui
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@ -14,7 +11,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEach
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.components.SecondaryButtonIconStart
import com.tangem.core.ui.components.SpacerH32
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
@ -25,16 +24,13 @@ import com.tangem.core.ui.components.label.entity.LabelStyle
import com.tangem.core.ui.components.label.entity.LabelUM
import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.ImageReference
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.themedColor
import com.tangem.core.ui.extensions.*
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@Composable
internal fun TangemPayTxHistoryDetailsContent(state: TangemPayTxHistoryDetailsUM) {
@ -93,19 +89,42 @@ internal fun TangemPayTxHistoryDetailsContent(state: TangemPayTxHistoryDetailsUM
iconTint = TangemTheme.colors.icon.secondary,
)
}
ButtonContainer(
ButtonsContainer(
modifier = Modifier
.padding(vertical = 16.dp)
.fillMaxWidth(),
buttonState = state.buttonState,
buttons = state.buttons,
)
}
}
}
@Composable
private fun ButtonContainer(buttonState: TangemPayTxHistoryDetailsUM.ButtonState, modifier: Modifier = Modifier) {
SecondaryButton(modifier = modifier, text = buttonState.text.resolveReference(), onClick = buttonState.onClick)
private fun ButtonsContainer(
buttons: ImmutableList<TangemPayTxHistoryDetailsUM.ButtonState>,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
buttons.fastForEach { buttonState ->
if (buttonState.startIcon != null) {
SecondaryButtonIconStart(
modifier = Modifier.fillMaxWidth(),
text = buttonState.text.resolveReference(),
iconResId = buttonState.startIcon.resId,
onClick = buttonState.onClick,
)
} else {
SecondaryButton(
modifier = Modifier.fillMaxWidth(),
text = buttonState.text.resolveReference(),
onClick = buttonState.onClick,
)
}
}
}
}
@Composable
@ -142,9 +161,11 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
icon = R.drawable.ic_clock_24,
),
notification = null,
buttonState = TangemPayTxHistoryDetailsUM.ButtonState(
text = stringReference("Dispute"),
onClick = {},
buttons = persistentListOf(
TangemPayTxHistoryDetailsUM.ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = {},
),
),
dismiss = {},
),
@ -164,9 +185,11 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
subtitle = TextReference.EMPTY,
iconResId = R.drawable.ic_token_info_24,
),
buttonState = TangemPayTxHistoryDetailsUM.ButtonState(
text = stringReference("Dispute"),
onClick = {},
buttons = persistentListOf(
TangemPayTxHistoryDetailsUM.ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = {},
),
),
dismiss = {},
),
@ -182,9 +205,11 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
style = LabelStyle.ACCENT,
),
notification = null,
buttonState = TangemPayTxHistoryDetailsUM.ButtonState(
text = stringReference("Dispute"),
onClick = {},
buttons = persistentListOf(
TangemPayTxHistoryDetailsUM.ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = {},
),
),
dismiss = {},
),
@ -201,9 +226,11 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
subtitle = TextReference.EMPTY,
iconResId = R.drawable.ic_token_info_24,
),
buttonState = TangemPayTxHistoryDetailsUM.ButtonState(
text = stringReference("Dispute"),
onClick = {},
buttons = persistentListOf(
TangemPayTxHistoryDetailsUM.ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = {},
),
),
dismiss = {},
),
@ -216,9 +243,11 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
transactionAmountColor = themedColor { TangemTheme.colors.text.accent },
labelState = null,
notification = null,
buttonState = TangemPayTxHistoryDetailsUM.ButtonState(
text = stringReference("Explore transaction"),
onClick = {},
buttons = persistentListOf(
TangemPayTxHistoryDetailsUM.ButtonState(
text = resourceReference(R.string.tangem_pay_explore_transaction),
onClick = {},
),
),
dismiss = {},
),
@ -231,9 +260,16 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 },
labelState = null,
notification = null,
buttonState = TangemPayTxHistoryDetailsUM.ButtonState(
text = stringReference("Explore transaction"),
onClick = {},
buttons = persistentListOf(
TangemPayTxHistoryDetailsUM.ButtonState(
text = resourceReference(R.string.tangem_pay_explore_transaction),
startIcon = ImageReference.Res(R.drawable.ic_explore_20),
onClick = {},
),
TangemPayTxHistoryDetailsUM.ButtonState(
text = resourceReference(R.string.tangem_pay_get_help),
onClick = {},
),
),
dismiss = {},
),