diff --git a/lib/pages/app.dart b/lib/pages/app.dart index 95b9552..78f120f 100644 --- a/lib/pages/app.dart +++ b/lib/pages/app.dart @@ -28,58 +28,70 @@ class _AppPageState extends State { body: WebView( initialUrl: app?.url, ), - bottomSheet: Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), - child: - Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - Expanded( - child: OutlinedButton( - onPressed: (app?.installedVersion == null || - appsProvider.checkAppObjectForUpdate(app!)) && - app?.currentDownloadId == null - ? () { - appsProvider.backgroundDownloadAndInstallApp(app!); - } - : null, - child: Text( - app?.installedVersion == null ? 'Install' : 'Update'))), - const SizedBox(width: 16.0), - OutlinedButton( - onPressed: app?.currentDownloadId != null - ? null - : () { - showDialog( - context: context, - builder: (BuildContext ctx) { - return AlertDialog( - title: const Text('Remove App?'), - content: Text( - 'This will remove \'${app?.name}\' from Obtainium.${app?.installedVersion != null ? '\n\nNote that while Obtainium will no longer track its updates, the App will remain installed.' : ''}'), - actions: [ - TextButton( - onPressed: () { - appsProvider.removeApp(app!.id).then((_) { - int count = 0; - Navigator.of(context) - .popUntil((_) => count++ >= 2); - }); - }, - child: const Text('Remove')), - TextButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: const Text('Cancel')) - ], - ); - }); - }, - style: TextButton.styleFrom( - foregroundColor: Theme.of(context).errorColor), - child: const Text('Remove'), - ) - // TODO: Add progress bar when app?.currentDownloadId != null - ])), + bottomSheet: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: + const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: OutlinedButton( + onPressed: (app?.installedVersion == null || + appsProvider + .checkAppObjectForUpdate(app!)) && + app?.currentDownloadId == null + ? () { + appsProvider + .backgroundDownloadAndInstallApp(app!); + } + : null, + child: Text(app?.installedVersion == null + ? 'Install' + : 'Update'))), + const SizedBox(width: 16.0), + OutlinedButton( + onPressed: app?.currentDownloadId != null + ? null + : () { + showDialog( + context: context, + builder: (BuildContext ctx) { + return AlertDialog( + title: const Text('Remove App?'), + content: Text( + 'This will remove \'${app?.name}\' from Obtainium.${app?.installedVersion != null ? '\n\nNote that while Obtainium will no longer track its updates, the App will remain installed.' : ''}'), + actions: [ + TextButton( + onPressed: () { + appsProvider + .removeApp(app!.id) + .then((_) { + int count = 0; + Navigator.of(context).popUntil( + (_) => count++ >= 2); + }); + }, + child: const Text('Remove')), + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: const Text('Cancel')) + ], + ); + }); + }, + style: TextButton.styleFrom( + foregroundColor: Theme.of(context).errorColor), + child: const Text('Remove'), + ), + ])), + if (app?.currentDownloadId != null) const LinearProgressIndicator() + ], + ), ); } } diff --git a/lib/services/apps_provider.dart b/lib/services/apps_provider.dart index 6d21410..95cd356 100644 --- a/lib/services/apps_provider.dart +++ b/lib/services/apps_provider.dart @@ -20,7 +20,9 @@ class AppsProvider with ChangeNotifier { AppsProvider() { initializeDownloader(); - loadApps(); + loadApps().then((_) { + clearDownloadStates(); + }); } // Notifications plugin for downloads @@ -90,7 +92,14 @@ class AppsProvider with ChangeNotifier { break; } } - // Change App status to no longer downloading + // Install the App (and remove warning notification if any) + FlutterDownloader.open(taskId: id); + downloaderNotifications.cancel(1); + } + // Change App status based on result (we assume user accepts install - no way to tell programatically) + if (status == DownloadTaskStatus.complete || + status == DownloadTaskStatus.failed || + status == DownloadTaskStatus.canceled) { App? foundApp; apps.forEach((appId, app) { if (app.currentDownloadId == id) { @@ -98,10 +107,10 @@ class AppsProvider with ChangeNotifier { } }); foundApp!.currentDownloadId = null; + if (status == DownloadTaskStatus.complete) { + foundApp!.installedVersion = foundApp!.latestVersion; + } saveApp(foundApp!); - // Install the App (and remove warning notification if any) - FlutterDownloader.open(taskId: id); - downloaderNotifications.cancel(1); } } @@ -158,6 +167,21 @@ class AppsProvider with ChangeNotifier { notifyListeners(); } + Future clearDownloadStates() async { + var appList = apps.values.toList(); + int count = 0; + for (int i = 0; i < appList.length; i++) { + if (appList[i].currentDownloadId != null) { + apps[appList[i].id]?.currentDownloadId = null; + await saveApp(apps[appList[i].id]!); + count++; + } + } + if (count > 0) { + notifyListeners(); + } + } + Future removeApp(String appId) async { File file = File('${(await getAppsDir()).path}/$appId.json'); if (file.existsSync()) {