feat(xep): Managers register the sending callback

This commit is contained in:
PapaTutuWawa 2023-06-06 15:14:19 +02:00
parent 6f5de9c4dc
commit 0ec3777f44
23 changed files with 498 additions and 218 deletions

View File

@ -31,3 +31,4 @@ const lastMessageCorrectionManager = 'org.moxxmpp.lastmessagecorrectionmanager';
const messageReactionsManager = 'org.moxxmpp.messagereactionsmanager'; const messageReactionsManager = 'org.moxxmpp.messagereactionsmanager';
const stickersManager = 'org.moxxmpp.stickersmanager'; const stickersManager = 'org.moxxmpp.stickersmanager';
const entityCapabilitiesManager = 'org.moxxmpp.entitycapabilities'; const entityCapabilitiesManager = 'org.moxxmpp.entitycapabilities';
const messageProcessingHintManager = 'org.moxxmpp.messageprocessinghint';

View File

@ -40,15 +40,6 @@ class MessageBodyData {
text: body, text: body,
); );
} }
static List<XMLNode> messageSendingCallback(TypedMap extensions) {
if (extensions.get<ReplyData>() != null) {
return [];
}
final data = extensions.get<MessageBodyData>();
return data != null ? [data.toXML()] : [];
}
} }
class MessageIdData { class MessageIdData {
@ -113,11 +104,16 @@ class MessageDetails {
} }
class MessageManager extends XmppManagerBase { class MessageManager extends XmppManagerBase {
MessageManager(this.messageSendingCallbacks) : super(messageManager); MessageManager() : super(messageManager);
/// A list of callbacks that are called when a message is sent in order to add /// A list of callbacks that are called when a message is sent in order to add
/// appropriate child elements. /// appropriate child elements.
final List<MessageSendingCallback> messageSendingCallbacks; final List<MessageSendingCallback> _messageSendingCallbacks =
List<MessageSendingCallback>.empty(growable: true);
void registerMessageSendingCallback(MessageSendingCallback callback) {
_messageSendingCallbacks.add(callback);
}
@override @override
List<StanzaHandler> getIncomingStanzaHandlers() => [ List<StanzaHandler> getIncomingStanzaHandlers() => [
@ -190,7 +186,7 @@ class MessageManager extends XmppManagerBase {
to: to.toString(), to: to.toString(),
id: extensions.get<MessageIdData>()?.id, id: extensions.get<MessageIdData>()?.id,
type: 'chat', type: 'chat',
children: messageSendingCallbacks children: _messageSendingCallbacks
.map((c) => c(extensions)) .map((c) => c(extensions))
.flattened .flattened
.toList(), .toList(),
@ -387,4 +383,30 @@ class MessageManager extends XmppManagerBase {
), ),
); );
} }
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
if (extensions.get<ReplyData>() != null) {
return [];
}
if (extensions.get<StickersData>() != null) {
return [];
}
if (extensions.get<StatelessFileSharingData>() != null) {
return [];
}
if (extensions.get<OOBData>() != null) {
return [];
}
final data = extensions.get<MessageBodyData>();
return data != null ? [data.toXML()] : [];
}
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -96,7 +96,7 @@ const httpFileUploadXmlns = 'urn:xmpp:http:upload:0';
// XEP-0372 // XEP-0372
const referenceXmlns = 'urn:xmpp:reference:0'; const referenceXmlns = 'urn:xmpp:reference:0';
// XEP-380 // XEP-0380
const emeXmlns = 'urn:xmpp:eme:0'; const emeXmlns = 'urn:xmpp:eme:0';
const emeOtr = 'urn:xmpp:otr:0'; const emeOtr = 'urn:xmpp:otr:0';
const emeLegacyOpenPGP = 'jabber:x:encrypted'; const emeLegacyOpenPGP = 'jabber:x:encrypted';

View File

