commit d10de2138f1359c1dd14af279fe367a3ce339893
parent 115d4e0da9e278e300be29634a7551072e356a82
Author: Iván Ávalos <avalos@disroot.org>
Date: Thu, 22 Aug 2024 11:28:10 +0200
[pos] UI/UX improvements
Diffstat:
11 files changed, 145 insertions(+), 22 deletions(-)
diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigManager.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigManager.kt
@@ -119,6 +119,11 @@ class ConfigManager(
}
@UiThread
+ fun reloadConfig() {
+ fetchConfig(config, true, config.hasPassword())
+ }
+
+ @UiThread
fun fetchConfig(config: Config, save: Boolean, savePassword: Boolean = false) {
mConfigUpdateResult.value = null
val configToSave = if (save) {
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
@@ -18,10 +18,16 @@ package net.taler.merchantpos.order
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.ViewGroup
+import android.widget.Toast
+import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.Lifecycle
import androidx.transition.TransitionManager.beginDelayedTransition
import net.taler.common.navigate
import net.taler.merchantpos.MainViewModel
@@ -52,6 +58,29 @@ class OrderFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+
+ requireActivity().addMenuProvider(object: MenuProvider {
+ override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
+ menuInflater.inflate(R.menu.order, menu)
+ }
+
+ override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
+ return when(menuItem.itemId) {
+ R.id.reload -> {
+ viewModel.configManager.reloadConfig()
+ Toast.makeText(
+ requireContext(),
+ getString(R.string.toast_reloading),
+ Toast.LENGTH_LONG,
+ ).show()
+ true
+ }
+
+ else -> false
+ }
+ }
+ }, viewLifecycleOwner, Lifecycle.State.RESUMED)
+
orderManager.currentOrderId.observe(viewLifecycleOwner) { orderId ->
val liveOrder = orderManager.getOrder(orderId)
onOrderSwitched(orderId, liveOrder)
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
@@ -26,9 +26,11 @@ import androidx.navigation.fragment.findNavController
import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_LONG
import com.google.android.material.snackbar.Snackbar
import net.taler.common.QrCodeManager.makeQrCode
+import net.taler.common.copyToClipBoard
import net.taler.common.fadeIn
import net.taler.common.fadeOut
import net.taler.common.navigate
+import net.taler.common.shareText
import net.taler.common.showError
import net.taler.lib.android.TalerNfcService.Companion.hasNfc
import net.taler.merchantpos.MainViewModel
@@ -80,12 +82,18 @@ class ProcessPaymentFragment : Fragment() {
return
}
if (payment.claimed) {
- ui.qrcodeView.fadeOut()
+ ui.qrcodeLayout.fadeOut()
ui.payIntroView.setText(R.string.payment_claimed)
} else {
payment.talerPayUri?.let {
ui.qrcodeView.setImageBitmap(makeQrCode(it))
- ui.qrcodeView.fadeIn()
+ ui.shareButton.setOnClickListener { _ ->
+ requireContext().shareText(it)
+ }
+ ui.copyButton.setOnClickListener { _ ->
+ copyToClipBoard(requireContext(), "Payment URI", it)
+ }
+ ui.qrcodeLayout.fadeIn()
ui.progressBar.fadeOut()
}
}
diff --git a/merchant-terminal/src/main/res/drawable/ic_menu_reload.xml b/merchant-terminal/src/main/res/drawable/ic_menu_reload.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ This file is part of GNU Taler
+ ~ (C) 2024 Taler Systems S.A.
+ ~
+ ~ GNU Taler is free software; you can redistribute it and/or modify it under the
+ ~ terms of the GNU General Public License as published by the Free Software
+ ~ Foundation; either version 3, or (at your option) any later version.
+ ~
+ ~ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ ~ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ ~ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU General Public License along with
+ ~ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="?attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
+
+ <path android:fillColor="@android:color/white" android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/>
+
+</vector>
diff --git a/merchant-terminal/src/main/res/layout/fragment_process_payment.xml b/merchant-terminal/src/main/res/layout/fragment_process_payment.xml
@@ -21,29 +21,59 @@
android:layout_height="match_parent"
tools:context=".payment.ProcessPaymentFragment">
- <ImageView
- android:id="@+id/qrcodeView"
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/qrcodeLayout"
android:layout_width="0dp"
android:layout_height="0dp"
- android:layout_margin="32dp"
- android:visibility="invisible"
+ android:layout_margin="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
- tools:ignore="ContentDescription"
- tools:src="@tools:sample/avatars"
- tools:visibility="visible" />
+ android:visibility="invisible"
+ tools:visibility="visible">
+
+ <ImageView
+ android:id="@+id/qrcodeView"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_margin="12dp"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/shareButton"
+ tools:ignore="ContentDescription"
+ tools:src="@tools:sample/avatars" />
+
+ <Button
+ android:id="@+id/shareButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/copyButton"
+ android:text="@string/share"/>
+
+ <Button
+ android:id="@+id/copyButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@id/shareButton"
+ android:text="@string/copy"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- app:layout_constraintBottom_toBottomOf="@+id/qrcodeView"
- app:layout_constraintEnd_toEndOf="@+id/qrcodeView"
- app:layout_constraintStart_toStartOf="@+id/qrcodeView"
- app:layout_constraintTop_toTopOf="@+id/qrcodeView" />
+ app:layout_constraintBottom_toBottomOf="@+id/qrcodeLayout"
+ app:layout_constraintEnd_toEndOf="@+id/qrcodeLayout"
+ app:layout_constraintStart_toStartOf="@+id/qrcodeLayout"
+ app:layout_constraintTop_toTopOf="@+id/qrcodeLayout" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
diff --git a/merchant-terminal/src/main/res/menu/order.xml b/merchant-terminal/src/main/res/menu/order.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ This file is part of GNU Taler
+ ~ (C) 2024 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/>
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+ <item
+ android:id="@+id/reload"
+ android:icon="@drawable/ic_menu_reload"
+ android:title="@string/menu_reload"
+ app:showAsAction="ifRoom" />
+</menu>
+\ No newline at end of file
diff --git a/merchant-terminal/src/main/res/values/strings.xml b/merchant-terminal/src/main/res/values/strings.xml
@@ -6,6 +6,7 @@
<string name="menu_order">Orders</string>
<string name="menu_history">History</string>
<string name="menu_settings">Settings</string>
+ <string name="menu_reload">Reload</string>
<string name="order_label_title">Order #%s</string>
<!-- The placeholder is the total order amount with currency -->
@@ -79,6 +80,7 @@
<string name="error_cancelled">Payment cancelled</string>
<string name="error_history">Error fetching the order history</string>
+ <string name="toast_reloading">Reloading inventory</string>
<string name="toast_back_to_exit">Click «back» again to exit</string>
<string name="host_apdu_service_desc">Taler Merchant NFC payments</string>
diff --git a/taler-kotlin-android/src/main/java/net/taler/common/AndroidUtils.kt b/taler-kotlin-android/src/main/java/net/taler/common/AndroidUtils.kt
@@ -18,6 +18,8 @@ package net.taler.common
import android.Manifest.permission.ACCESS_NETWORK_STATE
import android.content.ActivityNotFoundException
+import android.content.ClipData
+import android.content.ClipboardManager
import android.content.Context
import android.content.Context.CONNECTIVITY_SERVICE
import android.content.Intent
@@ -46,6 +48,7 @@ import android.view.inputmethod.InputMethodManager
import androidx.annotation.RequiresPermission
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat.getSystemService
+import androidx.core.content.getSystemService
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.navigation.NavDirections
@@ -201,3 +204,9 @@ fun Version.getIncompatibleStringOrNull(context: Context, otherVersion: String):
if (match.currentCmp > 0) return context.getString(R.string.version_too_new)
throw AssertionError("$this == $other")
}
+
+fun copyToClipBoard(context: Context, label: String, str: String) {
+ val clipboard = context.getSystemService<ClipboardManager>()
+ val clip = ClipData.newPlainText(label, str)
+ clipboard?.setPrimaryClip(clip)
+}
+\ No newline at end of file
diff --git a/taler-kotlin-android/src/main/res/values/strings.xml b/taler-kotlin-android/src/main/res/values/strings.xml
@@ -21,4 +21,5 @@
<string name="close">Close</string>
<string name="share">Share</string>
+ <string name="copy">Copy</string>
</resources>
diff --git a/wallet/src/main/java/net/taler/wallet/compose/ExpandableCard.kt b/wallet/src/main/java/net/taler/wallet/compose/ExpandableCard.kt
@@ -27,7 +27,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.KeyboardArrowDown
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedCard
@@ -43,7 +42,6 @@ import androidx.compose.ui.draw.rotate
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ExpandableCard(
modifier: Modifier = Modifier,
diff --git a/wallet/src/main/java/net/taler/wallet/compose/QrCodeUriComposable.kt b/wallet/src/main/java/net/taler/wallet/compose/QrCodeUriComposable.kt
@@ -51,8 +51,8 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.min
-import androidx.core.content.getSystemService
import net.taler.common.QrCodeManager
+import net.taler.common.copyToClipBoard
import net.taler.wallet.R
@Composable
@@ -148,9 +148,3 @@ fun CopyToClipboardButton(
Text(buttonText)
}
}
-
-fun copyToClipBoard(context: Context, label: String, str: String) {
- val clipboard = context.getSystemService<ClipboardManager>()
- val clip = ClipData.newPlainText(label, str)
- clipboard?.setPrimaryClip(clip)
-}