Updated on 2026-08-14

This commit is contained in:
Tangem 2021-11-11 07:40:54 +00:00
commit 3b5d917f0d
24 changed files with 194 additions and 163 deletions

View file

@ -1,7 +1,7 @@
package com.tangem.tap.common.redux
import com.tangem.common.extensions.VoidCallback
import com.tangem.tap.features.wallet.redux.AddressData
import com.tangem.tap.features.wallet.redux.Currency
/**
[REDACTED_AUTHOR]
@ -11,8 +11,7 @@ interface StateDialog
sealed class AppDialog : StateDialog {
object ScanFailsDialog : AppDialog()
data class AddressInfoDialog(
val currency: Currency,
val addressData: AddressData,
val onCopyAddress: VoidCallback,
val onShareAddress: VoidCallback
) : AppDialog()
}

View file

@ -43,20 +43,14 @@ fun globalReducer(action: Action, state: AppState): GlobalState {
}
is GlobalAction.SetWarningManager -> globalState.copy(warningManager = action.warningManager)
is GlobalAction.UpdateWalletSignedHashes -> {
val wallet = globalState.scanResponse?.card
?.wallet(action.walletPublicKey)
?.copy(
totalSignedHashes = action.walletSignedHashes,
remainingSignatures = action.remainingSignatures
)
val card = globalState.scanResponse?.card
wallet?.let { globalState.scanResponse.card.updateWallet(wallet) }
val card = globalState.scanResponse?.card ?: return globalState
val wallet = card.wallet(action.walletPublicKey) ?: return globalState
if (card != null) {
globalState.copy(scanResponse = globalState.scanResponse.copy(card = card))
} else {
globalState
}
val newCardInstance = card.updateWallet(wallet.copy(
totalSignedHashes = action.walletSignedHashes,
remainingSignatures = action.remainingSignatures
))
globalState.copy(scanResponse = globalState.scanResponse.copy(card = newCardInstance))
}
is GlobalAction.SetFeedbackManager -> {
globalState.copy(feedbackManager = action.feedbackManager)

View file

@ -125,6 +125,7 @@ class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Co
companion object {
val config = Config(
linkedTerminal = true,
allowUntrustedCards = true,
filter = CardFilter(
allowedCardTypes = FirmwareVersion.FirmwareType.values().toList()

View file

@ -1,19 +1,38 @@
package com.tangem.tap.domain.extensions
import com.tangem.blockchain.common.Blockchain
import com.tangem.tap.features.wallet.redux.Currency
import com.tangem.tap.network.moonpay.MoonpayStatus
/**
[REDACTED_AUTHOR]
*/
fun MoonpayStatus.buyIsAllowed(blockchain: Blockchain): Boolean {
if (blockchain == Blockchain.Unknown || blockchain == Blockchain.BSC) return false
fun MoonpayStatus.buyIsAllowed(currency: Currency): Boolean {
if (!isBuyAllowed) return false
return isBuyAllowed && availableToBuy.contains(blockchain.currency)
return when (currency) {
is Currency.Blockchain -> {
if (currency.blockchain == Blockchain.Unknown || currency.blockchain == Blockchain.BSC) {
false
} else {
availableToBuy.contains(currency.currencySymbol)
}
}
is Currency.Token -> false
}
}
fun MoonpayStatus.sellIsAllowed(blockchain: Blockchain): Boolean {
if (blockchain == Blockchain.Unknown || blockchain == Blockchain.BSC) return false
fun MoonpayStatus.sellIsAllowed(currency: Currency): Boolean {
if (!isSellAllowed) return false
return isSellAllowed && availableToSell.contains(blockchain.currency)
return when (currency) {
is Currency.Blockchain -> {
if (currency.blockchain == Blockchain.Unknown || currency.blockchain == Blockchain.BSC) {
false
} else {
availableToSell.contains(currency.currencySymbol)
}
}
is Currency.Token -> false
}
}

View file

@ -122,7 +122,7 @@ class CurrenciesRepository(val context: Application) {
tokensAdapter.fromJson(bscTokensJson)!!.map { it.toToken() } +
tokensAdapter.fromJson(binanceTokensJson)!!.mapNotNull {
// temporary exclude Binance BEP-8 tokens
if (it.type != null && it.type != BINANCE_TOKEN_TYPE_BEP8) it.toToken() else null
if (it.type != null && it.type == BINANCE_TOKEN_TYPE_BEP8) null else it.toToken()
}
}

View file

@ -281,8 +281,8 @@ class FeedbackEmail : EmailData {
override val mainMessage: String
get() = if (isS2CCard) s2cMainMessage else tangemMainMessage
private val tangemSubject = "Tangem Tap feedback"
private val tangemMainMessage = "Hi Tangem,"
private val tangemSubject = "Tangem feedback"
private val tangemMainMessage = "Hi support team,"
private val s2cSubject = "Feedback"
private val s2cMainMessage = "Hi support team,"

View file

@ -4,7 +4,10 @@ import android.content.Context
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.tangem.tap.common.extensions.copyToClipboard
import com.tangem.tap.common.extensions.dispatchDialogHide
import com.tangem.tap.common.extensions.dispatchShare
import com.tangem.tap.common.extensions.dispatchToastNotification
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.features.wallet.redux.Currency
import com.tangem.tap.store
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.dialog_onboarding_address_info.*
@ -35,10 +38,31 @@ class AddressInfoBottomSheetDialog(
tv_address.text = data.address
btn_fl_copy_address.setOnClickListener {
context.copyToClipboard(data.address)
stateDialog.onCopyAddress()
store.dispatchToastNotification(R.string.copy_toast_msg)
}
btn_fl_share.setOnClickListener {
stateDialog.onShareAddress()
store.dispatchShare(data.shareUrl)
}
tv_recieve_message.text = getQRReceiveMessage(tv_recieve_message.context, stateDialog.currency)
}
}
fun getQRReceiveMessage(context: Context, currency: Currency): String {
return when (currency) {
is Currency.Blockchain -> {
context.getString(
R.string.address_qr_code_message_format,
currency.blockchain.fullName,
currency.currencySymbol
)
}
is Currency.Token -> {
context.getString(
R.string.address_qr_code_message_token_format,
currency.token.name,
currency.currencySymbol,
currency.blockchain.fullName
)
}
}
}

View file

@ -134,12 +134,8 @@ private fun handleNoteAction(action: Action, dispatch: DispatchFunction) {
}
is OnboardingNoteAction.ShowAddressInfoDialog -> {
val addressData = noteState.walletManager?.getAddressData() ?: return
val addressWasCopied = globalState.resources.strings.addressWasCopied
val appDialog = AppDialog.AddressInfoDialog(
addressData,
onCopyAddress = { store.dispatchToastNotification(addressWasCopied) },
onShareAddress = { store.dispatchShare(addressData.shareUrl) }
)
val appDialog = AppDialog.AddressInfoDialog(noteState.walletBalance.currency, addressData)
store.dispatchDialogShow(appDialog)
}
is OnboardingNoteAction.TopUp -> {

View file

@ -27,7 +27,7 @@ data class OnboardingNoteState(
get() = steps.indexOf(currentStep)
val isBuyAllowed: Boolean by ReadOnlyProperty<Any, Boolean> { thisRef, property ->
store.state.globalState.moonpayStatus?.buyIsAllowed(walletBalance.currency.blockchain) ?: false
store.state.globalState.moonpayStatus?.buyIsAllowed(walletBalance.currency) ?: false
}
}

View file

@ -239,12 +239,7 @@ private fun handle(action: Action, dispatch: DispatchFunction) {
is TwinCardsAction.ShowAddressInfoDialog -> {
val addressData = twinCardsState.walletManager?.getAddressData() ?: return
val addressWasCopied = globalState.resources.strings.addressWasCopied
val appDialog = AppDialog.AddressInfoDialog(
addressData,
onCopyAddress = { store.dispatchToastNotification(addressWasCopied) },
onShareAddress = { store.dispatchShare(addressData.shareUrl) }
)
val appDialog = AppDialog.AddressInfoDialog(twinCardsState.walletBalance.currency, addressData)
store.dispatchDialogShow(appDialog)
}
is TwinCardsAction.TopUp -> {

View file

@ -57,7 +57,7 @@ data class TwinCardsState(
get() = currentStep == TwinCardsStep.CreateSecondWallet || currentStep == TwinCardsStep.CreateThirdWallet
val isBuyAllowed: Boolean by ReadOnlyProperty<Any, Boolean> { thisRef, property ->
store.state.globalState.moonpayStatus?.buyIsAllowed(walletBalance.currency.blockchain) ?: false
store.state.globalState.moonpayStatus?.buyIsAllowed(walletBalance.currency) ?: false
}
}

View file

@ -7,10 +7,10 @@ import com.tangem.blockchain.common.*
import com.tangem.blockchain.extensions.SimpleResult
import com.tangem.common.card.Card
import com.tangem.common.core.TangemSdkError
import com.tangem.common.services.Result
import com.tangem.tap.common.analytics.AnalyticsEvent
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.stripZeroPlainString
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.common.redux.navigation.NavigationAction
@ -57,12 +57,12 @@ class SendMiddleware {
val transactionData = appState()?.sendState?.externalTransactionData
if (transactionData != null) {
store.dispatchOnMain(AddressPayIdVerifyAction.AddressVerification.SetWalletAddress(
transactionData.destinationAddress, false
transactionData.destinationAddress, false
))
store.dispatchOnMain(AmountActionUi.SetMainCurrency(MainCurrencyType.CRYPTO))
store.dispatchOnMain(AmountActionUi.HandleUserInput(transactionData.amount))
store.dispatchOnMain(AmountAction.SetAmount(transactionData.amount.toBigDecimal(),
false))
false))
}
}
}
@ -72,8 +72,9 @@ class SendMiddleware {
}
}
private fun verifyAndSendTransaction(
action: SendActionUi.SendAmountToRecipient, appState: AppState?, dispatch: (Action) -> Unit,
action: SendActionUi.SendAmountToRecipient, appState: AppState?, dispatch: (Action) -> Unit,
) {
val sendState = appState?.sendState ?: return
val walletManager = sendState.walletManager ?: return
@ -105,21 +106,21 @@ private fun verifyAndSendTransaction(
}
else -> {
sendTransaction(action, walletManager, amountToSend, feeAmount, destinationAddress,
sendState.transactionExtrasState, card, sendState.externalTransactionData, dispatch)
sendState.transactionExtrasState, card, sendState.externalTransactionData, dispatch)
}
}
}
private fun sendTransaction(
action: SendActionUi.SendAmountToRecipient,
walletManager: WalletManager,
amountToSend: Amount,
feeAmount: Amount,
destinationAddress: String,
transactionExtras: TransactionExtrasState,
card: Card,
externalTransactionData: ExternalTransactionData?,
dispatch: (Action) -> Unit,
action: SendActionUi.SendAmountToRecipient,
walletManager: WalletManager,
amountToSend: Amount,
feeAmount: Amount,
destinationAddress: String,
transactionExtras: TransactionExtrasState,
card: Card,
externalTransactionData: ExternalTransactionData?,
dispatch: (Action) -> Unit,
) {
dispatch(SendAction.ChangeSendButtonState(ButtonState.PROGRESS))
var txData = walletManager.createTransaction(amountToSend, feeAmount, destinationAddress)
@ -128,7 +129,23 @@ private fun sendTransaction(
transactionExtras.xrpDestinationTag?.tag?.let { txData = txData.copy(extras = XrpTransactionBuilder.XrpTransactionExtras(it)) }
scope.launch {
walletManager.update()
val updateWalletResult = walletManager.safeUpdate()
if (updateWalletResult is Result.Failure) {
when (val error = updateWalletResult.error) {
is TapError -> store.dispatchErrorNotification(error)
else -> {
val tapError = if (error.message == null) {
TapError.UnknownError
} else {
TapError.CustomError(error.message!!)
}
store.dispatchErrorNotification(tapError)
}
}
withMainContext { dispatch(SendAction.ChangeSendButtonState(ButtonState.ENABLED)) }
return@launch
}
val isLinkedTerminal = tangemSdk.config.linkedTerminal
if (card.isStart2Coin) {
tangemSdk.config.linkedTerminal = false

View file

@ -5,7 +5,6 @@ import androidx.appcompat.app.AlertDialog
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.features.feedback.SendTransactionFailedEmail
import com.tangem.tap.features.send.redux.SendAction
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.store
import com.tangem.wallet.R
@ -23,7 +22,7 @@ class SendTransactionFailsDialog {
store.dispatch(GlobalAction.SendFeedback(SendTransactionFailedEmail(dialog.errorMessage)))
}
setPositiveButton(R.string.common_no) { _, _ -> }
setOnDismissListener { store.dispatch(WalletAction.HideDialog) }
setOnDismissListener { store.dispatch(SendAction.Dialog.Hide) }
}.create()
}
}

View file

@ -160,6 +160,14 @@ data class WalletState(
return updatedWallets + remainingWallets
}
fun updateTradeCryptoState(moonpayStatus: MoonpayStatus?, walletData: WalletData): WalletData {
return walletData.copy(tradeCryptoState = TradeCryptoState.from(moonpayStatus, walletData))
}
fun updateTradeCryptoState(moonpayStatus: MoonpayStatus?, walletDataList: List<WalletData>): List<WalletData> {
return walletDataList.map { it.copy(tradeCryptoState = TradeCryptoState.from(moonpayStatus, it)) }
}
fun addWalletManagers(newWalletManagers: List<WalletManager>): WalletState {
val updatedWalletManagers = this.walletManagers +
newWalletManagers.filterNot { this.blockchains.contains(it.wallet.blockchain) }
@ -168,10 +176,6 @@ data class WalletState(
}
sealed class WalletDialog : StateDialog {
data class QrDialog(
val qrCode: Bitmap?, val shareUrl: String?, val currencyName: CryptoCurrencyName?
) : WalletDialog()
data class SelectAmountToSendDialog(val amounts: List<Amount>?) : WalletDialog()
object SignedHashesMultiWalletDialog : WalletDialog()
object ChooseTradeActionDialog : WalletDialog()
@ -224,9 +228,9 @@ data class TradeCryptoState(
companion object {
fun from(moonpayStatus: MoonpayStatus?, walletData: WalletData): TradeCryptoState {
val status = moonpayStatus ?: return walletData.tradeCryptoState
val blockchain = walletData.currency?.blockchain ?: return walletData.tradeCryptoState
val currency = walletData.currency
return TradeCryptoState(status.sellIsAllowed(blockchain), status.buyIsAllowed(blockchain))
return TradeCryptoState(status.sellIsAllowed(currency), status.buyIsAllowed(currency))
}
}
}

View file

@ -12,6 +12,7 @@ import com.tangem.operations.attestation.OnlineCardVerifier
import com.tangem.tap.*
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.common.redux.navigation.AppScreen
@ -193,6 +194,13 @@ class WalletMiddleware {
store.dispatch(NavigationAction.NavigateTo(AppScreen.Send))
}
}
is WalletAction.ShowDialog.QrCode -> {
val selectedWalletData = walletState.getWalletData(walletState.selectedWallet) ?: return
val selectedAddressData = selectedWalletData.walletAddresses?.selectedAddress ?: return
val currency = selectedWalletData.currency
store.dispatchDialogShow(AppDialog.AddressInfoDialog(currency, selectedAddressData))
}
}
}

