Updated on 2026-08-14
This commit is contained in:
parent
e40ce860a4
commit
2b4aa16605
5 changed files with 93 additions and 47 deletions
|
|
@ -17,5 +17,6 @@ internal sealed class SendRecipientListContent {
|
|||
|
||||
data class Wallets(
|
||||
val list: PersistentList<Item>,
|
||||
val isWalletsOnly: Boolean,
|
||||
) : SendRecipientListContent()
|
||||
}
|
||||
|
|
@ -105,10 +105,15 @@ internal class SendStateFactory(
|
|||
//endregion
|
||||
|
||||
//region recipient
|
||||
fun onLoadedRecipientList(wallets: List<AvailableWallet?>, txHistory: PagingData<TxHistoryItem>) {
|
||||
fun onLoadedRecipientList(
|
||||
wallets: List<AvailableWallet?>,
|
||||
txHistory: PagingData<TxHistoryItem>,
|
||||
txHistoryCount: Int,
|
||||
) {
|
||||
recipientListStateConverter.convert(
|
||||
wallets = wallets,
|
||||
txHistory = txHistory,
|
||||
txHistoryCount = txHistoryCount,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ internal class SendRecipientListConverter(
|
|||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus>,
|
||||
) {
|
||||
|
||||
fun convert(wallets: List<AvailableWallet?>, txHistory: PagingData<TxHistoryItem>) {
|
||||
fun convert(wallets: List<AvailableWallet?>, txHistory: PagingData<TxHistoryItem>, txHistoryCount: Int) {
|
||||
val filteredWallets = wallets.filterNotNull()
|
||||
.groupBy { item -> item.name }
|
||||
.values.flatten()
|
||||
|
|
@ -32,49 +32,58 @@ internal class SendRecipientListConverter(
|
|||
)
|
||||
}
|
||||
|
||||
val walletsItem = getWalletItems(filteredWallets, txHistoryCount)
|
||||
|
||||
currentStateProvider().recipientList.update {
|
||||
txHistory.filter { item ->
|
||||
val isTransfer = item.type == TxHistoryItem.TransactionType.Transfer
|
||||
val isNotContract = item.interactionAddressType is TxHistoryItem.InteractionAddressType.User
|
||||
val isSingleAddress = if (item.isOutgoing) {
|
||||
item.destinationType is TxHistoryItem.DestinationType.Single
|
||||
} else {
|
||||
item.sourceType is TxHistoryItem.SourceType.Single
|
||||
}
|
||||
isTransfer && isSingleAddress && isNotContract
|
||||
}.map<TxHistoryItem, SendRecipientListContent> { tx ->
|
||||
SendRecipientListContent.Item(
|
||||
id = tx.txHash,
|
||||
title = tx.extractAddress(),
|
||||
subtitle = TextReference.Str(tx.getAmount()),
|
||||
info = tx.extractTimestamp(),
|
||||
subtitleIconRes = tx.extractIconRes(),
|
||||
)
|
||||
}.insertWallets(filteredWallets)
|
||||
if (txHistoryCount == 0) {
|
||||
PagingData.from(listOf(walletsItem))
|
||||
} else {
|
||||
txHistory.filter { item ->
|
||||
val isTransfer = item.type == TxHistoryItem.TransactionType.Transfer
|
||||
val isNotContract = item.interactionAddressType is TxHistoryItem.InteractionAddressType.User
|
||||
val isSingleAddress = if (item.isOutgoing) {
|
||||
item.destinationType is TxHistoryItem.DestinationType.Single
|
||||
} else {
|
||||
item.sourceType is TxHistoryItem.SourceType.Single
|
||||
}
|
||||
isTransfer && isSingleAddress && isNotContract
|
||||
}.map<TxHistoryItem, SendRecipientListContent> { tx ->
|
||||
SendRecipientListContent.Item(
|
||||
id = tx.txHash,
|
||||
title = tx.extractAddress(),
|
||||
subtitle = TextReference.Str(tx.getAmount()),
|
||||
info = tx.extractTimestamp(),
|
||||
subtitleIconRes = tx.extractIconRes(),
|
||||
)
|
||||
}.insertWallets(walletsItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun PagingData<SendRecipientListContent>.insertWallets(
|
||||
wallets: List<AvailableWallet>,
|
||||
wallets: SendRecipientListContent.Wallets,
|
||||
): PagingData<SendRecipientListContent> {
|
||||
return insertSeparators(terminalSeparatorType = TerminalSeparatorType.SOURCE_COMPLETE) { before, after ->
|
||||
return@insertSeparators when {
|
||||
before == null && after is SendRecipientListContent.Item -> {
|
||||
SendRecipientListContent.Wallets(
|
||||
wallets.map {
|
||||
SendRecipientListContent.Item(
|
||||
id = it.address,
|
||||
title = TextReference.Str(it.address),
|
||||
subtitle = TextReference.Str(it.name),
|
||||
)
|
||||
}.toPersistentList(),
|
||||
)
|
||||
}
|
||||
before == null && after is SendRecipientListContent.Item -> wallets
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getWalletItems(wallets: List<AvailableWallet>, txHistoryCount: Int): SendRecipientListContent.Wallets {
|
||||
return SendRecipientListContent.Wallets(
|
||||
wallets.map {
|
||||
SendRecipientListContent.Item(
|
||||
id = it.address,
|
||||
title = TextReference.Str(it.address),
|
||||
subtitle = TextReference.Str(it.name),
|
||||
)
|
||||
}.toPersistentList(),
|
||||
isWalletsOnly = txHistoryCount == 0,
|
||||
)
|
||||
}
|
||||
|
||||
private fun TxHistoryItem.extractAddress(): TextReference = if (isOutgoing) {
|
||||
when (val destination = destinationType) {
|
||||
is TxHistoryItem.DestinationType.Multiple -> TextReference.Res(
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ internal fun SendRecipientContent(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
private fun LazyListScope.recipientListItem(
|
||||
recipientList: LazyPagingItems<SendRecipientListContent>,
|
||||
|
|
@ -106,10 +107,17 @@ private fun LazyListScope.recipientListItem(
|
|||
.padding(top = TangemTheme.dimens.spacing20)
|
||||
.then(
|
||||
if (index == 0) {
|
||||
val bottomRadius = if (item.isWalletsOnly) {
|
||||
TangemTheme.dimens.radius12
|
||||
} else {
|
||||
TangemTheme.dimens.radius0
|
||||
}
|
||||
Modifier.clip(
|
||||
RoundedCornerShape(
|
||||
topEnd = TangemTheme.dimens.radius12,
|
||||
topStart = TangemTheme.dimens.radius12,
|
||||
bottomStart = bottomRadius,
|
||||
bottomEnd = bottomRadius,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
|
|
@ -182,18 +190,25 @@ private fun RecipientWalletListItem(
|
|||
onClick = { clickIntents.onRecipientAddressValueChange(title) },
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = stringResource(R.string.send_recent_transactions),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
top = TangemTheme.dimens.spacing8,
|
||||
bottom = TangemTheme.dimens.spacing8,
|
||||
start = TangemTheme.dimens.spacing12,
|
||||
end = TangemTheme.dimens.spacing12,
|
||||
),
|
||||
)
|
||||
if (!item.isWalletsOnly) {
|
||||
val topPadding = if (item.list.isNotEmpty()) {
|
||||
TangemTheme.dimens.spacing8
|
||||
} else {
|
||||
TangemTheme.dimens.spacing0
|
||||
}
|
||||
Text(
|
||||
text = stringResource(R.string.send_recent_transactions),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
top = topPadding,
|
||||
bottom = TangemTheme.dimens.spacing8,
|
||||
start = TangemTheme.dimens.spacing12,
|
||||
end = TangemTheme.dimens.spacing12,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import com.tangem.domain.tokens.model.CryptoCurrency
|
|||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -57,6 +58,7 @@ internal class SendViewModel @Inject constructor(
|
|||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val getCryptoCurrenciesUseCase: GetCryptoCurrenciesUseCase,
|
||||
private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase,
|
||||
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
|
||||
private val getFeeUseCase: GetFeeUseCase,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
|
|
@ -97,7 +99,6 @@ internal class SendViewModel @Inject constructor(
|
|||
override fun onCreate(owner: LifecycleOwner) {
|
||||
getWalletAddresses()
|
||||
subscribeOnCurrencyStatusUpdates(owner)
|
||||
getWalletsAndRecent()
|
||||
getFee()
|
||||
}
|
||||
|
||||
|
|
@ -134,6 +135,7 @@ internal class SendViewModel @Inject constructor(
|
|||
.onEach { either ->
|
||||
either.onRight {
|
||||
cryptoCurrencyStatus = it
|
||||
getWalletsAndRecent()
|
||||
uiState = stateFactory.getReadyState()
|
||||
}
|
||||
}
|
||||
|
|
@ -158,10 +160,12 @@ internal class SendViewModel @Inject constructor(
|
|||
combine(
|
||||
flow = getUserWallets().conflate(),
|
||||
flow2 = getTxHistory().conflate(),
|
||||
) { wallets, txHistory ->
|
||||
flow3 = getTxHistoryCount().conflate(),
|
||||
) { wallets, txHistory, txHistoryCount ->
|
||||
stateFactory.onLoadedRecipientList(
|
||||
wallets = wallets,
|
||||
txHistory = txHistory,
|
||||
txHistoryCount = txHistoryCount,
|
||||
)
|
||||
}
|
||||
.flowOn(dispatchers.io)
|
||||
|
|
@ -213,6 +217,18 @@ internal class SendViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getTxHistoryCount(): Flow<Int> {
|
||||
return flow {
|
||||
txHistoryItemsCountUseCase(
|
||||
userWalletId = userWalletId,
|
||||
currency = cryptoCurrency,
|
||||
).fold(
|
||||
ifRight = { emit(it) },
|
||||
ifLeft = { emit(0) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFee() {
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
uiState.currentState
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue