Adds a dedicated Family tab (tab index 2) to the bottom nav bar showing
all accessible dossiers as native profile cards. Tapping a card navigates
the home WebView directly to that dossier.
FamilyScreen:
- Fetches /api/v1/dashboard on load (pull-to-refresh)
- Profile cards: avatar with initials + color-coded background, name,
relation + age + sex subtitle, chevron
- 'Add family member' CTA card at the bottom (opens /dossier/add in WebView)
- Error state with retry button
- Loading + empty state handling
Navigation:
- Tapping a profile sets tab to Home and loads the dossier URL in the
existing WebView via loadRequest() — no new WebView instance
- Settings moved to tab index 3 (was 2)
API:
- Uses enriched /api/v1/dashboard fields: initials, color, age, dob,
sex, is_self (added in companion server commit)
iOS was missing NSFaceIDUsageDescription — Face ID prompts will
crash without it (required by Apple since iOS 11). Added with
user-facing reason string scoped to health data privacy.
Android was missing USE_BIOMETRIC and USE_FINGERPRINT permissions —
biometric_local_auth plugin requires both for API 28+/legacy compat.
The Flutter implementation was already complete:
- BiometricService (services/biometric_service.dart)
- AuthGate lock screen (core/auth_gate.dart)
- Settings toggle with policy control (features/settings/)
- Wired into main.dart
These permission declarations were the only missing pieces
blocking Face ID / fingerprint from working on device.
- Changed to /api/auth/send-code and /api/auth/verify
- Properly check content-type is JSON
- Check for success: true in response
- Backend needs these endpoints added
- Added inou_api.dart with real API calls to /send-code and /verify
- Updated auth_service to use real API
- Added http package
- Changed all text to use Sora font (inou brand font)
- Logo uses Sora w800 'i'
- Logo: extra bold 'i' (w800) in tighter rounded square
- Changed 'Sign in to your inou account' → 'Enter your email to continue'
- Changed 'Welcome' → 'Welcome to inou'
- Changed 'Sign in with Biometrics' → 'Use Biometrics'
- Created AuthService for managing login state
- Created LoginScreen with email/password form
- Auto-prompts to enable biometric after first login
- Integrated login flow into main.dart
- Shows splash screen during initialization
- AuthGate wraps main app for biometric re-auth
- Add google_mlkit_barcode_scanning dependency
- Scan priority: Barcode → OCR text → Nothing found
- Support UPC-A/E, EAN-8/13, QR, DataMatrix, PDF417, Code128/39
- BarcodeData class with product code detection and NDC hints
- ScanResult with type indicator (barcode|text|empty)
- Updated capture screen with barcode-specific UI:
- Green overlay for barcodes, blue for text
- Product code badge for UPC/EAN barcodes
- Format-specific result display
- Backward compatible legacy API (extractText, getTextBlocks)
- Create BiometricService with local_auth integration
- Check biometric availability (Face ID, Touch ID, fingerprint)
- Authenticate with fallback to PIN
- Session state: don't re-prompt within session
- Configurable lock policies: always, after 5 min inactive, never
- Create AuthGate widget that wraps the app
- Shows biometric prompt on app launch
- Handles app resume from background
- Activity tracking for inactivity timeout
- Graceful error handling with user-friendly messages
- Update SettingsScreen with biometric configuration
- Enable/disable toggle with verification
- Lock timing policy selection
- Edge case handling: not enrolled, not available
- Store preferences in shared_preferences
- Handle multiple failures with attempt counter
- Create InouWebView widget with:
- JavaScript bridge for native ↔ web communication
- Auth cookie/token handling
- Pull-to-refresh support
- Loading indicator with progress
- Offline/error state handling with retry
- Enhance WebViewScreen with:
- Full-screen WebView with optional app bar
- Back button handling (WebView history first, then app nav)
- Share functionality (copies to clipboard)
- Menu actions (copy URL, open in browser)
- Haptic feedback support via JS bridge
- Add deep link handling in main.dart:
- inou.com/app/* URLs open in WebView
- Navigator route generation for deep links
JS Bridge API:
- window.inouNativeBridge.postMessage(action, data)
- window.inouNativeBridge.share(title, text, url)
- window.inouNativeBridge.haptic(type)
- window.inouNativeBridge.setToken(token)
- window.inouNativeBridge.logout()