diff options
author | Torsten Grote <t@grobox.de> | 2020-02-03 12:27:34 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2020-02-03 12:27:34 -0300 |
commit | 163f1311116d4019a144d1cd98270a4e2fe1fd77 (patch) | |
tree | d5532d0bd16d4f4ba606d454c453d3cc52270fc9 | |
parent | f5740d3c47993577796c43fac068fff9141af3a2 (diff) | |
download | merchant-terminal-android-163f1311116d4019a144d1cd98270a4e2fe1fd77.tar.gz merchant-terminal-android-163f1311116d4019a144d1cd98270a4e2fe1fd77.tar.bz2 merchant-terminal-android-163f1311116d4019a144d1cd98270a4e2fe1fd77.zip |
Require valid configuration before showing UI
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> |