@ -2,8 +2,11 @@ import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart';
import 'package:moxxmpp/src/util/typed_map.dart';
import 'package:moxxmpp/src/xeps/xep_0446.dart'; import 'package:moxxmpp/src/xeps/xep_0446.dart';
/// NOTE: Specified by https://github.com/PapaTutuWawa/custom-xeps/blob/master/xep-xxxx-file-upload-notifications.md /// NOTE: Specified by https://github.com/PapaTutuWawa/custom-xeps/blob/master/xep-xxxx-file-upload-notifications.md
@ -15,6 +18,16 @@ class FileUploadNotificationData {
/// The file metadata indicated in the upload notification. /// The file metadata indicated in the upload notification.
final FileMetadataData metadata; final FileMetadataData metadata;
XMLNode toXML() {
return XMLNode.xmlns(
tag: 'file-upload',
xmlns: fileUploadNotificationXmlns,
children: [
metadata.toXML(),
],
);
}
} }
/// Indicates that a file upload has been cancelled. /// Indicates that a file upload has been cancelled.
@ -23,6 +36,16 @@ class FileUploadNotificationCancellationData {
/// The id of the upload notifiaction that is cancelled. /// The id of the upload notifiaction that is cancelled.
final String id; final String id;
XMLNode toXML() {
return XMLNode.xmlns(
tag: 'cancelled',
xmlns: fileUploadNotificationXmlns,
attributes: {
'id': id,
},
);
}
} }
/// Indicates that a file upload has been completed. /// Indicates that a file upload has been completed.
@ -31,6 +54,16 @@ class FileUploadNotificationReplacementData {
/// The id of the upload notifiaction that is replaced. /// The id of the upload notifiaction that is replaced.
final String id; final String id;
XMLNode toXML() {
return XMLNode.xmlns(
tag: 'replaces',
xmlns: fileUploadNotificationXmlns,
attributes: {
'id': id,
},
);
}
} }
class FileUploadNotificationManager extends XmppManagerBase { class FileUploadNotificationManager extends XmppManagerBase {
@ -107,4 +140,33 @@ class FileUploadNotificationManager extends XmppManagerBase {
), ),
); );
} }
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
final fun = extensions.get<FileUploadNotificationData>();
if (fun != null) {
return [fun.toXML()];
}
final cancel = extensions.get<FileUploadNotificationCancellationData>();
if (cancel != null) {
return [cancel.toXML()];
}
final replace = extensions.get<FileUploadNotificationReplacementData>();
if (replace != null) {
return [replace.toXML()];
}
return [];
}
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -2,9 +2,11 @@ import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
import 'package:moxxmpp/src/util/typed_map.dart';
/// A data class representing the jabber:x:oob tag. /// A data class representing the jabber:x:oob tag.
class OOBData { class OOBData {
@ -65,4 +67,23 @@ class OOBManager extends XmppManagerBase {
), ),
); );
} }
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
final data = extensions.get<OOBData>();
return data != null
? [
data.toXML(),
]
: [];
}
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -2,6 +2,7 @@ import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
@ -53,11 +54,6 @@ enum ChatState {
xmlns: chatStateXmlns, xmlns: chatStateXmlns,
); );
} }
static List<XMLNode> messageSendingCallback(TypedMap extensions) {
final data = extensions.get<ChatState>();
return data != null ? [data.toXML()] : [];
}
} }
class ChatStateManager extends XmppManagerBase { class ChatStateManager extends XmppManagerBase {
@ -109,4 +105,23 @@ class ChatStateManager extends XmppManagerBase {
), ),
); );
} }
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
final data = extensions.get<ChatState>();
return data != null
? [
data.toXML(),
]
: [];
}
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -4,6 +4,7 @@ import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
@ -25,15 +26,6 @@ class MessageDeliveryReceiptData {
xmlns: deliveryXmlns, xmlns: deliveryXmlns,
); );
} }
static List<XMLNode> messageSendingCallback(TypedMap extensions) {
final data = extensions.get<MessageDeliveryReceiptData>();
return data != null
? [
data.toXML(),
]
: [];
}
} }
class MessageDeliveryReceivedData { class MessageDeliveryReceivedData {
@ -49,11 +41,6 @@ class MessageDeliveryReceivedData {
attributes: {'id': id}, attributes: {'id': id},
); );
} }
static List<XMLNode> messageSendingCallback(TypedMap extensions) {
final data = extensions.get<MessageDeliveryReceivedData>();
return data != null ? [data.toXML()] : [];
}
} }
class MessageDeliveryReceiptManager extends XmppManagerBase { class MessageDeliveryReceiptManager extends XmppManagerBase {
@ -116,4 +103,23 @@ class MessageDeliveryReceiptManager extends XmppManagerBase {
); );
return state..done = true; return state..done = true;
} }
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
final data = extensions.get<MessageDeliveryReceivedData>();
return data != null
? [
data.toXML(),
]
: [];
}
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -2,6 +2,7 @@ import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
@ -22,15 +23,6 @@ class LastMessageCorrectionData {
}, },
); );
} }
static List<XMLNode> messageSendingCallback(TypedMap extensions) {
final data = extensions.get<LastMessageCorrectionData>();
return data != null
? [
data.toXML(),
]
: [];
}
} }
class LastMessageCorrectionManager extends XmppManagerBase { class LastMessageCorrectionManager extends XmppManagerBase {
@ -64,4 +56,23 @@ class LastMessageCorrectionManager extends XmppManagerBase {
LastMessageCorrectionData(edit.attributes['id']! as String), LastMessageCorrectionData(edit.attributes['id']! as String),
); );
} }
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
final data = extensions.get<LastMessageCorrectionData>();
return data != null
? [
data.toXML(),
]
: [];
}
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -4,9 +4,11 @@ import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
import 'package:moxxmpp/src/util/typed_map.dart';
class ChatMarkerData { class ChatMarkerData {
const ChatMarkerData(this.isMarkable); const ChatMarkerData(this.isMarkable);
@ -79,4 +81,19 @@ class ChatMarkerManager extends XmppManagerBase {
return state..done = true; return state..done = true;
} }
// TODO: Implement
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
return [];
}
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -1,4 +1,10 @@
import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.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/util/typed_map.dart'; import 'package:moxxmpp/src/util/typed_map.dart';
@ -46,8 +52,35 @@ enum MessageProcessingHint {
xmlns: messageProcessingHintsXmlns, xmlns: messageProcessingHintsXmlns,
); );
} }
}
static List<XMLNode> messageSendingCallback(TypedMap extensions) { class MessageProcessingHintManager extends XmppManagerBase {
MessageProcessingHintManager() : super(messageProcessingHintManager);
@override
Future<bool> isSupported() async => true;
@override
List<StanzaHandler> getIncomingStanzaHandlers() => [
StanzaHandler(
stanzaTag: 'message',
tagXmlns: messageProcessingHintsXmlns,
callback: _onMessage,
// Before the message handler
priority: -99,
),
];
// TODO: Test
Future<StanzaHandlerData> _onMessage(
Stanza stanza,
StanzaHandlerData state,
) async {
final element = stanza.findTagsByXmlns(messageProcessingHintsXmlns).first;
return state..extensions.set(MessageProcessingHint.fromName(element.tag));
}
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
final data = extensions.get<MessageProcessingHint>(); final data = extensions.get<MessageProcessingHint>();
return data != null return data != null
? [ ? [
@ -55,4 +88,14 @@ enum MessageProcessingHint {
] ]
: []; : [];
} }
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -3,6 +3,7 @@ import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
@ -65,11 +66,6 @@ class StableIdData {
if (stanzaIds != null) ...stanzaIds!.map((s) => s.toXML()), if (stanzaIds != null) ...stanzaIds!.map((s) => s.toXML()),
]; ];
} }
static List<XMLNode> messageSendingCallback(TypedMap extensions) {
final data = extensions.get<StableIdData>();
return data != null ? data.toXML() : [];
}
} }
class StableIdManager extends XmppManagerBase { class StableIdManager extends XmppManagerBase {
@ -126,4 +122,19 @@ class StableIdManager extends XmppManagerBase {
), ),
); );
} }
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
final data = extensions.get<StableIdData>();
return data != null ? data.toXML() : [];
}
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -70,7 +70,9 @@ StatelessMediaSharingData parseSIMSElement(XMLNode node) {
); );
} }
@Deprecated('Not maintained')
class SIMSManager extends XmppManagerBase { class SIMSManager extends XmppManagerBase {
@Deprecated('Not maintained')
SIMSManager() : super(simsManager); SIMSManager() : super(simsManager);
@override @override

View File

@ -2,6 +2,7 @@ import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
@ -15,37 +16,6 @@ class MessageRetractionData {
/// The id of the message that is retracted. /// The id of the message that is retracted.
final String id; final String id;
static List<XMLNode> messageSendingCallback(TypedMap extensions) {
final data = extensions.get<MessageRetractionData>();
return data != null
? [
XMLNode.xmlns(
tag: 'apply-to',
xmlns: fasteningXmlns,
attributes: <String, String>{
'id': data.id,
},
children: [
XMLNode.xmlns(
tag: 'retract',
xmlns: messageRetractionXmlns,
),
],
),
if (data.fallback != null)
XMLNode(
tag: 'body',
text: data.fallback,
),
if (data.fallback != null)
XMLNode.xmlns(
tag: 'fallback',
xmlns: fallbackIndicationXmlns,
),
]
: [];
}
} }
class MessageRetractionManager extends XmppManagerBase { class MessageRetractionManager extends XmppManagerBase {
@ -92,4 +62,45 @@ class MessageRetractionManager extends XmppManagerBase {
), ),
); );
} }
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
final data = extensions.get<MessageRetractionData>();
return data != null
? [
XMLNode.xmlns(
tag: 'apply-to',
xmlns: fasteningXmlns,
attributes: <String, String>{
'id': data.id,
},
children: [
XMLNode.xmlns(
tag: 'retract',
xmlns: messageRetractionXmlns,
),
],
),
if (data.fallback != null)
XMLNode(
tag: 'body',
text: data.fallback,
),
if (data.fallback != null)
XMLNode.xmlns(
tag: 'fallback',
xmlns: fallbackIndicationXmlns,
),
]
: [];
}
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -2,6 +2,7 @@ import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
@ -27,15 +28,6 @@ class MessageReactions {
}).toList(), }).toList(),
); );
} }
static List<XMLNode> messageSendingCallback(TypedMap extensions) {
final data = extensions.get<MessageReactions>();
return data != null
? [
data.toXML(),
]
: [];
}
} }
class MessageReactionsManager extends XmppManagerBase { class MessageReactionsManager extends XmppManagerBase {
@ -76,4 +68,23 @@ class MessageReactionsManager extends XmppManagerBase {
), ),
); );
} }
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
final data = extensions.get<MessageReactions>();
return data != null
? [
data.toXML(),
]
: [];
}
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -3,6 +3,7 @@ import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
@ -119,26 +120,6 @@ class StatelessFileSharingData {
source is StatelessFileSharingUrlSource, source is StatelessFileSharingUrlSource,
) as StatelessFileSharingUrlSource?; ) as StatelessFileSharingUrlSource?;
} }
static List<XMLNode> messageSendingCallback(TypedMap extensions) {
final data = extensions.get<StatelessFileSharingData>();
if (data == null) {
return [];
}
// TODO(Unknown): Consider all sources?
final source = data.sources.first;
OOBData? oob;
if (source is StatelessFileSharingUrlSource && data.includeOOBFallback) {
// SFS recommends OOB as a fallback
oob = OOBData(source.url, null);
}
return [
data.toXML(),
if (oob != null) oob.toXML(),
];
}
} }
class SFSManager extends XmppManagerBase { class SFSManager extends XmppManagerBase {
@ -159,6 +140,26 @@ class SFSManager extends XmppManagerBase {
@override @override
Future<bool> isSupported() async => true; Future<bool> isSupported() async => true;
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
final data = extensions.get<StatelessFileSharingData>();
if (data == null) {
return [];
}
// TODO(Unknown): Consider all sources?
final source = data.sources.first;
OOBData? oob;
if (source is StatelessFileSharingUrlSource && data.includeOOBFallback) {
// SFS recommends OOB as a fallback
oob = OOBData(source.url, null);
}
return [
data.toXML(),
if (oob != null) oob.toXML(),
];
}
Future<StanzaHandlerData> _onMessage( Future<StanzaHandlerData> _onMessage(
Stanza message, Stanza message,
StanzaHandlerData state, StanzaHandlerData state,
@ -170,4 +171,14 @@ class SFSManager extends XmppManagerBase {
StatelessFileSharingData.fromXML(sfs), StatelessFileSharingData.fromXML(sfs),
); );
} }
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -4,6 +4,7 @@ import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/rfcs/rfc_4790.dart'; import 'package:moxxmpp/src/rfcs/rfc_4790.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
@ -236,22 +237,6 @@ class StickersData {
/// The metadata of the sticker. /// The metadata of the sticker.
final StatelessFileSharingData sticker; final StatelessFileSharingData sticker;
static List<XMLNode> messageSendingCallback(TypedMap extensions) {
final data = extensions.get<StickersData>();
return data != null
? [
XMLNode.xmlns(
tag: 'sticker',
xmlns: stickersXmlns,
attributes: {
'pack': data.stickerPackId,
},
),
data.sticker.toXML(),
]
: [];
}
} }
class StickersManager extends XmppManagerBase { class StickersManager extends XmppManagerBase {
@ -285,6 +270,22 @@ class StickersManager extends XmppManagerBase {
); );
} }
List<XMLNode> _messageSendingCallback(TypedMap extensions) {
final data = extensions.get<StickersData>();
return data != null
? [
XMLNode.xmlns(
tag: 'sticker',
xmlns: stickersXmlns,
attributes: {
'pack': data.stickerPackId,
},
),
data.sticker.toXML(),
]
: [];
}
/// Publishes the StickerPack [pack] to the PubSub node of [jid]. If specified, then /// Publishes the StickerPack [pack] to the PubSub node of [jid]. If specified, then
/// [accessModel] will be used as the PubSub node's access model. /// [accessModel] will be used as the PubSub node's access model.
/// ///
@ -350,4 +351,14 @@ class StickersManager extends XmppManagerBase {
return Result(stickerPack); return Result(stickerPack);
} }
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(_messageSendingCallback);
}
} }

