feat(xep): Make avatar queries more explicit
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
PapaTutuWawa 2023-09-17 20:10:53 +02:00
parent 1625f912b0
commit 9666557655
5 changed files with 47 additions and 41 deletions

View File

@ -18,7 +18,10 @@
- **BREAKING**: `ChatState.toString()` is now `ChatState.toName()` - **BREAKING**: `ChatState.toString()` is now `ChatState.toName()`
- **BREAKING**: Overriding `BaseOmemoManager` is no longer required. `OmemoManager` now takes callback methods instead. - **BREAKING**: Overriding `BaseOmemoManager` is no longer required. `OmemoManager` now takes callback methods instead.
- Removed `ErrorResponseDiscoError` from the possible XEP-0030 errors. - 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 ## 0.3.1

View File

@ -401,8 +401,9 @@ class PubSubManager extends XmppManagerBase {
Future<Result<PubSubError, List<PubSubItem>>> getItems( Future<Result<PubSubError, List<PubSubItem>>> getItems(
JID jid, JID jid,
String node, String node, {
) async { int? maxItems,
}) async {
final result = (await getAttributes().sendStanza( final result = (await getAttributes().sendStanza(
StanzaDetails( StanzaDetails(
Stanza.iq( Stanza.iq(
@ -415,7 +416,10 @@ class PubSubManager extends XmppManagerBase {
children: [ children: [
XMLNode( XMLNode(
tag: 'items', tag: 'items',
attributes: <String, String>{'node': node}, attributes: {
'node': node,
if (maxItems != null) 'max_items': maxItems.toString(),
},
), ),
], ],
) )
@ -446,7 +450,7 @@ class PubSubManager extends XmppManagerBase {
} }
Future<Result<PubSubError, PubSubItem>> getItem( Future<Result<PubSubError, PubSubItem>> getItem(
String jid, JID jid,
String node, String node,
String id, String id,
) async { ) async {
@ -454,7 +458,7 @@ class PubSubManager extends XmppManagerBase {
StanzaDetails( StanzaDetails(
Stanza.iq( Stanza.iq(
type: 'get', type: 'get',
to: jid, to: jid.toString(),
children: [ children: [
XMLNode.xmlns( XMLNode.xmlns(
tag: 'pubsub', tag: 'pubsub',

View File

@ -5,10 +5,7 @@ import 'package:moxxmpp/src/jid.dart';
import 'package:moxxmpp/src/managers/base.dart'; import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.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/errors.dart';
import 'package:moxxmpp/src/xeps/xep_0060/xep_0060.dart'; import 'package:moxxmpp/src/xeps/xep_0060/xep_0060.dart';
@ -43,11 +40,7 @@ class UserAvatarMetadata {
); );
factory UserAvatarMetadata.fromXML(XMLNode node) { factory UserAvatarMetadata.fromXML(XMLNode node) {
assert( assert(node.tag == 'info', 'node must be an <info /> element');
node.tag == 'metadata' &&
node.attributes['xmlns'] == userAvatarMetadataXmlns,
'<metadata /> element required',
);
final width = node.attributes['width'] as String?; final width = node.attributes['width'] as String?;
final height = node.attributes['height'] 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 /// Requests the avatar from [jid]. Returns the avatar data if the request was
/// successful. Null otherwise /// successful. Null otherwise
Future<Result<AvatarError, UserAvatarData>> getUserAvatar(JID jid) async { Future<Result<AvatarError, UserAvatarData>> getUserAvatarData(
JID jid,
String id,
) async {
final pubsub = _getPubSubManager(); final pubsub = _getPubSubManager();
final resultsRaw = await pubsub.getItems(jid, userAvatarDataXmlns); final resultRaw = await pubsub.getItem(jid, userAvatarDataXmlns, id);
if (resultRaw.isType<PubSubError>()) return Result(UnknownAvatarError());
final result = resultRaw.get<PubSubItem>();
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<Result<AvatarError, List<UserAvatarMetadata>>> getLatestMetadata(
JID jid,
) async {
final resultsRaw = await _getPubSubManager()
.getItems(jid, userAvatarMetadataXmlns, maxItems: 1);
if (resultsRaw.isType<PubSubError>()) return Result(UnknownAvatarError()); if (resultsRaw.isType<PubSubError>()) return Result(UnknownAvatarError());
final results = resultsRaw.get<List<PubSubItem>>(); final results = resultsRaw.get<List<PubSubItem>>();
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( return Result(
UserAvatarData( metadata.findTags('info').map(UserAvatarMetadata.fromXML).toList(),
item.payload.innerText(),
item.id,
),
); );
} }
@ -216,21 +232,4 @@ class UserAvatarManager extends XmppManagerBase {
return const Result(true); 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<Result<AvatarError, String>> getAvatarId(JID jid) async {
final disco = getAttributes().getManagerById(discoManager)! as DiscoManager;
final response = await disco.discoItemsQuery(
jid,
node: userAvatarDataXmlns,
);
if (response.isType<StanzaError>()) return Result(UnknownAvatarError());
final items = response.get<List<DiscoItem>>();
if (items.isEmpty) return Result(UnknownAvatarError());
return Result(items.first.name);
}
} }

View File

@ -580,7 +580,7 @@ class OmemoManager extends XmppManagerBase {
int deviceId, int deviceId,
) async { ) async {
final pm = getAttributes().getManagerById<PubSubManager>(pubsubManager)!; final pm = getAttributes().getManagerById<PubSubManager>(pubsubManager)!;
final bareJid = jid.toBare().toString(); final bareJid = jid.toBare();
final item = await pm.getItem(bareJid, omemoBundlesXmlns, '$deviceId'); final item = await pm.getItem(bareJid, omemoBundlesXmlns, '$deviceId');
if (item.isType<PubSubError>()) return Result(UnknownOmemoError()); if (item.isType<PubSubError>()) return Result(UnknownOmemoError());

View File

@ -344,7 +344,7 @@ class StickersManager extends XmppManagerBase {
) async { ) async {
final pm = getAttributes().getManagerById<PubSubManager>(pubsubManager)!; final pm = getAttributes().getManagerById<PubSubManager>(pubsubManager)!;
final stickerPackDataRaw = await pm.getItem( final stickerPackDataRaw = await pm.getItem(
jid.toBare().toString(), jid.toBare(),
stickersXmlns, stickersXmlns,
id, id,
); );