gnunet-svn
[Top][All Lists]
Advanced

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

[taler-taler-android] branch master updated (e52ee8f -> d72548e)


From: gnunet
Subject: [taler-taler-android] branch master updated (e52ee8f -> d72548e)
Date: Fri, 03 Apr 2020 20:27:42 +0200

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

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

    from e52ee8f  [wallet] Show withdraw fee
     new bee6528  [wallet] add detail page for withdrawal event in history
     new d72548e  [wallet] add detail page for payment sent event in history

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:
 .../src/main/java/net/taler/common/AndroidUtils.kt |   6 +
 .../main/java/net/taler/wallet/BalanceFragment.kt  |  18 ++-
 .../src/main/java/net/taler/wallet/Utils.kt        |   7 +-
 .../net/taler/wallet/history/HistoryAdapter.kt     |  91 ++++++-------
 .../java/net/taler/wallet/history/HistoryEvent.kt  |   4 +
 .../taler/wallet/history/HistoryEventFragment.kt   | 107 +++++++++++++++
 .../net/taler/wallet/history/HistoryFragment.kt    |  30 ++++-
 .../net/taler/wallet/history/HistoryManager.kt     |  14 +-
 .../net/taler/wallet/history/JsonDialogFragment.kt |   7 +
 .../wallet/withdraw/PromptWithdrawFragment.kt      |   5 +-
 wallet/src/main/res/layout/fragment_event_paid.xml | 124 ++++++++++++++++++
 .../main/res/layout/fragment_event_withdraw.xml    | 143 +++++++++++++++++++++
 wallet/src/main/res/layout/history_payment.xml     |  24 ++--
 wallet/src/main/res/layout/history_receive.xml     |  43 +++----
 wallet/src/main/res/layout/history_row.xml         |  11 +-
 wallet/src/main/res/layout/list_item_balance.xml   |   1 +
 .../{pending_operations.xml => history_event.xml}  |   5 +-
 wallet/src/main/res/navigation/nav_graph.xml       |  14 +-
 wallet/src/main/res/values/strings.xml             |  14 ++
 wallet/src/main/res/values/styles.xml              |  27 +++-
 20 files changed, 573 insertions(+), 122 deletions(-)
 copy settings.gradle => wallet/src/main/java/net/taler/wallet/Utils.kt (82%)
 create mode 100644 
wallet/src/main/java/net/taler/wallet/history/HistoryEventFragment.kt
 create mode 100644 wallet/src/main/res/layout/fragment_event_paid.xml
 create mode 100644 wallet/src/main/res/layout/fragment_event_withdraw.xml
 copy wallet/src/main/res/menu/{pending_operations.xml => history_event.xml} 
(87%)

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 5bc5721..ad9dab9 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
@@ -27,6 +27,7 @@ import android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE
 import android.text.format.DateUtils.FORMAT_NO_YEAR
 import android.text.format.DateUtils.FORMAT_SHOW_DATE
 import android.text.format.DateUtils.FORMAT_SHOW_TIME
+import android.text.format.DateUtils.FORMAT_SHOW_YEAR
 import android.text.format.DateUtils.MINUTE_IN_MILLIS
 import android.text.format.DateUtils.formatDateTime
 import android.text.format.DateUtils.getRelativeTimeSpanString
@@ -82,3 +83,8 @@ fun Long.toRelativeTime(context: Context): CharSequence {
         formatDateTime(context, this, flags)
     } else getRelativeTimeSpanString(this, now, MINUTE_IN_MILLIS, 
FORMAT_ABBREV_RELATIVE)
 }
+
+fun Long.toAbsoluteTime(context: Context): CharSequence {
+    val flags = FORMAT_SHOW_TIME or FORMAT_SHOW_DATE or FORMAT_SHOW_YEAR
+    return formatDateTime(context, this, flags)
+}
diff --git a/wallet/src/main/java/net/taler/wallet/BalanceFragment.kt 
b/wallet/src/main/java/net/taler/wallet/BalanceFragment.kt
index d871cfb..3d5364b 100644
--- a/wallet/src/main/java/net/taler/wallet/BalanceFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/BalanceFragment.kt
@@ -31,6 +31,7 @@ import android.widget.TextView
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
 import androidx.lifecycle.Observer
+import androidx.navigation.fragment.findNavController
 import androidx.recyclerview.widget.DividerItemDecoration
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.LinearLayoutManager.VERTICAL
@@ -41,13 +42,17 @@ import 
com.google.zxing.integration.android.IntentIntegrator.QR_CODE
 import kotlinx.android.synthetic.main.fragment_show_balance.*
 import net.taler.wallet.BalanceAdapter.BalanceViewHolder
 
