From c4be1b2328c1e788dfb162e4a0db3eec69255306 Mon Sep 17 00:00:00 2001 From: provokateurin Date: Mon, 28 Oct 2024 20:22:14 +0100 Subject: [PATCH 1/2] fix(nextcloud): Add missing nids and delete-multiple fields to DecryptedSubject Signed-off-by: provokateurin --- .cspell/nextcloud.txt | 1 + .../notifications/notifications_helpers.dart | 11 ++- .../notifications_helpers.g.dart | 77 ++++++++++++++++++- 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/.cspell/nextcloud.txt b/.cspell/nextcloud.txt index da5aae82974..65f2ce4923a 100644 --- a/.cspell/nextcloud.txt +++ b/.cspell/nextcloud.txt @@ -39,6 +39,7 @@ mountpoint navigations nextcloud nextcloud's +nids organisation partlycloudy pollinterval diff --git a/packages/nextcloud/lib/src/api/notifications/notifications_helpers.dart b/packages/nextcloud/lib/src/api/notifications/notifications_helpers.dart index 8b9fcb19076..aa06dd18c20 100644 --- a/packages/nextcloud/lib/src/api/notifications/notifications_helpers.dart +++ b/packages/nextcloud/lib/src/api/notifications/notifications_helpers.dart @@ -2,6 +2,7 @@ import 'dart:convert'; +import 'package:built_collection/built_collection.dart'; import 'package:built_value/built_value.dart'; import 'package:built_value/serializer.dart'; import 'package:built_value/standard_json_plugin.dart'; @@ -35,9 +36,12 @@ abstract class DecryptedSubject implements Built get serializer => _$decryptedSubjectSerializer; - /// ID if the notification. + /// ID of the notification. int? get nid; + /// IDs of multiple notifications. + BuiltList? get nids; + /// App that sent the notification. String? get app; @@ -53,6 +57,10 @@ abstract class DecryptedSubject implements Built.new) ..addPlugin(StandardJsonPlugin())) .build(); diff --git a/packages/nextcloud/lib/src/api/notifications/notifications_helpers.g.dart b/packages/nextcloud/lib/src/api/notifications/notifications_helpers.g.dart index 372dcf1d3b3..db470fc4274 100644 --- a/packages/nextcloud/lib/src/api/notifications/notifications_helpers.g.dart +++ b/packages/nextcloud/lib/src/api/notifications/notifications_helpers.g.dart @@ -25,6 +25,12 @@ class _$DecryptedSubjectSerializer implements StructuredSerializer); + break; case 'app': result.app = serializers.deserialize(value, specifiedType: const FullType(String)) as String?; break; @@ -93,6 +109,9 @@ class _$DecryptedSubjectSerializer implements StructuredSerializer? nids; + @override final String? app; @override final String? subject; @@ -117,12 +138,24 @@ class _$DecryptedSubject extends DecryptedSubject { @override final bool? delete; @override + final bool? deleteMultiple; + @override final bool? deleteAll; factory _$DecryptedSubject([void Function(DecryptedSubjectBuilder)? updates]) => (DecryptedSubjectBuilder()..update(updates))._build(); - _$DecryptedSubject._({this.nid, this.app, this.subject, this.type, this.id, this.delete, this.deleteAll}) : super._(); + _$DecryptedSubject._( + {this.nid, + this.nids, + this.app, + this.subject, + this.type, + this.id, + this.delete, + this.deleteMultiple, + this.deleteAll}) + : super._(); @override DecryptedSubject rebuild(void Function(DecryptedSubjectBuilder) updates) => (toBuilder()..update(updates)).build(); @@ -135,11 +168,13 @@ class _$DecryptedSubject extends DecryptedSubject { if (identical(other, this)) return true; return other is DecryptedSubject && nid == other.nid && + nids == other.nids && app == other.app && subject == other.subject && type == other.type && id == other.id && delete == other.delete && + deleteMultiple == other.deleteMultiple && deleteAll == other.deleteAll; } @@ -147,11 +182,13 @@ class _$DecryptedSubject extends DecryptedSubject { int get hashCode { var _$hash = 0; _$hash = $jc(_$hash, nid.hashCode); + _$hash = $jc(_$hash, nids.hashCode); _$hash = $jc(_$hash, app.hashCode); _$hash = $jc(_$hash, subject.hashCode); _$hash = $jc(_$hash, type.hashCode); _$hash = $jc(_$hash, id.hashCode); _$hash = $jc(_$hash, delete.hashCode); + _$hash = $jc(_$hash, deleteMultiple.hashCode); _$hash = $jc(_$hash, deleteAll.hashCode); _$hash = $jf(_$hash); return _$hash; @@ -161,11 +198,13 @@ class _$DecryptedSubject extends DecryptedSubject { String toString() { return (newBuiltValueToStringHelper(r'DecryptedSubject') ..add('nid', nid) + ..add('nids', nids) ..add('app', app) ..add('subject', subject) ..add('type', type) ..add('id', id) ..add('delete', delete) + ..add('deleteMultiple', deleteMultiple) ..add('deleteAll', deleteAll)) .toString(); } @@ -178,6 +217,10 @@ class DecryptedSubjectBuilder implements Builder _$this._nid; set nid(int? nid) => _$this._nid = nid; + ListBuilder? _nids; + ListBuilder get nids => _$this._nids ??= ListBuilder(); + set nids(ListBuilder? nids) => _$this._nids = nids; + String? _app; String? get app => _$this._app; set app(String? app) => _$this._app = app; @@ -198,6 +241,10 @@ class DecryptedSubjectBuilder implements Builder _$this._delete; set delete(bool? delete) => _$this._delete = delete; + bool? _deleteMultiple; + bool? get deleteMultiple => _$this._deleteMultiple; + set deleteMultiple(bool? deleteMultiple) => _$this._deleteMultiple = deleteMultiple; + bool? _deleteAll; bool? get deleteAll => _$this._deleteAll; set deleteAll(bool? deleteAll) => _$this._deleteAll = deleteAll; @@ -208,11 +255,13 @@ class DecryptedSubjectBuilder implements Builder _build(); _$DecryptedSubject _build() { - final _$result = _$v ?? - _$DecryptedSubject._( - nid: nid, app: app, subject: subject, type: type, id: id, delete: delete, deleteAll: deleteAll); + _$DecryptedSubject _$result; + try { + _$result = _$v ?? + _$DecryptedSubject._( + nid: nid, + nids: _nids?.build(), + app: app, + subject: subject, + type: type, + id: id, + delete: delete, + deleteMultiple: deleteMultiple, + deleteAll: deleteAll); + } catch (_) { + late String _$failedField; + try { + _$failedField = 'nids'; + _nids?.build(); + } catch (e) { + throw BuiltValueNestedFieldError(r'DecryptedSubject', _$failedField, e.toString()); + } + rethrow; + } replace(_$result); return _$result; } From 86c401fd63207de5727747bcd9c7968321cb7d92 Mon Sep 17 00:00:00 2001 From: provokateurin Date: Mon, 28 Oct 2024 20:23:03 +0100 Subject: [PATCH 2/2] fix(neon_framework): Handle delete-multiple background push notifications Signed-off-by: provokateurin --- .../neon_framework/lib/src/utils/push_utils.dart | 13 +++++++++---- .../neon_framework/test/push_utils_test.dart | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/neon_framework/lib/src/utils/push_utils.dart b/packages/neon_framework/lib/src/utils/push_utils.dart index 694283fbc51..28c950c114f 100644 --- a/packages/neon_framework/lib/src/utils/push_utils.dart +++ b/packages/neon_framework/lib/src/utils/push_utils.dart @@ -113,7 +113,12 @@ class PushUtils { final pushNotifications = await parseEncryptedPushNotifications(storage, encryptedPushNotifications, accountID); for (final pushNotification in pushNotifications) { if (pushNotification.subject.delete ?? false) { - await localNotificationsPlugin.cancel(_getNotificationID(accountID, pushNotification)); + await localNotificationsPlugin.cancel(_getNotificationID(accountID, pushNotification.subject.nid!)); + } else if (pushNotification.subject.deleteMultiple ?? false) { + await Future.wait([ + for (final nid in pushNotification.subject.nids!) + localNotificationsPlugin.cancel(_getNotificationID(accountID, nid)), + ]); } else if (pushNotification.subject.deleteAll ?? false) { await localNotificationsPlugin.cancelAll(); } else if (pushNotification.type == 'background') { @@ -164,7 +169,7 @@ class PushUtils { final when = notification != null ? tz.TZDateTime.parse(tz.UTC, notification.datetime) : null; await localNotificationsPlugin.show( - _getNotificationID(accountID, pushNotification), + _getNotificationID(accountID, pushNotification.subject.nid!), message != null && appName != null ? '$appName: $title' : title, message, NotificationDetails( @@ -289,8 +294,8 @@ class PushUtils { return ByteArrayAndroidBitmap(img.encodeBmp(img.decodePng(bytes!.buffer.asUint8List())!)); } - static int _getNotificationID(String accountID, PushNotification notification) { - return sha256.convert(utf8.encode('$accountID${notification.subject.nid}')).bytes.reduce((a, b) => a + b); + static int _getNotificationID(String accountID, int nid) { + return sha256.convert(utf8.encode('$accountID$nid')).bytes.reduce((a, b) => a + b); } static int _getGroupSummaryID(String accountID, String app) { diff --git a/packages/neon_framework/test/push_utils_test.dart b/packages/neon_framework/test/push_utils_test.dart index 3cb31d6efa3..d9290de1a6f 100644 --- a/packages/neon_framework/test/push_utils_test.dart +++ b/packages/neon_framework/test/push_utils_test.dart @@ -207,6 +207,22 @@ void main() { verify(() => localNotificationsPlatform.cancel(3811)).called(1); }); + test('Delete multiple', () async { + final payload = { + 'priority': '', + 'type': '', + 'subject': { + 'nids': [1, 2], + 'delete-multiple': true, + }, + }; + + await PushUtils.onMessage(_encryptPushNotifications(keypair, [payload]), account.id); + + verify(() => localNotificationsPlatform.cancel(3811)).called(1); + verify(() => localNotificationsPlatform.cancel(4269)).called(1); + }); + test('Delete all', () async { final payload = { 'priority': '',