From 7a62946e8ff89c163f1f501d8c0234ba6265730e Mon Sep 17 00:00:00 2001 From: nahnah Date: Mon, 9 Feb 2026 20:54:38 +0000 Subject: [PATCH] [imp]: Add waitForInstalled and use after install This is an attempt to fix the issue of Uninstall/Open not displaying after install. The app requires a hot reload to fix it. --- lib/providers/app_provider.dart | 25 +++++++++++++++++++++++-- lib/screens/app_details_screen.dart | 6 ++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/providers/app_provider.dart b/lib/providers/app_provider.dart index d6e5936..480f545 100644 --- a/lib/providers/app_provider.dart +++ b/lib/providers/app_provider.dart @@ -550,7 +550,9 @@ class AppProvider extends ChangeNotifier { .toList(); // Clean up preferences for uninstalled apps - final installedPackages = _installedApps.map((app) => app.packageName).toSet(); + final installedPackages = _installedApps + .map((app) => app.packageName) + .toSet(); await _preferencesService.cleanupUninstalledApps(installedPackages); _installedAppsState = LoadingState.success; @@ -616,7 +618,9 @@ class AppProvider extends ChangeNotifier { /// Gets the latest version for an app based on per-app unstable preference Future getLatestVersion(FDroidApp app) async { - final includeUnstable = await _preferencesService.getIncludeUnstable(app.packageName); + final includeUnstable = await _preferencesService.getIncludeUnstable( + app.packageName, + ); return app.getLatestVersion(includeUnstable: includeUnstable); } @@ -644,6 +648,23 @@ class AppProvider extends ChangeNotifier { } } + /// Polls until an app shows up as installed or timeout is reached. + Future waitForInstalled( + String packageName, { + Duration timeout = const Duration(seconds: 20), + Duration interval = const Duration(milliseconds: 800), + }) async { + final deadline = DateTime.now().add(timeout); + while (DateTime.now().isBefore(deadline)) { + await fetchInstalledApps(); + if (isAppInstalled(packageName)) { + return true; + } + await Future.delayed(interval); + } + return isAppInstalled(packageName); + } + /// Refreshes all data Future refreshAll({RepositoriesProvider? repositoriesProvider}) async { // Clear cached data diff --git a/lib/screens/app_details_screen.dart b/lib/screens/app_details_screen.dart index e4c3481..aec5083 100644 --- a/lib/screens/app_details_screen.dart +++ b/lib/screens/app_details_screen.dart @@ -174,8 +174,7 @@ class _AppDetailsScreenState extends State { } await downloadProvider.installApk(downloadInfo!.filePath!); - await Future.delayed(const Duration(milliseconds: 100)); - await appProvider.fetchInstalledApps(); + await appProvider.waitForInstalled(widget.app.packageName); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( @@ -2469,8 +2468,7 @@ class _VersionDownloadButton extends StatelessWidget { try { if (downloadInfo.filePath != null) { await downloadProvider.installApk(downloadInfo.filePath!); - await Future.delayed(const Duration(milliseconds: 100)); - await appProvider.fetchInstalledApps(); + await appProvider.waitForInstalled(app.packageName); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Installing ${app.name}...')),