taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

commit cfa70e9f16db71aaae64798c8656961f7bcb7a6d
parent b5b77ef3b0aec393071e94843433eff49bd46495
Author: Bohdan Potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date:   Sat,  4 Jul 2026 07:54:58 +0200

[pos] finally? fix auto-screenshoting hopefully

Diffstat:
Mmerchant-terminal/scripts/capture-screenshots.sh | 27+++++++++++++++++++--------
Mmerchant-terminal/src/debug/java/net/taler/merchantpos/debug/ScreenshotActivity.kt | 51+++++++++++++++++++++++++++++++++------------------
Mmerchant-terminal/src/main/res/values-de/strings.xml | 3+++
Mmerchant-terminal/src/main/res/values-fr/strings.xml | 3+++
Mmerchant-terminal/src/main/res/values/strings.xml | 3+++
5 files changed, 61 insertions(+), 26 deletions(-)

diff --git a/merchant-terminal/scripts/capture-screenshots.sh b/merchant-terminal/scripts/capture-screenshots.sh @@ -13,9 +13,12 @@ else SCENARIOS=("login" "mfa-select" "mfa-code" "amount-entry" "order" "order-custom" "order-custom-added" "payment" "payment-success" "history" "refund" "refund-qr" "navigation") fi +LOCALES=("en" "de" "fr") + APP_ID="net.taler.merchantpos" ACTIVITY="$APP_ID/.debug.ScreenshotActivity" EXTRA_KEY="screenshot_scenario" +EXTRA_LOCALE_KEY="screenshot_locale" LOGCAT_TAG="SCREENSHOT_READY" WAIT_TIMEOUT=30 BOOTED_EMULATOR="" @@ -129,14 +132,22 @@ wait_for_ready() { "$REPO_ROOT/gradlew" :merchant-terminal:installDebug -for scenario in "${SCENARIOS[@]}"; do - echo "Capturing $scenario" - "${ADB[@]}" shell am force-stop "$APP_ID" >/dev/null 2>&1 || true - "${ADB[@]}" logcat -c 2>/dev/null || true - "${ADB[@]}" shell am start -W -n "$ACTIVITY" --es "$EXTRA_KEY" "$scenario" >/dev/null - wait_for_ready "$scenario" "$WAIT_TIMEOUT" - sleep 3 - "${ADB[@]}" exec-out screencap -p > "$OUT_DIR/$scenario.png" +for locale in "${LOCALES[@]}"; do + LOCALE_DIR="$OUT_DIR/$locale" + mkdir -p "$LOCALE_DIR" + echo "=== Locale: $locale ===" + + for scenario in "${SCENARIOS[@]}"; do + echo " Capturing $scenario ($locale)" + "${ADB[@]}" shell am force-stop "$APP_ID" >/dev/null 2>&1 || true + "${ADB[@]}" logcat -c 2>/dev/null || true + "${ADB[@]}" shell am start -W -n "$ACTIVITY" \ + --es "$EXTRA_KEY" "$scenario" \ + --es "$EXTRA_LOCALE_KEY" "$locale" >/dev/null + wait_for_ready "$scenario" "$WAIT_TIMEOUT" + sleep 3 + "${ADB[@]}" exec-out screencap -p > "$LOCALE_DIR/$scenario.png" + done done echo "Saved screenshots to $OUT_DIR" diff --git a/merchant-terminal/src/debug/java/net/taler/merchantpos/debug/ScreenshotActivity.kt b/merchant-terminal/src/debug/java/net/taler/merchantpos/debug/ScreenshotActivity.kt @@ -7,6 +7,8 @@ import android.util.Log import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.app.AppCompatDelegate +import androidx.core.os.LocaleListCompat import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.background import androidx.compose.foundation.horizontalScroll @@ -38,6 +40,8 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -69,6 +73,7 @@ class ScreenshotActivity : AppCompatActivity() { companion object { private const val TAG = "SCREENSHOT_READY" private const val EXTRA_SCENARIO = "screenshot_scenario" + private const val EXTRA_LOCALE = "screenshot_locale" private const val CURRENCY = "CHF" } @@ -88,6 +93,13 @@ class ScreenshotActivity : AppCompatActivity() { androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO, ) + val localeTag = intent.getStringExtra(EXTRA_LOCALE) + if (!localeTag.isNullOrEmpty()) { + AppCompatDelegate.setApplicationLocales( + LocaleListCompat.forLanguageTags(localeTag), + ) + } + val scenario = intent.getStringExtra(EXTRA_SCENARIO) ?: return val fixture = ScreenshotController.buildFixture(this) @@ -142,14 +154,15 @@ class ScreenshotActivity : AppCompatActivity() { } } - when (scenario) { - "order", "order-custom", "order-custom-added", "navigation" -> seedOrder(scenario) - "payment" -> seedPayment() - "history" -> seedHistory() - "refund", "refund-qr" -> seedRefund(scenario) + Handler(Looper.getMainLooper()).post { + when (scenario) { + "order", "order-custom", "order-custom-added", "navigation" -> seedOrder(scenario) + "payment" -> seedPayment() + "history" -> seedHistory() + "refund", "refund-qr" -> seedRefund(scenario) + } + signalReady(scenario) } - - signalReady(scenario) } private fun signalReady(scenario: String) { @@ -170,7 +183,7 @@ class ScreenshotActivity : AppCompatActivity() { if (scenario == "order-custom-added") { val orderId = model.orderManager.currentOrderId.value ?: 0 val customProduct = net.taler.merchantpos.config.ConfigProduct( - description = "Tip", + description = getString(R.string.order_custom_product_default), price = Amount.fromString(CURRENCY, "2.73"), categories = listOf(Int.MIN_VALUE), ) @@ -289,7 +302,7 @@ class ScreenshotActivity : AppCompatActivity() { refundUri = "taler://refund/example.invalid/2026-ORD-1047/REFUND-ABC123", item = refundItem, amount = Amount.fromString(CURRENCY, "18.30"), - reason = "Wrong order", + reason = getString(R.string.refund_reason_wrong_order), ), ) } @@ -545,15 +558,17 @@ class ScreenshotActivity : AppCompatActivity() { net.taler.merchantpos.order.OrderScreenContent( viewModel = model, showCustomDialog = showCustomDialog, - customDescription = if (showCustomDialog) "Tip" else null, + customDescription = if (showCustomDialog) stringResource(R.string.order_custom_product_default) else null, customAmount = if (showCustomDialog) "2.73" else null, ) } @Composable private fun PaymentScreenshot() { - val payment = model.paymentManager.payment.value ?: return - net.taler.merchantpos.payment.PaymentScreenContent(payment = payment) + val payment by model.paymentManager.payment.observeAsState() + payment?.let { + net.taler.merchantpos.payment.PaymentScreenContent(payment = it) + } } @Composable @@ -563,10 +578,9 @@ class ScreenshotActivity : AppCompatActivity() { @Composable private fun HistoryScreenshot() { - net.taler.merchantpos.history.HistoryScreenContent( - items = (model.historyManager.items.value - as? net.taler.merchantpos.history.HistoryResult.Success)?.items.orEmpty(), - ) + val result by model.historyManager.items.observeAsState() + val items = (result as? net.taler.merchantpos.history.HistoryResult.Success)?.items.orEmpty() + net.taler.merchantpos.history.HistoryScreenContent(items = items) } @Composable @@ -575,13 +589,14 @@ class ScreenshotActivity : AppCompatActivity() { net.taler.merchantpos.refund.RefundScreenContent( item = item, currencySpec = model.configManager.currencySpec, - initialReason = "Wrong order", + initialReason = stringResource(R.string.refund_reason_wrong_order), ) } @Composable private fun RefundQrScreenshot() { - val result = model.refundManager.refundResult.value as? RefundResult.Success ?: return + val refundResult by model.refundManager.refundResult.observeAsState() + val result = refundResult as? RefundResult.Success ?: return net.taler.merchantpos.refund.RefundQrScreenContent(result = result) } diff --git a/merchant-terminal/src/main/res/values-de/strings.xml b/merchant-terminal/src/main/res/values-de/strings.xml @@ -58,6 +58,9 @@ <string name="config_docs">Informationen zum Konfigurationsformat finden Sie in <a href="https://docs.taler.net/taler-merchant-pos-terminal.html#apis-and-data-formats">der Dokumentation</a>.</string> <string name="refund_error_max_amount">Größer als Bestellbetrag von %s</string> <string name="refund_error_backend">Fehler bei der Verarbeitung der Rückerstattung</string> + <string name="refund_reason_wrong_order">Falsche Bestellung</string> + <string name="refund_reason_duplicated">Doppelt</string> + <string name="refund_reason_customer_request">Auf Kundenwunsch</string> <string name="refund_intro_nfc">Bitte den Kunden den QR-Code scannen oder NFC nutzen, um die Rückerstattung anzubieten</string> <string name="config_changed">Neuer Händler für %s aktiviert</string> <string name="history_refund">Rückerstattung</string> diff --git a/merchant-terminal/src/main/res/values-fr/strings.xml b/merchant-terminal/src/main/res/values-fr/strings.xml @@ -67,6 +67,9 @@ <string name="refund_error_already_refunded">Déjà remboursé</string> <string name="refund_state_missing">L’état du remboursement n’est plus disponible</string> <string name="menu_history">Historique</string> + <string name="refund_reason_wrong_order">Mauvaise commande</string> + <string name="refund_reason_duplicated">Doublon</string> + <string name="refund_reason_customer_request">Demandé par le client</string> <string name="refund_intro_nfc">Demandez au client de scanner le QR code ou d\'utiliser la NFC pour effectuer le remboursement</string> <string name="refund_intro">Demandez au client de scanner le QR code pour effectuer le remboursement</string> <string name="refund_order_ref">Référence d\'achat : %1$s diff --git a/merchant-terminal/src/main/res/values/strings.xml b/merchant-terminal/src/main/res/values/strings.xml @@ -123,6 +123,9 @@ <string name="refund_intro_nfc">Please let customer scan QR Code or use NFC to offer refund</string> <string name="refund_intro">Please let customer scan QR Code to offer refund</string> <string name="refund_order_ref">Purchase reference: %1$s\n\n%2$s</string> + <string name="refund_reason_wrong_order">Wrong order</string> + <string name="refund_reason_duplicated">Duplicated</string> + <string name="refund_reason_customer_request">Requested by the customer</string> <string name="error_payment">Error: No payment received</string> <string name="error_order_creation">Error: Could not create order</string>