[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-android] branch master updated (36821f9 -> ce5a1d2)
From: |
gnunet |
Subject: |
[taler-taler-android] branch master updated (36821f9 -> ce5a1d2) |
Date: |
Thu, 03 Sep 2020 18:41:57 +0200 |
This is an automated email from the git hooks/post-receive script.
torsten-grote pushed a change to branch master
in repository taler-android.
from 36821f9 [cashier] amount, not balance amount (following ISO 20022)
new d56c5ea Don't crash on empty manual withdrawal amount
new 74b1394 [cashier] migrate to view binding as kotlin extensions are
broken
new 126b071 [pos] migrate to view binding
new 85c344b [wallet] migrate away from kotlin view extensions
new 1cb9161 [pos] make app work on API 24+
new ce5a1d2 [wallet] show different withdrawal error message when app is
offline
The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
cashier/build.gradle | 5 +-
cashier/proguard-rules.pro | 2 +
.../main/java/net/taler/cashier/BalanceFragment.kt | 57 ++++++------
.../main/java/net/taler/cashier/MainActivity.kt | 9 +-
.../main/java/net/taler/cashier/config/Config.kt | 1 -
.../net/taler/cashier/config/ConfigFragment.kt | 65 ++++++-------
.../net/taler/cashier/withdraw/ErrorFragment.kt | 13 ++-
.../taler/cashier/withdraw/TransactionFragment.kt | 58 ++++++------
merchant-terminal/build.gradle | 7 +-
.../java/net/taler/merchantpos/MainActivity.kt | 26 +++---
.../merchantpos/config/ConfigFetcherFragment.kt | 7 +-
.../net/taler/merchantpos/config/ConfigFragment.kt | 61 ++++++------
.../java/net/taler/merchantpos/config/PosConfig.kt | 4 +-
.../taler/merchantpos/history/HistoryFragment.kt | 18 ++--
.../taler/merchantpos/order/CategoriesFragment.kt | 15 +--
.../net/taler/merchantpos/order/OrderFragment.kt | 50 +++++-----
.../taler/merchantpos/order/OrderStateFragment.kt | 31 ++++---
.../taler/merchantpos/order/ProductsFragment.kt | 14 +--
.../merchantpos/payment/PaymentSuccessFragment.kt | 10 +-
.../merchantpos/payment/ProcessPaymentFragment.kt | 28 +++---
.../net/taler/merchantpos/refund/RefundFragment.kt | 42 +++++----
.../taler/merchantpos/refund/RefundUriFragment.kt | 19 ++--
.../src/main/res/layout/activity_main.xml | 1 +
.../main/java/net/taler/common/ContractTerms.kt | 9 +-
wallet/build.gradle | 9 +-
.../src/main/java/net/taler/wallet/MainActivity.kt | 39 ++++----
.../src/main/java/net/taler/wallet/MainFragment.kt | 14 +--
.../main/java/net/taler/wallet/UriInputFragment.kt | 23 +++--
.../net/taler/wallet/balances/BalancesFragment.kt | 20 ++--
.../taler/wallet/exchanges/ExchangeListFragment.kt | 26 +++---
.../wallet/exchanges/SelectExchangeFragment.kt | 29 +++---
.../taler/wallet/payment/AlreadyPaidFragment.kt | 10 +-
.../taler/wallet/payment/ProductImageFragment.kt | 10 +-
.../taler/wallet/payment/PromptPaymentFragment.kt | 56 +++++------
.../wallet/pending/PendingOperationsFragment.kt | 11 ++-
.../net/taler/wallet/settings/SettingsFragment.kt | 7 +-
.../transactions/TransactionDetailFragment.kt | 103 +++------------------
.../TransactionPaymentFragment.kt} | 42 +++++----
.../transactions/TransactionRefreshFragment.kt | 56 +++++++++++
.../transactions/TransactionRefundFragment.kt | 61 ++++++++++++
.../transactions/TransactionWithdrawalFragment.kt | 68 ++++++++++++++
.../net/taler/wallet/transactions/Transactions.kt | 19 ++--
.../wallet/transactions/TransactionsFragment.kt | 45 ++++-----
.../net/taler/wallet/withdraw/ErrorFragment.kt | 26 ++++--
.../wallet/withdraw/ManualWithdrawFragment.kt | 32 ++++---
.../wallet/withdraw/PromptWithdrawFragment.kt | 48 +++++-----
.../wallet/withdraw/ReviewExchangeTosFragment.kt | 29 +++---
.../net/taler/wallet/withdraw/WithdrawManager.kt | 34 +++----
wallet/src/main/res/layout/activity_main.xml | 3 +-
.../{app_bar_main.xml => app_content_main.xml} | 0
.../main/res/layout/fragment_prompt_payment.xml | 8 +-
wallet/src/main/res/layout/payment_bottom_bar.xml | 1 +
wallet/src/main/res/navigation/nav_graph.xml | 38 +++++++-
wallet/src/main/res/values/strings.xml | 3 +
54 files changed, 827 insertions(+), 595 deletions(-)
copy wallet/src/main/java/net/taler/wallet/{payment/ProductImageFragment.kt =>
transactions/TransactionPaymentFragment.kt} (53%)
create mode 100644
wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
create mode 100644
wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt
create mode 100644
wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
rename wallet/src/main/res/layout/{app_bar_main.xml => app_content_main.xml}
(100%)
diff --git a/cashier/build.gradle b/cashier/build.gradle
index f5c56a9..a749353 100644
--- a/cashier/build.gradle
+++ b/cashier/build.gradle
@@ -17,7 +17,6 @@
plugins {
id "com.android.application"
id "kotlin-android"
- id "kotlin-android-extensions"
id "kotlinx-serialization"
id "androidx.navigation.safeargs.kotlin"
}
@@ -51,6 +50,10 @@ android {
jvmTarget = "1.8"
}
+ buildFeatures {
+ viewBinding = true
+ }
+
packagingOptions {
exclude("META-INF/*.kotlin_module")
}
diff --git a/cashier/proguard-rules.pro b/cashier/proguard-rules.pro
index f612b29..a1cc1f6 100644
--- a/cashier/proguard-rules.pro
+++ b/cashier/proguard-rules.pro
@@ -20,6 +20,8 @@
# hide the original source file name.
#-renamesourcefileattribute SourceFile
+-keep class net.taler.cashier.** {*;}
+
# androidx.security:security-crypto
# https://github.com/google/tink/issues/361
-keep class * extends
com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite { *; }
diff --git a/cashier/src/main/java/net/taler/cashier/BalanceFragment.kt
b/cashier/src/main/java/net/taler/cashier/BalanceFragment.kt
index cdfa142..1114080 100644
--- a/cashier/src/main/java/net/taler/cashier/BalanceFragment.kt
+++ b/cashier/src/main/java/net/taler/cashier/BalanceFragment.kt
@@ -29,8 +29,8 @@ 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_balance.*
import
net.taler.cashier.BalanceFragmentDirections.Companion.actionBalanceFragmentToTransactionFragment
+import net.taler.cashier.databinding.FragmentBalanceBinding
import net.taler.cashier.withdraw.LastTransaction
import net.taler.cashier.withdraw.WithdrawStatus
import net.taler.common.exhaustive
@@ -50,12 +50,15 @@ class BalanceFragment : Fragment() {
private val configManager by lazy { viewModel.configManager}
private val withdrawManager by lazy { viewModel.withdrawManager }
+ private lateinit var ui: FragmentBalanceBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
setHasOptionsMenu(true)
- return inflater.inflate(R.layout.fragment_balance, container, false)
+ ui = FragmentBalanceBinding.inflate(layoutInflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -65,24 +68,24 @@ class BalanceFragment : Fragment() {
viewModel.balance.observe(viewLifecycleOwner, Observer { result ->
onBalanceUpdated(result)
})
- button5.setOnClickListener { onAmountButtonPressed(5) }
- button10.setOnClickListener { onAmountButtonPressed(10) }
- button20.setOnClickListener { onAmountButtonPressed(20) }
- button50.setOnClickListener { onAmountButtonPressed(50) }
+ ui.button5.setOnClickListener { onAmountButtonPressed(5) }
+ ui.button10.setOnClickListener { onAmountButtonPressed(10) }
+ ui.button20.setOnClickListener { onAmountButtonPressed(20) }
+ ui.button50.setOnClickListener { onAmountButtonPressed(50) }
if (savedInstanceState != null) {
-
amountView.editText!!.setText(savedInstanceState.getCharSequence("amountView"))
+
ui.amountView.editText!!.setText(savedInstanceState.getCharSequence("amountView"))
}
- amountView.editText!!.setOnEditorActionListener { _, actionId, _ ->
+ ui.amountView.editText!!.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_GO) {
onAmountConfirmed(getAmountFromView())
true
} else false
}
configManager.currency.observe(viewLifecycleOwner, Observer { currency
->
- currencyView.text = currency
+ ui.currencyView.text = currency
})
- confirmWithdrawalButton.setOnClickListener {
onAmountConfirmed(getAmountFromView()) }
+ ui.confirmWithdrawalButton.setOnClickListener {
onAmountConfirmed(getAmountFromView()) }
}
override fun onStart() {
@@ -96,7 +99,7 @@ class BalanceFragment : Fragment() {
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
// for some reason automatic restore isn't working at the moment!?
- amountView?.editText?.text.let {
+ ui.amountView.editText?.text.let {
outState.putCharSequence("amountView", it)
}
}
@@ -121,34 +124,34 @@ class BalanceFragment : Fragment() {
private fun onBalanceUpdated(result: BalanceResult) {
val uiList = listOf(
- introView,
- button5, button10, button20, button50,
- amountView, currencyView, confirmWithdrawalButton
+ ui.introView,
+ ui.button5, ui.button10, ui.button20, ui.button50,
+ ui.amountView, ui.currencyView, ui.confirmWithdrawalButton
)
when (result) {
is BalanceResult.Success -> {
- balanceView.text = result.amount.toString()
+ ui.balanceView.text = result.amount.toString()
uiList.forEach { it.fadeIn() }
}
is BalanceResult.Error -> {
- balanceView.text = getString(R.string.balance_error,
result.msg)
+ ui.balanceView.text = getString(R.string.balance_error,
result.msg)
uiList.forEach { it.fadeOut() }
}
BalanceResult.Offline -> {
- balanceView.text = getString(R.string.balance_offline)
+ ui.balanceView.text = getString(R.string.balance_offline)
uiList.forEach { it.fadeOut() }
}
}.exhaustive
- progressBar.fadeOut()
+ ui.progressBar.fadeOut()
}
private fun onAmountButtonPressed(amount: Int) {
- amountView.editText!!.setText(amount.toString())
- amountView.error = null
+ ui.amountView.editText!!.setText(amount.toString())
+ ui.amountView.error = null
}
private fun getAmountFromView(): Amount {
- val str = amountView.editText!!.text.toString()
+ val str = ui.amountView.editText!!.text.toString()
val currency = configManager.currency.value!!
if (str.isBlank()) return Amount.zero(currency)
return Amount.fromString(currency, str)
@@ -156,11 +159,11 @@ class BalanceFragment : Fragment() {
private fun onAmountConfirmed(amount: Amount) {
if (amount.isZero()) {
- amountView.error = getString(R.string.withdraw_error_zero)
+ ui.amountView.error = getString(R.string.withdraw_error_zero)
} else if (!withdrawManager.hasSufficientBalance(amount)) {
- amountView.error =
getString(R.string.withdraw_error_insufficient_balance)
+ ui.amountView.error =
getString(R.string.withdraw_error_insufficient_balance)
} else {
- amountView.error = null
+ ui.amountView.error = null
withdrawManager.withdraw(amount)
actionBalanceFragmentToTransactionFragment().let {
findNavController().navigate(it)
@@ -177,13 +180,13 @@ class BalanceFragment : Fragment() {
is WithdrawStatus.Aborted ->
getString(R.string.transaction_last_aborted)
else -> getString(R.string.transaction_last_error)
}
- lastTransactionView.text = text
+ ui.lastTransactionView.text = text
val drawable = if (status == WithdrawStatus.Success)
R.drawable.ic_check_circle
else
R.drawable.ic_error
-
lastTransactionView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable,
0, 0, 0)
- lastTransactionView.visibility = VISIBLE
+
ui.lastTransactionView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable,
0, 0, 0)
+ ui.lastTransactionView.visibility = VISIBLE
}
}
diff --git a/cashier/src/main/java/net/taler/cashier/MainActivity.kt
b/cashier/src/main/java/net/taler/cashier/MainActivity.kt
index ae31be5..2f4c4ec 100644
--- a/cashier/src/main/java/net/taler/cashier/MainActivity.kt
+++ b/cashier/src/main/java/net/taler/cashier/MainActivity.kt
@@ -25,18 +25,21 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
-import kotlinx.android.synthetic.main.activity_main.*
+import net.taler.cashier.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
private val configManager by lazy { viewModel.configManager}
+
+ private lateinit var ui: ActivityMainBinding
private lateinit var nav: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- setSupportActionBar(toolbar)
+ ui = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(ui.root)
+ setSupportActionBar(ui.toolbar)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as
NavHostFragment
nav = navHostFragment.navController
diff --git a/cashier/src/main/java/net/taler/cashier/config/Config.kt
b/cashier/src/main/java/net/taler/cashier/config/Config.kt
index b50cf92..c898f95 100644
--- a/cashier/src/main/java/net/taler/cashier/config/Config.kt
+++ b/cashier/src/main/java/net/taler/cashier/config/Config.kt
@@ -17,7 +17,6 @@
package net.taler.cashier.config
import kotlinx.serialization.Serializable
-import net.taler.lib.common.Version
import okhttp3.Credentials
data class Config(
diff --git a/cashier/src/main/java/net/taler/cashier/config/ConfigFragment.kt
b/cashier/src/main/java/net/taler/cashier/config/ConfigFragment.kt
index a7aaf2f..6498590 100644
--- a/cashier/src/main/java/net/taler/cashier/config/ConfigFragment.kt
+++ b/cashier/src/main/java/net/taler/cashier/config/ConfigFragment.kt
@@ -33,9 +33,9 @@ import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG
import com.google.android.material.snackbar.Snackbar
-import kotlinx.android.synthetic.main.fragment_config.*
import net.taler.cashier.MainViewModel
import net.taler.cashier.R
+import net.taler.cashier.databinding.FragmentConfigBinding
import net.taler.common.exhaustive
private const val URL_BANK_TEST = "https://bank.test.taler.net"
@@ -46,38 +46,41 @@ class ConfigFragment : Fragment() {
private val viewModel: MainViewModel by activityViewModels()
private val configManager by lazy { viewModel.configManager}
+ private lateinit var ui: FragmentConfigBinding
+
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_config, container, false)
+ ui = FragmentConfigBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
if (savedInstanceState == null) {
if (configManager.config.bankUrl.isBlank()) {
- urlView.editText!!.setText(URL_BANK_TEST)
+ ui.urlView.editText!!.setText(URL_BANK_TEST)
} else {
- urlView.editText!!.setText(configManager.config.bankUrl)
+ ui.urlView.editText!!.setText(configManager.config.bankUrl)
}
- usernameView.editText!!.setText(configManager.config.username)
- passwordView.editText!!.setText(configManager.config.password)
+ ui.usernameView.editText!!.setText(configManager.config.username)
+ ui.passwordView.editText!!.setText(configManager.config.password)
} else {
-
urlView.editText!!.setText(savedInstanceState.getCharSequence("urlView"))
-
usernameView.editText!!.setText(savedInstanceState.getCharSequence("usernameView"))
-
passwordView.editText!!.setText(savedInstanceState.getCharSequence("passwordView"))
+
ui.urlView.editText!!.setText(savedInstanceState.getCharSequence("urlView"))
+
ui.usernameView.editText!!.setText(savedInstanceState.getCharSequence("usernameView"))
+
ui.passwordView.editText!!.setText(savedInstanceState.getCharSequence("passwordView"))
}
- saveButton.setOnClickListener {
+ ui.saveButton.setOnClickListener {
val config = Config(
- bankUrl = urlView.editText!!.text.toString(),
- username = usernameView.editText!!.text.toString(),
- password = passwordView.editText!!.text.toString()
+ bankUrl = ui.urlView.editText!!.text.toString(),
+ username = ui.usernameView.editText!!.text.toString(),
+ password = ui.passwordView.editText!!.text.toString()
)
if (checkConfig(config)) {
// show progress
- saveButton.visibility = INVISIBLE
- progressBar.visibility = VISIBLE
+ ui.saveButton.visibility = INVISIBLE
+ ui.progressBar.visibility = VISIBLE
// kick off check and observe result
configManager.checkAndSaveConfig(config)
configManager.configResult.observe(viewLifecycleOwner,
onConfigResult)
@@ -87,43 +90,43 @@ class ConfigFragment : Fragment() {
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}
}
- demoView.text = HtmlCompat.fromHtml(
+ ui.demoView.text = HtmlCompat.fromHtml(
getString(R.string.config_demo_hint, URL_BANK_TEST_REGISTER),
FROM_HTML_MODE_LEGACY
)
- demoView.movementMethod = LinkMovementMethod.getInstance()
+ ui.demoView.movementMethod = LinkMovementMethod.getInstance()
}
override fun onStart() {
super.onStart()
// focus on password if it is the only missing value (like after
locking)
- if (urlView.editText!!.text.isNotBlank()
- && usernameView.editText!!.text.isNotBlank()
- && passwordView.editText!!.text.isBlank()
+ if (ui.urlView.editText!!.text.isNotBlank()
+ && ui.usernameView.editText!!.text.isNotBlank()
+ && ui.passwordView.editText!!.text.isBlank()
) {
- passwordView.editText!!.requestFocus()
+ ui.passwordView.editText!!.requestFocus()
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
// for some reason automatic restore isn't working at the moment!?
- outState.putCharSequence("urlView", urlView.editText?.text)
- outState.putCharSequence("usernameView", usernameView.editText?.text)
- outState.putCharSequence("passwordView", passwordView.editText?.text)
+ outState.putCharSequence("urlView", ui.urlView.editText?.text)
+ outState.putCharSequence("usernameView",
ui.usernameView.editText?.text)
+ outState.putCharSequence("passwordView",
ui.passwordView.editText?.text)
}
private fun checkConfig(config: Config): Boolean {
if (!config.bankUrl.startsWith("https://")) {
- urlView.error = getString(R.string.config_bank_url_error)
- urlView.requestFocus()
+ ui.urlView.error = getString(R.string.config_bank_url_error)
+ ui.urlView.requestFocus()
return false
}
if (config.username.isBlank()) {
- usernameView.error = getString(R.string.config_username_error)
- usernameView.requestFocus()
+ ui.usernameView.error = getString(R.string.config_username_error)
+ ui.usernameView.requestFocus()
return false
}
- urlView.isErrorEnabled = false
+ ui.urlView.isErrorEnabled = false
return true
}
@@ -146,8 +149,8 @@ class ConfigFragment : Fragment() {
}
}
}.exhaustive
- saveButton.visibility = VISIBLE
- progressBar.visibility = INVISIBLE
+ ui.saveButton.visibility = VISIBLE
+ ui.progressBar.visibility = INVISIBLE
configManager.configResult.removeObservers(viewLifecycleOwner)
}
diff --git a/cashier/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt
b/cashier/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt
index ea33b0d..4f98847 100644
--- a/cashier/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt
+++ b/cashier/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt
@@ -24,33 +24,36 @@ 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_error.*
import net.taler.cashier.MainViewModel
import net.taler.cashier.R
+import net.taler.cashier.databinding.FragmentErrorBinding
class ErrorFragment : Fragment() {
private val viewModel: MainViewModel by activityViewModels()
private val withdrawManager by lazy { viewModel.withdrawManager }
+ private lateinit var ui: FragmentErrorBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_error, container, false)
+ ui = FragmentErrorBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
withdrawManager.withdrawStatus.observe(viewLifecycleOwner, Observer {
status ->
if (status == null) return@Observer
if (status is WithdrawStatus.Aborted) {
- textView.setText(R.string.transaction_aborted)
+ ui.textView.setText(R.string.transaction_aborted)
} else if (status is WithdrawStatus.Error) {
- textView.text = status.msg
+ ui.textView.text = status.msg
}
withdrawManager.completeTransaction()
})
- backButton.setOnClickListener {
+ ui.backButton.setOnClickListener {
findNavController().popBackStack()
}
}
diff --git
a/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt
b/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt
index 0726a77..ffb1539 100644
--- a/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt
+++ b/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt
@@ -25,11 +25,10 @@ import android.view.ViewGroup
import androidx.core.content.ContextCompat.getColor
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_transaction.*
import net.taler.cashier.MainViewModel
import net.taler.cashier.R
+import net.taler.cashier.databinding.FragmentTransactionBinding
import
net.taler.cashier.withdraw.TransactionFragmentDirections.Companion.actionTransactionFragmentToBalanceFragment
import
net.taler.cashier.withdraw.TransactionFragmentDirections.Companion.actionTransactionFragmentToErrorFragment
import net.taler.cashier.withdraw.WithdrawResult.Error
@@ -46,30 +45,33 @@ class TransactionFragment : Fragment() {
private val withdrawManager by lazy { viewModel.withdrawManager }
private val nfcManager = NfcManager()
+ private lateinit var ui: FragmentTransactionBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_transaction, container,
false)
+ ui = FragmentTransactionBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- withdrawManager.withdrawAmount.observe(viewLifecycleOwner, Observer {
amount ->
- amountView.text = amount?.toString()
+ withdrawManager.withdrawAmount.observe(viewLifecycleOwner, { amount ->
+ ui.amountView.text = amount?.toString()
})
- withdrawManager.withdrawResult.observe(viewLifecycleOwner, Observer {
result ->
+ withdrawManager.withdrawResult.observe(viewLifecycleOwner, { result ->
onWithdrawResultReceived(result)
})
- withdrawManager.withdrawStatus.observe(viewLifecycleOwner, Observer {
status ->
+ withdrawManager.withdrawStatus.observe(viewLifecycleOwner, { status ->
onWithdrawStatusChanged(status)
})
// change intro text depending on whether NFC is available or not
val hasNfc = NfcManager.hasNfc(requireContext())
val intro = if (hasNfc) R.string.transaction_intro_nfc else
R.string.transaction_intro
- introView.setText(intro)
+ ui.introView.setText(intro)
- cancelButton.setOnClickListener {
+ ui.cancelButton.setOnClickListener {
findNavController().popBackStack()
}
}
@@ -95,9 +97,9 @@ class TransactionFragment : Fragment() {
private fun onWithdrawResultReceived(result: WithdrawResult?) {
if (result != null) {
- progressBar.animate()
+ ui.progressBar.animate()
.alpha(0f)
- .withEndAction { progressBar?.visibility = INVISIBLE }
+ .withEndAction { ui.progressBar.visibility = INVISIBLE }
.setDuration(750)
.start()
}
@@ -113,12 +115,12 @@ class TransactionFragment : Fragment() {
nfcManager
)
// show QR code
- qrCodeView.alpha = 0f
- qrCodeView.animate()
+ ui.qrCodeView.alpha = 0f
+ ui.qrCodeView.animate()
.alpha(1f)
.withStartAction {
- qrCodeView.visibility = VISIBLE
- qrCodeView.setImageBitmap(result.qrCode)
+ ui.qrCodeView.visibility = VISIBLE
+ ui.qrCodeView.setImageBitmap(result.qrCode)
}
.setDuration(750)
.start()
@@ -129,30 +131,30 @@ class TransactionFragment : Fragment() {
private fun setErrorMsg(str: String) {
val c = getColor(requireContext(), R.color.design_default_color_error)
- introView.setTextColor(c)
- introView.text = str
+ ui.introView.setTextColor(c)
+ ui.introView.text = str
}
private fun onWithdrawStatusChanged(status: WithdrawStatus?): Any = when
(status) {
is WithdrawStatus.SelectionDone -> {
- qrCodeView.fadeOut {
- qrCodeView?.setImageResource(R.drawable.ic_arrow)
- qrCodeView?.fadeIn()
+ ui.qrCodeView.fadeOut {
+ ui.qrCodeView.setImageResource(R.drawable.ic_arrow)
+ ui.qrCodeView.fadeIn()
}
- introView.fadeOut {
- introView?.text = getString(R.string.transaction_intro_scanned)
- introView?.fadeIn {
- confirmButton?.isEnabled = true
- confirmButton?.setOnClickListener {
+ ui.introView.fadeOut {
+ ui.introView.text =
getString(R.string.transaction_intro_scanned)
+ ui.introView.fadeIn {
+ ui.confirmButton.isEnabled = true
+ ui.confirmButton.setOnClickListener {
withdrawManager.confirm(status.withdrawalId)
}
}
}
}
is WithdrawStatus.Confirming -> {
- confirmButton.isEnabled = false
- qrCodeView.fadeOut()
- progressBar.fadeIn()
+ ui.confirmButton.isEnabled = false
+ ui.qrCodeView.fadeOut()
+ ui.progressBar.fadeIn()
}
is WithdrawStatus.Success -> {
withdrawManager.completeTransaction()
diff --git a/merchant-terminal/build.gradle b/merchant-terminal/build.gradle
index f7bbc1c..df8cee5 100644
--- a/merchant-terminal/build.gradle
+++ b/merchant-terminal/build.gradle
@@ -1,7 +1,6 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
- id 'kotlin-android-extensions'
id 'kotlinx-serialization'
id 'androidx.navigation.safeargs.kotlin'
}
@@ -13,7 +12,7 @@ android {
defaultConfig {
applicationId "net.taler.merchantpos"
- minSdkVersion 26
+ minSdkVersion 24
targetSdkVersion 29
versionCode 1
versionName "1.0"
@@ -40,6 +39,10 @@ android {
jvmTarget = "1.8"
}
+ buildFeatures {
+ viewBinding = true
+ }
+
testOptions {
unitTests {
includeAndroidResources = true
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt
index 533c540..47da74e 100644
--- a/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt
+++ b/merchant-terminal/src/main/java/net/taler/merchantpos/MainActivity.kt
@@ -28,21 +28,20 @@ import android.widget.Toast.LENGTH_SHORT
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat.START
-import androidx.lifecycle.Observer
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupWithNavController
import
com.google.android.material.navigation.NavigationView.OnNavigationItemSelectedListener
-import kotlinx.android.synthetic.main.activity_main.*
-import kotlinx.android.synthetic.main.app_bar_main.*
import net.taler.common.NfcManager
+import net.taler.merchantpos.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener {
private val model: MainViewModel by viewModels()
private val nfcManager = NfcManager()
+ private lateinit var ui: ActivityMainBinding
private lateinit var nav: NavController
private var reallyExit = false
@@ -53,9 +52,10 @@ class MainActivity : AppCompatActivity(),
OnNavigationItemSelectedListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
+ ui = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(ui.root)
- model.paymentManager.payment.observe(this, Observer { payment ->
+ model.paymentManager.payment.observe(this, { payment ->
payment?.talerPayUri?.let {
nfcManager.setTagString(it)
}
@@ -65,12 +65,12 @@ class MainActivity : AppCompatActivity(),
OnNavigationItemSelectedListener {
supportFragmentManager.findFragmentById(R.id.navHostFragment) as
NavHostFragment
nav = navHostFragment.navController
- nav_view.setupWithNavController(nav)
- nav_view.setNavigationItemSelectedListener(this)
+ ui.navView.setupWithNavController(nav)
+ ui.navView.setNavigationItemSelectedListener(this)
- setSupportActionBar(toolbar)
- val appBarConfiguration = AppBarConfiguration(nav.graph, drawer_layout)
- toolbar.setupWithNavController(nav, appBarConfiguration)
+ setSupportActionBar(ui.main.toolbar)
+ val appBarConfiguration = AppBarConfiguration(nav.graph,
ui.drawerLayout)
+ ui.main.toolbar.setupWithNavController(nav, appBarConfiguration)
}
override fun onStart() {
@@ -99,14 +99,14 @@ class MainActivity : AppCompatActivity(),
OnNavigationItemSelectedListener {
R.id.nav_history ->
nav.navigate(R.id.action_global_merchantHistory)
R.id.nav_settings ->
nav.navigate(R.id.action_global_merchantSettings)
}
- drawer_layout.closeDrawer(START)
+ ui.drawerLayout.closeDrawer(START)
return true
}
override fun onBackPressed() {
val currentDestination = nav.currentDestination?.id
- if (drawer_layout.isDrawerOpen(START)) {
- drawer_layout.closeDrawer(START)
+ if (ui.drawerLayout.isDrawerOpen(START)) {
+ ui.drawerLayout.closeDrawer(START)
} else if (currentDestination == R.id.nav_settings &&
!model.configManager.config.isValid()) {
// we are in the configuration screen and need a config to continue
val intent = Intent(ACTION_MAIN).apply {
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt
index 8231052..87004d8 100644
---
a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt
+++
b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt
@@ -27,20 +27,23 @@ import
com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_SHORT
import com.google.android.material.snackbar.Snackbar
import net.taler.common.navigate
import net.taler.merchantpos.MainViewModel
-import net.taler.merchantpos.R
import
net.taler.merchantpos.config.ConfigFetcherFragmentDirections.Companion.actionConfigFetcherToMerchantSettings
import
net.taler.merchantpos.config.ConfigFetcherFragmentDirections.Companion.actionConfigFetcherToOrder
+import net.taler.merchantpos.databinding.FragmentConfigFetcherBinding
class ConfigFetcherFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val configManager by lazy { model.configManager }
+ private lateinit var ui: FragmentConfigFetcherBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_config_fetcher, container,
false)
+ ui = FragmentConfigFetcherBinding.inflate(inflater)
+ return ui.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt
index daddbff..c31eb61 100644
---
a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt
+++
b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigFragment.kt
@@ -30,11 +30,11 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG
import com.google.android.material.snackbar.Snackbar
-import kotlinx.android.synthetic.main.fragment_merchant_config.*
import net.taler.common.navigate
import net.taler.merchantpos.MainViewModel
import net.taler.merchantpos.R
import
net.taler.merchantpos.config.ConfigFragmentDirections.Companion.actionSettingsToOrder
+import net.taler.merchantpos.databinding.FragmentMerchantConfigBinding
import net.taler.merchantpos.topSnackbar
/**
@@ -45,86 +45,89 @@ class ConfigFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val configManager by lazy { model.configManager }
+ private lateinit var ui: FragmentMerchantConfigBinding
+
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_merchant_config, container,
false)
+ ui = FragmentMerchantConfigBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- configUrlView.editText!!.setOnFocusChangeListener { _, hasFocus ->
+ ui.configUrlView.editText!!.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) checkForUrlCredentials()
}
- okButton.setOnClickListener {
+ ui.okButton.setOnClickListener {
checkForUrlCredentials()
- val inputUrl = configUrlView.editText!!.text
+ val inputUrl = ui.configUrlView.editText!!.text
val url = if (inputUrl.startsWith("http")) {
inputUrl.toString()
} else {
- "https://$inputUrl".also {
configUrlView.editText!!.setText(it) }
+ "https://$inputUrl".also {
ui.configUrlView.editText!!.setText(it) }
}
- progressBar.visibility = VISIBLE
- okButton.visibility = INVISIBLE
+ ui.progressBar.visibility = VISIBLE
+ ui.okButton.visibility = INVISIBLE
val config = Config(
configUrl = url,
- username = usernameView.editText!!.text.toString(),
- password = passwordView.editText!!.text.toString()
+ username = ui.usernameView.editText!!.text.toString(),
+ password = ui.passwordView.editText!!.text.toString()
)
- configManager.fetchConfig(config, true,
savePasswordCheckBox.isChecked)
+ configManager.fetchConfig(config, true,
ui.savePasswordCheckBox.isChecked)
configManager.configUpdateResult.observe(viewLifecycleOwner,
Observer { result ->
if (onConfigUpdate(result)) {
configManager.configUpdateResult.removeObservers(viewLifecycleOwner)
}
})
}
- forgetPasswordButton.setOnClickListener {
+ ui.forgetPasswordButton.setOnClickListener {
configManager.forgetPassword()
- passwordView.editText!!.text = null
- forgetPasswordButton.visibility = GONE
+ ui.passwordView.editText!!.text = null
+ ui.forgetPasswordButton.visibility = GONE
}
- configDocsView.movementMethod = LinkMovementMethod.getInstance()
+ ui.configDocsView.movementMethod = LinkMovementMethod.getInstance()
updateView(savedInstanceState == null)
}
override fun onStart() {
super.onStart()
// focus password if this is the only empty field
- if (passwordView.editText!!.text.isBlank()
- && !configUrlView.editText!!.text.isBlank()
- && !usernameView.editText!!.text.isBlank()
+ if (ui.passwordView.editText!!.text.isBlank()
+ && !ui.configUrlView.editText!!.text.isBlank()
+ && !ui.usernameView.editText!!.text.isBlank()
) {
- passwordView.requestFocus()
+ ui.passwordView.requestFocus()
}
}
private fun updateView(isInitialization: Boolean = false) {
val config = configManager.config
- configUrlView.editText!!.setText(
+ ui.configUrlView.editText!!.setText(
if (isInitialization && config.configUrl.isBlank()) CONFIG_URL_DEMO
else config.configUrl
)
- usernameView.editText!!.setText(
+ ui.usernameView.editText!!.setText(
if (isInitialization && config.username.isBlank())
CONFIG_USERNAME_DEMO
else config.username
)
- passwordView.editText!!.setText(
+ ui.passwordView.editText!!.setText(
if (isInitialization && config.password.isBlank())
CONFIG_PASSWORD_DEMO
else config.password
)
- forgetPasswordButton.visibility = if (config.hasPassword()) VISIBLE
else GONE
+ ui.forgetPasswordButton.visibility = if (config.hasPassword()) VISIBLE
else GONE
}
private fun checkForUrlCredentials() {
- val text = configUrlView.editText!!.text.toString()
+ val text = ui.configUrlView.editText!!.text.toString()
Uri.parse(text)?.userInfo?.let { userInfo ->
if (userInfo.contains(':')) {
val (user, pass) = userInfo.split(':')
val strippedUrl = text.replace("${userInfo}@", "")
- configUrlView.editText!!.setText(strippedUrl)
- usernameView.editText!!.setText(user)
- passwordView.editText!!.setText(pass)
+ ui.configUrlView.editText!!.setText(strippedUrl)
+ ui.usernameView.editText!!.setText(user)
+ ui.passwordView.editText!!.setText(pass)
}
}
}
@@ -157,8 +160,8 @@ class ConfigFragment : Fragment() {
}
private fun onResultReceived() {
- progressBar.visibility = INVISIBLE
- okButton.visibility = VISIBLE
+ ui.progressBar.visibility = INVISIBLE
+ ui.okButton.visibility = VISIBLE
}
}
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/config/PosConfig.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/config/PosConfig.kt
index cc8caf6..7def7cc 100644
--- a/merchant-terminal/src/main/java/net/taler/merchantpos/config/PosConfig.kt
+++ b/merchant-terminal/src/main/java/net/taler/merchantpos/config/PosConfig.kt
@@ -16,6 +16,7 @@
package net.taler.merchantpos.config
+import android.os.Build.VERSION.SDK_INT
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import net.taler.common.ContractProduct
@@ -49,7 +50,8 @@ data class Category(
val nameI18n: Map<String, String>? = null
) {
var selected: Boolean = false
- val localizedName: String get() = TalerUtils.getLocalizedString(nameI18n,
name)
+ val localizedName: String
+ get() = if (SDK_INT >= 26) TalerUtils.getLocalizedString(nameI18n,
name) else name
}
@Serializable
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryFragment.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryFragment.kt
index 8cc435a..3ef48e1 100644
---
a/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryFragment.kt
+++
b/merchant-terminal/src/main/java/net/taler/merchantpos/history/HistoryFragment.kt
@@ -23,18 +23,16 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.DividerItemDecoration.VERTICAL
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG
import com.google.android.material.snackbar.Snackbar
-import kotlinx.android.synthetic.main.fragment_merchant_history.*
import net.taler.common.exhaustive
import net.taler.common.navigate
import net.taler.merchantlib.OrderHistoryEntry
import net.taler.merchantpos.MainViewModel
-import net.taler.merchantpos.R
+import net.taler.merchantpos.databinding.FragmentMerchantHistoryBinding
import
net.taler.merchantpos.history.HistoryFragmentDirections.Companion.actionGlobalMerchantSettings
import
net.taler.merchantpos.history.HistoryFragmentDirections.Companion.actionNavHistoryToRefundFragment
@@ -55,31 +53,33 @@ class HistoryFragment : Fragment(), RefundClickListener {
private val historyManager by lazy { model.historyManager }
private val refundManager by lazy { model.refundManager }
+ private lateinit var ui: FragmentMerchantHistoryBinding
private val historyListAdapter = HistoryItemAdapter(this)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_merchant_history, container,
false)
+ ui = FragmentMerchantHistoryBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- list_history.apply {
+ ui.listHistory.apply {
layoutManager = LinearLayoutManager(requireContext())
addItemDecoration(DividerItemDecoration(context, VERTICAL))
adapter = historyListAdapter
}
- swipeRefresh.setOnRefreshListener {
+ ui.swipeRefresh.setOnRefreshListener {
Log.v(TAG, "refreshing!")
historyManager.fetchHistory()
}
- historyManager.isLoading.observe(viewLifecycleOwner, Observer {
loading ->
+ historyManager.isLoading.observe(viewLifecycleOwner, { loading ->
Log.v(TAG, "setting refreshing to $loading")
- swipeRefresh.isRefreshing = loading
+ ui.swipeRefresh.isRefreshing = loading
})
- historyManager.items.observe(viewLifecycleOwner, Observer { result ->
+ historyManager.items.observe(viewLifecycleOwner, { result ->
when (result) {
is HistoryResult.Error -> onError(result.msg)
is HistoryResult.Success ->
historyListAdapter.setData(result.items)
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/order/CategoriesFragment.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/order/CategoriesFragment.kt
index 4f8e5af..69e74ce 100644
---
a/merchant-terminal/src/main/java/net/taler/merchantpos/order/CategoriesFragment.kt
+++
b/merchant-terminal/src/main/java/net/taler/merchantpos/order/CategoriesFragment.kt
@@ -23,12 +23,10 @@ import android.view.View.INVISIBLE
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
-import kotlinx.android.synthetic.main.fragment_categories.*
import net.taler.merchantpos.MainViewModel
-import net.taler.merchantpos.R
import net.taler.merchantpos.config.Category
+import net.taler.merchantpos.databinding.FragmentCategoriesBinding
interface CategorySelectionListener {
fun onCategorySelected(category: Category)
@@ -38,6 +36,8 @@ class CategoriesFragment : Fragment(),
CategorySelectionListener {
private val viewModel: MainViewModel by activityViewModels()
private val orderManager by lazy { viewModel.orderManager }
+
+ private lateinit var ui: FragmentCategoriesBinding
private val adapter = CategoryAdapter(this)
override fun onCreateView(
@@ -45,18 +45,19 @@ class CategoriesFragment : Fragment(),
CategorySelectionListener {
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_categories, container, false)
+ ui = FragmentCategoriesBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- categoriesList.apply {
+ ui.categoriesList.apply {
adapter = this@CategoriesFragment.adapter
layoutManager = LinearLayoutManager(requireContext())
}
- orderManager.categories.observe(viewLifecycleOwner, Observer {
categories ->
+ orderManager.categories.observe(viewLifecycleOwner, { categories ->
adapter.setItems(categories)
- progressBar.visibility = INVISIBLE
+ ui.progressBar.visibility = INVISIBLE
})
}
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
index 7291a23..1335b65 100644
---
a/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
+++
b/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
@@ -22,12 +22,11 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.transition.TransitionManager.beginDelayedTransition
-import kotlinx.android.synthetic.main.fragment_order.*
import net.taler.common.navigate
import net.taler.merchantpos.MainViewModel
import net.taler.merchantpos.R
+import net.taler.merchantpos.databinding.FragmentOrderBinding
import
net.taler.merchantpos.order.OrderFragmentDirections.Companion.actionGlobalConfigFetcher
import
net.taler.merchantpos.order.OrderFragmentDirections.Companion.actionOrderToMerchantSettings
import
net.taler.merchantpos.order.OrderFragmentDirections.Companion.actionOrderToProcessPayment
@@ -40,17 +39,20 @@ class OrderFragment : Fragment() {
private val orderManager by lazy { viewModel.orderManager }
private val paymentManager by lazy { viewModel.paymentManager }
+ private lateinit var ui: FragmentOrderBinding
+
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_order, container, false)
+ ui = FragmentOrderBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
- orderManager.currentOrderId.observe(viewLifecycleOwner, Observer {
orderId ->
+ orderManager.currentOrderId.observe(viewLifecycleOwner, { orderId ->
val liveOrder = orderManager.getOrder(orderId)
onOrderSwitched(orderId, liveOrder)
// add a new OrderStateFragment for each order
@@ -72,39 +74,39 @@ class OrderFragment : Fragment() {
private fun onOrderSwitched(orderId: Int, liveOrder: LiveOrder) {
// order title
- liveOrder.order.observe(viewLifecycleOwner, Observer { order ->
+ liveOrder.order.observe(viewLifecycleOwner, { order ->
activity?.title = getString(R.string.order_label_title,
order.title)
})
// restart button
- restartButton.setOnClickListener { liveOrder.restartOrUndo() }
- liveOrder.restartState.observe(viewLifecycleOwner, Observer { state ->
+ ui.restartButton.setOnClickListener { liveOrder.restartOrUndo() }
+ liveOrder.restartState.observe(viewLifecycleOwner, { state ->
beginDelayedTransition(view as ViewGroup)
if (state == UNDO) {
- restartButton.setText(R.string.order_undo)
- restartButton.isEnabled = true
- completeButton.isEnabled = false
+ ui.restartButton.setText(R.string.order_undo)
+ ui.restartButton.isEnabled = true
+ ui.completeButton.isEnabled = false
} else {
- restartButton.setText(R.string.order_restart)
- restartButton.isEnabled = state == ENABLED
- completeButton.isEnabled = state == ENABLED
+ ui.restartButton.setText(R.string.order_restart)
+ ui.restartButton.isEnabled = state == ENABLED
+ ui.completeButton.isEnabled = state == ENABLED
}
})
// -1 and +1 buttons
- liveOrder.modifyOrderAllowed.observe(viewLifecycleOwner, Observer {
allowed ->
- minusButton.isEnabled = allowed
- plusButton.isEnabled = allowed
+ liveOrder.modifyOrderAllowed.observe(viewLifecycleOwner, { allowed ->
+ ui.minusButton.isEnabled = allowed
+ ui.plusButton.isEnabled = allowed
})
- minusButton.setOnClickListener { liveOrder.decreaseSelectedOrderLine()
}
- plusButton.setOnClickListener { liveOrder.increaseSelectedOrderLine() }
+ ui.minusButton.setOnClickListener {
liveOrder.decreaseSelectedOrderLine() }
+ ui.plusButton.setOnClickListener {
liveOrder.increaseSelectedOrderLine() }
// previous and next button
- prevButton.isEnabled = orderManager.hasPreviousOrder(orderId)
- orderManager.hasNextOrder(orderId).observe(viewLifecycleOwner,
Observer { hasNextOrder ->
- nextButton.isEnabled = hasNextOrder
+ ui.prevButton.isEnabled = orderManager.hasPreviousOrder(orderId)
+ orderManager.hasNextOrder(orderId).observe(viewLifecycleOwner, {
hasNextOrder ->
+ ui.nextButton.isEnabled = hasNextOrder
})
- prevButton.setOnClickListener { orderManager.previousOrder() }
- nextButton.setOnClickListener { orderManager.nextOrder() }
+ ui.prevButton.setOnClickListener { orderManager.previousOrder() }
+ ui.nextButton.setOnClickListener { orderManager.nextOrder() }
// complete button
- completeButton.setOnClickListener {
+ ui.completeButton.setOnClickListener {
val order = liveOrder.order.value ?: return@setOnClickListener
paymentManager.createPayment(order)
navigate(actionOrderToProcessPayment())
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt
index b60f3a5..93c4f97 100644
---
a/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt
+++
b/merchant-terminal/src/main/java/net/taler/merchantpos/order/OrderStateFragment.kt
@@ -22,16 +22,15 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.recyclerview.selection.SelectionPredicates
import androidx.recyclerview.selection.SelectionTracker
import androidx.recyclerview.selection.StorageStrategy
import androidx.recyclerview.widget.LinearLayoutManager
-import kotlinx.android.synthetic.main.fragment_order_state.*
import net.taler.common.fadeIn
import net.taler.common.fadeOut
import net.taler.merchantpos.MainViewModel
import net.taler.merchantpos.R
+import net.taler.merchantpos.databinding.FragmentOrderStateBinding
import net.taler.merchantpos.order.OrderAdapter.OrderLineLookup
class OrderStateFragment : Fragment() {
@@ -39,6 +38,8 @@ class OrderStateFragment : Fragment() {
private val viewModel: MainViewModel by activityViewModels()
private val orderManager by lazy { viewModel.orderManager }
private val liveOrder by lazy {
orderManager.getOrder(orderManager.currentOrderId.value!!) }
+
+ private lateinit var ui: FragmentOrderStateBinding
private val adapter = OrderAdapter()
private var tracker: SelectionTracker<String>? = null
@@ -47,18 +48,19 @@ class OrderStateFragment : Fragment() {
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_order_state, container,
false)
+ ui = FragmentOrderStateBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- orderList.apply {
+ ui.orderList.apply {
adapter = this@OrderStateFragment.adapter
layoutManager = LinearLayoutManager(requireContext())
}
- val detailsLookup = OrderLineLookup(orderList)
+ val detailsLookup = OrderLineLookup(ui.orderList)
val tracker = SelectionTracker.Builder(
"order-selection-id",
- orderList,
+ ui.orderList,
adapter.keyProvider,
detailsLookup,
StorageStrategy.createStringStorage()
@@ -80,16 +82,16 @@ class OrderStateFragment : Fragment() {
liveOrder.selectOrderLine(item)
}
})
- liveOrder.order.observe(viewLifecycleOwner, Observer { order ->
+ liveOrder.order.observe(viewLifecycleOwner, { order ->
onOrderChanged(order, tracker)
})
- liveOrder.orderTotal.observe(viewLifecycleOwner, Observer { orderTotal
->
+ liveOrder.orderTotal.observe(viewLifecycleOwner, { orderTotal ->
if (orderTotal.isZero()) {
- totalView.fadeOut()
- totalView.text = null
+ ui.totalView.fadeOut()
+ ui.totalView.text = null
} else {
- totalView.text = getString(R.string.order_total, orderTotal)
- totalView.fadeIn()
+ ui.totalView.text = getString(R.string.order_total, orderTotal)
+ ui.totalView.fadeIn()
}
})
}
@@ -104,9 +106,8 @@ class OrderStateFragment : Fragment() {
liveOrder.lastAddedProduct?.let {
val position = adapter.findPosition(it)
if (position >= 0) {
- // orderList can be null m(
- orderList?.scrollToPosition(position)
- orderList?.post { this.tracker?.select(it.id) }
+ ui.orderList.scrollToPosition(position)
+ ui.orderList.post { this.tracker?.select(it.id) }
}
}
// workaround for bug: SelectionObserver doesn't update when
removing selected item
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt
index 00eb509..a3898fd 100644
---
a/merchant-terminal/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt
+++
b/merchant-terminal/src/main/java/net/taler/merchantpos/order/ProductsFragment.kt
@@ -24,14 +24,13 @@ import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView.Adapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
-import kotlinx.android.synthetic.main.fragment_products.*
import net.taler.merchantpos.MainViewModel
import net.taler.merchantpos.R
import net.taler.merchantpos.config.ConfigProduct
+import net.taler.merchantpos.databinding.FragmentProductsBinding
import net.taler.merchantpos.order.ProductAdapter.ProductViewHolder
interface ProductSelectionListener {
@@ -44,27 +43,30 @@ class ProductsFragment : Fragment(),
ProductSelectionListener {
private val orderManager by lazy { viewModel.orderManager }
private val adapter = ProductAdapter(this)
+ private lateinit var ui: FragmentProductsBinding
+
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_products, container, false)
+ ui = FragmentProductsBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- productsList.apply {
+ ui.productsList.apply {
adapter = this@ProductsFragment.adapter
layoutManager = GridLayoutManager(requireContext(), 3)
}
- orderManager.products.observe(viewLifecycleOwner, Observer { products
->
+ orderManager.products.observe(viewLifecycleOwner, { products ->
if (products == null) {
adapter.setItems(emptyList())
} else {
adapter.setItems(products)
}
- progressBar.visibility = INVISIBLE
+ ui.progressBar.visibility = INVISIBLE
})
}
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt
index 10d538d..5b95dea 100644
---
a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt
+++
b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt
@@ -22,21 +22,23 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
-import kotlinx.android.synthetic.main.fragment_payment_success.*
-import net.taler.merchantpos.R
+import net.taler.merchantpos.databinding.FragmentPaymentSuccessBinding
class PaymentSuccessFragment : Fragment() {
+ private lateinit var ui: FragmentPaymentSuccessBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_payment_success, container,
false)
+ ui = FragmentPaymentSuccessBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
- paymentButton.setOnClickListener {
+ ui.paymentButton.setOnClickListener {
findNavController().navigateUp()
}
}
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt
index 27ef366..5c0a894 100644
---
a/merchant-terminal/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt
+++
b/merchant-terminal/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt
@@ -22,10 +22,8 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG
-import kotlinx.android.synthetic.main.fragment_process_payment.*
import net.taler.common.NfcManager.Companion.hasNfc
import net.taler.common.QrCodeManager.makeQrCode
import net.taler.common.fadeIn
@@ -33,6 +31,7 @@ import net.taler.common.fadeOut
import net.taler.common.navigate
import net.taler.merchantpos.MainViewModel
import net.taler.merchantpos.R
+import net.taler.merchantpos.databinding.FragmentProcessPaymentBinding
import
net.taler.merchantpos.payment.ProcessPaymentFragmentDirections.Companion.actionProcessPaymentToPaymentSuccess
import net.taler.merchantpos.topSnackbar
@@ -41,21 +40,24 @@ class ProcessPaymentFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val paymentManager by lazy { model.paymentManager }
+ private lateinit var ui: FragmentProcessPaymentBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_process_payment, container,
false)
+ ui = FragmentProcessPaymentBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val introRes =
if (hasNfc(requireContext())) R.string.payment_intro_nfc else
R.string.payment_intro
- payIntroView.setText(introRes)
- paymentManager.payment.observe(viewLifecycleOwner, Observer { payment
->
+ ui.payIntroView.setText(introRes)
+ paymentManager.payment.observe(viewLifecycleOwner, { payment ->
onPaymentStateChanged(payment)
})
- cancelPaymentButton.setOnClickListener {
+ ui.cancelPaymentButton.setOnClickListener {
onPaymentCancel()
}
}
@@ -76,17 +78,17 @@ class ProcessPaymentFragment : Fragment() {
navigate(actionProcessPaymentToPaymentSuccess())
return
}
- payIntroView.fadeIn()
- amountView.text = payment.order.total.toString()
+ ui.payIntroView.fadeIn()
+ ui.amountView.text = payment.order.total.toString()
payment.orderId?.let {
- orderRefView.text = getString(R.string.payment_order_id, it)
- orderRefView.fadeIn()
+ ui.orderRefView.text = getString(R.string.payment_order_id, it)
+ ui.orderRefView.fadeIn()
}
payment.talerPayUri?.let {
val qrcodeBitmap = makeQrCode(it)
- qrcodeView.setImageBitmap(qrcodeBitmap)
- qrcodeView.fadeIn()
- progressBar.fadeOut()
+ ui.qrcodeView.setImageBitmap(qrcodeBitmap)
+ ui.qrcodeView.fadeIn()
+ ui.progressBar.fadeOut()
}
}
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt
index 752b7aa..91e68e6 100644
---
a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt
+++
b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundFragment.kt
@@ -22,11 +22,9 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG
import com.google.android.material.snackbar.Snackbar
-import kotlinx.android.synthetic.main.fragment_refund.*
import net.taler.common.fadeIn
import net.taler.common.fadeOut
import net.taler.common.navigate
@@ -35,6 +33,7 @@ import net.taler.lib.common.AmountParserException
import net.taler.merchantlib.OrderHistoryEntry
import net.taler.merchantpos.MainViewModel
import net.taler.merchantpos.R
+import net.taler.merchantpos.databinding.FragmentRefundBinding
import
net.taler.merchantpos.refund.RefundFragmentDirections.Companion.actionRefundFragmentToRefundUriFragment
import net.taler.merchantpos.refund.RefundResult.AlreadyRefunded
import net.taler.merchantpos.refund.RefundResult.Error
@@ -46,44 +45,47 @@ class RefundFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val refundManager by lazy { model.refundManager }
+ private lateinit var ui: FragmentRefundBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_refund, container, false)
+ ui = FragmentRefundBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val item = refundManager.toBeRefunded ?: throw IllegalStateException()
- amountInputView.setText(item.amount.amountStr)
- currencyView.text = item.amount.currency
- abortButton.setOnClickListener { findNavController().navigateUp() }
- refundButton.setOnClickListener { onRefundButtonClicked(item) }
+ ui.amountInputView.setText(item.amount.amountStr)
+ ui.currencyView.text = item.amount.currency
+ ui.abortButton.setOnClickListener { findNavController().navigateUp() }
+ ui.refundButton.setOnClickListener { onRefundButtonClicked(item) }
- refundManager.refundResult.observe(viewLifecycleOwner, Observer {
result ->
+ refundManager.refundResult.observe(viewLifecycleOwner, { result ->
onRefundResultChanged(result)
})
}
private fun onRefundButtonClicked(item: OrderHistoryEntry) {
val inputAmount = try {
- Amount.fromString(item.amount.currency,
amountInputView.text.toString())
+ Amount.fromString(item.amount.currency,
ui.amountInputView.text.toString())
} catch (e: AmountParserException) {
- amountView.error = getString(R.string.refund_error_invalid_amount)
+ ui.amountView.error =
getString(R.string.refund_error_invalid_amount)
return
}
if (inputAmount > item.amount) {
- amountView.error = getString(R.string.refund_error_max_amount,
item.amount.amountStr)
+ ui.amountView.error = getString(R.string.refund_error_max_amount,
item.amount.amountStr)
return
}
if (inputAmount.isZero()) {
- amountView.error = getString(R.string.refund_error_zero)
+ ui.amountView.error = getString(R.string.refund_error_zero)
return
}
- amountView.error = null
- refundButton.fadeOut()
- progressBar.fadeIn()
- refundManager.refund(item, inputAmount,
reasonInputView.text.toString())
+ ui.amountView.error = null
+ ui.refundButton.fadeOut()
+ ui.progressBar.fadeIn()
+ refundManager.refund(item, inputAmount,
ui.reasonInputView.text.toString())
}
private fun onRefundResultChanged(result: RefundResult?): Any = when
(result) {
@@ -91,8 +93,8 @@ class RefundFragment : Fragment() {
PastDeadline -> onError(getString(R.string.refund_error_deadline))
AlreadyRefunded ->
onError(getString(R.string.refund_error_already_refunded))
is Success -> {
- progressBar.fadeOut()
- refundButton.fadeIn()
+ ui.progressBar.fadeOut()
+ ui.refundButton.fadeIn()
navigate(actionRefundFragmentToRefundUriFragment())
}
null -> { // no-op
@@ -101,8 +103,8 @@ class RefundFragment : Fragment() {
private fun onError(msg: String) {
Snackbar.make(requireView(), msg, LENGTH_LONG).show()
- progressBar.fadeOut()
- refundButton.fadeIn()
+ ui.progressBar.fadeOut()
+ ui.refundButton.fadeIn()
}
}
diff --git
a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundUriFragment.kt
b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundUriFragment.kt
index b8e8997..5e52404 100644
---
a/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundUriFragment.kt
+++
b/merchant-terminal/src/main/java/net/taler/merchantpos/refund/RefundUriFragment.kt
@@ -23,22 +23,25 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
-import kotlinx.android.synthetic.main.fragment_refund_uri.*
import net.taler.common.NfcManager.Companion.hasNfc
import net.taler.common.QrCodeManager.makeQrCode
import net.taler.merchantpos.MainViewModel
import net.taler.merchantpos.R
+import net.taler.merchantpos.databinding.FragmentRefundUriBinding
class RefundUriFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val refundManager by lazy { model.refundManager }
+ private lateinit var ui: FragmentRefundUriBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_refund_uri, container, false)
+ ui = FragmentRefundUriBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -46,19 +49,19 @@ class RefundUriFragment : Fragment() {
val result = refundManager.refundResult.value
if (result !is RefundResult.Success) throw IllegalStateException()
- refundQrcodeView.setImageBitmap(makeQrCode(result.refundUri))
+ ui.refundQrcodeView.setImageBitmap(makeQrCode(result.refundUri))
val introRes =
if (hasNfc(requireContext())) R.string.refund_intro_nfc else
R.string.refund_intro
- refundIntroView.setText(introRes)
+ ui.refundIntroView.setText(introRes)
- refundAmountView.text = result.amount.toString()
+ ui.refundAmountView.text = result.amount.toString()
- refundRefView.text =
+ ui.refundRefView.text =
getString(R.string.refund_order_ref, result.item.orderId,
result.reason)
- cancelRefundButton.setOnClickListener {
findNavController().navigateUp() }
- completeButton.setOnClickListener { findNavController().navigateUp() }
+ ui.cancelRefundButton.setOnClickListener {
findNavController().navigateUp() }
+ ui.completeButton.setOnClickListener {
findNavController().navigateUp() }
}
override fun onDestroy() {
diff --git a/merchant-terminal/src/main/res/layout/activity_main.xml
b/merchant-terminal/src/main/res/layout/activity_main.xml
index 1285b19..c801563 100644
--- a/merchant-terminal/src/main/res/layout/activity_main.xml
+++ b/merchant-terminal/src/main/res/layout/activity_main.xml
@@ -24,6 +24,7 @@
tools:openDrawer="start">
<include
+ android:id="@+id/main"
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
diff --git
a/taler-kotlin-android/src/main/java/net/taler/common/ContractTerms.kt
b/taler-kotlin-android/src/main/java/net/taler/common/ContractTerms.kt
index d22eaa0..fb30692 100644
--- a/taler-kotlin-android/src/main/java/net/taler/common/ContractTerms.kt
+++ b/taler-kotlin-android/src/main/java/net/taler/common/ContractTerms.kt
@@ -16,7 +16,7 @@
package net.taler.common
-import androidx.annotation.RequiresApi
+import android.os.Build
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import net.taler.common.TalerUtils.getLocalizedString
@@ -48,8 +48,11 @@ abstract class Product {
abstract val location: String?
abstract val image: String?
val localizedDescription: String
- @RequiresApi(26)
- get() = getLocalizedString(descriptionI18n, description)
+ get() = if (Build.VERSION.SDK_INT >= 26) {
+ getLocalizedString(descriptionI18n, description)
+ } else {
+ description
+ }
}
@Serializable
diff --git a/wallet/build.gradle b/wallet/build.gradle
index 30cf291..47de2dd 100644
--- a/wallet/build.gradle
+++ b/wallet/build.gradle
@@ -19,12 +19,11 @@ import com.android.build.gradle.tasks.MergeResources
plugins {
id "com.android.application"
id "kotlin-android"
- id "kotlin-android-extensions"
id "kotlinx-serialization"
id "de.undercouch.download"
}
-def walletCoreVersion = "v0.7.1-dev.23"
+def walletCoreVersion = "v0.7.1-dev.25"
static def versionCodeEpoch() {
return (new Date().getTime() / 1000).toInteger()
@@ -48,7 +47,7 @@ android {
minSdkVersion 24
targetSdkVersion 29
versionCode 6
- versionName "0.7.1.dev.23"
+ versionName "0.7.1.dev.25"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
buildConfigField "String", "WALLET_CORE_VERSION",
"\"$walletCoreVersion\""
}
@@ -88,6 +87,10 @@ android {
jvmTarget = "1.8"
}
+ buildFeatures {
+ viewBinding = true
+ }
+
packagingOptions {
exclude("META-INF/*.kotlin_module")
}
diff --git a/wallet/src/main/java/net/taler/wallet/MainActivity.kt
b/wallet/src/main/java/net/taler/wallet/MainActivity.kt
index 838ed2d..0605976 100644
--- a/wallet/src/main/java/net/taler/wallet/MainActivity.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainActivity.kt
@@ -47,8 +47,6 @@ import
com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_SHORT
import com.google.android.material.snackbar.Snackbar
import com.google.zxing.integration.android.IntentIntegrator
import
com.google.zxing.integration.android.IntentIntegrator.parseActivityResult
-import kotlinx.android.synthetic.main.activity_main.*
-import kotlinx.android.synthetic.main.app_bar_main.*
import net.taler.common.isOnline
import net.taler.wallet.BuildConfig.VERSION_CODE
import net.taler.wallet.BuildConfig.VERSION_NAME
@@ -56,6 +54,7 @@ import
net.taler.wallet.HostCardEmulatorService.Companion.HTTP_TUNNEL_RESPONSE
import
net.taler.wallet.HostCardEmulatorService.Companion.MERCHANT_NFC_CONNECTED
import
net.taler.wallet.HostCardEmulatorService.Companion.MERCHANT_NFC_DISCONNECTED
import
net.taler.wallet.HostCardEmulatorService.Companion.TRIGGER_PAYMENT_ACTION
+import net.taler.wallet.databinding.ActivityMainBinding
import net.taler.wallet.refund.RefundStatus
import java.util.Locale.ROOT
@@ -64,35 +63,37 @@ class MainActivity : AppCompatActivity(),
OnNavigationItemSelectedListener,
private val model: MainViewModel by viewModels()
+ private lateinit var ui: ActivityMainBinding
private lateinit var nav: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
+ ui = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(ui.root)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as
NavHostFragment
nav = navHostFragment.navController
- nav_view.setupWithNavController(nav)
- nav_view.setNavigationItemSelectedListener(this)
+ ui.navView.setupWithNavController(nav)
+ ui.navView.setNavigationItemSelectedListener(this)
if (savedInstanceState == null) {
- nav_view.menu.getItem(0).isChecked = true
+ ui.navView.menu.getItem(0).isChecked = true
}
- setSupportActionBar(toolbar)
+ setSupportActionBar(ui.content.toolbar)
val appBarConfiguration = AppBarConfiguration(
setOf(R.id.nav_main, R.id.nav_settings,
R.id.nav_pending_operations),
- drawer_layout
+ ui.drawerLayout
)
- toolbar.setupWithNavController(nav, appBarConfiguration)
+ ui.content.toolbar.setupWithNavController(nav, appBarConfiguration)
- model.showProgressBar.observe(this, Observer { show ->
- progress_bar.visibility = if (show) VISIBLE else INVISIBLE
+ model.showProgressBar.observe(this, { show ->
+ ui.content.progressBar.visibility = if (show) VISIBLE else
INVISIBLE
})
- val versionView: TextView =
nav_view.getHeaderView(0).findViewById(R.id.versionView)
- model.devMode.observe(this, Observer { enabled ->
- nav_view.menu.findItem(R.id.nav_dev).isVisible = enabled
+ val versionView: TextView =
ui.navView.getHeaderView(0).findViewById(R.id.versionView)
+ model.devMode.observe(this, { enabled ->
+ ui.navView.menu.findItem(R.id.nav_dev).isVisible = enabled
if (enabled) {
@SuppressLint("SetTextI18n")
versionView.text = "$VERSION_NAME ($VERSION_CODE)"
@@ -113,7 +114,7 @@ class MainActivity : AppCompatActivity(),
OnNavigationItemSelectedListener,
}
override fun onBackPressed() {
- if (drawer_layout.isDrawerOpen(START)) drawer_layout.closeDrawer(START)
+ if (ui.drawerLayout.isDrawerOpen(START))
ui.drawerLayout.closeDrawer(START)
else super.onBackPressed()
}
@@ -123,7 +124,7 @@ class MainActivity : AppCompatActivity(),
OnNavigationItemSelectedListener,
R.id.nav_settings -> nav.navigate(R.id.nav_settings)
R.id.nav_pending_operations ->
nav.navigate(R.id.nav_pending_operations)
}
- drawer_layout.closeDrawer(START)
+ ui.drawerLayout.closeDrawer(START)
return true
}
@@ -167,7 +168,7 @@ class MainActivity : AppCompatActivity(),
OnNavigationItemSelectedListener,
}
else -> {
Snackbar.make(
- nav_view,
+ ui.navView,
"URL from $from doesn't contain a supported Taler Uri.",
LENGTH_SHORT
).show()
@@ -179,13 +180,13 @@ class MainActivity : AppCompatActivity(),
OnNavigationItemSelectedListener,
model.showProgressBar.value = false
when (status) {
is RefundStatus.Error -> {
- Snackbar.make(nav_view, R.string.refund_error,
LENGTH_LONG).show()
+ Snackbar.make(ui.navView, R.string.refund_error,
LENGTH_LONG).show()
}
is RefundStatus.Success -> {
val amount = status.response.amountRefundGranted
model.showTransactions(amount.currency)
val str = getString(R.string.refund_success, amount.amountStr)
- Snackbar.make(nav_view, str, LENGTH_LONG).show()
+ Snackbar.make(ui.navView, str, 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 d5bd3fc..1479bc0 100644
--- a/wallet/src/main/java/net/taler/wallet/MainFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainFragment.kt
@@ -22,14 +22,13 @@ import android.view.View
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.BalanceItem
import net.taler.wallet.balances.BalancesFragment
+import net.taler.wallet.databinding.FragmentMainBinding
import net.taler.wallet.transactions.TransactionsFragment
enum class CurrencyMode { SINGLE, MULTI }
@@ -39,16 +38,19 @@ class MainFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private var currencyMode: CurrencyMode? = null
+ private lateinit var ui: FragmentMainBinding
+
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_main, container, false)
+ ui = FragmentMainBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- model.balances.observe(viewLifecycleOwner, Observer {
+ model.balances.observe(viewLifecycleOwner, {
onBalancesChanged(it)
})
model.transactionsEvent.observe(viewLifecycleOwner, EventObserver {
currency ->
@@ -59,10 +61,10 @@ class MainFragment : Fragment() {
}
})
- mainFab.setOnClickListener {
+ ui.mainFab.setOnClickListener {
scanQrCode(requireActivity())
}
- mainFab.setOnLongClickListener {
+ ui.mainFab.setOnLongClickListener {
findNavController().navigate(R.id.action_nav_main_to_nav_uri_input)
true
}
diff --git a/wallet/src/main/java/net/taler/wallet/UriInputFragment.kt
b/wallet/src/main/java/net/taler/wallet/UriInputFragment.kt
index eaa6d16..d17977b 100644
--- a/wallet/src/main/java/net/taler/wallet/UriInputFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/UriInputFragment.kt
@@ -27,40 +27,43 @@ import android.view.ViewGroup
import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import androidx.fragment.app.Fragment
-import kotlinx.android.synthetic.main.fragment_uri_input.*
+import net.taler.wallet.databinding.FragmentUriInputBinding
class UriInputFragment : Fragment() {
+ private lateinit var ui: FragmentUriInputBinding
+
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_uri_input, container, false)
+ ui = FragmentUriInputBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val clipboard =
requireContext().getSystemService(ClipboardManager::class.java)!!
- pasteButton.setOnClickListener {
+ ui.pasteButton.setOnClickListener {
val item = clipboard.primaryClip?.getItemAt(0)
if (item?.text != null) {
- uriView.setText(item.text)
+ ui.uriView.setText(item.text)
} else {
if (item?.uri != null) {
- uriView.setText(item.uri.toString())
+ ui.uriView.setText(item.uri.toString())
} else {
Toast.makeText(requireContext(), R.string.paste_invalid,
LENGTH_LONG).show()
}
}
}
- okButton.setOnClickListener {
- if (uriView.text?.startsWith("taler://") == true) {
- uriLayout.error = null
- val i = Intent(ACTION_VIEW, Uri.parse(uriView.text.toString()))
+ ui.okButton.setOnClickListener {
+ if (ui.uriView.text?.startsWith("taler://") == true) {
+ ui.uriLayout.error = null
+ val i = Intent(ACTION_VIEW,
Uri.parse(ui.uriView.text.toString()))
startActivity(i)
} else {
- uriLayout.error = getString(R.string.uri_invalid)
+ ui.uriLayout.error = getString(R.string.uri_invalid)
}
}
}
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 2b4d032..afd9a23 100644
--- a/wallet/src/main/java/net/taler/wallet/balances/BalancesFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/balances/BalancesFragment.kt
@@ -26,13 +26,11 @@ import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager.VERTICAL
-import kotlinx.android.synthetic.main.fragment_balances.*
import net.taler.common.fadeIn
import net.taler.wallet.MainViewModel
-import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentBalancesBinding
interface BalanceClickListener {
fun onBalanceClick(currency: String)
@@ -43,6 +41,7 @@ class BalancesFragment : Fragment(),
private val model: MainViewModel by activityViewModels()
+ private lateinit var ui: FragmentBalancesBinding
private val balancesAdapter = BalanceAdapter(this)
override fun onCreateView(
@@ -50,16 +49,17 @@ class BalancesFragment : Fragment(),
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_balances, container, false)
+ ui = FragmentBalancesBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- mainList.apply {
+ ui.mainList.apply {
adapter = balancesAdapter
addItemDecoration(DividerItemDecoration(context, VERTICAL))
}
- model.balances.observe(viewLifecycleOwner, Observer {
+ model.balances.observe(viewLifecycleOwner, {
onBalancesChanged(it)
})
}
@@ -67,12 +67,12 @@ class BalancesFragment : Fragment(),
private fun onBalancesChanged(balances: List<BalanceItem>) {
beginDelayedTransition(view as ViewGroup)
if (balances.isEmpty()) {
- mainEmptyState.visibility = VISIBLE
- mainList.visibility = GONE
+ ui.mainEmptyState.visibility = VISIBLE
+ ui.mainList.visibility = GONE
} else {
balancesAdapter.setItems(balances)
- mainEmptyState.visibility = INVISIBLE
- mainList.fadeIn()
+ ui.mainEmptyState.visibility = INVISIBLE
+ ui.mainList.fadeIn()
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt
b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt
index c7da205..86b2519 100644
--- a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt
@@ -24,43 +24,45 @@ import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
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_exchange_list.*
import net.taler.common.EventObserver
import net.taler.common.fadeIn
import net.taler.common.fadeOut
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentExchangeListBinding
class ExchangeListFragment : Fragment(), ExchangeClickListener {
private val model: MainViewModel by activityViewModels()
private val exchangeManager by lazy { model.exchangeManager }
+
+ private lateinit var ui: FragmentExchangeListBinding
private val exchangeAdapter by lazy { ExchangeAdapter(this) }
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_exchange_list, container,
false)
+ ui = FragmentExchangeListBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- list.apply {
+ ui.list.apply {
adapter = exchangeAdapter
addItemDecoration(DividerItemDecoration(context, VERTICAL))
}
- addExchangeFab.setOnClickListener {
+ ui.addExchangeFab.setOnClickListener {
AddExchangeDialogFragment().show(parentFragmentManager,
"ADD_EXCHANGE")
}
- exchangeManager.progress.observe(viewLifecycleOwner, Observer { show ->
- if (show) progressBar.fadeIn() else progressBar.fadeOut()
+ exchangeManager.progress.observe(viewLifecycleOwner, { show ->
+ if (show) ui.progressBar.fadeIn() else ui.progressBar.fadeOut()
})
- exchangeManager.exchanges.observe(viewLifecycleOwner, Observer {
exchanges ->
+ exchangeManager.exchanges.observe(viewLifecycleOwner, { exchanges ->
onExchangeUpdate(exchanges)
})
exchangeManager.addError.observe(viewLifecycleOwner, EventObserver {
error ->
@@ -71,11 +73,11 @@ class ExchangeListFragment : Fragment(),
ExchangeClickListener {
private fun onExchangeUpdate(exchanges: List<ExchangeItem>) {
exchangeAdapter.update(exchanges)
if (exchanges.isEmpty()) {
- emptyState.fadeIn()
- list.fadeOut()
+ ui.emptyState.fadeIn()
+ ui.list.fadeOut()
} else {
- emptyState.fadeOut()
- list.fadeIn()
+ ui.emptyState.fadeOut()
+ ui.list.fadeIn()
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt
b/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt
index 9f5a916..a95a51c 100644
--- a/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt
@@ -27,12 +27,12 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.RecyclerView.Adapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
-import kotlinx.android.synthetic.main.fragment_select_exchange.*
-import net.taler.lib.common.Amount
import net.taler.common.toRelativeTime
import net.taler.common.toShortDate
+import net.taler.lib.common.Amount
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentSelectExchangeBinding
import net.taler.wallet.exchanges.CoinFeeAdapter.CoinFeeViewHolder
import net.taler.wallet.exchanges.WireFeeAdapter.WireFeeViewHolder
@@ -41,28 +41,29 @@ class SelectExchangeFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val withdrawManager by lazy { model.withdrawManager }
+ private lateinit var ui: FragmentSelectExchangeBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_select_exchange, container,
false)
+ ui = FragmentSelectExchangeBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val fees = withdrawManager.exchangeFees ?: throw
IllegalStateException()
if (fees.withdrawFee.isZero()) {
- withdrawFeeLabel.visibility = GONE
- withdrawFeeView.visibility = GONE
- } else withdrawFeeView.setAmount(fees.withdrawFee)
+ ui.withdrawFeeLabel.visibility = GONE
+ ui.withdrawFeeView.visibility = GONE
+ } else ui.withdrawFeeView.setAmount(fees.withdrawFee)
if (fees.overhead.isZero()) {
- overheadLabel.visibility = GONE
- overheadView.visibility = GONE
- } else overheadView.setAmount(fees.overhead)
- expirationView.text =
fees.earliestDepositExpiration.ms.toRelativeTime(requireContext())
- coinFeesList.adapter =
- CoinFeeAdapter(fees.coinFees)
- wireFeesList.adapter =
- WireFeeAdapter(fees.wireFees)
+ ui.overheadLabel.visibility = GONE
+ ui.overheadView.visibility = GONE
+ } else ui.overheadView.setAmount(fees.overhead)
+ ui.expirationView.text =
fees.earliestDepositExpiration.ms.toRelativeTime(requireContext())
+ ui.coinFeesList.adapter = CoinFeeAdapter(fees.coinFees)
+ ui.wireFeesList.adapter = WireFeeAdapter(fees.wireFees)
}
private fun TextView.setAmount(amount: Amount) {
diff --git
a/wallet/src/main/java/net/taler/wallet/payment/AlreadyPaidFragment.kt
b/wallet/src/main/java/net/taler/wallet/payment/AlreadyPaidFragment.kt
index 33e3a1d..df2b2b8 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/AlreadyPaidFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/AlreadyPaidFragment.kt
@@ -22,8 +22,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
-import kotlinx.android.synthetic.main.fragment_already_paid.*
-import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentAlreadyPaidBinding
/**
* Display the message that the user already paid for the order
@@ -31,15 +30,18 @@ import net.taler.wallet.R
*/
class AlreadyPaidFragment : Fragment() {
+ private lateinit var ui: FragmentAlreadyPaidBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_already_paid, container,
false)
+ ui = FragmentAlreadyPaidBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- backButton.setOnClickListener {
+ ui.backButton.setOnClickListener {
findNavController().navigateUp()
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/payment/ProductImageFragment.kt
b/wallet/src/main/java/net/taler/wallet/payment/ProductImageFragment.kt
index ff70f75..75de93f 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/ProductImageFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/ProductImageFragment.kt
@@ -22,11 +22,12 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
-import kotlinx.android.synthetic.main.fragment_product_image.*
-import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentProductImageBinding
class ProductImageFragment private constructor() : DialogFragment() {
+ private lateinit var ui: FragmentProductImageBinding
+
companion object {
private const val IMAGE = "image"
@@ -41,12 +42,13 @@ class ProductImageFragment private constructor() :
DialogFragment() {
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_product_image, container,
false)
+ ui = FragmentProductImageBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val bitmap = requireArguments().getParcelable<Bitmap>(IMAGE)
- productImageView.setImageBitmap(bitmap)
+ ui.productImageView.setImageBitmap(bitmap)
}
}
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 99a6ec8..8815408 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt
@@ -32,14 +32,13 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.transition.TransitionManager.beginDelayedTransition
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
-import kotlinx.android.synthetic.main.payment_bottom_bar.*
-import kotlinx.android.synthetic.main.payment_details.*
import net.taler.common.ContractTerms
import net.taler.common.fadeIn
import net.taler.common.fadeOut
import net.taler.lib.common.Amount
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentPromptPaymentBinding
/**
* Show a payment and ask the user to accept/decline.
@@ -48,13 +47,16 @@ class PromptPaymentFragment : Fragment(),
ProductImageClickListener {
private val model: MainViewModel by activityViewModels()
private val paymentManager by lazy { model.paymentManager }
+
+ private lateinit var ui: FragmentPromptPaymentBinding
private val adapter = ProductAdapter(this)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_prompt_payment, container,
false)
+ ui = FragmentPromptPaymentBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -62,14 +64,14 @@ class PromptPaymentFragment : Fragment(),
ProductImageClickListener {
paymentManager.detailsShown.observe(viewLifecycleOwner, Observer {
shown ->
beginDelayedTransition(view as ViewGroup)
val res = if (shown) R.string.payment_hide_details else
R.string.payment_show_details
- detailsButton.setText(res)
- productsList.visibility = if (shown) VISIBLE else GONE
+ ui.details.detailsButton.setText(res)
+ ui.details.productsList.visibility = if (shown) VISIBLE else GONE
})
- detailsButton.setOnClickListener {
+ ui.details.detailsButton.setOnClickListener {
paymentManager.toggleDetailsShown()
}
- productsList.apply {
+ ui.details.productsList.apply {
adapter = this@PromptPaymentFragment.adapter
layoutManager = LinearLayoutManager(requireContext())
}
@@ -85,9 +87,9 @@ class PromptPaymentFragment : Fragment(),
ProductImageClickListener {
private fun showLoading(show: Boolean) {
model.showProgressBar.value = show
if (show) {
- progressBar.fadeIn()
+ ui.details.progressBar.fadeIn()
} else {
- progressBar.fadeOut()
+ ui.details.progressBar.fadeOut()
}
}
@@ -97,22 +99,22 @@ class PromptPaymentFragment : Fragment(),
ProductImageClickListener {
showLoading(false)
val fees = payStatus.amountEffective - payStatus.amountRaw
showOrder(payStatus.contractTerms, payStatus.amountRaw, fees)
- confirmButton.isEnabled = true
- confirmButton.setOnClickListener {
+ ui.bottom.confirmButton.isEnabled = true
+ ui.bottom.confirmButton.setOnClickListener {
model.showProgressBar.value = true
paymentManager.confirmPay(
payStatus.proposalId,
payStatus.contractTerms.amount.currency
)
- confirmButton.fadeOut()
- confirmProgressBar.fadeIn()
+ ui.bottom.confirmButton.fadeOut()
+ ui.bottom.confirmProgressBar.fadeIn()
}
}
is PayStatus.InsufficientBalance -> {
showLoading(false)
showOrder(payStatus.contractTerms, payStatus.amountRaw)
- errorView.setText(R.string.payment_balance_insufficient)
- errorView.fadeIn()
+
ui.details.errorView.setText(R.string.payment_balance_insufficient)
+ ui.details.errorView.fadeIn()
}
is PayStatus.Success -> {
showLoading(false)
@@ -128,8 +130,8 @@ class PromptPaymentFragment : Fragment(),
ProductImageClickListener {
}
is PayStatus.Error -> {
showLoading(false)
- errorView.text = getString(R.string.payment_error,
payStatus.error)
- errorView.fadeIn()
+ ui.details.errorView.text = getString(R.string.payment_error,
payStatus.error)
+ ui.details.errorView.fadeIn()
}
is PayStatus.None -> {
// No payment active.
@@ -143,21 +145,21 @@ class PromptPaymentFragment : Fragment(),
ProductImageClickListener {
}
private fun showOrder(contractTerms: ContractTerms, amount:Amount,
totalFees: Amount? = null) {
- orderView.text = contractTerms.summary
+ ui.details.orderView.text = contractTerms.summary
adapter.setItems(contractTerms.products)
if (contractTerms.products.size == 1)
paymentManager.toggleDetailsShown()
- totalView.text = amount.toString()
+ ui.bottom.totalView.text = amount.toString()
if (totalFees != null && !totalFees.isZero()) {
- feeView.text = getString(R.string.payment_fee, totalFees)
- feeView.fadeIn()
+ ui.bottom.feeView.text = getString(R.string.payment_fee, totalFees)
+ ui.bottom.feeView.fadeIn()
} else {
- feeView.visibility = GONE
+ ui.bottom.feeView.visibility = GONE
}
- orderLabelView.fadeIn()
- orderView.fadeIn()
- if (contractTerms.products.size > 1) detailsButton.fadeIn()
- totalLabelView.fadeIn()
- totalView.fadeIn()
+ ui.details.orderLabelView.fadeIn()
+ ui.details.orderView.fadeIn()
+ if (contractTerms.products.size > 1) ui.details.detailsButton.fadeIn()
+ ui.bottom.totalLabelView.fadeIn()
+ ui.bottom.totalView.fadeIn()
}
override fun onImageClick(image: Bitmap) {
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 293dbdb..e2f3ca1 100644
--- a/wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/pending/PendingOperationsFragment.kt
@@ -30,16 +30,15 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.snackbar.Snackbar.LENGTH_SHORT
-import kotlinx.android.synthetic.main.fragment_pending_operations.*
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
import net.taler.wallet.TAG
+import net.taler.wallet.databinding.FragmentPendingOperationsBinding
import org.json.JSONObject
interface PendingOperationClickListener {
@@ -52,6 +51,7 @@ class PendingOperationsFragment : Fragment(),
PendingOperationClickListener {
private val model: MainViewModel by activityViewModels()
private val pendingOperationsManager by lazy {
model.pendingOperationsManager }
+ private lateinit var ui: FragmentPendingOperationsBinding
private val pendingAdapter = PendingOperationsAdapter(emptyList(), this)
override fun onCreate(savedInstanceState: Bundle?) {
@@ -64,13 +64,14 @@ class PendingOperationsFragment : Fragment(),
PendingOperationClickListener {
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_pending_operations,
container, false)
+ ui = FragmentPendingOperationsBinding.inflate(inflater, container,
false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- list_pending.apply {
+ ui.listPending.apply {
val myLayoutManager = LinearLayoutManager(requireContext())
val myItemDecoration =
DividerItemDecoration(requireContext(),
myLayoutManager.orientation)
@@ -79,7 +80,7 @@ class PendingOperationsFragment : Fragment(),
PendingOperationClickListener {
addItemDecoration(myItemDecoration)
}
- pendingOperationsManager.pendingOperations.observe(viewLifecycleOwner,
Observer {
+ pendingOperationsManager.pendingOperations.observe(viewLifecycleOwner,
{
updatePending(it)
})
}
diff --git a/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt
b/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt
index a52b9d8..63492f4 100644
--- a/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt
@@ -20,7 +20,6 @@ import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
@@ -75,12 +74,12 @@ class SettingsFragment : PreferenceFragmentCompat() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- model.lastBackup.observe(viewLifecycleOwner, Observer {
+ model.lastBackup.observe(viewLifecycleOwner, {
val time = it.toRelativeTime(requireContext())
prefBackup.summary = getString(R.string.backup_last, time)
})
- model.devMode.observe(viewLifecycleOwner, Observer { enabled ->
+ model.devMode.observe(viewLifecycleOwner, { enabled ->
prefDevMode.isChecked = enabled
if (enabled) {
prefVersionApp.summary = "$VERSION_NAME ($FLAVOR
$VERSION_CODE)"
@@ -95,7 +94,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
true
}
- withdrawManager.testWithdrawalInProgress.observe(viewLifecycleOwner,
Observer { loading ->
+ withdrawManager.testWithdrawalInProgress.observe(viewLifecycleOwner, {
loading ->
prefWithdrawTest.isEnabled = !loading
model.showProgressBar.value = loading
})
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 f15e34f..302e684 100644
---
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
+++
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionDetailFragment.kt
@@ -19,68 +19,34 @@ package net.taler.wallet.transactions
import android.content.Intent
import android.net.Uri
import android.os.Bundle
-import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
-import android.view.View
-import android.view.View.GONE
-import android.view.ViewGroup
-import android.widget.Toast
-import android.widget.Toast.LENGTH_LONG
-import androidx.core.content.ContextCompat.getColor
+import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import kotlinx.android.synthetic.main.fragment_transaction_payment.*
-import kotlinx.android.synthetic.main.fragment_transaction_withdrawal.*
-import kotlinx.android.synthetic.main.fragment_transaction_withdrawal.feeView
-import kotlinx.android.synthetic.main.fragment_transaction_withdrawal.timeView
import net.taler.common.isSafe
-import net.taler.common.toAbsoluteTime
import net.taler.lib.common.Amount
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
-import net.taler.wallet.cleanExchange
-import net.taler.wallet.transactions.WithdrawalDetails.TalerBankIntegrationApi
-class TransactionDetailFragment : Fragment() {
+abstract class TransactionDetailFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val transactionManager by lazy { model.transactionManager }
- private val transaction by lazy {
requireNotNull(transactionManager.selectedTransaction) }
+ protected val transaction: Transaction? get() =
transactionManager.selectedTransaction
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(model.devMode.value == true)
}
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(transaction.detailPageLayout, container, false)
- }
-
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
requireActivity().apply {
- title = getString(transaction.generalTitleRes)
- }
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- timeView.text =
transaction.timestamp.ms.toAbsoluteTime(requireContext())
- when (val e = transaction) {
- is TransactionWithdrawal -> bind(e)
- is TransactionPayment -> bind(e)
- is TransactionRefund -> bind(e)
- is TransactionRefresh -> bind(e)
- else -> Toast.makeText(
- requireContext(),
- "Transaction ${e.javaClass.simpleName} not implemented.",
- LENGTH_LONG
- ).show()
+ transaction?.generalTitleRes?.let {
+ title = getString(it)
+ }
}
}
@@ -94,54 +60,15 @@ class TransactionDetailFragment : Fragment() {
}
}
- private fun bind(t: TransactionWithdrawal) {
- effectiveAmountLabel.text = getString(R.string.withdraw_total)
- effectiveAmountView.text = t.amountEffective.toString()
- if (t.pending && t.withdrawalDetails is TalerBankIntegrationApi &&
- !t.confirmed && t.withdrawalDetails.bankConfirmationUrl != null
- ) {
- val i = Intent().apply {
- data = Uri.parse(t.withdrawalDetails.bankConfirmationUrl)
- }
- if (i.isSafe(requireContext())) {
- confirmWithdrawalButton.setOnClickListener { startActivity(i) }
- }
- } else confirmWithdrawalButton.visibility = GONE
- chosenAmountLabel.text = getString(R.string.amount_chosen)
- chosenAmountView.text =
- getString(R.string.amount_positive, t.amountRaw.toString())
- val fee = t.amountRaw - t.amountEffective
- feeView.text = getString(R.string.amount_negative, fee.toString())
- exchangeView.text = cleanExchange(t.exchangeBaseUrl)
- }
-
- private fun bind(t: TransactionPayment) {
- amountPaidWithFeesView.text = t.amountEffective.toString()
- val fee = t.amountEffective - t.amountRaw
- bindOrderAndFee(t.info, t.amountRaw, fee)
- }
-
- private fun bind(t: TransactionRefund) {
- amountPaidWithFeesLabel.text = getString(R.string.transaction_refund)
- amountPaidWithFeesView.setTextColor(getColor(requireContext(),
R.color.green))
- amountPaidWithFeesView.text =
- getString(R.string.amount_positive, t.amountEffective.toString())
- val fee = t.amountRaw - t.amountEffective
- bindOrderAndFee(t.info, t.amountRaw, fee)
- }
-
- private fun bind(t: TransactionRefresh) {
- effectiveAmountLabel.visibility = GONE
- effectiveAmountView.visibility = GONE
- confirmWithdrawalButton.visibility = GONE
- chosenAmountLabel.visibility = GONE
- chosenAmountView.visibility = GONE
- val fee = t.amountEffective
- feeView.text = getString(R.string.amount_negative, fee.toString())
- exchangeView.text = cleanExchange(t.exchangeBaseUrl)
- }
-
- private fun bindOrderAndFee(info: TransactionInfo, raw: Amount, fee:
Amount) {
+ protected fun bindOrderAndFee(
+ orderSummaryView: TextView,
+ orderAmountView: TextView,
+ orderIdView: TextView,
+ feeView: TextView,
+ info: TransactionInfo,
+ raw: Amount,
+ fee: Amount
+ ) {
orderAmountView.text = raw.toString()
feeView.text = getString(R.string.amount_negative, fee.toString())
orderSummaryView.text = if (info.fulfillmentMessage == null) {
diff --git
a/wallet/src/main/java/net/taler/wallet/payment/ProductImageFragment.kt
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt
similarity index 53%
copy from wallet/src/main/java/net/taler/wallet/payment/ProductImageFragment.kt
copy to
wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt
index ff70f75..84c5c77 100644
--- a/wallet/src/main/java/net/taler/wallet/payment/ProductImageFragment.kt
+++
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionPaymentFragment.kt
@@ -14,39 +14,43 @@
* GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-package net.taler.wallet.payment
+package net.taler.wallet.transactions
-import android.graphics.Bitmap
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.fragment.app.DialogFragment
-import kotlinx.android.synthetic.main.fragment_product_image.*
-import net.taler.wallet.R
+import net.taler.common.toAbsoluteTime
+import net.taler.wallet.databinding.FragmentTransactionPaymentBinding
-class ProductImageFragment private constructor() : DialogFragment() {
+class TransactionPaymentFragment : TransactionDetailFragment() {
- companion object {
- private const val IMAGE = "image"
-
- fun new(image: Bitmap) = ProductImageFragment().apply {
- arguments = Bundle().apply {
- putParcelable(IMAGE, image)
- }
- }
- }
+ private lateinit var ui: FragmentTransactionPaymentBinding
override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
+ inflater: LayoutInflater,
+ container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_product_image, container,
false)
+ ui = FragmentTransactionPaymentBinding.inflate(inflater, container,
false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- val bitmap = requireArguments().getParcelable<Bitmap>(IMAGE)
- productImageView.setImageBitmap(bitmap)
+ val t = transaction as TransactionPayment
+ ui.timeView.text = t.timestamp.ms.toAbsoluteTime(requireContext())
+
+ ui.amountPaidWithFeesView.text = t.amountEffective.toString()
+ val fee = t.amountEffective - t.amountRaw
+ bindOrderAndFee(
+ ui.orderSummaryView,
+ ui.orderAmountView,
+ ui.orderIdView,
+ ui.feeView,
+ t.info,
+ t.amountRaw,
+ fee
+ )
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
new file mode 100644
index 0000000..717dd33
--- /dev/null
+++
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefreshFragment.kt
@@ -0,0 +1,56 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2020 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under
the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+package net.taler.wallet.transactions
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.View.GONE
+import android.view.ViewGroup
+import net.taler.common.toAbsoluteTime
+import net.taler.wallet.R
+import net.taler.wallet.cleanExchange
+import net.taler.wallet.databinding.FragmentTransactionWithdrawalBinding
+
+class TransactionRefreshFragment : TransactionDetailFragment() {
+
+ private lateinit var ui: FragmentTransactionWithdrawalBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ ui = FragmentTransactionWithdrawalBinding.inflate(inflater, container,
false)
+ return ui.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ val t = transaction as TransactionRefresh
+ ui.timeView.text = t.timestamp.ms.toAbsoluteTime(requireContext())
+
+ ui.effectiveAmountLabel.visibility = GONE
+ ui.effectiveAmountView.visibility = GONE
+ ui.confirmWithdrawalButton.visibility = GONE
+ ui.chosenAmountLabel.visibility = GONE
+ ui.chosenAmountView.visibility = GONE
+ val fee = t.amountEffective
+ ui.feeView.text = getString(R.string.amount_negative, fee.toString())
+ ui. exchangeView.text = cleanExchange(t.exchangeBaseUrl)
+ }
+
+}
diff --git
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt
new file mode 100644
index 0000000..6628d6c
--- /dev/null
+++
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionRefundFragment.kt
@@ -0,0 +1,61 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2020 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under
the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+package net.taler.wallet.transactions
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.core.content.ContextCompat.getColor
+import net.taler.common.toAbsoluteTime
+import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentTransactionPaymentBinding
+
+class TransactionRefundFragment : TransactionDetailFragment() {
+
+ private lateinit var ui: FragmentTransactionPaymentBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ ui = FragmentTransactionPaymentBinding.inflate(inflater, container,
false)
+ return ui.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ val t = transaction as TransactionRefund
+ ui.timeView.text = t.timestamp.ms.toAbsoluteTime(requireContext())
+
+ ui.amountPaidWithFeesLabel.text =
getString(R.string.transaction_refund)
+ ui.amountPaidWithFeesView.setTextColor(getColor(requireContext(),
R.color.green))
+ ui.amountPaidWithFeesView.text =
+ getString(R.string.amount_positive, t.amountEffective.toString())
+ val fee = t.amountRaw - t.amountEffective
+ bindOrderAndFee(
+ ui.orderSummaryView,
+ ui.orderAmountView,
+ ui.orderIdView,
+ ui.feeView,
+ t.info,
+ t.amountRaw,
+ fee
+ )
+ }
+
+}
diff --git
a/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
new file mode 100644
index 0000000..26965ef
--- /dev/null
+++
b/wallet/src/main/java/net/taler/wallet/transactions/TransactionWithdrawalFragment.kt
@@ -0,0 +1,68 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2020 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under
the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+package net.taler.wallet.transactions
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import net.taler.common.isSafe
+import net.taler.common.toAbsoluteTime
+import net.taler.wallet.R
+import net.taler.wallet.cleanExchange
+import net.taler.wallet.databinding.FragmentTransactionWithdrawalBinding
+
+class TransactionWithdrawalFragment : TransactionDetailFragment() {
+
+ private lateinit var ui: FragmentTransactionWithdrawalBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ ui = FragmentTransactionWithdrawalBinding.inflate(inflater, container,
false)
+ return ui.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ val t = transaction as TransactionWithdrawal
+ ui.timeView.text = t.timestamp.ms.toAbsoluteTime(requireContext())
+
+ ui.effectiveAmountLabel.text = getString(R.string.withdraw_total)
+ ui.effectiveAmountView.text = t.amountEffective.toString()
+ if (t.pending && t.withdrawalDetails is
WithdrawalDetails.TalerBankIntegrationApi &&
+ !t.confirmed && t.withdrawalDetails.bankConfirmationUrl != null
+ ) {
+ val i = Intent().apply {
+ data = Uri.parse(t.withdrawalDetails.bankConfirmationUrl)
+ }
+ if (i.isSafe(requireContext())) {
+ ui.confirmWithdrawalButton.setOnClickListener {
startActivity(i) }
+ }
+ } else ui.confirmWithdrawalButton.visibility = View.GONE
+ ui.chosenAmountLabel.text = getString(R.string.amount_chosen)
+ ui.chosenAmountView.text =
+ getString(R.string.amount_positive, t.amountRaw.toString())
+ val fee = t.amountRaw - t.amountEffective
+ ui.feeView.text = getString(R.string.amount_negative, fee.toString())
+ ui.exchangeView.text = cleanExchange(t.exchangeBaseUrl)
+ }
+
+}
diff --git a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
index db3f283..50181c5 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/Transactions.kt
@@ -18,7 +18,7 @@ package net.taler.wallet.transactions
import android.content.Context
import androidx.annotation.DrawableRes
-import androidx.annotation.LayoutRes
+import androidx.annotation.IdRes
import androidx.annotation.StringRes
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@@ -48,8 +48,8 @@ sealed class Transaction {
@get:DrawableRes
abstract val icon: Int
- @get:LayoutRes
- abstract val detailPageLayout: Int
+ @get:IdRes
+ abstract val detailPageNav: Int
abstract val amountType: AmountType
@@ -78,7 +78,8 @@ class TransactionWithdrawal(
override val amountEffective: Amount
) : Transaction() {
override val icon = R.drawable.transaction_withdrawal
- override val detailPageLayout = R.layout.fragment_transaction_withdrawal
+
+ override val detailPageNav = R.id.action_nav_transactions_detail_withdrawal
@Transient
override val amountType = AmountType.Positive
@@ -135,7 +136,7 @@ class TransactionPayment(
override val amountEffective: Amount
) : Transaction() {
override val icon = R.drawable.ic_cash_usd_outline
- override val detailPageLayout = R.layout.fragment_transaction_payment
+ override val detailPageNav = R.id.action_nav_transactions_detail_payment
@Transient
override val amountType = AmountType.Negative
@@ -190,13 +191,11 @@ class TransactionRefund(
*/
val amountInvalid: Amount? = null,
override val error: TalerErrorInfo? = null,
- @SerialName("amountEffective") // TODO remove when fixed in wallet-core
override val amountRaw: Amount,
- @SerialName("amountRaw") // TODO remove when fixed in wallet-core
override val amountEffective: Amount
) : Transaction() {
override val icon = R.drawable.transaction_refund
- override val detailPageLayout = R.layout.fragment_transaction_payment
+ override val detailPageNav = R.id.action_nav_transactions_detail_refund
@Transient
override val amountType = AmountType.Positive
@@ -221,7 +220,7 @@ class TransactionTip(
override val amountEffective: Amount
) : Transaction() {
override val icon = R.drawable.transaction_tip_accepted // TODO different
when declined
- override val detailPageLayout = R.layout.fragment_transaction_payment
+ override val detailPageNav = 0
@Transient
override val amountType = AmountType.Positive
@@ -244,7 +243,7 @@ class TransactionRefresh(
override val amountEffective: Amount
) : Transaction() {
override val icon = R.drawable.transaction_refresh
- override val detailPageLayout = R.layout.fragment_transaction_withdrawal
+ override val detailPageNav = R.id.action_nav_transactions_detail_refresh
@Transient
override val amountType = AmountType.Negative
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 8d47a3f..90510e6 100644
--- a/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/transactions/TransactionsFragment.kt
@@ -30,18 +30,17 @@ import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.SearchView.OnQueryTextListener
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.selection.SelectionPredicates
import androidx.recyclerview.selection.SelectionTracker
import androidx.recyclerview.selection.StorageStrategy
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager.VERTICAL
-import kotlinx.android.synthetic.main.fragment_transactions.*
import net.taler.common.fadeIn
import net.taler.common.fadeOut
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentTransactionsBinding
interface OnTransactionClickListener {
fun onTransactionClicked(transaction: Transaction)
@@ -52,6 +51,7 @@ class TransactionsFragment : Fragment(),
OnTransactionClickListener, ActionMode.
private val model: MainViewModel by activityViewModels()
private val transactionManager by lazy { model.transactionManager }
+ private lateinit var ui: FragmentTransactionsBinding
private val transactionAdapter by lazy { TransactionAdapter(this) }
private val currency by lazy { transactionManager.selectedCurrency!! }
private var tracker: SelectionTracker<String>? = null
@@ -66,19 +66,20 @@ class TransactionsFragment : Fragment(),
OnTransactionClickListener, ActionMode.
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_transactions, container,
false)
+ ui = FragmentTransactionsBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- list.apply {
+ ui.list.apply {
adapter = transactionAdapter
addItemDecoration(DividerItemDecoration(context, VERTICAL))
}
val tracker = SelectionTracker.Builder(
"transaction-selection-id",
- list,
+ ui.list,
transactionAdapter.keyProvider,
- TransactionLookup(list, transactionAdapter),
+ TransactionLookup(ui.list, transactionAdapter),
StorageStrategy.createStringStorage()
).withSelectionPredicate(
SelectionPredicates.createSelectAnything()
@@ -101,17 +102,17 @@ class TransactionsFragment : Fragment(),
OnTransactionClickListener, ActionMode.
}
})
- transactionManager.progress.observe(viewLifecycleOwner, Observer {
show ->
- if (show) progressBar.fadeIn() else progressBar.fadeOut()
+ transactionManager.progress.observe(viewLifecycleOwner, { show ->
+ if (show) ui.progressBar.fadeIn() else ui.progressBar.fadeOut()
})
- transactionManager.transactions.observe(viewLifecycleOwner, Observer {
result ->
+ transactionManager.transactions.observe(viewLifecycleOwner, { result ->
onTransactionsResult(result)
})
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
- model.balances.observe(viewLifecycleOwner, Observer { balances ->
+ model.balances.observe(viewLifecycleOwner, { balances ->
balances.find { it.currency == currency }?.available?.let { amount
->
requireActivity().title =
getString(R.string.transactions_detail_title_balance,
amount)
@@ -153,35 +154,35 @@ class TransactionsFragment : Fragment(),
OnTransactionClickListener, ActionMode.
override fun onTransactionClicked(transaction: Transaction) {
if (actionMode != null) return // don't react on clicks while in
action mode
- if (transaction.detailPageLayout != 0) {
+ if (transaction.detailPageNav != 0) {
transactionManager.selectedTransaction = transaction
- findNavController().navigate(R.id.action_nav_transaction_detail)
+ findNavController().navigate(transaction.detailPageNav)
}
}
private fun onTransactionsResult(result: TransactionsResult) = when
(result) {
is TransactionsResult.Error -> {
- list.fadeOut()
- emptyState.text = getString(R.string.transactions_error,
result.msg)
- emptyState.fadeIn()
+ ui.list.fadeOut()
+ ui.emptyState.text = getString(R.string.transactions_error,
result.msg)
+ ui.emptyState.fadeIn()
}
is TransactionsResult.Success -> {
if (result.transactions.isEmpty()) {
val isSearch = transactionManager.searchQuery.value != null
- emptyState.setText(if (isSearch)
R.string.transactions_empty_search else R.string.transactions_empty)
- emptyState.fadeIn()
- list.fadeOut()
+ ui.emptyState.setText(if (isSearch)
R.string.transactions_empty_search else R.string.transactions_empty)
+ ui.emptyState.fadeIn()
+ ui.list.fadeOut()
} else {
- emptyState.fadeOut()
+ ui.emptyState.fadeOut()
transactionAdapter.update(result.transactions)
- list.fadeIn()
+ ui.list.fadeIn()
}
}
}
private fun onSearch(query: String) {
- list.fadeOut()
- progressBar.fadeIn()
+ ui.list.fadeOut()
+ ui.progressBar.fadeIn()
transactionManager.searchQuery.value = query
}
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/ErrorFragment.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/ErrorFragment.kt
index fa5ab2f..14389c4 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/ErrorFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/ErrorFragment.kt
@@ -25,38 +25,46 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
-import kotlinx.android.synthetic.main.fragment_error.*
-import net.taler.wallet.R
+import net.taler.common.isOnline
import net.taler.wallet.MainViewModel
+import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentErrorBinding
class ErrorFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val withdrawManager by lazy { model.withdrawManager }
+ private lateinit var ui: FragmentErrorBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_error, container, false)
+ ui = FragmentErrorBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- errorTitle.setText(R.string.withdraw_error_title)
- errorMessage.setText(R.string.withdraw_error_message)
+ ui.errorTitle.setText(R.string.withdraw_error_title)
+ if (requireContext().isOnline()) {
+ ui.errorMessage.setText(R.string.withdraw_error_message)
+ } else {
+ ui.errorMessage.setText(R.string.offline)
+ }
// show dev error message if dev mode is on
val status = withdrawManager.withdrawStatus.value
if (model.devMode.value == true && status is WithdrawStatus.Error) {
- errorDevMessage.visibility = VISIBLE
- errorDevMessage.text = status.message
+ ui.errorDevMessage.visibility = VISIBLE
+ ui.errorDevMessage.text = status.message
} else {
- errorDevMessage.visibility = GONE
+ ui.errorDevMessage.visibility = GONE
}
- backButton.setOnClickListener {
+ ui.backButton.setOnClickListener {
findNavController().navigateUp()
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt
index fbee6ae..4b56dd0 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt
@@ -25,11 +25,11 @@ import android.widget.Toast
import android.widget.Toast.LENGTH_SHORT
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import kotlinx.android.synthetic.main.fragment_manual_withdraw.*
import net.taler.common.hideKeyboard
import net.taler.lib.common.Amount
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentManualWithdrawBinding
import net.taler.wallet.scanQrCode
import java.util.Locale
@@ -40,28 +40,38 @@ class ManualWithdrawFragment : Fragment() {
private val exchangeItem by lazy {
requireNotNull(exchangeManager.withdrawalExchange) }
private val withdrawManager by lazy { model.withdrawManager }
+ private lateinit var ui: FragmentManualWithdrawBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_manual_withdraw, container,
false)
+ ui = FragmentManualWithdrawBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- qrCodeButton.setOnClickListener { scanQrCode(requireActivity()) }
- currencyView.text = exchangeItem.currency
+ ui.qrCodeButton.setOnClickListener { scanQrCode(requireActivity()) }
+ ui.currencyView.text = exchangeItem.currency
val paymentOptions = exchangeItem.paytoUris.mapNotNull {paytoUri ->
Uri.parse(paytoUri).authority?.toUpperCase(Locale.getDefault())
}.joinToString(separator = "\n", prefix = "• ")
- paymentOptionsLabel.text =
+ ui.paymentOptionsLabel.text =
getString(R.string.withdraw_manual_payment_options,
exchangeItem.name, paymentOptions)
- checkFeesButton.setOnClickListener {
- val value = amountView.text.toString().toLong()
- val amount = Amount(exchangeItem.currency, value, 0)
- amountView.hideKeyboard()
- Toast.makeText(view.context, "Not implemented: $amount",
LENGTH_SHORT).show()
- withdrawManager.getWithdrawalDetails(exchangeItem.exchangeBaseUrl,
amount)
+ ui.checkFeesButton.setOnClickListener { onCheckFees() }
+ }
+
+ private fun onCheckFees() {
+ if (ui.amountView.text?.isEmpty() != false) {
+ ui.amountLayout.error = getString(R.string.withdraw_amount_error)
+ return
}
+ ui.amountLayout.error = null
+ val value = ui.amountView.text.toString().toLong()
+ val amount = Amount(exchangeItem.currency, value, 0)
+ ui.amountView.hideKeyboard()
+ Toast.makeText(requireContext(), "Not implemented: $amount",
LENGTH_SHORT).show()
+ withdrawManager.getWithdrawalDetails(exchangeItem.exchangeBaseUrl,
amount)
}
}
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 ffc64d4..0c7687c 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
@@ -24,17 +24,16 @@ import android.widget.Toast
import android.widget.Toast.LENGTH_SHORT
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
-import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
-import kotlinx.android.synthetic.main.fragment_prompt_withdraw.*
import net.taler.common.fadeIn
import net.taler.common.fadeOut
import net.taler.lib.common.Amount
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
import net.taler.wallet.cleanExchange
+import net.taler.wallet.databinding.FragmentPromptWithdrawBinding
import net.taler.wallet.withdraw.WithdrawStatus.Loading
import net.taler.wallet.withdraw.WithdrawStatus.TosReviewRequired
import net.taler.wallet.withdraw.WithdrawStatus.Withdrawing
@@ -44,17 +43,20 @@ class PromptWithdrawFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val withdrawManager by lazy { model.withdrawManager }
+ private lateinit var ui: FragmentPromptWithdrawBinding
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_prompt_withdraw, container,
false)
+ ui = FragmentPromptWithdrawBinding.inflate(inflater, container, false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- withdrawManager.withdrawStatus.observe(viewLifecycleOwner, Observer {
+ withdrawManager.withdrawStatus.observe(viewLifecycleOwner, {
showWithdrawStatus(it)
})
}
@@ -62,11 +64,11 @@ class PromptWithdrawFragment : Fragment() {
private fun showWithdrawStatus(status: WithdrawStatus?): Any = when
(status) {
is WithdrawStatus.ReceivedDetails -> {
showContent(status.amountRaw, status.amountEffective,
status.exchangeBaseUrl)
- confirmWithdrawButton.apply {
+ ui.confirmWithdrawButton.apply {
text = getString(R.string.withdraw_button_confirm)
setOnClickListener {
it.fadeOut()
- confirmProgressBar.fadeIn()
+ ui.confirmProgressBar.fadeIn()
withdrawManager.acceptWithdrawal()
}
isEnabled = true
@@ -87,7 +89,7 @@ class PromptWithdrawFragment : Fragment() {
}
is TosReviewRequired -> {
showContent(status.amountRaw, status.amountEffective,
status.exchangeBaseUrl)
- confirmWithdrawButton.apply {
+ ui.confirmWithdrawButton.apply {
text = getString(R.string.withdraw_button_tos)
setOnClickListener {
findNavController().navigate(R.id.action_promptWithdraw_to_reviewExchangeTOS)
@@ -104,29 +106,29 @@ class PromptWithdrawFragment : Fragment() {
private fun showContent(amountRaw: Amount, amountEffective: Amount,
exchange: String) {
model.showProgressBar.value = false
- progressBar.fadeOut()
+ ui.progressBar.fadeOut()
- introView.fadeIn()
- effectiveAmountView.text = amountEffective.toString()
- effectiveAmountView.fadeIn()
+ ui.introView.fadeIn()
+ ui.effectiveAmountView.text = amountEffective.toString()
+ ui.effectiveAmountView.fadeIn()
- chosenAmountLabel.fadeIn()
- chosenAmountView.text = amountRaw.toString()
- chosenAmountView.fadeIn()
+ ui.chosenAmountLabel.fadeIn()
+ ui.chosenAmountView.text = amountRaw.toString()
+ ui.chosenAmountView.fadeIn()
- feeLabel.fadeIn()
- feeView.text = getString(R.string.amount_negative, (amountRaw -
amountEffective).toString())
- feeView.fadeIn()
+ ui.feeLabel.fadeIn()
+ ui.feeView.text = getString(R.string.amount_negative, (amountRaw -
amountEffective).toString())
+ ui.feeView.fadeIn()
- exchangeIntroView.fadeIn()
- withdrawExchangeUrl.text = cleanExchange(exchange)
- withdrawExchangeUrl.fadeIn()
- selectExchangeButton.fadeIn()
- selectExchangeButton.setOnClickListener {
+ ui.exchangeIntroView.fadeIn()
+ ui.withdrawExchangeUrl.text = cleanExchange(exchange)
+ ui.withdrawExchangeUrl.fadeIn()
+ ui.selectExchangeButton.fadeIn()
+ ui.selectExchangeButton.setOnClickListener {
Toast.makeText(context, "Not yet implemented", LENGTH_SHORT).show()
}
- withdrawCard.fadeIn()
+ ui.withdrawCard.fadeIn()
}
}
diff --git
a/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt
index db1f326..73fe760 100644
---
a/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt
+++
b/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt
@@ -25,17 +25,19 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import io.noties.markwon.Markwon
-import kotlinx.android.synthetic.main.fragment_review_exchange_tos.*
import net.taler.common.fadeIn
import net.taler.common.fadeOut
import net.taler.wallet.MainViewModel
import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentReviewExchangeTosBinding
import java.text.ParseException
class ReviewExchangeTosFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
private val withdrawManager by lazy { model.withdrawManager }
+
+ private lateinit var ui: FragmentReviewExchangeTosBinding
private val markwon by lazy { Markwon.builder(requireContext()).build() }
private val adapter by lazy { TosAdapter(markwon) }
@@ -44,13 +46,14 @@ class ReviewExchangeTosFragment : Fragment() {
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_review_exchange_tos,
container, false)
+ ui = FragmentReviewExchangeTosBinding.inflate(inflater, container,
false)
+ return ui.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- acceptTosCheckBox.isChecked = false
- acceptTosCheckBox.setOnCheckedChangeListener { _, _ ->
+ ui.acceptTosCheckBox.isChecked = false
+ ui.acceptTosCheckBox.setOnCheckedChangeListener { _, _ ->
withdrawManager.acceptCurrentTermsOfService()
}
withdrawManager.withdrawStatus.observe(viewLifecycleOwner, Observer {
@@ -65,11 +68,11 @@ class ReviewExchangeTosFragment : Fragment() {
return@Observer
}
adapter.setSections(sections)
- tosList.adapter = adapter
- tosList.fadeIn()
+ ui.tosList.adapter = adapter
+ ui.tosList.fadeIn()
- acceptTosCheckBox.fadeIn()
- progressBar.fadeOut()
+ ui.acceptTosCheckBox.fadeIn()
+ ui.progressBar.fadeOut()
}
is WithdrawStatus.Loading -> {
findNavController().navigate(R.id.action_reviewExchangeTOS_to_promptWithdraw)
@@ -82,11 +85,11 @@ class ReviewExchangeTosFragment : Fragment() {
}
private fun onTosError(msg: String) {
- tosList.fadeIn()
- progressBar.fadeOut()
- buttonCard.fadeOut()
- errorView.text = getString(R.string.exchange_tos_error, "\n\n$msg")
- errorView.fadeIn()
+ ui.tosList.fadeIn()
+ ui.progressBar.fadeOut()
+ ui.buttonCard.fadeOut()
+ ui.errorView.text = getString(R.string.exchange_tos_error, "\n\n$msg")
+ ui.errorView.fadeIn()
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
index b6b4285..25c5b72 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
@@ -24,8 +24,8 @@ import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
import net.taler.lib.common.Amount
import net.taler.wallet.TAG
-import net.taler.wallet.backend.WalletBackendApi
import net.taler.wallet.backend.TalerErrorInfo
+import net.taler.wallet.backend.WalletBackendApi
import net.taler.wallet.exchanges.ExchangeFees
import net.taler.wallet.exchanges.ExchangeItem
import net.taler.wallet.withdraw.WithdrawStatus.ReceivedDetails
@@ -89,14 +89,11 @@ class WithdrawManager(
fun getWithdrawalDetails(uri: String) = scope.launch {
withdrawStatus.value = WithdrawStatus.Loading(uri)
- val response =
- api.request("getWithdrawalDetailsForUri",
WithdrawalDetailsForUri.serializer()) {
- put("talerWithdrawUri", uri)
- }
- response.onError { error ->
+ api.request("getWithdrawalDetailsForUri",
WithdrawalDetailsForUri.serializer()) {
+ put("talerWithdrawUri", uri)
+ }.onError { error ->
handleError("getWithdrawalDetailsForUri", error)
- }
- response.onSuccess { details ->
+ }.onSuccess { details ->
if (details.defaultExchangeBaseUrl == null) {
// TODO go to exchange selection screen instead
val chosenExchange =
details.possibleExchanges[0].exchangeBaseUrl
@@ -113,15 +110,12 @@ class WithdrawManager(
uri: String? = null
) = scope.launch {
withdrawStatus.value = WithdrawStatus.Loading(uri)
- val response =
- api.request("getWithdrawalDetailsForAmount",
WithdrawalDetails.serializer()) {
- put("exchangeBaseUrl", exchangeBaseUrl)
- put("amount", amount.toJSONString())
- }
- response.onError { error ->
+ api.request("getWithdrawalDetailsForAmount",
WithdrawalDetails.serializer()) {
+ put("exchangeBaseUrl", exchangeBaseUrl)
+ put("amount", amount.toJSONString())
+ }.onError { error ->
handleError("getWithdrawalDetailsForAmount", error)
- }
- response.onSuccess { details ->
+ }.onSuccess { details ->
if (details.tosAccepted) {
withdrawStatus.value = ReceivedDetails(
talerWithdrawUri = uri,
@@ -138,13 +132,11 @@ class WithdrawManager(
details: WithdrawalDetails,
uri: String?
) = scope.launch {
- val response = api.request("getExchangeTos", TosResponse.serializer())
{
+ api.request("getExchangeTos", TosResponse.serializer()) {
put("exchangeBaseUrl", exchangeBaseUrl)
- }
- response.onError {
+ }.onError {
handleError("getExchangeTos", it)
- }
- response.onSuccess {
+ }.onSuccess {
withdrawStatus.value = WithdrawStatus.TosReviewRequired(
talerWithdrawUri = uri,
exchangeBaseUrl = exchangeBaseUrl,
diff --git a/wallet/src/main/res/layout/activity_main.xml
b/wallet/src/main/res/layout/activity_main.xml
index 3879490..15e11fe 100644
--- a/wallet/src/main/res/layout/activity_main.xml
+++ b/wallet/src/main/res/layout/activity_main.xml
@@ -24,7 +24,8 @@
tools:openDrawer="start">
<include
- layout="@layout/app_bar_main"
+ android:id="@+id/content"
+ layout="@layout/app_content_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
diff --git a/wallet/src/main/res/layout/app_bar_main.xml
b/wallet/src/main/res/layout/app_content_main.xml
similarity index 100%
rename from wallet/src/main/res/layout/app_bar_main.xml
rename to wallet/src/main/res/layout/app_content_main.xml
diff --git a/wallet/src/main/res/layout/fragment_prompt_payment.xml
b/wallet/src/main/res/layout/fragment_prompt_payment.xml
index 8d8954d..8cfa3dd 100644
--- a/wallet/src/main/res/layout/fragment_prompt_payment.xml
+++ b/wallet/src/main/res/layout/fragment_prompt_payment.xml
@@ -22,23 +22,23 @@
tools:context=".payment.PromptPaymentFragment">
<include
- android:id="@+id/scrollView"
+ android:id="@+id/details"
layout="@layout/payment_details"
android:layout_width="0dp"
android:layout_height="0dp"
- app:layout_constraintBottom_toTopOf="@+id/bottomView"
+ app:layout_constraintBottom_toTopOf="@+id/bottom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
- android:id="@+id/bottomView"
+ android:id="@+id/bottom"
layout="@layout/payment_bottom_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/scrollView" />
+ app:layout_constraintTop_toBottomOf="@+id/details" />
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/wallet/src/main/res/layout/payment_bottom_bar.xml
b/wallet/src/main/res/layout/payment_bottom_bar.xml
index dbc60ae..496f2f3 100644
--- a/wallet/src/main/res/layout/payment_bottom_bar.xml
+++ b/wallet/src/main/res/layout/payment_bottom_bar.xml
@@ -17,6 +17,7 @@
<com.google.android.material.card.MaterialCardView
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:id="@+id/bottomView"
style="@style/BottomCard"
android:layout_width="0dp"
android:layout_height="wrap_content"
diff --git a/wallet/src/main/res/navigation/nav_graph.xml
b/wallet/src/main/res/navigation/nav_graph.xml
index 285fac9..d8ce5b2 100644
--- a/wallet/src/main/res/navigation/nav_graph.xml
+++ b/wallet/src/main/res/navigation/nav_graph.xml
@@ -89,8 +89,26 @@
tools:layout="@layout/fragment_transactions" />
<fragment
- android:id="@+id/nav_transactions_detail"
- android:name="net.taler.wallet.transactions.TransactionDetailFragment"
+ android:id="@+id/nav_transactions_detail_withdrawal"
+
android:name="net.taler.wallet.transactions.TransactionWithdrawalFragment"
+ android:label="@string/transactions_detail_title"
+ tools:layout="@layout/fragment_transaction_withdrawal" />
+
+ <fragment
+ android:id="@+id/nav_transactions_detail_payment"
+ android:name="net.taler.wallet.transactions.TransactionPaymentFragment"
+ android:label="@string/transactions_detail_title"
+ tools:layout="@layout/fragment_transaction_payment" />
+
+ <fragment
+ android:id="@+id/nav_transactions_detail_refund"
+ android:name="net.taler.wallet.transactions.TransactionRefundFragment"
+ android:label="@string/transactions_detail_title"
+ tools:layout="@layout/fragment_transaction_payment" />
+
+ <fragment
+ android:id="@+id/nav_transactions_detail_refresh"
+ android:name="net.taler.wallet.transactions.TransactionRefreshFragment"
android:label="@string/transactions_detail_title"
tools:layout="@layout/fragment_transaction_withdrawal" />
@@ -168,7 +186,19 @@
app:destination="@id/nav_pending_operations" />
<action
- android:id="@+id/action_nav_transaction_detail"
- app:destination="@id/nav_transactions_detail" />
+ android:id="@+id/action_nav_transactions_detail_withdrawal"
+ app:destination="@id/nav_transactions_detail_withdrawal" />
+
+ <action
+ android:id="@+id/action_nav_transactions_detail_payment"
+ app:destination="@id/nav_transactions_detail_payment" />
+
+ <action
+ android:id="@+id/action_nav_transactions_detail_refund"
+ app:destination="@id/nav_transactions_detail_refund" />
+
+ <action
+ android:id="@+id/action_nav_transactions_detail_refresh"
+ app:destination="@id/nav_transactions_detail_refresh" />
</navigation>
diff --git a/wallet/src/main/res/values/strings.xml
b/wallet/src/main/res/values/strings.xml
index a9f6c73..d49f5f7 100644
--- a/wallet/src/main/res/values/strings.xml
+++ b/wallet/src/main/res/values/strings.xml
@@ -54,6 +54,8 @@ GNU Taler is immune against many types of fraud, such as
phishing of credit card
<string name="menu">Menu</string>
<string name="or">or</string>
+ <string name="offline">Operation requires internet access. Please ensure
your internet connection works and try again.</string>
+
<string name="menu_settings">Settings</string>
<string name="menu_retry_pending_operations">Retry Pending
Operations</string>
@@ -113,6 +115,7 @@ GNU Taler is immune against many types of fraud, such as
phishing of credit card
<string name="withdraw_waiting_confirm">Waiting for confirmation</string>
<string name="withdraw_manual_title">Make a manual transfer to the
exchange</string>
<string name="withdraw_amount">How much to withdraw?</string>
+ <string name="withdraw_amount_error">Enter valid amount</string>
<string name="withdraw_manual_payment_options">Payment options supported
by %1$s:\n\n%2$s</string>
<string name="withdraw_manual_check_fees">Check fees</string>
<string name="withdraw_error_title">Withdrawal Error</string>
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-taler-android] branch master updated (36821f9 -> ce5a1d2),
gnunet <=
- [taler-taler-android] 01/06: Don't crash on empty manual withdrawal amount, gnunet, 2020/09/03
- [taler-taler-android] 02/06: [cashier] migrate to view binding as kotlin extensions are broken, gnunet, 2020/09/03
- [taler-taler-android] 06/06: [wallet] show different withdrawal error message when app is offline, gnunet, 2020/09/03
- [taler-taler-android] 05/06: [pos] make app work on API 24+, gnunet, 2020/09/03
- [taler-taler-android] 03/06: [pos] migrate to view binding, gnunet, 2020/09/03
- [taler-taler-android] 04/06: [wallet] migrate away from kotlin view extensions, gnunet, 2020/09/03