296a622d82
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>
56 lines
1.8 KiB
Dart
56 lines
1.8 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/foundation.dart' show kIsWeb, visibleForTesting;
|
|
|
|
import '../../core/constants/app_constants.dart';
|
|
|
|
class UpdateService {
|
|
static const _apiUrl =
|
|
'https://api.github.com/repos/davide3011/biteplan/releases/latest';
|
|
|
|
/// Returns the latest version string if it's newer than the current version,
|
|
/// or null if already up to date or if the check fails.
|
|
static Future<String?> checkUpdate() async {
|
|
if (kIsWeb) return null;
|
|
try {
|
|
final client = HttpClient()
|
|
..connectionTimeout = const Duration(seconds: 5);
|
|
final request = await client
|
|
.getUrl(Uri.parse(_apiUrl))
|
|
.timeout(const Duration(seconds: 5));
|
|
request.headers
|
|
..set('Accept', 'application/vnd.github+json')
|
|
..set('User-Agent', 'biteplan/$kAppVersion');
|
|
final response =
|
|
await request.close().timeout(const Duration(seconds: 5));
|
|
final body = await response.transform(utf8.decoder).join();
|
|
client.close();
|
|
if (response.statusCode != 200) return null;
|
|
final data = jsonDecode(body) as Map<String, dynamic>;
|
|
final tag = (data['tag_name'] as String).replaceFirst(RegExp(r'^v'), '');
|
|
return isNewer(tag, kAppVersion) ? tag : null;
|
|
} catch (_) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@visibleForTesting
|
|
static bool isNewer(String remote, String local) {
|
|
final r = parseVersion(remote);
|
|
final l = parseVersion(local);
|
|
for (var i = 0; i < 3; i++) {
|
|
if (r[i] > l[i]) return true;
|
|
if (r[i] < l[i]) return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@visibleForTesting
|
|
static List<int> parseVersion(String v) {
|
|
final parts = v.split('.');
|
|
return List.generate(
|
|
3, (i) => i < parts.length ? (int.tryParse(parts[i]) ?? 0) : 0);
|
|
}
|
|
}
|