Updated on 2026-08-14
This commit is contained in:
parent
3894f5d029
commit
1b0f395ea9
10 changed files with 142 additions and 43 deletions
|
|
@ -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) }
|
||||
}
|
||||
|
|
@ -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()
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
5
app/src/main/res/drawable/ic_arrow_angle_down.xml
Normal file
5
app/src/main/res/drawable/ic_arrow_angle_down.xml
Normal 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>
|
||||
11
app/src/main/res/drawable/ic_arrow_angle_right.xml
Normal file
11
app/src/main/res/drawable/ic_arrow_angle_right.xml
Normal 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>
|
||||
|
|
@ -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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue