/// The decrypted `subject` JSON of a Nextcloud push-v2 notification. /// /// Covers the full shape the notifications app emits, including the three /// delete variants which the neon `DecryptedSubject` helper only partially /// models (it lacks `delete-multiple`/`nids`). class PushSubject { /// Nextcloud notification id. final int? nid; /// App that raised the notification (e.g. `spreed` for Talk). final String? app; /// Human-readable subject line. final String? subject; /// Notification type (e.g. `chat`, `background`). final String? type; /// App-specific object id. For Talk this is the chat/room token. final String? id; final bool delete; final bool deleteMultiple; final bool deleteAll; /// Notification ids to remove for a `delete-multiple` push. final List nids; const PushSubject({ this.nid, this.app, this.subject, this.type, this.id, this.delete = false, this.deleteMultiple = false, this.deleteAll = false, this.nids = const [], }); bool get isAnyDelete => delete || deleteMultiple || deleteAll; /// True when this notification originates from Nextcloud Talk. bool get isTalk => app == 'spreed'; factory PushSubject.fromJson(Map json) { final rawNids = json['nids']; return PushSubject( nid: (json['nid'] as num?)?.toInt(), app: json['app'] as String?, subject: json['subject'] as String?, type: json['type'] as String?, id: json['id'] as String?, delete: json['delete'] == true, deleteMultiple: json['delete-multiple'] == true, deleteAll: json['delete-all'] == true, nids: rawNids is List ? rawNids .whereType() .map((e) => e is num ? e.toInt() : int.tryParse('$e')) .whereType() .toList() : const [], ); } }