Updated on 2026-08-14
This commit is contained in:
commit
e1ea317688
18 changed files with 170 additions and 112 deletions
|
|
@ -5,19 +5,23 @@ import androidx.annotation.ColorInt
|
|||
import androidx.core.graphics.luminance
|
||||
import androidx.core.graphics.toColorInt
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.wallet.R
|
||||
|
||||
@ColorInt
|
||||
fun Token.getColor(): Int {
|
||||
return try {
|
||||
("#" + this.contractAddress.subSequence(2..7).toString())
|
||||
.toColorInt()
|
||||
fun Token.getColor(isTestnet: Boolean = false): Int {
|
||||
val defaultColor = "#C7C7CC".toColorInt() // equivalent to R.color.lightGray4
|
||||
|
||||
return if (isTestnet)
|
||||
defaultColor
|
||||
else try {
|
||||
("#" + this.contractAddress.subSequence(2..7).toString()).toColorInt()
|
||||
} catch (exception: Exception) {
|
||||
R.color.lightGray4
|
||||
defaultColor
|
||||
}
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun Token.getTextColor(): Int {
|
||||
return if (this.getColor().luminance > 0.5) Color.BLACK else Color.WHITE
|
||||
fun Token.getTextColor(isTestnet: Boolean = false): Int = when {
|
||||
isTestnet -> Color.WHITE
|
||||
this.getColor().luminance > 0.5 -> Color.BLACK
|
||||
else -> Color.WHITE
|
||||
}
|
||||
|
|
@ -113,15 +113,11 @@ sealed class FeeActionUi : SendScreenActionUi {
|
|||
}
|
||||
|
||||
sealed class FeeAction : SendScreenAction {
|
||||
enum class Error {
|
||||
ADDRESS_OR_AMOUNT_IS_EMPTY,
|
||||
REQUEST_FAILED
|
||||
}
|
||||
|
||||
object RequestFee : FeeAction()
|
||||
sealed class FeeCalculation : FeeAction() {
|
||||
data class SetFeeResult(val fee: List<Amount>) : FeeCalculation()
|
||||
data class SetFeeError(val error: Error) : FeeCalculation()
|
||||
object ClearResult : FeeCalculation()
|
||||
}
|
||||
|
||||
data class ChangeLayoutVisibility(
|
||||
|
|
@ -160,6 +156,12 @@ sealed class SendAction : SendScreenAction {
|
|||
data class CardSdkError(val error: TangemSdkError): Dialog()
|
||||
data class BlockchainSdkError(val error: com.tangem.blockchain.common.BlockchainSdkError): Dialog()
|
||||
}
|
||||
|
||||
data class RequestFeeError(
|
||||
val error: com.tangem.blockchain.common.BlockchainSdkError,
|
||||
val onRetry: () -> Unit,
|
||||
) : Dialog()
|
||||
|
||||
object Hide : Dialog()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.tap.features.send.redux.middlewares
|
|||
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.blockchain.common.TransactionSender
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.common.extensions.isZero
|
||||
|
|
@ -31,8 +32,7 @@ class RequestFeeMiddleware {
|
|||
val scanResponse = appState.globalState.scanResponse ?: return
|
||||
|
||||
if (!SendState.isReadyToRequestFee()) {
|
||||
dispatch(FeeAction.FeeCalculation.SetFeeError(FeeAction.Error.ADDRESS_OR_AMOUNT_IS_EMPTY))
|
||||
// dispatch(FeeAction.ChangeLayoutVisibility(main = false, chipGroup = true))
|
||||
dispatch(FeeAction.FeeCalculation.ClearResult)
|
||||
dispatch(ReceiptAction.RefreshReceipt)
|
||||
dispatch(SendAction.ChangeSendButtonState(sendState.getButtonState()))
|
||||
return
|
||||
|
|
@ -66,14 +66,21 @@ class RequestFeeMiddleware {
|
|||
}
|
||||
}
|
||||
is Result.Failure -> {
|
||||
dispatch(FeeAction.FeeCalculation.SetFeeError(FeeAction.Error.REQUEST_FAILED))
|
||||
dispatch(FeeAction.FeeCalculation.ClearResult)
|
||||
dispatch(FeeAction.ChangeLayoutVisibility(main = false))
|
||||
|
||||
val blockchainSdkError = feeResult.error as? BlockchainSdkError ?: return@withContext
|
||||
dispatch(
|
||||
SendAction.Dialog.RequestFeeError(
|
||||
error = blockchainSdkError,
|
||||
onRetry = { dispatch(FeeAction.RequestFee) },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
dispatch(AmountActionUi.CheckAmountToSend)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,13 +100,13 @@ class FeeMock {
|
|||
suspend fun feeStandard(blockchain: Blockchain): List<Amount> = listOf(
|
||||
Amount(0.001500.toBigDecimal(), blockchain),
|
||||
Amount(0.0030.toBigDecimal(), blockchain),
|
||||
Amount(0.0045001.toBigDecimal(), blockchain)
|
||||
Amount(0.0045001.toBigDecimal(), blockchain),
|
||||
)
|
||||
|
||||
suspend fun feeStandardBig(blockchain: Blockchain): List<Amount> = listOf(
|
||||
Amount(1.76.toBigDecimal(), blockchain),
|
||||
Amount(2.30.toBigDecimal(), blockchain),
|
||||
Amount(3.45.toBigDecimal(), blockchain)
|
||||
Amount(3.45.toBigDecimal(), blockchain),
|
||||
)
|
||||
|
||||
suspend fun feeSingle(blockchain: Blockchain): List<Amount> = listOf(Amount(0.0015.toBigDecimal(), blockchain))
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class FeeReducer : SendInternalReducer {
|
|||
private fun handleAction(action: FeeAction, sendState: SendState, state: FeeState): SendState {
|
||||
val result = when (action) {
|
||||
is FeeAction.RequestFee -> {
|
||||
state.copy(error = null)
|
||||
state
|
||||
}
|
||||
is FeeAction.ChangeLayoutVisibility -> {
|
||||
fun getVisibility(current: Boolean, proposed: Boolean?): Boolean = proposed ?: current
|
||||
|
|
@ -56,7 +56,6 @@ class FeeReducer : SendInternalReducer {
|
|||
selectedFeeType = feeType,
|
||||
feeList = fees,
|
||||
currentFee = currentFee,
|
||||
error = null,
|
||||
feeIsApproximate = isFeeApproximate(sendState),
|
||||
)
|
||||
} else {
|
||||
|
|
@ -67,16 +66,14 @@ class FeeReducer : SendInternalReducer {
|
|||
selectedFeeType = feeType,
|
||||
feeList = fees,
|
||||
currentFee = currentFee,
|
||||
error = null,
|
||||
feeIsApproximate = isFeeApproximate(sendState),
|
||||
)
|
||||
}
|
||||
}
|
||||
is FeeAction.FeeCalculation.SetFeeError -> {
|
||||
FeeAction.FeeCalculation.ClearResult -> {
|
||||
state.copy(
|
||||
feeList = null,
|
||||
currentFee = null,
|
||||
error = action.error,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,10 +59,10 @@ private class SendReducer : SendInternalReducer {
|
|||
is SendAction.Dialog.TezosWarningDialog -> sendState.copy(dialog = action)
|
||||
is SendAction.Dialog.SendTransactionFails.CardSdkError -> sendState.copy(dialog = action)
|
||||
is SendAction.Dialog.SendTransactionFails.BlockchainSdkError -> sendState.copy(dialog = action)
|
||||
is SendAction.Dialog.RequestFeeError -> sendState.copy(dialog = action)
|
||||
is SendAction.Dialog.Hide -> sendState.copy(dialog = null)
|
||||
is SendAction.Warnings.Set -> sendState.copy(sendWarningsList = action.warningList)
|
||||
is SendAction.SendSpecificTransaction ->
|
||||
handleSendSpecificTransactionAction(action, sendState)
|
||||
is SendAction.SendSpecificTransaction -> handleSendSpecificTransactionAction(action, sendState)
|
||||
else -> return sendState
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.tap.features.send.redux.states
|
||||
|
||||
import com.tangem.blockchain.common.Amount
|
||||
import com.tangem.tap.features.send.redux.FeeAction
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
|
|
@ -21,12 +20,11 @@ data class FeeState(
|
|||
val controlsLayoutIsVisible: Boolean = false,
|
||||
val feeChipGroupIsVisible: Boolean = true,
|
||||
val includeFeeSwitcherIsEnabled: Boolean = true,
|
||||
val error: FeeAction.Error? = null,
|
||||
) : SendScreenState {
|
||||
|
||||
override val stateId: StateId = StateId.FEE
|
||||
|
||||
fun isReady(): Boolean = error == null && currentFee != null
|
||||
fun isReady(): Boolean = currentFee != null
|
||||
|
||||
fun getCurrentFeeValue(): BigDecimal = currentFee?.value ?: BigDecimal.ZERO
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.tangem.tap.features.send.ui.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.tangem.tap.common.feedback.SendTransactionFailedEmail
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.send.redux.SendAction
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class RequestFeeErrorDialog {
|
||||
|
||||
companion object {
|
||||
fun create(context: Context, dialog: SendAction.Dialog.RequestFeeError): AlertDialog {
|
||||
val errorMessage = dialog.error.customMessage
|
||||
|
||||
return AlertDialog.Builder(context).apply {
|
||||
setTitle(R.string.send_error_fee_request_failed)
|
||||
setMessage(context.getString(R.string.alert_failed_to_send_transaction_message, errorMessage))
|
||||
setNegativeButton(R.string.alert_button_send_feedback) { _, _ ->
|
||||
store.dispatch(GlobalAction.SendEmail(SendTransactionFailedEmail(errorMessage)))
|
||||
}
|
||||
setPositiveButton(R.string.common_retry) { _, _ -> dialog.onRetry() }
|
||||
setNeutralButton(R.string.common_cancel) { _, _ -> }
|
||||
setOnDismissListener { store.dispatch(SendAction.Dialog.Hide) }
|
||||
}.create()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,6 @@ import com.tangem.tap.domain.MultiMessageError
|
|||
import com.tangem.tap.domain.assembleErrors
|
||||
import com.tangem.tap.features.BaseStoreFragment
|
||||
import com.tangem.tap.features.send.redux.AddressPayIdVerifyAction.Error
|
||||
import com.tangem.tap.features.send.redux.FeeAction
|
||||
import com.tangem.tap.features.send.redux.SendAction
|
||||
import com.tangem.tap.features.send.redux.states.AddressPayIdState
|
||||
import com.tangem.tap.features.send.redux.states.AmountState
|
||||
|
|
@ -35,12 +34,12 @@ import com.tangem.tap.features.send.redux.states.TransactionExtrasState
|
|||
import com.tangem.tap.features.send.redux.states.XlmMemoType
|
||||
import com.tangem.tap.features.send.ui.FeeUiHelper
|
||||
import com.tangem.tap.features.send.ui.SendFragment
|
||||
import com.tangem.tap.features.send.ui.dialogs.RequestFeeErrorDialog
|
||||
import com.tangem.tap.features.send.ui.dialogs.SendTransactionFailsDialog
|
||||
import com.tangem.tap.features.send.ui.dialogs.TezosWarningDialog
|
||||
import com.tangem.tap.features.wallet.redux.WalletState.Companion.ROUGH_SIGN
|
||||
import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN
|
||||
import com.tangem.tap.features.wallet.ui.adapters.WarningMessagesAdapter
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
||||
/**
|
||||
|
|
@ -62,10 +61,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
when (it) {
|
||||
StateId.SEND_SCREEN -> handleSendScreen(fg, state)
|
||||
StateId.ADDRESS_PAY_ID -> handleAddressPayIdState(fg, state.addressPayIdState)
|
||||
StateId.TRANSACTION_EXTRAS -> handleTransactionExtrasState(
|
||||
fg,
|
||||
state.transactionExtrasState
|
||||
)
|
||||
StateId.TRANSACTION_EXTRAS -> handleTransactionExtrasState(fg, state.transactionExtrasState)
|
||||
StateId.AMOUNT -> handleAmountState(fg, state.amountState)
|
||||
StateId.FEE -> handleFeeState(fg, state.feeState)
|
||||
StateId.RECEIPT -> handleReceiptState(fg, state.receiptState)
|
||||
|
|
@ -144,6 +140,12 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
dialog?.show()
|
||||
}
|
||||
}
|
||||
is SendAction.Dialog.RequestFeeError -> {
|
||||
if (dialog == null) {
|
||||
dialog = RequestFeeErrorDialog.create(fg.requireContext(), state.dialog)
|
||||
dialog?.show()
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
dialog?.dismiss()
|
||||
dialog = null
|
||||
|
|
@ -161,7 +163,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
|
||||
toolbar.title = fg.getString(
|
||||
R.string.send_title_currency_format,
|
||||
state.amountState.mainCurrency.currencySymbol
|
||||
state.amountState.mainCurrency.currencySymbol,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -233,11 +235,11 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
val balanceText = when (state.mainCurrency.type) {
|
||||
MainCurrencyType.FIAT -> fg.getString(
|
||||
R.string.send_balance_subtitle_format,
|
||||
state.viewBalanceValue, state.mainCurrency.currencySymbol
|
||||
state.viewBalanceValue, state.mainCurrency.currencySymbol,
|
||||
).remove(":")
|
||||
MainCurrencyType.CRYPTO -> fg.getString(
|
||||
R.string.send_balance_subtitle_format,
|
||||
state.mainCurrency.currencySymbol, state.viewBalanceValue
|
||||
state.mainCurrency.currencySymbol, state.viewBalanceValue,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -263,14 +265,6 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
swIncludeFee.isChecked = state.feeIsIncluded
|
||||
}
|
||||
|
||||
if (state.error == FeeAction.Error.REQUEST_FAILED) {
|
||||
fg.showRetrySnackbar(
|
||||
fg.requireContext().getString(R.string.send_error_fee_request_failed)
|
||||
) {
|
||||
store.dispatch(FeeAction.RequestFee)
|
||||
}
|
||||
}
|
||||
|
||||
val chipId = FeeUiHelper.toId(state.selectedFeeType)
|
||||
if (chipGroup.checkedChipId != chipId && chipId != View.NO_ID) chipGroup.check(chipId)
|
||||
}
|
||||
|
|
@ -299,7 +293,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
|
||||
val willSent = getString(
|
||||
R.string.send_total_subtitle_format,
|
||||
receipt.willSentCrypto, receipt.symbols.crypto
|
||||
receipt.willSentCrypto, receipt.symbols.crypto,
|
||||
)
|
||||
llTotalContainer.tvWillBeSentValue.update(willSent)
|
||||
|
||||
|
|
@ -334,7 +328,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
val willSent = getString(
|
||||
R.string.send_total_subtitle_asset_format,
|
||||
receipt.symbols.token ?: "", receipt.willSentToken,
|
||||
receipt.symbols.crypto, receipt.willSentFeeCoin
|
||||
receipt.symbols.crypto, receipt.willSentFeeCoin,
|
||||
)
|
||||
llTotalContainer.tvWillBeSentValue.update(willSent)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import com.tangem.tap.features.wallet.redux.WalletState
|
|||
import com.tangem.tap.features.wallet.redux.WalletState.Companion.UNKNOWN_AMOUNT_SIGN
|
||||
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.images.load
|
||||
import com.tangem.tap.features.wallet.ui.test.TestWalletDetails
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import com.tangem.tap.common.extensions.show
|
|||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletData
|
||||
import com.tangem.tap.features.wallet.ui.BalanceStatus
|
||||
import com.tangem.tap.features.wallet.ui.images.load
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import com.tangem.wallet.databinding.ItemCurrencyWalletBinding
|
||||
|
|
@ -62,7 +63,7 @@ class WalletAdapter
|
|||
fun bind(wallet: WalletData) = with(binding) {
|
||||
val status = wallet.currencyData.status
|
||||
// Skip changes when on refreshing status
|
||||
if (status == BalanceStatus.Refreshing || wallet.fiatRateString == null) return@with
|
||||
if (status == BalanceStatus.Refreshing) return@with
|
||||
|
||||
val statusMessage = when (status) {
|
||||
BalanceStatus.TransactionInProgress -> {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ private const val VOYR = "VOYRME"
|
|||
|
||||
class CurrencyIconRequest(
|
||||
private val currencyImageView: ImageFilterView,
|
||||
private val currencyTextView: TextView,
|
||||
private val currencyTextView: TextView?,
|
||||
private val token: Token?,
|
||||
private val blockchain: Blockchain,
|
||||
) {
|
||||
|
|
@ -38,7 +38,7 @@ class CurrencyIconRequest(
|
|||
loadBlockchainIconBase(
|
||||
onStart = {
|
||||
currencyImageView.colorFilter = null
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ class CurrencyIconRequest(
|
|||
loadBlockchainIconBase(
|
||||
onStart = {
|
||||
currencyImageView.saturation = 0f
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +57,11 @@ class CurrencyIconRequest(
|
|||
},
|
||||
onSuccess = {
|
||||
currencyImageView.colorFilter = null
|
||||
}
|
||||
},
|
||||
onError = {
|
||||
currencyImageView.setColorFilter(it.getColor())
|
||||
currencyTextView?.setTextColor(it.getTextColor())
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +69,12 @@ class CurrencyIconRequest(
|
|||
loadTokenIconBase(
|
||||
onStart = {
|
||||
currencyImageView.saturation = 0f
|
||||
}
|
||||
},
|
||||
onError = {
|
||||
currencyImageView.saturation = 0f
|
||||
currencyImageView.setColorFilter(it.getColor(true))
|
||||
currencyTextView?.setTextColor(it.getTextColor(true))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -94,15 +103,19 @@ class CurrencyIconRequest(
|
|||
data = getTokenIcon(token, blockchain),
|
||||
placeholderRes = R.drawable.shape_circle,
|
||||
onStart = {
|
||||
currencyTextView.text = token.symbol.take(1)
|
||||
currencyTextView.setTextColor(token.getTextColor())
|
||||
currencyTextView?.text = token.name.take(1)
|
||||
currencyTextView?.setTextColor(token.getTextColor())
|
||||
onStart(token)
|
||||
},
|
||||
onSuccess = {
|
||||
currencyTextView.text = null
|
||||
currencyTextView?.text = null
|
||||
onSuccess(token)
|
||||
},
|
||||
onError = { onError(token) },
|
||||
onError = {
|
||||
// for some reason the onStart doesn't call if an error occurs
|
||||
currencyTextView?.text = token.name.take(1)
|
||||
onError(token)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -122,7 +135,7 @@ private inline fun ImageView.loadIcon(
|
|||
.listener(
|
||||
onStart = { onStart() },
|
||||
onSuccess = { _, _ -> onSuccess() },
|
||||
onError = { _, _ -> onError() }
|
||||
onError = { _, _ -> onError() },
|
||||
)
|
||||
.target(imageView = this)
|
||||
.build()
|
||||
|
|
|
|||
|
|
@ -4,13 +4,11 @@ import android.content.Context
|
|||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.constraintlayout.utils.widget.ImageFilterView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.isVisible
|
||||
import com.tangem.blockchain.common.DerivationStyle
|
||||
import com.tangem.tangem_sdk_new.extensions.dpToPx
|
||||
import com.tangem.tap.common.extensions.getRoundIconRes
|
||||
import com.tangem.tap.features.wallet.models.Currency
|
||||
import com.tangem.wallet.databinding.ViewCurrencyIconBinding
|
||||
import kotlin.math.roundToInt
|
||||
|
|
@ -25,46 +23,50 @@ class CurrencyIconView @JvmOverloads constructor(
|
|||
this,
|
||||
)
|
||||
|
||||
private val currencyImageView: ImageFilterView
|
||||
val currencyImageView: ImageFilterView
|
||||
get() = binding.ivCurrency
|
||||
|
||||
private val currencyTextView: TextView
|
||||
val currencyTextView: TextView
|
||||
get() = binding.tvTokenLetter
|
||||
|
||||
private var isBlockchainIconVisible: Boolean
|
||||
get() = binding.ivBlockchain.isVisible
|
||||
set(value) = binding.ivBlockchain::isVisible.set(value)
|
||||
val blockchainBadge: ImageFilterView
|
||||
get() = binding.ivBlockchainBadge
|
||||
|
||||
private var isBadgeVisible: Boolean
|
||||
get() = binding.badge.isVisible
|
||||
set(value) = binding.badge::isVisible.set(value)
|
||||
var isBlockchainBadgeVisible: Boolean
|
||||
get() = binding.ivBlockchainBadge.isVisible
|
||||
set(value) = binding.ivBlockchainBadge::isVisible.set(value)
|
||||
|
||||
@DrawableRes
|
||||
private var blockchainIconRes: Int? = null
|
||||
set(value) {
|
||||
if (value != null && value != field && isBlockchainIconVisible) {
|
||||
binding.ivBlockchain.setImageResource(value)
|
||||
field = value
|
||||
}
|
||||
}
|
||||
var isCustomCurrencyBadgeVisible: Boolean
|
||||
get() = binding.customBadge.isVisible
|
||||
set(value) = binding.customBadge::isVisible.set(value)
|
||||
|
||||
init {
|
||||
minWidth = dpToPx(48f).roundToInt()
|
||||
minHeight = dpToPx(48f).roundToInt()
|
||||
}
|
||||
}
|
||||
|
||||
fun load(
|
||||
currency: Currency,
|
||||
derivationStyle: DerivationStyle?,
|
||||
) {
|
||||
isBlockchainIconVisible = currency.isToken()
|
||||
isBadgeVisible = currency.isCustomCurrency(derivationStyle)
|
||||
blockchainIconRes = currency.blockchain.getRoundIconRes()
|
||||
fun CurrencyIconView.load(
|
||||
currency: Currency,
|
||||
derivationStyle: DerivationStyle?,
|
||||
) {
|
||||
isCustomCurrencyBadgeVisible = currency.isCustomCurrency(derivationStyle)
|
||||
|
||||
CurrencyIconRequest(
|
||||
currencyImageView = currencyImageView,
|
||||
currencyTextView = currencyTextView,
|
||||
token = (currency as? Currency.Token)?.token,
|
||||
blockchain = currency.blockchain,
|
||||
).load()
|
||||
|
||||
if (currency.isToken()) {
|
||||
// load a blockchain icon into the blockchain badge
|
||||
isBlockchainBadgeVisible = true
|
||||
|
||||
CurrencyIconRequest(
|
||||
currencyImageView = currencyImageView,
|
||||
currencyTextView = currencyTextView,
|
||||
token = (currency as? Currency.Token)?.token,
|
||||
currencyImageView = blockchainBadge,
|
||||
currencyTextView = null,
|
||||
token = null,
|
||||
blockchain = currency.blockchain,
|
||||
).load()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,12 +35,13 @@
|
|||
android:textColor="@android:color/white"
|
||||
android:textSize="25sp"
|
||||
android:textStyle="bold"
|
||||
android:translationY="-1dp"
|
||||
tools:text="J" />
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_blockchain"
|
||||
<androidx.constraintlayout.utils.widget.ImageFilterView
|
||||
android:id="@+id/iv_blockchain_badge"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:background="@drawable/shape_circle"
|
||||
|
|
@ -54,7 +55,7 @@
|
|||
tools:visibility="visible" />
|
||||
|
||||
<View
|
||||
android:id="@+id/badge"
|
||||
android:id="@+id/custom_badge"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"
|
||||
android:background="@drawable/shape_badge_custom_currency"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ ext.versions = [
|
|||
kotlin : '1.6.10',
|
||||
build_gradle : '7.1.3',
|
||||
tangem_card_sdk : 'develop-159',
|
||||
tangem_blockchain_sdk: 'develop-107',
|
||||
tangem_blockchain_sdk: 'develop-111',
|
||||
// tangem_blockchain_sdk: '0.0.1',
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import com.tangem.blockchain.common.Blockchain
|
|||
fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? {
|
||||
return when (networkId) {
|
||||
"arbitrum-one" -> Blockchain.Arbitrum
|
||||
"arbitrum-one/test" -> Blockchain.ArbitrumTestnet
|
||||
"arbitrum/test" -> Blockchain.ArbitrumTestnet
|
||||
"avalanche", "avalanche-2" -> Blockchain.Avalanche
|
||||
"avalanche/test", "avalanche-2/test" -> Blockchain.AvalancheTestnet
|
||||
"binancecoin" -> Blockchain.Binance
|
||||
|
|
@ -40,6 +40,7 @@ fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? {
|
|||
"xdai" -> Blockchain.Gnosis
|
||||
"polkadot" -> Blockchain.Polkadot
|
||||
"polkadot/test" -> Blockchain.PolkadotTestnet
|
||||
"kusama" -> Blockchain.Kusama
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
@ -84,6 +85,7 @@ fun Blockchain.toNetworkId(): String {
|
|||
Blockchain.Gnosis -> "xdai"
|
||||
Blockchain.Polkadot -> "polkadot"
|
||||
Blockchain.PolkadotTestnet -> "polkadot/test"
|
||||
Blockchain.Kusama -> "kusama"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,15 +103,16 @@ fun Blockchain.toCoinId(): String {
|
|||
Blockchain.Avalanche, Blockchain.AvalancheTestnet -> "avalanche-2"
|
||||
Blockchain.Solana, Blockchain.SolanaTestnet -> "solana"
|
||||
Blockchain.Fantom, Blockchain.FantomTestnet -> "fantom"
|
||||
Blockchain.Tron, Blockchain.TronTestnet -> "tron"
|
||||
Blockchain.Polkadot, Blockchain.PolkadotTestnet -> "polkadot"
|
||||
Blockchain.Ducatus -> "ducatus"
|
||||
Blockchain.Litecoin -> "litecoin"
|
||||
Blockchain.RSK -> "rootstock"
|
||||
Blockchain.Tezos -> "tezos"
|
||||
Blockchain.XRP -> "ripple"
|
||||
Blockchain.Dogecoin -> "dogecoin"
|
||||
Blockchain.Tron, Blockchain.TronTestnet -> "tron"
|
||||
Blockchain.Gnosis -> "xdai"
|
||||
Blockchain.Polkadot, Blockchain.PolkadotTestnet -> "polkadot"
|
||||
Blockchain.Kusama -> "kusama"
|
||||
Blockchain.Unknown -> "unknown"
|
||||
}
|
||||
}
|
||||
|
|
@ -18,8 +18,7 @@ fun Card.supportedBlockchains(): List<Blockchain> {
|
|||
Blockchain.fromCurve(EllipticCurve.Secp256k1)
|
||||
}
|
||||
else -> {
|
||||
Blockchain.fromCurve(EllipticCurve.Secp256k1) +
|
||||
Blockchain.fromCurve(EllipticCurve.Ed25519)
|
||||
(Blockchain.fromCurve(EllipticCurve.Secp256k1) + Blockchain.fromCurve(EllipticCurve.Ed25519)).distinct()
|
||||
}
|
||||
}
|
||||
val filtered = supportedBlockchains.filter { isTestCard == it.isTestnet() }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.domain.features
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.domain.common.extensions.fromNetworkId
|
||||
import com.tangem.domain.common.extensions.toNetworkId
|
||||
import org.junit.Test
|
||||
|
||||
class BlockchainTests {
|
||||
@Test
|
||||
fun allNetworkIdsAreImplemented() {
|
||||
val unimplementedIds = Blockchain.values()
|
||||
.toMutableList()
|
||||
.apply { remove(Blockchain.Unknown) }
|
||||
.map { it to Blockchain.fromNetworkId(it.toNetworkId()) }
|
||||
.mapNotNull { if(it.second == null) it.first else null }
|
||||
|
||||
Truth.assertThat(unimplementedIds).isEmpty()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
package com.tangem.domain.features
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue