diff --git a/app/build.gradle b/app/build.gradle index 09362acc3d..7a6c354f62 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -64,7 +64,7 @@ dependencies { implementation 'com.google.android.material:material:1.2.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10' - implementation 'com.tangem:blockchain:1.28.0' + implementation 'com.tangem:blockchain:1.31.0' //lifecycle implementation "androidx.lifecycle:lifecycle-runtime:2.2.0" diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt index 0544867508..268911757a 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.send.redux +import com.tangem.blockchain.common.Amount import org.rekotlin.Action /** @@ -10,6 +11,10 @@ interface SendScreenActionUi : SendScreenAction object ReleaseSendState : Action +data class PrepareSendScreen( + val amount: Amount +) : SendScreenAction + // Address or PayId sealed class AddressPayIdActionUi : SendScreenActionUi { data class ChangeAddressOrPayId(val data: String) : AddressPayIdActionUi() 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 9272568e7a..af4908547c 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 @@ -1,6 +1,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.commands.Card import com.tangem.tap.common.redux.ErrorAction @@ -39,7 +40,10 @@ sealed class WalletAction : Action { } object Scan : WalletAction() - object Send : WalletAction() + data class Send(val amount: Amount? = null) : WalletAction() { + object ChooseCurrency : WalletAction() + object Cancel : WalletAction() + } object CreatePayId : WalletAction() { data class CompleteCreatingPayId(val payId: String) : WalletAction() data class Success(val payId: String) : WalletAction() 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 3cc142d37f..6b1afaef9b 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 @@ -8,8 +8,11 @@ import com.tangem.common.CompletionResult import com.tangem.common.extensions.toHexString import com.tangem.tap.common.extensions.copyToClipboard import com.tangem.tap.common.redux.AppState +import com.tangem.tap.common.redux.navigation.AppScreen +import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.PayIdManager import com.tangem.tap.domain.TapError +import com.tangem.tap.features.send.redux.PrepareSendScreen import com.tangem.tap.network.NetworkStateChanged import com.tangem.tap.scope import com.tangem.tap.store @@ -60,7 +63,7 @@ val walletMiddleware: Middleware = { dispatch, state -> is WalletAction.CreatePayId.CompleteCreatingPayId -> { scope.launch { val cardId = store.state.globalState.scanNoteResponse?.card?.cardId - val wallet = store.state.walletState.wallet + val wallet = store.state.globalState.scanNoteResponse?.walletManager?.wallet val publicKey = store.state.globalState.scanNoteResponse?.card?.cardPublicKey if (cardId != null && wallet != null && publicKey != null) { val result = PayIdManager().setPayId( @@ -109,7 +112,23 @@ val walletMiddleware: Middleware = { dispatch, state -> val intent = Intent(Intent.ACTION_VIEW, uri) ContextCompat.startActivity(action.context, intent, null) } - + is WalletAction.Send -> { + if (action.amount != null) { + store.dispatch(PrepareSendScreen(action.amount)) + store.dispatch(NavigationAction.NavigateTo(AppScreen.Send)) + } else { + if (store.state.walletState.wallet?.amounts?.size ?: 0 > 1) { + store.dispatch(WalletAction.Send.ChooseCurrency) + } else { + val amount = store.state.walletState.wallet?.amounts?.toList() + ?.get(0)?.second + if (amount != null) { + store.dispatch(PrepareSendScreen(amount)) + store.dispatch(NavigationAction.NavigateTo(AppScreen.Send)) + } + } + } + } } next(action) } 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 29f7740272..f0b29211a5 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 @@ -153,17 +153,19 @@ private fun internalReduce(action: Action, state: AppState): WalletState { token = newState.currencyData.token?.copy(fiatAmount = tokenFiatAmount) )) } -// is WalletAction.LoadArtwork -> { -// newState = newState.copy(cardImage = null) -// } is WalletAction.LoadArtwork.Success -> { newState = newState.copy(cardImage = Artwork(action.artworkId, action.artwork.toBitmap())) } is WalletAction.ShowQrCode -> { - newState = newState.copy(qrCode = newState.addressData?.shareUrl?.toQrCode()) + newState = newState.copy( + walletDialog = WalletDialog.QrDialog( + newState.addressData?.shareUrl?.toQrCode(), + newState.addressData?.shareUrl + ) + ) } is WalletAction.HideQrCode -> { - newState = newState.copy(qrCode = null) + newState = newState.copy(walletDialog = null) } is WalletAction.LoadPayId.Success -> newState = newState.copy( payIdData = PayIdData(PayIdState.Created, action.payId) @@ -172,17 +174,25 @@ private fun internalReduce(action: Action, state: AppState): WalletState { payIdData = PayIdData(PayIdState.NotCreated, null) ) is WalletAction.CreatePayId, is WalletAction.CreatePayId.Failure -> - newState = newState.copy(creatingPayIdState = CreatingPayIdState.EnterPayId) + newState = newState.copy( + walletDialog = WalletDialog.CreatePayIdDialog(CreatingPayIdState.EnterPayId) + ) is WalletAction.CreatePayId.CompleteCreatingPayId -> newState = newState.copy( - creatingPayIdState = CreatingPayIdState.Waiting + walletDialog = WalletDialog.CreatePayIdDialog(CreatingPayIdState.Waiting) ) is WalletAction.CreatePayId.Success -> newState = newState.copy( payIdData = PayIdData(PayIdState.Created, action.payId), - creatingPayIdState = null - ) - is WalletAction.CreatePayId.Cancel -> newState = newState.copy( - creatingPayIdState = null + walletDialog = null ) + is WalletAction.CreatePayId.Cancel -> newState = newState.copy(walletDialog = null) + is WalletAction.Send.ChooseCurrency -> { + val amounts = newState.wallet?.amounts?.toList()?.unzip()?.second + newState = newState.copy( + walletDialog = WalletDialog.SelectAmountToSendDialog(amounts) + ) + } + is WalletAction.Send.Cancel -> newState = newState.copy(walletDialog = null) + } return newState } \ No newline at end of file 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 120ab1a281..90de886e55 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 @@ -1,6 +1,7 @@ package com.tangem.tap.features.wallet.redux import android.graphics.Bitmap +import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.Wallet import com.tangem.tap.common.entities.Button import com.tangem.tap.features.wallet.models.PendingTransaction @@ -16,11 +17,16 @@ data class WalletState( val addressData: AddressData? = null, val currencyData: BalanceWidgetData = BalanceWidgetData(), val payIdData: PayIdData = PayIdData(), - val qrCode: Bitmap? = null, - val creatingPayIdState: CreatingPayIdState? = null, + val walletDialog: WalletDialog? = null, val mainButton: WalletMainButton = WalletMainButton.SendButton(false) ) : StateType +sealed class WalletDialog { + data class QrDialog(val qrCode: Bitmap?, val shareUrl: String?) : WalletDialog() + data class CreatePayIdDialog(val creatingPayIdState: CreatingPayIdState?) : WalletDialog() + data class SelectAmountToSendDialog(val amounts: List?) : WalletDialog() +} + enum class ProgressState { Loading, Done, Error } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/PendingTransactionsAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/PendingTransactionsAdapter.kt index d6b3f66f7f..ef5f765188 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/PendingTransactionsAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/PendingTransactionsAdapter.kt @@ -10,14 +10,14 @@ import com.tangem.tap.common.extensions.getDrawableCompat import com.tangem.tap.features.wallet.models.PendingTransaction import com.tangem.tap.features.wallet.models.PendingTransactionType import com.tangem.wallet.R -import kotlinx.android.synthetic.main.layout_pending_transaction.view.* +import kotlinx.android.synthetic.main.item_pending_transaction.view.* class PendingTransactionsAdapter : ListAdapter(DiffUtilCallback) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionsViewHolder { val layout = LayoutInflater.from(parent.context) - .inflate(R.layout.layout_pending_transaction, parent, false) + .inflate(R.layout.item_pending_transaction, parent, false) return TransactionsViewHolder(layout) } @@ -26,8 +26,6 @@ class PendingTransactionsAdapter } object DiffUtilCallback : DiffUtil.ItemCallback() { - - override fun areContentsTheSame( oldItem: PendingTransaction, newItem: PendingTransaction ) = oldItem == newItem @@ -35,7 +33,6 @@ class PendingTransactionsAdapter override fun areItemsTheSame( oldItem: PendingTransaction, newItem: PendingTransaction ) = oldItem == newItem - } @@ -58,5 +55,4 @@ class PendingTransactionsAdapter view.iv_pending_transaction.setImageDrawable(view.context.getDrawableCompat(image)) } } - } \ No newline at end of file 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 598760abbd..d461023e6d 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 @@ -1,5 +1,6 @@ package com.tangem.tap.features.wallet.ui +import android.app.Dialog import android.graphics.Bitmap import android.os.Bundle import android.view.View @@ -11,9 +12,11 @@ import com.google.android.material.snackbar.Snackbar import com.tangem.tap.common.extensions.getDrawable import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show -import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.wallet.redux.* +import com.tangem.tap.features.wallet.ui.dialogs.AmountToSendDialog +import com.tangem.tap.features.wallet.ui.dialogs.PayIdDialog +import com.tangem.tap.features.wallet.ui.dialogs.QrDialog import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.card_balance.* @@ -24,8 +27,7 @@ import org.rekotlin.StoreSubscriber class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber { - private var qrDialog: QrDialog? = null - private var payIdDialog: PayIdDialog? = null + private var dialog: Dialog? = null private var snackbar: Snackbar? = null private lateinit var viewAdapter: PendingTransactionsAdapter @@ -93,12 +95,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber { } } - - when (state.creatingPayIdState) { - CreatingPayIdState.EnterPayId -> { - if (payIdDialog == null) payIdDialog = PayIdDialog(requireContext()) - payIdDialog?.show() - payIdDialog?.stopProgress() - } - CreatingPayIdState.Waiting -> payIdDialog?.showProgress() - null -> { - payIdDialog?.dismiss() - payIdDialog = null - } - } } private fun setupNoInternetHandling(state: WalletState) { @@ -169,7 +153,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber store.dispatch(NavigationAction.NavigateTo(AppScreen.Send)) + is WalletMainButton.SendButton -> store.dispatch(WalletAction.Send()) is WalletMainButton.CreateWalletButton -> store.dispatch(WalletAction.CreateWallet) } } @@ -195,4 +179,36 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber { + if (walletDialog.qrCode != null && walletDialog.shareUrl != null) { + if (dialog == null) dialog = QrDialog(requireContext()).apply { + this.showQr(walletDialog.qrCode, walletDialog.shareUrl) + } + } + } + is WalletDialog.CreatePayIdDialog -> { + when (walletDialog.creatingPayIdState) { + CreatingPayIdState.EnterPayId -> { + if (dialog == null) dialog = PayIdDialog(requireContext()).apply { + this.show() + this.stopProgress() + } + } + CreatingPayIdState.Waiting -> (dialog as? PayIdDialog)?.showProgress() + } + } + is WalletDialog.SelectAmountToSendDialog -> { + if (dialog == null) dialog = AmountToSendDialog(requireContext()).apply { + this.show(walletDialog.amounts) + } + } + null -> { + dialog?.dismiss() + dialog = null + } + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/AmountToSendDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/AmountToSendDialog.kt new file mode 100644 index 0000000000..0175d55b59 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/AmountToSendDialog.kt @@ -0,0 +1,82 @@ +package com.tangem.tap.features.wallet.ui.dialogs + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.view.ContextThemeWrapper +import androidx.recyclerview.widget.* +import com.google.android.material.bottomsheet.BottomSheetDialog +import com.tangem.blockchain.common.Amount +import com.tangem.tap.common.extensions.toFormattedString +import com.tangem.tap.features.wallet.redux.WalletAction +import com.tangem.tap.store +import com.tangem.wallet.R +import kotlinx.android.synthetic.main.dialog_wallet_send.* +import kotlinx.android.synthetic.main.item_wallet_amount_to_send.view.* + + +class AmountToSendDialog(context: Context) : BottomSheetDialog(context) { + + init { + this.setContentView(R.layout.dialog_wallet_send) + } + + fun show(amounts: List?) { + this.setOnDismissListener { + store.dispatch(WalletAction.Send.Cancel) + } + + rv_amounts_to_send.layoutManager = LinearLayoutManager(context) + val dividerItemDecoration = DividerItemDecoration( + ContextThemeWrapper(rv_amounts_to_send.context, R.style.AppTheme), + DividerItemDecoration.VERTICAL + ) + rv_amounts_to_send.addItemDecoration(dividerItemDecoration) + + val viewAdapter = ChooseAmountAdapter() + rv_amounts_to_send.adapter = viewAdapter + + viewAdapter.submitList(amounts) + + show() + } +} + + +class ChooseAmountAdapter + : ListAdapter(DiffUtilCallback) { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AmountViewHolder { + val layout = LayoutInflater.from(parent.context) + .inflate(R.layout.item_wallet_amount_to_send, parent, false) + return AmountViewHolder(layout) + } + + override fun onBindViewHolder(holder: AmountViewHolder, position: Int) { + holder.bind(currentList[position]) + } + + object DiffUtilCallback : DiffUtil.ItemCallback() { + override fun areContentsTheSame( + oldItem: Amount, newItem: Amount + ) = oldItem.currencySymbol == newItem.currencySymbol + + override fun areItemsTheSame( + oldItem: Amount, newItem: Amount + ) = oldItem == newItem + } + + class AmountViewHolder(val view: View) : + RecyclerView.ViewHolder(view) { + + fun bind(amount: Amount) { + view.tv_currency_symbol.text = amount.currencySymbol + view.tv_amount.text = amount.value?.toFormattedString(amount.decimals) + view.setOnClickListener { + store.dispatch(WalletAction.Send.Cancel) + store.dispatch(WalletAction.Send(amount)) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/PayIdDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/PayIdDialog.kt similarity index 96% rename from app/src/main/java/com/tangem/tap/features/wallet/ui/PayIdDialog.kt rename to app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/PayIdDialog.kt index 641504a3ae..024d185db0 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/PayIdDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/PayIdDialog.kt @@ -1,4 +1,4 @@ -package com.tangem.tap.features.wallet.ui +package com.tangem.tap.features.wallet.ui.dialogs import android.app.Dialog import android.content.Context diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/QrDialog.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/QrDialog.kt similarity index 93% rename from app/src/main/java/com/tangem/tap/features/wallet/ui/QrDialog.kt rename to app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/QrDialog.kt index 6d9f968fea..2c553f3614 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/QrDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/dialogs/QrDialog.kt @@ -1,4 +1,4 @@ -package com.tangem.tap.features.wallet.ui +package com.tangem.tap.features.wallet.ui.dialogs import android.app.Dialog import android.content.Context diff --git a/app/src/main/res/drawable/ic_baseline_error_outline_24.xml b/app/src/main/res/drawable/ic_baseline_error_outline_24.xml deleted file mode 100644 index 48ed5abadf..0000000000 --- a/app/src/main/res/drawable/ic_baseline_error_outline_24.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/layout/dialog_wallet_send.xml b/app/src/main/res/layout/dialog_wallet_send.xml new file mode 100644 index 0000000000..2fa54ef3d3 --- /dev/null +++ b/app/src/main/res/layout/dialog_wallet_send.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_pending_transaction.xml b/app/src/main/res/layout/item_pending_transaction.xml similarity index 100% rename from app/src/main/res/layout/layout_pending_transaction.xml rename to app/src/main/res/layout/item_pending_transaction.xml diff --git a/app/src/main/res/layout/item_wallet_amount_to_send.xml b/app/src/main/res/layout/item_wallet_amount_to_send.xml new file mode 100644 index 0000000000..c225c828e4 --- /dev/null +++ b/app/src/main/res/layout/item_wallet_amount_to_send.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_balance.xml b/app/src/main/res/layout/layout_balance.xml index 5fbdf694c6..44f29b2399 100644 --- a/app/src/main/res/layout/layout_balance.xml +++ b/app/src/main/res/layout/layout_balance.xml @@ -68,9 +68,9 @@