feature/background-image into fusion-app with fixes

- 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
This commit is contained in:
2026-03-25 03:52:24 +01:00
45 changed files with 1574 additions and 53 deletions

View File

@@ -7,6 +7,6 @@
<versions>
<version>2.6.4</version>
</versions>
<lastUpdated>20260323000000</lastUpdated>
<lastUpdated>20260325000000</lastUpdated>
</versioning>
</metadata>

View File

@@ -1 +1 @@
c8bb6b48c804212ad373ce0bb2d28885
afdf53af75a016d3a59635398d34f60d

View File

@@ -1 +1 @@
38e20434b1011d4356d9ae0fd248cc7567df09c3
bf02df387eb61f33404881f4a9a3c80dfa29e6d1

View File

@@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_treezor_entrust_sdk_bridge","path":"/Users/juliandalcalaf/Desktop/save-family-app/sf-app-platform/packages/flutter_treezor_entrust_sdk_bridge/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"integration_test","path":"/Users/juliandalcalaf/Development/flutter/packages/integration_test/","native_build":true,"dependencies":[],"dev_dependency":true}],"android":[{"name":"flutter_treezor_entrust_sdk_bridge","path":"/Users/juliandalcalaf/Desktop/save-family-app/sf-app-platform/packages/flutter_treezor_entrust_sdk_bridge/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"integration_test","path":"/Users/juliandalcalaf/Development/flutter/packages/integration_test/","native_build":true,"dependencies":[],"dev_dependency":true}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"flutter_treezor_entrust_sdk_bridge","dependencies":[]},{"name":"integration_test","dependencies":[]}],"date_created":"2026-03-18 14:45:40.203489","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_treezor_entrust_sdk_bridge","path":"/Users/juliandalcalaf/Desktop/save-family-app/sf-app-platform/packages/flutter_treezor_entrust_sdk_bridge/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"integration_test","path":"/Users/juliandalcalaf/Development/flutter/packages/integration_test/","native_build":true,"dependencies":[],"dev_dependency":true}],"android":[{"name":"flutter_treezor_entrust_sdk_bridge","path":"/Users/juliandalcalaf/Desktop/save-family-app/sf-app-platform/packages/flutter_treezor_entrust_sdk_bridge/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"integration_test","path":"/Users/juliandalcalaf/Development/flutter/packages/integration_test/","native_build":true,"dependencies":[],"dev_dependency":true}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"flutter_treezor_entrust_sdk_bridge","dependencies":[]},{"name":"integration_test","dependencies":[]}],"date_created":"2026-03-25 02:38:14.832197","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}}

View File

@@ -65,6 +65,7 @@ class AppRoutes {
static const appsUse = '$deviceManagement/apps_use';
static const volumeControl = '$deviceManagement/volume_control';
static const callHistory = '$deviceManagement/call_history';
static const backgroundImage = '$deviceManagement/background_image';
static const legacyLogin = '$legacy/login';
static const legacySignup = '$legacy/signup';

View File

@@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.23.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"path_provider_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_android-2.2.22/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.20/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_android-4.10.11/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.23.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"path_provider_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false}],"windows":[{"name":"path_provider_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false}],"web":[{"name":"shared_preferences_web","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"webview_flutter","dependencies":["webview_flutter_android","webview_flutter_wkwebview"]},{"name":"webview_flutter_android","dependencies":[]},{"name":"webview_flutter_wkwebview","dependencies":[]}],"date_created":"2026-03-21 22:57:09.164504","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.23.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"path_provider_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_android-2.2.22/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.20/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_android","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_android-4.10.11/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"path_provider_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.23.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"path_provider_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false}],"windows":[{"name":"path_provider_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false}],"web":[{"name":"shared_preferences_web","path":"/Users/juliandalcalaf/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"webview_flutter","dependencies":["webview_flutter_android","webview_flutter_wkwebview"]},{"name":"webview_flutter_android","dependencies":[]},{"name":"webview_flutter_wkwebview","dependencies":[]}],"date_created":"2026-03-25 02:38:21.345955","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}}

