Updated on 2026-08-14

This commit is contained in:
Tangem 2026-05-18 16:12:10 +03:00
parent a82d8cdbba
commit 4ae70b5391
2 changed files with 16 additions and 5 deletions

View file

@ -61,7 +61,7 @@ private fun LazyListScope.contentItems(listState: LazyListState, state: TxHistor
key = { item ->
when (item) {
is TxHistoryItemUM.GroupTitle -> "group_title:${item.itemKey}"
is TxHistoryItemUM.Transaction -> "tx:${item.state.txHash}"
is TxHistoryItemUM.Transaction -> "tx:${item.state.txHash}:${item.state.hashCode()}"
}
},
contentType = { item -> item::class.java },

View file

@ -33,14 +33,16 @@ internal class TxHistoryUiManager(
): List<Batch<Int, List<TxHistoryItemsUM.TxHistoryItemUM>>> {
val currentUiBatches = state.value.uiBatches
val batches = if (shouldClearUiBatches) mutableListOf() else currentUiBatches.toMutableList()
val seenTxIds = mutableSetOf<String>()
for ((key, data) in newCurrencyBatches) {
val uniqueItems = data.items.filter { seenTxIds.add(it.identityKey()) }
val existingBatchIndex = batches.indexOfFirst { it.key == key }
if (existingBatchIndex == -1) {
val items = generateUiItems(key, data, converter)
val items = generateUiItems(key, data.copy(items = uniqueItems), converter)
batches.add(Batch(key = key, data = items))
} else if (currentUiBatches[existingBatchIndex].data.transactionItemsSizeNotEqual(data.items)) {
val items = generateUiItems(key, data, converter)
} else if (currentUiBatches[existingBatchIndex].data.transactionItemsSizeNotEqual(uniqueItems)) {
val items = generateUiItems(key, data.copy(items = uniqueItems), converter)
batches[existingBatchIndex] = Batch(key = key, data = items)
}
}
@ -94,4 +96,13 @@ internal class TxHistoryUiManager(
private val TxHistoryListState.hasContent: Boolean
get() = status !is PaginationStatus.None &&
status !is PaginationStatus.InitialLoading &&
status !is PaginationStatus.InitialLoadingError
status !is PaginationStatus.InitialLoadingError
/**
* Cross-batch identity of a tx: `txHash` alone is not enough because gasless flows surface several
* events under the same on-chain hash (e.g. `GaslessFee` + `Transfer`). Pinning the [TxInfo.type]
* keeps those legitimate sibling events apart while still collapsing the same event seen twice
* e.g. an Unconfirmed copy injected via `addRecentTransactions` and a Confirmed copy that arrives
* in a later API batch.
*/
private fun TxInfo.identityKey(): String = "$txHash|$type"