aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--taler-kotlin-common/src/main/java/net/taler/common/Event.kt51
-rw-r--r--wallet/src/main/java/net/taler/wallet/MainActivity.kt1
-rw-r--r--wallet/src/main/java/net/taler/wallet/MainFragment.kt25
-rw-r--r--wallet/src/main/java/net/taler/wallet/MainViewModel.kt13
-rw-r--r--wallet/src/main/java/net/taler/wallet/balances/BalancesFragment.kt4
-rw-r--r--wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt3
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt3
7 files changed, 87 insertions, 13 deletions
diff --git a/taler-kotlin-common/src/main/java/net/taler/common/Event.kt b/taler-kotlin-common/src/main/java/net/taler/common/Event.kt
new file mode 100644
index 0000000..779247f
--- /dev/null
+++ b/taler-kotlin-common/src/main/java/net/taler/common/Event.kt
@@ -0,0 +1,51 @@
+/*
+ * 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.common
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.Observer
+import java.util.concurrent.atomic.AtomicBoolean
+
+/**
+ * Used as a wrapper for data that is exposed via a [LiveData] that represents an one-time event.
+ */
+open class Event<out T>(private val content: T) {
+
+ private val isConsumed = AtomicBoolean(false)
+
+ /**
+ * Returns the content and prevents its use again.
+ */
+ fun getIfNotConsumed(): T? {
+ return if (isConsumed.compareAndSet(false, true)) content else null
+ }
+
+}
+
+fun <T> T.toEvent() = Event(this)
+
+/**
+ * An [Observer] for [Event]s, simplifying the pattern of checking if the [Event]'s content has
+ * already been consumed.
+ *
+ * [onEvent] is *only* called if the [Event]'s contents has not been consumed.
+ */
+class EventObserver<T>(private val onEvent: (T) -> Unit) : Observer<Event<T>> {
+ override fun onChanged(event: Event<T>?) {
+ event?.getIfNotConsumed()?.let { onEvent(it) }
+ }
+}
diff --git a/wallet/src/main/java/net/taler/wallet/MainActivity.kt b/wallet/src/main/java/net/taler/wallet/MainActivity.kt
index a6385a9..f626e4f 100644
--- a/wallet/src/main/java/net/taler/wallet/MainActivity.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainActivity.kt
@@ -157,6 +157,7 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener {
model.showProgressBar.value = false
val res = when (status) {
is RefundStatus.Error -> R.string.refund_error
+ // TODO once wallet-core exposes currency, navigate to its transaction list
is RefundStatus.Success -> R.string.refund_success
}
Snackbar.make(nav_view, res, LENGTH_LONG).show()
diff --git a/wallet/src/main/java/net/taler/wallet/MainFragment.kt b/wallet/src/main/java/net/taler/wallet/MainFragment.kt
index 2905238..328d7a2 100644
--- a/wallet/src/main/java/net/taler/wallet/MainFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainFragment.kt
@@ -23,14 +23,20 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
+import androidx.navigation.fragment.findNavController
import kotlinx.android.synthetic.main.fragment_main.*
+import net.taler.common.EventObserver
+import net.taler.wallet.CurrencyMode.MULTI
+import net.taler.wallet.CurrencyMode.SINGLE
import net.taler.wallet.balances.BalancesFragment
import net.taler.wallet.transactions.TransactionsFragment
+enum class CurrencyMode { SINGLE, MULTI }
+
class MainFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
- private var currentTag: String? = null
+ private var currencyMode: CurrencyMode? = null
override fun onCreateView(
inflater: LayoutInflater,
@@ -44,6 +50,13 @@ class MainFragment : Fragment() {
model.balances.observe(viewLifecycleOwner, Observer {
onBalancesChanged(it.values.toList())
})
+ model.transactionsEvent.observe(viewLifecycleOwner, EventObserver { currency ->
+ // we only need to navigate to a dedicated list, when in multi-currency mode
+ if (currencyMode == MULTI) {
+ model.transactionManager.selectedCurrency = currency
+ findNavController().navigate(R.id.action_nav_main_to_nav_transactions)
+ }
+ })
mainFab.setOnClickListener {
scanQrCode(requireActivity())
@@ -56,17 +69,17 @@ class MainFragment : Fragment() {
}
private fun onBalancesChanged(balances: List<BalanceItem>) {
- val tag = if (balances.size == 1) "single" else "multi"
- if (currentTag != tag) {
- val f = if (tag == "single") {
+ val mode = if (balances.size == 1) SINGLE else MULTI
+ if (currencyMode != mode) {
+ val f = if (mode == SINGLE) {
model.transactionManager.selectedCurrency = balances[0].available.currency
TransactionsFragment()
} else {
BalancesFragment()
}
- currentTag = tag
+ currencyMode = mode
childFragmentManager.beginTransaction()
- .replace(R.id.mainFragmentContainer, f, tag)
+ .replace(R.id.mainFragmentContainer, f, mode.name)
.commitNow()
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
index f10666e..6a1d6aa 100644
--- a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
@@ -28,7 +28,9 @@ import com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PRO
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import net.taler.common.Amount
+import net.taler.common.Event
import net.taler.common.assertUiThread
+import net.taler.common.toEvent
import net.taler.wallet.backend.WalletBackendApi
import net.taler.wallet.history.DevHistoryManager
import net.taler.wallet.payment.PaymentManager
@@ -99,6 +101,9 @@ class MainViewModel(val app: Application) : AndroidViewModel(app) {
TransactionManager(walletBackendApi, viewModelScope, mapper)
val refundManager = RefundManager(walletBackendApi)
+ private val mTransactionsEvent = MutableLiveData<Event<String>>()
+ val transactionsEvent: LiveData<Event<String>> = mTransactionsEvent
+
override fun onCleared() {
walletBackendApi.destroy()
super.onCleared()
@@ -129,6 +134,14 @@ class MainViewModel(val app: Application) : AndroidViewModel(app) {
}
}
+ /**
+ * Navigates to the given currency's transaction list, when [MainFragment] is shown.
+ */
+ @UiThread
+ fun showTransactions(currency: String) {
+ mTransactionsEvent.value = currency.toEvent()
+ }
+
@UiThread
fun dangerouslyReset() {
walletBackendApi.sendRequest("reset", null)
diff --git a/wallet/src/main/java/net/taler/wallet/balances/BalancesFragment.kt b/wallet/src/main/java/net/taler/wallet/balances/BalancesFragment.kt
index 0a2b29a..ab4077a 100644
--- a/wallet/src/main/java/net/taler/wallet/balances/BalancesFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/balances/BalancesFragment.kt
@@ -27,7 +27,6 @@ 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.VERTICAL
import kotlinx.android.synthetic.main.fragment_balances.*
@@ -79,8 +78,7 @@ class BalancesFragment : Fragment(),
}
override fun onBalanceClick(currency: String) {
- model.transactionManager.selectedCurrency = currency
- findNavController().navigate(R.id.action_nav_main_to_nav_transactions)
+ model.showTransactions(currency)
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt
index ab109bc..6f806b7 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt
@@ -116,9 +116,8 @@ class PromptPaymentFragment : Fragment(), ProductImageClickListener {
is PayStatus.Success -> {
showLoading(false)
paymentManager.resetPayStatus()
- // TODO bring the user to the currency's transaction page, if there's more than one currency
- model.transactionManager.selectedCurrency = payStatus.currency
findNavController().navigate(R.id.action_promptPayment_to_nav_main)
+ model.showTransactions(payStatus.currency)
Snackbar.make(requireView(), R.string.payment_initiated, LENGTH_LONG).show()
}
is PayStatus.AlreadyPaid -> {
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 e700f67..331554b 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
@@ -77,9 +77,8 @@ class PromptWithdrawFragment : Fragment() {
is WithdrawStatus.Success -> {
model.showProgressBar.value = false
withdrawManager.withdrawStatus.value = null
- // TODO bring the user to the currency's transaction page, if there's more than one currency
- model.transactionManager.selectedCurrency = status.currency
findNavController().navigate(R.id.action_promptWithdraw_to_nav_main)
+ model.showTransactions(status.currency)
Snackbar.make(requireView(), R.string.withdraw_initiated, LENGTH_LONG).show()
}
is Loading -> {