mirror of
https://github.com/zapstore/zapstore.git
synced 2026-10-05 12:38:24 +00:00
Merge pull request #309 from zapstore/fix/install-button-state
Fix Install/Delete buttons after install
This commit is contained in:
@@ -330,7 +330,18 @@ abstract class PackageManager extends StateNotifier<PackageManagerState> {
|
||||
String? displayName,
|
||||
}) async {
|
||||
await _ensureDownloaderReady();
|
||||
if (hasOperation(appId)) return false;
|
||||
final existing = getOperation(appId);
|
||||
if (existing != null) {
|
||||
// We keep terminal states (Completed/Failed) in the operations map briefly so
|
||||
// batch progress UI can derive totals. However, starting a new download for the
|
||||
// same app should not be blocked by a stale terminal op (e.g. install -> uninstall
|
||||
// -> install again). Only in-flight operations should block.
|
||||
if (existing is Completed || existing is OperationFailed) {
|
||||
clearOperation(appId);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final downloadUrl = target.urls.firstOrNull;
|
||||
if (downloadUrl == null || downloadUrl.isEmpty) {
|
||||
|
||||
@@ -11,6 +11,7 @@ bool isDebugMode(String? pubkey) {
|
||||
const allowedHexKeys = {
|
||||
'726a1e261cc6474674e8285e3951b3bb139be9a773d1acf49dc868db861a1c11',
|
||||
'227ce06aa5fb84bf70f25d887519374d1bfd3e1ffb75697bb0aa8f6396f32e43',
|
||||
'24480686b56234a240fd9827209b584847f3d4f9657f0d9a97aec5320a264acb',
|
||||
};
|
||||
|
||||
// Try direct comparison first (hex format)
|
||||
|
||||
@@ -32,6 +32,12 @@ class InstallButton extends ConsumerWidget {
|
||||
|
||||
// Derive what to display
|
||||
final isInstalled = installedPkg != null;
|
||||
// Note: PackageManager keeps terminal operations (e.g. Completed) in the
|
||||
// operations map for a while so batch UX (e.g. "All done") can derive counts.
|
||||
// For the detail screen action row, Completed should be treated as "not busy"
|
||||
// so the user can immediately Open/Delete after install.
|
||||
final canShowActionButtons =
|
||||
isInstalled && (operation == null || operation is Completed);
|
||||
final hasUpdate = app.hasUpdate;
|
||||
final hasDowngrade = app.hasDowngrade;
|
||||
final hasRelease = release != null;
|
||||
@@ -77,7 +83,7 @@ class InstallButton extends ConsumerWidget {
|
||||
children: [
|
||||
Expanded(child: SizedBox(height: 48, child: button)),
|
||||
// Show action buttons only for installed apps with no active operation
|
||||
if (isInstalled && operation == null) ...[
|
||||
if (canShowActionButtons) ...[
|
||||
if (hasUpdate) ...[
|
||||
const SizedBox(width: 8),
|
||||
_buildOpenIconButton(context, ref),
|
||||
@@ -102,9 +108,15 @@ class InstallButton extends ConsumerWidget {
|
||||
required FileMetadata? fileMetadata,
|
||||
required double fontSize,
|
||||
}) {
|
||||
// Completed is a terminal "result" state and may linger for batch progress UX.
|
||||
// If the app is no longer installed (e.g. user uninstalled right after install),
|
||||
// ignore a stale Completed op so we fall back to the normal "Install" UI.
|
||||
final effectiveOperation =
|
||||
(!isInstalled && operation is Completed) ? null : operation;
|
||||
|
||||
// Handle operation states first
|
||||
if (operation != null) {
|
||||
return switch (operation) {
|
||||
if (effectiveOperation != null) {
|
||||
return switch (effectiveOperation) {
|
||||
DownloadQueued() => _buildSimpleButton(
|
||||
context,
|
||||
'Queued for download',
|
||||
|
||||
Reference in New Issue
Block a user