changed version check
All checks were successful
Build and Release FLUX (Multi-Platform) / build-android (push) Successful in 1m33s
Build and Release FLUX (Multi-Platform) / build-web (push) Successful in 1m4s
Build and Release FLUX (Multi-Platform) / build-windows (push) Successful in 6m14s

This commit is contained in:
2026-06-04 14:21:27 +02:00
parent 5ce0110197
commit 7ea0e2ac10
3 changed files with 95 additions and 20 deletions

View File

@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:firebase_core/firebase_core.dart'; 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:flux/features/settings/ui/settings.dart';
import 'package:flutter_web_plugins/url_strategy.dart'; import 'package:flutter_web_plugins/url_strategy.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:universal_html/html.dart' as html;
String? initialRecoveryFragment; String? initialRecoveryFragment;
void main() async { void main() async {
@@ -304,21 +306,71 @@ class GlobalUpdateChecker extends StatefulWidget {
State<GlobalUpdateChecker> createState() => _GlobalUpdateCheckerState(); State<GlobalUpdateChecker> createState() => _GlobalUpdateCheckerState();
} }
class _GlobalUpdateCheckerState extends State<GlobalUpdateChecker> { class _GlobalUpdateCheckerState extends State<GlobalUpdateChecker>
with WidgetsBindingObserver {
bool _mustUpdate = false; bool _mustUpdate = false;
String? _updateUrl; String? _updateUrl;
StreamSubscription? _versionSubscription;
@override @override
void initState() { void initState() {
super.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(); final updateUrl = await VersionCheckService().checkForceUpdate();
if (updateUrl != null && mounted) { if (updateUrl != null && mounted) {
// Invece di aprire un dialog, cambiamo lo stato e attiviamo lo "Scudo"
setState(() { setState(() {
_mustUpdate = true; _mustUpdate = true;
_updateUrl = updateUrl; _updateUrl = updateUrl;
@@ -328,21 +380,15 @@ class _GlobalUpdateCheckerState extends State<GlobalUpdateChecker> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// 1. Se l'app è aggiornata, mostriamo solo l'app normale
if (!_mustUpdate) return widget.child; if (!_mustUpdate) return widget.child;
// 2. Se l'app è vecchia, sovrapponiamo il blocco con uno Stack
return Stack( return Stack(
children: [ children: [
// L'app sotto continua ad esistere, ma è inaccessibile
widget.child, widget.child,
// IL BLOCCO INVALICABILE SOPRA A TUTTO
Positioned.fill( Positioned.fill(
child: Container( child: Container(
color: Colors.black.withValues(alpha: 0.85), // Sfondo oscurante color: Colors.black.withValues(alpha: 0.85),
child: Center( child: Center(
// Usiamo Material per ereditare correttamente temi, font e colori
child: Material( child: Material(
color: Colors.transparent, color: Colors.transparent,
child: Container( child: Container(
@@ -386,7 +432,7 @@ class _GlobalUpdateCheckerState extends State<GlobalUpdateChecker> {
const SizedBox(height: 16), const SizedBox(height: 16),
Text( Text(
kIsWeb 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.", : "Per continuare ad utilizzare l'applicazione è necessario scaricare e installare l'ultimo aggiornamento.",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: const TextStyle(fontSize: 16), style: const TextStyle(fontSize: 16),
@@ -399,18 +445,14 @@ class _GlobalUpdateCheckerState extends State<GlobalUpdateChecker> {
style: FilledButton.styleFrom( style: FilledButton.styleFrom(
minimumSize: const Size(double.infinity, 50), minimumSize: const Size(double.infinity, 50),
), ),
onPressed: () async { onPressed: () {
// Trick cross-platform per fare il reload // Hard reload aggirando la cache!
await launchUrl( html.window.location.reload();
Uri.parse(Uri.base.toString()),
webOnlyWindowName: '_self',
);
}, },
) )
else else
FilledButton.icon( FilledButton.icon(
icon: const Icon(Icons.download), icon: const Icon(Icons.download),
label: const Text("SCARICA AGGIORNAMENTO"), label: const Text("SCARICA AGGIORNAMENTO"),
style: FilledButton.styleFrom( style: FilledButton.styleFrom(
minimumSize: const Size(double.infinity, 50), minimumSize: const Size(double.infinity, 50),

View File

@@ -105,6 +105,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.1" version: "1.4.1"
charcode:
dependency: transitive
description:
name: charcode
sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a
url: "https://pub.dev"
source: hosted
version: "1.4.0"
checked_yaml: checked_yaml:
dependency: transitive dependency: transitive
description: description:
@@ -169,6 +177,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.7" version: "3.0.7"
csslib:
dependency: transitive
description:
name: csslib
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
dart_jsonwebtoken: dart_jsonwebtoken:
dependency: transitive dependency: transitive
description: description:
@@ -461,6 +477,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.2" version: "2.0.2"
html:
dependency: transitive
description:
name: html
sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602"
url: "https://pub.dev"
source: hosted
version: "0.15.6"
http: http:
dependency: transitive dependency: transitive
description: description:
@@ -1131,6 +1155,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "1.0.0"
universal_html:
dependency: "direct main"
description:
name: universal_html
sha256: c0bcae5c733c60f26c7dfc88b10b0fd27cbcc45cb7492311cdaa6067e21c9cd4
url: "https://pub.dev"
source: hosted
version: "2.3.0"
universal_io: universal_io:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@@ -1,7 +1,7 @@
name: flux name: flux
description: "Gestione attività negozio di telefonia" description: "Gestione attività negozio di telefonia"
publish_to: 'none' publish_to: 'none'
version: 1.1.17+35 version: 1.1.18+36
environment: environment:
sdk: ^3.11.3 sdk: ^3.11.3
@@ -41,6 +41,7 @@ dependencies:
flutter_staggered_grid_view: ^0.7.0 flutter_staggered_grid_view: ^0.7.0
firebase_core: ^4.9.0 firebase_core: ^4.9.0
firebase_messaging: ^16.2.2 firebase_messaging: ^16.2.2
universal_html: ^2.3.0
dependency_overrides: dependency_overrides:
pdfx: pdfx: