Replace the ThemePort/ThemeCode abstraction (GetIt-registered adapter)
with a Riverpod-driven Material 3 ColorScheme, an SfColors ThemeExtension
for brand tokens, and a user-facing appearance selector for light/dark/
system modes. Persisted via SharedPreferences, reacts to system
brightness changes. Payments mode keeps the existing ThemePort API.
Highlights
- New legacy_theme package: LegacyAppTheme (light/dark), LegacyColorSchemes,
SfColors ThemeExtension, LegacyThemePreferences, LegacyThemeNotifier,
LegacyThemeSelector. Timeframe-based variants scaffolded but disabled.
- New /legacy/dashboard/control_panel/settings/appearance route + screen.
- MaterialApp.router picks the legacy theme only when isLegacyMode.
- ~90 ThemeCode.* usages migrated to colorScheme.* / context.sfColors.*.
- 25 widgets dropped the 'ThemePort theme' constructor param.
- ~145 hardcoded colors migrated (exact hex 1:1, grey.shade tiers,
destructive red -> colorScheme.error, background whites -> surface).
Content-over-color whites, transparents, and brand semantic reds/
oranges/greens intentionally preserved.
- sf_localizations updated with appearance / appearanceDescription keys
in all six locales.
Full wrapper around jc_sdk v2.16.5 with clean architecture:
- 7 services covering 100% of jc_sdk public API (Client, Call, Device, Channel, Push, Net, Log)
- Constructor injection with GetIt DI module (follows sca_treezor pattern)
- VideocallSdkManager orchestrator for init/destroy lifecycle
- VideocallSdkConfig abstract for environment-specific AppKey
- Stream-based callbacks for reactive UI consumption
- Riverpod providers (service + stream) for feature layer
- AppKey configured per environment via dart-define-from-file
- Integrated in init_app.dart alongside scaTreezorModule
Extend CheckSessionUseCase to fetch /devices after confirming the
session and return InitialRoute.deviceSetup when the list is empty
(or the call fails). The splash builder now injects a
SharedDevicesRepository alongside the user repository, and the app
router maps the new route to legacyDeviceSetup / deviceSetup per
shell. The legacy builder reads legacyDevicesProvider to derive
isFirstDevice so the setup screen adapts its copy accordingly.
The two fields had been flipped, pointing API calls at the origin host
(platform.savefamily.app) and sending the Origin header as the gateway
host (api-platform.savefamily.app). Restore the intended wiring:
gateway handles /api, and Origin is the platform domain.
Route FCM and local notification taps to the device alerts screen
when the user is already inside the legacy dashboard. Adds payload
parsing with command-based routing and richer debug logs.
- Add AntelopAwareMessagingService so the Antelop SDK gets first dibs on every
FCM push before delegating to firebase_messaging. Unblocks SCA wallet
activation on Android, which was waiting forever for pushes that the
FlutterFirebaseMessagingService was swallowing ever since Firebase was
integrated. Remove the stock Antelop and firebase_messaging services via
manifest-merge so only the wrapper handles MESSAGING_EVENT.
- Add Copy AntelopRelease Build Phase in Xcode to copy
Runner/AntelopRelease-{flavor}.plist over the fixed AntelopRelease.plist
inside the .app bundle based on CONFIGURATION. Without this the iOS SDK
silently used the production plist on every flavor.
- Revert the six applicationId values (3 AndroidManifest + 3 AntelopRelease
plist) to the sample id 4713640103500149457, which is the only one
provisioned in Antelop's backend today. The four env+platform ids they
provided all fail with 9999 / cryptography: Error while decrypting data.
To be updated once Treezor confirms the real ids.
- Add packages/flutter_treezor_entrust_sdk_bridge/example as a pub workspace
member and bump its Dart SDK and flutter_lints constraints so
'melos bootstrap' stops failing with 'dependencies for
flutter_treezor_entrust_sdk_bridge_example missing'.
Adds a production-grade in-app version check that prompts users to update when a new build is available. Soft updates are dismissable. Force updates block the app entirely. Configured via FirebaseRemote Config so rollouts can be triggered without redeploying.
- Sealed result types (NoUpdate / SoftUpdate / ForceUpdate) for type-safe pattern matching
- AppVersionCheckService
- AppUpdateGate widget encapsulates listener, route guard and dialog wireup, isolated from save_family_app
- Serialized notifier operations prevent race between dismiss and refresh, mounted checks blindar disposal edge cases - Build-aware dismiss persistence via SharedPreferences
- Lazy-init sfTracking to avoid touching Firebase at import time
- DRY SfTrackingRepository with a single _broadcast helper
- Drop empty DashboardTracking, fix double step_completed in device_setup
- Move yearsBetween to packages/utils
- Add 5 unit tests for SfTrackingRepository
- Strip noisy comments from mixins and view models
Introduces packages/sf_tracking — a multi-client, GDPR-first analytics layer with feature mixins, a GoRouter listener for automatic screen views, and a user properties helper that runs on login.
Wires the package into the legacy module 61 events
Phase 2 of multi-environment setup. Adds Firebase core, Crashlytics,
Analytics, Remote Config, Performance, Messaging and flutter_local_notifications,
plus full APNs configuration for iOS push.
- Wire setupFirebase(env) and setupNotifications() in initApp
- Add firebase_options for dev and staging via flutterfire (sf-platform-pre)
- Register google-services / firebase-perf / crashlytics gradle plugins
- Add per-flavor GoogleService-Info.plist with Build Phase script that
copies the right plist into the .app bundle based on \$CONFIGURATION
- Bump iOS deployment target 13.0 -> 15.0 (required by firebase_analytics)
- Pin flutter_local_notifications to ^19.4.2 (v20+ needs Dart SDK >=3.10)
- Add aps-environment to staging (development) and production entitlements;
development flavor intentionally excluded (no App Store Connect entry)
- Fix AppDelegate.swift to call super.application after forwarding to
AntelopAppDelegate, otherwise Firebase Messaging swizzling breaks and
the APNs token is never captured
- Crashlytics reports in all builds (debug + release) for early detection
- Tag analytics events with env user property per flavor
- App Check intentionally not included (debug-token friction with large
QA team); can be re-added release-only later
The repo had no root-level .gitignore, so .dart_tool/, ephemeral plugin
symlinks and build artifacts were being tracked across the workspace.
Every flutter pub get regenerated them and they polluted PRs as recurring
noise.
- Add root .gitignore covering .dart_tool/, ephemeral plugin symlinks,
build/, coverage/, IDE files
- Untrack ~39 existing cache files across root, modules and packages
- Upgrade Melos to 7.5.1 using Dart pub workspaces (Melos 7 paradigm).
- Replace per-package pubspec_overrides.yaml with workspace-native resolution. Add dependencies.yaml as a centralized catalog for all external deps with sync_deps.dart tool to propagate and validate versions across the monorepo.
- Add DeviceSettingsSync extension on Ref to centralize device provider
updates after settings changes (sound, volume, language, timezone,
battery, disable functions, alerts, pedometer, heart rate freq,
location freq, background image)
- Add photo capture countdown with Lottie animation in remote camera
- Replace Image.network with Image.memory for photo display
- Fix commands datasource to handle text/html responses (post<dynamic>)
- Add typed error/success events to RemoteConnectionViewModel
- Add background image active indicator and backgroundImageId to device settings
- Change photos endpoint from /devices/identificator/:id/photos/files to /photos/files
- Remove dead deviceId param from getBackgroundImage chain
- Relax PictureEntity required fields to @Default for API compatibility
- Fix LocationViewModel rebuild crash (ref.watch → ref.read)
- Use .select() in RemoteCameraScreen for optimized rebuilds
- Increase health measure countdown to 60s
- Rename sms_alert feature to alerts with toggle list from device capabilities
- Implement disable functions (keyboard, GPS) with device settings update
- Implement battery night mode with dedicated view model
- Add keyboard, gps, nightMode fields to DeviceSettingsEntity/Model
- Fix photos endpoint to use /photos/files for file content
- Fix upload flow: capture photo ID from POST /photos response
- Fix endpoint: use /devices/identificator/{id}/photos/files for listing
- Fix setBackgroundImage: use device.id (UUID) instead of identificator
- Redesign screen as photo gallery with grid view
- Add image compression on pick (maxWidth: 800, quality: 80%)
- Fix multipart upload: remove content-type header for FormData auto-detection
- Replace hardcoded Spanish text with i18n in 6 languages
- Add typed error/success enums (BackgroundImageErrorEvent, BackgroundImageSuccessEvent)
- Revert initialLocation to splash
- Add missing translations for contacts and background-image features