Updated on 2026-08-14

This commit is contained in:
Tangem 2023-08-14 19:02:42 +08:00
parent f422604467
commit eef7bac933
7 changed files with 94 additions and 40 deletions

View file

@ -23,6 +23,7 @@ import com.tangem.core.ui.components.CircleShimmer
import com.tangem.core.ui.components.RectangleShimmer
import com.tangem.core.ui.components.transactions.state.TransactionState
import com.tangem.core.ui.res.TangemTheme
import java.util.UUID
/**
* Transaction component
@ -312,45 +313,53 @@ private fun Preview_TransactionItem_DarkTheme(
private class TransactionItemStateProvider : CollectionPreviewParameterProvider<TransactionState>(
collection = listOf(
TransactionState.Sending(
txHash = UUID.randomUUID().toString(),
address = "33BddS...ga2B",
amount = "-0.500913 BTC",
timestamp = "8:41",
),
TransactionState.Receiving(
txHash = UUID.randomUUID().toString(),
address = "33BddS...ga2B",
amount = "+0.500913 BTC",
timestamp = "8:41",
),
TransactionState.Approving(
txHash = UUID.randomUUID().toString(),
address = "33BddS...ga2B",
amount = "+0.500913 BTC",
timestamp = "8:41",
),
TransactionState.Swapping(
txHash = UUID.randomUUID().toString(),
address = "33BddS...ga2B",
amount = "+0.500913 BTC",
timestamp = "8:41",
),
TransactionState.Send(
txHash = UUID.randomUUID().toString(),
address = "33BddS...ga2B",
amount = "-0.500913 BTC",
timestamp = "8:41",
),
TransactionState.Receive(
txHash = UUID.randomUUID().toString(),
address = "33BddS...ga2B",
amount = "+0.500913 BTC",
timestamp = "8:41",
),
TransactionState.Approved(
txHash = UUID.randomUUID().toString(),
address = "33BddS...ga2B",
amount = "+0.500913 BTC",
timestamp = "8:41",
),
TransactionState.Swapped(
txHash = UUID.randomUUID().toString(),
address = "33BddS...ga2B",
amount = "+0.500913 BTC",
timestamp = "8:41",
),
TransactionState.Loading,
TransactionState.Loading(txHash = UUID.randomUUID().toString()),
),
)

View file

@ -60,26 +60,31 @@ private fun LazyListScope.contentItems(
) {
itemsIndexed(
items = txHistoryItems,
key = { index, _ -> index },
itemContent = { index, item ->
if (item == null) return@itemsIndexed
TxHistoryListItem(
state = item,
modifier = modifier
.animateItemPlacement()
.roundedShapeItemDecoration(
currentIndex = index,
lastIndex = txHistoryItems.itemSnapshotList.lastIndex,
),
)
key = { _, item ->
when (item) {
is TxHistoryState.TxHistoryItemState.GroupTitle -> item.title
is TxHistoryState.TxHistoryItemState.Title -> item.onExploreClick.hashCode()
is TxHistoryState.TxHistoryItemState.Transaction -> item.state.txHash
}
},
)
) { index, item ->
if (item == null) return@itemsIndexed
TxHistoryListItem(
state = item,
modifier = modifier
.animateItemPlacement()
.roundedShapeItemDecoration(
currentIndex = index,
lastIndex = txHistoryItems.itemSnapshotList.lastIndex,
),
)
}
}
@OptIn(ExperimentalFoundationApi::class)
private fun LazyListScope.nonContentItem(state: EmptyTransactionsBlockState, modifier: Modifier = Modifier) {
item {
item(key = state::class.java, contentType = state::class.java) {
EmptyTransactionBlock(
state = state,
modifier = modifier

View file

@ -7,33 +7,39 @@ package com.tangem.core.ui.components.transactions.state
*/
sealed interface TransactionState {
/** Transaction hash */
val txHash: String
/**
* Content state
*
* @property txHash transaction hash
* @property address address
* @property amount amount
* @property timestamp timestamp
*/
sealed class Content(
override val txHash: String,
open val address: String,
open val amount: String,
open val timestamp: String,
) : TransactionState {
fun copySealed(
txHash: String = this.txHash,
address: String = this.address,
amount: String = this.amount,
timestamp: String = this.timestamp,
): Content {
return when (this) {
is Approved -> copy(address, amount, timestamp)
is Receive -> copy(address, amount, timestamp)
is Send -> copy(address, amount, timestamp)
is Swapped -> copy(address, amount, timestamp)
is Approving -> copy(address, amount, timestamp)
is Receiving -> copy(address, amount, timestamp)
is Sending -> copy(address, amount, timestamp)
is Swapping -> copy(address, amount, timestamp)
is Approved -> copy(txHash, address, amount, timestamp)
is Receive -> copy(txHash, address, amount, timestamp)
is Send -> copy(txHash, address, amount, timestamp)
is Swapped -> copy(txHash, address, amount, timestamp)
is Approving -> copy(txHash, address, amount, timestamp)
is Receiving -> copy(txHash, address, amount, timestamp)
is Sending -> copy(txHash, address, amount, timestamp)
is Swapping -> copy(txHash, address, amount, timestamp)
}
}
}
@ -41,133 +47,157 @@ sealed interface TransactionState {
/**
* Content state for processed transaction
*
* @property txHash transaction hash
* @property address address
* @property amount amount
* @property timestamp timestamp
*/
sealed class ProcessedTransactionContent(
override val txHash: String,
override val address: String,
override val amount: String,
override val timestamp: String,
) : Content(address, amount, timestamp)
) : Content(txHash, address, amount, timestamp)
/**
* Content state for completed transaction
*
* @property txHash transaction hash
* @property address address
* @property amount amount
* @property timestamp timestamp
*/
sealed class CompletedTransactionContent(
override val txHash: String,
override val address: String,
override val amount: String,
override val timestamp: String,
) : Content(address, amount, timestamp)
) : Content(txHash, address, amount, timestamp)
/**
* Processed sending transaction state
*
* @property txHash transaction hash
* @property address address
* @property amount amount
* @property timestamp timestamp
*/
data class Sending(
override val txHash: String,
override val address: String,
override val amount: String,
override val timestamp: String,
) : ProcessedTransactionContent(address, amount, timestamp)
) : ProcessedTransactionContent(txHash, address, amount, timestamp)
/**
* Processed receiving transaction state
*
* @property txHash transaction hash
* @property address address
* @property amount amount
* @property timestamp timestamp
*/
data class Receiving(
override val txHash: String,
override val address: String,
override val amount: String,
override val timestamp: String,
) : ProcessedTransactionContent(address, amount, timestamp)
) : ProcessedTransactionContent(txHash, address, amount, timestamp)
/**
* Processed approving transaction state
*
* @property txHash transaction hash
* @property address address
* @property amount amount
* @property timestamp timestamp
*/
data class Approving(
override val txHash: String,
override val address: String,
override val amount: String,
override val timestamp: String,
) : ProcessedTransactionContent(address, amount, timestamp)
) : ProcessedTransactionContent(txHash, address, amount, timestamp)
/**
* Processed swapping transaction state
*
* @property txHash transaction hash
* @property address address
* @property amount amount
* @property timestamp timestamp
*/
data class Swapping(
override val txHash: String,
override val address: String,
override val amount: String,
override val timestamp: String,
) : ProcessedTransactionContent(address, amount, timestamp)
) : ProcessedTransactionContent(txHash, address, amount, timestamp)
/**
* Completed sending transaction state
*
* @property txHash transaction hash
* @property address address
* @property amount amount
* @property timestamp timestamp
*/
data class Send(
override val txHash: String,
override val address: String,
override val amount: String,
override val timestamp: String,
) : CompletedTransactionContent(address, amount, timestamp)
) : CompletedTransactionContent(txHash, address, amount, timestamp)
/**
* Completed receiving transaction state
*
* @property txHash transaction hash
* @property address address
* @property amount amount
* @property timestamp timestamp
*/
data class Receive(
override val txHash: String,
override val address: String,
override val amount: String,
override val timestamp: String,
) : CompletedTransactionContent(address, amount, timestamp)
) : CompletedTransactionContent(txHash, address, amount, timestamp)
/**
* Completed approving transaction state
*
* @property txHash transaction hash
* @property address address
* @property amount amount
* @property timestamp timestamp
*/
data class Approved(
override val txHash: String,
override val address: String,
override val amount: String,
override val timestamp: String,
) : CompletedTransactionContent(address, amount, timestamp)
) : CompletedTransactionContent(txHash, address, amount, timestamp)
/**
* Completed swapping transaction state
*
* @property txHash transaction hash
* @property address address
* @property amount amount
* @property timestamp timestamp
*/
data class Swapped(
override val txHash: String,
override val address: String,
override val amount: String,
override val timestamp: String,
) : CompletedTransactionContent(address, amount, timestamp)
) : CompletedTransactionContent(txHash, address, amount, timestamp)
/** Loading state */
object Loading : TransactionState
/**
* Loading state
*
* @property txHash transaction hash
*/
data class Loading(override val txHash: String) : TransactionState
}