View File

@@ -663,5 +663,14 @@
"errorActivityData": "Aktivitätsdaten konnten nicht geladen werden",
"errorPedometer": "Der Schrittzähler konnte nicht aktualisiert werden",
"errorContactsMin": "Das Gerät muss mindestens einen Kontakt haben",
"errorContactsMax": "Das Gerät kann nicht mehr als 10 Kontakte haben"
"errorContactsMax": "Das Gerät kann nicht mehr als 10 Kontakte haben",
"customBackground": "Benutzerdefiniertes Hintergrundbild",
"backgroundImageDescription": "Legen Sie ein Foto als benutzerdefinierten Bildschirmschoner für das Gerät fest",
"backgroundImageTapToSelect": "Tippen Sie, um ein Foto auszuwählen",
"backgroundImageTapToChange": "Tippen Sie auf das Bild, um den Bildschirmschoner zu ändern",
"backgroundImageUploaded": "Hintergrundbild aktualisiert",
"errorBackgroundImageLoad": "Das Hintergrundbild konnte nicht geladen werden",
"errorBackgroundImageUpload": "Das Hintergrundbild konnte nicht hochgeladen werden",
"errorBackgroundImageSet": "Das Hintergrundbild konnte nicht festgelegt werden",
"backgroundImageSet": "Hintergrundbild erfolgreich festgelegt"
}

View File

@@ -795,5 +795,14 @@
"errorActivityData": "Could not load activity data",
"errorPedometer": "Could not update pedometer",
"errorContactsMin": "The device must have at least one contact",
"errorContactsMax": "The device cannot have more than 10 contacts"
"errorContactsMax": "The device cannot have more than 10 contacts",
"customBackground": "Custom background image",
"backgroundImageDescription": "Set a photo as a custom screensaver for the device",
"backgroundImageTapToSelect": "Tap to select a photo",
"backgroundImageTapToChange": "Tap on the image to change the screensaver",
"backgroundImageUploaded": "Background image updated",
"errorBackgroundImageLoad": "Could not load background image",
"errorBackgroundImageUpload": "Could not upload background image",
"errorBackgroundImageSet": "Could not set background image",
"backgroundImageSet": "Background image set successfully"
}

View File

@@ -793,5 +793,14 @@
"errorActivityData": "No se pudieron cargar los datos de actividad",
"errorPedometer": "No se pudo actualizar el podómetro",
"errorContactsMin": "El dispositivo debe tener al menos un contacto",
"errorContactsMax": "El dispositivo no puede tener más de 10 contactos"
"errorContactsMax": "El dispositivo no puede tener más de 10 contactos",
"customBackground": "Fondo de pantalla personalizado",
"backgroundImageDescription": "Configura una foto como protector de pantalla exclusivo para el dispositivo",
"backgroundImageTapToSelect": "Pulsa para seleccionar una foto",
"backgroundImageTapToChange": "Pulsa en la imagen para cambiar el protector de pantalla",
"backgroundImageUploaded": "Imagen de fondo actualizada",
"errorBackgroundImageLoad": "No se pudo cargar la imagen de fondo",
"errorBackgroundImageUpload": "No se pudo subir la imagen de fondo",
"errorBackgroundImageSet": "No se pudo asignar la imagen de fondo",
"backgroundImageSet": "Imagen de fondo asignada correctamente"
}

View File

