diff options
author | Torsten Grote <t@grobox.de> | 2020-02-17 15:15:11 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2020-02-17 15:15:11 -0300 |
commit | 5522993ea436e1fb0eaec98b412fc97203bfd899 (patch) | |
tree | 566318804680b6726f26f80437b24c0d0ff061e7 /app/src/main/java | |
parent | 6f022dd8d9f14f9b52a8ca6d2b76c5ebb5286588 (diff) | |
download | wallet-android-5522993ea436e1fb0eaec98b412fc97203bfd899.tar.gz wallet-android-5522993ea436e1fb0eaec98b412fc97203bfd899.tar.bz2 wallet-android-5522993ea436e1fb0eaec98b412fc97203bfd899.zip |
Redesign payment screen
This uses a slightly different layout in landscape mode
and doesn't lock the QR code scanning orientation to fix orientation
detection which sometimes uses a wrong layout.
Diffstat (limited to 'app/src/main/java')
8 files changed, 105 insertions, 55 deletions
diff --git a/app/src/main/java/net/taler/wallet/MainActivity.kt b/app/src/main/java/net/taler/wallet/MainActivity.kt index e9b00f6..b2e716e 100644 --- a/app/src/main/java/net/taler/wallet/MainActivity.kt +++ b/app/src/main/java/net/taler/wallet/MainActivity.kt @@ -31,7 +31,8 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout import androidx.lifecycle.Observer -import androidx.navigation.findNavController +import androidx.navigation.NavController +import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.setupWithNavController import com.google.android.material.navigation.NavigationView.OnNavigationItemSelectedListener @@ -48,13 +49,12 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener, private val model: WalletViewModel by viewModels() + private lateinit var nav: NavController + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) - nav_view.menu.getItem(0).isChecked = true - nav_view.setNavigationItemSelectedListener(this) - fab.setOnClickListener { val integrator = IntentIntegrator(this) integrator.setPrompt("Place merchant's QR Code inside the viewfinder rectangle to initiate payment.") @@ -62,13 +62,17 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener, } fab.hide() - setSupportActionBar(toolbar) - val navController = findNavController(R.id.nav_host_fragment) - val appBarConfiguration = AppBarConfiguration( - setOf(R.id.showBalance, R.id.settings, R.id.walletHistory), - drawer_layout - ) - toolbar.setupWithNavController(navController, appBarConfiguration) + val navHostFragment = + supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment + nav = navHostFragment.navController + nav_view.setupWithNavController(nav) + nav_view.setNavigationItemSelectedListener(this) + if (savedInstanceState == null) { + nav_view.menu.getItem(0).isChecked = true + } + + val appBarConfiguration = AppBarConfiguration(nav.graph, drawer_layout) + toolbar.setupWithNavController(nav, appBarConfiguration) model.init() model.getBalances() @@ -81,13 +85,13 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener, registerReceiver(object : BroadcastReceiver() { override fun onReceive(p0: Context?, p1: Intent?) { - if (navController.currentDestination?.id == R.id.promptPayment) { + if (nav.currentDestination?.id == R.id.promptPayment) { return } val url = p1!!.extras!!.get("contractUrl") as String - findNavController(R.id.nav_host_fragment).navigate(R.id.action_global_promptPayment) + nav.navigate(R.id.action_global_promptPayment) model.paymentManager.preparePay(url) } @@ -156,13 +160,13 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener, // Handle navigation view item clicks here. when (item.itemId) { R.id.nav_home -> { - findNavController(R.id.nav_host_fragment).navigate(R.id.showBalance) + nav.navigate(R.id.showBalance) } R.id.nav_settings -> { - findNavController(R.id.nav_host_fragment).navigate(R.id.settings) + nav.navigate(R.id.settings) } R.id.nav_history -> { - findNavController(R.id.nav_host_fragment).navigate(R.id.walletHistory) + nav.navigate(R.id.walletHistory) } } val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout) @@ -176,7 +180,8 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener, return } - val scanResult: IntentResult? = IntentIntegrator.parseActivityResult(requestCode, resultCode, data) + val scanResult: IntentResult? = + IntentIntegrator.parseActivityResult(requestCode, resultCode, data) if (scanResult == null || scanResult.contents == null) { Snackbar.make(nav_view, "QR Code scan canceled.", LENGTH_SHORT).show() @@ -191,12 +196,12 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener, when { url.toLowerCase(ROOT).startsWith("taler://pay/") -> { Log.v(TAG, "navigating!") - findNavController(R.id.nav_host_fragment).navigate(R.id.action_showBalance_to_promptPayment) + nav.navigate(R.id.action_showBalance_to_promptPayment) model.paymentManager.preparePay(url) } url.toLowerCase(ROOT).startsWith("taler://withdraw/") -> { Log.v(TAG, "navigating!") - findNavController(R.id.nav_host_fragment).navigate(R.id.action_showBalance_to_promptWithdraw) + nav.navigate(R.id.action_showBalance_to_promptWithdraw) model.getWithdrawalInfo(url) } url.toLowerCase(ROOT).startsWith("taler://refund/") -> { diff --git a/app/src/main/java/net/taler/wallet/ShowBalance.kt b/app/src/main/java/net/taler/wallet/ShowBalance.kt index 7ff5bfe..b9e52ff 100644 --- a/app/src/main/java/net/taler/wallet/ShowBalance.kt +++ b/app/src/main/java/net/taler/wallet/ShowBalance.kt @@ -36,6 +36,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.snackbar.Snackbar import com.google.zxing.integration.android.IntentIntegrator +import com.google.zxing.integration.android.IntentIntegrator.QR_CODE_TYPES import me.zhanghai.android.materialprogressbar.MaterialProgressBar import org.json.JSONObject @@ -244,9 +245,10 @@ class ShowBalance : Fragment(), PendingOperationClickListener { val view = inflater.inflate(R.layout.fragment_show_balance, container, false) val payQrButton = view.findViewById<Button>(R.id.button_pay_qr) payQrButton.setOnClickListener { - val integrator = IntentIntegrator(activity) - integrator.setPrompt("Place merchant's QR Code inside the viewfinder rectangle to initiate payment.") - integrator.initiateScan(listOf("QR_CODE")) + IntentIntegrator(activity).apply { + setBeepEnabled(true) + setOrientationLocked(false) + }.initiateScan(QR_CODE_TYPES) } this.balancesView = view.findViewById(R.id.list_balances) @@ -321,8 +323,11 @@ class ShowBalance : Fragment(), PendingOperationClickListener { when (type) { "proposal-choice" -> { Log.v(TAG, "got action click on proposal-choice") - val json = detail.toString(4) - throw IllegalStateException("proposal-choice wasn't aborted automatically: $json") + val proposalId = detail.optString("proposalId", "") + if (proposalId == "") { + return + } + model.paymentManager.abortProposal(proposalId) } } } diff --git a/app/src/main/java/net/taler/wallet/Utils.kt b/app/src/main/java/net/taler/wallet/Utils.kt new file mode 100644 index 0000000..673fa2b --- /dev/null +++ b/app/src/main/java/net/taler/wallet/Utils.kt @@ -0,0 +1,35 @@ +/* + * This file is part of GNU Taler + * (C) 2020 Taler Systems S.A. + * + * GNU Taler is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3, or (at your option) any later version. + * + * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +package net.taler.wallet + +import android.view.View +import android.view.View.INVISIBLE +import android.view.View.VISIBLE + +fun View.fadeIn() { + alpha = 0f + visibility = VISIBLE + animate().alpha(1f).start() +} + +fun View.fadeOut() { + if (visibility == INVISIBLE) return + animate().alpha(0f).withEndAction { + visibility = INVISIBLE + alpha = 1f + }.start() +} diff --git a/app/src/main/java/net/taler/wallet/WithdrawSuccessful.kt b/app/src/main/java/net/taler/wallet/WithdrawSuccessful.kt index bb2abac..4ff7478 100644 --- a/app/src/main/java/net/taler/wallet/WithdrawSuccessful.kt +++ b/app/src/main/java/net/taler/wallet/WithdrawSuccessful.kt @@ -34,7 +34,7 @@ class WithdrawSuccessful : Fragment() { savedInstanceState: Bundle? ): View? { val view = inflater.inflate(R.layout.fragment_withdraw_successful, container, false) - view.findViewById<Button>(R.id.button_success_back).setOnClickListener { + view.findViewById<Button>(R.id.backButton).setOnClickListener { activity!!.findNavController(R.id.nav_host_fragment).navigateUp() } return view diff --git a/app/src/main/java/net/taler/wallet/payment/AlreadyPaidFragment.kt b/app/src/main/java/net/taler/wallet/payment/AlreadyPaidFragment.kt index b1abbf2..33e3a1d 100644 --- a/app/src/main/java/net/taler/wallet/payment/AlreadyPaidFragment.kt +++ b/app/src/main/java/net/taler/wallet/payment/AlreadyPaidFragment.kt @@ -39,7 +39,7 @@ class AlreadyPaidFragment : Fragment() { } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - button_success_back.setOnClickListener { + backButton.setOnClickListener { findNavController().navigateUp() } } diff --git a/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt b/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt index 5ddd5fa..a00a686 100644 --- a/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt +++ b/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt @@ -106,7 +106,7 @@ class PaymentManager( resetPayStatus() } - private fun abortProposal(proposalId: String) { + internal fun abortProposal(proposalId: String) { val args = JSONObject(mapOf("proposalId" to proposalId)) Log.i(TAG, "aborting proposal") diff --git a/app/src/main/java/net/taler/wallet/payment/PaymentSuccessfulFragment.kt b/app/src/main/java/net/taler/wallet/payment/PaymentSuccessfulFragment.kt index 54b9b8d..2084c45 100644 --- a/app/src/main/java/net/taler/wallet/payment/PaymentSuccessfulFragment.kt +++ b/app/src/main/java/net/taler/wallet/payment/PaymentSuccessfulFragment.kt @@ -24,6 +24,7 @@ import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController import kotlinx.android.synthetic.main.fragment_payment_successful.* import net.taler.wallet.R +import net.taler.wallet.fadeIn /** * Fragment that shows the success message for a payment. @@ -38,7 +39,9 @@ class PaymentSuccessfulFragment : Fragment() { } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - button_success_back.setOnClickListener { + successImageView.fadeIn() + successTextView.fadeIn() + backButton.setOnClickListener { findNavController().navigateUp() } } diff --git a/app/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt b/app/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt index 754a43e..2f7807a 100644 --- a/app/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt +++ b/app/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt @@ -21,7 +21,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.View.GONE -import android.view.View.INVISIBLE import android.view.View.VISIBLE import android.view.ViewGroup import androidx.fragment.app.Fragment @@ -31,10 +30,13 @@ import androidx.lifecycle.observe import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionManager.beginDelayedTransition -import kotlinx.android.synthetic.main.fragment_prompt_payment.* +import kotlinx.android.synthetic.main.payment_bottom_bar.* +import kotlinx.android.synthetic.main.payment_details.* import net.taler.wallet.Amount import net.taler.wallet.R import net.taler.wallet.WalletViewModel +import net.taler.wallet.fadeIn +import net.taler.wallet.fadeOut /** * Show a payment and ask the user to accept/decline. @@ -69,7 +71,7 @@ class PromptPaymentFragment : Fragment() { layoutManager = LinearLayoutManager(requireContext()) } - button_abort_payment.setOnClickListener { + abortButton.setOnClickListener { paymentManager.abortPay() findNavController().navigateUp() } @@ -84,6 +86,11 @@ class PromptPaymentFragment : Fragment() { private fun showLoading(show: Boolean) { model.showProgressBar.value = show + if (show) { + progressBar.fadeIn() + } else { + progressBar.fadeOut() + } } private fun onPaymentStatusChanged(payStatus: PayStatus) { @@ -91,18 +98,19 @@ class PromptPaymentFragment : Fragment() { is PayStatus.Prepared -> { showLoading(false) showOrder(payStatus.contractTerms, payStatus.totalFees) - button_confirm_payment.isEnabled = true - button_confirm_payment.setOnClickListener { - showLoading(true) + confirmButton.isEnabled = true + confirmButton.setOnClickListener { + model.showProgressBar.value = true paymentManager.confirmPay(payStatus.proposalId) - button_confirm_payment.isEnabled = false + confirmButton.fadeOut() + confirmProgressBar.fadeIn() } } is PayStatus.InsufficientBalance -> { showLoading(false) showOrder(payStatus.contractTerms, null) - error_text.setText(R.string.payment_balance_insufficient) - fadeInView(error_text) + errorView.setText(R.string.payment_balance_insufficient) + errorView.fadeIn() } is PayStatus.Success -> { showLoading(false) @@ -116,8 +124,8 @@ class PromptPaymentFragment : Fragment() { } is PayStatus.Error -> { showLoading(false) - error_text.text = getString(R.string.payment_error, payStatus.error) - fadeInView(error_text) + errorView.text = getString(R.string.payment_error, payStatus.error) + errorView.fadeIn() } is PayStatus.None -> { // No payment active. @@ -131,29 +139,23 @@ class PromptPaymentFragment : Fragment() { } private fun showOrder(contractTerms: ContractTerms, totalFees: Amount?) { - order_summary.text = contractTerms.summary + orderView.text = contractTerms.summary adapter.setItems(contractTerms.products) val amount = contractTerms.amount @SuppressLint("SetTextI18n") - order_amount.text = "${amount.amount} ${amount.currency}" + totalView.text = "${amount.amount} ${amount.currency}" if (totalFees != null && !totalFees.isZero()) { val fee = "${totalFees.amount} ${totalFees.currency}" - order_fees_amount.text = getString(R.string.payment_fee, fee) - fadeInView(order_fees_amount) + feeView.text = getString(R.string.payment_fee, fee) + feeView.fadeIn() } else { - order_fees_amount.visibility = INVISIBLE + feeView.visibility = GONE } - fadeInView(order_summary_label) - fadeInView(order_summary) - if (contractTerms.products.isNotEmpty()) fadeInView(detailsButton) - fadeInView(order_amount_label) - fadeInView(order_amount) - } - - private fun fadeInView(v: View) { - v.alpha = 0f - v.visibility = VISIBLE - v.animate().alpha(1f).start() + orderLabelView.fadeIn() + orderView.fadeIn() + if (contractTerms.products.isNotEmpty()) detailsButton.fadeIn() + totalLabelView.fadeIn() + totalView.fadeIn() } } |