mirror of
https://github.com/zapstore/zapstore.git
synced 2026-10-05 12:38:24 +00:00
Fix system dialog dismissed UX
This commit is contained in:
@@ -56,3 +56,5 @@ reference/*
|
||||
|
||||
# FVM Version Cache
|
||||
.fvm/
|
||||
|
||||
bugs/
|
||||
+19
-2
@@ -353,10 +353,27 @@ class AndroidPackageManagerPlugin :
|
||||
Log.d(TAG, "App foregrounded")
|
||||
|
||||
if (!wasForeground) {
|
||||
// Re-launch any pending install dialogs
|
||||
for ((packageName, intent) in pendingUserActionIntents.toMap()) {
|
||||
Log.d(TAG, "Re-launching pending dialog for $packageName")
|
||||
val sessionActive = findExistingSession(packageName) != null
|
||||
if (sessionActive) {
|
||||
// Session still alive — user was in another app, dialog is still pending.
|
||||
// Re-show it so the user can act on it without hunting for it.
|
||||
Log.d(TAG, "Re-launching pending dialog for $packageName (session active)")
|
||||
launchConfirmDialog(packageName, intent)
|
||||
} else {
|
||||
// Session is gone — dialog was dismissed without confirming.
|
||||
// Emit CANCELLED so Dart transitions to InstallCancelled immediately.
|
||||
Log.d(TAG, "Session gone for $packageName on foreground — emitting cancelled")
|
||||
pendingUserActionIntents.remove(packageName)
|
||||
val sessionId = sessionToPackage.entries.find { it.value == packageName }?.key ?: -1
|
||||
clearWatchdog(packageName)
|
||||
onInstallResult(
|
||||
sessionId = sessionId,
|
||||
status = InstallStatus.CANCELLED,
|
||||
packageName = packageName,
|
||||
message = "Install dialog dismissed"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,8 +71,6 @@ final class AndroidPackageManager extends PackageManager {
|
||||
|
||||
static const _methodChannel = MethodChannel('android_package_manager');
|
||||
static const _eventChannel = EventChannel('android_package_manager/events');
|
||||
static const _pendingUserActionTimeout = Duration(seconds: 10);
|
||||
|
||||
bool _supportsSilentInstall = false;
|
||||
int _syncGeneration = 0;
|
||||
StreamSubscription<dynamic>? _eventSubscription;
|
||||
@@ -230,29 +228,13 @@ final class AndroidPackageManager extends PackageManager {
|
||||
break;
|
||||
|
||||
case InstallStatus.pendingUserAction:
|
||||
// If pending user action lingers too long, treat it like dismiss/cancel
|
||||
// and surface "Install (retry)" instead of staying stuck requesting.
|
||||
if (existingOp is Installing &&
|
||||
!existingOp.isSilent &&
|
||||
DateTime.now().difference(existingOp.startedAt) >=
|
||||
_pendingUserActionTimeout) {
|
||||
if (filePath != null) {
|
||||
setOperation(
|
||||
appId,
|
||||
InstallCancelled(target: target, filePath: filePath),
|
||||
);
|
||||
} else {
|
||||
clearOperation(appId);
|
||||
}
|
||||
clearInstallSlot(appId);
|
||||
break;
|
||||
}
|
||||
|
||||
// User action required. Ensure we don't get stuck in Verifying if the
|
||||
// STARTED event was missed; show Installing state.
|
||||
// Skip if already in Installing or SystemProcessing to preserve the
|
||||
// original startedAt timestamp — otherwise the watchdog timeout resets
|
||||
// on every pendingUserAction/systemProcessing bounce and never fires.
|
||||
// Dialog dismiss is detected on the Kotlin side via onStart +
|
||||
// findExistingSession, which emits CANCELLED when the session is gone.
|
||||
if (filePath != null &&
|
||||
existingOp is! Installing &&
|
||||
existingOp is! SystemProcessing) {
|
||||
|
||||
@@ -175,7 +175,7 @@ class InstallButton extends ConsumerWidget {
|
||||
isSilent
|
||||
? (isInstalled ? 'Updating...' : 'Installing...')
|
||||
: (isInstalled ? 'Requesting update' : 'Requesting installation'),
|
||||
null, // Not tappable - auto-transitions to retry after 10s if no response
|
||||
null, // Not tappable - transitions to retry when Kotlin detects dialog dismissed
|
||||
fontSize: fontSize,
|
||||
showSpinner: true,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user