gnunet-svn
[Top][All Lists]
Advanced

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

[taler-cashier-terminal-android] 01/06: Add screen for entering amount t


From: gnunet
Subject: [taler-cashier-terminal-android] 01/06: Add screen for entering amount to withdraw
Date: Wed, 19 Feb 2020 21:31:55 +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 3d2d9d50caa071d1568d59abdf9348d952104dc8
Author: Torsten Grote <address@hidden>
AuthorDate: Mon Feb 10 10:54:56 2020 -0300

    Add screen for entering amount to withdraw
---
 .../main/java/net/taler/cashier/BalanceFragment.kt |   6 +-
 .../main/java/net/taler/cashier/MainViewModel.kt   |  10 ++
 .../java/net/taler/cashier/TransactionFragment.kt  |  26 +++++
 .../java/net/taler/cashier/WithdrawFragment.kt     |  68 +++++++++++++
 app/src/main/res/drawable/ic_check.xml             |   9 ++
 app/src/main/res/drawable/ic_clear.xml             |   9 ++
 app/src/main/res/layout/fragment_transaction.xml   |  19 ++++
 app/src/main/res/layout/fragment_withdraw.xml      | 112 +++++++++++++++++++++
 app/src/main/res/navigation/nav_graph.xml          |  28 +++++-
 app/src/main/res/values/strings.xml                |   5 +
 app/src/main/res/values/styles.xml                 |   7 ++
 11 files changed, 295 insertions(+), 4 deletions(-)

diff --git a/app/src/main/java/net/taler/cashier/BalanceFragment.kt 
b/app/src/main/java/net/taler/cashier/BalanceFragment.kt
index 987553f..90e2e8b 100644
--- a/app/src/main/java/net/taler/cashier/BalanceFragment.kt
+++ b/app/src/main/java/net/taler/cashier/BalanceFragment.kt
@@ -12,8 +12,6 @@ import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
 import androidx.lifecycle.Observer
 import androidx.navigation.fragment.findNavController
-import com.google.android.material.snackbar.Snackbar
-import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
 import kotlinx.android.synthetic.main.fragment_balance.*
 
 class BalanceFragment : Fragment() {
@@ -34,7 +32,9 @@ class BalanceFragment : Fragment() {
             progressBar.visibility = INVISIBLE
         })
         fab.setOnClickListener {
-            Snackbar.make(fab, "Withdrawals are not yet implemented!", 
LENGTH_LONG).show()
+            
BalanceFragmentDirections.actionBalanceFragmentToWithdrawFragment().let {
+                findNavController().navigate(it)
+            }
         }
     }
 