-class BalanceFragment : Fragment() {
+interface BalanceClickListener {
+    fun onBalanceClick()
+}
+
+class BalanceFragment : Fragment(), BalanceClickListener {
 
     private val model: WalletViewModel by activityViewModels()
     private val withdrawManager by lazy { model.withdrawManager }
 
     private var reloadBalanceMenuItem: MenuItem? = null
-    private val balancesAdapter = BalanceAdapter()
+    private val balancesAdapter = BalanceAdapter(this)
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -141,9 +146,13 @@ class BalanceFragment : Fragment() {
         beginDelayedTransition(view as ViewGroup)
     }
 
+    override fun onBalanceClick() {
+        findNavController().navigate(R.id.walletHistory)
+    }
+
 }
 
-class BalanceAdapter : Adapter<BalanceViewHolder>() {
+class BalanceAdapter(private val listener: BalanceClickListener) : 
Adapter<BalanceViewHolder>() {
 
     private var items = emptyList<BalanceItem>()
 
@@ -169,13 +178,14 @@ class BalanceAdapter : Adapter<BalanceViewHolder>() {
         this.notifyDataSetChanged()
     }
 
-    class BalanceViewHolder(private val v: View) : ViewHolder(v) {
+    inner class BalanceViewHolder(private val v: View) : ViewHolder(v) {
         private val currencyView: TextView = 
v.findViewById(R.id.balance_currency)
         private val amountView: TextView = v.findViewById(R.id.balance_amount)
         private val balanceInboundAmount: TextView = 
v.findViewById(R.id.balanceInboundAmount)
         private val balanceInboundLabel: TextView = 
v.findViewById(R.id.balanceInboundLabel)
 
         fun bind(item: BalanceItem) {
+            v.setOnClickListener { listener.onBalanceClick() }
             currencyView.text = item.available.currency
             amountView.text = item.available.amountStr
 
diff --git a/settings.gradle b/wallet/src/main/java/net/taler/wallet/Utils.kt
similarity index 82%
copy from settings.gradle
copy to wallet/src/main/java/net/taler/wallet/Utils.kt
index f254aa2..ae8712f 100644
--- a/settings.gradle
+++ b/wallet/src/main/java/net/taler/wallet/Utils.kt
@@ -14,5 +14,8 @@
  * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-include ':akono', ':cashier', ':merchant-terminal', ':wallet'
-include ':taler-kotlin-common'
+package net.taler.wallet
+
+fun cleanExchange(exchange: String) = exchange.let {
+    if (it.startsWith("https://";)) it.substring(8) else it
+}.trimEnd('/')
diff --git a/wallet/src/main/java/net/taler/wallet/history/HistoryAdapter.kt 
b/wallet/src/main/java/net/taler/wallet/history/HistoryAdapter.kt
index 43b7bd7..1c7f15e 100644
--- a/wallet/src/main/java/net/taler/wallet/history/HistoryAdapter.kt
+++ b/wallet/src/main/java/net/taler/wallet/history/HistoryAdapter.kt
@@ -16,27 +16,24 @@
 
 package net.taler.wallet.history
 
-import android.annotation.SuppressLint
+import android.content.Context
 import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG
 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.annotation.CallSuper
-import androidx.core.net.toUri
 import androidx.recyclerview.widget.RecyclerView.Adapter
 import androidx.recyclerview.widget.RecyclerView.ViewHolder
-import net.taler.common.Amount
 import net.taler.common.toRelativeTime
-import net.taler.wallet.BuildConfig
 import net.taler.wallet.R
+import net.taler.wallet.cleanExchange
 import net.taler.wallet.history.HistoryAdapter.HistoryEventViewHolder
 
 
 internal class HistoryAdapter(
+    private val devMode: Boolean,
     private val listener: OnEventClickListener,
     private var history: History = History()
 ) : Adapter<HistoryEventViewHolder>() {
@@ -68,15 +65,16 @@ internal class HistoryAdapter(
         this.notifyDataSetChanged()
     }
 
-    internal abstract inner class HistoryEventViewHolder(protected val v: 
View) : ViewHolder(v) {
+    internal abstract inner class HistoryEventViewHolder(private val v: View) 
: ViewHolder(v) {
 
+        protected val context: Context = v.context
         private val icon: ImageView = v.findViewById(R.id.icon)
         protected val title: TextView = v.findViewById(R.id.title)
         private val time: TextView = v.findViewById(R.id.time)
 
         @CallSuper
         open fun bind(event: HistoryEvent) {
-            if (BuildConfig.DEBUG) {  // doesn't produce recycling issues, no 
need to cover all cases
+            if (devMode || event.detailPageLayout != 0) {
                 v.setOnClickListener { listener.onEventClicked(event) }
             } else {
                 v.background = null
@@ -84,7 +82,7 @@ internal class HistoryAdapter(
             icon.setImageResource(event.icon)
             if (event.title == 0) title.text = event::class.java.simpleName
             else title.setText(event.title)
-            time.text = event.timestamp.ms.toRelativeTime(v.context)
+            time.text = event.timestamp.ms.toRelativeTime(context)
         }
 
     }
@@ -96,8 +94,8 @@ internal class HistoryAdapter(
         override fun bind(event: HistoryEvent) {
             super.bind(event)
             info.text = when (event) {
-                is ExchangeAddedEvent -> event.exchangeBaseUrl
-                is ExchangeUpdatedEvent -> event.exchangeBaseUrl
+                is ExchangeAddedEvent -> cleanExchange(event.exchangeBaseUrl)
+                is ExchangeUpdatedEvent -> cleanExchange(event.exchangeBaseUrl)
                 is ReserveBalanceUpdatedEvent -> 
event.amountReserveBalance.toString()
                 is HistoryPaymentSentEvent -> event.orderShortInfo.summary
                 is HistoryOrderAcceptedEvent -> event.orderShortInfo.summary
@@ -113,8 +111,7 @@ internal class HistoryAdapter(
 
         private val summary: TextView = v.findViewById(R.id.summary)
         private val amountWithdrawn: TextView = 
v.findViewById(R.id.amountWithdrawn)
-        private val feeLabel: TextView = v.findViewById(R.id.feeLabel)
-        private val fee: TextView = v.findViewById(R.id.fee)
+        private val paintFlags = amountWithdrawn.paintFlags
 
         override fun bind(event: HistoryEvent) {
             super.bind(event)
@@ -127,52 +124,31 @@ internal class HistoryAdapter(
         }
 
         private fun bind(event: HistoryWithdrawnEvent) {
-            title.text = getHostname(event.exchangeBaseUrl)
-            summary.setText(event.title)
-
-            showAmounts(event.amountWithdrawnEffective, 
event.amountWithdrawnRaw)
+            summary.text = cleanExchange(event.exchangeBaseUrl)
+            amountWithdrawn.text =
+                context.getString(R.string.amount_positive, 
event.amountWithdrawnEffective)
+            amountWithdrawn.paintFlags = paintFlags
         }
 
         private fun bind(event: HistoryRefundedEvent) {
-            title.text = event.orderShortInfo.summary
-            summary.setText(event.title)
-
-            showAmounts(event.amountRefundedEffective, event.amountRefundedRaw)
+            summary.text = event.orderShortInfo.summary
+            amountWithdrawn.text =
+                context.getString(R.string.amount_positive, 
event.amountRefundedEffective)
+            amountWithdrawn.paintFlags = paintFlags
         }
 
         private fun bind(event: HistoryTipAcceptedEvent) {
-            title.setText(event.title)
             summary.text = null
-            showAmounts(event.tipRaw, event.tipRaw)
+            amountWithdrawn.text = context.getString(R.string.amount_positive, 
event.tipRaw)
+            amountWithdrawn.paintFlags = paintFlags
         }
 
         private fun bind(event: HistoryTipDeclinedEvent) {
-            title.setText(event.title)
             summary.text = null
-            showAmounts(event.tipAmount, event.tipAmount)
+            amountWithdrawn.text = context.getString(R.string.amount_positive, 
event.tipAmount)
             amountWithdrawn.paintFlags = amountWithdrawn.paintFlags or 
STRIKE_THRU_TEXT_FLAG
         }
 
-        private fun showAmounts(effective: Amount, raw: Amount) {
-            @SuppressLint("SetTextI18n")
-            amountWithdrawn.text = "+$raw"
-            val calculatedFee = raw - effective
-            if (calculatedFee.isZero()) {
-                fee.visibility = GONE
-                feeLabel.visibility = GONE
-            } else {
-                @SuppressLint("SetTextI18n")
-                fee.text = "-$calculatedFee"
-                fee.visibility = VISIBLE
-                feeLabel.visibility = VISIBLE
-            }
-            amountWithdrawn.paintFlags = fee.paintFlags
-        }
-
-        private fun getHostname(url: String): String {
-            return url.toUri().host!!
-        }
-
     }
 
     internal inner class HistoryPaymentViewHolder(v: View) : 
HistoryEventViewHolder(v) {
@@ -182,7 +158,6 @@ internal class HistoryAdapter(
 
         override fun bind(event: HistoryEvent) {
             super.bind(event)
-            summary.setText(event.title)
             when (event) {
                 is HistoryPaymentSentEvent -> bind(event)
                 is HistoryPaymentAbortedEvent -> bind(event)
@@ -191,23 +166,29 @@ internal class HistoryAdapter(
         }
 
         private fun bind(event: HistoryPaymentSentEvent) {
-            title.text = event.orderShortInfo.summary
-            @SuppressLint("SetTextI18n")
-            amountPaidWithFees.text = "-${event.amountPaidWithFees}"
+            summary.text = event.orderShortInfo.summary
+            amountPaidWithFees.text =
+                context.getString(R.string.amount_negative, 
event.amountPaidWithFees)
         }
 
         private fun bind(event: HistoryPaymentAbortedEvent) {
-            title.text = event.orderShortInfo.summary
-            @SuppressLint("SetTextI18n")
-            amountPaidWithFees.text = "-${event.amountLost}"
+            summary.text = event.orderShortInfo.summary
+            amountPaidWithFees.text = 
context.getString(R.string.amount_negative, event.amountLost)
         }
 
         private fun bind(event: HistoryRefreshedEvent) {
-            title.text = ""
+            val res = when (event.refreshReason) {
+                RefreshReason.MANUAL -> 
R.string.history_event_refresh_reason_manual
+                RefreshReason.PAY -> R.string.history_event_refresh_reason_pay
+                RefreshReason.REFUND -> 
R.string.history_event_refresh_reason_refund
+                RefreshReason.ABORT_PAY -> 
R.string.history_event_refresh_reason_abort_pay
+                RefreshReason.RECOUP -> 
R.string.history_event_refresh_reason_recoup
+                RefreshReason.BACKUP_RESTORED -> 
R.string.history_event_refresh_reason_backup_restored
+            }
+            summary.text = context.getString(res)
             val fee = event.amountRefreshedRaw - event.amountRefreshedEffective
-            @SuppressLint("SetTextI18n")
             if (fee.isZero()) amountPaidWithFees.text = null
-            else amountPaidWithFees.text = "-$fee"
+            else amountPaidWithFees.text = 
context.getString(R.string.amount_negative, fee)
         }
 
     }
diff --git a/wallet/src/main/java/net/taler/wallet/history/HistoryEvent.kt 
b/wallet/src/main/java/net/taler/wallet/history/HistoryEvent.kt
index 86a7ac0..57bf6a3 100644
--- a/wallet/src/main/java/net/taler/wallet/history/HistoryEvent.kt
+++ b/wallet/src/main/java/net/taler/wallet/history/HistoryEvent.kt
@@ -138,6 +138,8 @@ abstract class HistoryEvent(
     val timestamp: Timestamp,
     @get:LayoutRes
     open val layout: Int = R.layout.history_row,
+    @get:LayoutRes
+    open val detailPageLayout: Int = 0,
     @get:StringRes
     open val title: Int = 0,
     @get:DrawableRes
@@ -215,6 +217,7 @@ class HistoryWithdrawnEvent(
     val amountWithdrawnEffective: Amount
 ) : HistoryEvent(timestamp) {
     override val layout = R.layout.history_receive
+    override val detailPageLayout = R.layout.fragment_event_withdraw
     override val title = R.string.history_event_withdrawn
     override val icon = R.drawable.history_withdrawn
     override val showToUser = true
@@ -270,6 +273,7 @@ class HistoryPaymentSentEvent(
     val sessionId: String?
 ) : HistoryEvent(timestamp) {
     override val layout = R.layout.history_payment
+    override val detailPageLayout = R.layout.fragment_event_paid
     override val title = R.string.history_event_payment_sent
     override val icon = R.drawable.ic_cash_usd_outline
     override val showToUser = true
diff --git 
a/wallet/src/main/java/net/taler/wallet/history/HistoryEventFragment.kt 
b/wallet/src/main/java/net/taler/wallet/history/HistoryEventFragment.kt
new file mode 100644
index 0000000..6a07625
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/history/HistoryEventFragment.kt
@@ -0,0 +1,107 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2020 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under 
the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+ * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+package net.taler.wallet.history
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.Menu
+import android.view.MenuInflater
+import android.view.MenuItem
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Toast
+import android.widget.Toast.LENGTH_LONG
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import kotlinx.android.synthetic.main.fragment_event_paid.*
+import kotlinx.android.synthetic.main.fragment_event_withdraw.*
+import kotlinx.android.synthetic.main.fragment_event_withdraw.feeView
+import kotlinx.android.synthetic.main.fragment_event_withdraw.timeView
+import net.taler.common.toAbsoluteTime
+import net.taler.wallet.R
+import net.taler.wallet.WalletViewModel
+import net.taler.wallet.cleanExchange
+
+class HistoryEventFragment : Fragment() {
+
+    private val model: WalletViewModel by activityViewModels()
+    private val historyManager by lazy { model.historyManager }
+    private val event by lazy { requireNotNull(historyManager.selectedEvent) }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setHasOptionsMenu(model.devMode.value == true)
+    }
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        return inflater.inflate(event.detailPageLayout, container, false)
+    }
+
+    override fun onActivityCreated(savedInstanceState: Bundle?) {
+        super.onActivityCreated(savedInstanceState)
+        requireActivity().title =
+            getString(if (event.title != 0) event.title else 
R.string.history_detail_title)
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        timeView.text = event.timestamp.ms.toAbsoluteTime(requireContext())
+        when (val e = event) {
+            is HistoryWithdrawnEvent -> bind(e)
+            is HistoryPaymentSentEvent -> bind(e)
+            else -> Toast.makeText(requireContext(), "event not implement", 
LENGTH_LONG).show()
+        }
+    }
+
+    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+        inflater.inflate(R.menu.history_event, menu)
+    }
+
+    override fun onOptionsItemSelected(item: MenuItem): Boolean {
+        return when (item.itemId) {
+            R.id.show_json -> {
+                
JsonDialogFragment.new(event.json.toString(2)).show(parentFragmentManager, null)
+                true
+            }
+            else -> super.onOptionsItemSelected(item)
+        }
+    }
+
+    private fun bind(event: HistoryWithdrawnEvent) {
+        effectiveAmountLabel.text = getString(R.string.withdraw_total)
+        effectiveAmountView.text = event.amountWithdrawnEffective.toString()
+        chosenAmountLabel.text = getString(R.string.amount_chosen)
+        chosenAmountView.text =
+            getString(R.string.amount_positive, 
event.amountWithdrawnRaw.toString())
+        val fee = event.amountWithdrawnRaw - event.amountWithdrawnEffective
+        feeView.text = getString(R.string.amount_negative, fee.toString())
+        exchangeView.text = cleanExchange(event.exchangeBaseUrl)
+    }
+
+    private fun bind(event: HistoryPaymentSentEvent) {
+        amountPaidWithFeesView.text = event.amountPaidWithFees.toString()
+        orderAmountView.text = event.orderShortInfo.amount.toString()
+        val fee = event.amountPaidWithFees - event.orderShortInfo.amount
+        feeView.text = getString(R.string.amount_negative, fee.toString())
+        orderSummaryView.text = event.orderShortInfo.summary
+        orderIdView.text =
+            getString(R.string.history_event_payment_sent_order_id, 
event.orderShortInfo.orderId)
+    }
+
+}
diff --git a/wallet/src/main/java/net/taler/wallet/history/HistoryFragment.kt 
b/wallet/src/main/java/net/taler/wallet/history/HistoryFragment.kt
index 2586ef8..73dbae0 100644
--- a/wallet/src/main/java/net/taler/wallet/history/HistoryFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/history/HistoryFragment.kt
@@ -28,10 +28,13 @@ import android.view.ViewGroup
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.activityViewModels
 import androidx.lifecycle.Observer
+import androidx.navigation.fragment.findNavController
 import androidx.recyclerview.widget.DividerItemDecoration
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.LinearLayoutManager.VERTICAL
 import kotlinx.android.synthetic.main.fragment_show_history.*
+import net.taler.common.fadeIn
+import net.taler.common.fadeOut
 import net.taler.wallet.R
 import net.taler.wallet.WalletViewModel
 
@@ -45,7 +48,7 @@ class HistoryFragment : Fragment(), OnEventClickListener {
     private val historyManager by lazy { model.historyManager }
     private lateinit var showAllItem: MenuItem
     private var reloadHistoryItem: MenuItem? = null
-    private val historyAdapter = HistoryAdapter(this)
+    private val historyAdapter by lazy { HistoryAdapter(model.devMode.value == 
true, this) }
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -73,8 +76,7 @@ class HistoryFragment : Fragment(), OnEventClickListener {
             historyProgressBar.visibility = if (show) VISIBLE else INVISIBLE
         })
         historyManager.history.observe(viewLifecycleOwner, Observer { history 
->
-            historyEmptyState.visibility = if (history.isEmpty()) VISIBLE else 
INVISIBLE
-            historyAdapter.update(history)
+            onHistoryResult(history)
         })
 
         // kicks off initial load, needs to be adapted if showAll state is 
ever saved
@@ -106,9 +108,25 @@ class HistoryFragment : Fragment(), OnEventClickListener {
     }
 
     override fun onEventClicked(event: HistoryEvent) {
-        if (model.devMode.value != true) return
-        JsonDialogFragment.new(event.json.toString(4))
-            .show(parentFragmentManager, null)
+        if (event.detailPageLayout != 0) {
+            historyManager.selectedEvent = event
+            
findNavController().navigate(R.id.action_walletHistory_to_historyEventFragment)
+        } else if (model.devMode.value == true) {
+            JsonDialogFragment.new(event.json.toString(2))
+                .show(parentFragmentManager, null)
+        }
+    }
+
+    private fun onHistoryResult(result: HistoryResult) = when (result) {
+        HistoryResult.Error -> {
+            historyList.fadeOut()
+            historyEmptyState.text = getString(R.string.history_error)
+            historyEmptyState.fadeIn()
+        }
+        is HistoryResult.Success -> {
+            historyEmptyState.visibility = if (result.history.isEmpty()) 
VISIBLE else INVISIBLE
+            historyAdapter.update(result.history)
+        }
     }
 
 }
diff --git a/wallet/src/main/java/net/taler/wallet/history/HistoryManager.kt 
b/wallet/src/main/java/net/taler/wallet/history/HistoryManager.kt
index c350daa..7ce4f5b 100644
--- a/wallet/src/main/java/net/taler/wallet/history/HistoryManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/history/HistoryManager.kt
@@ -29,6 +29,11 @@ import kotlinx.coroutines.flow.onCompletion
 import kotlinx.coroutines.flow.onStart
 import net.taler.wallet.backend.WalletBackendApi
 
+sealed class HistoryResult {
+    object Error : HistoryResult()
+    class Success(val history: History) : HistoryResult()
+}
+
 @Suppress("EXPERIMENTAL_API_USAGE")
 class HistoryManager(
     private val walletBackendApi: WalletBackendApi,
@@ -40,7 +45,9 @@ class HistoryManager(
 
     val showAll = MutableLiveData<Boolean>()
 
-    val history: LiveData<History> = showAll.switchMap { showAll ->
+    var selectedEvent: HistoryEvent? = null
+
+    val history: LiveData<HistoryResult> = showAll.switchMap { showAll ->
         loadHistory(showAll)
             .onStart { mProgress.postValue(true) }
             .onCompletion { mProgress.postValue(false) }
@@ -50,7 +57,7 @@ class HistoryManager(
     private fun loadHistory(showAll: Boolean) = callbackFlow {
         walletBackendApi.sendRequest("getHistory", null) { isError, result ->
             if (isError) {
-                // TODO show error message in [WalletHistory] fragment
+                offer(HistoryResult.Error)
                 close()
                 return@sendRequest
             }
@@ -62,7 +69,8 @@ class HistoryManager(
                 history.add(event)
             }
             history.reverse()  // show latest first
-            offer(if (showAll) history else history.filter { it.showToUser } 
as History)
+            val filtered = if (showAll) history else history.filter { 
it.showToUser } as History
+            offer(HistoryResult.Success(filtered))
             close()
         }
         awaitClose()
diff --git 
a/wallet/src/main/java/net/taler/wallet/history/JsonDialogFragment.kt 
b/wallet/src/main/java/net/taler/wallet/history/JsonDialogFragment.kt
index f51dba9..5421db3 100644
--- a/wallet/src/main/java/net/taler/wallet/history/JsonDialogFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/history/JsonDialogFragment.kt
@@ -20,6 +20,8 @@ import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import androidx.fragment.app.DialogFragment
 import kotlinx.android.synthetic.main.fragment_json.*
 import net.taler.wallet.R
@@ -47,4 +49,9 @@ class JsonDialogFragment : DialogFragment() {
         jsonView.text = json
     }
 
+    override fun onStart() {
+        super.onStart()
+        dialog?.window?.setLayout(MATCH_PARENT, WRAP_CONTENT)
+    }
+
 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt 
b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
index ea04e24..5d0fe63 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
@@ -30,6 +30,7 @@ import net.taler.common.fadeIn
 import net.taler.common.fadeOut
 import net.taler.wallet.R
 import net.taler.wallet.WalletViewModel
+import net.taler.wallet.cleanExchange
 import net.taler.wallet.withdraw.WithdrawStatus.Loading
 import net.taler.wallet.withdraw.WithdrawStatus.TermsOfServiceReviewRequired
 import net.taler.wallet.withdraw.WithdrawStatus.Withdrawing
@@ -115,9 +116,7 @@ class PromptWithdrawFragment : Fragment() {
         feeView.fadeIn()
 
         exchangeIntroView.fadeIn()
-        withdrawExchangeUrl.text = exchange.let {
-            if (it.startsWith("https://";)) it.substring(8) else it
-        }.trimEnd('/')
+        withdrawExchangeUrl.text = cleanExchange(exchange)
         withdrawExchangeUrl.fadeIn()
 
         withdrawCard.fadeIn()
diff --git a/wallet/src/main/res/layout/fragment_event_paid.xml 
b/wallet/src/main/res/layout/fragment_event_paid.xml
new file mode 100644
index 0000000..4485744
--- /dev/null
+++ b/wallet/src/main/res/layout/fragment_event_paid.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ This file is part of GNU Taler
+  ~ (C) 2020 Taler Systems S.A.
+  ~
+  ~ GNU Taler is free software; you can redistribute it and/or modify it under 
the
+  ~ terms of the GNU General Public License as published by the Free Software
+  ~ Foundation; either version 3, or (at your option) any later version.
+  ~
+  ~ GNU Taler is distributed in the hope that it will be useful, but WITHOUT 
ANY
+  ~ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+  ~ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License along 
with
+  ~ GNU Taler; see the file COPYING.  If not, see 
<http://www.gnu.org/licenses/>
+  -->
+
+<ScrollView 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"
+    android:fillViewport="true"
+    tools:context=".history.HistoryEventFragment">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:id="@+id/timeView"
+            style="@style/HistoryEventLabel.Time"
+            app:layout_constraintBottom_toTopOf="@+id/amountPaidWithFeesLabel"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_chainStyle="packed"
+            tools:text="23 March 2020 23:42pm" />
+
+        <TextView
+            android:id="@+id/amountPaidWithFeesLabel"
+            style="@style/HistoryEventLabel"
+            android:text="@string/history_event_payment_sent_paid"
+            app:layout_constraintBottom_toTopOf="@+id/amountPaidWithFeesView"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/timeView" />
+
+        <TextView
+            android:id="@+id/amountPaidWithFeesView"
+            style="@style/HistoryEventContent"
+            android:textColor="@color/red"
+            app:layout_constraintBottom_toTopOf="@+id/orderAmountLabel"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/amountPaidWithFeesLabel"
+            tools:text="-23.42 TESTKUDOS" />
+
+        <TextView
+            android:id="@+id/orderAmountLabel"
+            style="@style/HistoryEventLabel"
+            android:text="@string/history_event_payment_sent_amount"
+            app:layout_constraintBottom_toTopOf="@+id/orderAmountView"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/amountPaidWithFeesView" 
/>
+
+        <TextView
+            android:id="@+id/orderAmountView"
+            style="@style/HistoryEventContent"
+            app:layout_constraintBottom_toTopOf="@+id/feeLabel"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/orderAmountLabel"
+            tools:text="23 TESTKUDOS" />
+
+        <TextView
+            android:id="@+id/feeLabel"
+            style="@style/HistoryEventLabel"
+            android:text="@string/withdraw_fees"
+            app:layout_constraintBottom_toTopOf="@+id/feeView"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/orderAmountView" />
+
+        <TextView
+            android:id="@+id/feeView"
+            style="@style/HistoryEventContent"
+            android:textColor="@color/red"
+            app:layout_constraintBottom_toTopOf="@+id/orderSummaryLabel"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/feeLabel"
+            tools:text="-0.42 TESTKUDOS" />
+
+        <TextView
+            android:id="@+id/orderSummaryLabel"
+            style="@style/HistoryEventLabel"
+            android:text="@string/history_event_payment_sent_order"
+            app:layout_constraintBottom_toTopOf="@+id/orderSummaryView"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/feeView" />
+
+        <TextView
+            android:id="@+id/orderSummaryView"
+            style="@style/HistoryEventContent"
+            app:layout_constraintBottom_toTopOf="@+id/orderIdView"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/orderSummaryLabel"
+            tools:text="Some Product that was bought and can have quite a long 
label" />
+
+        <TextView
+            android:id="@+id/orderIdView"
+            style="@style/HistoryEventLabel"
+            android:text="@string/history_event_payment_sent_order_id"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/orderSummaryView" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</ScrollView>
diff --git a/wallet/src/main/res/layout/fragment_event_withdraw.xml 
b/wallet/src/main/res/layout/fragment_event_withdraw.xml
new file mode 100644
index 0000000..9c5d818
--- /dev/null
+++ b/wallet/src/main/res/layout/fragment_event_withdraw.xml
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ This file is part of GNU Taler
+  ~ (C) 2020 Taler Systems S.A.
+  ~
+  ~ GNU Taler is free software; you can redistribute it and/or modify it under 
the
+  ~ terms of the GNU General Public License as published by the Free Software
+  ~ Foundation; either version 3, or (at your option) any later version.
+  ~
+  ~ GNU Taler is distributed in the hope that it will be useful, but WITHOUT 
ANY
+  ~ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+  ~ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License along 
with
+  ~ GNU Taler; see the file COPYING.  If not, see 
<http://www.gnu.org/licenses/>
+  -->
+
+<ScrollView 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"
+    android:fillViewport="true"
+    tools:context=".history.HistoryEventFragment">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <TextView
+            android:id="@+id/timeView"
+            style="@style/HistoryEventLabel.Time"
+            app:layout_constraintBottom_toTopOf="@+id/effectiveAmountLabel"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintVertical_chainStyle="packed"
+            tools:text="23 March 2020 23:42pm" />
+
+        <TextView
+            android:id="@+id/effectiveAmountLabel"
+            style="@style/HistoryEventLabel"
+            app:layout_constraintBottom_toTopOf="@+id/effectiveAmountView"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/timeView"
+            tools:text="@string/withdraw_total" />
+
+        <TextView
+            android:id="@+id/effectiveAmountView"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginEnd="16dp"
+            android:layout_marginBottom="16dp"
+            android:gravity="center"
+            android:textColor="@color/green"
+            android:textSize="24sp"
+            app:layout_constraintBottom_toTopOf="@+id/chosenAmountLabel"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/effectiveAmountLabel"
+            tools:text="23.42 TESTKUDOS" />
+
+        <TextView
+            android:id="@+id/chosenAmountLabel"
+            style="@style/HistoryEventLabel"
+            app:layout_constraintBottom_toTopOf="@+id/chosenAmountView"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/effectiveAmountView"
+            tools:text="@string/amount_chosen" />
+
+        <TextView
+            android:id="@+id/chosenAmountView"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginEnd="16dp"
+            android:layout_marginBottom="16dp"
+            android:gravity="center"
+            android:textSize="24sp"
+            app:layout_constraintBottom_toTopOf="@+id/feeLabel"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/chosenAmountLabel"
+            tools:text="24 TESTKUDOS" />
+
+        <TextView
+            android:id="@+id/feeLabel"
+            style="@style/HistoryEventLabel"
+            android:text="@string/withdraw_fees"
+            app:layout_constraintBottom_toTopOf="@+id/feeView"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/chosenAmountView" />
+
+        <TextView
+            android:id="@+id/feeView"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginEnd="16dp"
+            android:layout_marginBottom="16dp"
+            android:gravity="center"
+            android:textColor="@color/red"
+            android:textSize="24sp"
+            app:layout_constraintBottom_toTopOf="@+id/exchangeLabel"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/feeLabel"
+            tools:text="-0.38 TESTKUDOS" />
+
+        <TextView
+            android:id="@+id/exchangeLabel"
+            style="@style/HistoryEventLabel"
+            android:text="@string/withdraw_exchange"
+            app:layout_constraintBottom_toTopOf="@+id/exchangeView"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/feeView" />
+
+        <TextView
+            android:id="@+id/exchangeView"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginEnd="16dp"
+            android:gravity="center"
+            android:textSize="24sp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintHorizontal_bias="0.5"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/exchangeLabel"
+            tools:text="exchange.demo.taler.net" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</ScrollView>
diff --git a/wallet/src/main/res/layout/history_payment.xml 
b/wallet/src/main/res/layout/history_payment.xml
index 3839038..33cb676 100644
--- a/wallet/src/main/res/layout/history_payment.xml
+++ b/wallet/src/main/res/layout/history_payment.xml
@@ -19,11 +19,11 @@
     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"
-    android:background="?attr/selectableItemBackground">
+    android:background="?attr/selectableItemBackground"
+    android:paddingStart="16dp"
+    android:paddingTop="8dp"
+    android:paddingEnd="16dp"
+    android:paddingBottom="8dp">
 
     <ImageView
         android:id="@+id/icon"
@@ -32,36 +32,36 @@
         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" />
+        tools:ignore="ContentDescription"
+        tools:src="@drawable/ic_cash_usd_outline" />
 
     <TextView
         android:id="@+id/title"
         style="@style/HistoryTitle"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_marginStart="8dp"
+        android:layout_marginStart="16dp"
         android:layout_marginEnd="8dp"
         app:layout_constraintEnd_toStartOf="@+id/amountPaidWithFees"
         app:layout_constraintStart_toEndOf="@+id/icon"
         app:layout_constraintTop_toTopOf="parent"
-        tools:text="Lots of books with very long titles" />
+        tools:text="@string/history_event_payment_sent" />
 
     <TextView
         android:id="@+id/summary"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginStart="8dp"
+        android:layout_marginStart="16dp"
         android:layout_marginTop="8dp"
         app:layout_constrainedWidth="true"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/amountPaidWithFees"
+        app:layout_constraintEnd_toStartOf="@+id/time"
         app:layout_constraintHorizontal_bias="0.0"
         app:layout_constraintStart_toEndOf="@+id/icon"
         app:layout_constraintTop_toBottomOf="@+id/title"
         app:layout_constraintVertical_bias="0.0"
-        tools:text="@string/history_event_payment_sent" />
+        tools:text="Lots of books with very long titles" />
 
     <TextView
         android:id="@+id/amountPaidWithFees"
diff --git a/wallet/src/main/res/layout/history_receive.xml 
b/wallet/src/main/res/layout/history_receive.xml
index def97a2..5f386a2 100644
--- a/wallet/src/main/res/layout/history_receive.xml
+++ b/wallet/src/main/res/layout/history_receive.xml
@@ -19,11 +19,11 @@
     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"
-    android:background="?attr/selectableItemBackground">
+    android:background="?attr/selectableItemBackground"
+    android:paddingStart="16dp"
+    android:paddingTop="8dp"
+    android:paddingEnd="16dp"
+    android:paddingBottom="8dp">
 
     <ImageView
         android:id="@+id/icon"
@@ -41,7 +41,7 @@
         style="@style/HistoryTitle"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_marginStart="8dp"
+        android:layout_marginStart="16dp"
         android:layout_marginEnd="8dp"
         android:text="@string/history_event_withdrawn"
         app:layout_constraintEnd_toStartOf="@+id/amountWithdrawn"
@@ -52,34 +52,18 @@
         android:id="@+id/summary"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_marginStart="8dp"
+        android:layout_marginStart="16dp"
         android:layout_marginTop="8dp"
         android:layout_marginEnd="8dp"
         android:layout_marginBottom="8dp"
         app:layout_constrainedWidth="true"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/feeLabel"
+        app:layout_constraintEnd_toStartOf="@+id/time"
+        app:layout_constraintHorizontal_bias="0.5"
         app:layout_constraintStart_toEndOf="@+id/icon"
         app:layout_constraintTop_toBottomOf="@+id/title"
-        tools:text="http://taler.quite-long-exchange.url"; />
-
-    <TextView
-        android:id="@+id/feeLabel"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginEnd="2dp"
-        android:text="@string/history_fee_label"
-        app:layout_constraintEnd_toStartOf="@+id/fee"
-        app:layout_constraintTop_toTopOf="@+id/fee" />
-
-    <TextView
-        android:id="@+id/fee"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:textColor="@color/red"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/amountWithdrawn"
-        tools:text="0.2 TESTKUDOS" />
+        app:layout_constraintVertical_bias="0.0"
+        tools:text="exchange.taler.quite-long-domain-name.org" />
 
     <TextView
         android:id="@+id/amountWithdrawn"
@@ -96,10 +80,13 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="8dp"
+        android:layout_marginBottom="8dp"
         android:textSize="14sp"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/fee"
+        app:layout_constraintStart_toEndOf="@+id/summary"
+        app:layout_constraintTop_toBottomOf="@+id/amountWithdrawn"
+        app:layout_constraintVertical_bias="1.0"
         tools:text="23 min. ago" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/wallet/src/main/res/layout/history_row.xml 
b/wallet/src/main/res/layout/history_row.xml
index 2982008..5eac44b 100644
--- a/wallet/src/main/res/layout/history_row.xml
+++ b/wallet/src/main/res/layout/history_row.xml
@@ -19,8 +19,11 @@
     xmlns:tools="http://schemas.android.com/tools";
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_margin="15dp"
-    android:background="?attr/selectableItemBackground">
+    android:background="?attr/selectableItemBackground"
+    android:paddingStart="16dp"
+    android:paddingTop="8dp"
+    android:paddingEnd="16dp"
+    android:paddingBottom="8dp">
 
     <ImageView
         android:id="@+id/icon"
@@ -38,7 +41,7 @@
         style="@style/HistoryTitle"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_marginStart="8dp"
+        android:layout_marginStart="16dp"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toEndOf="@+id/icon"
         app:layout_constraintTop_toTopOf="parent"
@@ -49,7 +52,7 @@
         android:id="@+id/info"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_marginStart="8dp"
+        android:layout_marginStart="16dp"
         android:layout_marginTop="8dp"
         android:layout_marginEnd="8dp"
         app:layout_constraintBottom_toBottomOf="parent"
diff --git a/wallet/src/main/res/layout/list_item_balance.xml 
b/wallet/src/main/res/layout/list_item_balance.xml
index dc24232..a9e15df 100644
--- a/wallet/src/main/res/layout/list_item_balance.xml
+++ b/wallet/src/main/res/layout/list_item_balance.xml
@@ -19,6 +19,7 @@
     xmlns:tools="http://schemas.android.com/tools";
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:background="?attr/selectableItemBackground"
     android:padding="16dp">
 
     <TextView
diff --git a/wallet/src/main/res/menu/pending_operations.xml 
b/wallet/src/main/res/menu/history_event.xml
similarity index 87%
copy from wallet/src/main/res/menu/pending_operations.xml
copy to wallet/src/main/res/menu/history_event.xml
index b632021..45a1e0e 100644
--- a/wallet/src/main/res/menu/pending_operations.xml
+++ b/wallet/src/main/res/menu/history_event.xml
@@ -17,8 +17,7 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android";
     xmlns:app="http://schemas.android.com/apk/res-auto";>
     <item
-        android:id="@+id/retry_pending"
-        android:orderInCategory="100"
-        android:title="@string/menu_retry_pending_operations"
+        android:id="@+id/show_json"
+        android:title="@string/history_detail_json"
         app:showAsAction="never" />
 </menu>
diff --git a/wallet/src/main/res/navigation/nav_graph.xml 
b/wallet/src/main/res/navigation/nav_graph.xml
index 9875b8a..c39df94 100644
--- a/wallet/src/main/res/navigation/nav_graph.xml
+++ b/wallet/src/main/res/navigation/nav_graph.xml
@@ -57,11 +57,23 @@
         android:name="net.taler.wallet.Settings"
         android:label="Settings"
         tools:layout="@layout/fragment_settings" />
+
     <fragment
         android:id="@+id/walletHistory"
         android:name="net.taler.wallet.history.HistoryFragment"
         android:label="@string/history_title"
-        tools:layout="@layout/fragment_show_history" />
+        tools:layout="@layout/fragment_show_history">
+        <action
+            android:id="@+id/action_walletHistory_to_historyEventFragment"
+            app:destination="@id/historyEventFragment" />
+    </fragment>
+
+    <fragment
+        android:id="@+id/historyEventFragment"
+        android:name="net.taler.wallet.history.HistoryEventFragment"
+        android:label="@string/history_detail_title"
+        tools:layout="@layout/fragment_event_withdraw" />
+
     <fragment
         android:id="@+id/alreadyPaid"
         android:name="net.taler.wallet.payment.AlreadyPaidFragment"
diff --git a/wallet/src/main/res/values/strings.xml 
b/wallet/src/main/res/values/strings.xml
index bcd173f..31aaf14 100644
--- a/wallet/src/main/res/values/strings.xml
+++ b/wallet/src/main/res/values/strings.xml
@@ -41,6 +41,7 @@
     <string name="balances_title">Balances</string>
     <string name="amount_positive">+%s</string>
     <string name="amount_negative">-%s</string>
+    <string name="amount_chosen">Chosen Amount</string>
     <string name="balances_inbound_label">inbound</string>
     <string name="balances_empty_state">There is no digital cash in your 
wallet.\n\nYou can get test money from the demo 
bank:\n\nhttps://bank.demo.taler.net</string>
 
@@ -49,12 +50,19 @@
     <string name="history_show_all">Show All</string>
     <string name="history_reload">Reload History</string>
     <string name="history_empty">The wallet history is empty</string>
+    <string name="history_error">Could not load history</string>
+    <string name="history_detail_title">Transaction</string>
+    <string name="history_detail_json">Show JSON</string>
 
     <!-- HistoryEvents -->
     <string name="history_event_exchange_added">Exchange Added</string>
     <string name="history_event_exchange_updated">Exchange Updated</string>
     <string name="history_event_reserve_balance_updated">Reserve Balance 
Updated</string>
     <string name="history_event_payment_sent">Payment</string>
+    <string name="history_event_payment_sent_paid">Paid</string>
+    <string name="history_event_payment_sent_amount">Order Total</string>
+    <string name="history_event_payment_sent_order">Order</string>
+    <string name="history_event_payment_sent_order_id">Order Reference: 
%1$s</string>
     <string name="history_event_payment_aborted">Payment Aborted</string>
     <string name="history_event_withdrawn">Withdraw</string>
     <string name="history_event_order_accepted">Purchase Confirmed</string>
@@ -64,6 +72,12 @@
     <string name="history_event_order_redirected">Purchase Redirected</string>
     <string name="history_event_refund">Refund</string>
     <string name="history_event_refreshed">Obtained change</string>
+    <string name="history_event_refresh_reason_manual">because of manual 
request</string>
+    <string name="history_event_refresh_reason_pay">for payment</string>
+    <string name="history_event_refresh_reason_refund">for refund</string>
+    <string name="history_event_refresh_reason_abort_pay">to abort 
payment</string>
+    <string name="history_event_refresh_reason_recoup">to recoup funds</string>
+    <string name="history_event_refresh_reason_backup_restored">because of 
restoring from backup</string>
     <string name="history_event_unknown">Unknown Event</string>
 
     <string name="payment_fee">+%s payment fee</string>
diff --git a/wallet/src/main/res/values/styles.xml 
b/wallet/src/main/res/values/styles.xml
index 83f3e3a..9ebcae5 100644
--- a/wallet/src/main/res/values/styles.xml
+++ b/wallet/src/main/res/values/styles.xml
@@ -34,10 +34,35 @@
     <style name="AppTheme.Toolbar" 
parent="Widget.MaterialComponents.Toolbar.Primary" />
 
     <style name="HistoryTitle">
-        <item name="android:textSize">17sp</item>
+        <item name="android:textSize">16sp</item>
         <item name="android:textColor">?android:textColorPrimary</item>
     </style>
 
+    <style name="HistoryEventLabel">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginStart">16dp</item>
+        <item name="android:layout_marginTop">16dp</item>
+        <item name="android:layout_marginEnd">16dp</item>
+        <item name="android:gravity">center</item>
+    </style>
+
+    <style name="HistoryEventLabel.Time">
+        <item name="android:layout_marginBottom">16dp</item>
+        <item 
name="android:textAppearance">@style/TextAppearance.AppCompat.Medium</item>
+    </style>
+
+    <style name="HistoryEventContent">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginStart">16dp</item>
+        <item name="android:layout_marginTop">8dp</item>
+        <item name="android:layout_marginEnd">16dp</item>
+        <item name="android:layout_marginBottom">16dp</item>
+        <item name="android:textSize">24sp</item>
+        <item name="android:gravity">center</item>
+    </style>
+
     <style name="BottomCard">
         <item name="cardCornerRadius">0dp</item>
         <item name="cardElevation">8dp</item>

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



reply via email to

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