Skip to content

Conversation

@Gaubee
Copy link
Contributor

@Gaubee Gaubee commented Dec 26, 2025

Summary

Implement high-performance QR code scanning with Web Worker, Stackflow integration, and contact protocol support.

Features

QR Scanner Core

  • Web Worker-based decoding for smooth UI performance
  • 150ms scan interval with automatic retry
  • Mock frame source for testing
  • Camera race condition handling for React StrictMode

ScannerJob (Stackflow BottomSheet)

  • Chain-specific validators (Ethereum, Bitcoin, Tron, Any)
  • Deep link support for authorize routes
  • Callback pattern for address input integration

Contact Protocol

  • JSON format: {"type":"contact","name":"张三","addresses":[...]}
  • URI format: contact://张三?eth=0x...&btc=bc1...
  • ContactAddConfirmJob for adding scanned contacts
  • ContactShareJob for sharing contact QR codes

Testing & CI

  • 1477 unit tests passing
  • 337 Storybook component tests integrated into CI
  • E2E tests for contact scanning flow
  • Comprehensive Storybook stories

Documentation

  • Updated whitepaper with Storybook + Vitest integration guide
  • Scanner component documentation

Changes

  • src/lib/qr-scanner/ - QR scanner core with Web Worker
  • src/lib/qr-parser.ts - Contact protocol parsing
  • src/stackflow/activities/sheets/ScannerJob.tsx - Scanner BottomSheet
  • src/stackflow/activities/sheets/ContactAddConfirmJob.tsx - Add contact confirmation
  • src/stackflow/activities/sheets/ContactShareJob.tsx - Share contact QR
  • .github/workflows/ci.yml - Added test:storybook to CI
  • .storybook/preview.tsx - Added QueryClientProvider
  • i18n translations for all new features

- Add QRScanner class with Web Worker for background decoding
- Add MockFrameSource supporting images, videos, and image sequences
- Add comprehensive reliability tests with QR transformation
- Update Scanner page to use new async QRScanner
- Enhance camera mock with frame source support
- Add Storybook stories for testing and demo
- Use refs for lastScanned and onScan to avoid dependency chain
- Initialize camera only once on mount with empty deps array
- Stop existing stream before starting new one
- Add ParsedDeepLink type for hash-based routes
- Parse #/authorize/address and #/authorize/signature URLs
- Handle deeplink, address, payment, and unknown content types
- Navigate to appropriate routes based on QR content
- Create ScannerJob as Stackflow BottomSheet activity
- Add chainType-based validators for address filtering
- Use callback pattern (setScannerResultCallback) for results
- Integrate with SendPage for address scanning
- Register ScannerJob in stackflow router
- Fix: execute callback after pop() to prevent SendPage exit
- Add ParsedContact type and parseContactURI for contact:// protocol
- Add generateContactQRContent for sharing contact cards
- Improve camera error handling with detailed messages
- Add scanPromptChain i18n for chain-specific scan hints
- Extract validators to scanner-validators.ts for testing
- Add unit tests for validators
- Create ContactAddConfirmJob to confirm adding scanned contacts
- Update Scanner page to handle 'contact' type QR codes
- Add addressBook i18n translations for contact sharing
- Register ContactAddConfirmJob in Stackflow router
- Create ContactShareJob to display contact QR code for sharing
- Add share option in address book contact menu
- Support QR code download and Web Share API
- Register ContactShareJob in Stackflow router
- Add ScannerJob.stories.tsx with ValidatorDemo, AddressFormats, UIPreview
- Add ContactJobs.stories.tsx with ContactProtocolDemo, ContactAddConfirmPreview, ContactSharePreview, EdgeCases
- Add 15+ contact protocol tests in qr-parser.test.ts
- Add 8+ edge case tests for validators in ScannerJob.test.ts
- Add E2E tests in contact-scanner.mock.spec.ts
- Fix empty addresses validation in qr-parser.ts
- Create Scanner.md documentation in whitepaper
- Update contact service docs with share/scan protocol

79 tests passing, 35 skipped
- Add mountedRef and initializingRef to prevent race conditions
- Handle AbortError gracefully (common in React StrictMode)
- Check component mount status before updating state
- Clean up stream if component unmounts during initialization
- Add QueryClientProvider to .storybook/preview.tsx global decorator
- Update CI workflow to run test:storybook in both fast and standard paths
- Update whitepaper testing strategy with Storybook + Vitest integration docs
- Document test types: unit (*.test.ts) vs component (*.stories.tsx)
- Add guidance on when to use play functions vs unit tests

All 337 Storybook tests now passing
Scanner:
- scanPromptChain, noCameraFound
- invalidAddress, invalidEthereumAddress, invalidBitcoinAddress, invalidTronAddress

AddressBook:
- addContact, namePlaceholder, addresses, memo, memoPlaceholder
- shareContact, scanToAdd
@Gaubee Gaubee merged commit ba5be57 into main Dec 26, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants