changed version check
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
@@ -47,6 +48,7 @@ import 'package:flux/features/master_data/store/data/store_repository.dart';
|
||||
import 'package:flux/features/settings/ui/settings.dart';
|
||||
import 'package:flutter_web_plugins/url_strategy.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
|
||||
String? initialRecoveryFragment;
|
||||
void main() async {
|
||||
@@ -304,21 +306,71 @@ class GlobalUpdateChecker extends StatefulWidget {
|
||||
State<GlobalUpdateChecker> createState() => _GlobalUpdateCheckerState();
|
||||
}
|
||||
|
||||
class _GlobalUpdateCheckerState extends State<GlobalUpdateChecker> {
|
||||
class _GlobalUpdateCheckerState extends State<GlobalUpdateChecker>
|
||||
with WidgetsBindingObserver {
|
||||
bool _mustUpdate = false;
|
||||
String? _updateUrl;
|
||||
StreamSubscription? _versionSubscription;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_checkVersionAndBlock();
|
||||
// 🥷 1. Registriamo questo widget per ascoltare i cicli vitali dell'app
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
_startRealtimeVersionCheck();
|
||||
}
|
||||
|
||||
Future<void> _checkVersionAndBlock() async {
|
||||
@override
|
||||
void dispose() {
|
||||
// 🥷 2. Rimuoviamo l'observer quando il widget muore (mai, in questo caso, ma è buona norma)
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
_stopRealtimeVersionCheck();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// 🥷 3. IL VERO GESTORE DEL CICLO VITALE
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
super.didChangeAppLifecycleState(state);
|
||||
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
// L'app è tornata attiva: riaccendiamo il radar
|
||||
_startRealtimeVersionCheck();
|
||||
} else if (state == AppLifecycleState.paused ||
|
||||
state == AppLifecycleState.hidden) {
|
||||
// L'app è andata in background: spegniamo il socket per evitare crash
|
||||
_stopRealtimeVersionCheck();
|
||||
}
|
||||
}
|
||||
|
||||
void _startRealtimeVersionCheck() {
|
||||
// Sicurezza: cancelliamo eventuali vecchi abbonamenti rimasti appesi
|
||||
_stopRealtimeVersionCheck();
|
||||
|
||||
// Facciamo un check immediato non appena rientriamo in app
|
||||
_checkVersion();
|
||||
|
||||
// Riapriamo il rubinetto di Supabase
|
||||
_versionSubscription = GetIt.I<SupabaseClient>()
|
||||
.from(
|
||||
'app_versions',
|
||||
) // <-- Sostituisci col nome reale della tua tabella
|
||||
.stream(primaryKey: ['id'])
|
||||
.listen((_) {
|
||||
_checkVersion();
|
||||
});
|
||||
}
|
||||
|
||||
void _stopRealtimeVersionCheck() {
|
||||
// Chiudiamo gentilmente il socket
|
||||
_versionSubscription?.cancel();
|
||||
_versionSubscription = null;
|
||||
}
|
||||
|
||||
Future<void> _checkVersion() async {
|
||||
final updateUrl = await VersionCheckService().checkForceUpdate();
|
||||
|
||||
if (updateUrl != null && mounted) {
|
||||
// Invece di aprire un dialog, cambiamo lo stato e attiviamo lo "Scudo"
|
||||
setState(() {
|
||||
_mustUpdate = true;
|
||||
_updateUrl = updateUrl;
|
||||
@@ -328,21 +380,15 @@ class _GlobalUpdateCheckerState extends State<GlobalUpdateChecker> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// 1. Se l'app è aggiornata, mostriamo solo l'app normale
|
||||
if (!_mustUpdate) return widget.child;
|
||||
|
||||
// 2. Se l'app è vecchia, sovrapponiamo il blocco con uno Stack
|
||||
return Stack(
|
||||
children: [
|
||||
// L'app sotto continua ad esistere, ma è inaccessibile
|
||||
widget.child,
|
||||
|
||||
// IL BLOCCO INVALICABILE SOPRA A TUTTO
|
||||
Positioned.fill(
|
||||
child: Container(
|
||||
color: Colors.black.withValues(alpha: 0.85), // Sfondo oscurante
|
||||
color: Colors.black.withValues(alpha: 0.85),
|
||||
child: Center(
|
||||
// Usiamo Material per ereditare correttamente temi, font e colori
|
||||
child: Material(
|
||||
color: Colors.transparent,
|
||||
child: Container(
|
||||
@@ -386,7 +432,7 @@ class _GlobalUpdateCheckerState extends State<GlobalUpdateChecker> {
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
kIsWeb
|
||||
? "È stata rilasciata una nuova versione dell'applicazione. Ricarica la pagina per continuare."
|
||||
? "È stata rilasciata una nuova versione dell'applicazione. Ricarica la pagina per scaricare il nuovo codice."
|
||||
: "Per continuare ad utilizzare l'applicazione è necessario scaricare e installare l'ultimo aggiornamento.",
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(fontSize: 16),
|
||||
@@ -399,18 +445,14 @@ class _GlobalUpdateCheckerState extends State<GlobalUpdateChecker> {
|
||||
style: FilledButton.styleFrom(
|
||||
minimumSize: const Size(double.infinity, 50),
|
||||
),
|
||||
onPressed: () async {
|
||||
// Trick cross-platform per fare il reload
|
||||
await launchUrl(
|
||||
Uri.parse(Uri.base.toString()),
|
||||
webOnlyWindowName: '_self',
|
||||
);
|
||||
onPressed: () {
|
||||
// Hard reload aggirando la cache!
|
||||
html.window.location.reload();
|
||||
},
|
||||
)
|
||||
else
|
||||
FilledButton.icon(
|
||||
icon: const Icon(Icons.download),
|
||||
|
||||
label: const Text("SCARICA AGGIORNAMENTO"),
|
||||
style: FilledButton.styleFrom(
|
||||
minimumSize: const Size(double.infinity, 50),
|
||||
|
||||
Reference in New Issue
Block a user