View file

@ -27,7 +27,7 @@ sealed interface TxHistoryState {
PagingData.from(
listOf(
TxHistoryItemState.Title(onExploreClick = onExploreClick),
TxHistoryItemState.Transaction(state = TransactionState.Loading),
TxHistoryItemState.Transaction(state = TransactionState.Loading(txHash = LOADING_TX_HASH)),
),
),
),
@ -42,7 +42,7 @@ sealed interface TxHistoryState {
items = flowOf(
value = PagingData.from(
data = buildList(capacity = itemsCount) {
add(TxHistoryItemState.Transaction(state = TransactionState.Loading))
add(TxHistoryItemState.Transaction(state = TransactionState.Loading(txHash = LOADING_TX_HASH)))
},
),
),
@ -66,7 +66,7 @@ sealed interface TxHistoryState {
PagingData.from(
listOf(
TxHistoryItemState.Title(onExploreClick = onExploreClick),
TxHistoryItemState.Transaction(state = TransactionState.Loading),
TxHistoryItemState.Transaction(state = TransactionState.Loading(txHash = LOADING_TX_HASH)),
),
),
),
@ -118,4 +118,8 @@ sealed interface TxHistoryState {
*/
data class Transaction(val state: TransactionState) : TxHistoryItemState
}
private companion object {
const val LOADING_TX_HASH = "LOADING_TX_HASH"
}
}