View file

@ -10,10 +10,7 @@ import com.tangem.tap.common.extensions.toFormattedFiatValue
import com.tangem.tap.domain.getFirstToken
import com.tangem.tap.features.wallet.models.removeUnknownTransactions
import com.tangem.tap.features.wallet.models.toPendingTransactions
import com.tangem.tap.features.wallet.redux.Currency
import com.tangem.tap.features.wallet.redux.ProgressState
import com.tangem.tap.features.wallet.redux.WalletMainButton
import com.tangem.tap.features.wallet.redux.WalletState
import com.tangem.tap.features.wallet.redux.*
import com.tangem.tap.features.wallet.ui.BalanceStatus
import com.tangem.tap.features.wallet.ui.BalanceWidgetData
import com.tangem.tap.features.wallet.ui.TokenData
@ -22,18 +19,18 @@ import java.math.RoundingMode
class OnWalletLoadedReducer {
fun reduce(wallet: Wallet, walletState: WalletState, topUpAllowed: Boolean? = null): WalletState {
fun reduce(wallet: Wallet, walletState: WalletState): WalletState {
return if (!walletState.isMultiwalletAllowed) {
onSingleWalletLoaded(wallet, walletState, topUpAllowed)
onSingleWalletLoaded(wallet, walletState)
} else {
onMultiWalletLoaded(wallet, walletState, topUpAllowed)
onMultiWalletLoaded(wallet, walletState)
}
}
private fun onMultiWalletLoaded(
wallet: Wallet, walletState: WalletState, topUpAllowed: Boolean? = null
): WalletState {
private fun onMultiWalletLoaded(wallet: Wallet, walletState: WalletState): WalletState {
val fiatCurrencySymbol = store.state.globalState.appCurrency
val moonpayStatus = store.state.globalState.moonpayStatus
val amount = wallet.amounts[AmountType.Coin]?.value
if (walletState.getWalletData(wallet.blockchain) == null) {
return walletState
@ -64,7 +61,8 @@ class OnWalletLoadedReducer {
),
pendingTransactions = pendingTransactions.removeUnknownTransactions(),
mainButton = WalletMainButton.SendButton(sendButtonEnabled),
currency = Currency.Blockchain(wallet.blockchain)
currency = Currency.Blockchain(wallet.blockchain),
tradeCryptoState = TradeCryptoState.from(moonpayStatus, walletData)
)
val tokens = wallet.getTokens().mapNotNull { token ->
@ -88,7 +86,9 @@ class OnWalletLoadedReducer {
fiatAmountFormatted = tokenFiatAmount?.toFormattedFiatValue(fiatCurrencySymbol)
),
pendingTransactions = tokenPendingTransactions.removeUnknownTransactions(),
mainButton = WalletMainButton.SendButton(sendButtonEnabled)
mainButton = WalletMainButton.SendButton(sendButtonEnabled),
tradeCryptoState = TradeCryptoState.from(moonpayStatus, tokenWalletData)
)
}
val newWallets = (tokens + newWalletData).mapNotNull { it }
@ -104,12 +104,12 @@ class OnWalletLoadedReducer {
)
}
private fun onSingleWalletLoaded(
wallet: Wallet, walletState: WalletState, topUpAllowed: Boolean? = null
): WalletState {
private fun onSingleWalletLoaded(wallet: Wallet, walletState: WalletState): WalletState {
if (wallet.blockchain != walletState.primaryBlockchain) return walletState
val fiatCurrencySymbol = store.state.globalState.appCurrency
val moonpayStatus = store.state.globalState.moonpayStatus
val token = wallet.getFirstToken()
val tokenData = if (token != null) {
val tokenAmount = wallet.getTokenAmount(token)
@ -155,7 +155,8 @@ class OnWalletLoadedReducer {
fiatAmount = fiatAmountRaw
),
pendingTransactions = pendingTransactions.removeUnknownTransactions(),
mainButton = WalletMainButton.SendButton(sendButtonEnabled)
mainButton = WalletMainButton.SendButton(sendButtonEnabled),
tradeCryptoState = TradeCryptoState.from(moonpayStatus, walletState.primaryWallet)
)
val wallets = walletData?.let { listOf(walletData) } ?: emptyList()
return walletState.copy(

View file

@ -3,7 +3,10 @@ package com.tangem.tap.features.wallet.redux.reducers
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.Wallet
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.extensions.toFiatString
import com.tangem.tap.common.extensions.toFiatValue
import com.tangem.tap.common.extensions.toFormattedCurrencyString
import com.tangem.tap.common.extensions.toFormattedFiatValue
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.FiatCurrencyName
import com.tangem.tap.domain.TapError
@ -13,6 +16,7 @@ import com.tangem.tap.domain.twins.TwinCardNumber
import com.tangem.tap.features.wallet.redux.*
import com.tangem.tap.features.wallet.ui.BalanceStatus
import com.tangem.tap.features.wallet.ui.BalanceWidgetData
import com.tangem.tap.store
import org.rekotlin.Action
import java.math.BigDecimal
import java.math.RoundingMode
@ -30,6 +34,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
if (action !is WalletAction) return state.walletState
val moonpayStatus = store.state.globalState.moonpayStatus
var newState = state.walletState
when (action) {
@ -109,7 +114,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
val walletManager = newState.getWalletManager(action.blockchain) ?: return newState
val blockchain = walletManager.wallet.blockchain
val currencies = listOf(Currency.Blockchain(blockchain)) +
walletManager.cardTokens.map { Currency.Token(it) }
walletManager.cardTokens.map { Currency.Token(it) }
val newWallets = newState.wallets.filter { currencies.contains(it.currency) }
.map { wallet ->
wallet.copy(
@ -123,7 +128,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
)
}
val wallets = newState.replaceSomeWallets(newWallets)
newState = newState.copy(wallets = wallets)
newState = newState.copy(wallets = newState.updateTradeCryptoState(moonpayStatus, wallets))
}
}
is WalletAction.LoadWallet.Success -> newState =
@ -148,7 +153,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
}
newState = newState.copy(
state = progressState,
wallets = wallets
wallets = newState.updateTradeCryptoState(moonpayStatus, wallets)
)
}
is WalletAction.LoadWallet.Failure -> {
@ -182,7 +187,8 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
ProgressState.Done
}
newState = newState.copy(
state = progressState, wallets = wallets
state = progressState,
wallets = newState.updateTradeCryptoState(moonpayStatus, wallets)
)
}
is WalletAction.SetArtworkId -> {
@ -198,23 +204,13 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
newState = setNewFiatRate(action.fiatRate, state.globalState.appCurrency, newState)
is WalletAction.LoadArtwork -> {
val artworkUrl = action.card.getArtworkUrl(action.artworkId)
?: when (state.twinCardsState.cardNumber) {
TwinCardNumber.First -> Artwork.TWIN_CARD_1
TwinCardNumber.Second -> Artwork.TWIN_CARD_2
else -> Artwork.DEFAULT_IMG_URL
}
?: when (state.twinCardsState.cardNumber) {
TwinCardNumber.First -> Artwork.TWIN_CARD_1
TwinCardNumber.Second -> Artwork.TWIN_CARD_2
else -> Artwork.DEFAULT_IMG_URL
}
newState = newState.copy(cardImage = Artwork(artworkId = artworkUrl))
}
is WalletAction.ShowDialog.QrCode -> {
val selectedWalletData = newState.getWalletData(newState.selectedWallet)
newState = newState.copy(
walletDialog = WalletDialog.QrDialog(
selectedWalletData?.walletAddresses?.selectedAddress?.shareUrl?.toQrCode(),
selectedWalletData?.walletAddresses?.selectedAddress?.shareUrl,
selectedWalletData?.currencyData?.currency
)
)
}
is WalletAction.ShowDialog.SignedHashesMultiWalletDialog -> {
newState = newState.copy(walletDialog = WalletDialog.SignedHashesMultiWalletDialog)
}
@ -261,7 +257,7 @@ fun createAddressList(wallet: Wallet?, walletAddresses: WalletAddresses? = null)
var indexOfSelectedWallet = 0
walletAddresses?.let {
val index =
listOfAddressData.indexOfFirst { it.address == walletAddresses.selectedAddress.address }
listOfAddressData.indexOfFirst { it.address == walletAddresses.selectedAddress.address }
if (index != -1) indexOfSelectedWallet = index
}
return WalletAddresses(listOfAddressData[indexOfSelectedWallet], listOfAddressData)
@ -272,10 +268,10 @@ fun Wallet.createAddressesData(): List<AddressData> {
// put a defaultAddress at the first place
addresses.forEach {
val addressData = AddressData(
it.value,
it.type,
getShareUri(it.value),
getExploreUrl(it.value)
it.value,
it.type,
getShareUri(it.value),
getExploreUrl(it.value)
)
if (it.type == blockchain.defaultAddressType()) {
listOfAddressData.add(0, addressData)

View file

@ -14,6 +14,7 @@ import com.tangem.tap.common.SnackbarHandler
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.StateDialog
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.features.onboarding.getQRReceiveMessage
import com.tangem.tap.features.wallet.models.PendingTransaction
import com.tangem.tap.features.wallet.redux.*
import com.tangem.tap.features.wallet.ui.adapters.PendingTransactionsAdapter
@ -180,6 +181,7 @@ class WalletDetailsFragment : Fragment(R.layout.fragment_wallet_details), StoreS
requireContext()))
}
iv_qr_code.setImageBitmap(state.walletAddresses.selectedAddress.shareUrl.toQrCode())
tv_recieve_message.text = getQRReceiveMessage(tv_recieve_message.context, state.currency)
}
}

View file

@ -1,36 +0,0 @@
package com.tangem.tap.features.wallet.ui.dialogs
import android.app.Dialog
import android.content.Context
import android.graphics.Bitmap
import com.tangem.tap.common.extensions.hide
import com.tangem.tap.common.extensions.show
import com.tangem.tap.common.redux.global.CryptoCurrencyName
import com.tangem.tap.features.wallet.redux.WalletAction
import com.tangem.tap.store
import com.tangem.wallet.R
import kotlinx.android.synthetic.main.dialog_qrcode.*
class QrDialog(context: Context) : Dialog(context) {
init {
this.setContentView(R.layout.dialog_qrcode)
}
fun showQr(qrCode: Bitmap, shareUrl: String, currencyName: CryptoCurrencyName?) {
this.setOnDismissListener { store.dispatch(WalletAction.HideDialog) }
this.btn_done?.setOnClickListener { store.dispatch(WalletAction.HideDialog) }
this.tv_qr_dialog_address?.text = shareUrl
this.iv_qrcode?.setImageBitmap(qrCode)
if (currencyName == null) {
this.tv_qr_dialog_header.hide()
} else {
this.tv_qr_dialog_header.show()
this.tv_qr_dialog_header.text = context.getString(
R.string.wallet_qr_title_format, currencyName
)
}
super.show()
}
}

