diff --git a/lib/models/app.dart b/lib/models/app.dart index fcabaca..6ffad33 100644 --- a/lib/models/app.dart +++ b/lib/models/app.dart @@ -89,7 +89,7 @@ mixin AppAdapter on Adapter { DataRequestLabel? label}) async { final map = await getInstalledAppsMap(); - findApps(Map params) async { + loadAppModels(Map params) async { final apps = await super.findAll(params: params); final releases = await ref.releases .findAll(params: {'#a': apps.map((app) => app.aTag)}); @@ -98,6 +98,11 @@ mixin AppAdapter on Adapter { 'ids': metadataIds, '#m': [kAndroidMimeType] }); + final userIds = { + for (final app in apps) app.signer.id, + for (final app in apps) app.developer.id + }.nonNulls; + await ref.users.findAll(params: {'ids': userIds}); return apps; } @@ -109,14 +114,14 @@ mixin AppAdapter on Adapter { final apps = findAllLocal(); if (apps.isNotEmpty) { - findApps(params); + loadAppModels(params); return apps; } - return findApps(params); + return loadAppModels(params); } } - return findApps(params); + return loadAppModels(params); } static AndroidPackageManager? _packageManager; @@ -178,7 +183,9 @@ extension AppX on App { if (!installPermission.isGranted) { final newStatus = await Permission.requestInstallPackages.request(); if (newStatus.isDenied) { - throw Exception('Installation permission denied'); + notifier.state = + ErrorInstallProgress(Exception('Installation permission denied')); + return; } } @@ -190,8 +197,9 @@ extension AppX on App { if (await _isHashMismatch(file.path, hash)) { await file.delete(); - notifier.state = IdleInstallProgress(); - throw Exception('Hash mismatch, aborted installation'); + notifier.state = ErrorInstallProgress( + Exception('Hash mismatch, aborted installation')); + return; } final result = await InstallPlugin.install(file.path); @@ -267,6 +275,11 @@ class DownloadingInstallProgress extends AppInstallProgress { class DeviceInstallProgress extends AppInstallProgress {} +class ErrorInstallProgress extends AppInstallProgress { + final Exception e; + ErrorInstallProgress(this.e); +} + final installedAppProvider = StateProvider>((_) => {}); final installationProgressProvider = diff --git a/lib/models/nostr_adapter.dart b/lib/models/nostr_adapter.dart index 33b9dc4..640150f 100644 --- a/lib/models/nostr_adapter.dart +++ b/lib/models/nostr_adapter.dart @@ -74,7 +74,6 @@ mixin NostrAdapter> on Adapter { kinds: {kind, ...?additionalKinds}, tags: params ?? {}, ); - print(req); final result = await notifier.query(req, relayUrls: ['wss://relay.zap.store']); diff --git a/lib/models/user.dart b/lib/models/user.dart index 838e0d0..3b48a7f 100644 --- a/lib/models/user.dart +++ b/lib/models/user.dart @@ -26,7 +26,11 @@ mixin UserAdapter on NostrAdapter { (data is Iterable ? data : [data as Map]).cast(); final k0s = list - .where((e) => e['kind'] == 0 && jsonDecode(e['content']).isNotEmpty) + .where((e) { + final map = Map.from(jsonDecode(e['content'])); + final name = map['name'] ?? map['display_name'] ?? map['displayName']; + return e['kind'] == 0 && name != null; + }) .toList() .groupSetsBy((e) => e['pubkey'] as String); final k3s = list @@ -61,9 +65,6 @@ mixin UserAdapter on NostrAdapter { for (final _ in k0s.entries) { final sl = _.value.sorted( (a, b) => (b['created_at'] as int).compareTo(a['created_at'])); - if (sl.length > 1) { - print('more than one for ${_.key}'); - } final k0 = sl.first; final id = k0['id'] = k0['pubkey']; if (included.containsKey(id)) { diff --git a/lib/screens/app_detail_screen.dart b/lib/screens/app_detail_screen.dart index f2db059..97d2590 100644 --- a/lib/screens/app_detail_screen.dart +++ b/lib/screens/app_detail_screen.dart @@ -352,24 +352,30 @@ class InstallButton extends ConsumerWidget { child: ElevatedButton( onPressed: switch (app.status) { AppInstallStatus.notInstallable => null, - AppInstallStatus.updated => () async { - await LaunchApp.openApp(androidPackageName: app.id!.toString()); + AppInstallStatus.updated => () { + LaunchApp.openApp(androidPackageName: app.id!.toString()); }, _ => switch (progress) { - IdleInstallProgress() => () { - app.install().catchError((e) { - context.showError(e.toString()); - }); + IdleInstallProgress() => () => app.install(), + ErrorInstallProgress(e: final e) => () { + // show error and reset state to idle + context.showError(e.toString()); + ref + .read(installationProgressProvider(app.id!.toString()) + .notifier) + .state = IdleInstallProgress(); }, _ => null, } }, style: ElevatedButton.styleFrom( - disabledForegroundColor: Colors.white, - disabledBackgroundColor: Colors.blue[700], - foregroundColor: Colors.white, - backgroundColor: Colors.blue[700], - ), + disabledForegroundColor: Colors.white, + disabledBackgroundColor: Colors.blue[700], + foregroundColor: Colors.white, + backgroundColor: switch (progress) { + ErrorInstallProgress() => Colors.red, + _ => Colors.blue[700], + }), child: switch (app.status) { AppInstallStatus.notInstallable => Text('Sorry, can\'t install'), AppInstallStatus.updated => Text('Open'), @@ -387,6 +393,9 @@ class InstallButton extends ConsumerWidget { width: 14, height: 14, child: CircularProgressIndicator()) : Text( '${app.canUpdate ? 'Updating' : 'Installing'} on device'), + ErrorInstallProgress() => compact + ? SizedBox(width: 14, height: 14, child: Icon(Icons.error)) + : Text('Error, tap to see message'), } }, ), diff --git a/lib/utils/extensions.dart b/lib/utils/extensions.dart index 22ead46..7d9cfef 100644 --- a/lib/utils/extensions.dart +++ b/lib/utils/extensions.dart @@ -6,7 +6,7 @@ extension ContextX on BuildContext { void showError(String message) { showToast( message, - duration: Duration(seconds: 7), + duration: Duration(seconds: 5), textStyle: TextStyle(fontWeight: FontWeight.bold, fontSize: 18), animDuration: Duration(milliseconds: 300), animation: StyledToastAnimation.fade, diff --git a/pubspec.lock b/pubspec.lock index b2c2612..40ce509 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -815,9 +815,11 @@ packages: purplebase: dependency: "direct main" description: - path: "../purplebase" - relative: true - source: path + path: "." + ref: "617e018201a875281b7c484bcd79ead7fea078d6" + resolved-ref: "617e018201a875281b7c484bcd79ead7fea078d6" + url: "https://github.com/purplebase/purplebase" + source: git version: "0.1.0" riverpod: dependency: transitive diff --git a/pubspec.yaml b/pubspec.yaml index 3825add..5bc622e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,7 +42,7 @@ dependencies: flutter_styled_toast: ^2.2.1 url_launcher: ^6.2.5 device_apps: ^2.2.0 - purplebase: + purplebase: ^0.1.0 sqlite3_flutter_libs: ^0.5.20 flutter_markdown: ^0.7.1 cached_network_image: ^3.3.1 @@ -55,7 +55,9 @@ dependencies: dependency_overrides: purplebase: - path: ../purplebase + git: + url: https://github.com/purplebase/purplebase + ref: 617e018201a875281b7c484bcd79ead7fea078d6 flutter_data: path: ../flutter_data