feat(version-check): add in-app update prompt with Remote Config

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
This commit is contained in:
2026-04-09 14:52:37 +02:00
parent 506dd5a80f
commit 693f55369c
24 changed files with 887 additions and 31 deletions

View File

@@ -857,5 +857,11 @@
"videoCall": "Videoanruf",
"watchesOnMap": "Smartwatches auf der Karte:",
"wifiSettings": "WLAN-Einstellungen",
"yesterday": "Gestern"
"yesterday": "Gestern",
"appUpdateAvailableTitle": "Update verfügbar",
"appUpdateAvailableMessage": "Eine neue Version von SaveFamily ist verfügbar.",
"appUpdateRequiredTitle": "Update erforderlich",
"appUpdateRequiredMessage": "Du musst SaveFamily aktualisieren, um die App weiterhin zu nutzen.",
"appUpdateLater": "Später",
"appUpdateNow": "Jetzt aktualisieren"
}

View File

@@ -857,5 +857,11 @@
"renewCardPinTitle": "Enter your security PIN to renew the card",
"renewCardSuccess": "Card renewed successfully",
"renewCardError": "Error renewing card",
"passwordLabel": "Password (6 to 12 characters)"
"passwordLabel": "Password (6 to 12 characters)",
"appUpdateAvailableTitle": "Update available",
"appUpdateAvailableMessage": "A new version of SaveFamily is available.",
"appUpdateRequiredTitle": "Update required",
"appUpdateRequiredMessage": "You need to update SaveFamily to keep using the app.",
"appUpdateLater": "Later",
"appUpdateNow": "Update now"
}

View File

@@ -857,5 +857,11 @@
"renewCardTokenHint": "Introduce el código de la nueva tarjeta",
"renewCardPinTitle": "Introduce tu PIN de seguridad para renovar la tarjeta",
"renewCardSuccess": "Tarjeta renovada correctamente",
"renewCardError": "Error al renovar la tarjeta"
"renewCardError": "Error al renovar la tarjeta",
"appUpdateAvailableTitle": "Actualización disponible",
"appUpdateAvailableMessage": "Hay una nueva versión de SaveFamily disponible.",
"appUpdateRequiredTitle": "Actualización requerida",
"appUpdateRequiredMessage": "Necesitas actualizar SaveFamily para seguir usando la app.",
"appUpdateLater": "Más tarde",
"appUpdateNow": "Actualizar ahora"
}

View File

@@ -857,5 +857,11 @@
"videoCall": "Appel vidéo",
"watchesOnMap": "Montres connectées sur la carte :",
"wifiSettings": "Paramètres WiFi",
"yesterday": "Hier"
"yesterday": "Hier",
"appUpdateAvailableTitle": "Mise à jour disponible",
"appUpdateAvailableMessage": "Une nouvelle version de SaveFamily est disponible.",
"appUpdateRequiredTitle": "Mise à jour requise",
"appUpdateRequiredMessage": "Vous devez mettre à jour SaveFamily pour continuer à utiliser l'application.",
"appUpdateLater": "Plus tard",
"appUpdateNow": "Mettre à jour maintenant"
}

View File

@@ -857,5 +857,11 @@
"videoCall": "Videochiamata",
"watchesOnMap": "Smartwatch sulla mappa:",
"wifiSettings": "Impostazioni WiFi",
"yesterday": "Ieri"
"yesterday": "Ieri",
"appUpdateAvailableTitle": "Aggiornamento disponibile",
"appUpdateAvailableMessage": "È disponibile una nuova versione di SaveFamily.",
"appUpdateRequiredTitle": "Aggiornamento richiesto",
"appUpdateRequiredMessage": "Devi aggiornare SaveFamily per continuare a usare l'app.",
"appUpdateLater": "Più tardi",
"appUpdateNow": "Aggiorna ora"
}

View File

@@ -857,5 +857,11 @@
"videoCall": "Videochamada",
"watchesOnMap": "Relógios inteligentes no mapa:",
"wifiSettings": "Configurações WiFi",
"yesterday": "Ontem"
"yesterday": "Ontem",
"appUpdateAvailableTitle": "Atualização disponível",
"appUpdateAvailableMessage": "Há uma nova versão do SaveFamily disponível.",
"appUpdateRequiredTitle": "Atualização necessária",
"appUpdateRequiredMessage": "Precisas atualizar o SaveFamily para continuar a usar a app.",
"appUpdateLater": "Mais tarde",
"appUpdateNow": "Atualizar agora"
}