Updated on 2026-08-14

This commit is contained in:
Tangem 2023-09-13 14:19:25 +03:00
parent 4b5adcd08a
commit 5ed381c263
56 changed files with 631 additions and 455 deletions

View file

@ -206,7 +206,7 @@ internal object WalletPreviewData {
val networkNumber = index + 1
val group = DraggableItem.GroupHeader(
id = "group_$networkNumber",
id = networkNumber,
networkName = "$networkNumber",
roundingMode = when (index) {
0 -> DraggableItem.RoundingMode.Top()
@ -328,7 +328,7 @@ internal object WalletPreviewData {
walletsListConfig = walletListConfig,
tokensListState = WalletTokensListState.Content(
persistentListOf(
TokensListItemState.NetworkGroupTitle(TextReference.Str("Bitcoin")),
TokensListItemState.NetworkGroupTitle(id = 0, stringReference("Bitcoin")),
TokensListItemState.Token(
tokenItemVisibleState.copy(
id = "token_1",
@ -357,7 +357,7 @@ internal object WalletPreviewData {
amount = "1,89340821 ETH",
),
),
TokensListItemState.NetworkGroupTitle(TextReference.Str("Ethereum")),
TokensListItemState.NetworkGroupTitle(id = 1, stringReference("Ethereum")),
TokensListItemState.Token(
tokenItemVisibleState.copy(
id = "token_5",

View file

@ -13,7 +13,7 @@ import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem
* */
@Immutable
internal sealed class DraggableItem {
abstract val id: String
abstract val id: Any
abstract val roundingMode: RoundingMode
abstract val showShadow: Boolean
@ -26,7 +26,7 @@ internal sealed class DraggableItem {
* @property showShadow if true then item should be elevated
* */
data class GroupHeader(
override val id: String,
override val id: Int,
val networkName: String,
override val roundingMode: RoundingMode = RoundingMode.None,
override val showShadow: Boolean = false,
@ -43,7 +43,7 @@ internal sealed class DraggableItem {
* */
data class Token(
val tokenItemState: TokenItemState.Draggable,
val groupId: String,
val groupId: Int,
override val showShadow: Boolean = false,
override val roundingMode: RoundingMode = RoundingMode.None,
) : DraggableItem() {

View file

@ -5,4 +5,4 @@ import com.tangem.domain.tokens.models.Network
internal fun getTokenItemId(currencyId: CryptoCurrency.ID): String = currencyId.value
internal fun getGroupHeaderId(networkId: Network.ID): String = networkId.value
internal fun getGroupHeaderId(network: Network): Int = network.hashCode()

View file

@ -36,7 +36,7 @@ internal class CryptoCurrencyToDraggableItemConverter(
): DraggableItem.Token {
return DraggableItem.Token(
tokenItemState = createTokenItemState(currencyStatus, appCurrency),
groupId = getGroupHeaderId(currencyStatus.currency.network.id),
groupId = getGroupHeaderId(currencyStatus.currency.network),
)
}

View file

@ -31,7 +31,7 @@ internal class NetworkGroupToDraggableItemsConverter(
}
private fun createGroupHeader(group: NetworkGroup) = DraggableItem.GroupHeader(
id = getGroupHeaderId(group.network.id),
id = getGroupHeaderId(group.network),
networkName = group.network.name,
)

View file

@ -7,7 +7,7 @@ import com.tangem.feature.wallet.presentation.organizetokens.utils.common.uniteI
internal class DraggableGroupsOperations {
private var groupIdToTokens: Map<String, List<DraggableItem.Token>>? = null
private var groupIdToTokens: Map<Int, List<DraggableItem.Token>>? = null
fun collapseGroup(items: List<DraggableItem>, movingGroup: DraggableItem.GroupHeader): List<DraggableItem> {
if (!groupIdToTokens.isNullOrEmpty()) return items

View file

@ -53,7 +53,7 @@ internal sealed class WalletTokensListState {
/** Locked content state */
object Locked : ContentState(
items = persistentListOf(
TokensListItemState.NetworkGroupTitle(value = TextReference.Res(id = R.string.main_tokens)),
TokensListItemState.NetworkGroupTitle(id = 42, name = TextReference.Res(id = R.string.main_tokens)),
TokensListItemState.Token(state = TokenItemState.Locked(id = LOCKED_TOKEN_ID)),
),
organizeTokensButton = OrganizeTokensButtonState.Hidden,
@ -84,19 +84,26 @@ internal sealed class WalletTokensListState {
@Immutable
sealed interface TokensListItemState {
val id: Any
/**
* Network group title item
*
* @property value network name
* @property name network name
*/
data class NetworkGroupTitle(val value: TextReference) : TokensListItemState
data class NetworkGroupTitle(
override val id: Int,
val name: TextReference,
) : TokensListItemState
/**
* Token item
*
* @property state token item state
*/
data class Token(val state: TokenItemState) : TokensListItemState
data class Token(val state: TokenItemState) : TokensListItemState {
override val id: String = state.id
}
}
private companion object {

View file

@ -71,6 +71,7 @@ internal class WalletSingleCurrencyLoadedBalanceConverter(
is CryptoCurrencyStatus.MissedDerivation,
is CryptoCurrencyStatus.NoAccount,
is CryptoCurrencyStatus.Unreachable,
is CryptoCurrencyStatus.NoAmount,
-> MarketPriceBlockState.Error(currencyName)
}
}
@ -112,6 +113,7 @@ internal class WalletSingleCurrencyLoadedBalanceConverter(
is CryptoCurrencyStatus.NoAccount,
is CryptoCurrencyStatus.Custom,
is CryptoCurrencyStatus.Unreachable,
is CryptoCurrencyStatus.NoAmount,
-> {
WalletCardState.Error(
id = selectedWallet.id,

View file

@ -44,12 +44,7 @@ private fun LazyListScope.contentItems(
) {
itemsIndexed(
items = items,
key = { _, item ->
when (item) {
is WalletTokensListState.TokensListItemState.NetworkGroupTitle -> item.value.hashCode()
is WalletTokensListState.TokensListItemState.Token -> item.state.id
}
},
key = { _, item -> item.id },
contentType = { _, item -> item::class.java },
itemContent = { index, item ->
MultiCurrencyContentItem(

View file

@ -19,7 +19,7 @@ import com.tangem.feature.wallet.presentation.wallet.state.components.WalletToke
internal fun MultiCurrencyContentItem(state: WalletTokensListState.TokensListItemState, modifier: Modifier = Modifier) {
when (state) {
is WalletTokensListState.TokensListItemState.NetworkGroupTitle -> {
NetworkGroupItem(networkName = state.value.resolveReference(), modifier = modifier)
NetworkGroupItem(networkName = state.name.resolveReference(), modifier = modifier)
}
is WalletTokensListState.TokensListItemState.Token -> {
TokenItem(state = state.state, modifier = modifier)

View file

@ -30,6 +30,7 @@ internal class CryptoCurrencyStatusToTokenItemConverter(
is CryptoCurrencyStatus.MissedDerivation,
is CryptoCurrencyStatus.NoAccount,
is CryptoCurrencyStatus.Unreachable,
is CryptoCurrencyStatus.NoAmount,
-> value.mapToUnreachableTokenItemState()
}
}

View file

@ -1,7 +1,7 @@
package com.tangem.feature.wallet.presentation.wallet.utils
import com.tangem.common.Provider
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.NetworkGroup
@ -68,7 +68,12 @@ internal class TokenListToContentItemsConverter(
}
private fun MutableList<TokensListItemState>.addGroup(group: NetworkGroup): List<TokensListItemState> {
this.add(TokensListItemState.NetworkGroupTitle(TextReference.Str(group.network.name)))
val groupTitle = TokensListItemState.NetworkGroupTitle(
id = group.network.hashCode(),
name = stringReference(group.network.name),
)
this.add(groupTitle)
group.currencies.forEach { token ->
this.addToken(token)

View file

@ -3,8 +3,6 @@ package com.tangem.feature.wallet.presentation.wallet.viewmodels
import androidx.lifecycle.*
import androidx.paging.cachedIn
import arrow.core.getOrElse
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.derivation.DerivationStyle
import com.tangem.common.Provider
import com.tangem.common.doOnFailure
import com.tangem.common.doOnSuccess
@ -15,7 +13,6 @@ import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.card.*
import com.tangem.domain.common.CardTypesResolver
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.demo.IsDemoCardUseCase
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.domain.settings.CanUseBiometryUseCase
@ -461,14 +458,18 @@ internal class WalletViewModel @Inject constructor(
val wallet = getWallet(
index = requireNotNull(uiState as? WalletState.ContentState).walletsListConfig.selectedWalletIndex,
)
router.openTxHistoryWebsite(
url = getExploreUrlUseCase(
userWalletId = wallet.walletId,
networkId = Network.ID(
value = wallet.scanResponse.cardTypesResolver.getBlockchain().id,
val currencyStatus = getPrimaryCurrencyStatusUpdatesUseCase(wallet.walletId)
.firstOrNull()
?.getOrNull()
if (currencyStatus != null) {
router.openTxHistoryWebsite(
url = getExploreUrlUseCase(
userWalletId = wallet.walletId,
network = currencyStatus.currency.network,
),
),
)
)
}
}
}
@ -582,31 +583,20 @@ internal class WalletViewModel @Inject constructor(
private fun getSingleCurrencyContent(index: Int) {
val wallet = getWallet(index)
val blockchain = getCardTypeResolver(index).getBlockchain()
updateTxHistory(
blockchain = blockchain,
derivationStyle = wallet.scanResponse.derivationStyleProvider.getDerivationStyle(),
)
updateMarketPrice(userWalletId = wallet.walletId)
updatePrimaryCurrencyStatus(userWalletId = wallet.walletId)
updateNotifications(index)
}
private fun updateTxHistory(blockchain: Blockchain, derivationStyle: DerivationStyle?) {
private fun updateTxHistory(network: Network) {
viewModelScope.launch(dispatchers.io) {
val derivationPath = blockchain.derivationPath(style = derivationStyle)?.rawPath
val txHistoryItemsCountEither = txHistoryItemsCountUseCase(
networkId = Network.ID(blockchain.id),
derivationPath = derivationPath,
)
val txHistoryItemsCountEither = txHistoryItemsCountUseCase(network)
uiState = stateFactory.getLoadingTxHistoryState(itemsCountEither = txHistoryItemsCountEither)
txHistoryItemsCountEither.onRight {
uiState = stateFactory.getLoadedTxHistoryState(
txHistoryEither = txHistoryItemsUseCase(
networkId = Network.ID(blockchain.id),
derivationPath = derivationPath,
network,
).map {
it.cachedIn(viewModelScope)
},
@ -615,8 +605,7 @@ internal class WalletViewModel @Inject constructor(
}
}
// It also update wallet balance
private fun updateMarketPrice(userWalletId: UserWalletId) {
private fun updatePrimaryCurrencyStatus(userWalletId: UserWalletId) {
getPrimaryCurrencyStatusUpdatesUseCase(userWalletId = userWalletId)
.distinctUntilChanged()
.onEach { maybeCryptoCurrencyStatus ->
@ -625,6 +614,7 @@ internal class WalletViewModel @Inject constructor(
maybeCryptoCurrencyStatus.onRight { status ->
singleWalletCryptoCurrencyStatus = status
updateButtons(userWalletId = userWalletId, currency = status.currency)
updateTxHistory(status.currency.network)
}
}
.flowOn(dispatchers.io)