Initial project import
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
class AppRelease {
|
||||
final String id;
|
||||
final String versionName;
|
||||
final int buildNumber;
|
||||
final String downloadUrl;
|
||||
final String releaseNotes;
|
||||
final String? sha256;
|
||||
final int? fileSize;
|
||||
final DateTime? publishedAt;
|
||||
|
||||
const AppRelease({
|
||||
required this.id,
|
||||
required this.versionName,
|
||||
required this.buildNumber,
|
||||
required this.downloadUrl,
|
||||
required this.releaseNotes,
|
||||
required this.sha256,
|
||||
required this.fileSize,
|
||||
required this.publishedAt,
|
||||
});
|
||||
|
||||
factory AppRelease.fromJson(Map<String, dynamic> json) {
|
||||
final id = json['id']?.toString().trim() ?? '';
|
||||
final versionName = json['versionName']?.toString().trim() ?? '';
|
||||
final buildNumber = (json['buildNumber'] as num?)?.toInt() ?? -1;
|
||||
final downloadUrl = json['downloadUrl']?.toString().trim() ?? '';
|
||||
if (id.isEmpty ||
|
||||
versionName.isEmpty ||
|
||||
buildNumber < 0 ||
|
||||
downloadUrl.isEmpty) {
|
||||
throw const FormatException('更新服务返回了不完整的版本信息');
|
||||
}
|
||||
return AppRelease(
|
||||
id: id,
|
||||
versionName: versionName,
|
||||
buildNumber: buildNumber,
|
||||
downloadUrl: downloadUrl,
|
||||
releaseNotes: json['releaseNotes']?.toString().trim() ?? '',
|
||||
sha256: json['sha256']?.toString().trim().nullIfEmpty,
|
||||
fileSize: (json['fileSize'] as num?)?.toInt(),
|
||||
publishedAt: DateTime.tryParse(json['publishedAt']?.toString() ?? ''),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateCheckResponse {
|
||||
final bool hasUpdate;
|
||||
final bool forceUpdate;
|
||||
final AppRelease? release;
|
||||
|
||||
const UpdateCheckResponse({
|
||||
required this.hasUpdate,
|
||||
required this.forceUpdate,
|
||||
required this.release,
|
||||
});
|
||||
|
||||
factory UpdateCheckResponse.fromJson(Map<String, dynamic> json) {
|
||||
final releaseJson = json['release'];
|
||||
final release = releaseJson is Map
|
||||
? AppRelease.fromJson(Map<String, dynamic>.from(releaseJson))
|
||||
: null;
|
||||
final hasUpdate = json['hasUpdate'] == true;
|
||||
if (hasUpdate && release == null) {
|
||||
throw const FormatException('更新服务未返回目标版本');
|
||||
}
|
||||
return UpdateCheckResponse(
|
||||
hasUpdate: hasUpdate,
|
||||
forceUpdate: json['forceUpdate'] == true,
|
||||
release: release,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension on String {
|
||||
String? get nullIfEmpty => isEmpty ? null : this;
|
||||
}
|
||||
|
||||
class UpdatePolicy {
|
||||
UpdatePolicy._();
|
||||
|
||||
static AppRelease? availableRelease(
|
||||
UpdateCheckResponse response, {
|
||||
required int currentBuild,
|
||||
}) {
|
||||
final release = response.release;
|
||||
if (!response.hasUpdate || release == null) return null;
|
||||
return release.buildNumber > currentBuild ? release : null;
|
||||
}
|
||||
|
||||
static bool shouldPresent({
|
||||
required AppRelease release,
|
||||
required bool forced,
|
||||
required bool manual,
|
||||
required String? ignoredReleaseId,
|
||||
}) {
|
||||
if (forced || manual) return true;
|
||||
return ignoredReleaseId != release.id;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user