Updated on 2026-08-14

This commit is contained in:
Tangem 2021-12-08 15:08:04 +03:00
parent f80e12e9ca
commit a6a59e0863
6 changed files with 97 additions and 64 deletions

View file

@ -21,9 +21,5 @@ sealed class TokensAction : Action {
data class ToggleShowTokensForBlockchain(val isShown: Boolean, val blockchain: Blockchain) : TokensAction()
sealed class TokensList : TokensAction() {
data class AddBlockchain(val blockchain: Blockchain) : TokensList()
data class AddToken(val token: Token) : TokensList()
object SaveChanges : TokensList()
}
data class SaveChanges(val addedItems: List<CurrencyListItem>) : TokensAction()
}

View file

@ -29,7 +29,7 @@ class TokensMiddleware {
{ action ->
when (action) {
is TokensAction.LoadCurrencies -> handleLoadCurrencies(action)
is TokensAction.TokensList.SaveChanges -> handleSaveChanges(action)
is TokensAction.SaveChanges -> handleSaveChanges(action)
}
next(action)
}
@ -69,10 +69,10 @@ class TokensMiddleware {
store.dispatch(TokensAction.LoadCurrencies.Success(currencies))
}
private fun handleSaveChanges(action: TokensAction.TokensList.SaveChanges) {
private fun handleSaveChanges(action: TokensAction.SaveChanges) {
val scanResponse = store.state.globalState.scanResponse ?: return
val candidatesToAdd = store.state.tokensState.candidateToAdd
val candidatesToAdd = action.addedItems
if (candidatesToAdd.isEmpty()) return
val blockchains = candidatesToAdd.filterIsInstance<CurrencyListItem.BlockchainListItem>()

View file

@ -43,16 +43,6 @@ private fun internalReduce(action: Action, state: AppState): TokensState {
tokensState.copy(shownCurrencies = shownCurrencies)
}
}
is TokensAction.TokensList.AddBlockchain -> {
val candidates = tokensState.candidateToAdd.toMutableSet()
candidates.add(CurrencyListItem.BlockchainListItem(action.blockchain))
tokensState.copy(candidateToAdd = candidates.toList())
}
is TokensAction.TokensList.AddToken -> {
val candidates = tokensState.candidateToAdd.toMutableSet()
candidates.add(CurrencyListItem.TokenListItem(action.token))
tokensState.copy(candidateToAdd = candidates.toList())
}
else -> tokensState
}
}

View file

@ -10,7 +10,6 @@ data class TokensState(
val addedCurrencies: CardCurrencies? = null,
val currencies: List<CurrencyListItem> = emptyList(),
val shownCurrencies: List<CurrencyListItem> = emptyList(),
val candidateToAdd: List<CurrencyListItem> = emptyList(),
) : StateType
data class TokenWithAmount(

View file

@ -61,12 +61,18 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
(activity as? AppCompatActivity)?.setSupportActionBar(toolbar)
toolbar.setNavigationOnClickListener { activity?.onBackPressed() }
btn_tokens_save_changes.setOnClickListener { store.dispatch(TokensAction.TokensList.SaveChanges)}
setupPopularTokensRecyclerView()
btn_tokens_save_changes.setOnClickListener {
store.dispatch(TokensAction.SaveChanges(viewAdapter.getAddedItems()))
}
}
private fun setupPopularTokensRecyclerView() {
viewAdapter = CurrenciesAdapter()
viewAdapter.setOnItemAddListener {
btn_tokens_save_changes.isEnabled = viewAdapter.getAddedItems().isNotEmpty()
}
rv_popular_tokens.layoutManager = LinearLayoutManager(context)
rv_popular_tokens.adapter = viewAdapter
}
@ -74,8 +80,6 @@ class AddTokensFragment : Fragment(R.layout.fragment_add_tokens),
override fun newState(state: TokensState) {
if (activity == null) return
btn_tokens_save_changes.isEnabled = state.candidateToAdd.isNotEmpty()
viewAdapter.addedCurrencies = state.addedCurrencies
viewAdapter.submitUnfilteredList(state.shownCurrencies)
}

View file

@ -7,6 +7,9 @@ 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.common.extensions.VoidCallback
import com.tangem.tap.common.extensions.getString
import com.tangem.tap.common.extensions.hide
import com.tangem.tap.common.extensions.loadCurrenciesIcon
@ -26,11 +29,28 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
private var unfilteredList = listOf<CurrencyListItem>()
private val currentlyAddedItems = mutableListOf<CurrencyListItem>()
private var vhOnItemAddListener: ((CurrencyListItem) -> Unit) = {
currentlyAddedItems.add(it)
onItemAddListener?.invoke()
}
private var onItemAddListener: VoidCallback? = null
fun submitUnfilteredList(list: List<CurrencyListItem>) {
unfilteredList = list
submitList(list)
}
fun setOnItemAddListener(itemAddListener: VoidCallback) {
onItemAddListener = itemAddListener
if (currentlyAddedItems.isNotEmpty()) itemAddListener()
}
fun getAddedItems(): List<CurrencyListItem> {
return currentlyAddedItems.toList()
}
override fun getItemViewType(position: Int): Int {
return when (currentList[position]) {
is CurrencyListItem.TitleListItem -> 0
@ -46,11 +66,13 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
)
1 -> CurrenciesViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_popular_token, parent, false)
.inflate(R.layout.item_popular_token, parent, false),
vhOnItemAddListener
)
else -> CurrenciesViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_popular_token, parent, false)
.inflate(R.layout.item_popular_token, parent, false),
vhOnItemAddListener
)
}
}
@ -60,7 +82,7 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
if (holder is TitleViewHolder && listItem is CurrencyListItem.TitleListItem) {
holder.bind(listItem)
} else if (holder is CurrenciesViewHolder) {
holder.bind(listItem, addedCurrencies)
holder.bind(listItem, addedCurrencies, currentlyAddedItems)
}
}
@ -104,56 +126,78 @@ class CurrenciesAdapter : ListAdapter<CurrencyListItem, RecyclerView.ViewHolder>
submitList(list)
}
class CurrenciesViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
class CurrenciesViewHolder(
private val view: View,
private val onItemAddListener: ((CurrencyListItem) -> Unit),
) : RecyclerView.ViewHolder(view) {
fun bind(currency: CurrencyListItem, addedCurrencies: CardCurrencies?) {
fun bind(
currency: CurrencyListItem,
addedCurrencies: CardCurrencies?,
currentlyAddedItems: MutableList<CurrencyListItem>
) {
when (currency) {
is CurrencyListItem.BlockchainListItem -> {
val blockchain = currency.blockchain
view.tv_currency_name.text = blockchain.fullName
view.tv_currency_symbol.text = blockchain.currency
currency.isAdded = addedCurrencies?.blockchains?.contains(blockchain) == true
modifyAddTokenButton(currency)
Picasso.get().loadCurrenciesIcon(
imageView = view.iv_currency,
textView = view.tv_token_letter,
blockchain = blockchain, token = null
)
view.btn_add_token.setOnClickListener {
store.dispatch(TokensAction.TokensList.AddBlockchain(blockchain))
currency.isAdded = !currency.isAdded
modifyAddTokenButton(currency)
}
val addedBlockchains = addedCurrencies?.blockchains ?: listOf()
val currentlyAdded = currentlyAddedItems.filterIsInstance<CurrencyListItem.BlockchainListItem>()
bindBlockchain(currency, addedBlockchains, currentlyAdded)
}
is CurrencyListItem.TokenListItem -> {
val token = currency.token
view.tv_currency_name.text = token.name
view.tv_currency_symbol.text = token.symbol
currency.isAdded = addedCurrencies?.tokens
?.any {
it.symbol == token.symbol && it.contractAddress == token.contractAddress
} == true
modifyAddTokenButton(currency)
Picasso.get().loadCurrenciesIcon(
imageView = view.iv_currency,
textView = view.tv_token_letter,
token = token, blockchain = token.blockchain
)
view.btn_add_token.setOnClickListener {
store.dispatch(TokensAction.TokensList.AddToken(token))
currency.isAdded = !currency.isAdded
modifyAddTokenButton(currency)
}
val addedTokens = addedCurrencies?.tokens ?: listOf()
val currentlyAdded = currentlyAddedItems.filterIsInstance<CurrencyListItem.TokenListItem>()
bindToken(currency, addedTokens, currentlyAdded)
}
}
}
private fun bindBlockchain(
currency: CurrencyListItem.BlockchainListItem,
addedBlockchains: List<Blockchain>,
currentlyAdded: List<CurrencyListItem.BlockchainListItem>
) {
val blockchain = currency.blockchain
Picasso.get().loadCurrenciesIcon(view.iv_currency, view.tv_token_letter, null, blockchain)
view.tv_currency_name.text = blockchain.fullName
view.tv_currency_symbol.text = blockchain.currency
view.btn_add_token.setOnClickListener {
onItemAddListener.invoke(currency)
currency.isAdded = true
modifyAddTokenButton(currency)
}
val isAddedBefore = addedBlockchains.contains(blockchain)
val isCurrentlyAdded = currentlyAdded.any { it.blockchain == blockchain }
currency.isAdded = isAddedBefore || isCurrentlyAdded
modifyAddTokenButton(currency)
}
private fun bindToken(
currency: CurrencyListItem.TokenListItem,
addedTokens: List<Token>,
currentlyAdded: List<CurrencyListItem.TokenListItem>
) {
val token = currency.token
Picasso.get().loadCurrenciesIcon(view.iv_currency, view.tv_token_letter, token, token.blockchain)
view.tv_currency_name.text = token.name
view.tv_currency_symbol.text = token.symbol
view.btn_add_token.setOnClickListener {
onItemAddListener.invoke(currency)
currency.isAdded = true
modifyAddTokenButton(currency)
}
val isAddedBefore = addedTokens.any { it == token }
val isCurrentlyAdded = currentlyAdded.any { it.token == token }
currency.isAdded = isAddedBefore || isCurrentlyAdded
modifyAddTokenButton(currency)
}
private fun modifyAddTokenButton(currency: CurrencyListItem) {
if (currency.isLock) {
view.btn_add_token.setText(R.string.common_add)
view.btn_add_token.isEnabled = false
} else {
val text = if (currency.isAdded) R.string.add_token_added else R.string.common_add