gnunet-svn
[Top][All Lists]
Advanced

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

[taler-cashier-terminal-android] branch master updated (b5c2b27 -> e2ed3


From: gnunet
Subject: [taler-cashier-terminal-android] branch master updated (b5c2b27 -> e2ed3f6)
Date: Mon, 02 Mar 2020 15:51:02 +0100

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

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

    from b5c2b27  Improve UI and balance error handling
     new 496200b  Show dedicated error message when device is offline
     new e2ed3f6  Show link to register a test account

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .idea/codeStyles/Project.xml                       |  3 --
 .idea/gradle.xml                                   |  4 ++-
 app/build.gradle                                   |  2 +-
 app/src/main/AndroidManifest.xml                   |  1 +
 .../main/java/net/taler/cashier/BalanceFragment.kt | 32 ++++++++++++++--------
 .../main/java/net/taler/cashier/ConfigFragment.kt  | 10 ++++++-
 .../main/java/net/taler/cashier/MainViewModel.kt   | 12 ++++----
 app/src/main/java/net/taler/cashier/Utils.kt       | 16 +++++++++++
 .../net/taler/cashier/withdraw/WithdrawManager.kt  |  5 +++-
 .../main/res/layout-w550dp/fragment_balance.xml    |  3 +-
 app/src/main/res/layout/fragment_balance.xml       |  3 +-
 app/src/main/res/layout/fragment_config.xml        | 14 ++++++++--
 app/src/main/res/values/strings.xml                |  2 ++
 build.gradle                                       |  2 +-
 gradle/wrapper/gradle-wrapper.properties           |  4 +--
 15 files changed, 82 insertions(+), 31 deletions(-)

diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 0c9ea66..26724fb 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -1,8 +1,5 @@
 <component name="ProjectCodeStyleConfiguration">
   <code_scheme name="Project" version="173">
-    <AndroidXmlCodeStyleSettings>
-      <option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
-    </AndroidXmlCodeStyleSettings>
     <JetCodeStyleSettings>
       <option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
       <option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" 
value="2147483647" />
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 169fd0d..674414f 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -1,8 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
+  <component name="GradleMigrationSettings" migrationVersion="1" />
   <component name="GradleSettings">
     <option name="linkedExternalProjectsSettings">
       <GradleProjectSettings>
+        <option name="delegatedBuild" value="false" />
+        <option name="testRunner" value="PLATFORM" />
         <option name="distributionType" value="DEFAULT_WRAPPED" />
         <option name="externalProjectPath" value="$PROJECT_DIR$" />
         <option name="modules">
@@ -12,7 +15,6 @@
           </set>
         </option>
         <option name="resolveModulePerSourceSet" value="false" />
-        <option name="testRunner" value="PLATFORM" />
       </GradleProjectSettings>
     </option>
   </component>
diff --git a/app/build.gradle b/app/build.gradle
index 8c72f16..fcc0dd6 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -21,7 +21,7 @@ apply plugin: 'androidx.navigation.safeargs.kotlin'
 
 android {
     compileSdkVersion 29
-    buildToolsVersion "29.0.2"
+    buildToolsVersion "29.0.3"
 
     defaultConfig {
         applicationId "net.taler.cashier"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bf1d766..345c9a1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,6 +3,7 @@
     xmlns:tools="http://schemas.android.com/tools";
     package="net.taler.cashier">
 
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.NFC" />
 
diff --git a/app/src/main/java/net/taler/cashier/BalanceFragment.kt 
b/app/src/main/java/net/taler/cashier/BalanceFragment.kt
index 6cb42e3..b3a0221 100644
--- a/app/src/main/java/net/taler/cashier/BalanceFragment.kt
+++ b/app/src/main/java/net/taler/cashier/BalanceFragment.kt
@@ -35,6 +35,12 @@ import 
net.taler.cashier.BalanceFragmentDirections.Companion.actionBalanceFragme
 import net.taler.cashier.withdraw.LastTransaction
 import net.taler.cashier.withdraw.WithdrawStatus
 
+sealed class BalanceResult {
+    object Error : BalanceResult()
+    object Offline : BalanceResult()
+    class Success(val amount: Amount) : BalanceResult()
+}
+
 class BalanceFragment : Fragment() {
 
     private val viewModel: MainViewModel by activityViewModels()
@@ -52,8 +58,11 @@ class BalanceFragment : Fragment() {
         withdrawManager.lastTransaction.observe(viewLifecycleOwner, Observer { 
lastTransaction ->
             onLastTransaction(lastTransaction)
         })
-        viewModel.balance.observe(viewLifecycleOwner, Observer { balance ->
-            onBalanceUpdated(balance)
+        viewModel.balance.observe(viewLifecycleOwner, Observer { result ->
+            when (result) {
+                is BalanceResult.Success -> onBalanceUpdated(result.amount)
+                else -> onBalanceUpdated(null, result is BalanceResult.Offline)
+            }
         })
         button5.setOnClickListener { onAmountButtonPressed(5) }
         button10.setOnClickListener { onAmountButtonPressed(10) }
@@ -109,19 +118,20 @@ class BalanceFragment : Fragment() {
         else -> super.onOptionsItemSelected(item)
     }
 
-    private fun onBalanceUpdated(amount: Amount?) {
+    private fun onBalanceUpdated(amount: Amount?, isOffline: Boolean = false) {
+        val uiList = listOf(
+            introView,
+            button5, button10, button20, button50,
+            amountView, currencyView, confirmWithdrawalButton
+        )
         if (amount == null) {
-            balanceView.text = getString(R.string.balance_error)
+            balanceView.text =
+                getString(if (isOffline) R.string.balance_offline else 
R.string.balance_error)
+            uiList.forEach { it.fadeOut() }
         } else {
             @SuppressLint("SetTextI18n")
             balanceView.text = "${amount.amount} ${amount.currency}"
-            listOf(
-                introView,
-                button5, button10, button20, button50,
-                amountView,
-                currencyView,
-                confirmWithdrawalButton
-            ).forEach { it.fadeIn() }
+            uiList.forEach { it.fadeIn() }
         }
         progressBar.fadeOut()
     }
diff --git a/app/src/main/java/net/taler/cashier/ConfigFragment.kt 
b/app/src/main/java/net/taler/cashier/ConfigFragment.kt
index dd7c273..b9a97e5 100644
--- a/app/src/main/java/net/taler/cashier/ConfigFragment.kt
+++ b/app/src/main/java/net/taler/cashier/ConfigFragment.kt
@@ -17,6 +17,7 @@
 package net.taler.cashier
 
 import android.os.Bundle
+import android.text.method.LinkMovementMethod
 import android.view.LayoutInflater
 import android.view.View
 import android.view.View.INVISIBLE
@@ -24,6 +25,8 @@ import android.view.View.VISIBLE
 import android.view.ViewGroup
 import android.view.inputmethod.InputMethodManager
 import androidx.core.content.ContextCompat.getSystemService
+import androidx.core.text.HtmlCompat
+import androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
 import androidx.lifecycle.Observer
@@ -33,6 +36,7 @@ import 
com.google.android.material.snackbar.Snackbar.LENGTH_LONG
 import kotlinx.android.synthetic.main.fragment_config.*
 
 private const val URL_BANK_TEST = "https://bank.test.taler.net";
+private const val URL_BANK_TEST_REGISTER = "$URL_BANK_TEST/accounts/register"
 
 class ConfigFragment : Fragment() {
 
@@ -48,7 +52,7 @@ class ConfigFragment : Fragment() {
 
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         if (savedInstanceState == null) {
-            if (viewModel.config.bankUrl.isBlank() && BuildConfig.DEBUG) {
+            if (viewModel.config.bankUrl.isBlank()) {
                 urlView.editText!!.setText(URL_BANK_TEST)
             } else {
                 urlView.editText!!.setText(viewModel.config.bankUrl)
@@ -79,6 +83,10 @@ class ConfigFragment : Fragment() {
                 inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
             }
         }
+        demoView.text = HtmlCompat.fromHtml(
+            getString(R.string.config_demo_hint, URL_BANK_TEST_REGISTER), 
FROM_HTML_MODE_LEGACY
+        )
+        demoView.movementMethod = LinkMovementMethod.getInstance()
     }
 
     override fun onStart() {
diff --git a/app/src/main/java/net/taler/cashier/MainViewModel.kt 
b/app/src/main/java/net/taler/cashier/MainViewModel.kt
index 6f3a0c9..3874038 100644
--- a/app/src/main/java/net/taler/cashier/MainViewModel.kt
+++ b/app/src/main/java/net/taler/cashier/MainViewModel.kt
@@ -44,7 +44,7 @@ private const val PREF_KEY_USERNAME = "username"
 private const val PREF_KEY_PASSWORD = "password"
 private const val PREF_KEY_CURRENCY = "currency"
 
-class MainViewModel(app: Application) : AndroidViewModel(app) {
+class MainViewModel(private val app: Application) : AndroidViewModel(app) {
 
     val configDestination = 
ConfigFragmentDirections.actionGlobalConfigFragment()
 
@@ -67,8 +67,8 @@ class MainViewModel(app: Application) : AndroidViewModel(app) 
{
     private val mConfigResult = MutableLiveData<ConfigResult>()
     val configResult: LiveData<ConfigResult> = mConfigResult
 
-    private val mBalance = MutableLiveData<Amount>()
-    val balance: LiveData<Amount> = mBalance
+    private val mBalance = MutableLiveData<BalanceResult>()
+    val balance: LiveData<BalanceResult> = mBalance
 
     internal val withdrawManager = WithdrawManager(app, this)
 
@@ -123,11 +123,11 @@ class MainViewModel(app: Application) : 
AndroidViewModel(app) {
         val result = when (val response = makeJsonGetRequest(url, config)) {
             is HttpJsonResult.Success -> {
                 val balance = response.json.getString("balance")
-                fromStringSigned(balance)
+                fromStringSigned(balance)?.let { BalanceResult.Success(it) } 
?: BalanceResult.Error
             }
             is HttpJsonResult.Error -> {
-                // show last known value or error string in case of an error
-                mBalance.value
+                if (app.isOnline()) BalanceResult.Error
+                else BalanceResult.Offline
             }
         }
         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 e6cd761..62f7a77 100644
--- a/app/src/main/java/net/taler/cashier/Utils.kt
+++ b/app/src/main/java/net/taler/cashier/Utils.kt
@@ -16,6 +16,11 @@
 
 package net.taler.cashier
 
+import android.content.Context
+import android.content.Context.CONNECTIVITY_SERVICE
+import android.net.ConnectivityManager
+import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
+import android.os.Build.VERSION.SDK_INT
 import android.view.View
 import android.view.View.INVISIBLE
 import android.view.View.VISIBLE
@@ -73,3 +78,14 @@ fun View.fadeOut(endAction: () -> Unit = {}) {
         endAction.invoke()
     }.start()
 }
+
+fun Context.isOnline(): Boolean {
+    val cm = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
+    return if (SDK_INT < 29) {
+        @Suppress("DEPRECATION")
+        cm.activeNetworkInfo?.isConnected == true
+    } else {
+        val capabilities = cm.getNetworkCapabilities(cm.activeNetwork) ?: 
return false
+        capabilities.hasCapability(NET_CAPABILITY_INTERNET)
+    }
+}
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 d92b74a..4c618ac 100644
--- a/app/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt
+++ b/app/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt
@@ -27,6 +27,7 @@ import androidx.lifecycle.viewModelScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.launch
+import net.taler.cashier.BalanceResult
 import net.taler.cashier.HttpHelper.makeJsonGetRequest
 import net.taler.cashier.HttpHelper.makeJsonPostRequest
 import net.taler.cashier.HttpJsonResult.Error
@@ -71,7 +72,9 @@ class WithdrawManager(
 
     @UiThread
     fun hasSufficientBalance(amount: Int): Boolean {
-        val balanceStr = viewModel.balance.value?.amount ?: return false
+        val balanceResult = viewModel.balance.value
+        if (balanceResult !is BalanceResult.Success) return false
+        val balanceStr = balanceResult.amount.amount
         val balanceDouble = balanceStr.toDouble()
         return amount <= balanceDouble
     }
diff --git a/app/src/main/res/layout-w550dp/fragment_balance.xml 
b/app/src/main/res/layout-w550dp/fragment_balance.xml
index 4ed92b4..d04698b 100644
--- a/app/src/main/res/layout-w550dp/fragment_balance.xml
+++ b/app/src/main/res/layout-w550dp/fragment_balance.xml
@@ -68,9 +68,10 @@
 
     <TextView
         android:id="@+id/balanceView"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_margin="@dimen/default_margin"
+        android:gravity="center"
         android:textAppearance="@style/TextAppearance.AppCompat.Headline"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toStartOf="@+id/guideline"
diff --git a/app/src/main/res/layout/fragment_balance.xml 
b/app/src/main/res/layout/fragment_balance.xml
index 3ab6423..5dafc59 100644
--- a/app/src/main/res/layout/fragment_balance.xml
+++ b/app/src/main/res/layout/fragment_balance.xml
@@ -63,10 +63,11 @@
 
     <TextView
         android:id="@+id/balanceView"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:paddingStart="@dimen/default_margin"
         android:paddingTop="8dp"
+        android:gravity="center"
         android:paddingEnd="@dimen/default_margin"
         android:paddingBottom="@dimen/default_margin"
         android:textAppearance="@style/TextAppearance.AppCompat.Headline"
diff --git a/app/src/main/res/layout/fragment_config.xml 
b/app/src/main/res/layout/fragment_config.xml
index 2bf17e2..47ec6f9 100644
--- a/app/src/main/res/layout/fragment_config.xml
+++ b/app/src/main/res/layout/fragment_config.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
   ~ This file is part of GNU Taler
   ~ (C) 2020 Taler Systems S.A.
   ~
@@ -28,6 +27,7 @@
         android:layout_height="wrap_content"
         android:layout_margin="@dimen/default_margin"
         android:hint="@string/config_bank_url"
+        app:endIconMode="clear_text"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent">
@@ -99,4 +99,14 @@
         app:layout_constraintTop_toTopOf="@+id/saveButton"
         tools:visibility="visible" />
 
+    <TextView
+        android:id="@+id/demoView"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_margin="@dimen/default_margin"
+        android:text="@string/config_demo_hint"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/saveButton" />
+
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/values/strings.xml 
b/app/src/main/res/values/strings.xml
index 37c4d92..5df5bfa 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -9,9 +9,11 @@
     <string name="config_username_error">Please enter your username</string>
     <string name="config_error">Error retrieving configuration</string>
     <string name="config_error_auth">Invalid username or password</string>
+    <string name="config_demo_hint">For testing, you can <![CDATA[<a 
href="%s">create a test account at the demo bank</a>]]>.</string>
 
     <string name="balance_current_label">Current balance</string>
     <string name="balance_error">ERROR</string>
+    <string name="balance_offline">Offline. Please connect to the 
Internet</string>
     <string name="action_reconfigure">Reconfigure</string>
     <string name="action_lock">Lock</string>
 
diff --git a/build.gradle b/build.gradle
index 0e297f6..e3fbed6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@ buildscript {
         
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.5.3'
+        classpath 'com.android.tools.build:gradle:3.6.1'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
         classpath 
"androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
     }
diff --git a/gradle/wrapper/gradle-wrapper.properties 
b/gradle/wrapper/gradle-wrapper.properties
index 608e7b6..43d1305 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Tue Feb 04 07:46:02 BRT 2020
+#Mon Mar 02 09:39:10 BRT 2020
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip

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



reply via email to

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