mirror of
https://github.com/zapstore/zapstore.git
synced 2026-10-05 20:48:24 +00:00
115 lines
4.3 KiB
Dart
115 lines
4.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:models/models.dart';
|
|
import 'package:zapstore/constants/app_constants.dart';
|
|
import 'package:zapstore/services/package_manager/package_manager.dart';
|
|
|
|
export 'package:zapstore/constants/app_constants.dart';
|
|
|
|
extension WidgetExt on WidgetRef {
|
|
StorageNotifier get storage => read(storageNotifierProvider.notifier);
|
|
PackageManager get packageManager => read(packageManagerProvider.notifier);
|
|
}
|
|
|
|
extension ContextExt on BuildContext {
|
|
TextTheme get textTheme => Theme.of(this).textTheme;
|
|
}
|
|
|
|
extension AppExt on App {
|
|
/// Whether this app is one of Zapstore's own apps
|
|
bool get isZapstoreApp => identifier == kZapstoreAppIdentifier;
|
|
|
|
/// Whether this app is signed by Zapstore pubkey
|
|
bool get isSignedByZapstore => pubkey == kZapstorePubkey;
|
|
|
|
/// Whether this app is "relay signed" - indexed by Zapstore but not a Zapstore app itself
|
|
bool get isRelaySigned => isSignedByZapstore && !isZapstoreApp;
|
|
|
|
/// Returns PackageInfo if installed, otherwise null
|
|
PackageInfo? get installedPackage =>
|
|
ref.read(packageManagerProvider).installed[identifier];
|
|
|
|
/// Whether the app is installed on the device
|
|
bool get isInstalled =>
|
|
ref.read(packageManagerProvider.notifier).isInstalled(identifier);
|
|
|
|
/// Latest file metadata associated to the latest release
|
|
/// Prefers SoftwareAsset (new format) over FileMetadata (old format)
|
|
/// Note: assumes latest metadata has been loaded for the current platform
|
|
FileMetadata? get latestFileMetadata =>
|
|
latestRelease.value?.latestAsset.value ??
|
|
latestRelease.value?.latestMetadata.value;
|
|
|
|
/// Whether there is an update available for the installed app.
|
|
/// Delegates to PackageManager (versionCode-only comparison).
|
|
bool get hasUpdate {
|
|
final latest = latestFileMetadata;
|
|
if (latest == null) return false;
|
|
return ref.read(packageManagerProvider.notifier).hasUpdate(identifier, latest);
|
|
}
|
|
|
|
/// Whether the relay version would be a downgrade from the installed version.
|
|
/// Delegates to PackageManager (versionCode-only comparison).
|
|
bool get hasDowngrade {
|
|
final latest = latestFileMetadata;
|
|
if (latest == null) return false;
|
|
return ref.read(packageManagerProvider.notifier).hasDowngrade(identifier, latest);
|
|
}
|
|
|
|
/// Whether the installed app is up to date (installed and no update)
|
|
bool get isUpdated => isInstalled && !hasUpdate;
|
|
}
|
|
|
|
extension WidgetRefExt on WidgetRef {
|
|
Ref get ref => read(Provider((ref) => ref));
|
|
}
|
|
|
|
/// Extension to handle both old and new format certificate hashes
|
|
extension FileMetadataExt on FileMetadata {
|
|
/// Returns the APK certificate hash, checking new format first then old
|
|
/// New format (SoftwareAsset): apkCertificateHashes (Set)
|
|
/// Old format (FileMetadata): apkSignatureHash (String?)
|
|
String? get certificateHash {
|
|
// Try new format first (SoftwareAsset has apkCertificateHashes)
|
|
if (this is SoftwareAsset) {
|
|
final hashes = (this as SoftwareAsset).apkCertificateHashes;
|
|
if (hashes.isNotEmpty) return hashes.first;
|
|
}
|
|
// Fall back to old format
|
|
return apkSignatureHash;
|
|
}
|
|
|
|
/// Returns all APK certificate hashes
|
|
Set<String> get certificateHashes {
|
|
// Try new format first
|
|
if (this is SoftwareAsset) {
|
|
final hashes = (this as SoftwareAsset).apkCertificateHashes;
|
|
if (hashes.isNotEmpty) return hashes;
|
|
}
|
|
// Fall back to old format (single hash as set)
|
|
return apkSignatureHash != null ? {apkSignatureHash!} : {};
|
|
}
|
|
}
|
|
|
|
/// String abbreviation utilities
|
|
extension StringAbbreviationExt on String {
|
|
/// Abbreviates a string to show beginning and end with ellipsis
|
|
/// Default: shows first 6 and last 6 chars if string is longer than 12
|
|
String abbreviate({int start = 6, int end = 6}) {
|
|
final t = trim();
|
|
final minLength = start + end;
|
|
if (t.length <= minLength) return t;
|
|
return '${t.substring(0, start)}...${t.substring(t.length - end)}';
|
|
}
|
|
|
|
/// Abbreviates npub identifiers to "npub1abc...xyz" format
|
|
/// Shows first 9 chars (npub1 + 4 chars) and last 7 chars
|
|
/// Returns original string if not an npub identifier
|
|
String abbreviateNpub() {
|
|
if (!startsWith('npub1') || length < 20) {
|
|
return this;
|
|
}
|
|
return '${substring(0, 9)}...${substring(length - 7)}';
|
|
}
|
|
}
|