mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-10 07:50:28 -07:00
feature: Added update notification and download links per platform (#362)
Co-authored-by: PartyDonut <PartyDonut@users.noreply.github.com>
This commit is contained in:
parent
5ef7936c33
commit
2c71dde228
16 changed files with 712 additions and 8 deletions
150
lib/util/update_checker.dart
Normal file
150
lib/util/update_checker.dart
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
|
||||
class ReleaseInfo {
|
||||
final String version;
|
||||
final String changelog;
|
||||
final String url;
|
||||
final bool isNewerThanCurrent;
|
||||
final Map<String, String> downloads;
|
||||
|
||||
ReleaseInfo({
|
||||
required this.version,
|
||||
required this.changelog,
|
||||
required this.url,
|
||||
required this.isNewerThanCurrent,
|
||||
required this.downloads,
|
||||
});
|
||||
|
||||
String? downloadUrlFor(String platform) => downloads[platform];
|
||||
|
||||
Map<String, String> get preferredDownloads {
|
||||
final group = _platformGroup();
|
||||
final entries = downloads.entries.where((e) => e.key.contains(group));
|
||||
return Map.fromEntries(entries);
|
||||
}
|
||||
|
||||
Map<String, String> get otherDownloads {
|
||||
final group = _platformGroup();
|
||||
final entries = downloads.entries.where((e) => !e.key.contains(group));
|
||||
return Map.fromEntries(entries);
|
||||
}
|
||||
|
||||
String _platformGroup() {
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
return 'android';
|
||||
case TargetPlatform.iOS:
|
||||
return 'ios';
|
||||
case TargetPlatform.windows:
|
||||
return 'windows';
|
||||
case TargetPlatform.macOS:
|
||||
return 'macos';
|
||||
case TargetPlatform.linux:
|
||||
return 'linux';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension DownloadLabelFormatter on String {
|
||||
String prettifyKey() {
|
||||
final parts = split('_');
|
||||
if (parts.isEmpty) return this;
|
||||
|
||||
final base = parts.first.capitalize();
|
||||
if (parts.length == 1) return base;
|
||||
|
||||
final variant = parts.sublist(1).join(' ').capitalize();
|
||||
return '$base ($variant)';
|
||||
}
|
||||
|
||||
String capitalize() => isEmpty ? this : '${this[0].toUpperCase()}${substring(1)}';
|
||||
}
|
||||
|
||||
class UpdateChecker {
|
||||
final String owner = 'DonutWare';
|
||||
final String repo = 'Fladder';
|
||||
|
||||
Future<List<ReleaseInfo>> fetchRecentReleases({int count = 5}) async {
|
||||
final info = await PackageInfo.fromPlatform();
|
||||
final currentVersion = info.version;
|
||||
|
||||
final url = Uri.parse('https://api.github.com/repos/$owner/$repo/releases?per_page=$count');
|
||||
final response = await http.get(url);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
print('Failed to fetch releases: ${response.statusCode}');
|
||||
return [];
|
||||
}
|
||||
|
||||
final List<dynamic> releases = jsonDecode(response.body);
|
||||
return releases.map((json) {
|
||||
final tag = (json['tag_name'] as String?)?.replaceFirst(RegExp(r'^v'), '');
|
||||
final changelog = json['body'] as String? ?? '';
|
||||
final htmlUrl = json['html_url'] as String? ?? '';
|
||||
final assets = json['assets'] as List<dynamic>? ?? [];
|
||||
|
||||
final Map<String, String> downloads = {};
|
||||
for (final asset in assets) {
|
||||
final name = asset['name'] as String? ?? '';
|
||||
final downloadUrl = asset['browser_download_url'] as String? ?? '';
|
||||
|
||||
if (name.contains('Android') && name.endsWith('.apk')) {
|
||||
downloads['android'] = downloadUrl;
|
||||
} else if (name.contains('iOS') && name.endsWith('.ipa')) {
|
||||
downloads['ios'] = downloadUrl;
|
||||
} else if (name.contains('Windows') && name.endsWith('Setup.exe')) {
|
||||
downloads['windows_installer'] = downloadUrl;
|
||||
} else if (name.contains('Windows') && name.endsWith('.zip')) {
|
||||
downloads['windows_portable'] = downloadUrl;
|
||||
} else if (name.contains('macOS') && name.endsWith('.dmg')) {
|
||||
downloads['macos'] = downloadUrl;
|
||||
} else if (name.contains('Linux') && name.endsWith('.AppImage')) {
|
||||
downloads['linux_appimage'] = downloadUrl;
|
||||
} else if (name.contains('Linux') && name.endsWith('.flatpak')) {
|
||||
downloads['linux_flatpak'] = downloadUrl;
|
||||
} else if (name.contains('Linux') && name.endsWith('.zip')) {
|
||||
downloads['linux_zip'] = downloadUrl;
|
||||
} else if (name.contains('Linux') && name.endsWith('.zsync')) {
|
||||
downloads['linux_zsync'] = downloadUrl;
|
||||
} else if (name.contains('Web') && name.endsWith('.zip')) {
|
||||
downloads['web'] = downloadUrl;
|
||||
}
|
||||
}
|
||||
|
||||
bool isNewer = tag != null && _compareVersions(tag, currentVersion) > 0;
|
||||
|
||||
return ReleaseInfo(
|
||||
version: tag ?? 'unknown',
|
||||
changelog: changelog.trim(),
|
||||
url: htmlUrl,
|
||||
isNewerThanCurrent: isNewer,
|
||||
downloads: downloads,
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
Future<bool> isUpToDate() async {
|
||||
final releases = await fetchRecentReleases(count: 1);
|
||||
if (releases.isEmpty) return true;
|
||||
return !releases.first.isNewerThanCurrent;
|
||||
}
|
||||
|
||||
static int _compareVersions(String a, String b) {
|
||||
final aParts = a.split('.').map(int.tryParse).toList();
|
||||
final bParts = b.split('.').map(int.tryParse).toList();
|
||||
|
||||
for (var i = 0; i < aParts.length || i < bParts.length; i++) {
|
||||
final aVal = i < aParts.length ? (aParts[i] ?? 0) : 0;
|
||||
final bVal = i < bParts.length ? (bParts[i] ?? 0) : 0;
|
||||
if (aVal != bVal) return aVal.compareTo(bVal);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue