gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-android] 01/03: Support base64 encoded images in rfc2397 d


From: gnunet
Subject: [taler-wallet-android] 01/03: Support base64 encoded images in rfc2397 data URLs for product images
Date: Wed, 11 Mar 2020 13:58:29 +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 6b7b8070355d44841a9602e7790e22a0a86b37ca
Author: Torsten Grote <address@hidden>
AuthorDate: Tue Mar 10 15:01:20 2020 -0300

    Support base64 encoded images in rfc2397 data URLs for product images
---
 .../java/net/taler/wallet/payment/ContractTerms.kt |  6 +++--
 .../net/taler/wallet/payment/PaymentManager.kt     | 21 +++++++++++++--
 .../net/taler/wallet/payment/ProductAdapter.kt     | 16 +++++++++++
 app/src/main/res/layout/list_item_product.xml      | 31 +++++++++++++++++-----
 4 files changed, 64 insertions(+), 10 deletions(-)

diff --git a/app/src/main/java/net/taler/wallet/payment/ContractTerms.kt 
b/app/src/main/java/net/taler/wallet/payment/ContractTerms.kt
index a9f75ed..da91dea 100644
--- a/app/src/main/java/net/taler/wallet/payment/ContractTerms.kt
+++ b/app/src/main/java/net/taler/wallet/payment/ContractTerms.kt
@@ -29,20 +29,22 @@ data class ContractTerms(
 )
 
 interface Product {
-    val id: String
+    val id: String?
     val description: String
     val price: Amount
     val location: String?
+    val image: String?
 }
 
 @JsonIgnoreProperties("totalPrice")
 data class ContractProduct(
     @JsonProperty("product_id")
-    override val id: String,
+    override val id: String?,
     override val description: String,
     override val price: Amount,
     @JsonProperty("delivery_location")
     override val location: String?,
+    override val image: String?,
     val quantity: Int
 ) : Product {
 
diff --git a/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt 
b/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt
index a00a686..ee0edaf 100644
--- a/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt
+++ b/app/src/main/java/net/taler/wallet/payment/PaymentManager.kt
@@ -26,6 +26,9 @@ import net.taler.wallet.Amount
 import net.taler.wallet.TAG
 import net.taler.wallet.backend.WalletBackendApi
 import org.json.JSONObject
+import java.net.MalformedURLException
+
+val REGEX_PRODUCT_IMAGE = 
Regex("^data:image/(jpeg|png);base64,([A-Za-z0-9+/=]+)$")
 
 class PaymentManager(
     private val walletBackendApi: WalletBackendApi,
@@ -61,7 +64,12 @@ class PaymentManager(
                 }
                 else -> {
                     val status = result.getString("status")
-                    mPayStatus.postValue(getPayStatusUpdate(status, result))
+                    try {
+                        mPayStatus.postValue(getPayStatusUpdate(status, 
result))
+                    } catch (e: Exception) {
+                        Log.e(TAG, "Error getting PayStatusUpdate", e)
+                        mPayStatus.postValue(PayStatus.Error(e.message ?: 
"unknown error"))
+                    }
                 }
             }
         }
@@ -80,7 +88,16 @@ class PaymentManager(
     }
 
     private fun getContractTerms(json: JSONObject): ContractTerms {
-        return mapper.readValue(json.getString("contractTermsRaw"))
+        val terms: ContractTerms = 
mapper.readValue(json.getString("contractTermsRaw"))
+        // validate product images
+        terms.products.forEach { product ->
+            product.image?.let { image ->
+                if (REGEX_PRODUCT_IMAGE.matchEntire(image) == null) {
+                    throw MalformedURLException("Invalid image data URL for 
${product.description}")
+                }
+            }
+        }
+        return terms
     }
 
     @UiThread
diff --git a/app/src/main/java/net/taler/wallet/payment/ProductAdapter.kt 
b/app/src/main/java/net/taler/wallet/payment/ProductAdapter.kt
index 3a0dca6..8519dcb 100644
--- a/app/src/main/java/net/taler/wallet/payment/ProductAdapter.kt
+++ b/app/src/main/java/net/taler/wallet/payment/ProductAdapter.kt
@@ -16,9 +16,14 @@
 
 package net.taler.wallet.payment
 
+import android.graphics.BitmapFactory.decodeByteArray
+import android.util.Base64
 import android.view.LayoutInflater
 import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
 import android.view.ViewGroup
+import android.widget.ImageView
 import android.widget.TextView
 import androidx.recyclerview.widget.RecyclerView
 import androidx.recyclerview.widget.RecyclerView.ViewHolder
@@ -50,11 +55,22 @@ internal class ProductAdapter : 
RecyclerView.Adapter<ProductViewHolder>() {
 
     internal inner class ProductViewHolder(v: View) : ViewHolder(v) {
         private val quantity: TextView = v.findViewById(R.id.quantity)
+        private val image: ImageView = v.findViewById(R.id.image)
         private val name: TextView = v.findViewById(R.id.name)
         private val price: TextView = v.findViewById(R.id.price)
 
         fun bind(product: ContractProduct) {
             quantity.text = product.quantity.toString()
+            if (product.image == null) {
+                image.visibility = GONE
+            } else {
+                image.visibility = VISIBLE
+                // product.image was validated before, so non-null below
+                val match = REGEX_PRODUCT_IMAGE.matchEntire(product.image)!!
+                val decodedString = Base64.decode(match.groups[2]!!.value, 
Base64.DEFAULT)
+                val bitmap = decodeByteArray(decodedString, 0, 
decodedString.size)
+                image.setImageBitmap(bitmap)
+            }
             name.text = product.description
             price.text = product.totalPrice.toString()
         }
diff --git a/app/src/main/res/layout/list_item_product.xml 
b/app/src/main/res/layout/list_item_product.xml
index 606022e..fe6ba23 100644
--- a/app/src/main/res/layout/list_item_product.xml
+++ b/app/src/main/res/layout/list_item_product.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.
   ~
@@ -20,9 +19,7 @@
         xmlns:tools="http://schemas.android.com/tools";
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:paddingStart="8dp"
-        android:paddingTop="8dp"
-        android:paddingEnd="8dp">
+        android:padding="8dp">
 
     <TextView
             android:id="@+id/quantity"
@@ -30,27 +27,49 @@
             android:layout_height="wrap_content"
             android:gravity="end"
             android:minWidth="24dp"
+            app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.0"
             tools:text="31" />
 
+    <ImageView
+            android:id="@+id/image"
+            android:layout_width="wrap_content"
+            android:layout_height="0dp"
+            android:layout_marginStart="8dp"
+            app:layout_constrainedWidth="true"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintDimensionRatio="H,4:3"
+            app:layout_constraintEnd_toStartOf="@+id/name"
+            app:layout_constraintStart_toEndOf="@+id/quantity"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintWidth_max="64dp"
+            tools:ignore="ContentDescription"
+            tools:srcCompat="@tools:sample/avatars"
+            tools:visibility="visible" />
+
     <TextView
             android:id="@+id/name"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_marginStart="8dp"
             android:layout_marginEnd="8dp"
+            app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toStartOf="@+id/price"
-            app:layout_constraintStart_toEndOf="@+id/quantity"
+            app:layout_constraintStart_toEndOf="@+id/image"
             app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.0"
             tools:text="A product item that in some cases could have a very 
long name" />
 
     <TextView
             android:id="@+id/price"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_bias="0.0"
             tools:text="23.42" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>

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



reply via email to

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