gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-cashier-terminal-android] 05/06: Add app logo and optimize UX wor


From: gnunet
Subject: [taler-cashier-terminal-android] 05/06: Add app logo and optimize UX workflow
Date: Wed, 19 Feb 2020 21:31:59 +0100

This is an automated email from the git hooks/post-receive script.

torsten-grote pushed a commit to branch master
in repository cashier-terminal-android.

commit 2f7eb8ad573b26e244ec17173abe98218bee39eb
Author: Torsten Grote <address@hidden>
AuthorDate: Wed Feb 19 15:33:07 2020 -0300

    Add app logo and optimize UX workflow
---
 app/build.gradle                                   |   2 +-
 app/src/main/ic_launcher-web.png                   | Bin 0 -> 30434 bytes
 .../main/java/net/taler/cashier/BalanceFragment.kt |  87 ++++++++-
 .../main/java/net/taler/cashier/MainViewModel.kt   |  16 +-
 app/src/main/java/net/taler/cashier/Utils.kt       |   1 +
 .../net/taler/cashier/withdraw/ErrorFragment.kt    |  10 +-
 .../java/net/taler/cashier/withdraw/NfcManager.kt  |  17 +-
 .../net/taler/cashier/withdraw/SuccessFragment.kt  |  33 ----
 .../taler/cashier/withdraw/TransactionFragment.kt  |  50 ++++--
 .../net/taler/cashier/withdraw/WithdrawFragment.kt |  79 ---------
 .../net/taler/cashier/withdraw/WithdrawManager.kt  |  88 +++++++---
 app/src/main/res/drawable-w550dp/ic_arrow.xml      |  11 ++
 app/src/main/res/drawable/ic_arrow.xml             |  11 ++
 app/src/main/res/drawable/ic_check_circle.xml      |   1 -
 .../main/res/drawable/ic_launcher_foreground.xml   |  13 ++
 .../main/res/layout-w550dp/fragment_balance.xml    | 195 +++++++++++++++++++++
 .../res/layout-w550dp/fragment_transaction.xml     |  21 ++-
 app/src/main/res/layout/activity_main.xml          |   4 +-
 app/src/main/res/layout/fragment_balance.xml       | 127 +++++++++++++-
 app/src/main/res/layout/fragment_error.xml         |   2 +-
 app/src/main/res/layout/fragment_success.xml       |  49 ------
 app/src/main/res/layout/fragment_transaction.xml   |  18 +-
 app/src/main/res/layout/fragment_withdraw.xml      | 105 -----------
 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml |   5 +
 .../res/mipmap-anydpi-v26/ic_launcher_round.xml    |   5 +
 app/src/main/res/mipmap-hdpi/ic_launcher.png       | Bin 0 -> 3687 bytes
 app/src/main/res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 3687 bytes
 app/src/main/res/mipmap-mdpi/ic_launcher.png       | Bin 0 -> 2408 bytes
 app/src/main/res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2408 bytes
 app/src/main/res/mipmap-xhdpi/ic_launcher.png      | Bin 0 -> 4875 bytes
 .../main/res/mipmap-xhdpi/ic_launcher_round.png    | Bin 0 -> 4875 bytes
 app/src/main/res/mipmap-xxhdpi/ic_launcher.png     | Bin 0 -> 7673 bytes
 .../main/res/mipmap-xxhdpi/ic_launcher_round.png   | Bin 0 -> 7673 bytes
 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png    | Bin 0 -> 10362 bytes
 .../main/res/mipmap-xxxhdpi/ic_launcher_round.png  | Bin 0 -> 10362 bytes
 app/src/main/res/navigation/nav_graph.xml          |  35 +---
 app/src/main/res/values/colors.xml                 |   2 +-
 app/src/main/res/values/ic_launcher_background.xml |   4 +
 app/src/main/res/values/strings.xml                |  14 +-
 app/src/main/res/values/styles.xml                 |   8 +-
 artwork/ic_bottom_left.svg                         |  56 ++++++
 artwork/ic_bottom_right.svg                        |  56 ++++++
 artwork/ic_launcher.svg                            |  55 ++++++
 43 files changed, 797 insertions(+), 383 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index 217ad35..bc3e2ed 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -35,7 +35,7 @@ dependencies {
     implementation 'androidx.core:core-ktx:1.2.0'
     implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
     implementation 'androidx.security:security-crypto:1.0.0-alpha02'
-    implementation 'com.google.android.material:material:1.2.0-alpha04'
+    implementation 'com.google.android.material:material:1.1.0'
 
     implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
     implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png
new file mode 100644
index 0000000..04a58c6
Binary files /dev/null and b/app/src/main/ic_launcher-web.png differ
diff --git a/app/src/main/java/net/taler/cashier/BalanceFragment.kt 
b/app/src/main/java/net/taler/cashier/BalanceFragment.kt
index 50e8488..13274f5 100644
--- a/app/src/main/java/net/taler/cashier/BalanceFragment.kt
+++ b/app/src/main/java/net/taler/cashier/BalanceFragment.kt
@@ -6,17 +6,22 @@ import android.view.Menu
 import android.view.MenuInflater
 import android.view.MenuItem
 import android.view.View
-import android.view.View.INVISIBLE
+import android.view.View.VISIBLE
 import android.view.ViewGroup
+import android.view.inputmethod.EditorInfo
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
 import androidx.lifecycle.Observer
 import androidx.navigation.fragment.findNavController
 import kotlinx.android.synthetic.main.fragment_balance.*
+import 
net.taler.cashier.BalanceFragmentDirections.Companion.actionBalanceFragmentToTransactionFragment
+import net.taler.cashier.withdraw.LastTransaction
+import net.taler.cashier.withdraw.WithdrawStatus
 
 class BalanceFragment : Fragment() {
 
     private val viewModel: MainViewModel by activityViewModels()
+    private val withdrawManager by lazy { viewModel.withdrawManager }
 
     override fun onCreateView(
         inflater: LayoutInflater, container: ViewGroup?,
@@ -27,16 +32,35 @@ class BalanceFragment : Fragment() {
     }
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        withdrawManager.lastTransaction.observe(viewLifecycleOwner, Observer { 
lastTransaction ->
+            onLastTransaction(lastTransaction)
+        })
         viewModel.balance.observe(viewLifecycleOwner, Observer { balance ->
             balanceView.text = balance
-            progressBar.visibility = INVISIBLE
+            val fadeIn =
+                listOf(introView, button5, button10, button20, button50, 
amountView, currencyView)
+            for (v in fadeIn) v.fadeIn()
             fab.show()
+            progressBar.fadeOut()
         })
-        fab.setOnClickListener {
-            
BalanceFragmentDirections.actionBalanceFragmentToWithdrawFragment().let {
-                findNavController().navigate(it)
-            }
+        button5.setOnClickListener { onAmountButtonPressed(5) }
+        button10.setOnClickListener { onAmountButtonPressed(10) }
+        button20.setOnClickListener { onAmountButtonPressed(20) }
+        button50.setOnClickListener { onAmountButtonPressed(50) }
+
+        if (savedInstanceState != null) {
+            
amountView.editText!!.setText(savedInstanceState.getCharSequence("amountView"))
+        }
+        amountView.editText!!.setOnEditorActionListener { _, actionId, _ ->
+            if (actionId == EditorInfo.IME_ACTION_GO) {
+                onAmountConfirmed(getAmountFromView())
+                true
+            } else false
         }
+        viewModel.currency.observe(viewLifecycleOwner, Observer { currency ->
+            currencyView.text = currency
+        })
+        fab.setOnClickListener { onAmountConfirmed(getAmountFromView()) }
     }
 
     override fun onStart() {
@@ -47,6 +71,14 @@ class BalanceFragment : Fragment() {
         }
     }
 
+    override fun onSaveInstanceState(outState: Bundle) {
+        super.onSaveInstanceState(outState)
+        // for some reason automatic restore isn't working at the moment!?
+        amountView?.editText?.text.let {
+            outState.putCharSequence("amountView", it)
+        }
+    }
+
     override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
         inflater.inflate(R.menu.balance, menu)
         super.onCreateOptionsMenu(menu, inflater)
@@ -65,4 +97,47 @@ class BalanceFragment : Fragment() {
         else -> super.onOptionsItemSelected(item)
     }
 
+    private fun onAmountButtonPressed(amount: Int) {
+        amountView.editText!!.setText(amount.toString())
+        amountView.error = null
+    }
+
+    private fun getAmountFromView(): Int {
+        val str = amountView.editText!!.text.toString()
+        if (str.isBlank()) return 0
+        return Integer.parseInt(str)
+    }
+
+    private fun onAmountConfirmed(amount: Int) {
+        if (amount <= 0) {
+            amountView.error = getString(R.string.withdraw_error_zero)
+        } else if (!withdrawManager.hasSufficientBalance(amount)) {
+            amountView.error = 
getString(R.string.withdraw_error_insufficient_balance)
+        } else {
+            amountView.error = null
+            withdrawManager.withdraw(amount)
+            actionBalanceFragmentToTransactionFragment().let {
+                findNavController().navigate(it)
+            }
+        }
+    }
+
+    private fun onLastTransaction(lastTransaction: LastTransaction?) {
+        val status = lastTransaction?.withdrawStatus
+        val text = when (status) {
+            is WithdrawStatus.Success -> getString(
+                R.string.transaction_last_success, 
lastTransaction.withdrawAmount
+            )
+            is WithdrawStatus.Aborted -> 
getString(R.string.transaction_last_aborted)
+            else -> getString(R.string.transaction_last_error)
+        }
+        lastTransactionView.text = text
+        val drawable = if (status == WithdrawStatus.Success)
+            R.drawable.ic_check_circle
+        else
+            R.drawable.ic_error
+        
lastTransactionView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable, 
0, 0, 0)
+        lastTransactionView.visibility = VISIBLE
+    }
+
 }
diff --git a/app/src/main/java/net/taler/cashier/MainViewModel.kt 
b/app/src/main/java/net/taler/cashier/MainViewModel.kt
index b3b1184..2ef7a09 100644
--- a/app/src/main/java/net/taler/cashier/MainViewModel.kt
+++ b/app/src/main/java/net/taler/cashier/MainViewModel.kt
@@ -43,8 +43,10 @@ class MainViewModel(private val app: Application) : 
AndroidViewModel(app) {
         password = prefs.getString(PREF_KEY_PASSWORD, "")!!
     )
 
-    internal var currency: String = prefs.getString(PREF_KEY_CURRENCY, 
"TESTKUDOS")!!
-        private set
+    private val mCurrency = MutableLiveData<String>(
+        prefs.getString(PREF_KEY_CURRENCY, null)
+    )
+    internal val currency: LiveData<String> = mCurrency
 
     private val mConfigResult = MutableLiveData<ConfigResult>()
     val configResult: LiveData<ConfigResult> = mConfigResult
@@ -52,8 +54,7 @@ class MainViewModel(private val app: Application) : 
AndroidViewModel(app) {
     private val mBalance = MutableLiveData<String>()
     val balance: LiveData<String> = mBalance
 
-    internal val withdrawManager =
-        WithdrawManager(app, this)
+    internal val withdrawManager = WithdrawManager(app, this)
 
     fun hasConfig() = config.bankUrl.isNotEmpty()
             && config.username.isNotEmpty()
@@ -73,8 +74,8 @@ class MainViewModel(private val app: Application) : 
AndroidViewModel(app) {
                 is HttpJsonResult.Success -> {
                     val balance = response.json.getString("balance")
                     val amount = fromStringSigned(balance)!!
-                    currency = amount.currency
-                    prefs.edit().putString(PREF_KEY_CURRENCY, currency).apply()
+                    mCurrency.postValue(amount.currency)
+                    prefs.edit().putString(PREF_KEY_CURRENCY, 
amount.currency).apply()
                     // save config
                     saveConfig(config)
                     ConfigResult(true)
@@ -110,7 +111,8 @@ class MainViewModel(private val app: Application) : 
AndroidViewModel(app) {
                 "${amount.amount} ${amount.currency}"
             }
             is HttpJsonResult.Error -> {
-                app.getString(R.string.balance_error)
+                // show last known value or error string in case of an error
+                mBalance.value ?: app.getString(R.string.balance_error)
             }
         }
         mBalance.postValue(result)
diff --git a/app/src/main/java/net/taler/cashier/Utils.kt 
b/app/src/main/java/net/taler/cashier/Utils.kt
index 5c9cf5c..e8abe9a 100644
--- a/app/src/main/java/net/taler/cashier/Utils.kt
+++ b/app/src/main/java/net/taler/cashier/Utils.kt
@@ -40,6 +40,7 @@ object Utils {
 }
 
 fun View.fadeIn(endAction: () -> Unit = {}) {
+    if (visibility == VISIBLE) return
     alpha = 0f
     visibility = VISIBLE
     animate().alpha(1f).withEndAction {
diff --git a/app/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt 
b/app/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt
index acb0ea3..3ab2f73 100644
--- a/app/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt
+++ b/app/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt
@@ -6,8 +6,9 @@ import android.view.View
 import android.view.ViewGroup
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.Observer
 import androidx.navigation.fragment.findNavController
-import kotlinx.android.synthetic.main.fragment_success.*
+import kotlinx.android.synthetic.main.fragment_error.*
 import net.taler.cashier.MainViewModel
 import net.taler.cashier.R
 
@@ -24,7 +25,12 @@ class ErrorFragment : Fragment() {
     }
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        withdrawManager.resetState()
+        withdrawManager.withdrawStatus.observe(viewLifecycleOwner, Observer { 
status ->
+            if (status is WithdrawStatus.Aborted) {
+                textView.setText(R.string.transaction_aborted)
+            }
+        })
+        withdrawManager.completeTransaction()
         backButton.setOnClickListener {
             findNavController().popBackStack()
         }
diff --git a/app/src/main/java/net/taler/cashier/withdraw/NfcManager.kt 
b/app/src/main/java/net/taler/cashier/withdraw/NfcManager.kt
index 3aa1caa..f05cb52 100644
--- a/app/src/main/java/net/taler/cashier/withdraw/NfcManager.kt
+++ b/app/src/main/java/net/taler/cashier/withdraw/NfcManager.kt
@@ -5,6 +5,7 @@ import android.content.Context
 import android.nfc.NfcAdapter
 import android.nfc.NfcAdapter.FLAG_READER_NFC_A
 import android.nfc.NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK
+import android.nfc.NfcAdapter.getDefaultAdapter
 import android.nfc.Tag
 import android.nfc.tech.IsoDep
 import android.util.Log
@@ -19,25 +20,29 @@ class NfcManager : NfcAdapter.ReaderCallback {
     companion object {
         const val TAG = "taler-merchant"
 
+        /**
+         * Returns true if NFC is supported and false otherwise.
+         */
+        fun hasNfc(context: Context): Boolean {
+            return getDefaultAdapter(context) != null
+        }
+
         /**
          * Enables NFC reader mode. Don't forget to call [stop] afterwards.
          */
         fun start(activity: Activity, nfcManager: NfcManager) {
-            getNfcAdapter(
-                activity
-            )?.enableReaderMode(activity, nfcManager, nfcManager.flags, null)
+            getNfcAdapter(activity)?.enableReaderMode(activity, nfcManager, 
nfcManager.flags, null)
         }
 
         /**
          * Disables NFC reader mode. Call after [start].
          */
         fun stop(activity: Activity) {
-            getNfcAdapter(
-                activity
-            )?.disableReaderMode(activity)
+            getNfcAdapter(activity)?.disableReaderMode(activity)
         }
 
         private fun getNfcAdapter(context: Context): NfcAdapter? {
+            val test: android.nfc.NfcManager
             return NfcAdapter.getDefaultAdapter(context)
         }
     }
diff --git a/app/src/main/java/net/taler/cashier/withdraw/SuccessFragment.kt 
b/app/src/main/java/net/taler/cashier/withdraw/SuccessFragment.kt
deleted file mode 100644
index 53459f9..0000000
--- a/app/src/main/java/net/taler/cashier/withdraw/SuccessFragment.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package net.taler.cashier.withdraw
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
-import androidx.navigation.fragment.findNavController
-import kotlinx.android.synthetic.main.fragment_success.*
-import net.taler.cashier.MainViewModel
-import net.taler.cashier.R
-
-class SuccessFragment : Fragment() {
-
-    private val viewModel: MainViewModel by activityViewModels()
-    private val withdrawManager by lazy { viewModel.withdrawManager }
-
-    override fun onCreateView(
-        inflater: LayoutInflater, container: ViewGroup?,
-        savedInstanceState: Bundle?
-    ): View? {
-        return inflater.inflate(R.layout.fragment_success, container, false)
-    }
-
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        withdrawManager.resetState()
-        backButton.setOnClickListener {
-            findNavController().popBackStack()
-        }
-    }
-
-}
diff --git 
a/app/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt 
b/app/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt
index f359cbc..dfef1cf 100644
--- a/app/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt
+++ b/app/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt
@@ -16,8 +16,8 @@ import net.taler.cashier.MainViewModel
 import net.taler.cashier.R
 import net.taler.cashier.fadeIn
 import net.taler.cashier.fadeOut
+import 
net.taler.cashier.withdraw.TransactionFragmentDirections.Companion.actionTransactionFragmentToBalanceFragment
 import 
net.taler.cashier.withdraw.TransactionFragmentDirections.Companion.actionTransactionFragmentToErrorFragment
-import 
net.taler.cashier.withdraw.TransactionFragmentDirections.Companion.actionTransactionFragmentToSuccessFragment
 import net.taler.cashier.withdraw.WithdrawResult.Error
 import net.taler.cashier.withdraw.WithdrawResult.InsufficientBalance
 import net.taler.cashier.withdraw.WithdrawResult.Success
@@ -45,6 +45,12 @@ class TransactionFragment : Fragment() {
         withdrawManager.withdrawStatus.observe(viewLifecycleOwner, Observer { 
status ->
             onWithdrawStatusChanged(status)
         })
+
+        // change intro text depending on whether NFC is available or not
+        val hasNfc = NfcManager.hasNfc(requireContext())
+        val intro = if (hasNfc) R.string.transaction_intro_nfc else 
R.string.transaction_intro
+        introView.setText(intro)
+
         cancelButton.setOnClickListener {
             findNavController().popBackStack()
         }
@@ -53,10 +59,7 @@ class TransactionFragment : Fragment() {
     override fun onStart() {
         super.onStart()
         if (withdrawManager.withdrawResult.value is Success) {
-            NfcManager.start(
-                requireActivity(),
-                nfcManager
-            )
+            NfcManager.start(requireActivity(), nfcManager)
         }
     }
 
@@ -82,18 +85,12 @@ class TransactionFragment : Fragment() {
         }
         when (result) {
             is InsufficientBalance -> {
-                val c = getColor(
-                    requireContext(),
-                    R.color.design_default_color_error
-                )
+                val c = getColor(requireContext(), 
R.color.design_default_color_error)
                 introView.setTextColor(c)
                 introView.text = 
getString(R.string.withdraw_error_insufficient_balance)
             }
             is Error -> {
-                val c = getColor(
-                    requireContext(),
-                    R.color.design_default_color_error
-                )
+                val c = getColor(requireContext(), 
R.color.design_default_color_error)
                 introView.setTextColor(c)
                 introView.text = result.msg
             }
@@ -120,15 +117,30 @@ class TransactionFragment : Fragment() {
 
     private fun onWithdrawStatusChanged(status: WithdrawStatus?): Any = when 
(status) {
         is WithdrawStatus.SelectionDone -> {
-            qrCodeView.fadeOut()
-            progressBar.fadeIn()
+            qrCodeView.fadeOut {
+                qrCodeView?.setImageResource(R.drawable.ic_arrow)
+                qrCodeView?.fadeIn()
+            }
             introView.fadeOut {
-                introView.text = getString(R.string.transaction_intro_scanned)
-                introView.fadeIn()
+                introView?.text = getString(R.string.transaction_intro_scanned)
+                introView?.fadeIn {
+                    confirmButton?.isEnabled = true
+                    confirmButton?.setOnClickListener {
+                        withdrawManager.confirm(status.withdrawalId)
+                    }
+                }
             }
         }
-        is WithdrawStatus.Confirmed -> 
actionTransactionFragmentToSuccessFragment().let {
-            findNavController().navigate(it)
+        is WithdrawStatus.Confirming -> {
+            confirmButton.isEnabled = false
+            qrCodeView.fadeOut()
+            progressBar.fadeIn()
+        }
+        is WithdrawStatus.Success -> {
+            withdrawManager.completeTransaction()
+            actionTransactionFragmentToBalanceFragment().let {
+                findNavController().navigate(it)
+            }
         }
         is WithdrawStatus.Aborted -> onError()
         is WithdrawStatus.Error -> onError()
diff --git a/app/src/main/java/net/taler/cashier/withdraw/WithdrawFragment.kt 
b/app/src/main/java/net/taler/cashier/withdraw/WithdrawFragment.kt
deleted file mode 100644
index d4b4c8d..0000000
--- a/app/src/main/java/net/taler/cashier/withdraw/WithdrawFragment.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-package net.taler.cashier.withdraw
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.view.inputmethod.EditorInfo.IME_ACTION_GO
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
-import androidx.navigation.fragment.findNavController
-import kotlinx.android.synthetic.main.fragment_withdraw.*
-import net.taler.cashier.MainViewModel
-import net.taler.cashier.R
-
-class WithdrawFragment : Fragment() {
-
-    private val viewModel: MainViewModel by activityViewModels()
-    private val withdrawManager by lazy { viewModel.withdrawManager }
-
-    override fun onCreateView(
-        inflater: LayoutInflater, container: ViewGroup?,
-        savedInstanceState: Bundle?
-    ): View? {
-        return inflater.inflate(R.layout.fragment_withdraw, container, false)
-    }
-
-    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
-        button5.setOnClickListener { onAmountButtonPressed(5) }
-        button10.setOnClickListener { onAmountButtonPressed(10) }
-        button20.setOnClickListener { onAmountButtonPressed(20) }
-        button50.setOnClickListener { onAmountButtonPressed(50) }
-
-        if (savedInstanceState != null) {
-            
amountView.editText!!.setText(savedInstanceState.getCharSequence("amount"))
-        }
-        amountView.editText!!.setOnEditorActionListener { _, actionId, _ ->
-            if (actionId == IME_ACTION_GO) {
-                onAmountConfirmed(getAmountFromView())
-                true
-            } else false
-        }
-        fab.setOnClickListener { onAmountConfirmed(getAmountFromView()) }
-    }
-
-    override fun onSaveInstanceState(outState: Bundle) {
-        super.onSaveInstanceState(outState)
-        // for some reason automatic restore isn't working at the moment!?
-        amountView?.editText?.text.let {
-            outState.putCharSequence("amount", it)
-        }
-    }
-
-    private fun onAmountButtonPressed(amount: Int) {
-        amountView.editText!!.setText(amount.toString())
-        amountView.error = null
-    }
-
-    private fun getAmountFromView(): Int {
-        val str = amountView.editText!!.text.toString()
-        if (str.isBlank()) return 0
-        return Integer.parseInt(str)
-    }
-
-    private fun onAmountConfirmed(amount: Int) {
-        if (amount <= 0) {
-            amountView.error = getString(R.string.withdraw_error_zero)
-        } else if (!withdrawManager.hasSufficientBalance(amount)) {
-            amountView.error = 
getString(R.string.withdraw_error_insufficient_balance)
-        } else {
-            amountView.error = null
-            withdrawManager.withdraw(amount)
-            
WithdrawFragmentDirections.actionWithdrawFragmentToTransactionFragment()
-                .let {
-                findNavController().navigate(it)
-            }
-        }
-    }
-
-}
diff --git a/app/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt 
b/app/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt
index 6ccf344..c8b1972 100644
--- a/app/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt
+++ b/app/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt
@@ -5,12 +5,11 @@ import android.graphics.Bitmap
 import android.os.CountDownTimer
 import android.util.Log
 import androidx.annotation.UiThread
-import androidx.annotation.WorkerThread
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.distinctUntilChanged
 import androidx.lifecycle.viewModelScope
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.launch
 import net.taler.cashier.HttpHelper.makeJsonGetRequest
 import net.taler.cashier.HttpHelper.makeJsonPostRequest
@@ -37,8 +36,10 @@ class WithdrawManager(
     private val config
         get() = viewModel.config
 
-    private val currency
-        get() = viewModel.currency
+    private val currency: String?
+        get() = viewModel.currency.value
+
+    private var withdrawStatusCheck: Job? = null
 
     private val mWithdrawAmount = MutableLiveData<String>()
     val withdrawAmount: LiveData<String> = mWithdrawAmount
@@ -47,7 +48,10 @@ class WithdrawManager(
     val withdrawResult: LiveData<WithdrawResult> = mWithdrawResult
 
     private val mWithdrawStatus = MutableLiveData<WithdrawStatus>()
-    val withdrawStatus: LiveData<WithdrawStatus> = 
mWithdrawStatus.distinctUntilChanged()
+    val withdrawStatus: LiveData<WithdrawStatus> = mWithdrawStatus
+
+    private val mLastTransaction = MutableLiveData<LastTransaction>()
+    val lastTransaction: LiveData<LastTransaction> = mLastTransaction
 
     @UiThread
     fun hasSufficientBalance(amount: Int): Boolean {
@@ -60,6 +64,7 @@ class WithdrawManager(
     @UiThread
     fun withdraw(amount: Int) {
         check(amount > 0) { "Withdraw amount was <= 0" }
+        check(currency != null) { "Currency is null" }
         mWithdrawResult.value = null
         mWithdrawAmount.value = "$amount $currency"
         scope.launch(Dispatchers.IO) {
@@ -89,7 +94,11 @@ class WithdrawManager(
         override fun onTick(millisUntilFinished: Long) {
             val result = withdrawResult.value
             if (result is WithdrawResult.Success) {
-                checkWithdrawStatus(result.id)
+                // check for active jobs and only do one at a time
+                val hasActiveCheck = withdrawStatusCheck?.isActive ?: false
+                if (!hasActiveCheck) {
+                    withdrawStatusCheck = checkWithdrawStatus(result.id)
+                }
             } else {
                 cancel()
             }
@@ -107,34 +116,44 @@ class WithdrawManager(
         Log.d(TAG, "Checking withdraw status at $url")
         val response = makeJsonGetRequest(url, config)
         if (response !is Success) return@launch  // ignore errors and continue 
trying
+        val oldStatus = mWithdrawStatus.value
         when {
             response.json.getBoolean("aborted") -> {
+                cancelWithdrawStatusCheck()
                 mWithdrawStatus.postValue(WithdrawStatus.Aborted)
-                timer.cancel()
             }
             response.json.getBoolean("confirmation_done") -> {
-                mWithdrawStatus.postValue(WithdrawStatus.Confirmed)
-                viewModel.getBalance()
-                timer.cancel()
+                if (oldStatus !is WithdrawStatus.Success) {
+                    cancelWithdrawStatusCheck()
+                    mWithdrawStatus.postValue(WithdrawStatus.Success)
+                    viewModel.getBalance()
+                }
             }
             response.json.getBoolean("selection_done") -> {
-                if (mWithdrawStatus.value != WithdrawStatus.SelectionDone) {
-                    mWithdrawStatus.postValue(WithdrawStatus.SelectionDone)
-                    confirm(withdrawalId)
+                // only update status, if there's none, yet
+                // so we don't re-notify or overwrite newer status info
+                if (oldStatus == null) {
+                    
mWithdrawStatus.postValue(WithdrawStatus.SelectionDone(withdrawalId))
                 }
             }
         }
     }
 
+    private fun cancelWithdrawStatusCheck() {
+        timer.cancel()
+        withdrawStatusCheck?.cancel()
+    }
+
     /**
      * Aborts the last [withdrawResult], if it exists und there is no 
[withdrawStatus].
      * Otherwise this is a no-op.
      */
+    @UiThread
     fun abort() {
         val result = withdrawResult.value
         val status = withdrawStatus.value
         if (result is WithdrawResult.Success && status == null) {
-            timer.cancel()
+            cancelWithdrawStatusCheck()
             abort(result.id)
         }
     }
@@ -145,24 +164,29 @@ class WithdrawManager(
         makeJsonPostRequest(url, "", config)
     }
 
-    @WorkerThread
-    private fun confirm(withdrawalId: String) {
-        val url =
-            
"${config.bankUrl}/accounts/${config.username}/withdrawals/${withdrawalId}/confirm"
-        Log.d(TAG, "Confirming withdrawal at $url")
-        when (val result = makeJsonPostRequest(url, "", config)) {
-            is Success -> {
-                mWithdrawStatus.postValue(WithdrawStatus.Confirmed)
-            }
-            is Error -> {
-                Log.e(TAG, "Error confirming withdrawal. Status code: 
${result.statusCode}")
-                mWithdrawStatus.postValue(WithdrawStatus.Error)
+    @UiThread
+    fun confirm(withdrawalId: String) {
+        mWithdrawStatus.value = WithdrawStatus.Confirming
+        scope.launch(Dispatchers.IO) {
+            val url =
+                
"${config.bankUrl}/accounts/${config.username}/withdrawals/${withdrawalId}/confirm"
+            Log.d(TAG, "Confirming withdrawal at $url")
+            when (val result = makeJsonPostRequest(url, "", config)) {
+                is Success -> {
+                    // no-op still waiting for [timer] to confirm our 
confirmation
+                }
+                is Error -> {
+                    Log.e(TAG, "Error confirming withdrawal. Status code: 
${result.statusCode}")
+                    mWithdrawStatus.postValue(WithdrawStatus.Error)
+                }
             }
         }
     }
 
     @UiThread
-    fun resetState() {
+    fun completeTransaction() {
+        mLastTransaction.value = LastTransaction(withdrawAmount.value!!, 
withdrawStatus.value!!)
+        withdrawStatusCheck = null
         mWithdrawAmount.value = null
         mWithdrawResult.value = null
         mWithdrawStatus.value = null
@@ -179,6 +203,12 @@ sealed class WithdrawResult {
 sealed class WithdrawStatus {
     object Error : WithdrawStatus()
     object Aborted : WithdrawStatus()
-    object SelectionDone : WithdrawStatus()
-    object Confirmed : WithdrawStatus()
+    class SelectionDone(val withdrawalId: String) : WithdrawStatus()
+    object Confirming : WithdrawStatus()
+    object Success : WithdrawStatus()
 }
+
+data class LastTransaction(
+    val withdrawAmount: String,
+    val withdrawStatus: WithdrawStatus
+)
diff --git a/app/src/main/res/drawable-w550dp/ic_arrow.xml 
b/app/src/main/res/drawable-w550dp/ic_arrow.xml
new file mode 100644
index 0000000..331ea06
--- /dev/null
+++ b/app/src/main/res/drawable-w550dp/ic_arrow.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android";
+    android:width="24dp"
+    android:height="24dp"
+    android:alpha="0.56"
+    android:tint="@color/green"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#000000"
+        android:pathData="M20,5.41 L18.59,4 7,15.59V9H5V19H15V17H8.41" />
+</vector>
diff --git a/app/src/main/res/drawable/ic_arrow.xml 
b/app/src/main/res/drawable/ic_arrow.xml
new file mode 100644
index 0000000..d7578bd
--- /dev/null
+++ b/app/src/main/res/drawable/ic_arrow.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android";
+    android:width="24dp"
+    android:height="24dp"
+    android:alpha="0.56"
+    android:tint="@color/green"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#000000"
+        android:pathData="M5,5.41 L6.41,4 18,15.59V9h2V19H10v-2h6.59" />
+</vector>
diff --git a/app/src/main/res/drawable/ic_check_circle.xml 
b/app/src/main/res/drawable/ic_check_circle.xml
index 7fbbed1..d43d6ba 100644
--- a/app/src/main/res/drawable/ic_check_circle.xml
+++ b/app/src/main/res/drawable/ic_check_circle.xml
@@ -2,7 +2,6 @@
     android:width="24dp"
     android:height="24dp"
     android:alpha="0.56"
-    android:tint="@color/green"
     android:viewportWidth="24.0"
     android:viewportHeight="24.0">
     <path
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml 
b/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..581c480
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,13 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android";
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48">
+  <group android:translateX="12"
+      android:translateY="12">
+    <path
+        android:pathData="M6,3L6,6L9,6L9,7L6.25,7C5.05,7 4.0508,8 
4.0508,9L3.5,16L20.5,16L20,9C19.8,8 18.8008,7 
17.8008,7L11,7L11,6L14,6L14,3L6,3zM7,4L13,4L13,5L7,5L7,4zM6,9L8,9L8,10L6,10L6,9zM9,9L11,9L11,10L9,10L9,9zM13,9L18,9L18,11L13,11L13,9zM6,11L8,11L8,12L6,12L6,11zM9,11L11,11L11,12L9,12L9,11zM6,13L8,13L8,14L6,14L6,13zM9,13L11,13L11,14L9,14L9,13zM2,17L2,21L22,21L22,17L2,17zM4.7422,17.291L7.2695,17.291L7.2695,17.7793L6.3574,17.7793L6.3574,20.6777L5.6543,20.6777L5.6543,17.7793L4.7422,
 [...]
+        android:fillColor="#f9f9f9"
+        android:fillAlpha="1"/>
+  </group>
+</vector>
diff --git a/app/src/main/res/layout-w550dp/fragment_balance.xml 
b/app/src/main/res/layout-w550dp/fragment_balance.xml
new file mode 100644
index 0000000..72d5b89
--- /dev/null
+++ b/app/src/main/res/layout-w550dp/fragment_balance.xml
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.coordinatorlayout.widget.CoordinatorLayout 
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="match_parent"
+    tools:context=".BalanceFragment">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <TextView
+            android:id="@+id/lastTransactionView"
+            style="@style/Widget.MaterialComponents.Snackbar.FullWidth"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:background="?attr/colorPrimaryDark"
+            android:drawableStart="@drawable/ic_check_circle"
+            android:drawablePadding="8dp"
+            android:drawableTint="?attr/colorOnPrimarySurface"
+            android:gravity="center_vertical"
+            android:padding="8dp"
+            android:textColor="?attr/colorOnPrimarySurface"
+            android:visibility="gone"
+            app:layout_constraintEnd_toStartOf="@+id/guideline"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:text="@string/transaction_last_success"
+            tools:visibility="visible" />
+
+        <TextView
+            android:id="@+id/balanceLabel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="32dp"
+            android:layout_marginTop="32dp"
+            android:layout_marginEnd="32dp"
+            android:text="@string/balance_current_label"
+            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
+            app:layout_constraintBottom_toTopOf="@+id/balanceView"
+            app:layout_constraintEnd_toStartOf="@+id/guideline"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/lastTransactionView"
+            app:layout_constraintVertical_bias="0.0"
+            app:layout_constraintVertical_chainStyle="packed" />
+
+        <TextView
+            android:id="@+id/balanceView"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="32dp"
+            android:textAppearance="@style/TextAppearance.AppCompat.Headline"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@+id/guideline"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/balanceLabel"
+            tools:text="100 KUDOS" />
+
+        <ProgressBar
+            android:id="@+id/progressBar"
+            style="?android:attr/progressBarStyle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:layout_constraintBottom_toBottomOf="@+id/balanceView"
+            app:layout_constraintEnd_toEndOf="@+id/balanceView"
+            app:layout_constraintStart_toStartOf="@+id/balanceView"
+            app:layout_constraintTop_toTopOf="@+id/balanceView" />
+
+        <androidx.constraintlayout.widget.Guideline
+            android:id="@+id/guideline"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            app:layout_constraintGuide_percent="0.5" />
+
+        <TextView
+            android:id="@+id/introView"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_margin="32dp"
+            android:text="@string/withdraw_into"
+            android:textAlignment="center"
+            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="@+id/guideline"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:visibility="visible" />
+
+        <Button
+            android:id="@+id/button5"
+            style="@style/AmountButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="5"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toStartOf="@+id/button10"
+            app:layout_constraintHorizontal_chainStyle="packed"
+            app:layout_constraintStart_toStartOf="@+id/guideline"
+            app:layout_constraintTop_toBottomOf="@+id/introView"
+            tools:ignore="HardcodedText"
+            tools:visibility="visible" />
+
+        <Button
+            android:id="@+id/button10"
+            style="@style/AmountButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="10"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toStartOf="@+id/button20"
+            app:layout_constraintStart_toEndOf="@+id/button5"
+            app:layout_constraintTop_toBottomOf="@+id/introView"
+            tools:ignore="HardcodedText"
+            tools:visibility="visible" />
+
+        <Button
+            android:id="@+id/button20"
+            style="@style/AmountButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="20"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toStartOf="@+id/button50"
+            app:layout_constraintStart_toEndOf="@+id/button10"
+            app:layout_constraintTop_toBottomOf="@+id/introView"
+            tools:ignore="HardcodedText"
+            tools:visibility="visible" />
+
+        <Button
+            android:id="@+id/button50"
+            style="@style/AmountButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="50"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@+id/button20"
+            app:layout_constraintTop_toBottomOf="@+id/introView"
+            tools:ignore="HardcodedText"
+            tools:visibility="visible" />
+
+        <com.google.android.material.textfield.TextInputLayout
+            android:id="@+id/amountView"
+            
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="32dp"
+            android:hint="@string/withdraw_input_amount"
+            android:visibility="invisible"
+            app:endIconDrawable="@drawable/ic_clear"
+            app:endIconMode="clear_text"
+            app:endIconTint="?attr/colorControlNormal"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="@+id/guideline"
+            app:layout_constraintTop_toBottomOf="@+id/button5"
+            tools:visibility="visible">
+
+            <com.google.android.material.textfield.TextInputEditText
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:ems="6"
+                android:imeOptions="actionGo"
+                android:inputType="number"
+                android:maxLength="4" />
+
+        </com.google.android.material.textfield.TextInputLayout>
+
+        <TextView
+            android:id="@+id/currencyView"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_margin="16dp"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@+id/amountView"
+            app:layout_constraintTop_toTopOf="@+id/amountView"
+            tools:text="TESTKUDOS"
+            tools:visibility="visible" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <com.google.android.material.floatingactionbutton.FloatingActionButton
+        android:id="@+id/fab"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|end"
+        android:layout_margin="@dimen/default_margin"
+        android:visibility="invisible"
+        app:srcCompat="@drawable/ic_withdraw"
+        app:useCompatPadding="true"
+        tools:visibility="visible" />
+
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/layout-w550dp/fragment_transaction.xml 
b/app/src/main/res/layout-w550dp/fragment_transaction.xml
index 0076f25..634633a 100644
--- a/app/src/main/res/layout-w550dp/fragment_transaction.xml
+++ b/app/src/main/res/layout-w550dp/fragment_transaction.xml
@@ -49,7 +49,7 @@
         app:layout_constraintStart_toStartOf="@+id/guideline"
         app:layout_constraintTop_toTopOf="parent"
         tools:ignore="ContentDescription"
-        tools:src="@tools:sample/avatars"
+        tools:src="@drawable/ic_arrow"
         tools:visibility="visible" />
 
     <ProgressBar
@@ -70,9 +70,26 @@
         android:backgroundTint="@color/red"
         android:text="@string/transaction_abort"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/guideline"
+        app:layout_constraintEnd_toStartOf="@+id/confirmButton"
+        app:layout_constraintHorizontal_bias="0.5"
+        app:layout_constraintHorizontal_chainStyle="spread_inside"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@+id/qrCodeView"
         app:layout_constraintVertical_bias="1.0" />
 
+    <Button
+        android:id="@+id/confirmButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_margin="16dp"
+        android:backgroundTint="@color/green"
+        android:enabled="false"
+        android:text="@string/transaction_confirm"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/guideline"
+        app:layout_constraintHorizontal_bias="0.5"
+        app:layout_constraintStart_toEndOf="@+id/cancelButton"
+        tools:enabled="true" />
+
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/activity_main.xml 
b/app/src/main/res/layout/activity_main.xml
index bf7f543..766537e 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -13,9 +13,9 @@
 
         <com.google.android.material.appbar.MaterialToolbar
             android:id="@+id/toolbar"
+            style="@style/AppTheme.Toolbar"
             android:layout_width="match_parent"
-            android:layout_height="?attr/actionBarSize"
-            android:background="?attr/colorPrimary" />
+            android:layout_height="wrap_content" />
 
     </com.google.android.material.appbar.AppBarLayout>
 
diff --git a/app/src/main/res/layout/fragment_balance.xml 
b/app/src/main/res/layout/fragment_balance.xml
index dd376d0..2ef77fd 100644
--- a/app/src/main/res/layout/fragment_balance.xml
+++ b/app/src/main/res/layout/fragment_balance.xml
@@ -10,6 +10,25 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
+        <TextView
+            android:id="@+id/lastTransactionView"
+            style="@style/Widget.MaterialComponents.Snackbar.FullWidth"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:background="?attr/colorPrimaryDark"
+            android:drawableStart="@drawable/ic_check_circle"
+            android:drawablePadding="8dp"
+            android:drawableTint="?attr/colorOnPrimarySurface"
+            android:gravity="center_vertical"
+            android:padding="8dp"
+            android:textColor="?attr/colorOnPrimarySurface"
+            android:visibility="gone"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            tools:text="@string/transaction_last_success"
+            tools:visibility="visible" />
+
         <TextView
             android:id="@+id/balanceLabel"
             android:layout_width="wrap_content"
@@ -19,7 +38,7 @@
             android:textAppearance="@style/TextAppearance.AppCompat.Medium"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent" />
+            app:layout_constraintTop_toBottomOf="@+id/lastTransactionView" />
 
         <TextView
             android:id="@+id/balanceView"
@@ -42,6 +61,112 @@
             app:layout_constraintStart_toStartOf="@+id/balanceView"
             app:layout_constraintTop_toTopOf="@+id/balanceView" />
 
+        <TextView
+            android:id="@+id/introView"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_margin="32dp"
+            android:text="@string/withdraw_into"
+            android:textAlignment="center"
+            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/progressBar"
+            tools:visibility="visible" />
+
+        <Button
+            android:id="@+id/button5"
+            style="@style/AmountButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="5"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toStartOf="@+id/button10"
+            app:layout_constraintHorizontal_chainStyle="packed"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/introView"
+            tools:ignore="HardcodedText"
+            tools:visibility="visible" />
+
+        <Button
+            android:id="@+id/button10"
+            style="@style/AmountButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="10"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toStartOf="@+id/button20"
+            app:layout_constraintStart_toEndOf="@+id/button5"
+            app:layout_constraintTop_toBottomOf="@+id/introView"
+            tools:ignore="HardcodedText"
+            tools:visibility="visible" />
+
+        <Button
+            android:id="@+id/button20"
+            style="@style/AmountButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="20"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toStartOf="@+id/button50"
+            app:layout_constraintStart_toEndOf="@+id/button10"
+            app:layout_constraintTop_toBottomOf="@+id/introView"
+            tools:ignore="HardcodedText"
+            tools:visibility="visible" />
+
+        <Button
+            android:id="@+id/button50"
+            style="@style/AmountButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="50"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@+id/button20"
+            app:layout_constraintTop_toBottomOf="@+id/introView"
+            tools:ignore="HardcodedText"
+            tools:visibility="visible" />
+
+        <com.google.android.material.textfield.TextInputLayout
+            android:id="@+id/amountView"
+            
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="32dp"
+            android:hint="@string/withdraw_input_amount"
+            android:visibility="invisible"
+            app:endIconDrawable="@drawable/ic_clear"
+            app:endIconMode="clear_text"
+            app:endIconTint="?attr/colorControlNormal"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/button5"
+            tools:visibility="visible">
+
+            <com.google.android.material.textfield.TextInputEditText
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:ems="6"
+                android:imeOptions="actionGo"
+                android:inputType="number"
+                android:maxLength="4" />
+
+        </com.google.android.material.textfield.TextInputLayout>
+
+        <TextView
+            android:id="@+id/currencyView"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_margin="16dp"
+            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
+            android:visibility="invisible"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@+id/amountView"
+            app:layout_constraintTop_toTopOf="@+id/amountView"
+            tools:text="TESTKUDOS"
+            tools:visibility="visible" />
+
     </androidx.constraintlayout.widget.ConstraintLayout>
 
     <com.google.android.material.floatingactionbutton.FloatingActionButton
diff --git a/app/src/main/res/layout/fragment_error.xml 
b/app/src/main/res/layout/fragment_error.xml
index 143a92d..f96e08f 100644
--- a/app/src/main/res/layout/fragment_error.xml
+++ b/app/src/main/res/layout/fragment_error.xml
@@ -5,7 +5,7 @@
     android:id="@+id/frameLayout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    tools:context=".withdraw.SuccessFragment">
+    tools:context=".withdraw.ErrorFragment">
 
     <ImageView
         android:id="@+id/imageView"
diff --git a/app/src/main/res/layout/fragment_success.xml 
b/app/src/main/res/layout/fragment_success.xml
deleted file mode 100644
index e59072e..0000000
--- a/app/src/main/res/layout/fragment_success.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout 
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:id="@+id/frameLayout"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".withdraw.SuccessFragment">
-
-    <ImageView
-        android:id="@+id/imageView"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:layout_margin="32dp"
-        android:src="@drawable/ic_check_circle"
-        app:layout_constraintBottom_toTopOf="@+id/textView"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintHorizontal_bias="0.5"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        tools:ignore="ContentDescription" />
-
-    <androidx.appcompat.widget.AppCompatTextView
-        android:id="@+id/textView"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:layout_margin="32dp"
-        android:text="@string/transaction_success"
-        android:textAlignment="center"
-        android:textColor="@color/green"
-        app:autoSizeMaxTextSize="42sp"
-        app:autoSizeTextType="uniform"
-        app:layout_constraintBottom_toTopOf="@+id/backButton"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintHorizontal_bias="0.5"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/imageView" />
-
-    <Button
-        android:id="@+id/backButton"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_margin="16dp"
-        android:text="@string/transaction_button_back"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_transaction.xml 
b/app/src/main/res/layout/fragment_transaction.xml
index 8083fcf..43c7db3 100644
--- a/app/src/main/res/layout/fragment_transaction.xml
+++ b/app/src/main/res/layout/fragment_transaction.xml
@@ -41,7 +41,7 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@+id/amountView"
         tools:ignore="ContentDescription"
-        tools:src="@tools:sample/avatars"
+        tools:src="@drawable/ic_arrow"
         tools:visibility="visible" />
 
     <ProgressBar
@@ -62,9 +62,23 @@
         android:backgroundTint="@color/red"
         android:text="@string/transaction_abort"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/confirmButton"
+        app:layout_constraintHorizontal_chainStyle="spread_inside"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@+id/qrCodeView"
         app:layout_constraintVertical_bias="1.0" />
 
+    <Button
+        android:id="@+id/confirmButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_margin="16dp"
+        android:backgroundTint="@color/green"
+        android:enabled="false"
+        android:text="@string/transaction_confirm"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/cancelButton"
+        tools:enabled="true" />
+
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_withdraw.xml 
b/app/src/main/res/layout/fragment_withdraw.xml
deleted file mode 100644
index e038978..0000000
--- a/app/src/main/res/layout/fragment_withdraw.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.coordinatorlayout.widget.CoordinatorLayout 
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="match_parent"
-    tools:context=".withdraw.WithdrawFragment">
-
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-
-        <TextView
-            android:id="@+id/introView"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_margin="32dp"
-            android:text="@string/withdraw_into"
-            android:textSize="16sp"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent" />
-
-        <com.google.android.material.textfield.TextInputLayout
-            android:id="@+id/amountView"
-            
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_margin="32dp"
-            android:hint="@string/withdraw_input_amount"
-            app:endIconDrawable="@drawable/ic_clear"
-            app:endIconMode="clear_text"
-            app:endIconTint="?attr/colorControlNormal"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/button5">
-
-            <com.google.android.material.textfield.TextInputEditText
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:ems="6"
-                android:imeOptions="actionGo"
-                android:inputType="number"
-                android:maxLength="4" />
-
-        </com.google.android.material.textfield.TextInputLayout>
-
-        <Button
-            android:id="@+id/button5"
-            style="@style/AmountButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="5"
-            app:layout_constraintEnd_toStartOf="@+id/button10"
-            app:layout_constraintHorizontal_chainStyle="packed"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/introView"
-            tools:ignore="HardcodedText" />
-
-        <Button
-            android:id="@+id/button10"
-            style="@style/AmountButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="10"
-            app:layout_constraintEnd_toStartOf="@+id/button20"
-            app:layout_constraintStart_toEndOf="@+id/button5"
-            app:layout_constraintTop_toBottomOf="@+id/introView"
-            tools:ignore="HardcodedText" />
-
-        <Button
-            android:id="@+id/button20"
-            style="@style/AmountButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="20"
-            app:layout_constraintEnd_toStartOf="@+id/button50"
-            app:layout_constraintStart_toEndOf="@+id/button10"
-            app:layout_constraintTop_toBottomOf="@+id/introView"
-            tools:ignore="HardcodedText" />
-
-        <Button
-            android:id="@+id/button50"
-            style="@style/AmountButton"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="50"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toEndOf="@+id/button20"
-            app:layout_constraintTop_toBottomOf="@+id/introView"
-            tools:ignore="HardcodedText" />
-
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-    <com.google.android.material.floatingactionbutton.FloatingActionButton
-        android:id="@+id/fab"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom|end"
-        android:layout_margin="@dimen/default_margin"
-        android:tint="@color/design_default_color_surface"
-        app:srcCompat="@drawable/ic_check"
-        app:useCompatPadding="true" />
-
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml 
b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..7353dbd
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android";>
+    <background android:drawable="@color/ic_launcher_background"/>
+    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml 
b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..7353dbd
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android";>
+    <background android:drawable="@color/ic_launcher_background"/>
+    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png 
b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..c52928c
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png 
b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..c52928c
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png 
differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png 
b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..b97178b
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png 
b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..b97178b
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png 
differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png 
b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..8f92c07
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png 
differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png 
b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8f92c07
Binary files /dev/null and 
b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png 
b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..214cbea
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png 
differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png 
b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..214cbea
Binary files /dev/null and 
b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png 
b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b959cd3
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png 
differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png 
b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..b959cd3
Binary files /dev/null and 
b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/navigation/nav_graph.xml 
b/app/src/main/res/navigation/nav_graph.xml
index 5d7dd78..0bd6d15 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -23,24 +23,8 @@
         android:label="fragment_balance"
         tools:layout="@layout/fragment_balance">
         <action
-            android:id="@+id/action_balanceFragment_to_withdrawFragment"
-            app:destination="@id/withdrawFragment"
-            app:enterAnim="@anim/fragment_open_enter"
-            app:exitAnim="@anim/fragment_open_exit"
-            app:launchSingleTop="true" />
-    </fragment>
-
-    <fragment
-        android:id="@+id/withdrawFragment"
-        android:name="net.taler.cashier.withdraw.WithdrawFragment"
-        android:label="fragment_withdraw"
-        tools:layout="@layout/fragment_withdraw">
-        <action
-            android:id="@+id/action_withdrawFragment_to_transactionFragment"
-            app:destination="@id/transactionFragment"
-            app:enterAnim="@anim/fragment_open_enter"
-            app:exitAnim="@anim/fragment_open_exit"
-            app:launchSingleTop="true" />
+            android:id="@+id/action_balanceFragment_to_transactionFragment"
+            app:destination="@id/transactionFragment" />
     </fragment>
 
     <fragment
@@ -49,22 +33,17 @@
         android:label="fragment_transaction"
         tools:layout="@layout/fragment_transaction">
         <action
-            android:id="@+id/action_transactionFragment_to_successFragment"
-            app:destination="@id/successFragment"
+            android:id="@+id/action_transactionFragment_to_errorFragment"
+            app:destination="@id/errorFragment"
             app:launchSingleTop="true"
             app:popUpTo="@+id/balanceFragment" />
         <action
-            android:id="@+id/action_transactionFragment_to_errorFragment"
-            app:destination="@id/errorFragment"
+            android:id="@+id/action_transactionFragment_to_balanceFragment"
+            app:destination="@id/balanceFragment"
             app:launchSingleTop="true"
-            app:popUpTo="@+id/withdrawFragment" />
+            app:popUpTo="@+id/balanceFragment" />
     </fragment>
 
-    <fragment
-        android:id="@+id/successFragment"
-        android:name="net.taler.cashier.withdraw.SuccessFragment"
-        tools:layout="@layout/fragment_success" />
-
     <fragment
         android:id="@+id/errorFragment"
         android:name="net.taler.cashier.withdraw.ErrorFragment"
diff --git a/app/src/main/res/values/colors.xml 
b/app/src/main/res/values/colors.xml
index d9acb88..f69adcd 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -4,6 +4,6 @@
     <color name="colorPrimaryDark">#6A1B9A</color>
     <color name="colorAccent">#D81B60</color>
 
-    <color name="green">#4CAF50</color>
+    <color name="green">#388E3C</color>
     <color name="red">#D32F2F</color>
 </resources>
diff --git a/app/src/main/res/values/ic_launcher_background.xml 
b/app/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..3862264
--- /dev/null
+++ b/app/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="ic_launcher_background">#1565C0</color>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml 
b/app/src/main/res/values/strings.xml
index ab15c09..2d33169 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -10,23 +10,29 @@
     <string name="config_error">Error retrieving configuration</string>
     <string name="config_error_auth">Invalid username or password</string>
 
-    <string name="balance_current_label">Current Balance:</string>
+    <string name="balance_current_label">Current balance</string>
     <string name="balance_error">ERROR</string>
     <string name="action_reconfigure">Reconfigure</string>
     <string name="action_lock">Lock</string>
 
     <string name="withdraw_input_amount">Amount</string>
     <string name="withdraw_clear">clear amount</string>
-    <string name="withdraw_into">How much to cash in?</string>
+    <string name="withdraw_into">How much e-cash should be withdrawn?</string>
     <string name="withdraw_error_zero">Enter positive amount</string>
     <string name="withdraw_error_insufficient_balance">Insufficient 
balance</string>
     <string name="withdraw_error_fetch">Error communicating with bank</string>
 
-    <string name="transaction_intro">Scan code or use NFC\nwith the Taler 
wallet app\nto get</string>
-    <string name="transaction_intro_scanned">Waiting for confirmation…</string>
+    <string name="transaction_intro">Scan code\nwith the Taler wallet app\nto 
get</string>
+    <string name="transaction_intro_nfc">Scan code or use NFC\nwith the Taler 
wallet app\nto get</string>
+    <string name="transaction_intro_scanned">Please confirm the 
transaction!</string>
+    <string name="transaction_confirm">Confirm</string>
     <string name="transaction_abort">Abort</string>
     <string name="transaction_success">Transaction successful</string>
     <string name="transaction_error">Transaction error</string>
+    <string name="transaction_aborted">Transaction aborted</string>
     <string name="transaction_button_back">Go back</string>
+    <string name="transaction_last_success">Last Transaction: %s 
withdrawn</string>
+    <string name="transaction_last_aborted">Last Transaction: Aborted</string>
+    <string name="transaction_last_error">Last Transaction: Error</string>
 
 </resources>
diff --git a/app/src/main/res/values/styles.xml 
b/app/src/main/res/values/styles.xml
index 667fe05..84dfe74 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -7,10 +7,6 @@
         <item name="colorSecondary">@color/colorAccent</item>
         <item 
name="colorOnSecondary">@color/design_default_color_background</item>
         <item name="colorAccent">@color/colorAccent</item>
-
-        <!-- https://stackoverflow.com/q/59081672/4856311 -->
-        <item 
name="actionOverflowMenuStyle">@style/Widget.MaterialComponents.PopupMenu.Overflow
-        </item>
     </style>
 
     <style name="AppTheme.NoActionBar">
@@ -18,7 +14,9 @@
         <item name="windowNoTitle">true</item>
     </style>
 
-    <style name="AppTheme.AppBarOverlay" 
parent="ThemeOverlay.MaterialComponents.Dark.ActionBar" />
+    <style name="AppTheme.AppBarOverlay" 
parent="ThemeOverlay.MaterialComponents.ActionBar" />
+
+    <style name="AppTheme.Toolbar" 
parent="Widget.MaterialComponents.Toolbar.Primary" />
 
     <style name="AmountButton" parent="Widget.MaterialComponents.Button">
         <item name="android:minWidth">48dp</item>
diff --git a/artwork/ic_bottom_left.svg b/artwork/ic_bottom_left.svg
new file mode 100644
index 0000000..c3aa7e4
--- /dev/null
+++ b/artwork/ic_bottom_left.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   height="24"
+   version="1.1"
+   viewBox="0 0 24 24"
+   width="24"
+   id="svg4"
+   sodipodi:docname="ic_bottom_left.svg"
+   inkscape:version="0.92.4 (unknown)">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="982"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="9.8333333"
+     inkscape:cx="-10.728814"
+     inkscape:cy="12"
+     inkscape:window-x="1920"
+     inkscape:window-y="72"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4" />
+  <path
+     d="M 20,5.41 18.59,4 7,15.59 V 9 H 5 V 19 H 15 V 17 H 8.41"
+     id="path2"
+     inkscape:connector-curvature="0"
+     style="fill:#000000" />
+</svg>
diff --git a/artwork/ic_bottom_right.svg b/artwork/ic_bottom_right.svg
new file mode 100644
index 0000000..26869ba
--- /dev/null
+++ b/artwork/ic_bottom_right.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   height="24"
+   version="1.1"
+   viewBox="0 0 24 24"
+   width="24"
+   id="svg4"
+   sodipodi:docname="ic_bottom_right.svg"
+   inkscape:version="0.92.4 (unknown)">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="982"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="9.8333333"
+     inkscape:cx="-10.728814"
+     inkscape:cy="12"
+     inkscape:window-x="1920"
+     inkscape:window-y="72"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4" />
+  <path
+     d="M 5,5.41 6.41,4 18,15.59 V 9 h 2 V 19 H 10 v -2 h 6.59"
+     id="path2"
+     inkscape:connector-curvature="0"
+     style="fill:#000000" />
+</svg>
diff --git a/artwork/ic_launcher.svg b/artwork/ic_launcher.svg
new file mode 100644
index 0000000..4868fe4
--- /dev/null
+++ b/artwork/ic_launcher.svg
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.1"
+   width="24"
+   height="24"
+   viewBox="0 0 24 24"
+   id="svg4"
+   sodipodi:docname="ic_launcher.svg"
+   inkscape:version="0.92.4 (unknown)">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#000000"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="982"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="9.8333335"
+     inkscape:cx="-21.143993"
+     inkscape:cy="20.1778"
+     inkscape:window-x="1920"
+     inkscape:window-y="72"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4" />
+  <path
+     d="M 6 3 L 6 6 L 9 6 L 9 7 L 6.25 7 C 5.05 7 4.0507812 8 4.0507812 9 L 
3.5 16 L 20.5 16 L 20 9 C 19.8 8 18.800781 7 17.800781 7 L 11 7 L 11 6 L 14 6 L 
14 3 L 6 3 z M 7 4 L 13 4 L 13 5 L 7 5 L 7 4 z M 6 9 L 8 9 L 8 10 L 6 10 L 6 9 
z M 9 9 L 11 9 L 11 10 L 9 10 L 9 9 z M 13 9 L 18 9 L 18 11 L 13 11 L 13 9 z M 
6 11 L 8 11 L 8 12 L 6 12 L 6 11 z M 9 11 L 11 11 L 11 12 L 9 12 L 9 11 z M 6 
13 L 8 13 L 8 14 L 6 14 L 6 13 z M 9 13 L 11 13 L 11 14 L 9 14 L 9 13 z M 2 17 
L 2 21 L 22 21 L 22 1 [...]
+     id="path2"
+     style="fill:#f9f9f9;fill-opacity:1" />
+</svg>

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]