View File

@ -1,8 +1,10 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:moxxmpp/src/jid.dart'; 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/data.dart'; import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/message.dart';
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
@ -51,44 +53,6 @@ class ReplyData {
return body!.replaceRange(start!, end, ''); return body!.replaceRange(start!, end, '');
} }
static List<XMLNode> messageSendingCallback(TypedMap extensions) {
final data = extensions.get<ReplyData>();
return data != null
? [
XMLNode.xmlns(
tag: 'reply',
xmlns: replyXmlns,
attributes: {
// The to attribute is optional
if (data.jid != null) 'to': data.jid!.toString(),
'id': data.id,
},
),
if (data.body != null)
XMLNode(
tag: 'body',
text: data.body,
),
if (data.body != null)
XMLNode.xmlns(
tag: 'fallback',
xmlns: fallbackXmlns,
attributes: {'for': replyXmlns},
children: [
XMLNode(
tag: 'body',
attributes: {
'start': data.start!.toString(),
'end': data.end!.toString(),
},
),
],
),
]
: [];
}
} }
/// Internal class describing how to build a message with a quote fallback body. /// Internal class describing how to build a message with a quote fallback body.
@ -138,6 +102,45 @@ class MessageRepliesManager extends XmppManagerBase {
@override @override
Future<bool> isSupported() async => true; Future<bool> isSupported() async => true;
@visibleForTesting
List<XMLNode> messageSendingCallback(TypedMap extensions) {
final data = extensions.get<ReplyData>();
return data != null
? [
XMLNode.xmlns(
tag: 'reply',
xmlns: replyXmlns,
attributes: {
// The to attribute is optional
if (data.jid != null) 'to': data.jid!.toString(),
'id': data.id,
},
),
if (data.body != null)
XMLNode(
tag: 'body',
text: data.body,
),
if (data.body != null)
XMLNode.xmlns(
tag: 'fallback',
xmlns: fallbackXmlns,
attributes: {'for': replyXmlns},
children: [
XMLNode(
tag: 'body',
attributes: {
'start': data.start!.toString(),
'end': data.end!.toString(),
},
),
],
),
]
: [];
}
Future<StanzaHandlerData> _onMessage( Future<StanzaHandlerData> _onMessage(
Stanza stanza, Stanza stanza,
StanzaHandlerData state, StanzaHandlerData state,
@ -167,4 +170,14 @@ class MessageRepliesManager extends XmppManagerBase {
), ),
); );
} }
@override
Future<void> postRegisterCallback() async {
await super.postRegisterCallback();
// Register the sending callback
getAttributes()
.getManagerById<MessageManager>(messageManager)
?.registerMessageSendingCallback(messageSendingCallback);
}
} }

