summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2020-02-03 12:27:34 -0300
committerTorsten Grote <t@grobox.de>2020-02-03 12:27:34 -0300
commit163f1311116d4019a144d1cd98270a4e2fe1fd77 (patch)
treed5532d0bd16d4f4ba606d454c453d3cc52270fc9
parentf5740d3c47993577796c43fac068fff9141af3a2 (diff)
downloadmerchant-terminal-android-163f1311116d4019a144d1cd98270a4e2fe1fd77.tar.gz
merchant-terminal-android-163f1311116d4019a144d1cd98270a4e2fe1fd77.tar.bz2
merchant-terminal-android-163f1311116d4019a144d1cd98270a4e2fe1fd77.zip
Require valid configuration before showing UI
-rw-r--r--app/src/main/java/net/taler/merchantpos/MainActivity.kt22
-rw-r--r--app/src/main/java/net/taler/merchantpos/MainViewModel.kt2
-rw-r--r--app/src/main/java/net/taler/merchantpos/MerchantHistory.kt210
-rw-r--r--app/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt46
-rw-r--r--app/src/main/java/net/taler/merchantpos/config/MerchantConfig.kt4
-rw-r--r--app/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt6
-rw-r--r--app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt10
-rw-r--r--app/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt9
-rw-r--r--app/src/main/java/net/taler/merchantpos/payment/PaymentSuccess.kt30
-rw-r--r--app/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt27
-rw-r--r--app/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt1
-rw-r--r--app/src/main/res/layout/activity_main.xml1
-rw-r--r--app/src/main/res/layout/content_main.xml4
-rw-r--r--app/src/main/res/layout/fragment_config_fetcher.xml29
-rw-r--r--app/src/main/res/layout/fragment_order.xml1
-rw-r--r--app/src/main/res/navigation/nav_graph.xml66
-rw-r--r--app/src/main/res/values/strings.xml1
17 files changed, 297 insertions, 172 deletions
diff --git a/app/src/main/java/net/taler/merchantpos/MainActivity.kt b/app/src/main/java/net/taler/merchantpos/MainActivity.kt
index 9841339..e26146d 100644
--- a/app/src/main/java/net/taler/merchantpos/MainActivity.kt
+++ b/app/src/main/java/net/taler/merchantpos/MainActivity.kt
@@ -10,7 +10,7 @@ import androidx.core.view.GravityCompat.START
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.Observer
import androidx.navigation.NavController
-import androidx.navigation.findNavController
+import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.navigation.NavigationView
@@ -22,6 +22,7 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener {
private val nfcManager = NfcManager()
private var nfcAdapter: NfcAdapter? = null
+ private lateinit var nav: NavController
private lateinit var drawerLayout: DrawerLayout
override fun onCreate(savedInstanceState: Bundle?) {
@@ -40,10 +41,7 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener {
drawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
-
navView.setNavigationItemSelectedListener(this)
-
- val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.order,
@@ -51,7 +49,20 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener {
R.id.merchantHistory
), drawerLayout
)
- toolbar.setupWithNavController(navController, appBarConfiguration)
+
+ val navHostFragment =
+ supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
+ nav = navHostFragment.navController
+ toolbar.setupWithNavController(nav, appBarConfiguration)
+ }
+
+ override fun onStart() {
+ super.onStart()
+ if (!model.configManager.config.isValid()) {
+ nav.navigate(R.id.action_global_merchantSettings)
+ } else if (model.configManager.merchantConfig == null) {
+ nav.navigate(R.id.action_global_configFetcher)
+ }
}
public override fun onResume() {
@@ -67,7 +78,6 @@ class MainActivity : AppCompatActivity(), OnNavigationItemSelectedListener {
override fun onNavigationItemSelected(item: MenuItem): Boolean {
// Handle navigation view item clicks here.
- val nav: NavController = findNavController(R.id.nav_host_fragment)
when (item.itemId) {
R.id.nav_order -> nav.navigate(R.id.action_global_order)
R.id.nav_history -> nav.navigate(R.id.action_global_merchantHistory)
diff --git a/app/src/main/java/net/taler/merchantpos/MainViewModel.kt b/app/src/main/java/net/taler/merchantpos/MainViewModel.kt
index c07c996..c14ab66 100644
--- a/app/src/main/java/net/taler/merchantpos/MainViewModel.kt
+++ b/app/src/main/java/net/taler/merchantpos/MainViewModel.kt
@@ -29,7 +29,7 @@ class MainViewModel(app: Application) : AndroidViewModel(app) {
get() = configManager.merchantConfig
init {
- if (configManager.merchantConfig == null) {
+ if (configManager.merchantConfig == null && configManager.config.isValid()) {
configManager.fetchConfig(configManager.config, false)
}
}
diff --git a/app/src/main/java/net/taler/merchantpos/MerchantHistory.kt b/app/src/main/java/net/taler/merchantpos/MerchantHistory.kt
index 167bb9d..eb8288c 100644
--- a/app/src/main/java/net/taler/merchantpos/MerchantHistory.kt
+++ b/app/src/main/java/net/taler/merchantpos/MerchantHistory.kt
@@ -1,6 +1,5 @@
package net.taler.merchantpos
-
import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
@@ -11,85 +10,42 @@ import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
+import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.DividerItemDecoration
+import androidx.recyclerview.widget.DividerItemDecoration.VERTICAL
import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-import com.android.volley.Request
+import androidx.recyclerview.widget.RecyclerView.Adapter
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import com.android.volley.Request.Method.GET
import com.android.volley.RequestQueue
-import com.android.volley.Response
-import com.android.volley.VolleyError
+import com.android.volley.Response.ErrorListener
+import com.android.volley.Response.Listener
import com.android.volley.toolbox.Volley
import com.google.android.material.snackbar.Snackbar
+import com.google.android.material.snackbar.Snackbar.LENGTH_SHORT
+import kotlinx.android.synthetic.main.fragment_merchant_history.*
+import net.taler.merchantpos.HistoryItemAdapter.HistoryItemViewHolder
import net.taler.merchantpos.config.MerchantRequest
import org.json.JSONObject
import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
-import java.time.format.FormatStyle
+import java.time.format.FormatStyle.SHORT
import java.util.*
-
-
-data class HistoryItem(
- val orderId: String,
- val amount: Amount,
- val summary: String,
- val timestamp: Instant
-)
-
-class MyAdapter(private var myDataset: List<HistoryItem>) :
- RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
- val view =
- LayoutInflater.from(parent.context).inflate(R.layout.history_row, parent, false)
- return MyViewHolder(view)
- }
-
- override fun getItemCount(): Int {
- return myDataset.size
- }
-
- override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
- val item = myDataset[position]
- val summaryTextView = holder.rowView.findViewById<TextView>(R.id.text_history_summary)
- summaryTextView.text = myDataset[position].summary
-
- val amount = myDataset[position].amount
- val amountTextView = holder.rowView.findViewById<TextView>(R.id.text_history_amount)
- @SuppressLint("SetTextI18n")
- amountTextView.text = "${amount.amount} ${amount.currency}"
-
- val formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
- .withLocale(Locale.UK)
- .withZone(ZoneId.systemDefault())
- val timestampTextView = holder.rowView.findViewById<TextView>(R.id.text_history_time)
- timestampTextView.text = formatter.format(item.timestamp)
-
- val orderIdTextView = holder.rowView.findViewById<TextView>(R.id.text_history_order_id)
- orderIdTextView.text = item.orderId
- }
-
- fun setData(dataset: List<HistoryItem>) {
- this.myDataset = dataset
- this.notifyDataSetChanged()
- }
-
- class MyViewHolder(val rowView: View) : RecyclerView.ViewHolder(rowView)
-}
-
-fun parseTalerTimestamp(s: String): Instant {
- return Instant.ofEpochSecond(s.substringAfterLast('(').substringBeforeLast(')').toLong())
-}
-
/**
* Fragment to display the merchant's payment history,
* received from the backend.
*/
class MerchantHistory : Fragment() {
+
+ companion object {
+ const val TAG = "taler-merchant"
+ }
+
private lateinit var queue: RequestQueue
private val model: MainViewModel by activityViewModels()
- private val historyListAdapter = MyAdapter(listOf())
+ private val historyListAdapter = HistoryItemAdapter(listOf())
private val isLoading = MutableLiveData<Boolean>().apply { value = false }
@@ -99,10 +55,49 @@ class MerchantHistory : Fragment() {
queue = Volley.newRequestQueue(context)
}
- private fun onNetworkError(volleyError: VolleyError?) {
- this.isLoading.value = false
- val mySnackbar = Snackbar.make(view!!, "Network Error", Snackbar.LENGTH_SHORT)
- mySnackbar.show()
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.fragment_merchant_history, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ list_history.apply {
+ layoutManager = LinearLayoutManager(requireContext())
+ addItemDecoration(DividerItemDecoration(context, VERTICAL))
+ adapter = historyListAdapter
+ }
+
+ swiperefresh.isRefreshing = false
+ swiperefresh.setOnRefreshListener {
+ Log.v(TAG, "refreshing!")
+ fetchHistory()
+ }
+
+ this.isLoading.observe(viewLifecycleOwner, androidx.lifecycle.Observer { loading ->
+ Log.v(TAG, "setting refreshing to $loading")
+ swiperefresh.isRefreshing = loading
+ })
+ }
+
+ override fun onStart() {
+ super.onStart()
+ if (model.configManager.merchantConfig?.instance == null) {
+ findNavController().navigate(R.id.action_global_merchantSettings)
+ } else {
+ fetchHistory()
+ }
+ }
+
+ private fun fetchHistory() {
+ isLoading.value = true
+ val merchantConfig = model.configManager.merchantConfig!!
+ val params = mapOf("instance" to merchantConfig.instance)
+ val req = MerchantRequest(GET, merchantConfig, "history", params, null,
+ Listener { onHistoryResponse(it) },
+ ErrorListener { onNetworkError() })
+ queue.add(req)
}
private fun onHistoryResponse(body: JSONObject) {
@@ -123,55 +118,56 @@ class MerchantHistory : Fragment() {
historyListAdapter.setData(data)
}
- private fun fetchHistory() {
- isLoading.value = true
- val instance = model.merchantConfig!!.instance
- val req = MerchantRequest(
- Request.Method.GET,
- model.merchantConfig!!,
- "history",
- mapOf("instance" to instance),
- null,
- Response.Listener { onHistoryResponse(it) },
- Response.ErrorListener { onNetworkError(it) })
- queue.add(req)
+ private fun onNetworkError() {
+ this.isLoading.value = false
+ Snackbar.make(view!!, "Network Error", LENGTH_SHORT).show()
}
- override fun onResume() {
- super.onResume()
- fetchHistory()
- }
+}
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- val myLayoutManager = LinearLayoutManager(this@MerchantHistory.context)
- val myItemDecoration = DividerItemDecoration(context, myLayoutManager.orientation)
- // Inflate the layout for this fragment
- val view = inflater.inflate(R.layout.fragment_merchant_history, container, false)
- view.findViewById<RecyclerView>(R.id.list_history).apply {
- layoutManager = myLayoutManager
- adapter = historyListAdapter
- addItemDecoration(myItemDecoration)
- }
+data class HistoryItem(
+ val orderId: String,
+ val amount: Amount,
+ val summary: String,
+ val timestamp: Instant
+)
- val refreshLayout = view.findViewById<SwipeRefreshLayout>(R.id.swiperefresh)
- refreshLayout.isRefreshing = false
- refreshLayout.setOnRefreshListener {
- Log.v(TAG, "refreshing!")
- fetchHistory()
- }
+class HistoryItemAdapter(private var items: List<HistoryItem>) : Adapter<HistoryItemViewHolder>() {
- this.isLoading.observe(viewLifecycleOwner, androidx.lifecycle.Observer { loading ->
- Log.v(TAG, "setting refreshing to $loading")
- refreshLayout.isRefreshing = loading
- })
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HistoryItemViewHolder {
+ val v = LayoutInflater.from(parent.context).inflate(R.layout.history_row, parent, false)
+ return HistoryItemViewHolder(v)
+ }
- return view
+ override fun getItemCount() = items.size
+
+ override fun onBindViewHolder(holder: HistoryItemViewHolder, position: Int) {
+ holder.bind(items[position])
}
- companion object {
- const val TAG = "taler-merchant"
+ fun setData(items: List<HistoryItem>) {
+ this.items = items
+ this.notifyDataSetChanged()
}
+
+ class HistoryItemViewHolder(v: View) : ViewHolder(v) {
+
+ private val summaryTextView: TextView = v.findViewById(R.id.text_history_summary)
+ private val amountTextView: TextView = v.findViewById(R.id.text_history_amount)
+ private val timestampTextView: TextView = v.findViewById(R.id.text_history_time)
+ private val orderIdTextView: TextView = v.findViewById(R.id.text_history_order_id)
+ private val formatter: DateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(SHORT)
+ .withLocale(Locale.getDefault())
+ .withZone(ZoneId.systemDefault())
+
+ fun bind(item: HistoryItem) {
+ summaryTextView.text = item.summary
+ val amount = item.amount
+ @SuppressLint("SetTextI18n")
+ amountTextView.text = "${amount.amount} ${amount.currency}"
+ timestampTextView.text = formatter.format(item.timestamp)
+ orderIdTextView.text = item.orderId
+ }
+ }
+
}
diff --git a/app/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt b/app/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt
new file mode 100644
index 0000000..4d387da
--- /dev/null
+++ b/app/src/main/java/net/taler/merchantpos/config/ConfigFetcherFragment.kt
@@ -0,0 +1,46 @@
+package net.taler.merchantpos.config
+
+import android.os.Bundle
+import android.view.LayoutInflater
+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.Snackbar
+import com.google.android.material.snackbar.Snackbar.LENGTH_SHORT
+import net.taler.merchantpos.MainViewModel
+import net.taler.merchantpos.R
+
+class ConfigFetcherFragment : Fragment() {
+
+ private val model: MainViewModel by activityViewModels()
+ private val configManager by lazy { model.configManager }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.fragment_config_fetcher, container, false)
+ }
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+
+ configManager.configUpdateResult.observe(viewLifecycleOwner, Observer { result ->
+ when {
+ result == null -> return@Observer
+ result.error -> onNetworkError(result.authError)
+ else -> findNavController().navigate(R.id.order)
+ }
+ })
+ }
+
+ private fun onNetworkError(authError: Boolean) {
+ val res = if (authError) R.string.config_auth_error else R.string.config_error
+ Snackbar.make(view!!, res, LENGTH_SHORT).show()
+ findNavController().navigate(R.id.action_configFetcher_to_merchantSettings)
+ }
+
+}
diff --git a/app/src/main/java/net/taler/merchantpos/config/MerchantConfig.kt b/app/src/main/java/net/taler/merchantpos/config/MerchantConfig.kt
index 63dd487..c237a24 100644
--- a/app/src/main/java/net/taler/merchantpos/config/MerchantConfig.kt
+++ b/app/src/main/java/net/taler/merchantpos/config/MerchantConfig.kt
@@ -7,7 +7,9 @@ data class Config(
val configUrl: String,
val username: String,
val password: String
-)
+) {
+ fun isValid() = !configUrl.isBlank()
+}
data class MerchantConfig(
@JsonProperty("base_url")
diff --git a/app/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt b/app/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt
index b824d38..27e22ad 100644
--- a/app/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt
+++ b/app/src/main/java/net/taler/merchantpos/config/MerchantConfigFragment.kt
@@ -8,6 +8,7 @@ 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.Snackbar
import com.google.android.material.snackbar.Snackbar.LENGTH_SHORT
import kotlinx.android.synthetic.main.fragment_merchant_settings.*
@@ -51,10 +52,6 @@ class MerchantConfigFragment : Fragment() {
configManager.configUpdateResult.removeObservers(viewLifecycleOwner)
})
}
- }
-
- override fun onStart() {
- super.onStart()
updateView()
}
@@ -85,6 +82,7 @@ class MerchantConfigFragment : Fragment() {
onResultReceived()
updateView()
Snackbar.make(view!!, "Changed to new $currency merchant", LENGTH_SHORT).show()
+ findNavController().navigate(R.id.order)
}
private fun onNetworkError(authError: Boolean) {
diff --git a/app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt b/app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
index f4c5a15..99f6c57 100644
--- a/app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
+++ b/app/src/main/java/net/taler/merchantpos/order/OrderFragment.kt
@@ -35,9 +35,11 @@ class OrderFragment : Fragment() {
if (state == UNDO) {
restartButton.setText(R.string.order_undo)
restartButton.isEnabled = true
+ completeButton.isEnabled = false
} else {
restartButton.setText(R.string.order_restart)
restartButton.isEnabled = state == ENABLED
+ completeButton.isEnabled = state == ENABLED
}
})
}
@@ -45,13 +47,13 @@ class OrderFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val nav: NavController = findNavController(requireActivity(), R.id.nav_host_fragment)
- reconfigureButton.setOnClickListener { nav.navigate(R.id.action_global_merchantSettings) }
- historyButton.setOnClickListener { nav.navigate(R.id.action_global_merchantHistory) }
- logoutButton.setOnClickListener { nav.navigate(R.id.action_global_merchantSettings) }
+ reconfigureButton.setOnClickListener { nav.navigate(R.id.action_order_to_merchantSettings) }
+ historyButton.setOnClickListener { nav.navigate(R.id.action_order_to_merchantHistory) }
+ logoutButton.setOnClickListener { nav.navigate(R.id.action_order_to_merchantSettings) }
completeButton.setOnClickListener {
val order = orderManager.order.value ?: return@setOnClickListener
paymentManager.createPayment(order)
- nav.navigate(R.id.action_createPayment_to_processPayment)
+ nav.navigate(R.id.action_order_to_processPayment)
}
}
diff --git a/app/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt b/app/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt
index bb030e2..3e6ee2c 100644
--- a/app/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt
+++ b/app/src/main/java/net/taler/merchantpos/payment/PaymentManager.kt
@@ -32,7 +32,7 @@ class PaymentManager(
) {
private val mPayment = MutableLiveData<Payment>()
- var payment: LiveData<Payment> = mPayment
+ val payment: LiveData<Payment> = mPayment
private val checkTimer = object : CountDownTimer(TIMEOUT, CHECK_INTERVAL) {
override fun onTick(millisUntilFinished: Long) {
@@ -111,12 +111,13 @@ class PaymentManager(
* Called when the /check-payment response gave a result.
*/
private fun onPaymentChecked(checkPaymentResponse: JSONObject) {
+ val currentValue = requireNotNull(mPayment.value)
if (checkPaymentResponse.getBoolean("paid")) {
- mPayment.value = mPayment.value!!.copy(paid = true)
+ mPayment.value = currentValue.copy(paid = true)
checkTimer.cancel()
- } else {
+ } else if (currentValue.talerPayUri == null) {
val talerPayUri = checkPaymentResponse.getString("taler_pay_uri")
- mPayment.value = mPayment.value!!.copy(talerPayUri = talerPayUri)
+ mPayment.value = currentValue.copy(talerPayUri = talerPayUri)
}
}
diff --git a/app/src/main/java/net/taler/merchantpos/payment/PaymentSuccess.kt b/app/src/main/java/net/taler/merchantpos/payment/PaymentSuccess.kt
deleted file mode 100644
index c62abbc..0000000
--- a/app/src/main/java/net/taler/merchantpos/payment/PaymentSuccess.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package net.taler.merchantpos.payment
-
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.Button
-import androidx.fragment.app.Fragment
-import androidx.navigation.findNavController
-import net.taler.merchantpos.R
-
-/**
- * A simple [Fragment] subclass.
- */
-class PaymentSuccess : Fragment() {
-
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- val view = inflater.inflate(R.layout.fragment_payment_success, container, false)
- view.findViewById<Button>(R.id.button_success_back).setOnClickListener {
- activity!!.findNavController(R.id.nav_host_fragment).navigateUp()
- }
- return view
- }
-
-
-}
diff --git a/app/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt b/app/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt
new file mode 100644
index 0000000..176b6fc
--- /dev/null
+++ b/app/src/main/java/net/taler/merchantpos/payment/PaymentSuccessFragment.kt
@@ -0,0 +1,27 @@
+package net.taler.merchantpos.payment
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.navigation.findNavController
+import kotlinx.android.synthetic.main.fragment_payment_success.*
+import net.taler.merchantpos.R
+
+class PaymentSuccessFragment : Fragment() {
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.fragment_payment_success, container, false)
+ }
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ button_success_back.setOnClickListener {
+ requireActivity().findNavController(R.id.nav_host_fragment).navigateUp()
+ }
+ }
+}
diff --git a/app/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt b/app/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt
index 67a913f..4a235da 100644
--- a/app/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt
+++ b/app/src/main/java/net/taler/merchantpos/payment/ProcessPaymentFragment.kt
@@ -50,6 +50,7 @@ class ProcessPaymentFragment : Fragment() {
}
if (payment.paid) {
findNavController().navigate(R.id.action_processPayment_to_paymentSuccess)
+ model.orderManager.restartOrUndo()
return
}
text_view_amount.text = "${payment.order.getTotalAsString()} ${payment.currency}"
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index f67c32c..5f21a42 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -20,6 +20,7 @@
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
+ app:menu="@menu/activity_main_drawer"
app:headerLayout="@layout/nav_header_main" />
</androidx.drawerlayout.widget.DrawerLayout>
diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml
index 112382e..a87cf40 100644
--- a/app/src/main/res/layout/content_main.xml
+++ b/app/src/main/res/layout/content_main.xml
@@ -9,7 +9,7 @@
tools:showIn="@layout/app_bar_main"
tools:context=".MainActivity">
- <fragment
+ <androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
@@ -21,4 +21,4 @@
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_config_fetcher.xml b/app/src/main/res/layout/fragment_config_fetcher.xml
new file mode 100644
index 0000000..e00a307
--- /dev/null
+++ b/app/src/main/res/layout/fragment_config_fetcher.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="16dp">
+
+ <TextView
+ android:id="@+id/titleView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="16dp"
+ android:text="@string/config_fetching"
+ android:textAppearance="@style/TextAppearance.AppCompat.Headline"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+ <ProgressBar
+ android:id="@+id/progressBar"
+ style="?android:attr/progressBarStyleLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="16dp"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/titleView" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/fragment_order.xml b/app/src/main/res/layout/fragment_order.xml
index 968544e..bcf8be8 100644
--- a/app/src/main/res/layout/fragment_order.xml
+++ b/app/src/main/res/layout/fragment_order.xml
@@ -89,6 +89,7 @@
android:layout_marginStart="16dp"
android:backgroundTint="@color/logoutButton"
android:text="@string/button_logout"
+ android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/historyButton" />
diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml
index a1c0d8d..f615ba2 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -11,27 +11,67 @@
android:label="Order"
tools:layout="@layout/fragment_order">
<action
- android:id="@+id/action_createPayment_to_processPayment"
+ android:id="@+id/action_order_to_processPayment"
app:destination="@id/processPayment" />
+ <action
+ android:id="@+id/action_order_to_merchantHistory"
+ app:destination="@id/merchantHistory" />
+ <action
+ android:id="@+id/action_order_to_merchantSettings"
+ app:destination="@id/merchantSettings" />
</fragment>
- <fragment android:id="@+id/processPayment" android:name="net.taler.merchantpos.payment.ProcessPaymentFragment"
- android:label="Payment Prompt" tools:layout="@layout/fragment_process_payment">
+ <fragment
+ android:id="@+id/processPayment"
+ android:name="net.taler.merchantpos.payment.ProcessPaymentFragment"
+ android:label="Payment Prompt"
+ tools:layout="@layout/fragment_process_payment">
<action
android:id="@+id/action_processPayment_to_paymentSuccess"
app:destination="@id/paymentSuccess"
- app:popUpTo="@id/order"/>
+ app:popUpTo="@id/order" />
+ </fragment>
+
+ <fragment
+ android:id="@+id/merchantHistory"
+ android:name="net.taler.merchantpos.MerchantHistory"
+ android:label="Payment History"
+ tools:layout="@layout/fragment_merchant_history" />
+
+ <fragment
+ android:id="@+id/merchantSettings"
+ android:name="net.taler.merchantpos.config.MerchantConfigFragment"
+ android:label="Merchant Settings"
+ tools:layout="@layout/fragment_merchant_settings"/>
+
+ <fragment
+ android:id="@+id/configFetcher"
+ android:name="net.taler.merchantpos.config.ConfigFetcherFragment"
+ android:label="Fetching Configuration"
+ tools:layout="@layout/fragment_config_fetcher">
+ <action
+ android:id="@+id/action_configFetcher_to_merchantSettings"
+ app:destination="@id/merchantSettings"
+ app:popUpToInclusive="true" />
</fragment>
- <fragment android:id="@+id/merchantHistory" android:name="net.taler.merchantpos.MerchantHistory"
- android:label="Payment History" tools:layout="@layout/fragment_merchant_history"/>
- <action android:id="@+id/action_global_merchantHistory" app:destination="@id/merchantHistory"/>
- <action android:id="@+id/action_global_order" app:destination="@id/order"/>
- <fragment android:id="@+id/merchantSettings" android:name="net.taler.merchantpos.config.MerchantConfigFragment"
- android:label="Merchant Settings" tools:layout="@layout/fragment_merchant_settings"/>
- <action android:id="@+id/action_global_merchantSettings" app:destination="@id/merchantSettings"/>
+
<fragment
android:id="@+id/paymentSuccess"
- android:name="net.taler.merchantpos.payment.PaymentSuccess"
+ android:name="net.taler.merchantpos.payment.PaymentSuccessFragment"
android:label="Payment Received"
tools:layout="@layout/fragment_payment_success" />
-</navigation> \ No newline at end of file
+
+ <action
+ android:id="@+id/action_global_order"
+ app:destination="@id/order" />
+ <action
+ android:id="@+id/action_global_merchantHistory"
+ app:destination="@id/merchantHistory" />
+ <action
+ android:id="@+id/action_global_merchantSettings"
+ app:destination="@id/merchantSettings" />
+ <action
+ android:id="@+id/action_global_configFetcher"
+ app:destination="@id/configFetcher" />
+
+</navigation>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f179915..8e5511e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -33,5 +33,6 @@
<string name="config_malformed_url">Invalid URL</string>
<string name="config_auth_error">Invalid username or password</string>
<string name="config_error">Error: Invalid Configuration</string>
+ <string name="config_fetching">Fetching Configuration…</string>
</resources>