From 973576cf6a4075a5fd54f00823661e036d4287fe Mon Sep 17 00:00:00 2001 From: Shihaam Abdul Rahman Date: Sun, 31 May 2026 00:06:37 +0500 Subject: [PATCH] save static BML QR scans to recents #31 --- .../sar/basedbank/ui/home/BmlQrPayFragment.kt | 15 +++++++++++++++ .../ui/home/ContactPickerSheetFragment.kt | 4 ++++ .../sar/basedbank/ui/home/TransferFragment.kt | 18 +++++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/sh/sar/basedbank/ui/home/BmlQrPayFragment.kt b/app/src/main/java/sh/sar/basedbank/ui/home/BmlQrPayFragment.kt index 4058ddf..f2dd473 100644 --- a/app/src/main/java/sh/sar/basedbank/ui/home/BmlQrPayFragment.kt +++ b/app/src/main/java/sh/sar/basedbank/ui/home/BmlQrPayFragment.kt @@ -33,6 +33,8 @@ import sh.sar.basedbank.api.models.BankAccount import sh.sar.basedbank.databinding.FragmentBmlQrPayBinding import sh.sar.basedbank.databinding.ItemAccountDropdownBinding import sh.sar.basedbank.util.CredentialStore +import sh.sar.basedbank.util.RecentPick +import sh.sar.basedbank.util.RecentsCache import sh.sar.basedbank.util.Totp class BmlQrPayFragment : Fragment() { @@ -150,6 +152,19 @@ class BmlQrPayFragment : Fragment() { return@launch } merchantInfo = info + if (info.amount == 0.0) { + val qrUrl = arguments?.getString(ARG_QR_URL) + if (qrUrl != null) { + RecentsCache.save(requireContext(), RecentPick( + accountNumber = "bmlqr:$qrUrl", + displayName = info.merchantName, + subtitle = info.merchantAddress.ifBlank { "BML Merchant" }, + colorHex = "#0066A1", + imageHash = null, + isProfileImage = false + )) + } + } populateMerchant(info) } } diff --git a/app/src/main/java/sh/sar/basedbank/ui/home/ContactPickerSheetFragment.kt b/app/src/main/java/sh/sar/basedbank/ui/home/ContactPickerSheetFragment.kt index 7424db1..225a965 100644 --- a/app/src/main/java/sh/sar/basedbank/ui/home/ContactPickerSheetFragment.kt +++ b/app/src/main/java/sh/sar/basedbank/ui/home/ContactPickerSheetFragment.kt @@ -168,6 +168,10 @@ class ContactPickerSheetFragment : BottomSheetDialogFragment() { val account = accounts.firstOrNull { it.accountNumber == accountNumber } val bundle = bundleOf(KEY_ACCOUNT_NUMBER to accountNumber, KEY_LABEL to label) when { + accountNumber.startsWith("bmlqr:") -> { + bundle.putString(KEY_SUBTITLE, "BML QR Merchant") + bundle.putString(KEY_COLOR, "#0066A1") + } account != null -> { bundle.putString(KEY_SUBTITLE, "${account.accountNumber} ยท ${account.currencyName} ${account.availableBalance}") bundle.putString(KEY_COLOR, "#FE860E") diff --git a/app/src/main/java/sh/sar/basedbank/ui/home/TransferFragment.kt b/app/src/main/java/sh/sar/basedbank/ui/home/TransferFragment.kt index b5d04af..6ddea6f 100644 --- a/app/src/main/java/sh/sar/basedbank/ui/home/TransferFragment.kt +++ b/app/src/main/java/sh/sar/basedbank/ui/home/TransferFragment.kt @@ -95,6 +95,7 @@ class TransferFragment : Fragment() { // BML QR merchant payment mode (set when navigated from a card QR scan) private var bmlQrInfo: BmlQrPayInfo? = null private var bmlGatewayQr = false // true for pay.bml.com.mv QRs (requires pre-initiate step) + private var bmlQrLookupAttempted = false // prevents re-lookup after user clears the merchant private val dropdownProfileImageCache = mutableMapOf() // BML business profile OTP flow state @@ -245,6 +246,10 @@ class TransferFragment : Fragment() { childFragmentManager.setFragmentResultListener(ContactPickerSheetFragment.REQUEST_KEY, viewLifecycleOwner) { _, bundle -> val accountNumber = bundle.getString(ContactPickerSheetFragment.KEY_ACCOUNT_NUMBER) ?: return@setFragmentResultListener + if (accountNumber.startsWith("bmlqr:")) { + lookupBmlQrMerchant(accountNumber.removePrefix("bmlqr:")) + return@setFragmentResultListener + } val label = bundle.getString(ContactPickerSheetFragment.KEY_LABEL) ?: "" val subtitle = bundle.getString(ContactPickerSheetFragment.KEY_SUBTITLE) ?: accountNumber val colorHex = bundle.getString(ContactPickerSheetFragment.KEY_COLOR) ?: "#607D8B" @@ -292,6 +297,7 @@ class TransferFragment : Fragment() { } private fun lookupBmlQrMerchant(qrUrl: String) { + bmlQrLookupAttempted = true bmlGatewayQr = qrUrl.startsWith("https://pay.bml.com.mv/app/") val base64Url = android.util.Base64.encodeToString( qrUrl.toByteArray(Charsets.UTF_8), android.util.Base64.NO_WRAP) @@ -316,6 +322,16 @@ class TransferFragment : Fragment() { return@launch } bmlQrInfo = info + if (info.amount == 0.0) { + RecentsCache.save(requireContext(), RecentPick( + accountNumber = "bmlqr:$qrUrl", + displayName = info.merchantName, + subtitle = info.merchantAddress.ifBlank { "BML Merchant" }, + colorHex = "#0066A1", + imageHash = null, + isProfileImage = false + )) + } // Auto-select the user's default BML card if no card was pre-selected if (selectedAccount == null) { @@ -426,7 +442,7 @@ class TransferFragment : Fragment() { // On a cold start (e.g. share intent), anyBmlSession() may be null when // onViewCreated runs. Retry the lookup once sessions are available. val pendingBmlQrUrl = arguments?.getString(ARG_BML_QR_URL) - if (pendingBmlQrUrl != null && bmlQrInfo == null && binding.tilTo.visibility == View.VISIBLE) { + if (pendingBmlQrUrl != null && !bmlQrLookupAttempted) { val app = requireActivity().application as BasedBankApp if (app.anyBmlSession() != null) lookupBmlQrMerchant(pendingBmlQrUrl) }