forked from shihaam/thijooree
101 lines
4.3 KiB
Markdown
101 lines
4.3 KiB
Markdown
# Cards
|
|
|
|
Unified card management screen for both MIB and BML cards. Supports a horizontally-paged stack, freeze / unfreeze, default-card and hide-from-dashboard toggles, and launches the [Tap to Pay](23-tap-to-pay.md) NFC flow.
|
|
|
|
---
|
|
|
|
## Fragment — `CardsFragment`
|
|
|
|
File: `ui/home/PayWithCardFragment.kt`. Bound to nav id `R.id.nav_pay_with_card`.
|
|
|
|
Opened via:
|
|
- Navigation slot ("Cards")
|
|
- `OPEN_PAY_WITH_CARD` intent
|
|
- `TAP_TO_PAY` intent — auto-enters tap mode for the user's default BML card
|
|
- Dashboard NFC button — auto-enters tap mode for the selected card
|
|
|
|
`newInstanceWithAutoTapMode(accountNumber? = null)` (`PayWithCardFragment.kt:1203-1208`) is the factory for the auto-tap entry points.
|
|
|
|
---
|
|
|
|
## Card Stack
|
|
|
|
A horizontal `RecyclerView` driven by `CardStackAdapter` with a `PagerSnapHelper`. Off-centre cards are scaled to 82% and faded to 60% via `applyCardScales()`. Page dots beneath the stack are rebuilt on each scroll-idle.
|
|
|
|
### Sources
|
|
|
|
`rebuildCards()` (`PayWithCardFragment.kt:894-958`) merges two lists:
|
|
|
|
- BML: `viewModel.accounts` filtered to `profileType in (BML_PREPAID, BML_CREDIT, BML_DEBIT)`
|
|
- MIB: `viewModel.mibCards`
|
|
|
|
The combined order is `bmlActive + mibActive + bmlInactive + mibInactive`. The user's default card (`CredentialStore.getDefaultCardAccountNumber()`) is moved to position 0. Initial data is seeded from `CardsCache` so the stack appears immediately; a background `HomeActivity.triggerRefreshCards()` refreshes it.
|
|
|
|
### Card Art
|
|
|
|
| Source | Asset path |
|
|
|---|---|
|
|
| MIB `cardType` → asset | `CardsFragment.cardImageAsset(card)` — `51` → `cards/mib/faisa_card.png`, `53` → `visa_black_platinum.png`, `57` → `visa_blue_everyday.png`, `70` → `visa_business.png`, `701/702` → `visa_bingaa_mvr.png` / `visa_bingaa_usd.png` |
|
|
| BML | `BmlCardParser.cardImageAsset(account)` |
|
|
|
|
Status chips use `bindCardStatus(...)`. MIB statuses: `CHST0` = active (no chip), `CHST20` = "Temporary blocked by client", other values shown verbatim.
|
|
|
|
---
|
|
|
|
## Pay Buttons
|
|
|
|
| Button | Behaviour |
|
|
|---|---|
|
|
| Scan to Pay (`btnScanToPay`) | Launches [QrScannerActivity](25-qr-scanner.md). BML cards route the result to `TransferFragment` (BML QR mode or PayMV pre-fill). MIB cards show "not supported" |
|
|
| Tap to Pay (`btnTapToPay`) | `NfcPaymentUtil.checkAndProceed(...)`. If `biometrics_transfer_confirm` is on, shows a `BIOMETRIC_STRONG` prompt first, then enters tap mode. MIB cards show "not supported" |
|
|
|
|
---
|
|
|
|
## Manage Mode
|
|
|
|
Toggle: `btnManageCard`. Animates the focused card up into a single full-width "manage card" panel, hides the carousel, and exposes:
|
|
|
|
| Control | Effect |
|
|
|---|---|
|
|
| Default card switch | `CredentialStore.setDefaultCardAccountNumber()` — BML only |
|
|
| Hide from dashboard switch | `CredentialStore.setCardHiddenFromDashboard(accountNumber, hidden)` |
|
|
| Freeze / Unfreeze | BML: `BmlCardClient.setCardFreezeState(session, internalId, "freeze"/"unfreeze")`. MIB: prompts for a comments string, then `MibCardsClient().setCardFreezeState(session, cardId, action, comments)` serialised through `app.mibMutex` with a profile switch first |
|
|
| Change PIN / Block | Wired but currently shows a "work in progress" toast |
|
|
|
|
Manage mode can be dismissed by tapping the button again or swipe-down on the manage card.
|
|
|
|
---
|
|
|
|
## Tap Mode
|
|
|
|
Entered via `setTapMode(true, item)`. Hides the carousel, animates the selected card to the top, draws an `NfcTapAnimationView` and a Cancel button.
|
|
|
|
`fetchAndArmToken()`:
|
|
|
|
1. Generates a TOTP from the BML OTP seed
|
|
2. `BmlTapToPayClient().fetchTokens(session, internalId, otp)` returns a single-use `BmlWalletToken`
|
|
3. `BmlHostCardEmulatorService.setToken(token)`
|
|
4. Sets `BmlHostCardEmulatorService.onTransactionComplete` — on success shows a "Payment complete" toast and refreshes balances
|
|
|
|
Exiting tap mode clears the token and the callback. See [Tap to Pay](23-tap-to-pay.md) for the HCE protocol details.
|
|
|
|
---
|
|
|
|
## Inactive Cards
|
|
|
|
Inactive cards remain in the stack at 45% alpha. Tap-to-pay and "default card" are disabled for them. Hide-from-dashboard is force-enabled and locked on for inactive cards (`PayWithCardFragment.kt:522-530`).
|
|
|
|
---
|
|
|
|
## Back Handling
|
|
|
|
`onBackPressed()` returns `true` while in manage mode or tap mode so `HomeActivity` does not pop the back stack — instead the fragment exits the current mode.
|
|
|
|
---
|
|
|
|
|
|
|
|
---
|
|
|
|
[← Dashboard](21-dashboard.md) **Next →** [Tap to Pay](23-tap-to-pay.md)
|