diff options
author | Torsten Grote <t@grobox.de> | 2020-04-15 13:49:25 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2020-04-15 13:49:25 -0300 |
commit | ea2abcac101645e429cab734c726e3b6a744dae9 (patch) | |
tree | ed70393d7889b10446d5dbe1f402835e2dab1e2c /wallet | |
parent | ea3250845fb266a2ecd5ebeba561bc99101bf3de (diff) | |
download | taler-android-ea2abcac101645e429cab734c726e3b6a744dae9.tar.gz taler-android-ea2abcac101645e429cab734c726e3b6a744dae9.tar.bz2 taler-android-ea2abcac101645e429cab734c726e3b6a744dae9.zip |
[wallet] show simplified transactions per currency
Diffstat (limited to 'wallet')
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> |