diff --git a/app/src/main/java/net/taler/cashier/MainViewModel.kt 
b/app/src/main/java/net/taler/cashier/MainViewModel.kt
index e9d4d94..a6accfe 100644
--- a/app/src/main/java/net/taler/cashier/MainViewModel.kt
+++ b/app/src/main/java/net/taler/cashier/MainViewModel.kt
@@ -47,6 +47,8 @@ class MainViewModel(private val app: Application) : 
AndroidViewModel(app) {
     private val mBalance = MutableLiveData<String>()
     val balance: LiveData<String> = mBalance
 
+    var currentWithdrawAmount: Int = 0
+
     fun hasConfig() = config.bankUrl.isNotEmpty()
             && config.username.isNotEmpty()
             && config.password.isNotEmpty()
@@ -120,6 +122,14 @@ class MainViewModel(private val app: Application) : 
AndroidViewModel(app) {
         saveConfig(config.copy(password=""))
     }
 
+    @UiThread
+    fun hasSufficientBalance(amount: Int): Boolean {
+        val balanceStr = balance.value?.split(' ')?.get(0)
+        if (balanceStr == app.getString(R.string.balance_error)) return false
+        val balanceDouble = balanceStr?.toDouble() ?: 0.0
+        return amount <= balanceDouble
+    }
+
 }
 
 data class Config(
diff --git a/app/src/main/java/net/taler/cashier/TransactionFragment.kt 
b/app/src/main/java/net/taler/cashier/TransactionFragment.kt
new file mode 100644
index 0000000..1c9c0db
--- /dev/null
+++ b/app/src/main/java/net/taler/cashier/TransactionFragment.kt
@@ -0,0 +1,26 @@
+package net.taler.cashier
+
+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 kotlinx.android.synthetic.main.fragment_transaction.*
+
+class TransactionFragment : Fragment() {
+
+    private val viewModel: MainViewModel by activityViewModels()
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        return inflater.inflate(R.layout.fragment_transaction, container, 
false)
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        test.text = viewModel.currentWithdrawAmount.toString()
+    }
+
+}
diff --git a/app/src/main/java/net/taler/cashier/WithdrawFragment.kt 
b/app/src/main/java/net/taler/cashier/WithdrawFragment.kt
new file mode 100644
index 0000000..08db4af
--- /dev/null
+++ b/app/src/main/java/net/taler/cashier/WithdrawFragment.kt
@@ -0,0 +1,68 @@
+package net.taler.cashier
+
+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.*
+
+class WithdrawFragment : Fragment() {
+
+    private val viewModel: MainViewModel by activityViewModels()
+
+    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) }
+
+        amountView.editText!!.setOnEditorActionListener { _, actionId, _ ->
+            if (actionId == IME_ACTION_GO) {
+                onAmountConfirmed(getAmountFromView())
+                true
+            } else false
+        }
+        clearButton.setOnClickListener {
+            amountView.editText!!.text = null
+            amountView.error = null
+        }
+        fab.setOnClickListener { onAmountConfirmed(getAmountFromView()) }
+    }
+
+    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 (!viewModel.hasSufficientBalance(amount)) {
+            amountView.error = 
getString(R.string.withdraw_error_insufficient_balance)
+        } else {
+            amountView.error = null
+            viewModel.currentWithdrawAmount = amount
+            
WithdrawFragmentDirections.actionWithdrawFragmentToTransactionFragment().let {
+                findNavController().navigate(it)
+            }
+        }
+    }
+
+}
diff --git a/app/src/main/res/drawable/ic_check.xml 
b/app/src/main/res/drawable/ic_check.xml
new file mode 100644
index 0000000..3c728c5
--- /dev/null
+++ b/app/src/main/res/drawable/ic_check.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android";
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
+</vector>
diff --git a/app/src/main/res/drawable/ic_clear.xml 
b/app/src/main/res/drawable/ic_clear.xml
new file mode 100644
index 0000000..f50fd99
--- /dev/null
+++ b/app/src/main/res/drawable/ic_clear.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android";
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 
5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />
+</vector>
diff --git a/app/src/main/res/layout/fragment_transaction.xml 
b/app/src/main/res/layout/fragment_transaction.xml
new file mode 100644
index 0000000..533593d
--- /dev/null
+++ b/app/src/main/res/layout/fragment_transaction.xml
@@ -0,0 +1,19 @@
+<?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=".TransactionFragment">
+
+    <TextView
+        android:id="@+id/test"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_withdraw.xml 
b/app/src/main/res/layout/fragment_withdraw.xml
new file mode 100644
index 0000000..4a98660
--- /dev/null
+++ b/app/src/main/res/layout/fragment_withdraw.xml
@@ -0,0 +1,112 @@
+<?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=".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"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_margin="32dp"
+            app:boxBackgroundMode="outline"
+            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>
+
+        <androidx.appcompat.widget.AppCompatImageButton
+            android:id="@+id/clearButton"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:background="?attr/selectableItemBackgroundBorderless"
+            android:contentDescription="@string/withdraw_clear"
+            android:src="@drawable/ic_clear"
+            app:layout_constraintEnd_toEndOf="@+id/amountView"
+            app:layout_constraintTop_toTopOf="@+id/amountView"
+            app:tint="?attr/colorControlNormal" />
+
+        <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/navigation/nav_graph.xml 
b/app/src/main/res/navigation/nav_graph.xml
index c8870f3..930d13f 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -21,7 +21,33 @@
         android:id="@+id/balanceFragment"
         android:name="net.taler.cashier.BalanceFragment"
         android:label="fragment_balance"
-        tools:layout="@layout/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.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" />
+    </fragment>
+
+    <fragment
+        android:id="@+id/transactionFragment"
+        android:name="net.taler.cashier.TransactionFragment"
+        android:label="fragment_transaction"
+        tools:layout="@layout/fragment_transaction" />
 
     <action
         android:id="@+id/action_global_configFragment"
diff --git a/app/src/main/res/values/strings.xml 
b/app/src/main/res/values/strings.xml
index 2f114de..f122111 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -14,4 +14,9 @@
     <string name="action_reconfigure">Reconfigure</string>
     <string name="action_lock">Lock</string>
 
+    <string name="withdraw_clear">clear amount</string>
+    <string name="withdraw_into">How much to cash in?</string>
+    <string name="withdraw_error_zero">Enter positive amount</string>
+    <string name="withdraw_error_insufficient_balance">Insufficient 
balance</string>
+
 </resources>
diff --git a/app/src/main/res/values/styles.xml 
b/app/src/main/res/values/styles.xml
index 35e952e..e3ef098 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -16,4 +16,11 @@
 
     <style name="AppTheme.PopupOverlay" 
parent="ThemeOverlay.AppCompat.DayNight" />
 
+    <style name="AmountButton" parent="Widget.AppCompat.Button.Colored">
+        <item name="android:minWidth">48dp</item>
+        <item name="android:layout_marginStart">@dimen/default_margin</item>
+        <item name="android:layout_marginEnd">@dimen/default_margin</item>
+        <item name="android:layout_marginTop">32dp</item>
+    </style>
+
 </resources>

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



reply via email to

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