diff --git a/lib/pages/app.dart b/lib/pages/app.dart index 5f88189..1852680 100644 --- a/lib/pages/app.dart +++ b/lib/pages/app.dart @@ -50,8 +50,10 @@ class _AppPageState extends State { appsProvider .downloadAndInstallLatestApp( [app!.app.id], - context).then((_) { - Navigator.of(context).pop(); + context).then((res) { + if (res) { + Navigator.of(context).pop(); + } }); } : null, diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index 50e810d..be7df5d 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -170,6 +170,11 @@ class _SettingsPageState extends State { ) ]), actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: const Text('Cancel')), TextButton( onPressed: () { if (formKey.currentState! @@ -198,11 +203,6 @@ class _SettingsPageState extends State { } }, child: const Text('Import')), - TextButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: const Text('Cancel')) ], ); }); diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index e98a43e..10ac212 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -82,7 +82,7 @@ class AppsProvider with ChangeNotifier { // Given an AppId, uses stored info about the app to download an APK (with user input if needed) and install it // Installs can only be done in the foreground, so a notification is sent to get the user's attention if needed // Returns upon successful download, regardless of installation result - Future downloadAndInstallLatestApp( + Future downloadAndInstallLatestApp( List appIds, BuildContext context) async { NotificationsProvider notificationsProvider = context.read(); @@ -91,37 +91,17 @@ class AppsProvider with ChangeNotifier { if (apps[id] == null) { throw 'App not found'; } - String apkUrl = apps[id]!.app.apkUrls.last; + String? apkUrl = apps[id]!.app.apkUrls.last; if (apps[id]!.app.apkUrls.length > 1) { - await showDialog( + apkUrl = await showDialog( context: context, builder: (BuildContext ctx) { - return AlertDialog( - scrollable: true, - title: const Text('Pick an APK'), - content: Column(children: [ - Text( - '${apps[id]!.app.name} has more than one package - pick one.'), - ...apps[id]!.app.apkUrls.map((u) => ListTile( - title: Text(Uri.parse(u).pathSegments.last), - leading: Radio( - value: u, - groupValue: apkUrl, - onChanged: (String? val) { - apkUrl = val!; - }))) - ]), - actions: [ - TextButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: const Text('Continue')) - ], - ); + return APKPicker(app: apps[id]!.app, initVal: apkUrl); }); } - appsToInstall.putIfAbsent(id, () => apkUrl); + if (apkUrl != null) { + appsToInstall.putIfAbsent(id, () => apkUrl!); + } } List downloadedFiles = await Future.wait(appsToInstall.entries @@ -144,6 +124,8 @@ class AppsProvider with ChangeNotifier { apps[f.appId]!.app.installedVersion = apps[f.appId]!.app.latestVersion; await saveApp(apps[f.appId]!.app); } + + return downloadedFiles.isNotEmpty; } Future getAppsDir() async { @@ -281,3 +263,51 @@ class AppsProvider with ChangeNotifier { super.dispose(); } } + +class APKPicker extends StatefulWidget { + const APKPicker({super.key, required this.app, this.initVal}); + + final App app; + final String? initVal; + + @override + State createState() => _APKPickerState(); +} + +class _APKPickerState extends State { + String? apkUrl; + + @override + Widget build(BuildContext context) { + apkUrl ??= widget.initVal; + return AlertDialog( + scrollable: true, + title: const Text('Pick an APK'), + content: Column(children: [ + Text('${widget.app.name} has more than one package - pick one.'), + ...widget.app.apkUrls.map((u) => ListTile( + title: Text(Uri.parse(u).pathSegments.last), + leading: Radio( + value: u, + groupValue: apkUrl, + onChanged: (String? val) { + setState(() { + apkUrl = val; + }); + }))) + ]), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(null); + }, + child: const Text('Cancel')), + TextButton( + onPressed: () { + Navigator.of(context).pop(apkUrl); + }, + child: const Text('Continue')) + ], + ); + } +}