View file

@ -356,6 +356,7 @@ internal object WalletPreviewData {
TxHistoryState.TxHistoryItemState.GroupTitle("Today"),
TxHistoryState.TxHistoryItemState.Transaction(
TransactionState.Sending(
txHash = UUID.randomUUID().toString(),
address = "33BddS...ga2B",
amount = "-0.500913 BTC",
timestamp = "8:41",
@ -364,6 +365,7 @@ internal object WalletPreviewData {
TxHistoryState.TxHistoryItemState.GroupTitle("Yesterday"),
TxHistoryState.TxHistoryItemState.Transaction(
TransactionState.Sending(
txHash = UUID.randomUUID().toString(),
address = "33BddS...ga2B",
amount = "-0.500913 BTC",
timestamp = "8:41",

View file

@ -97,11 +97,13 @@ internal class WalletTxHistoryItemFlowConverter(
): TransactionState {
return when (item.status) {
TxHistoryItem.TxStatus.Confirmed -> TransactionState.Receive(
txHash = item.txHash,
address = direction.from.toBriefAddressFormat(),
amount = item.amount.toCryptoCurrencyFormat(blockchain = blockchain),
timestamp = item.getRawTimestamp(),
)
TxHistoryItem.TxStatus.Unconfirmed -> TransactionState.Receiving(
txHash = item.txHash,
address = direction.from.toBriefAddressFormat(),
amount = item.amount.toCryptoCurrencyFormat(blockchain = blockchain),
timestamp = item.getRawTimestamp(),
@ -116,11 +118,13 @@ internal class WalletTxHistoryItemFlowConverter(
): TransactionState {
return when (item.status) {
TxHistoryItem.TxStatus.Confirmed -> TransactionState.Send(
txHash = item.txHash,
address = direction.to.toBriefAddressFormat(),
amount = item.amount.toCryptoCurrencyFormat(blockchain = blockchain),
timestamp = item.getRawTimestamp(),
)
TxHistoryItem.TxStatus.Unconfirmed -> TransactionState.Sending(
txHash = item.txHash,
address = direction.to.toBriefAddressFormat(),
amount = item.amount.toCryptoCurrencyFormat(blockchain = blockchain),
timestamp = item.getRawTimestamp(),

View file

@ -29,7 +29,7 @@ internal class TokenListToContentItemsConverter(
override fun convert(value: TokenList): WalletTokensListState {
val isEmptyList = when (value) {
is TokenList.GroupedByNetwork -> value.groups.isEmpty()
is TokenList.NotInitialized -> true
is TokenList.NotInitialized -> false
is TokenList.Ungrouped -> value.currencies.isEmpty()
}