diff --git a/app/src/main/java/sh/sar/basedbank/ui/home/AccountHistoryAdapter.kt b/app/src/main/java/sh/sar/basedbank/ui/home/AccountHistoryAdapter.kt index 22bf102..24b3827 100644 --- a/app/src/main/java/sh/sar/basedbank/ui/home/AccountHistoryAdapter.kt +++ b/app/src/main/java/sh/sar/basedbank/ui/home/AccountHistoryAdapter.kt @@ -37,7 +37,12 @@ class AccountHistoryAdapter( var onImageNeeded: ((counterpartyName: String) -> Unit)? = null var onIconUrlNeeded: ((url: String) -> Unit)? = null var onTransferClick: ((BankAccount) -> Unit)? = null + var onDefaultToggle: ((Boolean) -> Unit)? = null private var hideAmounts: Boolean = false + var showDefaultToggle: Boolean = false + set(value) { if (field == value) return; field = value; notifyItemChanged(0) } + var isDefaultAccount: Boolean = false + set(value) { if (field == value) return; field = value; notifyItemChanged(0) } fun setHideAmounts(hide: Boolean) { if (hideAmounts == hide) return @@ -174,6 +179,20 @@ class AccountHistoryAdapter( b.llHeaderBlocked.visibility = View.GONE } b.btnHeaderTransfer.setOnClickListener { onTransferClick?.invoke(account) } + + if (showDefaultToggle) { + b.dividerDefaultAccount.visibility = View.VISIBLE + b.llDefaultAccountRow.visibility = View.VISIBLE + b.switchDefaultAccount.setOnCheckedChangeListener(null) + b.switchDefaultAccount.isChecked = isDefaultAccount + b.switchDefaultAccount.setOnCheckedChangeListener { _, checked -> + isDefaultAccount = checked + onDefaultToggle?.invoke(checked) + } + } else { + b.dividerDefaultAccount.visibility = View.GONE + b.llDefaultAccountRow.visibility = View.GONE + } } } diff --git a/app/src/main/java/sh/sar/basedbank/ui/home/AccountHistoryFragment.kt b/app/src/main/java/sh/sar/basedbank/ui/home/AccountHistoryFragment.kt index 2d4232d..7d2f2ba 100644 --- a/app/src/main/java/sh/sar/basedbank/ui/home/AccountHistoryFragment.kt +++ b/app/src/main/java/sh/sar/basedbank/ui/home/AccountHistoryFragment.kt @@ -29,7 +29,9 @@ import sh.sar.basedbank.api.models.BankTransaction import sh.sar.basedbank.api.mib.TransactionCache import sh.sar.basedbank.databinding.FragmentAccountHistoryBinding import sh.sar.basedbank.util.AccountHistoryParser +import sh.sar.basedbank.util.AccountListParser import sh.sar.basedbank.util.ContactImageCache +import sh.sar.basedbank.util.CredentialStore import sh.sar.basedbank.util.HistoryFetcher import sh.sar.basedbank.util.MerchantIconCache @@ -80,6 +82,23 @@ class AccountHistoryFragment : Fragment() { } adapter.setHideAmounts(viewModel.hideAmounts.value ?: false) viewModel.hideAmounts.observe(viewLifecycleOwner) { adapter.setHideAmounts(it) } + + // Show default account toggle only for non-card accounts + val isCard = AccountListParser.from(account)?.isCard ?: false + if (!isCard) { + val store = CredentialStore(requireContext()) + adapter.showDefaultToggle = true + adapter.isDefaultAccount = store.getDefaultAccountNumber() == account.accountNumber + adapter.onDefaultToggle = { isChecked -> + if (isChecked) { + store.setDefaultAccountNumber(account.accountNumber) + } else { + if (store.getDefaultAccountNumber() == account.accountNumber) { + store.setDefaultAccountNumber(null) + } + } + } + } binding.recyclerView.layoutManager = LinearLayoutManager(requireContext()) binding.recyclerView.adapter = adapter @@ -131,7 +150,12 @@ class AccountHistoryFragment : Fragment() { override fun onResume() { super.onResume() - if (::account.isInitialized) requireActivity().title = account.accountBriefName + if (::account.isInitialized) { + requireActivity().title = account.accountBriefName + if (adapter.showDefaultToggle) { + adapter.isDefaultAccount = CredentialStore(requireContext()).getDefaultAccountNumber() == account.accountNumber + } + } } private fun filterAndDisplay() { diff --git a/app/src/main/java/sh/sar/basedbank/ui/home/PayMvQrFragment.kt b/app/src/main/java/sh/sar/basedbank/ui/home/PayMvQrFragment.kt index c05e72b..afca8b7 100644 --- a/app/src/main/java/sh/sar/basedbank/ui/home/PayMvQrFragment.kt +++ b/app/src/main/java/sh/sar/basedbank/ui/home/PayMvQrFragment.kt @@ -124,6 +124,20 @@ class PayMvQrFragment : Fragment() { selectedAccount = picked scheduleGenerate() } + + // Auto-select default account if none is selected yet + if (selectedAccount == null) { + val defaultNum = CredentialStore(requireContext()).getDefaultAccountNumber() + if (defaultNum != null) { + val defaultAcc = eligible.firstOrNull { it.accountNumber == defaultNum } + if (defaultAcc != null) { + selectedAccount = defaultAcc + val prefix = if (defaultAcc.bank == "BML" && defaultAcc.profileName.isNotBlank()) "${defaultAcc.profileName} · " else "" + binding.actvAccount.setText("$prefix${defaultAcc.accountBriefName}", false) + scheduleGenerate() + } + } + } } } 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 778796e..ae5e16a 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 @@ -573,8 +573,21 @@ class TransferFragment : Fragment() { private fun lookupAccount() { if (selectedAccount == null) { - Toast.makeText(requireContext(), R.string.transfer_select_source_first, Toast.LENGTH_SHORT).show() - return + val defaultNum = CredentialStore(requireContext()).getDefaultAccountNumber() + if (defaultNum != null) { + val allAccounts = viewModel.accounts.value ?: emptyList() + val defaultAcc = allAccounts.firstOrNull { it.accountNumber == defaultNum } + if (defaultAcc != null) { + selectedAccount = defaultAcc + updateAmountPrefix(defaultAcc) + showFromCard(defaultAcc) + updateTransferButton() + } + } + if (selectedAccount == null) { + Toast.makeText(requireContext(), R.string.transfer_no_from_account, Toast.LENGTH_SHORT).show() + return + } } val accountNumber = AccountInputParser.normalize(binding.etTo.text?.toString()?.trim() ?: "") if (accountNumber.isBlank()) { diff --git a/app/src/main/java/sh/sar/basedbank/util/CredentialStore.kt b/app/src/main/java/sh/sar/basedbank/util/CredentialStore.kt index 989284a..095c07e 100644 --- a/app/src/main/java/sh/sar/basedbank/util/CredentialStore.kt +++ b/app/src/main/java/sh/sar/basedbank/util/CredentialStore.kt @@ -627,6 +627,18 @@ class CredentialStore(context: Context) { editor.apply() } + // ── Default transfer/QR account ─────────────────────────────────────────── + + /** Account number the user has pinned as their default source for transfers and PayMV QR, or null. */ + fun getDefaultAccountNumber(): String? = prefs.getString("default_account_number", null) + + fun setDefaultAccountNumber(accountNumber: String?) { + val editor = prefs.edit() + if (accountNumber == null) editor.remove("default_account_number") + else editor.putString("default_account_number", accountNumber) + editor.apply() + } + // ── Dashboard card visibility ───────────────────────────────────────────── fun getHiddenDashboardCardNumbers(): Set = diff --git a/app/src/main/res/layout/item_account_history_header.xml b/app/src/main/res/layout/item_account_history_header.xml index 2866877..b4a5533 100644 --- a/app/src/main/res/layout/item_account_history_header.xml +++ b/app/src/main/res/layout/item_account_history_header.xml @@ -182,6 +182,55 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 85f2f3b..11c1b7a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -246,6 +246,7 @@ Camera access is needed to take a photo. Please grant the permission in Settings. Go to Settings Select a source account first + Please set a default account or select From account first Enter an account number first Account not found Session unavailable — please re-login