Updated on 2026-08-14
This commit is contained in:
parent
f6f3aabbfc
commit
cff379462f
12 changed files with 848 additions and 71 deletions
|
|
@ -7,5 +7,6 @@ internal class DefaultTangemPayFeatureToggles(
|
|||
private val featureTogglesManager: FeatureTogglesManager,
|
||||
) : TangemPayFeatureToggles {
|
||||
override val isRedesignEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15368_VISA_PAY_REDESIGN)
|
||||
get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15368_VISA_PAY_REDESIGN) &&
|
||||
featureTogglesManager.isFeatureEnabled(FeatureToggles.APP_REDESIGN_ENABLED)
|
||||
}
|
||||
|
|
@ -5,9 +5,12 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.res.LocalVisaRedesignEnabled
|
||||
import com.tangem.features.tangempay.components.TangemPayTransactionBottomSheetComponent
|
||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUiState
|
||||
import com.tangem.features.tangempay.model.TangemPayTxHistoryDetailsModel
|
||||
import com.tangem.features.tangempay.ui.TangemPayTxHistoryDetailsContent
|
||||
import com.tangem.features.tangempay.ui.TangemPayTxHistoryDetailsContentV2
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
|
@ -25,8 +28,15 @@ internal class TangemPayTxHistoryDetailsComponent @AssistedInject constructor(
|
|||
|
||||
@Composable
|
||||
override fun BottomSheet() {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
TangemPayTxHistoryDetailsContent(state = state)
|
||||
val states by model.uiState.collectAsStateWithLifecycle()
|
||||
when (val uiState = states.toUiState(isRedesignEnabled = LocalVisaRedesignEnabled.current)) {
|
||||
is TangemPayTxHistoryDetailsUiState.Legacy -> {
|
||||
TangemPayTxHistoryDetailsContent(state = uiState.state)
|
||||
}
|
||||
is TangemPayTxHistoryDetailsUiState.Redesign -> {
|
||||
TangemPayTxHistoryDetailsContentV2(state = uiState.state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package com.tangem.features.tangempay.entity
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.components.label.entity.LabelUM
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
import com.tangem.core.ui.extensions.ColorReference
|
||||
import com.tangem.core.ui.extensions.ImageReference
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
|
@ -28,6 +30,58 @@ internal data class TangemPayTxHistoryDetailsUM(
|
|||
val iconTint: ColorReference,
|
||||
val containerColor: ColorReference?,
|
||||
)
|
||||
}
|
||||
|
||||
data class ButtonState(val text: TextReference, val onClick: () -> Unit, val startIcon: ImageReference.Res? = null)
|
||||
internal data class ButtonState(
|
||||
val text: TextReference,
|
||||
val onClick: () -> Unit,
|
||||
val startIcon: ImageReference.Res? = null,
|
||||
)
|
||||
|
||||
internal data class TangemPayTxHistoryDetailsUMV2(
|
||||
val isBalanceHidden: Boolean,
|
||||
val title: TextReference,
|
||||
val subtitle: TextReference,
|
||||
val iconState: TangemIconUM,
|
||||
val transactionTitle: TextReference,
|
||||
val transactionCategory: TextReference,
|
||||
val mcc: TextReference?,
|
||||
val transactionAmount: String,
|
||||
val localTransactionText: String?,
|
||||
val label: TransactionLabelUM?,
|
||||
val buttonState: ButtonState,
|
||||
val dismiss: () -> Unit,
|
||||
)
|
||||
|
||||
internal data class TransactionLabelUM(
|
||||
val transactionStateType: TransactionStateType,
|
||||
val icon: TangemIconUM,
|
||||
val title: TextReference,
|
||||
val subtitle: TextReference? = null,
|
||||
)
|
||||
|
||||
internal enum class TransactionStateType {
|
||||
Completed,
|
||||
InProgress,
|
||||
Rejected,
|
||||
Reversed,
|
||||
}
|
||||
|
||||
@Immutable
|
||||
internal sealed interface TangemPayTxHistoryDetailsUiState {
|
||||
data class Legacy(val state: TangemPayTxHistoryDetailsUM) : TangemPayTxHistoryDetailsUiState
|
||||
data class Redesign(val state: TangemPayTxHistoryDetailsUMV2) : TangemPayTxHistoryDetailsUiState
|
||||
}
|
||||
|
||||
internal data class TangemPayTxHistoryDetailsUiStates(
|
||||
val legacy: TangemPayTxHistoryDetailsUM,
|
||||
val redesign: TangemPayTxHistoryDetailsUMV2,
|
||||
) {
|
||||
fun toUiState(isRedesignEnabled: Boolean): TangemPayTxHistoryDetailsUiState {
|
||||
return if (isRedesignEnabled) {
|
||||
TangemPayTxHistoryDetailsUiState.Redesign(redesign)
|
||||
} else {
|
||||
TangemPayTxHistoryDetailsUiState.Legacy(legacy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,8 @@ import com.tangem.core.ui.format.bigdecimal.getJavaCurrencyByCode
|
|||
import com.tangem.core.ui.format.bigdecimal.optionalDecimals
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.generated.icons.Icons
|
||||
import com.tangem.core.ui.res.generated.icons.ic_arrow_refresh_20
|
||||
import com.tangem.core.ui.test.TangemPayTestTags
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.TokenReceiveConfig
|
||||
|
|
@ -222,7 +224,7 @@ internal class TangemPayCardPageModel @Inject constructor(
|
|||
title = TextReference.Res(R.string.tangempay_card_details_reissue_card),
|
||||
onClick = ::onClickReissueCard,
|
||||
icon = TangemIconUM.Icon(
|
||||
iconRes = CoreUiR.drawable.ic_replace_20,
|
||||
imageVector = Icons.ic_arrow_refresh_20,
|
||||
tintReference = {
|
||||
TangemTheme.colors3.icon.primary
|
||||
},
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
|||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||
import com.tangem.features.tangempay.components.TangemPayTransactionBottomSheetComponent
|
||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUiStates
|
||||
import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryDetailsConverter
|
||||
import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryDetailsConverterV2
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -35,18 +36,8 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor(
|
|||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<TangemPayTransactionBottomSheetComponent.Params>()
|
||||
val uiState: StateFlow<TangemPayTxHistoryDetailsUM>
|
||||
field = MutableStateFlow(
|
||||
value = TangemPayTxHistoryDetailsConverter.convert(
|
||||
value = TangemPayTxHistoryDetailsConverter.Input(
|
||||
item = params.transaction,
|
||||
isBalanceHidden = params.isBalanceHidden,
|
||||
onExplorerClick = ::openExplorer,
|
||||
onDisputeClick = { dispute(customerId = params.customerId) },
|
||||
onDismiss = ::dismiss,
|
||||
),
|
||||
),
|
||||
)
|
||||
val uiState: StateFlow<TangemPayTxHistoryDetailsUiStates>
|
||||
field = MutableStateFlow(buildUiStates(isBalanceHidden = params.isBalanceHidden))
|
||||
|
||||
init {
|
||||
subscribeToBalanceHiding()
|
||||
|
|
@ -58,10 +49,32 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor(
|
|||
|
||||
private fun subscribeToBalanceHiding() {
|
||||
balanceHidingSettings.isBalanceHidden()
|
||||
.onEach { isBalanceHidden -> uiState.update { it.copy(isBalanceHidden = isBalanceHidden) } }
|
||||
.onEach { isBalanceHidden -> uiState.update { buildUiStates(isBalanceHidden) } }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun buildUiStates(isBalanceHidden: Boolean): TangemPayTxHistoryDetailsUiStates {
|
||||
val converterInput = TangemPayTxHistoryDetailsConverter.Input(
|
||||
item = params.transaction,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
onExplorerClick = ::openExplorer,
|
||||
onDisputeClick = { dispute(customerId = params.customerId) },
|
||||
onDismiss = ::dismiss,
|
||||
)
|
||||
return TangemPayTxHistoryDetailsUiStates(
|
||||
legacy = TangemPayTxHistoryDetailsConverter.convert(converterInput),
|
||||
redesign = TangemPayTxHistoryDetailsConverterV2.convert(
|
||||
value = TangemPayTxHistoryDetailsConverterV2.Input(
|
||||
item = converterInput.item,
|
||||
isBalanceHidden = converterInput.isBalanceHidden,
|
||||
onExplorerClick = converterInput.onExplorerClick,
|
||||
onDisputeClick = converterInput.onDisputeClick,
|
||||
onDismiss = converterInput.onDismiss,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun openExplorer(txHash: String?) {
|
||||
txHash?.let(urlOpener::openUrlExternalBrowser)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ 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.ButtonState
|
||||
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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,322 @@
|
|||
package com.tangem.features.tangempay.model.transformers
|
||||
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.core.ui.format.bigdecimal.price
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.generated.icons.*
|
||||
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.ButtonState
|
||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUMV2
|
||||
import com.tangem.features.tangempay.entity.TransactionLabelUM
|
||||
import com.tangem.features.tangempay.entity.TransactionStateType
|
||||
import com.tangem.utils.StringsSigns
|
||||
import com.tangem.utils.converter.Converter
|
||||
import com.tangem.utils.extensions.isPositive
|
||||
import com.tangem.utils.extensions.isZero
|
||||
|
||||
internal object TangemPayTxHistoryDetailsConverterV2 :
|
||||
Converter<TangemPayTxHistoryDetailsConverterV2.Input, TangemPayTxHistoryDetailsUMV2> {
|
||||
private val dateFormatter = DateTimeFormatters.getBestFormatterBySkeleton("MMM dd yyyy, HH:mm")
|
||||
|
||||
override fun convert(value: Input): TangemPayTxHistoryDetailsUMV2 {
|
||||
val transaction = value.item
|
||||
return TangemPayTxHistoryDetailsUMV2(
|
||||
isBalanceHidden = value.isBalanceHidden,
|
||||
title = transaction.extractBottomSheetTitle(),
|
||||
subtitle = transaction.extractDate(),
|
||||
iconState = transaction.extractIcon(),
|
||||
transactionTitle = transaction.extractTransactionTitle(),
|
||||
transactionCategory = transaction.extractTransactionCategory(),
|
||||
mcc = transaction.extractMcc(),
|
||||
transactionAmount = transaction.extractAmount(),
|
||||
localTransactionText = transaction.extractLocalAmount(),
|
||||
label = transaction.extractTransactionLabel(),
|
||||
buttonState = value.extractButtonState(),
|
||||
dismiss = value.onDismiss,
|
||||
)
|
||||
}
|
||||
|
||||
private fun TangemPayTxHistoryItem.extractDate(): TextReference {
|
||||
val date = DateTimeFormatters.formatDate(this.date, dateFormatter)
|
||||
return stringReference(date)
|
||||
}
|
||||
|
||||
private fun TangemPayTxHistoryItem.extractBottomSheetTitle(): TextReference {
|
||||
return when (this) {
|
||||
is TangemPayTxHistoryItem.Spend -> resourceReference(R.string.tangem_pay_purchase)
|
||||
is TangemPayTxHistoryItem.Payment -> resourceReference(R.string.tangem_pay_withdrawal)
|
||||
is TangemPayTxHistoryItem.Collateral -> when (this.type) {
|
||||
TangemPayTxHistoryItem.Type.Deposit -> resourceReference(R.string.tangem_pay_deposit)
|
||||
TangemPayTxHistoryItem.Type.Withdrawal -> resourceReference(R.string.tangem_pay_withdrawal)
|
||||
}
|
||||
is TangemPayTxHistoryItem.Fee -> resourceReference(R.string.tangem_pay_fee_title)
|
||||
}
|
||||
}
|
||||
|
||||
private fun TangemPayTxHistoryItem.extractIcon(): TangemIconUM {
|
||||
return when (this) {
|
||||
is TangemPayTxHistoryItem.Collateral -> when (this.type) {
|
||||
TangemPayTxHistoryItem.Type.Deposit -> TangemIconUM.Icon(
|
||||
imageVector = Icons.ic_arrow_down_24,
|
||||
tintReference = {
|
||||
TangemTheme.colors3.icon.secondary
|
||||
},
|
||||
)
|
||||
TangemPayTxHistoryItem.Type.Withdrawal -> TangemIconUM.Icon(
|
||||
imageVector = Icons.ic_arrow_up_24,
|
||||
tintReference = {
|
||||
TangemTheme.colors3.icon.secondary
|
||||
},
|
||||
)
|
||||
}
|
||||
is TangemPayTxHistoryItem.Fee -> {
|
||||
TangemIconUM.Icon(
|
||||
iconRes = R.drawable.ic_percent_24,
|
||||
tintReference = {
|
||||
TangemTheme.colors3.icon.secondary
|
||||
},
|
||||
)
|
||||
}
|
||||
is TangemPayTxHistoryItem.Payment -> TangemIconUM.Icon(
|
||||
imageVector = Icons.ic_arrow_up_24,
|
||||
tintReference = {
|
||||
TangemTheme.colors3.icon.secondary
|
||||
},
|
||||
)
|
||||
is TangemPayTxHistoryItem.Spend -> {
|
||||
val merchantIcon = this.enrichedMerchantIconUrl
|
||||
if (merchantIcon != null) {
|
||||
TangemIconUM.Url(merchantIcon, R.drawable.ic_category_24)
|
||||
} else {
|
||||
TangemIconUM.Icon(
|
||||
iconRes = R.drawable.ic_category_24,
|
||||
tintReference = {
|
||||
TangemTheme.colors3.icon.secondary
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TangemPayTxHistoryItem.extractTransactionTitle(): TextReference {
|
||||
return when (this) {
|
||||
is TangemPayTxHistoryItem.Spend -> stringReference(this.enrichedMerchantName ?: this.merchantName)
|
||||
is TangemPayTxHistoryItem.Payment -> resourceReference(R.string.common_transfer)
|
||||
is TangemPayTxHistoryItem.Collateral -> resourceReference(R.string.common_transfer)
|
||||
is TangemPayTxHistoryItem.Fee -> {
|
||||
this.description?.let(::stringReference) ?: resourceReference(R.string.tangem_pay_fee_subtitle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TangemPayTxHistoryItem.extractTransactionCategory(): TextReference {
|
||||
return when (this) {
|
||||
is TangemPayTxHistoryItem.Fee -> resourceReference(R.string.tangem_pay_fee_subtitle)
|
||||
is TangemPayTxHistoryItem.Payment -> resourceReference(R.string.common_transfer)
|
||||
is TangemPayTxHistoryItem.Collateral -> resourceReference(R.string.common_transfer)
|
||||
is TangemPayTxHistoryItem.Spend -> extractSpendCategory()
|
||||
}
|
||||
}
|
||||
|
||||
private fun TangemPayTxHistoryItem.Spend.extractSpendCategory(): TextReference {
|
||||
val merchantCategory = merchantCategory
|
||||
val enrichedMerchantCategory = enrichedMerchantCategory
|
||||
return when {
|
||||
!merchantCategory.isNullOrEmpty() -> stringReference(merchantCategory)
|
||||
!enrichedMerchantCategory.isNullOrEmpty() -> stringReference(enrichedMerchantCategory)
|
||||
else -> resourceReference(R.string.tangem_pay_other)
|
||||
}
|
||||
}
|
||||
|
||||
private fun TangemPayTxHistoryItem.extractMcc(): TextReference? {
|
||||
return when (this) {
|
||||
is TangemPayTxHistoryItem.Spend -> merchantCategoryCode
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?.let(::stringReference)
|
||||
is TangemPayTxHistoryItem.Fee,
|
||||
is TangemPayTxHistoryItem.Payment,
|
||||
is TangemPayTxHistoryItem.Collateral,
|
||||
-> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun TangemPayTxHistoryItem.extractAmount(): String {
|
||||
return when (this) {
|
||||
is TangemPayTxHistoryItem.Fee,
|
||||
is TangemPayTxHistoryItem.Payment,
|
||||
-> {
|
||||
val amount = this.amount.format {
|
||||
fiat(
|
||||
fiatCurrencyCode = this@extractAmount.currency.currencyCode,
|
||||
fiatCurrencySymbol = this@extractAmount.currency.symbol,
|
||||
)
|
||||
}
|
||||
StringsSigns.MINUS + amount
|
||||
}
|
||||
is TangemPayTxHistoryItem.Spend -> {
|
||||
val amountPrefix = when {
|
||||
this.amount.isZero() -> ""
|
||||
this.status == TangemPayTxHistoryItem.Status.REVERSED -> StringsSigns.MINUS
|
||||
this.status == TangemPayTxHistoryItem.Status.DECLINED ||
|
||||
this.amount.isPositive() -> StringsSigns.MINUS
|
||||
else -> StringsSigns.PLUS
|
||||
}
|
||||
val amount = when (this.status) {
|
||||
TangemPayTxHistoryItem.Status.DECLINED -> this.authorizedAmount
|
||||
else -> this.amount
|
||||
}
|
||||
val formattedAmount = amount.abs().format {
|
||||
fiat(
|
||||
fiatCurrencyCode = this@extractAmount.currency.currencyCode,
|
||||
fiatCurrencySymbol = this@extractAmount.currency.symbol,
|
||||
)
|
||||
}
|
||||
amountPrefix + formattedAmount
|
||||
}
|
||||
is TangemPayTxHistoryItem.Collateral -> {
|
||||
val amountPrefix = when {
|
||||
this.amount.isZero() -> ""
|
||||
this.amount.isPositive() -> StringsSigns.PLUS
|
||||
else -> StringsSigns.MINUS
|
||||
}
|
||||
val amount = this.amount.abs().format {
|
||||
fiat(
|
||||
fiatCurrencyCode = this@extractAmount.currency.currencyCode,
|
||||
fiatCurrencySymbol = this@extractAmount.currency.symbol,
|
||||
)
|
||||
}
|
||||
amountPrefix + amount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TangemPayTxHistoryItem.extractLocalAmount(): String? {
|
||||
return when (this) {
|
||||
is TangemPayTxHistoryItem.Collateral,
|
||||
is TangemPayTxHistoryItem.Fee,
|
||||
is TangemPayTxHistoryItem.Payment,
|
||||
-> null
|
||||
is TangemPayTxHistoryItem.Spend -> {
|
||||
val localCurrency = this.localCurrency
|
||||
val localAmount = this.localAmount
|
||||
if (localCurrency != null && localAmount != null && localCurrency != currency) {
|
||||
val amountPrefix = when {
|
||||
localAmount.isZero() -> ""
|
||||
this.status == TangemPayTxHistoryItem.Status.DECLINED ||
|
||||
localAmount.isPositive() -> StringsSigns.MINUS
|
||||
else -> StringsSigns.PLUS
|
||||
}
|
||||
val amount = localAmount.abs().format {
|
||||
fiat(
|
||||
fiatCurrencyCode = localCurrency.currencyCode,
|
||||
fiatCurrencySymbol = localCurrency.symbol,
|
||||
).price()
|
||||
}
|
||||
amountPrefix + amount
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TangemPayTxHistoryItem.extractTransactionLabel(): TransactionLabelUM? {
|
||||
return when (this) {
|
||||
is TangemPayTxHistoryItem.Payment,
|
||||
is TangemPayTxHistoryItem.Collateral,
|
||||
-> {
|
||||
TransactionLabelUM(
|
||||
transactionStateType = TransactionStateType.Completed,
|
||||
icon = TangemIconUM.Icon(
|
||||
imageVector = Icons.ic_success_24,
|
||||
tintReference = { TangemTheme.colors3.icon.status.success },
|
||||
),
|
||||
title = resourceReference(R.string.tangem_pay_status_completed),
|
||||
)
|
||||
}
|
||||
is TangemPayTxHistoryItem.Fee -> TransactionLabelUM(
|
||||
transactionStateType = TransactionStateType.Completed,
|
||||
icon = TangemIconUM.Icon(
|
||||
imageVector = Icons.ic_success_24,
|
||||
tintReference = { TangemTheme.colors3.icon.status.success },
|
||||
),
|
||||
title = resourceReference(R.string.tangem_pay_status_completed),
|
||||
subtitle = resourceReference(R.string.tangem_pay_transaction_fee_notification_text),
|
||||
)
|
||||
is TangemPayTxHistoryItem.Spend -> when (this.status) {
|
||||
TangemPayTxHistoryItem.Status.COMPLETED -> TransactionLabelUM(
|
||||
transactionStateType = TransactionStateType.Completed,
|
||||
icon = TangemIconUM.Icon(
|
||||
imageVector = Icons.ic_success_24,
|
||||
tintReference = { TangemTheme.colors3.icon.status.success },
|
||||
),
|
||||
title = resourceReference(R.string.tangem_pay_status_completed),
|
||||
)
|
||||
TangemPayTxHistoryItem.Status.PENDING,
|
||||
TangemPayTxHistoryItem.Status.RESERVED,
|
||||
-> TransactionLabelUM(
|
||||
transactionStateType = TransactionStateType.InProgress,
|
||||
icon = TangemIconUM.Icon(
|
||||
imageVector = Icons.ic_clock_24,
|
||||
tintReference = { TangemTheme.colors3.icon.status.info },
|
||||
),
|
||||
title = resourceReference(R.string.tangem_pay_status_pending),
|
||||
)
|
||||
TangemPayTxHistoryItem.Status.DECLINED -> TransactionLabelUM(
|
||||
transactionStateType = TransactionStateType.Rejected,
|
||||
icon = TangemIconUM.Icon(
|
||||
iconRes = R.drawable.ic_warning_20,
|
||||
tintReference = { TangemTheme.colors3.icon.status.error },
|
||||
),
|
||||
title = resourceReference(R.string.tangem_pay_status_declined),
|
||||
subtitle = extractDeclinedSubtitle(),
|
||||
)
|
||||
TangemPayTxHistoryItem.Status.REVERSED -> TransactionLabelUM(
|
||||
transactionStateType = TransactionStateType.Reversed,
|
||||
icon = TangemIconUM.Icon(
|
||||
imageVector = Icons.ic_success_24,
|
||||
tintReference = { TangemTheme.colors3.icon.status.success },
|
||||
),
|
||||
title = resourceReference(R.string.tangem_pay_status_reversed),
|
||||
subtitle = resourceReference(R.string.tangem_pay_transaction_reversed_notification_text),
|
||||
)
|
||||
TangemPayTxHistoryItem.Status.UNKNOWN -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TangemPayTxHistoryItem.Spend.extractDeclinedSubtitle(): TextReference {
|
||||
return if (declinedReason.isNullOrEmpty()) {
|
||||
resourceReference(R.string.tangem_pay_transaction_declined_notification_text)
|
||||
} else {
|
||||
resourceReference(
|
||||
id = R.string.tangem_pay_history_item_spend_mc_declined_reason,
|
||||
formatArgs = wrappedList(requireNotNull(declinedReason)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Input.extractButtonState(): ButtonState {
|
||||
return ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_get_help),
|
||||
onClick = this.onDisputeClick,
|
||||
)
|
||||
}
|
||||
|
||||
data class Input(
|
||||
val item: TangemPayTxHistoryItem,
|
||||
val isBalanceHidden: Boolean,
|
||||
val onExplorerClick: (String?) -> Unit,
|
||||
val onDisputeClick: () -> Unit,
|
||||
val onDismiss: () -> Unit,
|
||||
)
|
||||
}
|
||||
|
|
@ -30,6 +30,7 @@ import com.tangem.core.ui.res.TangemColorPalette
|
|||
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.ButtonState
|
||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -115,10 +116,7 @@ internal fun TangemPayTxHistoryDetailsContent(state: TangemPayTxHistoryDetailsUM
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun ButtonsContainer(
|
||||
buttons: ImmutableList<TangemPayTxHistoryDetailsUM.ButtonState>,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
private fun ButtonsContainer(buttons: ImmutableList<ButtonState>, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
|
|
@ -179,7 +177,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
|
|||
),
|
||||
notification = null,
|
||||
buttons = persistentListOf(
|
||||
TangemPayTxHistoryDetailsUM.ButtonState(
|
||||
ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_dispute),
|
||||
onClick = {},
|
||||
),
|
||||
|
|
@ -210,7 +208,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
|
|||
containerColor = themedColor { TangemColorPalette.Amaranth.copy(alpha = 0.1F) },
|
||||
),
|
||||
buttons = persistentListOf(
|
||||
TangemPayTxHistoryDetailsUM.ButtonState(
|
||||
ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_dispute),
|
||||
onClick = {},
|
||||
),
|
||||
|
|
@ -232,7 +230,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
|
|||
),
|
||||
notification = null,
|
||||
buttons = persistentListOf(
|
||||
TangemPayTxHistoryDetailsUM.ButtonState(
|
||||
ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_dispute),
|
||||
onClick = {},
|
||||
),
|
||||
|
|
@ -260,7 +258,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
|
|||
containerColor = null,
|
||||
),
|
||||
buttons = persistentListOf(
|
||||
TangemPayTxHistoryDetailsUM.ButtonState(
|
||||
ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_dispute),
|
||||
onClick = {},
|
||||
),
|
||||
|
|
@ -279,7 +277,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
|
|||
labelState = null,
|
||||
notification = null,
|
||||
buttons = persistentListOf(
|
||||
TangemPayTxHistoryDetailsUM.ButtonState(
|
||||
ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_get_help),
|
||||
onClick = {},
|
||||
),
|
||||
|
|
@ -298,7 +296,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
|
|||
labelState = null,
|
||||
notification = null,
|
||||
buttons = persistentListOf(
|
||||
TangemPayTxHistoryDetailsUM.ButtonState(
|
||||
ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_get_help),
|
||||
onClick = {},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,389 @@
|
|||
package com.tangem.features.tangempay.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.TextAutoSize
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Devices
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import com.tangem.core.ui.components.SpacerW
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetType
|
||||
import com.tangem.core.ui.ds.image.TangemIcon
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
import com.tangem.core.ui.ds.topbar.TangemTopBar
|
||||
import com.tangem.core.ui.ds.topbar.TangemTopBarType
|
||||
import com.tangem.core.ui.ds2.button.TangemButton
|
||||
import com.tangem.core.ui.ds2.row.TangemRow
|
||||
import com.tangem.core.ui.ds2.row.TangemRowContentLead
|
||||
import com.tangem.core.ui.ds2.row.TangemRowText
|
||||
import com.tangem.core.ui.ds2.row.TangemRowTextRole
|
||||
import com.tangem.core.ui.extensions.orMaskWithStars
|
||||
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.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreviewRedesign
|
||||
import com.tangem.core.ui.res.generated.icons.Icons
|
||||
import com.tangem.core.ui.res.generated.icons.ic_arrow_down_24
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.ButtonState
|
||||
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUMV2
|
||||
import com.tangem.features.tangempay.entity.TransactionLabelUM
|
||||
import com.tangem.features.tangempay.entity.TransactionStateType
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
internal fun TangemPayTxHistoryDetailsContentV2(state: TangemPayTxHistoryDetailsUMV2) {
|
||||
TangemBottomSheet<TangemBottomSheetConfigContent.Empty>(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = state.dismiss,
|
||||
content = TangemBottomSheetConfigContent.Empty,
|
||||
),
|
||||
type = TangemBottomSheetType.Modal,
|
||||
containerColor = TangemTheme.colors3.bg.secondary,
|
||||
title = {
|
||||
TangemTopBar(
|
||||
title = state.title,
|
||||
subtitle = state.subtitle,
|
||||
type = TangemTopBarType.BottomSheet,
|
||||
endContent = {
|
||||
TangemButton(
|
||||
iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_24),
|
||||
onClick = state.dismiss,
|
||||
size = TangemButton.Size.X11,
|
||||
variant = TangemButton.Variant.Material,
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
content = {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = TangemTheme.dimens2.x4)
|
||||
.padding(bottom = TangemTheme.dimens2.x4),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
TransactionIcon(
|
||||
iconState = state.iconState,
|
||||
modifier = Modifier.padding(top = TangemTheme.dimens2.x12),
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(top = TangemTheme.dimens2.x6),
|
||||
text = state.transactionAmount.orMaskWithStars(state.isBalanceHidden),
|
||||
style = TangemTheme.typography3.display.medium,
|
||||
color = TangemTheme.colors3.text.primary,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
autoSize = TextAutoSize.StepBased(
|
||||
minFontSize = TangemTheme.typography3.body.medium.fontSize,
|
||||
maxFontSize = TangemTheme.typography3.display.medium.fontSize,
|
||||
),
|
||||
)
|
||||
TransactionSecondaryLine(
|
||||
state = state,
|
||||
modifier = Modifier.padding(top = TangemTheme.dimens2.x1),
|
||||
)
|
||||
if (state.label != null) {
|
||||
TransactionLabel(
|
||||
label = state.label,
|
||||
modifier = Modifier
|
||||
.padding(top = TangemTheme.dimens2.x12)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
TransactionDetailsBlock(
|
||||
state = state,
|
||||
modifier = Modifier
|
||||
.padding(top = TangemTheme.dimens2.x4, bottom = TangemTheme.dimens2.x2)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
TangemButton(
|
||||
modifier = Modifier
|
||||
.padding(vertical = TangemTheme.dimens2.x4)
|
||||
.fillMaxWidth(),
|
||||
text = state.buttonState.text,
|
||||
onClick = state.buttonState.onClick,
|
||||
size = TangemButton.Size.X12,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TransactionIcon(iconState: TangemIconUM, modifier: Modifier = Modifier) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(TangemTheme.dimens2.x20)
|
||||
.clip(CircleShape)
|
||||
.background(TangemTheme.colors3.bg.opaque.primary),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
TangemIcon(
|
||||
tangemIconUM = iconState,
|
||||
modifier = Modifier.size(
|
||||
if (iconState is TangemIconUM.Icon) {
|
||||
TangemTheme.dimens2.x12
|
||||
} else {
|
||||
TangemTheme.dimens2.x20
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TransactionSecondaryLine(state: TangemPayTxHistoryDetailsUMV2, modifier: Modifier = Modifier) {
|
||||
val secondaryText = when {
|
||||
state.localTransactionText != null -> {
|
||||
buildString {
|
||||
append(state.localTransactionText.orMaskWithStars(state.isBalanceHidden))
|
||||
append(" · ")
|
||||
append(state.transactionTitle.resolveReference())
|
||||
}
|
||||
}
|
||||
else -> state.transactionTitle.resolveReference()
|
||||
}
|
||||
Text(
|
||||
modifier = modifier,
|
||||
text = secondaryText,
|
||||
style = TangemTheme.typography3.subheading.medium,
|
||||
color = TangemTheme.colors3.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun TransactionLabel(label: TransactionLabelUM, modifier: Modifier = Modifier) {
|
||||
val (backgroundColor, textColor) = when (label.transactionStateType) {
|
||||
TransactionStateType.Completed,
|
||||
TransactionStateType.Reversed,
|
||||
-> {
|
||||
TangemTheme.colors3.bg.status.successSubtle to TangemTheme.colors3.text.status.success
|
||||
}
|
||||
TransactionStateType.InProgress -> {
|
||||
TangemTheme.colors3.bg.status.infoSubtle to TangemTheme.colors3.text.status.info
|
||||
}
|
||||
TransactionStateType.Rejected -> {
|
||||
TangemTheme.colors3.bg.status.errorSubtle to TangemTheme.colors3.text.status.error
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = modifier
|
||||
.background(
|
||||
color = backgroundColor,
|
||||
shape = RoundedCornerShape(TangemTheme.dimens3.borderRadius.b250),
|
||||
)
|
||||
.padding(
|
||||
vertical = TangemTheme.dimens2.x3,
|
||||
horizontal = TangemTheme.dimens2.x4,
|
||||
),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
|
||||
) {
|
||||
Text(
|
||||
text = label.title.resolveReference(),
|
||||
style = TangemTheme.typography3.body.medium,
|
||||
color = textColor,
|
||||
)
|
||||
|
||||
label.subtitle?.let { text ->
|
||||
Text(
|
||||
text = text.resolveReference(),
|
||||
style = TangemTheme.typography3.caption.medium,
|
||||
color = textColor,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
SpacerW(TangemTheme.dimens2.x1)
|
||||
|
||||
TangemIcon(
|
||||
tangemIconUM = label.icon,
|
||||
modifier = Modifier.size(TangemTheme.dimens2.x5),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TransactionDetailsBlock(state: TangemPayTxHistoryDetailsUMV2, modifier: Modifier = Modifier) {
|
||||
Column(modifier = modifier) {
|
||||
TangemRow(
|
||||
divider = state.mcc != null,
|
||||
contentLead = TangemRowContentLead.Start,
|
||||
titleSlot = {
|
||||
TangemRowText(
|
||||
text = resourceReference(R.string.tangem_pay_transaction_details_category),
|
||||
role = TangemRowTextRole.Title,
|
||||
)
|
||||
},
|
||||
valueSlot = {
|
||||
TangemRowText(
|
||||
text = state.transactionCategory,
|
||||
role = TangemRowTextRole.Value,
|
||||
)
|
||||
},
|
||||
)
|
||||
if (state.mcc != null) {
|
||||
TangemRow(
|
||||
contentLead = TangemRowContentLead.Start,
|
||||
titleSlot = {
|
||||
TangemRowText(
|
||||
text = resourceReference(R.string.tangem_pay_transaction_details_mcc),
|
||||
role = TangemRowTextRole.Title,
|
||||
)
|
||||
},
|
||||
valueSlot = {
|
||||
TangemRowText(
|
||||
text = state.mcc,
|
||||
role = TangemRowTextRole.Value,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(device = Devices.PIXEL_7_PRO)
|
||||
@Preview(device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun TangemPayTxHistoryDetailsContentPreview(
|
||||
@PreviewParameter(TangemPayTxHistoryDetailsUMProviderV2::class) state: TangemPayTxHistoryDetailsUMV2,
|
||||
) {
|
||||
TangemThemePreviewRedesign {
|
||||
TangemPayTxHistoryDetailsContentV2(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
private class TangemPayTxHistoryDetailsUMProviderV2 :
|
||||
CollectionPreviewParameterProvider<TangemPayTxHistoryDetailsUMV2>(
|
||||
listOf(
|
||||
TangemPayTxHistoryDetailsUMV2(
|
||||
isBalanceHidden = true,
|
||||
title = resourceReference(R.string.tangem_pay_purchase),
|
||||
subtitle = stringReference("12 June 2026, 12:40"),
|
||||
iconState = TangemIconUM.Icon(iconRes = R.drawable.ic_category_24),
|
||||
transactionTitle = stringReference("Starbucks"),
|
||||
transactionCategory = stringReference("Food and drinks"),
|
||||
mcc = stringReference("5814"),
|
||||
transactionAmount = "-$5.86",
|
||||
localTransactionText = null,
|
||||
label = TransactionLabelUM(
|
||||
transactionStateType = TransactionStateType.InProgress,
|
||||
icon = TangemIconUM.Icon(iconRes = com.tangem.core.ui.R.drawable.ic_clock_24),
|
||||
title = resourceReference(R.string.tangem_pay_status_pending),
|
||||
),
|
||||
buttonState = ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_get_help),
|
||||
onClick = {},
|
||||
),
|
||||
dismiss = {},
|
||||
),
|
||||
TangemPayTxHistoryDetailsUMV2(
|
||||
isBalanceHidden = true,
|
||||
title = resourceReference(R.string.tangem_pay_purchase),
|
||||
subtitle = stringReference("12 June 2026, 12:40"),
|
||||
iconState = TangemIconUM.Icon(iconRes = R.drawable.ic_category_24),
|
||||
transactionTitle = stringReference("NuCaloric"),
|
||||
transactionCategory = stringReference("Groceries"),
|
||||
mcc = stringReference("0000"),
|
||||
transactionAmount = "-$820.52",
|
||||
localTransactionText = "-€696,52",
|
||||
label = TransactionLabelUM(
|
||||
transactionStateType = TransactionStateType.Rejected,
|
||||
icon = TangemIconUM.Icon(iconRes = R.drawable.ic_token_info_24),
|
||||
title = resourceReference(R.string.tangem_pay_status_declined),
|
||||
subtitle = stringReference("Reason: account credit limit exceeded"),
|
||||
),
|
||||
buttonState = ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_get_help),
|
||||
onClick = {},
|
||||
),
|
||||
dismiss = {},
|
||||
),
|
||||
TangemPayTxHistoryDetailsUMV2(
|
||||
isBalanceHidden = true,
|
||||
title = resourceReference(R.string.tangem_pay_purchase),
|
||||
subtitle = stringReference("12 June 2026, 12:40"),
|
||||
iconState = TangemIconUM.Icon(iconRes = R.drawable.ic_category_24),
|
||||
transactionTitle = stringReference("Starbucks"),
|
||||
transactionCategory = stringReference("Food and drinks"),
|
||||
mcc = null,
|
||||
transactionAmount = "-$5.86",
|
||||
localTransactionText = "€ 5.36",
|
||||
label = TransactionLabelUM(
|
||||
transactionStateType = TransactionStateType.Completed,
|
||||
icon = TangemIconUM.Empty,
|
||||
title = resourceReference(R.string.tangem_pay_status_completed),
|
||||
),
|
||||
buttonState = ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_get_help),
|
||||
onClick = {},
|
||||
),
|
||||
dismiss = {},
|
||||
),
|
||||
TangemPayTxHistoryDetailsUMV2(
|
||||
isBalanceHidden = false,
|
||||
title = resourceReference(R.string.tangem_pay_fee_title),
|
||||
subtitle = stringReference("12 June 2026, 12:40"),
|
||||
iconState = TangemIconUM.Icon(iconRes = R.drawable.ic_percent_24),
|
||||
transactionTitle = stringReference("Service fees"),
|
||||
transactionCategory = stringReference("Service fees"),
|
||||
mcc = null,
|
||||
transactionAmount = "-$5.86",
|
||||
localTransactionText = null,
|
||||
label = TransactionLabelUM(
|
||||
transactionStateType = TransactionStateType.Completed,
|
||||
icon = TangemIconUM.Icon(iconRes = R.drawable.ic_token_info_24),
|
||||
title = resourceReference(R.string.tangem_pay_fee_title),
|
||||
subtitle = resourceReference(R.string.tangem_pay_transaction_fee_notification_text),
|
||||
),
|
||||
buttonState = ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_get_help),
|
||||
onClick = {},
|
||||
),
|
||||
dismiss = {},
|
||||
),
|
||||
TangemPayTxHistoryDetailsUMV2(
|
||||
isBalanceHidden = false,
|
||||
title = resourceReference(R.string.tangem_pay_deposit),
|
||||
subtitle = stringReference("12 June 2026, 12:40"),
|
||||
iconState = TangemIconUM.Icon(imageVector = Icons.ic_arrow_down_24),
|
||||
transactionTitle = resourceReference(R.string.common_transfer),
|
||||
transactionCategory = resourceReference(R.string.common_transfer),
|
||||
mcc = null,
|
||||
transactionAmount = "+$20",
|
||||
localTransactionText = null,
|
||||
label = null,
|
||||
buttonState = ButtonState(
|
||||
text = resourceReference(R.string.tangem_pay_get_help),
|
||||
onClick = {},
|
||||
),
|
||||
dismiss = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue