feat: aggiungi controllo aggiornamenti con dialog all'avvio

All'avvio l'app chiama l'API GitHub releases per confrontare la versione
installata con l'ultima disponibile (comparazione semantica major.minor.patch).
Se esiste una versione più recente, mostra un AlertDialog con i pulsanti
"Più tardi" e "Scarica" — quest'ultimo apre releases/latest nel browser.
Il controllo è silenzioso in caso di assenza di rete o errori, e disabilitato
su Flutter web (dart:io non disponibile).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 16:17:53 +02:00
parent 0f1f585b4a
commit 296a622d82
3 changed files with 100 additions and 0 deletions
+36
View File
@@ -4,6 +4,8 @@ import 'features/meal_planner/presentation/pages/meal_planner_page.dart';
import 'features/converter/presentation/pages/converter_page.dart';
import 'features/shopping_list/presentation/pages/shopping_list_page.dart';
import 'features/guide/presentation/widgets/info_bottom_sheet.dart';
import 'shared/services/update_service.dart';
import 'shared/services/url_launcher_service.dart';
class BitePlanApp extends StatelessWidget {
const BitePlanApp({super.key});
@@ -31,6 +33,8 @@ class _MainScaffoldState extends State<_MainScaffold> {
late final List<Widget> _pages;
static const _titles = ['Piano Pasti', 'Convertitore', 'Lista della spesa'];
static const _releasesUrl =
'https://github.com/davide3011/biteplan/releases/latest';
@override
void initState() {
@@ -42,6 +46,38 @@ class _MainScaffoldState extends State<_MainScaffold> {
const ConverterPage(),
const ShoppingListPage(),
];
UpdateService.checkUpdate().then((newVersion) {
if (newVersion != null && mounted) {
_showUpdateDialog(newVersion);
}
});
}
void _showUpdateDialog(String newVersion) {
showDialog<void>(
context: context,
builder: (ctx) => AlertDialog(
icon: const Icon(Icons.system_update_outlined, size: 32),
title: const Text('Aggiornamento disponibile'),
content: Text(
'È disponibile la versione $newVersion di BitePlan.\n'
'Vuoi scaricare il nuovo APK?',
),
actions: [
TextButton(
onPressed: () => Navigator.of(ctx).pop(),
child: const Text('Più tardi'),
),
FilledButton(
onPressed: () {
Navigator.of(ctx).pop();
UrlLauncherService.launch(_releasesUrl);
},
child: const Text('Scarica'),
),
],
),
);
}
@override