Updated on 2026-08-14

This commit is contained in:
Tangem 2022-05-20 17:58:04 +03:00
parent d17e5a3cf9
commit d9e745fbc6
10 changed files with 110 additions and 67 deletions

View file

@ -0,0 +1,20 @@
package com.tangem.tap.features.wallet.models
sealed class WalletWarning(
val showingPosition: Int,
) {
object TransactionInProgress : WalletWarning(10)
object SolanaTokensUnsupported : WalletWarning(20)
data class BalanceNotEnoughForFee(val blockchainFullName: String) : WalletWarning(30)
data class Rent(val walletRent: WalletRent) : WalletWarning(40)
}
data class WalletWarningDescription(
val title: String,
val message: String,
)
data class WalletRent(
val minRentValue: String,
val rentExemptValue: String,
)

View file

@ -5,6 +5,7 @@ import com.tangem.blockchain.common.*
import com.tangem.blockchain.common.address.AddressType
import com.tangem.blockchain.extensions.isAboveZero
import com.tangem.common.extensions.isZero
import com.tangem.domain.common.extensions.canHandleToken
import com.tangem.domain.common.extensions.toCoinId
import com.tangem.domain.features.addCustomToken.CustomCurrency
import com.tangem.tap.common.entities.Button
@ -19,10 +20,7 @@ import com.tangem.tap.domain.extensions.toSendableAmounts
import com.tangem.tap.domain.tokens.BlockchainNetwork
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState
import com.tangem.tap.features.tokens.redux.TokenWithBlockchain
import com.tangem.tap.features.wallet.models.PendingTransaction
import com.tangem.tap.features.wallet.models.TotalBalance
import com.tangem.tap.features.wallet.models.toPendingTransactions
import com.tangem.tap.features.wallet.models.toPendingTransactionsForToken
import com.tangem.tap.features.wallet.models.*
import com.tangem.tap.features.wallet.ui.BalanceStatus
import com.tangem.tap.features.wallet.ui.BalanceWidgetData
import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager
@ -364,24 +362,37 @@ data class WalletData(
return listOfAddresses.size > 1
}
fun shouldShowCoinAmountWarning(): Boolean = when (currency) {
is Currency.Blockchain -> false
is Currency.Token -> blockchainAmountIsEmpty() && !tokenAmountIsEmpty()
}
fun shouldEnableTokenSendButton(): Boolean = !blockchainAmountIsEmpty() || !tokenAmountIsEmpty()
private fun blockchainAmountIsEmpty(): Boolean =
currencyData.blockchainAmount?.isZero() ?: false
fun assembleWarnings(): List<WalletWarning> {
val blockchain = currency.blockchain
val walletWarnings = mutableListOf<WalletWarning>()
if (currencyData.status == BalanceStatus.SameCurrencyTransactionInProgress) {
walletWarnings.add(WalletWarning.TransactionInProgress)
}
if (currency.isBlockchain()) {
if (blockchain == Blockchain.Solana || blockchain == Blockchain.SolanaTestnet) {
val card = store.state.globalState.scanResponse?.card
if (card?.canHandleToken(blockchain) == false) {
walletWarnings.add(WalletWarning.SolanaTokensUnsupported)
}
}
}
if (walletRent != null) {
walletWarnings.add(WalletWarning.Rent(walletRent))
}
if (!currency.isBlockchain() && (blockchainAmountIsEmpty() && !tokenAmountIsEmpty())) {
val fullName = currency.blockchain.fullName
walletWarnings.add(WalletWarning.BalanceNotEnoughForFee(fullName))
}
return walletWarnings.sortedBy { it.showingPosition }
}
private fun blockchainAmountIsEmpty(): Boolean = currencyData.blockchainAmount?.isZero() ?: false
private fun tokenAmountIsEmpty(): Boolean = currencyData.amount?.isZero() == true
}
data class WalletRent(
val minRentValue: String,
val rentExemptValue: String
)
sealed interface Currency {
val coinId: String?

View file

@ -25,7 +25,6 @@ import com.tangem.tap.features.wallet.models.PendingTransaction
import com.tangem.tap.features.wallet.redux.*
import com.tangem.tap.features.wallet.ui.adapters.PendingTransactionsAdapter
import com.tangem.tap.features.wallet.ui.adapters.WalletDetailWarningMessagesAdapter
import com.tangem.tap.features.wallet.ui.adapters.WalletDetailsWarning
import com.tangem.tap.features.wallet.ui.dialogs.AmountToSendDialog
import com.tangem.tap.features.wallet.ui.test.TestWalletDetails
import com.tangem.tap.store
@ -173,35 +172,11 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details),
}
private fun handleWarnings(selectedWallet: WalletData) = with(binding) {
val walletWarnings = mutableListOf<WalletDetailsWarning>()
if (selectedWallet.currencyData.status == BalanceStatus.SameCurrencyTransactionInProgress) {
val txInProgress = WalletDetailsWarning(
title = R.string.common_warning,
message = R.string.wallet_pending_transaction_warning,
)
walletWarnings.add(0, txInProgress)
}
if (selectedWallet.walletRent != null) {
val rent = selectedWallet.walletRent
val rentWarning = WalletDetailsWarning(
title = R.string.common_warning,
message = R.string.solana_rent_warning,
messageArgs = listOf(rent.minRentValue, rent.rentExemptValue)
)
walletWarnings.add(rentWarning)
}
if (!selectedWallet.currency.isBlockchain() && selectedWallet.shouldShowCoinAmountWarning()) {
val blockchainName = selectedWallet.currency.blockchain.fullName
val notEnoughBalanceForFee = WalletDetailsWarning(
title = R.string.common_warning,
message = R.string.token_details_send_blocked_fee_format,
messageArgs = listOf(blockchainName, blockchainName)
)
walletWarnings.add(notEnoughBalanceForFee)
}
val converter = WalletWarningConverter(requireContext())
val warningDetails = selectedWallet.assembleWarnings().map { converter.convert(it) }
warningMessagesAdapter.submitList(walletWarnings)
rvWarningMessages.show(walletWarnings.isNotEmpty())
warningMessagesAdapter.submitList(warningDetails)
rvWarningMessages.show(warningDetails.isNotEmpty())
}
private fun handleCurrencyIcon(wallet: WalletData) = with(binding.lWalletDetails.lBalance) {

View file

@ -0,0 +1,39 @@
package com.tangem.tap.features.wallet.ui
import android.content.Context
import com.tangem.common.module.ModuleMessageConverter
import com.tangem.tap.features.wallet.models.WalletWarning
import com.tangem.tap.features.wallet.models.WalletWarningDescription
import com.tangem.wallet.R
/**
[REDACTED_AUTHOR]
*/
class WalletWarningConverter(
private val context: Context,
) : ModuleMessageConverter<WalletWarning, WalletWarningDescription> {
override fun convert(message: WalletWarning): WalletWarningDescription {
val warningMessage = when (message) {
is WalletWarning.BalanceNotEnoughForFee -> {
context.getString(
R.string.token_details_send_blocked_fee_format,
message.blockchainFullName, message.blockchainFullName
)
}
WalletWarning.SolanaTokensUnsupported -> {
context.getString(R.string.warning_token_send_unsupported_message)
}
WalletWarning.TransactionInProgress -> {
context.getString(R.string.wallet_pending_transaction_warning)
}
is WalletWarning.Rent -> {
context.getString(
R.string.solana_rent_warning,
message.walletRent.minRentValue, message.walletRent.rentExemptValue
)
}
}
return WalletWarningDescription(context.getString(R.string.common_warning), warningMessage)
}
}

View file

@ -6,7 +6,7 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.tangem.tap.common.extensions.getColor
import com.tangem.tap.common.extensions.getString
import com.tangem.tap.features.wallet.models.WalletWarningDescription
import com.tangem.wallet.R
import com.tangem.wallet.databinding.LayoutWarningCardBinding
@ -14,7 +14,7 @@ import com.tangem.wallet.databinding.LayoutWarningCardBinding
[REDACTED_AUTHOR]
*/
class WalletDetailWarningMessagesAdapter
: ListAdapter<WalletDetailsWarning, WalletDetailsWarningMessageVH>(DiffUtilCallback()) {
: ListAdapter<WalletWarningDescription, WalletDetailsWarningMessageVH>(DiffUtilCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WalletDetailsWarningMessageVH {
val inflater = LayoutInflater.from(parent.context)
@ -27,11 +27,11 @@ class WalletDetailWarningMessagesAdapter
holder.bind(currentList[position])
}
private class DiffUtilCallback : DiffUtil.ItemCallback<WalletDetailsWarning>() {
override fun areContentsTheSame(oldItem: WalletDetailsWarning, newItem: WalletDetailsWarning) =
private class DiffUtilCallback : DiffUtil.ItemCallback<WalletWarningDescription>() {
override fun areContentsTheSame(oldItem: WalletWarningDescription, newItem: WalletWarningDescription) =
oldItem == newItem
override fun areItemsTheSame(oldItem: WalletDetailsWarning, newItem: WalletDetailsWarning) =
override fun areItemsTheSame(oldItem: WalletWarningDescription, newItem: WalletWarningDescription) =
oldItem == newItem
}
}
@ -40,25 +40,13 @@ class WalletDetailsWarningMessageVH(
val binding: LayoutWarningCardBinding
) : RecyclerView.ViewHolder(binding.root) {
fun bind(warning: WalletDetailsWarning) {
fun bind(warning: WalletWarningDescription) {
binding.warningCard.setCardBackgroundColor(binding.root.getColor(R.color.darkGray2))
setText(warning)
}
private fun setText(warning: WalletDetailsWarning) = with(binding.warningContentContainer) {
fun getString(
stringResId: Int,
formatArgs: List<String> = emptyList()
) = root.getString(stringResId, *formatArgs.toTypedArray())
tvTitle.text = getString(warning.title)
tvMessage.text = getString(warning.message, warning.messageArgs)
private fun setText(warning: WalletWarningDescription) = with(binding.warningContentContainer) {
tvTitle.text = warning.title
tvMessage.text = warning.message
}
}
data class WalletDetailsWarning(
val title: Int,
val message: Int,
val titleArgs: List<String> = emptyList(),
val messageArgs: List<String> = emptyList(),
)
}

View file

@ -39,6 +39,8 @@
<string name="currency_subtitle_expanded">Available networks</string>
<string name="alert_manage_tokens_addresses_message">Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds.</string>
<string name="alert_manage_tokens_unsupported_message">Tokens in Solana network are not supported by this card due to firmware limitation.</string>
<string name="warning_token_send_unsupported_message">Do not transfer your funds to tokens in this blockchain, otherwise it may lead to their irretrievable loss.</string>
<string name="contract_address_copied_message">Contract address copied!</string>
<string name="alert_funds_restoration_message">If you chose the wrong network during your crypto transfer from the exchange, this guide will help you recover your funds</string>

View file

@ -39,6 +39,8 @@
<string name="currency_subtitle_expanded">Available networks</string>
<string name="alert_manage_tokens_addresses_message">Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds.</string>
<string name="alert_manage_tokens_unsupported_message">Tokens in Solana network are not supported by this card due to firmware limitation.</string>
<string name="warning_token_send_unsupported_message">Do not transfer your funds to tokens in this blockchain, otherwise it may lead to their irretrievable loss.</string>
<string name="contract_address_copied_message">Contract address copied!</string>
<string name="alert_funds_restoration_message">If you chose the wrong network during your crypto transfer from the exchange, this guide will help you recover your funds</string>

View file

@ -39,6 +39,8 @@
<string name="currency_subtitle_expanded">Available networks</string>
<string name="alert_manage_tokens_addresses_message">Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds.</string>
<string name="alert_manage_tokens_unsupported_message">Tokens in Solana network are not supported by this card due to firmware limitation.</string>
<string name="warning_token_send_unsupported_message">Do not transfer your funds to tokens in this blockchain, otherwise it may lead to their irretrievable loss.</string>
<string name="contract_address_copied_message">Contract address copied!</string>
<string name="alert_funds_restoration_message">If you chose the wrong network during your crypto transfer from the exchange, this guide will help you recover your funds</string>

View file

@ -39,6 +39,8 @@
<string name="currency_subtitle_expanded">Доступные сети</string>
<string name="alert_manage_tokens_addresses_message">Внимание! Валюты на разных сетях имеют разные адреса. Убедитесь, что адрес соответствует сети, в которой вы отправляете средства.</string>
<string name="alert_manage_tokens_unsupported_message">Токены в сети Solana не поддерживаются этой картой из-за ограничений прошивки.</string>
<string name="warning_token_send_unsupported_message">Не осуществляйте перевод на токены в данной сети иначе это может привести к их безвозвратной утере.</string>
<string name="contract_address_copied_message">Адрес контракта скопирован!</string>
<string name="alert_funds_restoration_message">Если вы совершили ошибку с выбором сети при переводе средств с биржи, эта инструкция поможет вам восстановить средства</string>

View file

@ -39,6 +39,8 @@
<string name="currency_subtitle_expanded">Available networks</string>
<string name="alert_manage_tokens_addresses_message">Note that tokens on different networks have different addresses. Double check that your address matches the network when you transfer funds.</string>
<string name="alert_manage_tokens_unsupported_message">Tokens in Solana network are not supported by this card due to firmware limitation.</string>
<string name="warning_token_send_unsupported_message">Do not transfer your funds to tokens in this blockchain, otherwise it may lead to their irretrievable loss.</string>
<string name="contract_address_copied_message">Contract address copied!</string>
<string name="alert_funds_restoration_message">If you chose the wrong network during your crypto transfer from the exchange, this guide will help you recover your funds</string>