Files
umbrix/lib/features/app_update/model/remote_version_entity.dart
Umbrix Developer 04eccff819
Some checks are pending
CI / run (push) Waiting to run
feat: Android auto-update notifications with dialog
- Add auto-check updates for Android in bootstrap
- Show update dialog instead of toast notification
- Same UX as Desktop: dialog with 'Later' and 'Update' buttons
- Notifications appear 5 seconds after app launch

Part of v1.7.6
2026-01-20 19:36:33 +03:00

121 lines
3.9 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:umbrix/core/model/environment.dart';
part 'remote_version_entity.freezed.dart';
@Freezed()
class RemoteVersionEntity with _$RemoteVersionEntity {
const RemoteVersionEntity._();
const factory RemoteVersionEntity({
required String version,
required String buildNumber,
required String releaseTag,
required bool preRelease,
required String url,
required DateTime publishedAt,
required Environment flavor,
@Default([]) List<ReleaseAsset> assets,
}) = _RemoteVersionEntity;
String get presentVersion => flavor == Environment.prod ? version : "$version ${flavor.name}";
/// Найти asset по расширению файла с умным определением
String? findAssetByExtension(String extension) {
try {
// Для Linux используем приоритет: .deb > .rpm > .AppImage
if (extension == '.deb' || extension == '.rpm' || extension == '.AppImage') {
final priorities = ['.deb', '.rpm', '.AppImage'];
for (final ext in priorities) {
try {
final asset = assets.firstWhere((asset) => asset.name.endsWith(ext));
return asset.downloadUrl;
} catch (_) {
continue;
}
}
return null;
}
// Для Windows - ищем .exe или .zip
if (extension == '.exe' || extension == '.zip') {
final targetExt = extension;
// Приоритет для zip: portable -> windows -> любой .zip
if (targetExt == '.zip') {
for (final pattern in ['portable', 'windows', 'win']) {
try {
final asset = assets.firstWhere(
(asset) => asset.name.toLowerCase().contains(pattern) && asset.name.endsWith('.zip'),
);
return asset.downloadUrl;
} catch (_) {
continue;
}
}
}
// Приоритет для exe: x64 setup/installer
if (targetExt == '.exe') {
for (final pattern in ['x64', 'amd64', 'win64', 'setup', 'installer']) {
try {
final asset = assets.firstWhere(
(asset) => asset.name.toLowerCase().contains(pattern) && asset.name.endsWith('.exe'),
);
return asset.downloadUrl;
} catch (_) {
continue;
}
}
}
// Если не нашли специфичный - берём любой с нужным расширением
try {
final asset = assets.firstWhere((asset) => asset.name.endsWith(targetExt));
return asset.downloadUrl;
} catch (_) {
return null;
}
}
// Для macOS - ищем .dmg
if (extension == '.dmg') {
// Сначала ищем universal или arm64 (для M1/M2)
for (final pattern in ['universal', 'arm64', 'apple-silicon']) {
try {
final asset = assets.firstWhere(
(asset) => asset.name.toLowerCase().contains(pattern) && asset.name.endsWith('.dmg'),
);
return asset.downloadUrl;
} catch (_) {
continue;
}
}
// Если не нашли - берём любой .dmg
try {
final asset = assets.firstWhere((asset) => asset.name.endsWith('.dmg'));
return asset.downloadUrl;
} catch (_) {
return null;
}
}
// Для других расширений - прямой поиск
return assets.firstWhere((asset) => asset.name.endsWith(extension)).downloadUrl;
} catch (_) {
return null;
}
}
}
@freezed
class ReleaseAsset with _$ReleaseAsset {
const factory ReleaseAsset({
required String name,
required String downloadUrl,
required int size,
}) = _ReleaseAsset;
}