@@ -663,5 +663,14 @@
"errorActivityData": "Impossible de charger les données d'activité",
"errorPedometer": "Impossible de mettre à jour le podomètre",
"errorContactsMin": "L'appareil doit avoir au moins un contact",
"errorContactsMax": "L'appareil ne peut pas avoir plus de 10 contacts"
"errorContactsMax": "L'appareil ne peut pas avoir plus de 10 contacts",
"customBackground": "Image de fond personnalisée",
"backgroundImageDescription": "Définissez une photo comme écran de veille personnalisé pour l'appareil",
"backgroundImageTapToSelect": "Appuyez pour sélectionner une photo",
"backgroundImageTapToChange": "Appuyez sur l'image pour changer l'écran de veille",
"backgroundImageUploaded": "Image de fond mise à jour",
"errorBackgroundImageLoad": "Impossible de charger l'image de fond",
"errorBackgroundImageUpload": "Impossible de télécharger l'image de fond",
"errorBackgroundImageSet": "Impossible de définir l'image de fond",
"backgroundImageSet": "Image de fond définie avec succès"
}

View File

@@ -663,5 +663,14 @@
"errorActivityData": "Impossibile caricare i dati di attività",
"errorPedometer": "Impossibile aggiornare il contapassi",
"errorContactsMin": "Il dispositivo deve avere almeno un contatto",
"errorContactsMax": "Il dispositivo non può avere più di 10 contatti"
"errorContactsMax": "Il dispositivo non può avere più di 10 contatti",
"customBackground": "Immagine di sfondo personalizzata",
"backgroundImageDescription": "Imposta una foto come screensaver personalizzato per il dispositivo",
"backgroundImageTapToSelect": "Tocca per selezionare una foto",
"backgroundImageTapToChange": "Tocca l'immagine per cambiare lo screensaver",
"backgroundImageUploaded": "Immagine di sfondo aggiornata",
"errorBackgroundImageLoad": "Impossibile caricare l'immagine di sfondo",
"errorBackgroundImageUpload": "Impossibile caricare l'immagine di sfondo",
"errorBackgroundImageSet": "Impossibile impostare l'immagine di sfondo",
"backgroundImageSet": "Immagine di sfondo impostata con successo"
}

View File

@@ -663,5 +663,14 @@
"errorActivityData": "Não foi possível carregar os dados de atividade",
"errorPedometer": "Não foi possível atualizar o pedómetro",
"errorContactsMin": "O dispositivo deve ter pelo menos um contacto",
"errorContactsMax": "O dispositivo não pode ter mais de 10 contactos"
"errorContactsMax": "O dispositivo não pode ter mais de 10 contactos",
"customBackground": "Imagem de fundo personalizada",
"backgroundImageDescription": "Defina uma foto como protetor de ecrã personalizado para o dispositivo",
"backgroundImageTapToSelect": "Toque para selecionar uma foto",
"backgroundImageTapToChange": "Toque na imagem para alterar o protetor de ecrã",
"backgroundImageUploaded": "Imagem de fundo atualizada",
"errorBackgroundImageLoad": "Não foi possível carregar a imagem de fundo",
"errorBackgroundImageUpload": "Não foi possível carregar a imagem de fundo",
"errorBackgroundImageSet": "Não foi possível definir a imagem de fundo",
"backgroundImageSet": "Imagem de fundo definida com sucesso"
}

View File

@@ -800,4 +800,13 @@ class I18n {
static const String errorPedometer = 'errorPedometer';
static const String errorContactsMin = 'errorContactsMin';
static const String errorContactsMax = 'errorContactsMax';
static const String customBackground = 'customBackground';
static const String backgroundImageDescription = 'backgroundImageDescription';
static const String backgroundImageTapToSelect = 'backgroundImageTapToSelect';
static const String backgroundImageTapToChange = 'backgroundImageTapToChange';
static const String backgroundImageUploaded = 'backgroundImageUploaded';
static const String errorBackgroundImageLoad = 'errorBackgroundImageLoad';
static const String errorBackgroundImageUpload = 'errorBackgroundImageUpload';
static const String errorBackgroundImageSet = 'errorBackgroundImageSet';
static const String backgroundImageSet = 'backgroundImageSet';
}