From 966655765584beab45f9ff6392fa7c6f1109697c Mon Sep 17 00:00:00 2001 From: "Alexander \"PapaTutuWawa" Date: Sun, 17 Sep 2023 20:10:53 +0200 Subject: [PATCH] feat(xep): Make avatar queries more explicit --- packages/moxxmpp/CHANGELOG.md | 5 +- .../lib/src/xeps/xep_0060/xep_0060.dart | 14 ++-- packages/moxxmpp/lib/src/xeps/xep_0084.dart | 65 +++++++++---------- .../lib/src/xeps/xep_0384/xep_0384.dart | 2 +- packages/moxxmpp/lib/src/xeps/xep_0449.dart | 2 +- 5 files changed, 47 insertions(+), 41 deletions(-) diff --git a/packages/moxxmpp/CHANGELOG.md b/packages/moxxmpp/CHANGELOG.md index f752ae8..1ebeb2a 100644 --- a/packages/moxxmpp/CHANGELOG.md +++ b/packages/moxxmpp/CHANGELOG.md @@ -18,7 +18,10 @@ - **BREAKING**: `ChatState.toString()` is now `ChatState.toName()` - **BREAKING**: Overriding `BaseOmemoManager` is no longer required. `OmemoManager` now takes callback methods instead. - Removed `ErrorResponseDiscoError` from the possible XEP-0030 errors. -- **BREAKING**: Removed "Extensible File Thumbnails" (The `Thumbnail` type) +- **BREAKING**: Removed "Extensible File Thumbnails" (The `Thumbnail` type). +- *BREAKING*: Rename `UserAvatarManager`'s `getUserAvatar` to `getUserAvatarData`. It now also requires the id of the avatar to fetch +- *BREAKING*: `UserAvatarManager`'s `getAvatarId` with `getLatestMetadata`. +- The `PubSubManager` now supports PubSub's `max_items` in `getItems`. ## 0.3.1 diff --git a/packages/moxxmpp/lib/src/xeps/xep_0060/xep_0060.dart b/packages/moxxmpp/lib/src/xeps/xep_0060/xep_0060.dart index 9dcae8b..bb9f94c 100644 --- a/packages/moxxmpp/lib/src/xeps/xep_0060/xep_0060.dart +++ b/packages/moxxmpp/lib/src/xeps/xep_0060/xep_0060.dart @@ -401,8 +401,9 @@ class PubSubManager extends XmppManagerBase { Future>> getItems( JID jid, - String node, - ) async { + String node, { + int? maxItems, + }) async { final result = (await getAttributes().sendStanza( StanzaDetails( Stanza.iq( @@ -415,7 +416,10 @@ class PubSubManager extends XmppManagerBase { children: [ XMLNode( tag: 'items', - attributes: {'node': node}, + attributes: { + 'node': node, + if (maxItems != null) 'max_items': maxItems.toString(), + }, ), ], ) @@ -446,7 +450,7 @@ class PubSubManager extends XmppManagerBase { } Future> getItem( - String jid, + JID jid, String node, String id, ) async { @@ -454,7 +458,7 @@ class PubSubManager extends XmppManagerBase { StanzaDetails( Stanza.iq( type: 'get', - to: jid, + to: jid.toString(), children: [ XMLNode.xmlns( tag: 'pubsub', diff --git a/packages/moxxmpp/lib/src/xeps/xep_0084.dart b/packages/moxxmpp/lib/src/xeps/xep_0084.dart index c7656ae..7d865b8 100644 --- a/packages/moxxmpp/lib/src/xeps/xep_0084.dart +++ b/packages/moxxmpp/lib/src/xeps/xep_0084.dart @@ -5,10 +5,7 @@ import 'package:moxxmpp/src/jid.dart'; import 'package:moxxmpp/src/managers/base.dart'; import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart'; -import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stringxml.dart'; -import 'package:moxxmpp/src/xeps/xep_0030/types.dart'; -import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart'; import 'package:moxxmpp/src/xeps/xep_0060/errors.dart'; import 'package:moxxmpp/src/xeps/xep_0060/xep_0060.dart'; @@ -43,11 +40,7 @@ class UserAvatarMetadata { ); factory UserAvatarMetadata.fromXML(XMLNode node) { - assert( - node.tag == 'metadata' && - node.attributes['xmlns'] == userAvatarMetadataXmlns, - ' element required', - ); + assert(node.tag == 'info', 'node must be an element'); final width = node.attributes['width'] as String?; final height = node.attributes['height'] as String?; @@ -121,20 +114,43 @@ class UserAvatarManager extends XmppManagerBase { /// Requests the avatar from [jid]. Returns the avatar data if the request was /// successful. Null otherwise - Future> getUserAvatar(JID jid) async { + Future> getUserAvatarData( + JID jid, + String id, + ) async { final pubsub = _getPubSubManager(); - final resultsRaw = await pubsub.getItems(jid, userAvatarDataXmlns); + final resultRaw = await pubsub.getItem(jid, userAvatarDataXmlns, id); + if (resultRaw.isType()) return Result(UnknownAvatarError()); + + final result = resultRaw.get(); + return Result( + UserAvatarData( + result.payload.innerText(), + id, + ), + ); + } + + /// Attempts to fetch the latest item from the User Avatar metadata node. Returns the list of + /// metadata contained within it. The list may be empty. + /// + /// If an error occured, returns an [AvatarError]. + Future>> getLatestMetadata( + JID jid, + ) async { + final resultsRaw = await _getPubSubManager() + .getItems(jid, userAvatarMetadataXmlns, maxItems: 1); if (resultsRaw.isType()) return Result(UnknownAvatarError()); final results = resultsRaw.get>(); - if (results.isEmpty) return Result(UnknownAvatarError()); + if (results.isEmpty) { + return Result(UnknownAvatarError()); + } - final item = results[0]; + final metadata = results.first.payload + .firstTag('metadata', xmlns: userAvatarMetadataXmlns)!; return Result( - UserAvatarData( - item.payload.innerText(), - item.id, - ), + metadata.findTags('info').map(UserAvatarMetadata.fromXML).toList(), ); } @@ -216,21 +232,4 @@ class UserAvatarManager extends XmppManagerBase { return const Result(true); } - - /// Returns the PubSub Id of an avatar after doing a disco#items query. - /// Note that this assumes that there is only one (1) item published on - /// the node. - Future> getAvatarId(JID jid) async { - final disco = getAttributes().getManagerById(discoManager)! as DiscoManager; - final response = await disco.discoItemsQuery( - jid, - node: userAvatarDataXmlns, - ); - if (response.isType()) return Result(UnknownAvatarError()); - - final items = response.get>(); - if (items.isEmpty) return Result(UnknownAvatarError()); - - return Result(items.first.name); - } } diff --git a/packages/moxxmpp/lib/src/xeps/xep_0384/xep_0384.dart b/packages/moxxmpp/lib/src/xeps/xep_0384/xep_0384.dart index cdddcd8..2edbb54 100644 --- a/packages/moxxmpp/lib/src/xeps/xep_0384/xep_0384.dart +++ b/packages/moxxmpp/lib/src/xeps/xep_0384/xep_0384.dart @@ -580,7 +580,7 @@ class OmemoManager extends XmppManagerBase { int deviceId, ) async { final pm = getAttributes().getManagerById(pubsubManager)!; - final bareJid = jid.toBare().toString(); + final bareJid = jid.toBare(); final item = await pm.getItem(bareJid, omemoBundlesXmlns, '$deviceId'); if (item.isType()) return Result(UnknownOmemoError()); diff --git a/packages/moxxmpp/lib/src/xeps/xep_0449.dart b/packages/moxxmpp/lib/src/xeps/xep_0449.dart index 26bfc3c..92ba28b 100644 --- a/packages/moxxmpp/lib/src/xeps/xep_0449.dart +++ b/packages/moxxmpp/lib/src/xeps/xep_0449.dart @@ -344,7 +344,7 @@ class StickersManager extends XmppManagerBase { ) async { final pm = getAttributes().getManagerById(pubsubManager)!; final stickerPackDataRaw = await pm.getItem( - jid.toBare().toString(), + jid.toBare(), stickersXmlns, id, );