mirror of
https://github.com/wanghongenpin/proxypin.git
synced 2026-06-01 17:15:48 +08:00
108 lines
3.6 KiB
Dart
108 lines
3.6 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:proxypin/l10n/app_localizations.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:proxypin/network/util/logger.dart';
|
|
import 'package:proxypin/ui/app_update/remote_version_entity.dart';
|
|
import 'package:proxypin/ui/component/app_dialog.dart';
|
|
import 'package:proxypin/ui/configuration.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import 'constants.dart';
|
|
import 'new_version_dialog.dart';
|
|
|
|
class AppUpdateRepository {
|
|
static final HttpClient httpClient = HttpClient();
|
|
|
|
static Future<void> checkUpdate(BuildContext context, {bool canIgnore = true, bool showToast = false}) async {
|
|
try {
|
|
var lastVersion = await getLatestVersion();
|
|
if (lastVersion == null) {
|
|
logger.w("[AppUpdate] failed to fetch latest version info");
|
|
return;
|
|
}
|
|
|
|
if (!context.mounted) return;
|
|
|
|
var availableUpdates = compareVersions(AppConfiguration.version, lastVersion.version);
|
|
if (availableUpdates) {
|
|
if (canIgnore) {
|
|
var ignoreVersion = await SharedPreferencesAsync().getString(Constants.ignoreReleaseVersionKey);
|
|
if (ignoreVersion == lastVersion.version) {
|
|
logger.d("ignored release [${lastVersion.version}]");
|
|
return;
|
|
}
|
|
}
|
|
|
|
logger.d("new version available: $lastVersion");
|
|
|
|
if (!context.mounted) return;
|
|
NewVersionDialog(
|
|
AppConfiguration.version,
|
|
lastVersion,
|
|
canIgnore: true,
|
|
).show(context);
|
|
return;
|
|
}
|
|
|
|
logger.i("already using latest version[${AppConfiguration.version}], last: [${lastVersion.version}]");
|
|
|
|
if (showToast) {
|
|
AppLocalizations localizations = AppLocalizations.of(context)!;
|
|
CustomToast.success(localizations.appUpdateNotAvailableMsg).show(context);
|
|
}
|
|
} catch (e) {
|
|
logger.e("Error checking for updates: $e");
|
|
if (showToast) {
|
|
CustomToast.error(e.toString()).show(context);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Fetches the latest version information from the GitHub releases API.
|
|
static Future<RemoteVersionEntity?> getLatestVersion({bool includePreReleases = false}) async {
|
|
final response = await http.get(Uri.parse(Constants.githubReleasesApiUrl));
|
|
if (response.statusCode != 200 || response.body.isEmpty) {
|
|
logger.w("[AppUpdate] failed to fetch latest version info");
|
|
return null;
|
|
}
|
|
|
|
var body = jsonDecode(response.body) as List;
|
|
final releases = body.map((e) => GithubReleaseParser.parse(e as Map<String, dynamic>));
|
|
late RemoteVersionEntity latest;
|
|
if (includePreReleases) {
|
|
latest = releases.first;
|
|
} else {
|
|
latest = releases.firstWhere((e) => e.preRelease == false);
|
|
}
|
|
|
|
logger.d("[AppUpdate] latest version: $latest");
|
|
return latest;
|
|
}
|
|
|
|
static bool compareVersions(String currentVersion, String latestVersion) {
|
|
String normalizeVersion(String version) {
|
|
return version.startsWith('v') ? version.substring(1) : version;
|
|
}
|
|
|
|
List<int> parseVersion(String version) {
|
|
return normalizeVersion(version).split('.').map(int.parse).toList();
|
|
}
|
|
|
|
List<int> current = parseVersion(currentVersion);
|
|
List<int> latest = parseVersion(latestVersion);
|
|
|
|
for (int i = 0; i < current.length; i++) {
|
|
if (i >= latest.length || current[i] > latest[i]) {
|
|
return false; // 当前版本高于最新版本
|
|
} else if (current[i] < latest[i]) {
|
|
return true; // 需要更新
|
|
}
|
|
}
|
|
|
|
return latest.length > current.length; // 最新版本有更多的子版本号
|
|
}
|
|
}
|