View File

@ -41,7 +41,8 @@ class TestingManagerHolder {
return _managers[id] as T?; return _managers[id] as T?;
} }
Future<void> register(XmppManagerBase manager) async { Future<void> register(List<XmppManagerBase> managers) async {
for (final manager in managers) {
manager.register( manager.register(
XmppManagerAttributes( XmppManagerAttributes(
sendStanza: _sendStanza, sendStanza: _sendStanza,
@ -60,8 +61,11 @@ class TestingManagerHolder {
getManagerById: _getManagerById, getManagerById: _getManagerById,
), ),
); );
await manager.postRegisterCallback();
_managers[manager.id] = manager; _managers[manager.id] = manager;
} }
for (final manager in managers) {
await manager.postRegisterCallback();
}
}
} }

View File

@ -120,8 +120,7 @@ void main() {
final ecm = EntityCapabilitiesManager(''); final ecm = EntityCapabilitiesManager('');
final dm = DiscoManager([]); final dm = DiscoManager([]);
await tm.register(dm); await tm.register([dm, ecm]);
await tm.register(ecm);
// Inject a capability hash into the cache // Inject a capability hash into the cache
final aliceJid = JID.fromString('alice@example.org/abc123'); final aliceJid = JID.fromString('alice@example.org/abc123');

View File

@ -55,8 +55,10 @@ void main() {
() async { () async {
final manager = PubSubManager(); final manager = PubSubManager();
final tm = TestingManagerHolder(); final tm = TestingManagerHolder();
await tm.register(StubbedDiscoManager(false)); await tm.register([
await tm.register(manager); StubbedDiscoManager(false),
manager,
]);
final result = await manager.preprocessPublishOptions( final result = await manager.preprocessPublishOptions(
JID.fromString('pubsub.server.example.org'), JID.fromString('pubsub.server.example.org'),
@ -72,8 +74,10 @@ void main() {
() async { () async {
final manager = PubSubManager(); final manager = PubSubManager();
final tm = TestingManagerHolder(); final tm = TestingManagerHolder();
await tm.register(StubbedDiscoManager(true)); await tm.register([
await tm.register(manager); StubbedDiscoManager(true),
manager,
]);
final result = await manager.preprocessPublishOptions( final result = await manager.preprocessPublishOptions(
JID.fromString('pubsub.server.example.org'), JID.fromString('pubsub.server.example.org'),

View File

@ -319,8 +319,10 @@ void main() {
final tm = TestingManagerHolder(); final tm = TestingManagerHolder();
final manager = EntityCapabilitiesManager(''); final manager = EntityCapabilitiesManager('');
await tm.register(StubbedDiscoManager()); await tm.register([
await tm.register(manager); StubbedDiscoManager(),
manager,
]);
await manager.onPresence( await manager.onPresence(
PresenceReceivedEvent( PresenceReceivedEvent(
@ -352,8 +354,10 @@ void main() {
final tm = TestingManagerHolder(); final tm = TestingManagerHolder();
final manager = EntityCapabilitiesManager(''); final manager = EntityCapabilitiesManager('');
await tm.register(StubbedDiscoManager()); await tm.register([
await tm.register(manager); StubbedDiscoManager(),
manager,
]);
await manager.onPresence( await manager.onPresence(
PresenceReceivedEvent( PresenceReceivedEvent(
@ -385,10 +389,10 @@ void main() {
final tm = TestingManagerHolder(); final tm = TestingManagerHolder();
final manager = EntityCapabilitiesManager(''); final manager = EntityCapabilitiesManager('');
await tm.register( await tm.register([
StubbedDiscoManager()..multipleEqualIdentities = true, StubbedDiscoManager()..multipleEqualIdentities = true,
); manager,
await tm.register(manager); ]);
await manager.onPresence( await manager.onPresence(
PresenceReceivedEvent( PresenceReceivedEvent(
@ -420,10 +424,10 @@ void main() {
final tm = TestingManagerHolder(); final tm = TestingManagerHolder();
final manager = EntityCapabilitiesManager(''); final manager = EntityCapabilitiesManager('');
await tm.register( await tm.register([
StubbedDiscoManager()..multipleEqualFeatures = true, StubbedDiscoManager()..multipleEqualFeatures = true,
); manager,
await tm.register(manager); ]);
await manager.onPresence( await manager.onPresence(
PresenceReceivedEvent( PresenceReceivedEvent(
@ -455,10 +459,10 @@ void main() {
final tm = TestingManagerHolder(); final tm = TestingManagerHolder();
final manager = EntityCapabilitiesManager(''); final manager = EntityCapabilitiesManager('');
await tm.register( await tm.register([
StubbedDiscoManager()..multipleExtendedFormsWithSameType = true, StubbedDiscoManager()..multipleExtendedFormsWithSameType = true,
); manager,
await tm.register(manager); ]);
await manager.onPresence( await manager.onPresence(
PresenceReceivedEvent( PresenceReceivedEvent(
@ -490,10 +494,10 @@ void main() {
final tm = TestingManagerHolder(); final tm = TestingManagerHolder();
final manager = EntityCapabilitiesManager(''); final manager = EntityCapabilitiesManager('');
await tm.register( await tm.register([
StubbedDiscoManager()..invalidExtension1 = true, StubbedDiscoManager()..invalidExtension1 = true,
); manager,
await tm.register(manager); ]);
await manager.onPresence( await manager.onPresence(
PresenceReceivedEvent( PresenceReceivedEvent(
@ -527,10 +531,10 @@ void main() {
final tm = TestingManagerHolder(); final tm = TestingManagerHolder();
final manager = EntityCapabilitiesManager(''); final manager = EntityCapabilitiesManager('');
await tm.register( await tm.register([
StubbedDiscoManager()..invalidExtension2 = true, StubbedDiscoManager()..invalidExtension2 = true,
); manager,
await tm.register(manager); ]);
await manager.onPresence( await manager.onPresence(
PresenceReceivedEvent( PresenceReceivedEvent(
@ -564,10 +568,10 @@ void main() {
final tm = TestingManagerHolder(); final tm = TestingManagerHolder();
final manager = EntityCapabilitiesManager(''); final manager = EntityCapabilitiesManager('');
await tm.register( await tm.register([
StubbedDiscoManager()..invalidExtension3 = true, StubbedDiscoManager()..invalidExtension3 = true,
); manager,
await tm.register(manager); ]);
await manager.onPresence( await manager.onPresence(
PresenceReceivedEvent( PresenceReceivedEvent(

View File

@ -234,10 +234,7 @@ void main() {
}); });
test('Test sending a sticker', () async { test('Test sending a sticker', () async {
final manager = MessageManager([ final manager = MessageManager();
StatelessFileSharingData.messageSendingCallback,
StickersData.messageSendingCallback,
]);
final holder = TestingManagerHolder( final holder = TestingManagerHolder(
stubSocket: StubTCPSocket([ stubSocket: StubTCPSocket([
StanzaExpectation( StanzaExpectation(
@ -265,7 +262,11 @@ void main() {
), ),
]), ]),
); );
await holder.register(manager); await holder.register([
manager,
StickersManager(),
SFSManager(),
]);
await manager.sendMessage2( await manager.sendMessage2(
JID.fromString('user@example.org'), JID.fromString('user@example.org'),
@ -360,7 +361,7 @@ void main() {
password: 'aaaa', password: 'aaaa',
); );
await conn.registerManagers([ await conn.registerManagers([
MessageManager([]), MessageManager(),
SFSManager(), SFSManager(),
StickersManager(), StickersManager(),
]); ]);

View File

@ -45,7 +45,7 @@ void main() {
}); });
test('Test calling the message sending callback', () { test('Test calling the message sending callback', () {
final result = ReplyData.messageSendingCallback( final result = MessageRepliesManager().messageSendingCallback(
TypedMap() TypedMap()
..set( ..set(
ReplyData.fromQuoteData( ReplyData.fromQuoteData(
@ -129,7 +129,7 @@ void main() {
password: 'aaaa', password: 'aaaa',
); );
await conn.registerManagers([ await conn.registerManagers([
MessageManager([]), MessageManager(),
MessageRepliesManager(), MessageRepliesManager(),
]); ]);
await conn.registerFeatureNegotiators([ await conn.registerFeatureNegotiators([
@ -228,7 +228,7 @@ void main() {
password: 'aaaa', password: 'aaaa',
); );
await conn.registerManagers([ await conn.registerManagers([
MessageManager([]), MessageManager(),
MessageRepliesManager(), MessageRepliesManager(),
]); ]);
await conn.registerFeatureNegotiators([ await conn.registerFeatureNegotiators([