gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-android] 02/10: Use special layout for withdraw event in w


From: gnunet
Subject: [taler-wallet-android] 02/10: Use special layout for withdraw event in wallet history
Date: Thu, 30 Jan 2020 18:40:10 +0100

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

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

commit 35ba17db04f48f4ec41f55ac6944051093f7b78b
Author: Torsten Grote <address@hidden>
AuthorDate: Fri Dec 27 11:13:19 2019 -0300

    Use special layout for withdraw event in wallet history
    
    This is how it could be done for all event types.
---
 .../main/java/net/taler/wallet/WalletViewModel.kt  | 27 +++-----
 .../java/net/taler/wallet/history/HistoryEvent.kt  |  7 --
 .../java/net/taler/wallet/history/WalletHistory.kt | 13 ++--
 .../taler/wallet/history/WalletHistoryAdapter.kt   | 75 +++++++++++++++++-----
 app/src/main/res/drawable/history_withdrawn.xml    |  9 +++
 app/src/main/res/layout/fragment_show_history.xml  |  3 +-
 app/src/main/res/layout/history_row.xml            | 34 +++++-----
 app/src/main/res/layout/history_withdrawn.xml      | 71 ++++++++++++++++++++
 app/src/main/res/values/strings.xml                |  2 +
 9 files changed, 173 insertions(+), 68 deletions(-)

diff --git a/app/src/main/java/net/taler/wallet/WalletViewModel.kt 
b/app/src/main/java/net/taler/wallet/WalletViewModel.kt
index 291321d..94d2d8a 100644
--- a/app/src/main/java/net/taler/wallet/WalletViewModel.kt
+++ b/app/src/main/java/net/taler/wallet/WalletViewModel.kt
@@ -20,8 +20,11 @@ import android.app.Application
 import android.util.Log
 import androidx.lifecycle.AndroidViewModel
 import androidx.lifecycle.MutableLiveData
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.module.kotlin.KotlinModule
+import com.fasterxml.jackson.module.kotlin.readValue
 import net.taler.wallet.backend.WalletBackendApi
-import net.taler.wallet.history.HistoryEntry
+import net.taler.wallet.history.History
 import org.json.JSONObject
 
 const val TAG = "taler-wallet"
@@ -94,10 +97,6 @@ open class WithdrawStatus {
     data class Withdrawing(val talerWithdrawUri: String) : WithdrawStatus()
 }
 
