gnunet-svn
[Top][All Lists]
Advanced

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

[taler-taler-android] branch master updated: [wallet] implement transact


From: gnunet
Subject: [taler-taler-android] branch master updated: [wallet] implement transaction search
Date: Wed, 20 May 2020 16:48:15 +0200

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

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

The following commit(s) were added to refs/heads/master by this push:
     new b086928  [wallet] implement transaction search
b086928 is described below

commit b0869289dc9fa2f983991915e77ba0260e59ed8b
Author: Torsten Grote <address@hidden>
AuthorDate: Wed May 20 11:47:26 2020 -0300

    [wallet] implement transaction search
---
 .../src/main/java/net/taler/common/AndroidUtils.kt |  2 +-
 .../wallet/transactions/TransactionManager.kt      | 35 ++++++++-----
 .../wallet/transactions/TransactionsFragment.kt    | 57 +++++++++++++++++-----
 wallet/src/main/res/drawable/ic_search.xml         | 10 ++++
 wallet/src/main/res/layout/app_bar_main.xml        |  1 +
 wallet/src/main/res/menu/transactions.xml          |  6 +++
 wallet/src/main/res/values/strings.xml             |  2 +
 7 files changed, 87 insertions(+), 26 deletions(-)

diff --git a/taler-kotlin-common/src/main/java/net/taler/common/AndroidUtils.kt 
b/taler-kotlin-common/src/main/java/net/taler/common/AndroidUtils.kt
index 3ab45ad..fda537b 100644
--- a/taler-kotlin-common/src/main/java/net/taler/common/AndroidUtils.kt
+++ b/taler-kotlin-common/src/main/java/net/taler/common/AndroidUtils.kt
@@ -43,7 +43,7 @@ import androidx.navigation.NavDirections
 import androidx.navigation.fragment.findNavController
 
 fun View.fadeIn(endAction: () -> Unit = {}) {
-    if (visibility == VISIBLE) return
+    if (visibility == VISIBLE && alpha == 1f) return
     alpha = 0f
     visibility = VISIBLE
     animate().alpha(1f).withEndAction {
diff --git 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt
index d5cee16..882b29b 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt
@@ -20,6 +20,7 @@ import androidx.annotation.UiThread
 import androidx.annotation.WorkerThread
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.switchMap
 import com.fasterxml.jackson.databind.ObjectMapper
 import com.fasterxml.jackson.module.kotlin.readValue
 import kotlinx.coroutines.CoroutineScope
@@ -46,26 +47,36 @@ class TransactionManager(
     var selectedCurrency: String? = null
     var selectedTransaction: Transaction? = null
 
+    val searchQuery = MutableLiveData<String>(null)
+    private val allTransactions = HashMap<String, List<Transaction>>()
     private val mTransactions = HashMap<String, 
MutableLiveData<TransactionsResult>>()
     val transactions: LiveData<TransactionsResult>
         @UiThread
-        get() {
+        get() = searchQuery.switchMap { query ->
             val currency = selectedCurrency
             check(currency != null) { "Did not select currency before getting 
transactions" }
-            return mTransactions.getOrPut(currency) { MutableLiveData() }
+            loadTransactions(query)
+            mTransactions[currency]!! // non-null because filled in 
[loadTransactions]
         }
 
     @UiThread
-    fun loadTransactions() {
+    fun loadTransactions(searchQuery: String? = null) {
         val currency = selectedCurrency ?: return
-        val liveData = mTransactions.getOrPut(currency) {
-            MutableLiveData<TransactionsResult>()
+        val liveData = mTransactions.getOrPut(currency) { MutableLiveData() }
+        if (searchQuery == null && allTransactions.containsKey(currency)) {
+            liveData.value = 
TransactionsResult.Success(allTransactions[currency]!!)
         }
         if (liveData.value == null) mProgress.value = true
         val request = JSONObject(mapOf("currency" to currency))
+        searchQuery?.let { request.put("search", it) }
         walletBackendApi.sendRequest("getTransactions", request) { isError, 
result ->
-            scope.launch(Dispatchers.Default) {
-                onTransactionsLoaded(liveData, isError, result)
+            if (isError) {
+                liveData.postValue(TransactionsResult.Error)
+            } else {
+                val currencyToUpdate = if (searchQuery == null) currency else 
null
+                scope.launch(Dispatchers.Default) {
+                    onTransactionsLoaded(liveData, currencyToUpdate, result)
+                }
             }
         }
     }
@@ -73,13 +84,9 @@ class TransactionManager(
     @WorkerThread
     private fun onTransactionsLoaded(
         liveData: MutableLiveData<TransactionsResult>,
-        isError: Boolean,
+        currency: String?,  // only non-null if we should update all 
transactions cache
         result: JSONObject
     ) {
-        if (isError) {
-            liveData.postValue(TransactionsResult.Error)
-            return
-        }
         val transactionsArray = result.getString("transactions")
         val transactions: LinkedList<Transaction> = 
mapper.readValue(transactionsArray)
         // TODO remove when fixed in wallet-core
@@ -87,6 +94,10 @@ class TransactionManager(
         transactions.reverse()  // show latest first
         mProgress.postValue(false)
         liveData.postValue(TransactionsResult.Success(transactions))
+        // update all transactions on UiThread if there was a currency
+        currency?.let {
+            scope.launch(Dispatchers.Main) { allTransactions[currency] = 
transactions }
+        }
     }
 
     @UiThread
diff --git 
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt 
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
index dfd00ea..526aa94 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
@@ -23,11 +23,11 @@ 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.widget.Toast
 import android.widget.Toast.LENGTH_LONG
+import androidx.appcompat.widget.SearchView
+import androidx.appcompat.widget.SearchView.OnQueryTextListener
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
 import androidx.lifecycle.Observer
@@ -102,14 +102,11 @@ class TransactionsFragment : Fragment(), 
OnTransactionClickListener, ActionMode.
         })
 
         transactionManager.progress.observe(viewLifecycleOwner, Observer { 
show ->
-            progressBar.visibility = if (show) VISIBLE else INVISIBLE
+            if (show) progressBar.fadeIn() else progressBar.fadeOut()
         })
         transactionManager.transactions.observe(viewLifecycleOwner, Observer { 
result ->
             onTransactionsResult(result)
         })
-
-        // kicks off initial load, needs to be adapted if showAll state is 
ever saved
-        if (savedInstanceState == null) transactionManager.loadTransactions()
     }
 
     override fun onActivityCreated(savedInstanceState: Bundle?) {
@@ -129,12 +126,29 @@ class TransactionsFragment : Fragment(), 
OnTransactionClickListener, ActionMode.
 
     override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
         inflater.inflate(R.menu.transactions, menu)
+        setupSearch(menu.findItem(R.id.action_search))
     }
 
-    override fun onOptionsItemSelected(item: MenuItem): Boolean {
-        return when (item.itemId) {
-            else -> super.onOptionsItemSelected(item)
-        }
+    private fun setupSearch(item: MenuItem) {
+        item.setOnActionExpandListener(object : 
MenuItem.OnActionExpandListener {
+            override fun onMenuItemActionExpand(item: MenuItem) = true
+            override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
+                onSearchClosed()
+                return true
+            }
+        })
+        val searchView = item.actionView as SearchView
+        searchView.setOnQueryTextListener(object : OnQueryTextListener {
+            override fun onQueryTextChange(newText: String) = false
+            override fun onQueryTextSubmit(query: String): Boolean {
+                // workaround to avoid issues with some emulators and keyboard 
devices
+                // firing twice if a keyboard enter is used
+                // see https://code.google.com/p/android/issues/detail?id=24599
+                item.actionView.clearFocus()
+                onSearch(query)
+                return true
+            }
+        })
     }
 
     override fun onTransactionClicked(transaction: Transaction) {
@@ -152,12 +166,29 @@ class TransactionsFragment : Fragment(), 
OnTransactionClickListener, ActionMode.
             emptyState.fadeIn()
         }
         is TransactionsResult.Success -> {
-            emptyState.visibility = if (result.transactions.isEmpty()) VISIBLE 
else INVISIBLE
-            transactionAdapter.update(result.transactions)
-            list.fadeIn()
+            if (result.transactions.isEmpty()) {
+                val isSearch = transactionManager.searchQuery.value != null
+                emptyState.setText(if (isSearch) 
R.string.transactions_empty_search else R.string.transactions_empty)
+                emptyState.fadeIn()
+                list.fadeOut()
+            } else {
+                emptyState.fadeOut()
+                transactionAdapter.update(result.transactions)
+                list.fadeIn()
+            }
         }
     }
 
+    private fun onSearch(query: String) {
+        list.fadeOut()
+        progressBar.fadeIn()
+        transactionManager.searchQuery.value = query
+    }
+
+    private fun onSearchClosed() {
+        transactionManager.searchQuery.value = null
+    }
+
     override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
         val inflater = mode.menuInflater
         inflater.inflate(R.menu.transactions_action_mode, menu)
diff --git a/wallet/src/main/res/drawable/ic_search.xml 
b/wallet/src/main/res/drawable/ic_search.xml
new file mode 100644
index 0000000..13e67fe
--- /dev/null
+++ b/wallet/src/main/res/drawable/ic_search.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android";
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="?attr/colorControlNormal"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 
16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 
4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 
5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
+</vector>
diff --git a/wallet/src/main/res/layout/app_bar_main.xml 
b/wallet/src/main/res/layout/app_bar_main.xml
index 5ee55b2..6937e59 100644
--- a/wallet/src/main/res/layout/app_bar_main.xml
+++ b/wallet/src/main/res/layout/app_bar_main.xml
@@ -36,6 +36,7 @@
                 style="@style/AppTheme.Toolbar"
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
+                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
                 app:layout_constraintTop_toTopOf="parent" />
diff --git a/wallet/src/main/res/menu/transactions.xml 
b/wallet/src/main/res/menu/transactions.xml
index d4568d4..2ea8a23 100644
--- a/wallet/src/main/res/menu/transactions.xml
+++ b/wallet/src/main/res/menu/transactions.xml
@@ -16,4 +16,10 @@
 
 <menu xmlns:android="http://schemas.android.com/apk/res/android";
     xmlns:app="http://schemas.android.com/apk/res-auto";>
+    <item
+        android:id="@+id/action_search"
+        android:icon="@drawable/ic_search"
+        android:title="@string/search"
+        app:actionViewClass="androidx.appcompat.widget.SearchView"
+        app:showAsAction="always|collapseActionView" />
 </menu>
diff --git a/wallet/src/main/res/values/strings.xml 
b/wallet/src/main/res/values/strings.xml
index 7d76806..167ab53 100644
--- a/wallet/src/main/res/values/strings.xml
+++ b/wallet/src/main/res/values/strings.xml
@@ -45,6 +45,7 @@ GNU Taler is immune against many types of fraud, such as 
phishing of credit card
 
     <string name="button_back">Go Back</string>
     <string name="button_scan_qr_code">Scan Taler QR Code</string>
+    <string name="search">Search</string>
 
     <string name="menu_settings">Settings</string>
     <string name="menu_retry_pending_operations">Retry Pending 
Operations</string>
@@ -61,6 +62,7 @@ GNU Taler is immune against many types of fraud, such as 
phishing of credit card
 
     <string name="transactions_title">Transactions</string>
     <string name="transactions_empty">You don\'t have any transactions</string>
+    <string name="transactions_empty_search">No transactions found. Try a 
different search.</string>
     <string name="transactions_error">Could not load transactions</string>
     <string name="transactions_detail_title">Transaction</string>
     <string name="transactions_detail_title_balance">Balance: %s</string>

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



reply via email to

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