Updated on 2026-08-14

This commit is contained in:
Tangem 2022-08-17 11:02:43 +03:00
commit b07a453e2e
21 changed files with 119 additions and 172 deletions

View file

@ -76,6 +76,6 @@ fun Store<*>.dispatchDialogShow(dialog: StateDialog) {
fun Store<*>.dispatchDialogHide() {
scope.launch(Dispatchers.Main) {
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
}

View file

@ -22,9 +22,8 @@ import timber.log.Timber
*/
suspend fun WalletManager.safeUpdate(): Result<Wallet> = try {
val scanResponse = store.state.globalState.scanResponse
?: error("Scan response must not be null")
if (scanResponse.isDemoCard() || TestActions.testAmountInjectionForWalletManagerEnabled) {
if (scanResponse?.isDemoCard() == true || TestActions.testAmountInjectionForWalletManagerEnabled) {
delay(500)
TestActions.testAmountInjectionForWalletManagerEnabled = false
Result.Success(wallet)

View file

@ -34,7 +34,7 @@ sealed class GlobalAction : Action {
// dialogs
data class ShowDialog(val stateDialog: StateDialog) : GlobalAction()
data class HideDialog(val stateDialog: StateDialog? = null) : GlobalAction()
object HideDialog : GlobalAction()
sealed class Onboarding {
data class Start(val scanResponse: ScanResponse?, val fromHomeScreen: Boolean = true) : GlobalAction()

View file

@ -68,11 +68,7 @@ fun globalReducer(action: Action, state: AppState): GlobalState {
globalState.copy(dialog = action.stateDialog)
}
is GlobalAction.HideDialog -> {
if (action.stateDialog == null || action.stateDialog == globalState.dialog) {
globalState.copy(dialog = null)
} else {
globalState
}
globalState.copy(dialog = null)
}
is GlobalAction.ExchangeManager.Init.Success -> {
globalState.copy(exchangeManager = action.exchangeManager)

View file

@ -51,7 +51,7 @@ class SimpleCancelableAlertDialog {
setNegativeButton(context.getText(secondaryButtonRes)) { _, _ -> secondaryButtonAction()}
}
setOnDismissListener {
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
}.create()
}

View file

@ -5,7 +5,6 @@ import androidx.appcompat.app.AlertDialog
import com.tangem.blockchain.common.Blockchain
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectDialog
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectSession
import com.tangem.tap.store
import com.tangem.wallet.R
@ -23,19 +22,22 @@ class ApproveWcSessionDialog {
setTitle(context.getString(R.string.wallet_connect))
setMessage(message)
setPositiveButton(context.getText(R.string.common_start)) { _, _ ->
store.dispatch(GlobalAction.HideDialog)
store.dispatch(WalletConnectAction.ChooseNetwork(session.wallet.blockchain!!))
}
if (networks.size > 1) {
setNeutralButton(context.getText(R.string.wallet_connect_select_network)) { _, _ ->
store.dispatch(GlobalAction.HideDialog(WalletConnectDialog.ApproveWcSession(session, networks)))
store.dispatch(GlobalAction.HideDialog)
store.dispatch(WalletConnectAction.SelectNetwork(session = session, networks = networks))
}
}
setNegativeButton(context.getText(R.string.common_reject)) { _, _ ->
store.dispatch(GlobalAction.HideDialog)
store.dispatch(WalletConnectAction.FailureEstablishingSession(session.session))
}
setOnDismissListener {
store.dispatch(GlobalAction.HideDialog(WalletConnectDialog.ApproveWcSession(session, networks)))
setOnCancelListener {
store.dispatch(GlobalAction.HideDialog)
store.dispatch(WalletConnectAction.FailureEstablishingSession(session.session))
}
}.create()
}

View file

@ -58,7 +58,7 @@ class BnbTransactionDialog {
store.dispatch(WalletConnectAction.RejectRequest(session, sessionId))
}
setOnDismissListener {
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
}.create()
}

View file

@ -21,7 +21,7 @@ object ChooseNetworkDialog {
store.dispatch(WalletConnectAction.FailureEstablishingSession(session.session))
}
.setOnDismissListener {
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
.setSingleChoiceItems(networks.map { it.fullName }.toTypedArray(), 0) { _, which ->
networks.getOrNull(which)?.let { selectedBlockchain ->
@ -30,7 +30,7 @@ object ChooseNetworkDialog {
blockchain = selectedBlockchain,
),
)
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
}
.create()

View file

@ -22,7 +22,7 @@ class ClipboardOrScanQrDialog {
store.dispatch(NavigationAction.NavigateTo(AppScreen.QrScan))
}
setOnDismissListener {
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
}.create()
}

View file

@ -29,7 +29,7 @@ class PersonalSignDialog {
store.dispatch(WalletConnectAction.RejectRequest(data.session, data.id))
}
setOnDismissListener {
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
}.create()
}

View file

@ -45,7 +45,7 @@ class TransactionDialog {
store.dispatch(WalletConnectAction.RejectRequest(data.session, data.id))
}
setOnDismissListener {
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
}.create()
}

View file

@ -20,7 +20,7 @@ class AddMoreBackupCardsDialog {
}
setOnDismissListener {
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
}.create()
}

View file

@ -13,10 +13,10 @@ class BackupInProgressDialog {
setTitle(R.string.alert_title)
setMessage(R.string.onboarding_backup_exit_warning)
setPositiveButton(R.string.warning_button_ok) { _, _ ->
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
setOnDismissListener {
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
}.create()
}

View file

@ -20,7 +20,7 @@ class ConfirmDiscardingBackupDialog {
store.dispatch(BackupAction.DiscardSavedBackup)
}
setOnDismissListener {
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
}
setCancelable(false)
}.create()

View file

@ -15,11 +15,11 @@ class UnfinishedBackupFoundDialog {
setTitle(R.string.alert_title)
setMessage(R.string.welcome_interrupted_backup_alert_message)
setPositiveButton(R.string.welcome_interrupted_backup_alert_resume) { _, _ ->
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
store.dispatch(BackupAction.ResumeBackup)
}
setNegativeButton(R.string.welcome_interrupted_backup_alert_discard) { _, _ ->
store.dispatch(GlobalAction.HideDialog())
store.dispatch(GlobalAction.HideDialog)
store.dispatch(GlobalAction.ShowDialog(BackupDialog.ConfirmDiscardingBackup))
}
setCancelable(false)

View file

@ -12,9 +12,10 @@ internal class WalletDetailsButtonsRow @JvmOverloads constructor(
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
) : LinearLayout(context, attrs, defStyleAttr) {
private val binding = ViewWalletDetailsButtonsRowBinding.inflate(
LayoutInflater.from(context),
this
this,
)
var onBuyClick: (() -> Unit)? = null
@ -36,7 +37,7 @@ internal class WalletDetailsButtonsRow @JvmOverloads constructor(
fun updateButtonsVisibility(
buyAllowed: Boolean,
sellAllowed: Boolean,
sendAllowed: Boolean
sendAllowed: Boolean,
) = with(binding) {
btnBuy.isVisible = (buyAllowed && !sellAllowed) || (!buyAllowed && !sellAllowed)
btnBuy.isEnabled = buyAllowed

View file

@ -1,5 +1,6 @@
package com.tangem.tap.features.wallet.ui.wallet
import android.widget.Button
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import com.tangem.common.card.Card
@ -20,11 +21,11 @@ import com.tangem.tap.features.wallet.redux.WalletState
import com.tangem.tap.features.wallet.ui.BalanceStatus
import com.tangem.tap.features.wallet.ui.WalletFragment
import com.tangem.tap.features.wallet.ui.adapters.WalletAdapter
import com.tangem.tap.features.wallet.ui.view.WalletDetailsButtonsRow
import com.tangem.tap.store
import com.tangem.wallet.R
import com.tangem.wallet.databinding.FragmentWalletBinding
class MultiWalletView : WalletView() {
private lateinit var walletsAdapter: WalletAdapter
override fun changeWalletView(fragment: WalletFragment, binding: FragmentWalletBinding) {
@ -33,14 +34,12 @@ class MultiWalletView : WalletView() {
showMultiWalletView(binding)
}
private fun showMultiWalletView(binding: FragmentWalletBinding) = with(binding) {
tvTwinCardNumber.hide()
rvPendingTransaction.hide()
lCardBalance.root.hide()
lAddress.root.hide()
lButtonsShort.root.hide()
lButtonsLong.root.hide()
rowButtons.hide()
lSingleWalletBalance.root.hide()
rvMultiwallet.show()
btnAddToken.show()
@ -59,7 +58,6 @@ class MultiWalletView : WalletView() {
}
}
override fun onViewCreated() {
setupWalletsRecyclerView()
}
@ -86,17 +84,17 @@ class MultiWalletView : WalletView() {
TokensAction.LoadCurrencies(
supportedBlockchains = currenciesRepository.getBlockchains(
card.firmwareVersion,
card.isTestCard
card.isTestCard,
),
scanResponse = store.state.globalState.scanResponse
)
scanResponse = store.state.globalState.scanResponse,
),
)
store.dispatch(TokensAction.AllowToAddTokens(true))
store.dispatch(
TokensAction.SetAddedCurrencies(
wallets = state.walletsData,
derivationStyle = card.derivationStyle
)
derivationStyle = card.derivationStyle,
),
)
store.dispatch(NavigationAction.NavigateTo(AppScreen.AddTokens))
}
@ -105,7 +103,7 @@ class MultiWalletView : WalletView() {
private fun handleBackupWarning(
binding: FragmentWalletBinding,
showBackupWarning: Boolean
showBackupWarning: Boolean,
) = with(binding.lWalletBackupWarning) {
root.isVisible = showBackupWarning
root.setOnClickListener {
@ -128,11 +126,11 @@ class MultiWalletView : WalletView() {
veilBalance.unVeil()
}
tvProcessing.animateVisibility(
show = totalBalance.state == ProgressState.Error
show = totalBalance.state == ProgressState.Error,
)
tvBalance.text = totalBalance.fiatAmount.formatAmountAsSpannedString(
currencySymbol = totalBalance.fiatCurrency.symbol
currencySymbol = totalBalance.fiatCurrency.symbol,
)
tvCurrencyName.text = totalBalance.fiatCurrency.code
@ -145,14 +143,14 @@ class MultiWalletView : WalletView() {
private fun handleErrorStates(
state: WalletState,
binding: FragmentWalletBinding,
fragment: WalletFragment
fragment: WalletFragment,
) {
when (state.primaryWallet?.currencyData?.status) {
BalanceStatus.EmptyCard -> {
showErrorState(
binding,
fragment.getText(R.string.wallet_error_empty_card),
fragment.getString(R.string.wallet_error_empty_card_subtitle)
fragment.getString(R.string.wallet_error_empty_card_subtitle),
)
configureButtonsForEmptyWalletState(binding)
}
@ -160,7 +158,7 @@ class MultiWalletView : WalletView() {
showErrorState(
binding,
fragment.getText(R.string.wallet_error_unsupported_blockchain),
fragment.getString(R.string.wallet_error_unsupported_blockchain_subtitle)
fragment.getString(R.string.wallet_error_unsupported_blockchain_subtitle),
)
}
else -> { /* no-op */
@ -184,9 +182,21 @@ class MultiWalletView : WalletView() {
private fun configureButtonsForEmptyWalletState(binding: FragmentWalletBinding) =
with(binding) {
lButtonsLong.root.show()
lButtonsLong.btnConfirmLong.setOnClickListener { store.dispatch(WalletAction.CreateWallet) }
lButtonsLong.btnConfirmLong.text =
fragment?.getText(R.string.wallet_button_create_wallet)
rowButtons.btnBuy.hide()
rowButtons.btnSell.hide()
rowButtons.btnTrade.hide()
rowButtons.show()
rowButtons.btnSend.text = fragment?.getText(R.string.wallet_button_create_wallet)
rowButtons.onSendClick = { store.dispatch(WalletAction.CreateWallet) }
}
}
}
private val WalletDetailsButtonsRow.btnBuy: Button
get() = this.findViewById(R.id.btn_buy)
private val WalletDetailsButtonsRow.btnSell: Button
get() = this.findViewById(R.id.btn_sell)
private val WalletDetailsButtonsRow.btnTrade: Button
get() = this.findViewById(R.id.btn_trade)
private val WalletDetailsButtonsRow.btnSend: Button
get() = this.findViewById(R.id.btn_send)

View file

@ -2,7 +2,6 @@ package com.tangem.tap.features.wallet.ui.wallet
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.recyclerview.widget.LinearLayoutManager
import com.tangem.domain.common.TwinCardNumber
import com.tangem.tap.common.extensions.beginDelayedTransition
@ -12,11 +11,15 @@ import com.tangem.tap.common.extensions.show
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState
import com.tangem.tap.features.wallet.models.Currency
import com.tangem.tap.features.wallet.models.PendingTransaction
import com.tangem.tap.features.wallet.redux.*
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.features.wallet.redux.WalletData
import com.tangem.tap.features.wallet.redux.WalletMainButton
import com.tangem.tap.features.wallet.redux.WalletState
import com.tangem.tap.features.wallet.ui.BalanceWidget
import com.tangem.tap.features.wallet.ui.MultipleAddressUiHelper
import com.tangem.tap.features.wallet.ui.WalletFragment
import com.tangem.tap.features.wallet.ui.adapters.PendingTransactionsAdapter
import com.tangem.tap.features.wallet.ui.view.WalletDetailsButtonsRow
import com.tangem.tap.store
import com.tangem.wallet.R
import com.tangem.wallet.databinding.FragmentWalletBinding
@ -55,7 +58,7 @@ class SingleWalletView : WalletView() {
state.primaryWallet ?: return
setupTwinCards(state.twinCardsState, binding)
setupButtons(state.primaryWallet, state.isTangemTwins, binding)
setupButtons(state.primaryWallet, binding)
setupAddressCard(state.primaryWallet, binding)
showPendingTransactionsIfPresent(state.primaryWallet.pendingTransactions)
setupBalance(state, state.primaryWallet)
@ -79,9 +82,7 @@ class SingleWalletView : WalletView() {
}
}
private fun setupTwinCards(
twinCardsState: TwinCardsState?, binding: FragmentWalletBinding,
) = with(binding) {
private fun setupTwinCards(twinCardsState: TwinCardsState?, binding: FragmentWalletBinding) = with(binding) {
twinCardsState?.cardNumber?.let { cardNumber ->
tvTwinCardNumber.show()
val number = when (cardNumber) {
@ -96,19 +97,8 @@ class SingleWalletView : WalletView() {
}
}
private fun setupButtons(
state: WalletData, isTwinsWallet: Boolean, binding: FragmentWalletBinding,
) = with(binding) {
setupButtonsType(state, binding)
val tradeState = state.tradeCryptoState
val btnConfirm = if (tradeState.isAvailableToSell() || tradeState.isAvailableToBuy()) {
lButtonsShort.btnConfirm
} else {
lButtonsLong.btnConfirmLong
}
setupConfirmButton(state, btnConfirm, isTwinsWallet)
private fun setupButtons(state: WalletData, binding: FragmentWalletBinding) = with(binding) {
setupRowButtons(state, rowButtons)
lAddress.btnCopy.setOnClickListener {
state.walletAddresses?.selectedAddress?.address?.let { addressString ->
store.dispatch(WalletAction.CopyAddress(addressString, fragment!!.requireContext()))
@ -124,64 +114,22 @@ class SingleWalletView : WalletView() {
)
}
}
setupTradeButton(binding, state.tradeCryptoState)
}
private fun setupTradeButton(binding: FragmentWalletBinding, tradeCryptoState: TradeCryptoState) {
val allowedToBuy = tradeCryptoState.isAvailableToBuy()
val allowedToSell = tradeCryptoState.isAvailableToSell()
val action = when {
allowedToBuy && !allowedToSell -> WalletAction.TradeCryptoAction.Buy()
!allowedToBuy && allowedToSell -> WalletAction.TradeCryptoAction.Sell
allowedToBuy && allowedToSell -> WalletAction.DialogAction.ChooseTradeActionDialog
else -> null
}
val text = when {
allowedToBuy && !allowedToSell -> R.string.wallet_button_buy
!allowedToBuy && allowedToSell -> R.string.wallet_button_sell
allowedToBuy && allowedToSell -> R.string.wallet_button_trade
else -> R.string.wallet_button_trade
}
val icon = when {
allowedToBuy && !allowedToSell -> R.drawable.ic_arrow_up
!allowedToBuy && allowedToSell -> R.drawable.ic_arrow_down
allowedToBuy && allowedToSell -> R.drawable.ic_arrows_up_down
else -> null
}
with(binding) {
lButtonsShort.btnTrade.text = fragment?.getText(text)
icon?.let { lButtonsShort.btnTrade.setIconResource(it) }
lButtonsShort.btnTrade.setOnClickListener { if (action != null) store.dispatch(action) }
}
}
private fun setupRowButtons(state: WalletData, rowButtons: WalletDetailsButtonsRow) {
val allowedToBuy = state.tradeCryptoState.isAvailableToBuy()
val allowedToSell = state.tradeCryptoState.isAvailableToSell()
rowButtons.updateButtonsVisibility(
buyAllowed = allowedToBuy,
sellAllowed = allowedToSell,
sendAllowed = state.mainButton.enabled,
)
private fun setupButtonsType(state: WalletData, binding: FragmentWalletBinding) = with(binding) {
if (state.tradeCryptoState.isAvailableToSell() || state.tradeCryptoState.isAvailableToBuy()) {
lButtonsLong.root.hide()
lButtonsShort.root.show()
} else {
lButtonsLong.root.show()
lButtonsShort.root.hide()
}
}
rowButtons.onBuyClick = { store.dispatch(WalletAction.TradeCryptoAction.Buy()) }
rowButtons.onSendClick = { store.dispatch(WalletAction.TradeCryptoAction.Sell) }
rowButtons.onTradeClick = { store.dispatch(WalletAction.DialogAction.ChooseTradeActionDialog) }
private fun setupConfirmButton(
state: WalletData, btnConfirm: Button, isTwinsWallet: Boolean,
) {
val buttonTitle = when (state.mainButton) {
is WalletMainButton.SendButton -> R.string.wallet_button_send
is WalletMainButton.CreateWalletButton -> {
if (!isTwinsWallet) {
R.string.wallet_button_create_wallet
} else {
R.string.wallet_button_create_twin_wallet
}
}
}
btnConfirm.text = fragment?.getString(buttonTitle)
btnConfirm.isEnabled = state.mainButton.enabled
btnConfirm.setOnClickListener {
rowButtons.onSendClick = {
when (state.mainButton) {
is WalletMainButton.SendButton -> store.dispatch(WalletAction.Send())
is WalletMainButton.CreateWalletButton -> store.dispatch(WalletAction.CreateWallet)

View file

@ -47,7 +47,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingBottom="74dp">
android:paddingBottom="32dp">
<ImageView
android:id="@+id/iv_card"
@ -176,31 +176,15 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/rv_pending_transaction" />
<include
android:id="@+id/l_buttons_long"
layout="@layout/layout_wallet_long_buttons"
<com.tangem.tap.features.wallet.ui.view.WalletDetailsButtonsRow
android:id="@+id/row_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="16dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/l_address"
app:layout_constraintVertical_bias="1" />
<include
android:id="@+id/l_buttons_short"
layout="@layout/layout_wallet_short_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="16dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/l_address"
app:layout_constraintVertical_bias="1" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_add_token"
@ -213,6 +197,7 @@
android:elevation="4dp"
android:text="@string/main_manage_tokens"
android:textSize="16sp"
android:visibility="gone"
app:cornerRadius="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/rv_multiwallet"

View file

@ -1,50 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<merge 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:layout_width="match_parent"
android:layout_height="wrap_content"
tools:parentTag="android.widget.LinearLayout"
tools:orientation="horizontal">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:orientation="horizontal"
tools:parentTag="android.widget.LinearLayout">
<com.google.android.material.button.MaterialButton
<FrameLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="6dp"
android:layout_weight="1">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_trade"
style="@style/TapButtonWithIcon"
android:layout_width="0dp"
android:layout_marginEnd="6dp"
android:layout_weight="1"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wallet_button_trade"
android:visibility="gone"
app:icon="@drawable/ic_arrows_up_down"
tools:visibility="visible" />
<com.google.android.material.button.MaterialButton
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_buy"
style="@style/TapButtonWithIcon"
android:layout_width="0dp"
android:layout_marginEnd="6dp"
android:layout_weight="1"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wallet_button_buy"
android:visibility="gone"
app:icon="@drawable/ic_arrow_up" />
<com.google.android.material.button.MaterialButton
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_sell"
style="@style/TapButtonWithIcon"
android:layout_width="0dp"
android:layout_marginEnd="6dp"
android:layout_weight="1"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wallet_button_sell"
android:visibility="gone"
app:icon="@drawable/ic_arrow_down" />
</FrameLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_send"
style="@style/TapButtonWithIcon"
android:layout_width="0dp"
android:layout_marginStart="6dp"
android:layout_weight="1"
android:text="@string/wallet_button_send"
app:icon="@drawable/ic_send" />
android:id="@+id/btn_send"
style="@style/TapButtonWithIcon"
android:layout_width="0dp"
android:layout_marginStart="6dp"
android:layout_weight="1"
android:text="@string/wallet_button_send"
app:icon="@drawable/ic_send" />
</merge>

View file

@ -2,7 +2,7 @@ ext.versions = [
kotlin : '1.6.10',
build_gradle : '7.1.3',
tangem_card_sdk : 'develop-159',
tangem_blockchain_sdk: 'develop-103',
tangem_blockchain_sdk: 'develop-104',
// tangem_blockchain_sdk: '0.0.1',
]