-open class HistoryResult(
-    val history: List<HistoryEntry>
-)
-
 open class PendingOperationInfo(
     val type: String,
     val detail: JSONObject
@@ -138,6 +137,7 @@ class WalletViewModel(val app: Application) : 
AndroidViewModel(app) {
     private var currentWithdrawRequestId = 0
 
     private val walletBackendApi = WalletBackendApi(app)
+    private val mapper = ObjectMapper().registerModule(KotlinModule())
 
     fun init() {
         if (initialized) {
@@ -214,23 +214,14 @@ class WalletViewModel(val app: Application) : 
AndroidViewModel(app) {
         }
     }
 
-    fun getHistory(cb: (r: HistoryResult) -> Unit) {
+    fun getHistory(cb: (r: History) -> Unit) {
         walletBackendApi.sendRequest("getHistory", null) { isError, result ->
             if (isError) {
+                // TODO show error message in [WalletHistory] fragment
                 return@sendRequest
             }
-            val historyEntries = mutableListOf<HistoryEntry>()
-            val historyList = result.getJSONArray("history")
-            for (i in 0 until historyList.length()) {
-                val h = historyList.getJSONObject(i)
-                Log.v(TAG, "got history entry $h")
-                val type = h.getString("type")
-                Log.v(TAG, "got history entry type $type")
-                val detail = h
-                val timestamp = h.getJSONObject("timestamp")
-                historyEntries.add(HistoryEntry(detail, type, timestamp))
-            }
-            cb(HistoryResult(historyEntries))
+            val history: History = 
mapper.readValue(result.getString("history"))
+            cb(history)
         }
     }
 
diff --git a/app/src/main/java/net/taler/wallet/history/HistoryEvent.kt 
b/app/src/main/java/net/taler/wallet/history/HistoryEvent.kt
index be48ac9..34f3164 100644
--- a/app/src/main/java/net/taler/wallet/history/HistoryEvent.kt
+++ b/app/src/main/java/net/taler/wallet/history/HistoryEvent.kt
@@ -5,13 +5,6 @@ import 
com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY
 import com.fasterxml.jackson.annotation.JsonSubTypes.Type
 import com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY
 import com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME
-import org.json.JSONObject
-
-open class HistoryEntry(
-    val detail: JSONObject,
-    val type: String,
-    val timestamp: JSONObject
-)
 
 enum class ReserveType {
     /**
diff --git a/app/src/main/java/net/taler/wallet/history/WalletHistory.kt 
b/app/src/main/java/net/taler/wallet/history/WalletHistory.kt
index 89c6b3f..cdc90ae 100644
--- a/app/src/main/java/net/taler/wallet/history/WalletHistory.kt
+++ b/app/src/main/java/net/taler/wallet/history/WalletHistory.kt
@@ -24,7 +24,6 @@ import androidx.lifecycle.ViewModelProviders
 import androidx.recyclerview.widget.DividerItemDecoration
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
-import net.taler.wallet.HistoryResult
 import net.taler.wallet.R
 import net.taler.wallet.WalletViewModel
 
@@ -35,17 +34,13 @@ import net.taler.wallet.WalletViewModel
 class WalletHistory : Fragment() {
 
     lateinit var model: WalletViewModel
-    lateinit var historyAdapter: WalletHistoryAdapter
+    private val historyAdapter = WalletHistoryAdapter()
     lateinit var historyPlaceholder: View
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setHasOptionsMenu(true)
 
-        historyAdapter = WalletHistoryAdapter(
-            HistoryResult(listOf())
-        )
-
         model = activity?.run {
             ViewModelProviders.of(this)[WalletViewModel::class.java]
         } ?: throw Exception("Invalid Activity")
@@ -68,7 +63,7 @@ class WalletHistory : Fragment() {
 
     private fun updateHistory() {
         model.getHistory {
-            if (it.history.isEmpty()) {
+            if (it.isEmpty()) {
                 historyPlaceholder.visibility = View.VISIBLE
             }
             historyAdapter.update(it)
@@ -81,7 +76,9 @@ class WalletHistory : Fragment() {
     ): View? {
         // Inflate the layout for this fragment
         val view = inflater.inflate(R.layout.fragment_show_history, container, 
false)
-        val myLayoutManager = LinearLayoutManager(context)
+        val myLayoutManager = LinearLayoutManager(context).apply {
+            reverseLayout = true  // show latest events first
+        }
         val myItemDecoration = DividerItemDecoration(context, 
myLayoutManager.orientation)
         view.findViewById<RecyclerView>(R.id.list_history).apply {
             layoutManager = myLayoutManager
diff --git a/app/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt 
b/app/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt
index 46bca30..37dc742 100644
--- a/app/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt
+++ b/app/src/main/java/net/taler/wallet/history/WalletHistoryAdapter.kt
@@ -1,41 +1,82 @@
 package net.taler.wallet.history
 
+import android.text.format.DateUtils.*
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-import net.taler.wallet.HistoryResult
+import androidx.annotation.CallSuper
+import androidx.recyclerview.widget.RecyclerView.Adapter
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
 import net.taler.wallet.R
 
 
-class WalletHistoryAdapter(private var myDataset: HistoryResult) : 
RecyclerView.Adapter<WalletHistoryAdapter.MyViewHolder>() {
+internal class WalletHistoryAdapter(private var history: History = History()) :
+    Adapter<HistoryEventViewHolder>() {
 
     init {
         setHasStableIds(false)
     }
 
-    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): 
MyViewHolder {
-        val rowView = 
LayoutInflater.from(parent.context).inflate(R.layout.history_row, parent, false)
-        return MyViewHolder(rowView)
+    override fun getItemViewType(position: Int): Int = when 
(history[position]) {
+        is HistoryWithdrawnEvent -> R.layout.history_withdrawn
+        else -> R.layout.history_row
     }
 
-    override fun getItemCount(): Int {
-        return myDataset.history.size
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): 
HistoryEventViewHolder {
+        val view = LayoutInflater.from(parent.context).inflate(viewType, 
parent, false)
+        return when (viewType) {
+            R.layout.history_withdrawn -> HistoryWithdrawnEventViewHolder(view)
+            else -> HistoryEventViewHolder(view)
+        }
     }
 
-    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
-        val h = myDataset.history[myDataset.history.size - position - 1]
-        val text = holder.rowView.findViewById<TextView>(R.id.history_text)
-        val subText = 
holder.rowView.findViewById<TextView>(R.id.history_subtext)
-        text.text = h.type
-        subText.text = h.timestamp.toString() + "\n" + h.detail.toString(1)
+    override fun getItemCount(): Int = history.size
+
+    override fun onBindViewHolder(holder: HistoryEventViewHolder, position: 
Int) {
+        val event = history[position]
+        holder.bind(event)
     }
 
-    fun update(updatedHistory: HistoryResult) {
-        this.myDataset = updatedHistory
+    fun update(updatedHistory: History) {
+        this.history = updatedHistory
         this.notifyDataSetChanged()
     }
 
-    class MyViewHolder(val rowView: View) : RecyclerView.ViewHolder(rowView)
+}
+
+internal open class HistoryEventViewHolder(protected val v: View) : 
ViewHolder(v) {
+
+    protected val title: TextView = v.findViewById(R.id.title)
+    private val time: TextView = v.findViewById(R.id.time)
+
+    @CallSuper
+    open fun bind(event: HistoryEvent) {
+        title.text = event::class.java.simpleName
+        time.text = getRelativeTime(event.timestamp.ms)
+    }
+
+    private fun getRelativeTime(timestamp: Long): CharSequence {
+        val now = System.currentTimeMillis()
+        return getRelativeTimeSpanString(timestamp, now, MINUTE_IN_MILLIS, 
FORMAT_ABBREV_RELATIVE)
+    }
+
+    protected fun getString(resId: Int) = v.context.getString(resId)
+
+}
+
+internal class HistoryWithdrawnEventViewHolder(v: View) : 
HistoryEventViewHolder(v) {
+
+    private val amountWithdrawnRaw: TextView = 
v.findViewById(R.id.amountWithdrawnRaw)
+    private val amountWithdrawnEffective: TextView = 
v.findViewById(R.id.amountWithdrawnEffective)
+
+    override fun bind(event: HistoryEvent) {
+        super.bind(event)
+        event as HistoryWithdrawnEvent
+
+        title.text = getString(R.string.history_event_withdrawn)
+        amountWithdrawnRaw.text = event.amountWithdrawnRaw
+        amountWithdrawnEffective.text = event.amountWithdrawnEffective
+    }
+
 }
diff --git a/app/src/main/res/drawable/history_withdrawn.xml 
b/app/src/main/res/drawable/history_withdrawn.xml
new file mode 100644
index 0000000..f6bb884
--- /dev/null
+++ b/app/src/main/res/drawable/history_withdrawn.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android";
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+            android:fillColor="#000"
+            android:pathData="M3 0V3H0V5H3V8H5V5H8V3H5V0H3M9 3V6H6V9H3V19C3 
20.1 3.89 21 5 21H19C20.11 21 21 20.11 21 19V18H12C10.9 18 10 17.11 10 16V8C10 
6.9 10.89 6 12 6H21V5C21 3.9 20.11 3 19 3H9M12 8V16H22V8H12M16 10.5C16.83 10.5 
17.5 11.17 17.5 12C17.5 12.83 16.83 13.5 16 13.5C15.17 13.5 14.5 12.83 14.5 
12C14.5 11.17 15.17 10.5 16 10.5Z" />
+</vector>
diff --git a/app/src/main/res/layout/fragment_show_history.xml 
b/app/src/main/res/layout/fragment_show_history.xml
index 4ed11ac..6265a50 100644
--- a/app/src/main/res/layout/fragment_show_history.xml
+++ b/app/src/main/res/layout/fragment_show_history.xml
@@ -3,8 +3,7 @@
         xmlns:android="http://schemas.android.com/apk/res/android";
         xmlns:tools="http://schemas.android.com/tools";
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_margin="15dp">
+        android:layout_height="match_parent">
 
     <LinearLayout
             android:layout_width="match_parent"
diff --git a/app/src/main/res/layout/history_row.xml 
b/app/src/main/res/layout/history_row.xml
index 669fbd1..2ea6d9d 100644
--- a/app/src/main/res/layout/history_row.xml
+++ b/app/src/main/res/layout/history_row.xml
@@ -1,22 +1,24 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android";
-              xmlns:tools="http://schemas.android.com/tools";
-              android:orientation="vertical"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content">
+        xmlns:tools="http://schemas.android.com/tools";
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_margin="15dp">
 
-        <TextView
-                  android:layout_width="wrap_content"
-                  android:layout_height="wrap_content"
-                  android:id="@+id/history_text"
-                  android:textSize="24sp" tools:text="My History Event">
-        </TextView>
+    <TextView
+            android:id="@+id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="24sp"
+            tools:text="My History Event"/>
 
-        <TextView
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:id="@+id/history_subtext"
-                android:textSize="14sp" tools:text="My History Event">
-        </TextView>
+    <TextView
+            android:id="@+id/time"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="end"
+            android:textSize="14sp"
+            tools:text="3 days ago"/>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/history_withdrawn.xml 
b/app/src/main/res/layout/history_withdrawn.xml
new file mode 100644
index 0000000..8290c37
--- /dev/null
+++ b/app/src/main/res/layout/history_withdrawn.xml
@@ -0,0 +1,71 @@
+<?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:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="16dp"
+        android:layout_marginBottom="8dp">
+
+    <ImageView
+            android:id="@+id/icon"
+            android:layout_width="32dp"
+            android:layout_height="32dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:srcCompat="@drawable/history_withdrawn"
+            app:tint="?android:colorControlNormal"
+            tools:ignore="ContentDescription" />
+
+    <TextView
+            android:id="@+id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
+            android:text="@string/history_event_withdrawn"
+            android:textColor="?android:textColorPrimary"
+            android:textSize="20sp"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.0"
+            app:layout_constraintStart_toEndOf="@+id/icon"
+            app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+            android:id="@+id/amountWithdrawnRaw"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
+            android:layout_marginEnd="8dp"
+            
app:layout_constraintBottom_toBottomOf="@+id/amountWithdrawnEffective"
+            app:layout_constraintEnd_toStartOf="@+id/amountWithdrawnEffective"
+            app:layout_constraintHorizontal_bias="1.0"
+            app:layout_constraintStart_toEndOf="@+id/icon"
+            app:layout_constraintTop_toTopOf="@+id/amountWithdrawnEffective"
+            tools:text="TESTKUDOS:10" />
+
+    <TextView
+            android:id="@+id/amountWithdrawnEffective"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
+            android:textSize="16sp"
+            android:textColor="?android:textColorPrimary"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/title"
+            tools:text="TESTKUDOS:9.8" />
+
+    <TextView
+            android:id="@+id/time"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
+            android:textSize="14sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/amountWithdrawnEffective"
+            tools:text="23 min ago" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/values/strings.xml 
b/app/src/main/res/values/strings.xml
index cfd2213..82b942b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -16,6 +16,8 @@
     <string name="servicedesc">my service</string>
     <string name="aiddescription">my aid</string>
 
+    <string name="history_event_withdrawn">Withdraw</string>
+
     <!-- TODO: Remove or change this placeholder text -->
     <string name="hello_blank_fragment">Hello blank fragment</string>
 </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]