diff --git a/lib/main.dart b/lib/main.dart index 76231fa..80780ec 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,6 +2,7 @@ // FILE: lib/main.dart // =========================================================================== +import 'dart:io' show Platform; import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:provider/provider.dart'; @@ -15,6 +16,10 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'firebase_options.dart'; import 'package:firebase_app_check/firebase_app_check.dart'; +// --- NUOVI IMPORT PER GLI AGGIORNAMENTI --- +import 'package:upgrader/upgrader.dart'; +import 'package:in_app_update/in_app_update.dart'; + // --- IMPORT PER IL SUPPORTO MULTILINGUA --- import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:tetraq/l10n/app_localizations.dart'; @@ -71,7 +76,68 @@ class TetraQApp extends StatelessWidget { supportedLocales: AppLocalizations.supportedLocales, // ------------------------------------ - home: const HomeScreen(), + // Avvolgiamo la HomeScreen nel nostro nuovo gestore di aggiornamenti! + home: const UpdateWrapper(child: HomeScreen()), ); } +} + +// =========================================================================== +// WIDGET WRAPPER PER LA GESTIONE DEGLI AGGIORNAMENTI IBRIDI (iOS/Android) +// =========================================================================== +class UpdateWrapper extends StatefulWidget { + final Widget child; + const UpdateWrapper({super.key, required this.child}); + + @override + State createState() => _UpdateWrapperState(); +} + +class _UpdateWrapperState extends State { + @override + void initState() { + super.initState(); + // Controlla gli aggiornamenti in background solo se siamo su Android + if (!kIsWeb && Platform.isAndroid) { + _checkForAndroidUpdate(); + } + } + + Future _checkForAndroidUpdate() async { + try { + final info = await InAppUpdate.checkForUpdate(); + if (info.updateAvailability == UpdateAvailability.updateAvailable) { + // Se possibile, fai scaricare l'aggiornamento in background mentre l'utente gioca + if (info.flexibleUpdateAllowed) { + await InAppUpdate.startFlexibleUpdate(); + await InAppUpdate.completeFlexibleUpdate(); // Chiede il riavvio rapido dell'app + } + // Se l'aggiornamento è impostato come critico dalla console di Google Play + else if (info.immediateUpdateAllowed) { + await InAppUpdate.performImmediateUpdate(); + } + } + } catch (e) { + debugPrint("Errore in_app_update Android: $e"); + } + } + + @override + Widget build(BuildContext context) { + // Su iOS e macOS usiamo "upgrader" che si occupa di mostrare il pop-up nativo + if (!kIsWeb && (Platform.isIOS || Platform.isMacOS)) { + return UpgradeAlert( + upgrader: Upgrader( + debugDisplayAlways: true, // <--- AGGIUNGI QUESTA RIGA PER IL TEST + dialogStyle: Platform.isIOS ? UpgradeDialogStyle.cupertino : UpgradeDialogStyle.material, + showIgnore: false, // Togliamo il tasto "Ignora per sempre" + showLater: true, // Lasciamo il tasto "Ricordamelo più tardi" + ), + child: widget.child, + ); + } + + // Su Android restituiamo la UI normale (l'aggiornamento è gestito nel background da initState) + return widget.child; + } } \ No newline at end of file diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index df55aed..4bc0f61 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -15,6 +15,7 @@ import firebase_core import package_info_plus import share_plus import shared_preferences_foundation +import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) @@ -27,4 +28,5 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 499324c..34526fa 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -1411,6 +1411,8 @@ PODS: - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS + - url_launcher_macos (0.0.1): + - FlutterMacOS DEPENDENCIES: - app_links (from `Flutter/ephemeral/.symlinks/plugins/app_links/macos`) @@ -1424,6 +1426,7 @@ DEPENDENCIES: - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) + - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) SPEC REPOS: trunk: @@ -1472,6 +1475,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos shared_preferences_foundation: :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin + url_launcher_macos: + :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos SPEC CHECKSUMS: abseil: a05cc83bf02079535e17169a73c5be5ba47f714b @@ -1506,6 +1511,7 @@ SPEC CHECKSUMS: PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 share_plus: 510bf0af1a42cd602274b4629920c9649c52f4cc shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb + url_launcher_macos: f87a979182d112f911de6820aefddaf56ee9fbfd PODFILE CHECKSUM: 54d867c82ac51cbd61b565781b9fada492027009 diff --git a/pubspec.lock b/pubspec.lock index b535e12..0b596b5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -225,6 +225,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.7" + csslib: + dependency: transitive + description: + name: csslib + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" + url: "https://pub.dev" + source: hosted + version: "1.0.2" cupertino_icons: dependency: "direct main" description: @@ -429,6 +437,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" + html: + dependency: transitive + description: + name: html + sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" + url: "https://pub.dev" + source: hosted + version: "0.15.6" http: dependency: transitive description: @@ -453,6 +469,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.8.0" + in_app_update: + dependency: "direct main" + description: + name: in_app_update + sha256: "9924a3efe592e1c0ec89dda3683b3cfec3d4cd02d908e6de00c24b759038ddb1" + url: "https://pub.dev" + source: hosted + version: "4.2.5" intl: dependency: "direct main" description: @@ -573,6 +597,14 @@ packages: url: "https://pub.dev" source: hosted version: "9.3.0" + os_detect: + dependency: transitive + description: + name: os_detect + sha256: "7d87c0dd98c6faf110d5aa498e9a6df02ffce4bb78cc9cfc8ad02929be9bb71f" + url: "https://pub.dev" + source: hosted + version: "2.0.3" package_info_plus: dependency: "direct main" description: @@ -834,6 +866,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + upgrader: + dependency: "direct main" + description: + name: upgrader + sha256: "3fae4eb861c7e8567f91412d9ca4a287e024e58d6f79f98da79e3f6d78da74ba" + url: "https://pub.dev" + source: hosted + version: "12.5.0" + url_launcher: + dependency: transitive + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611" + url: "https://pub.dev" + source: hosted + version: "6.3.28" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" + url: "https://pub.dev" + source: hosted + version: "6.4.1" url_launcher_linux: dependency: transitive description: @@ -842,6 +906,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.2" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + url: "https://pub.dev" + source: hosted + version: "3.2.5" url_launcher_platform_interface: dependency: transitive description: @@ -882,6 +954,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + version: + dependency: transitive + description: + name: version + sha256: "3d4140128e6ea10d83da32fef2fa4003fccbf6852217bb854845802f04191f94" + url: "https://pub.dev" + source: hosted + version: "3.0.2" vm_service: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 54d6790..f22bc08 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -28,6 +28,10 @@ dependencies: package_info_plus: ^9.0.0 device_info_plus: ^12.3.0 + # --- NUOVI PACCHETTI PER GLI AGGIORNAMENTI --- + upgrader: ^12.5.0 + in_app_update: ^4.2.0 + dev_dependencies: flutter_test: sdk: flutter