View file

@ -140,7 +140,9 @@ class SingleWalletView : WalletView {
store.dispatch(WalletAction.CopyAddress(addressString, fragment.requireContext()))
}
}
btn_show_qr.setOnClickListener { store.dispatch(WalletAction.ShowDialog.QrCode) }
btn_show_qr.setOnClickListener {
store.dispatch(WalletAction.ShowDialog.QrCode)
}
setupTradeButton(fragment, state.tradeCryptoState)
}
@ -242,15 +244,6 @@ class SingleWalletView : WalletView {
private fun handleDialogs(walletDialog: StateDialog?, fragment: WalletFragment) {
val context = fragment.context ?: return
when (walletDialog) {
is WalletDialog.QrDialog -> {
if (walletDialog.qrCode != null && walletDialog.shareUrl != null) {
if (dialog == null) dialog = QrDialog(context).apply {
this.showQr(
walletDialog.qrCode, walletDialog.shareUrl, walletDialog.currencyName
)
}
}
}
is WalletDialog.SelectAmountToSendDialog -> {
if (dialog == null) dialog = AmountToSendDialog(context).apply {
this.show(walletDialog.amounts)

View file

@ -24,24 +24,26 @@
app:layout_constraintTop_toBottomOf="@+id/pseudo_toolbar" />
<TextView
android:id="@+id/tv_scan_address"
android:id="@+id/tv_recieve_message"
style="@style/TextViewOnboarding.Body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="@string/onboarding_dialog_wallet_address"
android:layout_marginStart="40dp"
android:layout_marginEnd="40dp"
android:textAlignment="center"
android:textAllCaps="false"
app:layout_constraintEnd_toEndOf="@+id/imv_qr_code"
app:layout_constraintStart_toStartOf="@+id/imv_qr_code"
app:layout_constraintTop_toBottomOf="@+id/imv_qr_code" />
app:layout_constraintBottom_toTopOf="@+id/guideline3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imv_qr_code"
tools:text="@string/address_qr_code_message_token_format" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.8047809" />
app:layout_constraintGuide_percent="0.8" />
<FrameLayout
android:id="@+id/btn_fl_copy_address"
@ -83,6 +85,7 @@
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless"
android:src="@drawable/ic_copy_green" />
</androidx.appcompat.widget.LinearLayoutCompat>
@ -104,11 +107,12 @@
app:layout_constraintTop_toTopOf="@+id/guideline3">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_gravity="center"
android:background="?selectableItemBackgroundBorderless"
android:src="@drawable/ic_share_green" />
android:src="@drawable/ic_share_chip"
android:tint="@color/accent" />
</FrameLayout>

View file

@ -53,6 +53,7 @@
android:layout_height="82dp"
android:background="@color/backgroundLightGray"
android:fontFamily="sans-serif-light"
android:imeOptions="actionDone"
android:inputType="numberDecimal"
android:paddingStart="0dp"
android:paddingEnd="96dp"

View file

@ -179,6 +179,20 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_copy" />
<TextView
android:id="@+id/tv_recieve_message"
style="@style/TextViewOnboarding.Body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:textAlignment="center"
android:textAllCaps="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv_qr_code"
tools:text="@string/address_qr_code_message_token_format" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -195,7 +195,7 @@
<string name="onboarding_done_button_continue" translatable="false">Continue</string>
<string name="onboarding_balance_title" translatable="false">Balance</string>
<string name="address_qr_code_message_format" translatable="false">Send only %s (%s) to this address. Sending any other currency will result in its irreversible loss.</string>
<string name="address_qr_code_message_token_format" translatable="false">Send only %s (%s) from %@snetwork to this address. Sending any other currency will result in its irreversible loss.</string>
<string name="address_qr_code_message_token_format" translatable="false">Send only %s (%s) from %s network to this address. Sending any other currency will result in its irreversible loss.</string>
<string name="onboarding_twins_interrupt_warning" translatable="false">If the process of re-creating the wallet gets interrupted in any way, youll have to start over.</string>