diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/TangemPayTxHistoryResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/TangemPayTxHistoryResponse.kt
index f3273753ed..04496bd572 100644
--- a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/TangemPayTxHistoryResponse.kt
+++ b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/TangemPayTxHistoryResponse.kt
@@ -35,20 +35,20 @@ data class TangemPayTxHistoryResponse(
@Json(name = "authorized_amount") val authorizedAmount: BigDecimal? = null,
@Json(name = "authorization_method") val authorizationMethod: String? = null,
@Json(name = "memo") val memo: String? = null,
- @Json(name = "receipt") val receipt: Boolean? = null,
- @Json(name = "merchant_name") val merchantName: String? = null,
- @Json(name = "merchant_category") val merchantCategory: String? = null,
- @Json(name = "merchant_category_code") val merchantCategoryCode: String? = null,
+ @Json(name = "receipt") val receipt: Boolean,
+ @Json(name = "merchant_name") val merchantName: String,
+ @Json(name = "merchant_category") val merchantCategory: String,
+ @Json(name = "merchant_category_code") val merchantCategoryCode: String,
@Json(name = "merchant_id") val merchantId: String? = null,
@Json(name = "enriched_merchant_icon") val enrichedMerchantIcon: String? = null,
@Json(name = "enriched_merchant_name") val enrichedMerchantName: String? = null,
@Json(name = "enriched_merchant_category") val enrichedMerchantCategory: String? = null,
@Json(name = "card_id") val cardId: String? = null,
@Json(name = "card_type") val cardType: String? = null,
- @Json(name = "status") val status: String? = null,
+ @Json(name = "status") val status: String,
@Json(name = "declined_reason") val declinedReason: String? = null,
- @Json(name = "authorized_at") val authorizedAt: DateTime? = null,
- @Json(name = "posted_at") val postedAt: DateTime? = null,
+ @Json(name = "authorized_at") val authorizedAt: DateTime,
+ @Json(name = "posted_at") val postedAt: DateTime,
)
@JsonClass(generateAdapter = true)
@@ -56,10 +56,10 @@ data class TangemPayTxHistoryResponse(
@Json(name = "amount") val amount: BigDecimal,
@Json(name = "currency") val currency: String,
@Json(name = "memo") val memo: String? = null,
- @Json(name = "chain_id") val chainId: Long? = null,
- @Json(name = "wallet_address") val walletAddress: String? = null,
- @Json(name = "transaction_hash") val transactionHash: String? = null,
- @Json(name = "posted_at") val postedAt: DateTime? = null,
+ @Json(name = "chain_id") val chainId: Long,
+ @Json(name = "wallet_address") val walletAddress: String,
+ @Json(name = "transaction_hash") val transactionHash: String,
+ @Json(name = "posted_at") val postedAt: DateTime?,
)
@JsonClass(generateAdapter = true)
@@ -70,8 +70,8 @@ data class TangemPayTxHistoryResponse(
@Json(name = "chain_id") val chainId: Long? = null,
@Json(name = "wallet_address") val walletAddress: String? = null,
@Json(name = "transaction_hash") val transactionHash: String? = null,
- @Json(name = "status") val status: String? = null,
- @Json(name = "posted_at") val postedAt: DateTime? = null,
+ @Json(name = "status") val status: String,
+ @Json(name = "posted_at") val postedAt: DateTime,
)
@JsonClass(generateAdapter = true)
@@ -79,6 +79,6 @@ data class TangemPayTxHistoryResponse(
@Json(name = "amount") val amount: BigDecimal,
@Json(name = "currency") val currency: String,
@Json(name = "description") val description: String? = null,
- @Json(name = "posted_at") val postedAt: DateTime? = null,
+ @Json(name = "posted_at") val postedAt: DateTime,
)
}
\ No newline at end of file
diff --git a/core/ui/src/main/res/drawable/ic_category_24.xml b/core/ui/src/main/res/drawable/ic_category_24.xml
new file mode 100644
index 0000000000..7fd56ce3ed
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_category_24.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_percent_24.xml b/core/ui/src/main/res/drawable/ic_percent_24.xml
new file mode 100644
index 0000000000..241b3ba85c
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_percent_24.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt
index 450444bf67..b005177a40 100644
--- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt
+++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt
@@ -13,12 +13,15 @@ import com.tangem.domain.pay.model.CustomerInfo.ProductInstance
import com.tangem.domain.pay.model.MainScreenCustomerInfo
import com.tangem.domain.pay.model.OrderStatus
import com.tangem.domain.pay.repository.OnboardingRepository
+import com.tangem.utils.coroutines.CoroutineDispatcherProvider
+import kotlinx.coroutines.withContext
import javax.inject.Inject
private const val VALID_STATUS = "valid"
private const val TAG = "TangemPay: OnboardingRepository"
internal class DefaultOnboardingRepository @Inject constructor(
+ private val dispatcherProvider: CoroutineDispatcherProvider,
private val tangemPayApi: TangemPayApi,
private val requestHelper: TangemPayRequestPerformer,
private val tangemPayStorage: TangemPayStorage,
@@ -54,8 +57,8 @@ internal class DefaultOnboardingRepository @Inject constructor(
}
}
- override suspend fun createOrder(): Either {
- return requestHelper.runWithErrorLogs(TAG) {
+ override suspend fun createOrder(): Either = withContext(dispatcherProvider.io) {
+ requestHelper.runWithErrorLogs(TAG) {
val walletAddress = requestHelper.getCustomerWalletAddress()
val result = requestHelper.requestWithPersistedToken { authHeader ->
tangemPayApi.createOrder(authHeader, body = OrderRequest(walletAddress))
@@ -68,14 +71,13 @@ internal class DefaultOnboardingRepository @Inject constructor(
private fun getCustomerInfo(response: CustomerMeResponse.Result?): CustomerInfo {
val card = response?.card
val balance = response?.balance
- val productInstance = response?.productInstance
- val cardInfo = if (productInstance != null && card != null && balance != null) {
+ val paymentAccount = response?.paymentAccount
+ val cardInfo = if (paymentAccount != null && card != null && balance != null) {
CardInfo(
lastFourDigits = card.cardNumberEnd,
balance = balance.availableBalance,
currencyCode = balance.currency,
- customerWalletAddress = productInstance.cardWalletAddress,
-
+ customerWalletAddress = paymentAccount.customerWalletAddress,
)
} else {
null
diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayTxHistoryRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayTxHistoryRepository.kt
index b2006f60c4..be43b2bd72 100644
--- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayTxHistoryRepository.kt
+++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayTxHistoryRepository.kt
@@ -84,7 +84,7 @@ internal class DefaultTangemPayTxHistoryRepository @Inject constructor(
val result = requestPerformer.request { authHeader ->
visaApi.getTangemPayTxHistory(authHeader = authHeader, limit = pageSize, cursor = cursor)
}.result
- val items = TangemPayTxHistoryItemConverter.convertList(result.transactions)
+ val items = TangemPayTxHistoryItemConverter.convertList(result.transactions).filterNotNull()
txHistoryItemsStore.store(key = customerWalletAddress, cursor = cursor ?: INITIAL_CURSOR, value = items)
}
}
diff --git a/data/visa/src/main/kotlin/com/tangem/data/visa/utils/TangemPayTxHistoryItemConverter.kt b/data/visa/src/main/kotlin/com/tangem/data/visa/utils/TangemPayTxHistoryItemConverter.kt
index 9c4257091e..4a01623666 100644
--- a/data/visa/src/main/kotlin/com/tangem/data/visa/utils/TangemPayTxHistoryItemConverter.kt
+++ b/data/visa/src/main/kotlin/com/tangem/data/visa/utils/TangemPayTxHistoryItemConverter.kt
@@ -3,49 +3,55 @@ package com.tangem.data.visa.utils
import com.tangem.datasource.api.pay.models.response.TangemPayTxHistoryResponse
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
import com.tangem.utils.converter.Converter
+import timber.log.Timber
+import java.util.Currency
internal object TangemPayTxHistoryItemConverter :
- Converter {
+ Converter {
- @Suppress("CyclomaticComplexMethod")
- override fun convert(value: TangemPayTxHistoryResponse.Transaction): TangemPayTxHistoryItem {
- val spend = value.spend
- val collateral = value.collateral
- val payment = value.payment
- val fee = value.fee
+ 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) }
+ ?: run {
+ Timber.wtf("unknown type of transaction: $value")
+ null
+ }
+ }
- return TangemPayTxHistoryItem(
- id = value.id,
- date = when {
- spend != null -> spend.postedAt
- collateral != null -> collateral.postedAt
- payment != null -> payment.postedAt
- fee != null -> fee.postedAt
- else -> null
- },
- amount = when {
- spend != null -> spend.amount
- collateral != null -> collateral.amount
- payment != null -> payment.amount
- fee != null -> fee.amount
- else -> null
- },
- merchantName = when {
- spend != null -> spend.merchantName
- else -> null
- },
- status = when {
- spend != null -> spend.status
- payment != null -> payment.status
- else -> null
- },
- currency = when {
- spend != null -> spend.currency
- collateral != null -> collateral.currency
- payment != null -> payment.currency
- fee != null -> fee.currency
- else -> null
- },
+ private fun convertSpend(id: String, spend: TangemPayTxHistoryResponse.Spend): TangemPayTxHistoryItem.Spend {
+ return TangemPayTxHistoryItem.Spend(
+ id = id,
+ date = spend.postedAt,
+ amount = spend.amount,
+ currency = Currency.getInstance(spend.currency),
+ enrichedMerchantName = spend.enrichedMerchantName,
+ merchantName = spend.merchantName,
+ enrichedMerchantCategory = spend.enrichedMerchantCategory,
+ merchantCategory = spend.merchantCategory,
+ status = spend.status,
+ enrichedMerchantIconUrl = spend.enrichedMerchantIcon,
+ )
+ }
+
+ private fun convertPayment(
+ id: String,
+ payment: TangemPayTxHistoryResponse.Payment,
+ ): TangemPayTxHistoryItem.Payment {
+ return TangemPayTxHistoryItem.Payment(
+ id = id,
+ date = payment.postedAt,
+ currency = Currency.getInstance(payment.currency),
+ amount = payment.amount,
+ )
+ }
+
+ private fun convertFee(id: String, fee: TangemPayTxHistoryResponse.Fee): TangemPayTxHistoryItem.Fee {
+ return TangemPayTxHistoryItem.Fee(
+ id = id,
+ date = fee.postedAt,
+ currency = Currency.getInstance(fee.currency),
+ amount = fee.amount,
)
}
}
\ No newline at end of file
diff --git a/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/TangemPayTxHistoryItem.kt b/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/TangemPayTxHistoryItem.kt
index 2e97128461..65d960d01c 100644
--- a/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/TangemPayTxHistoryItem.kt
+++ b/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/TangemPayTxHistoryItem.kt
@@ -2,14 +2,38 @@ package com.tangem.domain.visa.model
import org.joda.time.DateTime
import java.math.BigDecimal
+import java.util.Currency
-data class TangemPayTxHistoryItem(
- val id: String,
- val date: DateTime?,
- val amount: BigDecimal?,
- val merchantName: String?,
- val status: String?,
- val currency: String?,
-) {
- val timeStampInMillis: Long = date?.millis ?: 0
+sealed class TangemPayTxHistoryItem {
+ abstract val id: String
+ abstract val date: DateTime
+ abstract val amount: BigDecimal
+ abstract val currency: Currency
+
+ data class Spend(
+ override val id: String,
+ override val date: DateTime,
+ override val amount: BigDecimal,
+ override val currency: Currency,
+ val enrichedMerchantName: String?,
+ val merchantName: String,
+ val enrichedMerchantCategory: String?,
+ val merchantCategory: String,
+ val status: String,
+ val enrichedMerchantIconUrl: String?,
+ ) : TangemPayTxHistoryItem()
+
+ data class Payment(
+ override val id: String,
+ override val date: DateTime,
+ override val amount: BigDecimal,
+ override val currency: Currency,
+ ) : TangemPayTxHistoryItem()
+
+ data class Fee(
+ override val id: String,
+ override val date: DateTime,
+ override val amount: BigDecimal,
+ override val currency: Currency,
+ ) : TangemPayTxHistoryItem()
}
\ No newline at end of file
diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/TangemPayIssueOrderUseCase.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/TangemPayIssueOrderUseCase.kt
index 2cf992c3d8..6127e5225b 100644
--- a/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/TangemPayIssueOrderUseCase.kt
+++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/TangemPayIssueOrderUseCase.kt
@@ -1,10 +1,12 @@
package com.tangem.domain.pay.usecase
+import arrow.core.Either
+import com.tangem.core.error.UniversalError
import com.tangem.domain.pay.repository.OnboardingRepository
class TangemPayIssueOrderUseCase(
private val repository: OnboardingRepository,
) {
- suspend operator fun invoke(): Unit? = repository.createOrder().getOrNull()
+ suspend operator fun invoke(): Either = repository.createOrder()
}
\ No newline at end of file
diff --git a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/ManageTokensScreen.kt b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/ManageTokensScreen.kt
index ebb75ad905..e7426ae87c 100644
--- a/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/ManageTokensScreen.kt
+++ b/features/manage-tokens/impl/src/main/kotlin/com/tangem/features/managetokens/ui/ManageTokensScreen.kt
@@ -442,7 +442,7 @@ private class PreviewManageTokensComponentProvider : PreviewParameterProvider = model.uiState
+ override val state: StateFlow = model.uiState
- override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TxHistoryUM) {
- txHistoryItems(listState, state)
+ override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TangemPayTxHistoryUM) {
+ tangemPayTxHistoryItems(listState, state)
}
data class Params(val customerWalletAddress: String)
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/PreviewTangemPayTxHistoryComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/PreviewTangemPayTxHistoryComponent.kt
index 61d078d853..b430960c14 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/PreviewTangemPayTxHistoryComponent.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/PreviewTangemPayTxHistoryComponent.kt
@@ -2,170 +2,150 @@ package com.tangem.features.tangempay.components.txHistory
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
-import com.tangem.core.ui.components.transactions.state.TransactionState
import com.tangem.core.ui.extensions.stringReference
-import com.tangem.features.tangempay.details.impl.R
-import com.tangem.features.txhistory.entity.TxHistoryUM
-import com.tangem.features.txhistory.ui.txHistoryItems
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.features.tangempay.entity.TangemPayTransactionState
+import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
+import com.tangem.features.tangempay.ui.tangemPayTxHistoryItems
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
-internal class PreviewTangemPayTxHistoryComponent(txHistoryUM: TxHistoryUM) : TangemPayTxHistoryComponent {
- override val state: StateFlow = MutableStateFlow(txHistoryUM)
+internal class PreviewTangemPayTxHistoryComponent(txHistoryUM: TangemPayTxHistoryUM) : TangemPayTxHistoryComponent {
+ override val state: StateFlow = MutableStateFlow(txHistoryUM)
- override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TxHistoryUM) {
- txHistoryItems(listState, state)
+ override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TangemPayTxHistoryUM) {
+ tangemPayTxHistoryItems(listState = listState, state = state)
}
companion object {
- val loadingUM = TxHistoryUM.Loading(isBalanceHidden = true, onExploreClick = {})
- val emptyUM = TxHistoryUM.Empty(isBalanceHidden = true, onExploreClick = {})
- val contentUM = TxHistoryUM.Content(
+ val loadingUM = TangemPayTxHistoryUM.Loading(isBalanceHidden = true)
+ val emptyUM = TangemPayTxHistoryUM.Empty(isBalanceHidden = true)
+ val contentUM = TangemPayTxHistoryUM.Content(
isBalanceHidden = false,
loadMore = { false },
items = persistentListOf(
- TxHistoryUM.TxHistoryItemUM.Title(onExploreClick = {}),
- TxHistoryUM.TxHistoryItemUM.GroupTitle(title = "Today", itemKey = "Today"),
- TxHistoryUM.TxHistoryItemUM.Transaction(
- state = TransactionState.Content(
- txHash = "signiferumque",
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Title,
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle(title = "Today", itemKey = "Today"),
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
+ transaction = TangemPayTransactionState.Content.Spend(
+ id = "signiferumque",
+ onClick = {},
amount = "-4.99 USD",
+ amountColor = { TangemTheme.colors.text.primary1 },
time = "16:41",
- status = TransactionState.Content.Status.Confirmed,
- direction = TransactionState.Content.Direction.OUTGOING,
- onClick = {},
- iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
- timestamp = 3464,
+ iconUrl = null,
),
),
- TxHistoryUM.TxHistoryItemUM.Transaction(
- state = TransactionState.Content(
- txHash = "signiferumque",
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
+ transaction = TangemPayTransactionState.Content.Spend(
+ id = "signiferumque",
amount = "-126.20 USD",
+ amountColor = { TangemTheme.colors.text.primary1 },
time = "12:04",
- status = TransactionState.Content.Status.Confirmed,
- direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
- iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
- timestamp = 3465,
+ iconUrl = null,
),
),
- TxHistoryUM.TxHistoryItemUM.GroupTitle(title = "Yesterday", itemKey = "Yesterday"),
- TxHistoryUM.TxHistoryItemUM.Transaction(
- state = TransactionState.Content(
- txHash = "signiferumque",
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle(title = "Yesterday", itemKey = "Yesterday"),
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
+ transaction = TangemPayTransactionState.Content.Spend(
+ id = "signiferumque",
amount = "-4.99 USD",
+ amountColor = { TangemTheme.colors.text.primary1 },
time = "21:41",
- status = TransactionState.Content.Status.Confirmed,
- direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
- iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
- timestamp = 3464,
+ iconUrl = null,
),
),
- TxHistoryUM.TxHistoryItemUM.Transaction(
- state = TransactionState.Content(
- txHash = "signiferumque",
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
+ transaction = TangemPayTransactionState.Content.Spend(
+ id = "signiferumque",
amount = "-126.20 USD",
+ amountColor = { TangemTheme.colors.text.primary1 },
time = "10:04",
- status = TransactionState.Content.Status.Confirmed,
- direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
- iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
- timestamp = 3465,
+ iconUrl = null,
),
),
- TxHistoryUM.TxHistoryItemUM.Transaction(
- state = TransactionState.Content(
- txHash = "signiferumque",
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
+ transaction = TangemPayTransactionState.Content.Spend(
+ id = "signiferumque",
amount = "-4.99 USD",
+ amountColor = { TangemTheme.colors.text.primary1 },
time = "19:41",
- status = TransactionState.Content.Status.Confirmed,
- direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
- iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
- timestamp = 3464,
+ iconUrl = null,
),
),
- TxHistoryUM.TxHistoryItemUM.Transaction(
- state = TransactionState.Content(
- txHash = "signiferumque",
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
+ transaction = TangemPayTransactionState.Content.Spend(
+ id = "signiferumque",
amount = "-126.20 USD",
+ amountColor = { TangemTheme.colors.text.primary1 },
time = "18:04",
- status = TransactionState.Content.Status.Confirmed,
- direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
- iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
- timestamp = 3465,
+ iconUrl = null,
),
),
- TxHistoryUM.TxHistoryItemUM.Transaction(
- state = TransactionState.Content(
- txHash = "signiferumque",
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
+ transaction = TangemPayTransactionState.Content.Spend(
+ id = "signiferumque",
amount = "-4.99 USD",
+ amountColor = { TangemTheme.colors.text.primary1 },
time = "17:41",
- status = TransactionState.Content.Status.Confirmed,
- direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
- iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
- timestamp = 3464,
+ iconUrl = null,
),
),
- TxHistoryUM.TxHistoryItemUM.Transaction(
- state = TransactionState.Content(
- txHash = "signiferumque",
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
+ transaction = TangemPayTransactionState.Content.Spend(
+ id = "signiferumque",
amount = "-126.20 USD",
+ amountColor = { TangemTheme.colors.text.primary1 },
time = "16:04",
- status = TransactionState.Content.Status.Confirmed,
- direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
- iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
- timestamp = 3465,
+ iconUrl = null,
),
),
- TxHistoryUM.TxHistoryItemUM.Transaction(
- state = TransactionState.Content(
- txHash = "signiferumque",
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
+ transaction = TangemPayTransactionState.Content.Spend(
+ id = "signiferumque",
amount = "-4.99 USD",
+ amountColor = { TangemTheme.colors.text.primary1 },
time = "15:41",
- status = TransactionState.Content.Status.Confirmed,
- direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
- iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
- timestamp = 3464,
+ iconUrl = null,
),
),
- TxHistoryUM.TxHistoryItemUM.Transaction(
- state = TransactionState.Content(
- txHash = "signiferumque",
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(
+ transaction = TangemPayTransactionState.Content.Spend(
+ id = "signiferumque",
amount = "-126.20 USD",
+ amountColor = { TangemTheme.colors.text.primary1 },
time = "14:04",
- status = TransactionState.Content.Status.Confirmed,
- direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
- iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
- timestamp = 3465,
+ iconUrl = null,
),
),
),
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryComponent.kt
index 3b538ef7fd..8bc58a08f9 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryComponent.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryComponent.kt
@@ -2,10 +2,10 @@ package com.tangem.features.tangempay.components.txHistory
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
-import com.tangem.features.txhistory.entity.TxHistoryUM
+import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
import kotlinx.coroutines.flow.StateFlow
internal interface TangemPayTxHistoryComponent {
- val state: StateFlow
- fun LazyListScope.txHistoryContent(listState: LazyListState, state: TxHistoryUM)
+ val state: StateFlow
+ fun LazyListScope.txHistoryContent(listState: LazyListState, state: TangemPayTxHistoryUM)
}
\ No newline at end of file
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTransactionState.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTransactionState.kt
new file mode 100644
index 0000000000..675103d42e
--- /dev/null
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTransactionState.kt
@@ -0,0 +1,54 @@
+package com.tangem.features.tangempay.entity
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Color
+import com.tangem.core.ui.extensions.TextReference
+
+internal sealed interface TangemPayTransactionState {
+
+ val id: String
+
+ data class Loading(override val id: String) : TangemPayTransactionState
+
+ sealed interface Content : TangemPayTransactionState {
+
+ val onClick: () -> Unit
+ val amount: String
+ val amountColor: @Composable (() -> Color)
+ val title: TextReference
+ val subtitle: TextReference
+ 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 title: TextReference,
+ override val subtitle: TextReference,
+ 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 title: TextReference,
+ override val subtitle: TextReference,
+ 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 title: TextReference,
+ override val subtitle: TextReference,
+ override val time: String,
+ ) : Content
+ }
+}
\ No newline at end of file
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTxHistoryUM.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTxHistoryUM.kt
new file mode 100644
index 0000000000..4bc4f8207b
--- /dev/null
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTxHistoryUM.kt
@@ -0,0 +1,45 @@
+package com.tangem.features.tangempay.entity
+
+import com.tangem.core.ui.components.transactions.state.TxHistoryState
+import kotlinx.collections.immutable.ImmutableList
+import kotlinx.collections.immutable.persistentListOf
+
+internal sealed interface TangemPayTxHistoryUM {
+
+ val isBalanceHidden: Boolean
+
+ data class Loading(override val isBalanceHidden: Boolean) : TangemPayTxHistoryUM {
+ val items = persistentListOf(
+ TangemPayTxHistoryItemUM.Title,
+ TangemPayTxHistoryItemUM.Transaction(TangemPayTransactionState.Loading("LOADING_TX_HASH_1")),
+ TangemPayTxHistoryItemUM.Transaction(TangemPayTransactionState.Loading("LOADING_TX_HASH_2")),
+ TangemPayTxHistoryItemUM.Transaction(TangemPayTransactionState.Loading("LOADING_TX_HASH_3")),
+ )
+ }
+
+ data class Empty(override val isBalanceHidden: Boolean) : TangemPayTxHistoryUM
+ data class Error(override val isBalanceHidden: Boolean, val onReload: () -> Unit) : TangemPayTxHistoryUM
+
+ data class Content(
+ override val isBalanceHidden: Boolean,
+ val items: ImmutableList,
+ val loadMore: () -> Boolean,
+ ) : TangemPayTxHistoryUM
+
+ fun copySealed(isBalanceHidden: Boolean): TangemPayTxHistoryUM {
+ return when (this) {
+ is Content -> copy(isBalanceHidden = isBalanceHidden)
+ is Empty -> copy(isBalanceHidden = isBalanceHidden)
+ is Error -> copy(isBalanceHidden = isBalanceHidden)
+ is Loading -> copy(isBalanceHidden = isBalanceHidden)
+ }
+ }
+
+ sealed interface TangemPayTxHistoryItemUM {
+ data object Title : TangemPayTxHistoryItemUM
+ data class GroupTitle(val title: String, val itemKey: String) : TangemPayTxHistoryItemUM {
+ val legacyGroupTitle = TxHistoryState.TxHistoryItemState.GroupTitle(title = title, itemKey = itemKey)
+ }
+ data class Transaction(val transaction: TangemPayTransactionState) : TangemPayTxHistoryItemUM
+ }
+}
\ No newline at end of file
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryModel.kt
index f7b8a89c8b..1b3778feb0 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryModel.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryModel.kt
@@ -6,10 +6,11 @@ import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository
+import com.tangem.domain.visa.model.TangemPayTxHistoryItem
import com.tangem.features.tangempay.components.txHistory.DefaultTangemPayTxHistoryComponent
+import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
import com.tangem.features.tangempay.utils.TangemPayTxHistoryListManager
-import com.tangem.features.txhistory.entity.TxHistoryUM
-import com.tangem.features.txhistory.utils.TxHistoryUiActions
+import com.tangem.features.tangempay.utils.TangemPayTxHistoryUiActions
import com.tangem.pagination.PaginationStatus
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.collections.immutable.ImmutableList
@@ -25,7 +26,7 @@ internal class TangemPayTxHistoryModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
tangemPayTxHistoryRepository: TangemPayTxHistoryRepository,
paramsContainer: ParamsContainer,
-) : Model(), TxHistoryUiActions {
+) : Model(), TangemPayTxHistoryUiActions {
private val params: DefaultTangemPayTxHistoryComponent.Params = paramsContainer.require()
private val listManager = TangemPayTxHistoryListManager(
@@ -35,8 +36,8 @@ internal class TangemPayTxHistoryModel @Inject constructor(
txHistoryUiActions = this,
)
- val uiState: StateFlow
- field = MutableStateFlow(getLoadingState(isBalanceHidden = true))
+ val uiState: StateFlow
+ field = MutableStateFlow(getLoadingState(isBalanceHidden = true))
init {
handleBalanceHiding()
@@ -50,19 +51,19 @@ internal class TangemPayTxHistoryModel @Inject constructor(
private fun subscribeToUiItemChanges() {
listManager.uiItems
- .onEach { updateState(it) }
+ .onEach(::updateState)
.launchIn(modelScope)
listManager.paginationStatus
.onEach { paginationStatus -> handlePaginationStatus(paginationStatus) }
.launchIn(modelScope)
}
- private fun updateState(items: ImmutableList) {
+ private fun updateState(items: ImmutableList) {
uiState.update { state ->
- if (state is TxHistoryUM.Content) {
+ if (state is TangemPayTxHistoryUM.Content) {
state.copy(items = items)
} else {
- TxHistoryUM.Content(
+ TangemPayTxHistoryUM.Content(
items = items,
isBalanceHidden = state.isBalanceHidden,
loadMore = ::loadMoreItems,
@@ -91,11 +92,8 @@ internal class TangemPayTxHistoryModel @Inject constructor(
}
fun reload() {
- // fast exit
- if (uiState.value is TxHistoryUM.NotSupported) return
-
uiState.update { state ->
- state as? TxHistoryUM.Content ?: getLoadingState(state.isBalanceHidden)
+ state as? TangemPayTxHistoryUM.Content ?: getLoadingState(state.isBalanceHidden)
}
modelScope.launch { listManager.reload() }
}
@@ -106,23 +104,15 @@ internal class TangemPayTxHistoryModel @Inject constructor(
.launchIn(modelScope)
}
- override fun openExplorer() {
- Timber.d("onExploreClick: open explorer")
+ override fun onTransactionClick(item: TangemPayTxHistoryItem) {
+ Timber.d("onTransactionClick: $item")
}
- override fun openTxInExplorer(txHash: String) {
- Timber.d("openTxInExplorer: $txHash")
+ private fun getErrorState(isBalanceHidden: Boolean): TangemPayTxHistoryUM.Error {
+ return TangemPayTxHistoryUM.Error(isBalanceHidden = isBalanceHidden, onReload = ::reload)
}
- private fun getErrorState(isBalanceHidden: Boolean): TxHistoryUM.Error {
- return TxHistoryUM.Error(
- isBalanceHidden = isBalanceHidden,
- onReloadClick = ::reload,
- onExploreClick = ::openExplorer,
- )
- }
-
- private fun getLoadingState(isBalanceHidden: Boolean): TxHistoryUM.Loading {
- return TxHistoryUM.Loading(isBalanceHidden = isBalanceHidden, onExploreClick = ::openExplorer)
+ private fun getLoadingState(isBalanceHidden: Boolean): TangemPayTxHistoryUM.Loading {
+ return TangemPayTxHistoryUM.Loading(isBalanceHidden = isBalanceHidden)
}
}
\ No newline at end of file
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryItemsConverter.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryItemsConverter.kt
index 3e07907e7b..9184fac026 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryItemsConverter.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryItemsConverter.kt
@@ -1,40 +1,80 @@
package com.tangem.features.tangempay.model.transformers
-import com.tangem.core.ui.components.transactions.state.TransactionState
-import com.tangem.core.ui.extensions.capitalize
import com.tangem.core.ui.extensions.stringReference
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.txhistory.utils.TxHistoryUiActions
-import com.tangem.utils.StringsSigns
+import com.tangem.features.tangempay.entity.TangemPayTransactionState
+import com.tangem.features.tangempay.utils.TangemPayTxHistoryUiActions
import com.tangem.utils.converter.Converter
+import com.tangem.utils.extensions.isPositive
import org.joda.time.DateTimeZone
-import java.util.Currency
internal class TangemPayTxHistoryItemsConverter(
- private val txHistoryUiActions: TxHistoryUiActions,
-) : Converter {
- override fun convert(value: TangemPayTxHistoryItem): TransactionState {
- val localDate = value.date?.withZone(DateTimeZone.getDefault())
- val currency = Currency.getInstance(value.currency)
- val amount = value.amount.format {
- fiat(fiatCurrencyCode = currency.currencyCode, fiatCurrencySymbol = currency.symbol)
+ private val txHistoryUiActions: TangemPayTxHistoryUiActions,
+) : Converter {
+ override fun convert(value: TangemPayTxHistoryItem): TangemPayTransactionState.Content {
+ return when (value) {
+ is TangemPayTxHistoryItem.Spend -> convertSpend(spend = value)
+ is TangemPayTxHistoryItem.Payment -> convertPayment(payment = value)
+ is TangemPayTxHistoryItem.Fee -> convertFee(fee = value)
}
+ }
- return TransactionState.Content(
- txHash = value.id,
- amount = "${StringsSigns.MINUS}$amount",
- time = localDate?.let { DateTimeFormatters.formatDate(it, DateTimeFormatters.timeFormatter) } ?: "",
- status = TransactionState.Content.Status.Confirmed,
- direction = TransactionState.Content.Direction.OUTGOING,
- iconRes = R.drawable.ic_arrow_up_24,
- title = stringReference(value = value.merchantName?.capitalize() ?: "Unknown merchant"),
- subtitle = stringReference("How to get merchant type?"),
- timestamp = localDate?.millis ?: 0,
- onClick = { txHistoryUiActions.openTxInExplorer(value.id) },
+ private fun convertSpend(spend: TangemPayTxHistoryItem.Spend): TangemPayTransactionState.Content.Spend {
+ val localDate = spend.date.withZone(DateTimeZone.getDefault())
+ val amount = spend.amount.format {
+ fiat(fiatCurrencyCode = spend.currency.currencyCode, fiatCurrencySymbol = spend.currency.symbol)
+ }
+ return TangemPayTransactionState.Content.Spend(
+ id = spend.id,
+ onClick = { txHistoryUiActions.onTransactionClick(spend) },
+ amount = amount,
+ amountColor = { TangemTheme.colors.text.primary1 },
+ title = stringReference(spend.enrichedMerchantName ?: spend.merchantName),
+ subtitle = stringReference(spend.enrichedMerchantCategory ?: spend.merchantCategory),
+ time = DateTimeFormatters.formatDate(localDate, DateTimeFormatters.timeFormatter),
+ iconUrl = spend.enrichedMerchantIconUrl,
+ )
+ }
+
+ private fun convertPayment(payment: TangemPayTxHistoryItem.Payment): TangemPayTransactionState.Content.Payment {
+ val amount = payment.amount.format {
+ fiat(fiatCurrencyCode = payment.currency.currencyCode, fiatCurrencySymbol = payment.currency.symbol)
+ }
+ val title = if (payment.amount.isPositive()) "Deposit" else "Withdrawal"
+ return TangemPayTransactionState.Content.Payment(
+ id = payment.id,
+ onClick = { txHistoryUiActions.onTransactionClick(payment) },
+ amount = amount,
+ amountColor = {
+ 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(),
+ )
+ }
+
+ private fun convertFee(fee: TangemPayTxHistoryItem.Fee): TangemPayTransactionState.Content.Fee {
+ val amount = fee.amount.format {
+ fiat(fiatCurrencyCode = fee.currency.currencyCode, fiatCurrencySymbol = fee.currency.symbol)
+ }
+ return TangemPayTransactionState.Content.Fee(
+ id = fee.id,
+ onClick = { txHistoryUiActions.onTransactionClick(fee) },
+ amount = amount,
+ amountColor = { TangemTheme.colors.text.primary1 },
+ title = stringReference("Fee"),
+ subtitle = stringReference("Service fees"),
+ time = DateTimeFormatters.formatDate(fee.date, DateTimeFormatters.timeFormatter),
)
}
}
\ No newline at end of file
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUi.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUi.kt
new file mode 100644
index 0000000000..b7c07cbc03
--- /dev/null
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayTxHistoryUi.kt
@@ -0,0 +1,373 @@
+package com.tangem.features.tangempay.ui
+
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyListScope
+import androidx.compose.foundation.lazy.LazyListState
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Surface
+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.graphics.Color
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.constraintlayout.compose.ChainStyle
+import androidx.constraintlayout.compose.ConstraintLayout
+import androidx.constraintlayout.compose.Dimension
+import coil.compose.rememberAsyncImagePainter
+import com.tangem.core.ui.R
+import com.tangem.core.ui.components.CircleShimmer
+import com.tangem.core.ui.components.RectangleShimmer
+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.orMaskWithStars
+import com.tangem.core.ui.extensions.resolveReference
+import com.tangem.core.ui.extensions.stringResourceSafe
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.test.TransactionHistoryBlockTestTags
+import com.tangem.features.tangempay.entity.TangemPayTransactionState
+import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
+
+private const val LOAD_ITEMS_BUFFER = 20
+
+internal fun LazyListScope.tangemPayTxHistoryItems(listState: LazyListState, state: TangemPayTxHistoryUM) {
+ when (state) {
+ is TangemPayTxHistoryUM.Content -> contentItems(listState = listState, state = state)
+ is TangemPayTxHistoryUM.Empty -> TODO("[REDACTED_JIRA]")
+ is TangemPayTxHistoryUM.Error -> TODO("[REDACTED_JIRA]")
+ is TangemPayTxHistoryUM.Loading -> loadingItems(state = state)
+ }
+}
+
+private fun LazyListScope.contentItems(listState: LazyListState, state: TangemPayTxHistoryUM.Content) {
+ itemsIndexed(
+ items = state.items,
+ key = { index, item ->
+ when (item) {
+ is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle -> item.itemKey
+ is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Title -> index + item.hashCode()
+ is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction ->
+ item.transaction.id + (item.transaction as? TangemPayTransactionState.Content)?.hashCode()
+ }
+ },
+ contentType = { _, item -> item::class.java },
+ itemContent = { index, item ->
+ TangemPayTxHistoryListItem(
+ state = item,
+ isBalanceHidden = state.isBalanceHidden,
+ modifier = Modifier.roundedShapeItemDecoration(
+ currentIndex = index,
+ lastIndex = state.items.lastIndex,
+ ),
+ )
+ },
+ )
+ item {
+ InfiniteListHandler(
+ listState = listState,
+ buffer = LOAD_ITEMS_BUFFER,
+ onLoadMore = state.loadMore,
+ )
+ }
+}
+
+private fun LazyListScope.loadingItems(state: TangemPayTxHistoryUM.Loading) {
+ itemsIndexed(
+ items = state.items,
+ key = { _, item ->
+ when (item) {
+ is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle -> item.itemKey
+ is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Title -> item.hashCode()
+ is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction ->
+ item.transaction.id + (item.transaction as? TangemPayTransactionState.Content)?.hashCode()
+ }
+ },
+ contentType = { _, item -> item::class.java },
+ itemContent = { index, item ->
+ TangemPayTxHistoryListItem(
+ state = item,
+ isBalanceHidden = true,
+ modifier = Modifier.roundedShapeItemDecoration(
+ currentIndex = index,
+ lastIndex = state.items.lastIndex,
+ ),
+ )
+ },
+ )
+}
+
+@Composable
+private fun TangemPayTxHistoryListItem(
+ state: TangemPayTxHistoryUM.TangemPayTxHistoryItemUM,
+ isBalanceHidden: Boolean,
+ modifier: Modifier = Modifier,
+) {
+ when (state) {
+ is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle -> {
+ TxHistoryGroupTitle(config = state.legacyGroupTitle, modifier = modifier)
+ }
+ is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Title -> {
+ TangemPayTxHistoryTitle(modifier = modifier)
+ }
+ is TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction -> {
+ TangemPayTransaction(
+ transactionState = state.transaction,
+ isBalanceHidden = isBalanceHidden,
+ modifier = modifier,
+ )
+ }
+ }
+}
+
+@Composable
+private fun TangemPayTxHistoryTitle(modifier: Modifier = Modifier) {
+ Text(
+ text = stringResourceSafe(id = R.string.common_transactions),
+ color = TangemTheme.colors.text.tertiary,
+ style = TangemTheme.typography.subtitle2,
+ modifier = modifier
+ .background(TangemTheme.colors.background.primary)
+ .padding(top = TangemTheme.dimens.spacing12)
+ .padding(horizontal = TangemTheme.dimens.spacing12)
+ .fillMaxWidth()
+ .heightIn(min = TangemTheme.dimens.size24)
+ .testTag(TransactionHistoryBlockTestTags.TITLE_TEXT),
+ )
+}
+
+@Suppress("LongMethod")
+@Composable
+private fun TangemPayTransaction(
+ transactionState: TangemPayTransactionState,
+ isBalanceHidden: Boolean,
+ modifier: Modifier = Modifier,
+) {
+ Surface(
+ modifier = modifier
+ .background(TangemTheme.colors.background.primary)
+ .clickable(
+ enabled = transactionState is TangemPayTransactionState.Content,
+ onClick = (transactionState as? TangemPayTransactionState.Content)?.onClick ?: {},
+ )
+ .fillMaxWidth()
+ .heightIn(min = TangemTheme.dimens.size56)
+ .padding(
+ vertical = TangemTheme.dimens.spacing8,
+ horizontal = TangemTheme.dimens.spacing12,
+ ),
+ color = TangemTheme.colors.background.primary,
+ ) {
+ @Suppress("DestructuringDeclarationWithTooManyEntries")
+ ConstraintLayout(modifier = Modifier.fillMaxWidth()) {
+ val (iconItem, titleItem, subtitleItem, amountItem, timestampItem) = createRefs()
+
+ createVerticalChain(titleItem, subtitleItem, chainStyle = ChainStyle.Spread)
+ createVerticalChain(amountItem, timestampItem, chainStyle = ChainStyle.Spread)
+
+ Icon(
+ state = transactionState,
+ modifier = Modifier
+ .size(TangemTheme.dimens.size40)
+ .constrainAs(iconItem) {
+ start.linkTo(parent.start)
+ centerVerticallyTo(parent)
+ },
+ )
+
+ Title(
+ state = transactionState,
+ modifier = Modifier
+ .padding(
+ start = TangemTheme.dimens.spacing12,
+ end = TangemTheme.dimens.spacing4,
+ )
+ .constrainAs(titleItem) {
+ top.linkTo(parent.top)
+ bottom.linkTo(subtitleItem.top)
+ start.linkTo(iconItem.end)
+ end.linkTo(amountItem.start)
+ width = Dimension.fillToConstraints
+ },
+ )
+
+ Subtitle(
+ state = transactionState,
+ modifier = Modifier
+ .padding(
+ start = TangemTheme.dimens.spacing12,
+ end = TangemTheme.dimens.spacing4,
+ )
+ .constrainAs(subtitleItem) {
+ top.linkTo(titleItem.bottom)
+ bottom.linkTo(parent.bottom)
+ start.linkTo(iconItem.end)
+ end.linkTo(timestampItem.start)
+ width = Dimension.fillToConstraints
+ },
+ )
+
+ Amount(
+ state = transactionState,
+ isBalanceHidden = isBalanceHidden,
+ modifier = Modifier.constrainAs(amountItem) {
+ top.linkTo(parent.top)
+ bottom.linkTo(timestampItem.top)
+ start.linkTo(titleItem.end)
+ end.linkTo(parent.end)
+ width = Dimension.fillToConstraints
+ },
+ )
+
+ Timestamp(
+ state = transactionState,
+ modifier = Modifier.constrainAs(timestampItem) {
+ top.linkTo(amountItem.bottom)
+ bottom.linkTo(parent.bottom)
+ end.linkTo(parent.end)
+ },
+ )
+ }
+ }
+}
+
+@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)
+ }
+ }
+ is TangemPayTransactionState.Content.Fee -> LocalStaticIcon(modifier = modifier, id = R.drawable.ic_percent_24)
+ is TangemPayTransactionState.Content.Payment -> LocalStaticIcon(
+ modifier = modifier,
+ id = if (state.isIncome) R.drawable.ic_arrow_down_24 else R.drawable.ic_arrow_up_24,
+ )
+ is TangemPayTransactionState.Loading -> {
+ CircleShimmer(modifier = modifier.size(TangemTheme.dimens.size40))
+ }
+ }
+}
+
+@Composable
+private fun RemoteIcon(url: String, modifier: Modifier = Modifier) {
+ Icon(
+ modifier = modifier
+ .size(TangemTheme.dimens.size40)
+ .clip(CircleShape),
+ painter = rememberAsyncImagePainter(url),
+ contentDescription = null,
+ tint = Color.Unspecified,
+ )
+}
+
+@Composable
+private fun LocalStaticIcon(@DrawableRes id: Int, modifier: Modifier = Modifier) {
+ Box(
+ modifier = modifier
+ .size(TangemTheme.dimens.size40)
+ .background(color = TangemTheme.colors.icon.secondary.copy(alpha = 0.1F), shape = CircleShape),
+ ) {
+ Icon(
+ painter = painterResource(id),
+ contentDescription = null,
+ modifier = Modifier
+ .size(TangemTheme.dimens.size20)
+ .align(Alignment.Center),
+ tint = TangemTheme.colors.icon.informative,
+ )
+ }
+}
+
+@Composable
+private fun Title(state: TangemPayTransactionState, modifier: Modifier = Modifier) {
+ when (state) {
+ is TangemPayTransactionState.Content -> {
+ Text(
+ modifier = modifier,
+ text = state.title.resolveReference(),
+ color = TangemTheme.colors.text.primary1,
+ style = TangemTheme.typography.subtitle2,
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 1,
+ )
+ }
+ is TangemPayTransactionState.Loading -> {
+ RectangleShimmer(
+ modifier = modifier.size(width = TangemTheme.dimens.size70, height = TangemTheme.dimens.size12),
+ )
+ }
+ }
+}
+
+@Composable
+private fun Subtitle(state: TangemPayTransactionState, modifier: Modifier = Modifier) {
+ when (state) {
+ is TangemPayTransactionState.Content -> {
+ Text(
+ text = state.subtitle.resolveReference(),
+ modifier = modifier,
+ textAlign = TextAlign.Start,
+ color = TangemTheme.colors.text.tertiary,
+ style = TangemTheme.typography.caption2,
+ )
+ }
+ is TangemPayTransactionState.Loading -> {
+ RectangleShimmer(
+ modifier = modifier.size(width = TangemTheme.dimens.size52, height = TangemTheme.dimens.size12),
+ )
+ }
+ }
+}
+
+@Composable
+private fun Amount(state: TangemPayTransactionState, isBalanceHidden: Boolean, modifier: Modifier = Modifier) {
+ when (state) {
+ is TangemPayTransactionState.Content -> {
+ Text(
+ text = state.amount.orMaskWithStars(isBalanceHidden),
+ modifier = modifier,
+ textAlign = TextAlign.End,
+ color = state.amountColor(),
+ style = TangemTheme.typography.body2,
+ )
+ }
+ is TangemPayTransactionState.Loading -> {
+ RectangleShimmer(
+ modifier = modifier.size(width = TangemTheme.dimens.size40, height = TangemTheme.dimens.size12),
+ )
+ }
+ }
+}
+
+@Composable
+private fun Timestamp(state: TangemPayTransactionState, modifier: Modifier = Modifier) {
+ when (state) {
+ is TangemPayTransactionState.Content -> {
+ Text(
+ text = state.time,
+ modifier = modifier,
+ textAlign = TextAlign.End,
+ color = TangemTheme.colors.text.tertiary,
+ style = TangemTheme.typography.caption2,
+ )
+ }
+ is TangemPayTransactionState.Loading -> {
+ RectangleShimmer(
+ modifier = modifier.size(width = TangemTheme.dimens.size40, height = TangemTheme.dimens.size12),
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryListManager.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryListManager.kt
index 05ec6ef1d9..3ccf9cf202 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryListManager.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryListManager.kt
@@ -4,8 +4,7 @@ import com.tangem.domain.tangempay.model.TangemPayTxHistoryListBatchingContext
import com.tangem.domain.tangempay.model.TangemPayTxHistoryListConfig
import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
-import com.tangem.features.txhistory.entity.TxHistoryUM
-import com.tangem.features.txhistory.utils.TxHistoryUiActions
+import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
import com.tangem.pagination.BatchAction
import com.tangem.pagination.BatchListState
import com.tangem.pagination.PaginationStatus
@@ -23,7 +22,7 @@ internal class TangemPayTxHistoryListManager(
private val repository: TangemPayTxHistoryRepository,
private val dispatchers: CoroutineDispatcherProvider,
private val customerWalletAddress: String,
- private val txHistoryUiActions: TxHistoryUiActions,
+ private val txHistoryUiActions: TangemPayTxHistoryUiActions,
) {
private val jobHolder = JobHolder()
private val actionsFlow: MutableSharedFlow = MutableSharedFlow(
@@ -33,7 +32,7 @@ internal class TangemPayTxHistoryListManager(
private val state: MutableStateFlow = MutableStateFlow(TangemPayTxHistoryState())
private val uiManager = TangemPayTxHistoryUiManager(state = state, txHistoryUiActions = txHistoryUiActions)
- val uiItems: Flow> = uiManager.items
+ val uiItems: Flow> = uiManager.items
val paginationStatus: Flow> = state.map { it.status }.distinctUntilChanged()
suspend fun launchPagination() = coroutineScope {
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryState.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryState.kt
index b9b28372b3..5717238dda 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryState.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryState.kt
@@ -1,10 +1,10 @@
package com.tangem.features.tangempay.utils
-import com.tangem.features.txhistory.entity.TxHistoryUM
+import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
import com.tangem.pagination.Batch
import com.tangem.pagination.PaginationStatus
-data class TangemPayTxHistoryState(
+internal data class TangemPayTxHistoryState(
val status: PaginationStatus<*> = PaginationStatus.None,
- val uiBatches: List>> = listOf(),
+ val uiBatches: List>> = listOf(),
)
\ No newline at end of file
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryUiActions.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryUiActions.kt
new file mode 100644
index 0000000000..08b2f82527
--- /dev/null
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryUiActions.kt
@@ -0,0 +1,7 @@
+package com.tangem.features.tangempay.utils
+
+import com.tangem.domain.visa.model.TangemPayTxHistoryItem
+
+internal interface TangemPayTxHistoryUiActions {
+ fun onTransactionClick(item: TangemPayTxHistoryItem)
+}
\ No newline at end of file
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryUiManager.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryUiManager.kt
index fc3dc5f1df..0c4fb3698e 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryUiManager.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/utils/TangemPayTxHistoryUiManager.kt
@@ -2,9 +2,8 @@ package com.tangem.features.tangempay.utils
import com.tangem.core.ui.utils.toDateFormatWithTodayYesterday
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
+import com.tangem.features.tangempay.entity.TangemPayTxHistoryUM
import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryItemsConverter
-import com.tangem.features.txhistory.entity.TxHistoryUM
-import com.tangem.features.txhistory.utils.TxHistoryUiActions
import com.tangem.pagination.Batch
import com.tangem.pagination.PaginationStatus
import kotlinx.collections.immutable.ImmutableList
@@ -15,11 +14,11 @@ import java.util.UUID
internal class TangemPayTxHistoryUiManager(
private val state: MutableStateFlow,
- private val txHistoryUiActions: TxHistoryUiActions,
+ private val txHistoryUiActions: TangemPayTxHistoryUiActions,
) {
@OptIn(ExperimentalCoroutinesApi::class)
- val items: Flow> = state
+ val items: Flow> = state
// filter initial states, since we dont emit loading items as UI items
.filter {
it.status !is PaginationStatus.None &&
@@ -38,7 +37,7 @@ internal class TangemPayTxHistoryUiManager(
fun createOrUpdateUiBatches(
newCurrencyBatches: List>>,
clearUiBatches: Boolean,
- ): List>> {
+ ): List>> {
val currentUiBatches = state.value.uiBatches
val batches = if (clearUiBatches) mutableListOf() else currentUiBatches.toMutableList()
@@ -68,51 +67,58 @@ internal class TangemPayTxHistoryUiManager(
return batches
}
- private fun generateUiItems(key: Int, data: List): List {
- val items = mutableListOf()
+ private fun generateUiItems(
+ key: Int,
+ data: List,
+ ): List {
+ val items = mutableListOf()
// Add title for the first batch
if (key == 0) {
- items.add(TxHistoryUM.TxHistoryItemUM.Title(onExploreClick = txHistoryUiActions::openExplorer))
+ items.add(TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Title)
}
// Process batch items only if there are any
if (data.isNotEmpty()) {
// Add first item with its group title
val firstItem = data.first()
- val firstDate = firstItem.timeStampInMillis.toDateFormatWithTodayYesterday()
+ val firstDate = firstItem.date.millis.toDateFormatWithTodayYesterday()
items.add(
- TxHistoryUM.TxHistoryItemUM.GroupTitle(
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle(
title = firstDate,
itemKey = UUID.randomUUID().toString(),
),
)
- items.add(TxHistoryUM.TxHistoryItemUM.Transaction(txHistoryItemConverter.convert(firstItem)))
+ items.add(
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(txHistoryItemConverter.convert(firstItem)),
+ )
// Process remaining items with date separators when needed
data.zipWithNext { current, next ->
- val currentDate = current.timeStampInMillis.toDateFormatWithTodayYesterday()
- val nextDate = next.timeStampInMillis.toDateFormatWithTodayYesterday()
+ val currentDate = current.date.millis.toDateFormatWithTodayYesterday()
+ val nextDate = next.date.millis.toDateFormatWithTodayYesterday()
if (currentDate != nextDate) {
items.add(
- TxHistoryUM.TxHistoryItemUM.GroupTitle(
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.GroupTitle(
title = nextDate,
itemKey = UUID.randomUUID().toString(),
),
)
}
- items.add(TxHistoryUM.TxHistoryItemUM.Transaction(txHistoryItemConverter.convert(next)))
+ items.add(
+ TangemPayTxHistoryUM.TangemPayTxHistoryItemUM.Transaction(txHistoryItemConverter.convert(next)),
+ )
}
}
return items
}
- private fun List.transactionItemsSizeNotEqual(
+ private fun List.transactionItemsSizeNotEqual(
txInfos: List,
): Boolean {
- return this.filterIsInstance().size != txInfos.size
+ return this.filterIsInstance().size != txInfos.size
}
}
\ No newline at end of file
diff --git a/features/txhistory/api/src/main/kotlin/com/tangem/features/txhistory/utils/TxHistoryUiActions.kt b/features/txhistory/impl/src/main/kotlin/com/tangem/features/txhistory/utils/TxHistoryUiActions.kt
similarity index 73%
rename from features/txhistory/api/src/main/kotlin/com/tangem/features/txhistory/utils/TxHistoryUiActions.kt
rename to features/txhistory/impl/src/main/kotlin/com/tangem/features/txhistory/utils/TxHistoryUiActions.kt
index 9f7922aeda..57a50a9014 100644
--- a/features/txhistory/api/src/main/kotlin/com/tangem/features/txhistory/utils/TxHistoryUiActions.kt
+++ b/features/txhistory/impl/src/main/kotlin/com/tangem/features/txhistory/utils/TxHistoryUiActions.kt
@@ -1,6 +1,6 @@
package com.tangem.features.txhistory.utils
-interface TxHistoryUiActions {
+internal interface TxHistoryUiActions {
fun openExplorer()
fun openTxInExplorer(txHash: String)
diff --git a/features/wallet/impl/build.gradle.kts b/features/wallet/impl/build.gradle.kts
index b622e8fe42..4b2119adcb 100644
--- a/features/wallet/impl/build.gradle.kts
+++ b/features/wallet/impl/build.gradle.kts
@@ -58,6 +58,7 @@ dependencies {
implementation(projects.core.decompose)
implementation(projects.core.datasource)
implementation(projects.core.res)
+ implementation(projects.core.error)
implementation(projects.libs.crypto)
implementation(projects.libs.blockchainSdk)
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt
index 8fd08667d7..c843cb1153 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/WalletModel.kt
@@ -356,42 +356,28 @@ internal class WalletModel @Inject constructor(
}
private suspend fun refreshTangemPayInfo() {
- val newState = withContext(dispatchers.io) {
- tangemPayMainScreenCustomerInfoUseCase()?.let { info ->
- TangemPayStateTransformer(
+ val info = tangemPayMainScreenCustomerInfoUseCase()
+ if (info != null) {
+ stateHolder.update(
+ transformer = TangemPayStateTransformer(
value = info,
onIssueOrderClick = ::issueOrder,
onContinueKycClick = innerWalletRouter::openTangemPayOnboarding,
- cardOnClick = ::tangemPayCardOnClick,
- ).transform(stateHolder.uiState.value.tangemPayState)
- }
- } ?: return
- stateHolder.update { it.copy(tangemPayState = newState) }
+ openDetails = innerWalletRouter::openTangemPayDetails,
+ ),
+ )
+ }
}
private fun issueOrder() {
modelScope.launch {
- stateHolder.update {
- it.copy(
- tangemPayState = TangemPayStateTransformer(issueProgressState = true)
- .transform(it.tangemPayState),
- )
- }
- withContext(dispatchers.io) {
- tangemPayIssueOrderUseCase()
- } ?: stateHolder.update {
- it.copy(
- tangemPayState = TangemPayStateTransformer(issueState = true, onIssueOrderClick = ::issueOrder)
- .transform(it.tangemPayState),
- )
+ stateHolder.update(TangemPayStateTransformer(issueProgressState = true))
+ tangemPayIssueOrderUseCase().onLeft {
+ stateHolder.update(TangemPayStateTransformer(issueState = true, onIssueOrderClick = ::issueOrder))
}
}
}
- private fun tangemPayCardOnClick(customerWalletAddress: String, cardNumberEnd: String) {
- innerWalletRouter.openTangemPayDetails(customerWalletAddress, cardNumberEnd)
- }
-
private fun needToRefreshTimer() {
modelScope.launch {
delay(REFRESH_WALLET_BACKGROUND_TIMER_MILLIS)
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/TangemPayStateTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/TangemPayStateTransformer.kt
index b1d5ef746f..9e367377ba 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/TangemPayStateTransformer.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/TangemPayStateTransformer.kt
@@ -6,26 +6,29 @@ import com.tangem.core.ui.format.bigdecimal.fiat
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.domain.pay.model.CustomerInfo.CardInfo
import com.tangem.domain.pay.model.MainScreenCustomerInfo
-import com.tangem.domain.pay.model.OrderStatus.NOT_ISSUED
import com.tangem.domain.pay.model.OrderStatus.CANCELED
+import com.tangem.domain.pay.model.OrderStatus.NOT_ISSUED
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState.Progress
-import com.tangem.utils.transformer.Transformer
+import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenState
import java.util.Currency
internal class TangemPayStateTransformer(
private val value: MainScreenCustomerInfo? = null,
private val onIssueOrderClick: () -> Unit = {},
private val onContinueKycClick: () -> Unit = {},
- private val cardOnClick: (customerWalletAddress: String, cardNumberEnd: String) -> Unit = { _, _ -> },
+ private val openDetails: (customerWalletAddress: String, cardNumberEnd: String) -> Unit = { _, _ -> },
private val issueProgressState: Boolean = false,
private val issueState: Boolean = false,
-) : Transformer {
+) : WalletScreenStateTransformer {
- override fun transform(prevState: TangemPayState): TangemPayState = when {
- issueProgressState -> createIssueProgressState()
- issueState -> createIssueState()
- else -> createInitialState()
+ override fun transform(prevState: WalletScreenState): WalletScreenState {
+ val tangemPayState = when {
+ issueProgressState -> createIssueProgressState()
+ issueState -> createIssueState()
+ else -> createInitialState()
+ }
+ return prevState.copy(tangemPayState = tangemPayState)
}
private fun createInitialState(): TangemPayState {
@@ -64,7 +67,7 @@ internal class TangemPayStateTransformer(
private fun getCardInfoState(cardInfo: CardInfo): TangemPayState = TangemPayState.Card(
lastFourDigits = TextReference.Str("*${cardInfo.lastFourDigits}"),
balanceText = TextReference.Str(getBalanceText(cardInfo)),
- onClick = { cardOnClick(cardInfo.customerWalletAddress, cardInfo.lastFourDigits) },
+ onClick = { openDetails(cardInfo.customerWalletAddress, cardInfo.lastFourDigits) },
)
private fun getBalanceText(cardInfo: CardInfo): String {
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/singlecurrency/TangemPayCardMainBlock.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/singlecurrency/TangemPayCardMainBlock.kt
index 35c2b614fc..c108284448 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/singlecurrency/TangemPayCardMainBlock.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/singlecurrency/TangemPayCardMainBlock.kt
@@ -1,7 +1,6 @@
package com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency
import androidx.compose.foundation.Image
-import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Surface
@@ -22,11 +21,10 @@ import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
@Composable
internal fun TangemPayCardMainBlock(state: TangemPayState.Card, modifier: Modifier = Modifier) {
Surface(
- modifier = modifier
- .fillMaxWidth()
- .clickable { state.onClick() },
+ modifier = modifier.fillMaxWidth(),
shape = TangemTheme.shapes.roundedCornersXMedium,
color = TangemTheme.colors.background.primary,
+ onClick = state.onClick,
) {
Row(
modifier = Modifier