feat(mobile): add QR scanner component using expo-camera - #548
Conversation
Creates QrScanner component that replaces the web BarcodeDetector approach with expo-camera's CameraView + onBarcodeScanned for native mobile QR scanning. Includes camera permission handling, viewfinder overlay, and manual address entry fallback. Closes Miracle656#468
|
@iredis is attempting to deploy a commit to the miracle656's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
@iredis Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
- Drop app.json (main uses app.config.ts, which already registers the expo-camera plugin with its permission string) and take main's dependencies. - The scanner only accepted a bare G…/C… address, so a SEP-7 payment-request QR — the form most payment QR codes actually take — was silently ignored and the camera just kept scanning. It now goes through parseQrValue from lib/sep7.ts, which handles both, falling back to the bare-address path. - Replaced the local isValidStellarAddress (a startsWith + length === 56 check) with lib/address.ts's StrKey-based one, so a corrupted address of the right shape is rejected rather than accepted and handed to the send form. - Wired the scanner into (tabs)/send.tsx behind a "Scan QR" action next to "Choose contact", which is what makes the acceptance criterion true — nothing rendered QrScanner before. tsc clean; jest 12 suites / 206 tests; expo lint clean.
|
Merging. The permission handling is the part I'd highlight — distinguishing "undetermined" from "denied" and offering a manual-entry fallback when the camera isn't available is more than most scanner implementations bother with, and it means the screen is still usable if a user declines. Three changes before merge: SEP-7 QR codes were being ignored. The scan handler only accepted a bare address: const addr = data.trim();
if (isValidStellarAddress(addr)) { ... }So pointing the camera at a It now goes through Validation swapped for the checksum version. The local helper was: return (v.startsWith('G') || v.startsWith('C')) && v.length === 56;
Wired it into the send screen. Nothing rendered Also dropped the re-added Verified: One follow-up: a SEP-7 code carries |
Overview
This PR adds a QR Scanner component for the mobile app that replaces the web's
BarcodeDetector/getUserMediaapproach withexpo-camera's nativeCameraView+onBarcodeScanned. The component handles camera permissions viauseCameraPermissions, scans Stellar/SEP-7 QR codes, and includes a manual address entry fallback for users who cannot use the camera.Related Issue
Closes #468
Changes
📦 New Files
frontend/mobile/components/QrScanner.tsx— Full QR scanner component with:CameraViewfromexpo-camerawith QR barcode scanning viaonBarcodeScanneduseCameraPermissions): grants on first use, shows settings prompt if deniedG…orC…address with validation)isValidStellarAddress—G/Cprefix, 56 chars)visible/onScan/onCloseprops using React NativeModal📝 Modified Files
frontend/mobile/package.json— Addedexpo-cameradependencyfrontend/mobile/app.json— Added camera plugin config with permission stringVerification
onBarcodeScannedcallback returns decodeddata; component callsonScanwith the addressuseCameraPermissionshook; shows permission prompt or settings redirectonScanG…/C…(56 chars) triggeronScan