Updated on 2026-08-14

This commit is contained in:
Tangem 2021-11-12 13:52:31 +03:00
parent 3894f5d029
commit 1b0f395ea9
10 changed files with 142 additions and 43 deletions

View file

@ -0,0 +1,69 @@
package com.tangem.tap.features.tokens.redux
import androidx.annotation.StringRes
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.wallet.R
sealed class CurrencyListItem {
data class TokenListItem(val token: Token) : CurrencyListItem()
data class BlockchainListItem(val blockchain: Blockchain) : CurrencyListItem()
data class TitleListItem(
@StringRes val titleResId: Int,
val isContentShown: Boolean = true,
val blockchain: Blockchain? = null,
) : CurrencyListItem()
companion object {
fun createListOfCurrencies(
blockchains: List<Blockchain>,
tokens: List<Token>,
): List<CurrencyListItem> {
val blockchainsTitle = R.string.add_tokens_subtitle_blockchains
val ethereumTokensTitle = R.string.add_tokens_subtitle_ethereum_tokens
val bscTokensTitle = R.string.add_tokens_subtitle_bsc_tokens
val binanceTokensTitle = R.string.add_tokens_subtitle_binance_tokens
val ethereumTokens = tokens.filter { it.blockchain == Blockchain.Ethereum }
val bscTokens = tokens.filter { it.blockchain == Blockchain.BSC }
val binanceTokens = tokens.filter { it.blockchain == Blockchain.Binance }
return listOf(TitleListItem(blockchainsTitle)) +
blockchains.map { BlockchainListItem(it) } +
listOf(TitleListItem(ethereumTokensTitle, blockchain = Blockchain.Ethereum)) +
ethereumTokens.map { TokenListItem(it) } +
listOf(TitleListItem(bscTokensTitle, blockchain = Blockchain.BSC)) +
bscTokens.map { TokenListItem(it) } +
listOf(TitleListItem(binanceTokensTitle, blockchain = Blockchain.Binance)) +
binanceTokens.map { TokenListItem(it) }
}
}
}
fun List<CurrencyListItem>.removeTokensForBlockchain(blockchain: Blockchain): List<CurrencyListItem> {
return filterNot {
it is CurrencyListItem.TokenListItem && it.token.blockchain == blockchain
}
}
fun List<CurrencyListItem>.addTokensForBlockchain(
blockchain: Blockchain, fullCurrenciesList: List<CurrencyListItem>,
): List<CurrencyListItem> {
val tokensToAdd = fullCurrenciesList.filter {
it is CurrencyListItem.TokenListItem && it.token.blockchain == blockchain
}
val indexToInsert = indexOfFirst {
it is CurrencyListItem.TitleListItem && it.blockchain == blockchain
} + 1
return this.toMutableList().apply { addAll(indexToInsert, tokensToAdd) }
}
fun List<CurrencyListItem>.toggleHeaderContentShownValue(
blockchain: Blockchain
): List<CurrencyListItem> {
val indexOfTitle = indexOfFirst {
it is CurrencyListItem.TitleListItem && it.blockchain == blockchain
}
val title = this[indexOfTitle] as CurrencyListItem.TitleListItem
val updatedTitle = title.copy(isContentShown = !title.isContentShown)
return this.toMutableList().apply { set(indexOfTitle, updatedTitle) }
}

View file

@ -1,7 +1,7 @@
package com.tangem.tap.features.tokens.redux
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.tap.features.tokens.ui.adapters.CurrencyListItem
import com.tangem.tap.features.wallet.redux.WalletData
import org.rekotlin.Action
@ -17,5 +17,6 @@ sealed class TokensAction : Action {
data class SetAddedCurrencies(val wallets: List<WalletData>) : TokensAction()
data class ToggleShowTokensForBlockchain(val isShown: Boolean, val blockchain: Blockchain) : TokensAction()
}

View file

@ -3,7 +3,6 @@ package com.tangem.tap.features.tokens.redux
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.currenciesRepository
import com.tangem.tap.domain.TapWorkarounds.isTestCard
import com.tangem.tap.features.tokens.ui.adapters.CurrencyListItem
import com.tangem.tap.store
import org.rekotlin.Middleware

View file

@ -18,7 +18,7 @@ private fun internalReduce(action: Action, state: AppState): TokensState {
val tokensState = state.tokensState
return when (action) {
is TokensAction.LoadCurrencies.Success -> {
tokensState.copy(currencies = action.currencies)
tokensState.copy(currencies = action.currencies, shownCurrencies = action.currencies)
}
is TokensAction.SetAddedCurrencies -> {
tokensState.copy(addedCurrencies = action.wallets.toCardCurrencies())
@ -28,6 +28,20 @@ private fun internalReduce(action: Action, state: AppState): TokensState {
action.tokens.map { TokenWithAmount(it, null) }
))
}
is TokensAction.ToggleShowTokensForBlockchain -> {
if (action.isShown) {
val shownCurrencies = tokensState.shownCurrencies
.removeTokensForBlockchain(action.blockchain)
.toggleHeaderContentShownValue(action.blockchain)
tokensState.copy(shownCurrencies = shownCurrencies)
} else {
val shownCurrencies = tokensState.shownCurrencies
.addTokensForBlockchain(action.blockchain, tokensState.currencies)
.toggleHeaderContentShownValue(action.blockchain)
tokensState.copy(shownCurrencies = shownCurrencies)
}
}
else -> tokensState
}
}

View file

