aboutsummaryrefslogtreecommitdiff
path: root/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'wallet')
-rw-r--r--wallet/src/main/java/net/taler/wallet/MainFragment.kt7
-rw-r--r--wallet/src/main/java/net/taler/wallet/MainViewModel.kt14
-rw-r--r--wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/Transaction.kt82
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt168
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt6
-rw-r--r--wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt11
-rw-r--r--wallet/src/main/res/drawable/ic_history_black_24dp.xml25
-rw-r--r--wallet/src/main/res/drawable/pending_border.xml6
-rw-r--r--wallet/src/main/res/layout/fragment_main.xml (renamed from wallet/src/main/res/layout/fragment_show_balance.xml)1
-rw-r--r--wallet/src/main/res/layout/fragment_pending_operations.xml2
-rw-r--r--wallet/src/main/res/layout/list_item_pending_operation.xml (renamed from wallet/src/main/res/layout/pending_row.xml)0
-rw-r--r--wallet/src/main/res/layout/list_item_transaction.xml (renamed from wallet/src/main/res/layout/transaction_row.xml)34
-rw-r--r--wallet/src/main/res/layout/transaction_in.xml92
-rw-r--r--wallet/src/main/res/layout/transaction_out.xml87
-rw-r--r--wallet/src/main/res/navigation/nav_graph.xml2
-rw-r--r--wallet/src/main/res/values/strings.xml7
18 files changed, 164 insertions, 384 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/MainFragment.kt b/wallet/src/main/java/net/taler/wallet/MainFragment.kt
index 2145596..e0e6f51 100644
--- a/wallet/src/main/java/net/taler/wallet/MainFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainFragment.kt
@@ -35,7 +35,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager.VERTICAL
import com.google.zxing.integration.android.IntentIntegrator
import com.google.zxing.integration.android.IntentIntegrator.QR_CODE
-import kotlinx.android.synthetic.main.fragment_show_balance.*
+import kotlinx.android.synthetic.main.fragment_main.*
interface BalanceClickListener {
fun onBalanceClick(currency: String)
@@ -57,7 +57,7 @@ class MainFragment : Fragment(), BalanceClickListener {
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_show_balance, container, false)
+ return inflater.inflate(R.layout.fragment_main, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -68,7 +68,7 @@ class MainFragment : Fragment(), BalanceClickListener {
}
model.balances.observe(viewLifecycleOwner, Observer {
- onBalancesChanged(it)
+ onBalancesChanged(it.values.toList())
})
mainFab.setOnClickListener {
@@ -117,6 +117,7 @@ class MainFragment : Fragment(), BalanceClickListener {
}
override fun onBalanceClick(currency: String) {
+ model.transactionManager.selectedCurrency = currency
findNavController().navigate(R.id.nav_transactions)
}
diff --git a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
index c1662c8..907278c 100644
--- a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
@@ -28,10 +28,10 @@ import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import net.taler.common.Amount
import net.taler.wallet.backend.WalletBackendApi
-import net.taler.wallet.transactions.TransactionManager
import net.taler.wallet.payment.PaymentManager
import net.taler.wallet.pending.PendingOperationsManager
import net.taler.wallet.refund.RefundManager
+import net.taler.wallet.transactions.TransactionManager
import net.taler.wallet.withdraw.WithdrawManager
import org.json.JSONObject
@@ -41,8 +41,8 @@ data class BalanceItem(val available: Amount, val pendingIncoming: Amount)
class MainViewModel(val app: Application) : AndroidViewModel(app) {
- private val mBalances = MutableLiveData<List<BalanceItem>>()
- val balances: LiveData<List<BalanceItem>> = mBalances.distinctUntilChanged()
+ private val mBalances = MutableLiveData<Map<String, BalanceItem>>()
+ val balances: LiveData<Map<String, BalanceItem>> = mBalances.distinctUntilChanged()
val devMode = MutableLiveData(BuildConfig.DEBUG)
val showProgressBar = MutableLiveData<Boolean>()
@@ -82,7 +82,7 @@ class MainViewModel(val app: Application) : AndroidViewModel(app) {
Log.e(TAG, "Error retrieving balances: ${result.toString(2)}")
return@sendRequest
}
- val balanceList = mutableListOf<BalanceItem>()
+ val balanceMap = HashMap<String, BalanceItem>()
val byCurrency = result.getJSONObject("byCurrency")
val currencyList = byCurrency.keys().asSequence().toList().sorted()
for (currency in currencyList) {
@@ -92,9 +92,9 @@ class MainViewModel(val app: Application) : AndroidViewModel(app) {
val jsonAmountIncoming = byCurrency.getJSONObject(currency)
.getJSONObject("pendingIncoming")
val amountIncoming = Amount.fromJsonObject(jsonAmountIncoming)
- balanceList.add(BalanceItem(amount, amountIncoming))
+ balanceMap[currency] = BalanceItem(amount, amountIncoming)
}
- mBalances.postValue(balanceList)
+ mBalances.postValue(balanceMap)
showProgressBar.postValue(false)
}
}
@@ -103,7 +103,7 @@ class MainViewModel(val app: Application) : AndroidViewModel(app) {
fun dangerouslyReset() {
walletBackendApi.sendRequest("reset", null)
withdrawManager.testWithdrawalInProgress.value = false
- mBalances.value = emptyList()
+ mBalances.value = emptyMap()
}
fun startTunnel() {
diff --git a/wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt b/wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt
index 1e776d4..2eb8721 100644
--- a/wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt
@@ -139,7 +139,7 @@ class PendingOperationsAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val rowView =
- LayoutInflater.from(parent.context).inflate(R.layout.pending_row, parent, false)
+ LayoutInflater.from(parent.context).inflate(R.layout.list_item_pending_operation, parent, false)
return MyViewHolder(rowView)
}
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/Transaction.kt b/wallet/src/main/java/net/taler/wallet/transactions/Transaction.kt
index 5fcabe7..c0142d5 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/Transaction.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/Transaction.kt
@@ -18,7 +18,6 @@ package net.taler.wallet.transactions
import androidx.annotation.DrawableRes
import androidx.annotation.LayoutRes
-import androidx.annotation.StringRes
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY
@@ -32,6 +31,7 @@ import com.fasterxml.jackson.annotation.JsonTypeName
import net.taler.common.Amount
import net.taler.common.Timestamp
import net.taler.wallet.R
+import net.taler.wallet.cleanExchange
import org.json.JSONObject
enum class ReserveType {
@@ -93,6 +93,17 @@ class ReserveShortInfo(
val reserveCreationDetail: ReserveCreationDetail
)
+sealed class AmountType {
+ object Positive : AmountType()
+ object Negative : AmountType()
+ object Neutral : AmountType()
+}
+
+class DisplayAmount(
+ val amount: Amount,
+ val type: AmountType
+)
+
typealias Transactions = ArrayList<Transaction>
@JsonTypeInfo(
@@ -137,21 +148,20 @@ ReserveCreated = "reserve-created",
abstract class Transaction(
val timestamp: Timestamp,
@get:LayoutRes
- open val layout: Int = R.layout.transaction_row,
- @get:LayoutRes
open val detailPageLayout: Int = 0,
- @get:StringRes
- open val title: Int = 0,
@get:DrawableRes
open val icon: Int = R.drawable.ic_account_balance,
open val showToUser: Boolean = false
) {
+ abstract val title: String?
open lateinit var json: JSONObject
+ open val displayAmount: DisplayAmount? = null
+ open fun isCurrency(currency: String): Boolean = true
}
class UnknownTransaction(timestamp: Timestamp) : Transaction(timestamp) {
- override val title = R.string.transaction_unknown
+ override val title: String? = null
}
@JsonTypeName("exchange-added")
@@ -160,7 +170,7 @@ class ExchangeAddedEvent(
val exchangeBaseUrl: String,
val builtIn: Boolean
) : Transaction(timestamp) {
- override val title = R.string.history_event_exchange_added
+ override val title = cleanExchange(exchangeBaseUrl)
}
@JsonTypeName("exchange-updated")
@@ -168,7 +178,7 @@ class ExchangeUpdatedEvent(
timestamp: Timestamp,
val exchangeBaseUrl: String
) : Transaction(timestamp) {
- override val title = R.string.history_event_exchange_updated
+ override val title = cleanExchange(exchangeBaseUrl)
}
@@ -193,7 +203,9 @@ class ReserveBalanceUpdatedTransaction(
*/
val reserveUnclaimedAmount: Amount
) : Transaction(timestamp) {
- override val title = R.string.transaction_reserve_balance_updated
+ override val title: String? = null
+ override val displayAmount = DisplayAmount(reserveBalance, AmountType.Neutral)
+ override fun isCurrency(currency: String) = reserveBalance.currency == currency
}
@JsonTypeName("withdrawn")
@@ -219,11 +231,12 @@ class WithdrawTransaction(
*/
val amountWithdrawnEffective: Amount
) : Transaction(timestamp) {
- override val layout = R.layout.transaction_in
override val detailPageLayout = R.layout.fragment_event_withdraw
- override val title = R.string.transaction_withdrawal
+ override val title = cleanExchange(exchangeBaseUrl)
override val icon = R.drawable.transaction_withdrawal
override val showToUser = true
+ override val displayAmount = DisplayAmount(amountWithdrawnEffective, AmountType.Positive)
+ override fun isCurrency(currency: String) = amountWithdrawnRaw.currency == currency
}
@JsonTypeName("order-accepted")
@@ -235,7 +248,8 @@ class OrderAcceptedTransaction(
val orderShortInfo: OrderShortInfo
) : Transaction(timestamp) {
override val icon = R.drawable.ic_add_circle
- override val title = R.string.transaction_order_accepted
+ override val title: String? = null
+ override fun isCurrency(currency: String) = orderShortInfo.amount.currency == currency
}
@JsonTypeName("order-refused")
@@ -247,7 +261,8 @@ class OrderRefusedTransaction(
val orderShortInfo: OrderShortInfo
) : Transaction(timestamp) {
override val icon = R.drawable.ic_cancel
- override val title = R.string.transaction_order_refused
+ override val title: String? = null
+ override fun isCurrency(currency: String) = orderShortInfo.amount.currency == currency
}
@JsonTypeName("payment-sent")
@@ -275,11 +290,12 @@ class PaymentTransaction(
*/
val sessionId: String?
) : Transaction(timestamp) {
- override val layout = R.layout.transaction_out
override val detailPageLayout = R.layout.fragment_event_paid
- override val title = R.string.transaction_payment
+ override val title = orderShortInfo.summary
override val icon = R.drawable.ic_cash_usd_outline
override val showToUser = true
+ override val displayAmount = DisplayAmount(amountPaidWithFees, AmountType.Negative)
+ override fun isCurrency(currency: String) = orderShortInfo.amount.currency == currency
}
@JsonTypeName("payment-aborted")
@@ -294,10 +310,11 @@ class PaymentAbortedTransaction(
*/
val amountLost: Amount
) : Transaction(timestamp) {
- override val layout = R.layout.transaction_out
- override val title = R.string.transaction_payment_aborted
+ override val title = orderShortInfo.summary
override val icon = R.drawable.transaction_payment_aborted
override val showToUser = true
+ override val displayAmount = DisplayAmount(amountLost, AmountType.Negative)
+ override fun isCurrency(currency: String) = orderShortInfo.amount.currency == currency
}
@JsonTypeName("refreshed")
@@ -325,10 +342,19 @@ class RefreshTransaction(
*/
val refreshGroupId: String
) : Transaction(timestamp) {
- override val layout = R.layout.transaction_out
override val icon = R.drawable.transaction_refresh
- override val title = R.string.transaction_refresh
+ override val title: String? = null
override val showToUser = !(amountRefreshedRaw - amountRefreshedEffective).isZero()
+ override val displayAmount: DisplayAmount?
+ get() {
+ return if (showToUser) DisplayAmount(
+ amountRefreshedRaw - amountRefreshedEffective,
+ AmountType.Negative
+ )
+ else null
+ }
+
+ override fun isCurrency(currency: String) = amountRefreshedRaw.currency == currency
}
@JsonTypeName("order-redirected")
@@ -345,7 +371,8 @@ class OrderRedirectedTransaction(
val alreadyPaidOrderShortInfo: OrderShortInfo
) : Transaction(timestamp) {
override val icon = R.drawable.ic_directions
- override val title = R.string.transaction_order_redirected
+ override val title = newOrderShortInfo.summary
+ override fun isCurrency(currency: String) = newOrderShortInfo.amount.currency == currency
}
@JsonTypeName("tip-accepted")
@@ -361,9 +388,10 @@ class TipAcceptedTransaction(
val tipRaw: Amount
) : Transaction(timestamp) {
override val icon = R.drawable.transaction_tip_accepted
- override val title = R.string.transaction_tip_accepted
- override val layout = R.layout.transaction_in
+ override val title: String? = null
override val showToUser = true
+ override val displayAmount = DisplayAmount(tipRaw, AmountType.Positive)
+ override fun isCurrency(currency: String) = tipRaw.currency == currency
}
@JsonTypeName("tip-declined")
@@ -379,9 +407,10 @@ class TipDeclinedTransaction(
val tipAmount: Amount
) : Transaction(timestamp) {
override val icon = R.drawable.transaction_tip_declined
- override val title = R.string.transaction_tip_declined
- override val layout = R.layout.transaction_in
+ override val title: String? = null
override val showToUser = true
+ override val displayAmount = DisplayAmount(tipAmount, AmountType.Neutral)
+ override fun isCurrency(currency: String) = tipAmount.currency == currency
}
@JsonTypeName("refund")
@@ -408,10 +437,11 @@ class RefundTransaction(
val amountRefundedEffective: Amount
) : Transaction(timestamp) {
override val icon = R.drawable.transaction_refund
- override val title = R.string.transaction_refund
- override val layout = R.layout.transaction_in
+ override val title = orderShortInfo.summary
override val detailPageLayout = R.layout.fragment_event_paid
override val showToUser = true
+ override val displayAmount = DisplayAmount(amountRefundedEffective, AmountType.Positive)
+ override fun isCurrency(currency: String) = amountRefundedRaw.currency == currency
}
@JsonTypeInfo(
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt
index beebcda..809f6a9 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionAdapter.kt
@@ -17,18 +17,19 @@
package net.taler.wallet.transactions
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.recyclerview.widget.RecyclerView.Adapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import net.taler.common.exhaustive
import net.taler.common.toRelativeTime
import net.taler.wallet.R
-import net.taler.wallet.cleanExchange
import net.taler.wallet.transactions.TransactionAdapter.TransactionViewHolder
@@ -42,15 +43,10 @@ internal class TransactionAdapter(
setHasStableIds(false)
}
- override fun getItemViewType(position: Int): Int = transactions[position].layout
-
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionViewHolder {
- val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
- return when (viewType) {
- R.layout.transaction_in -> TransactionInViewHolder(view)
- R.layout.transaction_out -> TransactionOutViewHolder(view)
- else -> GenericTransactionViewHolder(view)
- }
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.list_item_transaction, parent, false)
+ return TransactionViewHolder(view)
}
override fun getItemCount(): Int = transactions.size
@@ -65,122 +61,73 @@ internal class TransactionAdapter(
this.notifyDataSetChanged()
}
- internal abstract inner class TransactionViewHolder(private val v: View) : ViewHolder(v) {
+ internal open inner class TransactionViewHolder(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)
+ private val amount: TextView = v.findViewById(R.id.amount)
+
private val selectableBackground = v.background
+ private val amountColor = amount.currentTextColor
@CallSuper
- open fun bind(event: Transaction) {
- if (devMode || event.detailPageLayout != 0) {
+ open fun bind(transaction: Transaction) {
+ if (devMode || transaction.detailPageLayout != 0) {
v.background = selectableBackground
- v.setOnClickListener { listener.onEventClicked(event) }
+ v.setOnClickListener { listener.onEventClicked(transaction) }
} else {
v.background = null
v.setOnClickListener(null)
}
- 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(context)
- }
-
- }
-
- internal inner class GenericTransactionViewHolder(v: View) : TransactionViewHolder(v) {
-
- private val info: TextView = v.findViewById(R.id.info)
-
- override fun bind(transaction: Transaction) {
- super.bind(transaction)
- info.text = when (transaction) {
- is ExchangeAddedEvent -> cleanExchange(transaction.exchangeBaseUrl)
- is ExchangeUpdatedEvent -> cleanExchange(transaction.exchangeBaseUrl)
- is ReserveBalanceUpdatedTransaction -> transaction.reserveBalance.toString()
- is PaymentTransaction -> transaction.orderShortInfo.summary
- is OrderAcceptedTransaction -> transaction.orderShortInfo.summary
- is OrderRefusedTransaction -> transaction.orderShortInfo.summary
- is OrderRedirectedTransaction -> transaction.newOrderShortInfo.summary
- else -> ""
- }
+ icon.setImageResource(transaction.icon)
+
+ title.text = if (transaction.title == null) {
+ when (transaction) {
+ is RefreshTransaction -> getRefreshTitle(transaction)
+ is OrderAcceptedTransaction -> context.getString(R.string.transaction_order_accepted)
+ is OrderRefusedTransaction -> context.getString(R.string.transaction_order_refused)
+ is TipAcceptedTransaction -> context.getString(R.string.transaction_tip_accepted)
+ is TipDeclinedTransaction -> context.getString(R.string.transaction_tip_declined)
+ is ReserveBalanceUpdatedTransaction -> context.getString(R.string.transaction_reserve_balance_updated)
+ else -> transaction::class.java.simpleName
+ }
+ } else transaction.title
+
+ time.text = transaction.timestamp.ms.toRelativeTime(context)
+ bindAmount(transaction.displayAmount)
}
- }
-
- internal inner class TransactionInViewHolder(v: View) : TransactionViewHolder(v) {
-
- private val summary: TextView = v.findViewById(R.id.summary)
- private val amountWithdrawn: TextView = v.findViewById(R.id.amountWithdrawn)
- private val paintFlags = amountWithdrawn.paintFlags
-
- override fun bind(event: Transaction) {
- super.bind(event)
- when (event) {
- is WithdrawTransaction -> bind(event)
- is RefundTransaction -> bind(event)
- is TipAcceptedTransaction -> bind(event)
- is TipDeclinedTransaction -> bind(event)
- }
- }
-
- private fun bind(event: WithdrawTransaction) {
- summary.text = cleanExchange(event.exchangeBaseUrl)
- amountWithdrawn.text =
- context.getString(R.string.amount_positive, event.amountWithdrawnEffective)
- amountWithdrawn.paintFlags = paintFlags
- }
-
- private fun bind(event: RefundTransaction) {
- summary.text = event.orderShortInfo.summary
- amountWithdrawn.text =
- context.getString(R.string.amount_positive, event.amountRefundedEffective)
- amountWithdrawn.paintFlags = paintFlags
- }
-
- private fun bind(transaction: TipAcceptedTransaction) {
- summary.text = null
- amountWithdrawn.text = context.getString(R.string.amount_positive, transaction.tipRaw)
- amountWithdrawn.paintFlags = paintFlags
- }
-
- private fun bind(transaction: TipDeclinedTransaction) {
- summary.text = null
- amountWithdrawn.text = context.getString(R.string.amount_positive, transaction.tipAmount)
- amountWithdrawn.paintFlags = amountWithdrawn.paintFlags or STRIKE_THRU_TEXT_FLAG
- }
-
- }
-
- internal inner class TransactionOutViewHolder(v: View) : TransactionViewHolder(v) {
-
- private val summary: TextView = v.findViewById(R.id.summary)
- private val amountPaidWithFees: TextView = v.findViewById(R.id.amountPaidWithFees)
-
- override fun bind(event: Transaction) {
- super.bind(event)
- when (event) {
- is PaymentTransaction -> bind(event)
- is PaymentAbortedTransaction -> bind(event)
- is RefreshTransaction -> bind(event)
+ private fun bindAmount(displayAmount: DisplayAmount?) {
+ if (displayAmount == null) {
+ amount.visibility = GONE
+ } else {
+ amount.visibility = VISIBLE
+ when (displayAmount.type) {
+ AmountType.Positive -> {
+ amount.text = context.getString(
+ R.string.amount_positive, displayAmount.amount.amountStr
+ )
+ amount.setTextColor(context.getColor(R.color.green))
+ }
+ AmountType.Negative -> {
+ amount.text = context.getString(
+ R.string.amount_negative, displayAmount.amount.amountStr
+ )
+ amount.setTextColor(context.getColor(R.color.red))
+ }
+ AmountType.Neutral -> {
+ amount.text = displayAmount.amount.amountStr
+ amount.setTextColor(amountColor)
+ }
+ }.exhaustive
}
}
- private fun bind(event: PaymentTransaction) {
- summary.text = event.orderShortInfo.summary
- amountPaidWithFees.text =
- context.getString(R.string.amount_negative, event.amountPaidWithFees)
- }
-
- private fun bind(transaction: PaymentAbortedTransaction) {
- summary.text = transaction.orderShortInfo.summary
- amountPaidWithFees.text = context.getString(R.string.amount_negative, transaction.amountLost)
- }
-
- private fun bind(event: RefreshTransaction) {
- val res = when (event.refreshReason) {
+ private fun getRefreshTitle(transaction: RefreshTransaction): String {
+ val res = when (transaction.refreshReason) {
RefreshReason.MANUAL -> R.string.transaction_refresh_reason_manual
RefreshReason.PAY -> R.string.transaction_refresh_reason_pay
RefreshReason.REFUND -> R.string.transaction_refresh_reason_refund
@@ -188,10 +135,7 @@ internal class TransactionAdapter(
RefreshReason.RECOUP -> R.string.transaction_refresh_reason_recoup
RefreshReason.BACKUP_RESTORED -> R.string.transaction_refresh_reason_backup_restored
}
- summary.text = context.getString(res)
- val fee = event.amountRefreshedRaw - event.amountRefreshedEffective
- if (fee.isZero()) amountPaidWithFees.text = null
- else amountPaidWithFees.text = context.getString(R.string.amount_negative, fee)
+ return context.getString(R.string.transaction_refresh) + " " + context.getString(res)
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
index f198215..909a7bf 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
@@ -59,7 +59,7 @@ class TransactionDetailFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
requireActivity().title =
- getString(if (event.title != 0) event.title else R.string.transactions_detail_title)
+ if (event.title != null) event.title else getString(R.string.transactions_detail_title)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
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 c4ab785..549b2a8 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionManager.kt
@@ -46,6 +46,7 @@ class TransactionManager(
val showAll = MutableLiveData<Boolean>()
+ var selectedCurrency: String? = null
var selectedEvent: Transaction? = null
val transactions: LiveData<TransactionsResult> = showAll.switchMap { showAll ->
@@ -65,10 +66,13 @@ class TransactionManager(
}
val transactions = Transactions()
val json = result.getJSONArray("history")
+ val currency = selectedCurrency
for (i in 0 until json.length()) {
val event: Transaction = mapper.readValue(json.getString(i))
event.json = json.getJSONObject(i)
- transactions.add(event)
+ if (currency == null || event.isCurrency(currency)) {
+ transactions.add(event)
+ }
}
transactions.reverse() // show latest first
val filtered =
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 663a5aa..4f62547 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
@@ -47,6 +47,7 @@ class TransactionsFragment : Fragment(), OnEventClickListener {
private val model: MainViewModel by activityViewModels()
private val transactionManager by lazy { model.transactionManager }
private val transactionAdapter by lazy { TransactionAdapter(model.devMode.value == true, this) }
+ private val currency by lazy { transactionManager.selectedCurrency!! }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -78,6 +79,16 @@ class TransactionsFragment : Fragment(), OnEventClickListener {
if (savedInstanceState == null) transactionManager.showAll.value = model.devMode.value
}
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ model.balances.observe(viewLifecycleOwner, Observer { balances ->
+ balances[currency]?.available?.let { amount ->
+ requireActivity().title =
+ getString(R.string.transactions_detail_title_balance, amount)
+ }
+ })
+ }
+
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.transactions, menu)
}
diff --git a/wallet/src/main/res/drawable/ic_history_black_24dp.xml b/wallet/src/main/res/drawable/ic_history_black_24dp.xml
deleted file mode 100644
index 5836444..0000000
--- a/wallet/src/main/res/drawable/ic_history_black_24dp.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
- ~ 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/>
- -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z" />
-</vector>
diff --git a/wallet/src/main/res/drawable/pending_border.xml b/wallet/src/main/res/drawable/pending_border.xml
index c858219..0e201dc 100644
--- a/wallet/src/main/res/drawable/pending_border.xml
+++ b/wallet/src/main/res/drawable/pending_border.xml
@@ -18,14 +18,14 @@
android:shape="rectangle">
<!-- View background color -->
- <solid android:color="@android:color/transparent"></solid>
+ <solid android:color="@android:color/transparent"/>
<!-- View border color and width -->
<stroke
android:width="1dp"
- android:color="@color/colorPrimary"></stroke>
+ android:color="@color/colorPrimary"/>
<!-- The radius makes the corners rounded -->
- <corners android:radius="2dp"></corners>
+ <corners android:radius="2dp"/>
</shape> \ No newline at end of file
diff --git a/wallet/src/main/res/layout/fragment_show_balance.xml b/wallet/src/main/res/layout/fragment_main.xml
index 3f4aa2e..57fe73e 100644
--- a/wallet/src/main/res/layout/fragment_show_balance.xml
+++ b/wallet/src/main/res/layout/fragment_main.xml
@@ -46,6 +46,7 @@
android:layout_gravity="bottom|end"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
+ android:contentDescription="@string/button_scan_qr_code"
android:src="@drawable/ic_scan_qr"
app:backgroundTint="@color/colorPrimary"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
diff --git a/wallet/src/main/res/layout/fragment_pending_operations.xml b/wallet/src/main/res/layout/fragment_pending_operations.xml
index 775c89f..5030234 100644
--- a/wallet/src/main/res/layout/fragment_pending_operations.xml
+++ b/wallet/src/main/res/layout/fragment_pending_operations.xml
@@ -29,6 +29,6 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
- tools:listitem="@layout/pending_row" />
+ tools:listitem="@layout/list_item_pending_operation" />
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/wallet/src/main/res/layout/pending_row.xml b/wallet/src/main/res/layout/list_item_pending_operation.xml
index bd606c3..bd606c3 100644
--- a/wallet/src/main/res/layout/pending_row.xml
+++ b/wallet/src/main/res/layout/list_item_pending_operation.xml
diff --git a/wallet/src/main/res/layout/transaction_row.xml b/wallet/src/main/res/layout/list_item_transaction.xml
index ac6bdb7..a3ac980 100644
--- a/wallet/src/main/res/layout/transaction_row.xml
+++ b/wallet/src/main/res/layout/list_item_transaction.xml
@@ -32,9 +32,9 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
- app:srcCompat="@drawable/ic_account_balance"
app:tint="?android:colorControlNormal"
- tools:ignore="ContentDescription" />
+ tools:ignore="ContentDescription"
+ tools:src="@drawable/ic_cash_usd_outline" />
<TextView
android:id="@+id/title"
@@ -42,35 +42,33 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
- app:layout_constraintEnd_toEndOf="parent"
+ android:layout_marginEnd="8dp"
+ app:layout_constraintEnd_toStartOf="@+id/amount"
app:layout_constraintStart_toEndOf="@+id/icon"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_chainStyle="packed"
- tools:text="My Transaction" />
+ tools:text="@string/transaction_payment" />
<TextView
- android:id="@+id/info"
- android:layout_width="0dp"
+ android:id="@+id/amount"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginTop="8dp"
- android:layout_marginEnd="8dp"
+ android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toStartOf="@+id/time"
- app:layout_constraintStart_toEndOf="@+id/icon"
- app:layout_constraintTop_toBottomOf="@+id/title"
- tools:text="TextView" />
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="- 1337.23" />
<TextView
android:id="@+id/time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
- android:gravity="end"
+ android:layout_marginEnd="8dp"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/amount"
+ app:layout_constraintStart_toStartOf="@+id/title"
app:layout_constraintTop_toBottomOf="@+id/title"
- tools:text="3 days ago" />
+ tools:text="23 min ago" />
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/wallet/src/main/res/layout/transaction_in.xml b/wallet/src/main/res/layout/transaction_in.xml
deleted file mode 100644
index f116240..0000000
--- a/wallet/src/main/res/layout/transaction_in.xml
+++ /dev/null
@@ -1,92 +0,0 @@
-<?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/>
- -->
-
-<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:background="?attr/selectableItemBackground"
- android:paddingStart="16dp"
- android:paddingTop="8dp"
- android:paddingEnd="16dp"
- android:paddingBottom="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/transaction_withdrawal"
- app:tint="?android:colorControlNormal"
- tools:ignore="ContentDescription" />
-
- <TextView
- android:id="@+id/title"
- style="@style/TransactionTitle"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginEnd="8dp"
- android:text="@string/transaction_withdrawal"
- app:layout_constraintEnd_toStartOf="@+id/amountWithdrawn"
- app:layout_constraintStart_toEndOf="@+id/icon"
- app:layout_constraintTop_toTopOf="parent" />
-
- <TextView
- android:id="@+id/summary"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- 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/time"
- app:layout_constraintHorizontal_bias="0.5"
- app:layout_constraintStart_toEndOf="@+id/icon"
- app:layout_constraintTop_toBottomOf="@+id/title"
- app:layout_constraintVertical_bias="0.0"
- tools:text="exchange.taler.quite-long-domain-name.org" />
-
- <TextView
- android:id="@+id/amountWithdrawn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@color/green"
- android:textSize="16sp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- tools:text="10 TESTKUDOS" />
-
- <TextView
- android:id="@+id/time"
- 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_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/transaction_out.xml b/wallet/src/main/res/layout/transaction_out.xml
deleted file mode 100644
index 49f76b7..0000000
--- a/wallet/src/main/res/layout/transaction_out.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?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/>
- -->
-
-<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:background="?attr/selectableItemBackground"
- android:paddingStart="16dp"
- android:paddingTop="8dp"
- android:paddingEnd="16dp"
- android:paddingBottom="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:tint="?android:colorControlNormal"
- tools:ignore="ContentDescription"
- tools:src="@drawable/ic_cash_usd_outline" />
-
- <TextView
- android:id="@+id/title"
- style="@style/TransactionTitle"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- 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="@string/transaction_payment" />
-
- <TextView
- android:id="@+id/summary"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginTop="8dp"
- app:layout_constrainedWidth="true"
- app:layout_constraintBottom_toBottomOf="parent"
- 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="Lots of books with very long titles" />
-
- <TextView
- android:id="@+id/amountPaidWithFees"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@color/red"
- android:textSize="16sp"
- app:layout_constraintBottom_toTopOf="@+id/time"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintVertical_bias="0.0"
- tools:text="0.2 TESTKUDOS" />
-
- <TextView
- android:id="@+id/time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="14sp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- tools:text="23 min ago" />
-
-</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/wallet/src/main/res/navigation/nav_graph.xml b/wallet/src/main/res/navigation/nav_graph.xml
index f8927a6..ef0f48b 100644
--- a/wallet/src/main/res/navigation/nav_graph.xml
+++ b/wallet/src/main/res/navigation/nav_graph.xml
@@ -25,7 +25,7 @@
android:id="@+id/showBalance"
android:name="net.taler.wallet.MainFragment"
android:label="@string/balances_title"
- tools:layout="@layout/fragment_show_balance">
+ tools:layout="@layout/fragment_main">
<action
android:id="@+id/action_showBalance_to_promptPayment"
app:destination="@id/promptPayment" />
diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml
index d2840de..e0b3183 100644
--- a/wallet/src/main/res/values/strings.xml
+++ b/wallet/src/main/res/values/strings.xml
@@ -47,24 +47,20 @@
<string name="transactions_empty">You don\'t have any transactions</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>
<string name="transactions_detail_json">Show JSON</string>
<!-- Transactions -->
- <string name="history_event_exchange_added">Exchange Added</string>
- <string name="history_event_exchange_updated">Exchange Updated</string>
<string name="transaction_reserve_balance_updated">Reserve Balance Updated</string>
<string name="transaction_payment">Payment</string>
<string name="transaction_paid">Paid</string>
<string name="transaction_order_total">Order Total</string>
<string name="transaction_order">Order</string>
<string name="transaction_order_id">Order Reference: %1$s</string>
- <string name="transaction_payment_aborted">Payment Aborted</string>
- <string name="transaction_withdrawal">Withdraw</string>
<string name="transaction_order_accepted">Purchase Confirmed</string>
<string name="transaction_order_refused">Purchase Cancelled</string>
<string name="transaction_tip_accepted">Tip Accepted</string>
<string name="transaction_tip_declined">Tip Declined</string>
- <string name="transaction_order_redirected">Purchase Redirected</string>
<string name="transaction_refund">Refund</string>
<string name="transaction_refresh">Obtained change</string>
<string name="transaction_refresh_reason_manual">because of manual request</string>
@@ -73,7 +69,6 @@
<string name="transaction_refresh_reason_abort_pay">to abort payment</string>
<string name="transaction_refresh_reason_recoup">to recoup funds</string>
<string name="transaction_refresh_reason_backup_restored">because of restoring from backup</string>
- <string name="transaction_unknown">Unknown Transaction</string>
<string name="payment_fee">+%s payment fee</string>
<string name="payment_button_confirm">Confirm Payment</string>