Commit Graph

356 Commits

Author SHA1 Message Date
a547f7a786 refactor(legacy-account): move delete_account dialog state to provider (no setState) 2026-04-22 00:30:20 +02:00
42698631a3 refactor(legacy-account): move personal_data form state to provider (no setState) 2026-04-22 00:16:48 +02:00
69fdc2233f refactor(legacy-account): move change_password local error to provider (no setState) 2026-04-22 00:10:43 +02:00
75b47e2c25 refactor(legacy-settings): move language selection state to provider (no setState) 2026-04-22 00:00:14 +02:00
1c0a8b7bb7 refactor(legacy-settings): migrate language to AsyncNotifier 2026-04-21 23:51:38 +02:00
417b6660fc refactor(legacy-customer-service): migrate contact form to AsyncNotifier 2026-04-21 23:45:41 +02:00
b8ac786146 refactor(sf_shared): add help center URL to BrandLinks 2026-04-21 23:33:12 +02:00
dd1617939b refactor(sf_shared): move brand links to Firebase Remote Config 2026-04-21 23:32:26 +02:00
4c85af38aa refactor(legacy-account): use .select for AsyncValue field reads 2026-04-21 23:32:01 +02:00
309ff8b8b7 refactor(legacy-account): migrate account_settings to AsyncNotifier 2026-04-21 23:31:56 +02:00
e040944965 refactor(legacy-account): migrate delete_account to AsyncNotifier + fix A1 2026-04-21 22:12:51 +02:00
b6526f20ee refactor(legacy-account): migrate linked_devices to AsyncNotifier 2026-04-21 21:47:36 +02:00
0418f16f87 fix(sf_shared): distinguish 401 vs 403 error UX 2026-04-21 21:34:32 +02:00
f36ad5e4a6 refactor(legacy-account): migrate personal_data to AsyncNotifier 2026-04-21 21:00:42 +02:00
0a50941c2b fix(legacy-account): show success dialog after password change 2026-04-21 20:49:13 +02:00
7746d08759 refactor(legacy-account): migrate change_password to AsyncNotifier 2026-04-21 20:35:18 +02:00
72c88cc4b0 refactor(legacy-account): migrate app_users to FutureProvider 2026-04-21 20:03:45 +02:00
b21b234b9a feat(sf_tracking): consent-aware crashlytics wrapper 2026-04-21 19:33:54 +02:00
f89bca99b3 feat(sf_shared): add FailureType + handleFailure + feedback dialogs 2026-04-21 19:32:49 +02:00
1056895c31 chore(legacy): add test infrastructure + mocktail 2026-04-21 19:32:40 +02:00
424b8d9034 fix 2026-04-21 18:24:25 +02:00
4aa91c355e Revert "docs: add snackbar messages reference in Spanish"
This reverts commit 7ea415cb6e.
2026-04-21 18:15:07 +02:00
7ea415cb6e docs: add snackbar messages reference in Spanish 2026-04-21 17:59:58 +02:00
21fd1e0197 chore(i18n): add missing translation keys and device debug logging 2026-04-21 17:59:50 +02:00
d618ed76d0 feat(wifi): enable wifi settings entry point and add debug logging 2026-04-21 17:59:39 +02:00
dfd7ba9c41 fix(sos-contacts): prevent deleting last emergency contact 2026-04-21 17:59:29 +02:00
b8f5c5d6f8 feat(block-phone): add edit contact functionality 2026-04-21 17:59:16 +02:00
d470ed470a fix(location): add sharePositionOrigin for iPad share 2026-04-21 17:59:08 +02:00
a400fef77d fix(control-panel): match dropdown value by device id to prevent crash 2026-04-21 17:59:00 +02:00
febc21a590 fix(do-not-disturb): return empty schedule on 404 instead of error 2026-04-21 17:58:52 +02:00
29fca859fc fix(personal-data): send all required fields in PUT and autofill form 2026-04-21 17:58:44 +02:00
d92fe887fd fix(rewards): send rewards key instead of amount in command data 2026-04-21 17:58:27 +02:00
315e5b2908 fix(volume): use capabilities max per slider and fix 0-10 scale 2026-04-21 17:58:20 +02:00
244e5bbd03 feat(capabilities): add volume limits (media, ringtone, alarm) 2026-04-21 17:58:12 +02:00
a86041885c feat(settings): add falldown, falldownLevel and rename gps to location 2026-04-21 17:58:03 +02:00
12011ce525 fix(notifications): handle deep linking on cold start without crash 2026-04-21 17:57:53 +02:00
c92e2fb67f refactor(legacy): align with Riverpod architecture (DTOs, repos, drop UseCases) 2026-04-19 23:20:38 +02:00
7e1ead9cae refactor(legacy): split legacy_shared into cohesive packages
legacy_shared was the junk drawer of the legacy app mode — 37 files
mixing device entities, command infrastructure, UI primitives, generic
formatters, and a duplicate of sf_infrastructure's dio_error_mapper.
Any module needing one piece pulled the whole bag into its graph.

Split it by responsibility, following Mandamiento 4 of Real-World Flutter:

- legacy_ui (new): 6 widget/layout primitives (PageLayout, MenuButton,
  SectionButton, PulsingLocationMarker, RefreshableErrorState,
  WeekDayChips) plus mapStyleProvider — shared UI state that was the
  only reason two modules needed a common package.
- legacy_device_state (expanded 9 → 30): absorbed device entities,
  commands infrastructure (datasource + repo + provider + guard),
  device settings update flow, and the CSV exporter. Now one package
  owns the device domain end-to-end.
- packages/utils: absorbed battery_utils and date_format_utils as pure
  formatters that never belonged in a legacy-scoped package.
- legacy_shared: deleted entirely.

The duplicate dio_error_mapper in legacy_shared is gone; callers now use
the sf_infrastructure version (which was always the superset — it adds
ApiException and the dart:io socket handling).

DeviceEntity note: legacy_device_state keeps its own DeviceEntity (with
int timestamps and typed paymentOptions) separate from sf_shared's
DeviceEntity (String timestamps, untyped paymentOptions). The legacy
one is intentionally not exported from the barrel to avoid the
ambiguous_import collision that legacy_shared quietly hid by never
exporting it in the first place. Unifying the two is a domain-model
refactor out of scope here.

0 cross-module imports remain among legacy feature modules.
2026-04-19 05:42:31 +02:00
e59ce36033 chore(sf_localizations): switch i18n source to es.json and add parity check
Spanish is the app default (SFLocalizations.testInit uses 'es',
localeResolutionCallback falls back to the first supported locale), so
make that explicit by pointing the code generator at es.json instead of
en.json. Regenerating picked up 12 activity-meter keys that were already
present in every locale file but had drifted out of I18n.

Add scripts/check_i18n_parity.dart: treats es.json as the template and
reports any missing or orphan keys in en/fr/de/it/pt. Exits non-zero so
it can gate CI or a pre-commit hook later.
2026-04-19 04:58:09 +02:00
aa3ffdb6a7 refactor(legacy): migrate theming to Material 3 + SfColors extension
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.
2026-04-19 04:47:22 +02:00
2eddb99c47 chore: ignore flutter auto-generated files
These files are regenerated by flutter pub get and contain machine-
specific paths (FLUTTER_ROOT, FLUTTER_APPLICATION_PATH). They should
not be tracked — the file header itself states "do not check into
version control".

- Update .gitignore: prepend **/ to .flutter-plugins-dependencies so
  it matches in sub-packages, add Generated.xcconfig and
  flutter_export_environment.sh patterns.
- git rm --cached the 4 files that were already tracked (keeps them
  on disk for local builds but removes from repo).
2026-04-19 01:58:45 +02:00
c461519597 refactor(legacy): extract shared device state into legacy_device_state package
- New package legacy_device_state hosts shared device/position state
  consumed by both control_panel and location screens. ControlPanel*
  classes renamed to LegacyDevice* in 8 moved files.
- Move PositionEntity + AddressEntity + NetworkEntity +
  LatestPositionsResponseModel + BatteryUtils + DateFormatUtils from
  control_panel to legacy_shared (shared domain entities).
- Remove anti-pattern re-export of sf_infrastructure/dio_error_mapper
  from legacy_shared barrel. Update consumers to import
  sf_infrastructure directly.
- Clean 14 unused legacy_shared imports across view models in
  account, device_management, legacy_auth and settings modules.

Eliminates cross-module dependency location -> control_panel.
0 errors, 0 warnings in flutter analyze across 11 packages/modules.
2026-04-19 01:55:11 +02:00
919ee55c45 fix(location): keep map visible on transient network errors
Show snackbar instead of replacing the entire map with an error state
when a reload fails. Only show RefreshableErrorState on first load failure.
2026-04-17 17:49:25 +02:00
f5350f5e78 fix(location): guard frequency timer minimum and filter zero options
Prevent position polling timer from firing with frequency < 60s (protects
against 0s values that saturate the API). Also filter out 0 from location
capability options in the frequency selector.
2026-04-17 17:11:01 +02:00
e7ebe7f403 fix 2026-04-17 15:13:34 +02:00
ed41b82076 chore(legacy): hide wifi settings and forgot password entry points
Comment out the navigation entry points for the wifi settings flow
from the device settings list and for the forgot-password link from
the login screen while these flows wait for product sign-off. The
underlying screens and providers stay in place so re-enabling them is
a single uncomment.
2026-04-17 11:16:08 +02:00
9470f54867 chore(notifications): log push token registration outcome for debugging
Add debugPrint entries before and after POST /universal-notifications/push
so we can trace whether a given token was accepted by the backend
during debugging of push delivery issues.
2026-04-17 11:13:59 +02:00
f82d222df3 style(device_setup): redesign activation code dialog with icon and OK action
Replace the bare centered text with a rounded dialog that leads with a
mail icon, keeps the activation-code message, and adds an explicit OK
button to dismiss. Aligns the dialog with the rest of the legacy
design system.
2026-04-17 11:13:53 +02:00
fd8ef27185 feat(splash): route to device setup when a logged-in user has zero devices
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.
2026-04-17 11:13:48 +02:00
5b6ed5cf16 fix(config): swap production apiBaseUrl and apiOrigin back to correct hosts
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.
2026-04-17 11:13:40 +02:00