From 91a9792c8478068c39033f406761bd2c00071d05 Mon Sep 17 00:00:00 2001 From: Tangem Date: Sun, 29 Nov 2020 23:09:30 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/features/send/ui/SendFragment.kt | 2 +- .../stateSubscribers/SendStateSubscriber.kt | 3 +- .../tap/features/wallet/redux/WalletAction.kt | 3 ++ .../features/wallet/redux/WalletMiddleware.kt | 6 +-- .../features/wallet/redux/WalletReducer.kt | 43 ++++++++++++---- .../tap/features/wallet/redux/WalletState.kt | 16 +++++- .../tap/features/wallet/ui/WalletFragment.kt | 43 +++++++++++++++- app/src/main/res/layout/layout_address.xml | 51 +++++++++++++++---- app/src/main/res/layout/layout_send_fee.xml | 6 +-- .../main/res/values/strings_untranslated.xml | 3 ++ app/src/main/res/values/styles.xml | 2 +- 11 files changed, 147 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt index b9d542836f..9714886b7b 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/SendFragment.kt @@ -240,7 +240,7 @@ class FeeUiHelper { companion object { fun feeToId(fee: FeeType): Int { return when (fee) { - FeeType.SINGLE -> 0 + FeeType.SINGLE -> View.NO_ID FeeType.LOW -> R.id.chipLow FeeType.NORMAL -> R.id.chipNormal FeeType.PRIORITY -> R.id.chipPriority diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt index c6065b1752..087c63af7a 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt @@ -3,6 +3,7 @@ package com.tangem.tap.features.send.ui.stateSubscribers import android.app.Dialog import android.content.Context import android.text.SpannableStringBuilder +import android.view.View import android.view.ViewGroup import androidx.core.text.bold import com.tangem.tap.common.extensions.* @@ -200,7 +201,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber } val chipId = FeeUiHelper.feeToId(state.selectedFeeType) - if (fg.chipGroup.checkedChipId != chipId && chipId != 0) fg.chipGroup.check(chipId) + if (fg.chipGroup.checkedChipId != chipId && chipId != View.NO_ID) fg.chipGroup.check(chipId) } private fun handleReceiptState(fg: BaseStoreFragment, state: ReceiptState) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt index e129bf08b3..4bd5972e2e 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt @@ -3,6 +3,7 @@ package com.tangem.tap.features.wallet.redux import android.content.Context import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.Wallet +import com.tangem.blockchain.common.address.AddressType import com.tangem.commands.Card import com.tangem.tap.common.redux.ErrorAction import com.tangem.tap.common.redux.NotificationAction @@ -91,4 +92,6 @@ sealed class WalletAction : Action { sealed class TopUpAction : WalletAction() { data class TopUp(val context: Context, val toolbarColor: Int) : TopUpAction() } + + data class ChangeSelectedAddress(val type: AddressType): WalletAction() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt index 8fbbe8a149..5aeba06e50 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt @@ -133,13 +133,13 @@ class WalletMiddleware { } } is WalletAction.CopyAddress -> { - store.state.walletState.addressData?.address?.let { + store.state.walletState.walletAddresses?.selectedAddress?.address?.let { action.context.copyToClipboard(it) store.dispatch(WalletAction.CopyAddress.Success) } } is WalletAction.ExploreAddress -> { - val uri = Uri.parse(store.state.walletState.addressData?.exploreUrl) + val uri = Uri.parse(store.state.walletState.walletAddresses?.selectedAddress?.exploreUrl) val intent = Intent(Intent.ACTION_VIEW, uri) ContextCompat.startActivity(action.context, intent, null) } @@ -258,7 +258,7 @@ private class TopUpMiddleware { val config = store.state.globalState.configManager?.config ?: return val url = TopUpHelper.getUrl( store.state.walletState.currencyData.currencySymbol!!, - store.state.walletState.addressData!!.address, + store.state.walletState.walletAddresses!!.selectedAddress.address, config.moonPayApiKey, config.moonPayApiSecretKey ) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt index 4194fabd9e..e544f0a16d 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt @@ -2,6 +2,7 @@ package com.tangem.tap.features.wallet.redux import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.Wallet +import com.tangem.blockchain.common.address.DefaultAddressType import com.tangem.commands.common.network.TangemService import com.tangem.common.extensions.isZero import com.tangem.common.extensions.toHexString @@ -44,15 +45,10 @@ private fun internalReduce(action: Action, state: AppState): WalletState { when (action.error) { is TapError.NoInternetConnection -> { val wallet = state.globalState.scanNoteResponse?.walletManager?.wallet - val addressData = if (wallet == null) { - null - } else { - AddressData(wallet.address, wallet.getShareUri(wallet.address), wallet.getExploreUrl()) - } newState = newState.copy( state = ProgressState.Error, error = ErrorType.NoInternetConnection, - addressData = addressData, + walletAddresses = createAddressList(wallet, newState.walletAddresses), currencyData = BalanceWidgetData( status = BalanceStatus.Unreachable, currency = wallet?.blockchain?.fullName, @@ -91,7 +87,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState { TokenData("", tokenSymbol = it) } ), - addressData = AddressData(wallet.address, wallet.getShareUri(wallet.address), wallet.getExploreUrl()), + walletAddresses = createAddressList(wallet, newState.walletAddresses), mainButton = WalletMainButton.SendButton(false), topUpState = TopUpState(allowed = action.allowTopUp) ) @@ -172,8 +168,8 @@ private fun internalReduce(action: Action, state: AppState): WalletState { is WalletAction.ShowQrCode -> { newState = newState.copy( walletDialog = WalletDialog.QrDialog( - newState.addressData?.shareUrl?.toQrCode(), - newState.addressData?.shareUrl, + newState.walletAddresses?.selectedAddress?.shareUrl?.toQrCode(), + newState.walletAddresses?.selectedAddress?.shareUrl, newState.currencyData.currency ) ) @@ -217,10 +213,39 @@ private fun internalReduce(action: Action, state: AppState): WalletState { is WalletAction.TopUpAction -> { newState = newState.copy(topUpState = handleTopUpActions(action, newState.topUpState)) } + is WalletAction.ChangeSelectedAddress -> { + val walletAddresses = newState.walletAddresses ?: return newState + val address = walletAddresses.list.firstOrNull { it.type == action.type } ?: return newState + + newState = newState.copy(walletAddresses = WalletAddresses(address, walletAddresses.list)) + } } return newState } +fun createAddressList(wallet: Wallet?, walletAddresses: WalletAddresses? = null): WalletAddresses? { + if (wallet == null) return null + + val listOfAddressData = mutableListOf() + // put a defaultAddress at the first place + wallet.addresses.forEach { + val addressData = AddressData(it.value, it.type, wallet.getShareUri(it.value), wallet.getExploreUrl(it.value)) + if (it.type == DefaultAddressType) { + listOfAddressData.add(0, addressData) + } else { + listOfAddressData.add(addressData) + } + } + + // restore a selected wallet address + var indexOfSelectedWallet = 0 + walletAddresses?.let { + val index = listOfAddressData.indexOfFirst { it.address == walletAddresses.selectedAddress.address } + if (index != -1) indexOfSelectedWallet = index + } + return WalletAddresses(listOfAddressData[indexOfSelectedWallet], listOfAddressData) +} + private fun handleTopUpActions(action: WalletAction.TopUpAction, state: TopUpState): TopUpState { return when (action) { is WalletAction.TopUpAction.TopUp -> state diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index d6c916d79e..b55c64bbd4 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -2,7 +2,9 @@ package com.tangem.tap.features.wallet.redux import android.graphics.Bitmap import com.tangem.blockchain.common.Amount +import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Wallet +import com.tangem.blockchain.common.address.AddressType import com.tangem.tap.common.entities.Button import com.tangem.tap.common.redux.global.CryptoCurrencyName import com.tangem.tap.features.wallet.models.PendingTransaction @@ -16,7 +18,7 @@ data class WalletState( val wallet: Wallet? = null, val pendingTransactions: List = emptyList(), val hashesCountVerified: Boolean? = null, - val addressData: AddressData? = null, + val walletAddresses: WalletAddresses? = null, val currencyData: BalanceWidgetData = BalanceWidgetData(), val payIdData: PayIdData = PayIdData(), val walletDialog: WalletDialog? = null, @@ -27,6 +29,12 @@ data class WalletState( val showDetails: Boolean = currencyData.status != com.tangem.tap.features.wallet.ui.BalanceStatus.EmptyCard && currencyData.status != com.tangem.tap.features.wallet.ui.BalanceStatus.UnknownBlockchain + + val showSegwitAddress: Boolean + get() { + val listOfAddresses = walletAddresses?.list ?: return false + return wallet?.blockchain == Blockchain.Bitcoin && listOfAddresses.size > 1 + } } sealed class WalletDialog { @@ -60,8 +68,14 @@ sealed class WalletMainButton(enabled: Boolean) : Button(enabled) { class CreateWalletButton(enabled: Boolean) : WalletMainButton(enabled) } +data class WalletAddresses( + val selectedAddress: AddressData, + val list: List +) + data class AddressData( val address: String, + val type: AddressType, val shareUrl: String, val exploreUrl: String ) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index 2be04ad3c9..34057a0f6f 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -14,6 +14,8 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionInflater import com.google.android.material.snackbar.Snackbar import com.squareup.picasso.Picasso +import com.tangem.blockchain.blockchains.bitcoin.BitcoinAddressType +import com.tangem.blockchain.common.address.AddressType import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show import com.tangem.tap.common.redux.navigation.AppScreen @@ -29,6 +31,7 @@ import com.tangem.wallet.R import kotlinx.android.synthetic.main.card_balance.* import kotlinx.android.synthetic.main.fragment_wallet.* import kotlinx.android.synthetic.main.layout_address.* +import kotlinx.android.synthetic.main.layout_send_fee.* import kotlinx.android.synthetic.main.layout_wallet_long_buttons.* import kotlinx.android.synthetic.main.layout_wallet_short_buttons.* import org.rekotlin.StoreSubscriber @@ -206,9 +209,25 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber + if (checkedId == -1) return@setOnCheckedChangeListener + + SegwitUiHelper.idToType(checkedId)?.let { + store.dispatch(WalletAction.ChangeSelectedAddress(it)) + } + } + } else { + chip_group_segwit.setOnCheckedChangeListener(null) + chip_group_segwit.hide() + } + tv_address.text = state.walletAddresses.selectedAddress.address tv_explore?.setOnClickListener { store.dispatch(WalletAction.ExploreAddress(requireContext())) } @@ -285,4 +304,24 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber R.id.chip_legacy + is BitcoinAddressType.Segwit -> R.id.chip_default + else -> View.NO_ID + } + } + + fun idToType(id: Int): AddressType? { + return when (id) { + R.id.chip_default -> BitcoinAddressType.Segwit + R.id.chip_legacy -> BitcoinAddressType.Legacy + else -> null + } + } + } } \ No newline at end of file diff --git a/app/src/main/res/layout/layout_address.xml b/app/src/main/res/layout/layout_address.xml index ab3ff4955a..ecad7ebcaa 100644 --- a/app/src/main/res/layout/layout_address.xml +++ b/app/src/main/res/layout/layout_address.xml @@ -23,6 +23,38 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> + + + + + + + + + app:layout_constraintTop_toBottomOf="@id/chip_group_segwit"> + app:layout_constraintTop_toBottomOf="@id/chip_group_segwit"> + tools:text="roman$payid.tangem.com" /> diff --git a/app/src/main/res/values/strings_untranslated.xml b/app/src/main/res/values/strings_untranslated.xml index 834037ecad..fa4aa42ee7 100644 --- a/app/src/main/res/values/strings_untranslated.xml +++ b/app/src/main/res/values/strings_untranslated.xml @@ -1,3 +1,6 @@ Top Up + Default + Compatibility + Legacy diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 5c6ee06378..ae260a7854 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -51,7 +51,7 @@ @color/selector_btn_black -