@ -2,15 +2,14 @@ package com.tangem.tap.features.tokens.redux
import com.tangem.blockchain.common.Amount
import com.tangem.blockchain.common.Token
import com.tangem.tap.common.redux.global.CryptoCurrencyName
import com.tangem.tap.domain.tokens.CardCurrencies
import com.tangem.tap.features.tokens.ui.adapters.CurrencyListItem
import org.rekotlin.StateType
data class TokensState(
val addedTokens: LinkedHashSet<TokenWithAmount> = LinkedHashSet(),
val addedCurrencies: CardCurrencies? = null,
val currencies: List<CurrencyListItem> = emptyList(),
val shownCurrencies: List<CurrencyListItem> = emptyList(),
) : StateType
data class TokenWithAmount(

View file

@ -73,7 +73,7 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
override fun newState(state: TokensState) {
if (activity == null) return
viewAdapter.addedCurrencies = state.addedCurrencies
viewAdapter.submitUnfilteredList(state.currencies)
viewAdapter.submitUnfilteredList(state.shownCurrencies)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {

View file

@ -3,18 +3,17 @@ package com.tangem.tap.features.tokens.ui.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.StringRes
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.squareup.picasso.Picasso
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Token
import com.tangem.tap.common.extensions.getString
import com.tangem.tap.common.extensions.hide
import com.tangem.tap.common.extensions.loadCurrenciesIcon
import com.tangem.tap.common.extensions.show
import com.tangem.tap.domain.tokens.CardCurrencies
import com.tangem.tap.features.tokens.redux.CurrencyListItem
import com.tangem.tap.features.tokens.redux.TokensAction
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.store
import com.tangem.wallet.R
@ -68,11 +67,11 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
object DiffUtilCallback : DiffUtil.ItemCallback<CurrencyListItem>() {
override fun areContentsTheSame(
oldItem: CurrencyListItem, newItem: CurrencyListItem
oldItem: CurrencyListItem, newItem: CurrencyListItem,
) = oldItem == newItem
override fun areItemsTheSame(
oldItem: CurrencyListItem, newItem: CurrencyListItem
oldItem: CurrencyListItem, newItem: CurrencyListItem,
) = oldItem == newItem
}
@ -161,38 +160,24 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
class TitleViewHolder(val view: View) :
RecyclerView.ViewHolder(view) {
fun bind(title: CurrencyListItem.TitleListItem) {
view.tv_subtitle.text = view.getString(title.titleResId).toUpperCase(Locale.US)
}
}
}
sealed class CurrencyListItem {
data class TokenListItem(val token: Token) : CurrencyListItem()
data class BlockchainListItem(val blockchain: Blockchain) : CurrencyListItem()
data class TitleListItem(@StringRes val titleResId: Int) : CurrencyListItem()
companion object {
fun createListOfCurrencies(
blockchains: List<Blockchain>,
tokens: List<Token>
): List<CurrencyListItem> {
val blockchainsTitle = R.string.add_tokens_subtitle_blockchains
val ethereumTokensTitle = R.string.add_tokens_subtitle_ethereum_tokens
val bscTokensTitle = R.string.add_tokens_subtitle_bsc_tokens
val binanceTokensTitle = R.string.add_tokens_subtitle_binance_tokens
val ethereumTokens = tokens.filter { it.blockchain == Blockchain.Ethereum }
val bscTokens = tokens.filter { it.blockchain == Blockchain.BSC }
val binanceTokens = tokens.filter { it.blockchain == Blockchain.Binance }
return listOf(TitleListItem(blockchainsTitle)) +
blockchains.map { BlockchainListItem(it) } +
listOf(TitleListItem(ethereumTokensTitle)) +
ethereumTokens.map { TokenListItem(it) } +
listOf(TitleListItem(bscTokensTitle)) +
bscTokens.map { TokenListItem(it) } +
listOf(TitleListItem(binanceTokensTitle)) +
binanceTokens.map { TokenListItem(it) }
view.tv_subtitle.text = view.getString(title.titleResId).uppercase()
if (title.blockchain != null) {
view.cl_subtitle_container.setOnClickListener {
store.dispatch(TokensAction.ToggleShowTokensForBlockchain(
title.isContentShown, title.blockchain
))
}
view.iv_toggle_sublist_visibility.show()
val imageRes = if (title.isContentShown) {
R.drawable.ic_arrow_angle_down
} else {
R.drawable.ic_arrow_angle_right
}
view.iv_toggle_sublist_visibility.setImageResource(imageRes)
} else {
view.iv_toggle_sublist_visibility.hide()
}
}
}
}

View file

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#1C1C1E" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M7.41,8.59L12,13.17l4.59,-4.58L18,10l-6,6 -6,-6 1.41,-1.41z"/>
</vector>

View file

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:tint="#1C1C1E"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M8.59,16.59L13.17,12 8.59,7.41 10,6l6,6 -6,6 -1.41,-1.41z" />
</vector>

View file

@ -2,6 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cl_subtitle_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
@ -20,4 +21,19 @@
app:layout_constraintTop_toTopOf="parent"
tools:text="BLOCKCHAINS" />
<ImageView
android:id="@+id/iv_toggle_sublist_visibility"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textAllCaps="true"
android:textColor="@color/darkGray1"
android:textSize="13sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_subtitle"
app:layout_constraintBottom_toBottomOf="@id/tv_subtitle"
tools:src="@drawable/ic_arrow_angle_right" />
</androidx.constraintlayout.widget.ConstraintLayout>