diff --git a/packages/moxxmpp/CHANGELOG.md b/packages/moxxmpp/CHANGELOG.md
index a68b154..d8ad087 100644
--- a/packages/moxxmpp/CHANGELOG.md
+++ b/packages/moxxmpp/CHANGELOG.md
@@ -1,4 +1,4 @@
-## 0.3.2
+## 0.4.0
- **BREAKING**: Remove `lastResource` from `XmppConnection`'s `connect` method. Instead, set the `StreamManagementNegotiator`'s `resource` attribute instead. Since the resource can only really be restored by stream management, this is no issue.
- **BREAKING**: Changed order of parameters of `CryptographicHashManager.hashFromData`
@@ -11,6 +11,8 @@
- **BREAKING**: `PubSubManager` and `UserAvatarManager` now use `JID` instead of `String`.
- **BREAKING**: `XmppConnection.sendStanza` not only takes a `StanzaDetails` argument.
- Sent stanzas are now kept in a queue until sent.
+- **BREAKING**: `MessageManager.sendMessage` does not use `MessageDetails` anymore. Instead, use `TypedMap`.
+- `MessageManager` now allows registering callbacks for adding data whenever a message is sent.
## 0.3.1
diff --git a/packages/moxxmpp/lib/src/message.dart b/packages/moxxmpp/lib/src/message.dart
index 701d8ce..e10dd2e 100644
--- a/packages/moxxmpp/lib/src/message.dart
+++ b/packages/moxxmpp/lib/src/message.dart
@@ -1,5 +1,4 @@
import 'package:collection/collection.dart';
-import 'package:moxlib/moxlib.dart';
import 'package:moxxmpp/src/events.dart';
import 'package:moxxmpp/src/jid.dart';
import 'package:moxxmpp/src/managers/base.dart';
@@ -15,19 +14,22 @@ import 'package:moxxmpp/src/xeps/xep_0066.dart';
import 'package:moxxmpp/src/xeps/xep_0085.dart';
import 'package:moxxmpp/src/xeps/xep_0184.dart';
import 'package:moxxmpp/src/xeps/xep_0280.dart';
-import 'package:moxxmpp/src/xeps/xep_0308.dart';
import 'package:moxxmpp/src/xeps/xep_0333.dart';
import 'package:moxxmpp/src/xeps/xep_0334.dart';
import 'package:moxxmpp/src/xeps/xep_0359.dart';
import 'package:moxxmpp/src/xeps/xep_0385.dart';
import 'package:moxxmpp/src/xeps/xep_0424.dart';
import 'package:moxxmpp/src/xeps/xep_0444.dart';
-import 'package:moxxmpp/src/xeps/xep_0446.dart';
import 'package:moxxmpp/src/xeps/xep_0447.dart';
-import 'package:moxxmpp/src/xeps/xep_0448.dart';
import 'package:moxxmpp/src/xeps/xep_0449.dart';
import 'package:moxxmpp/src/xeps/xep_0461.dart';
+/// A callback that is called whenever a message is sent using
+/// [MessageManager.sendMessage]. The input the typed map that is passed to
+/// sendMessage.
+typedef MessageSendingCallback = List Function(TypedMap);
+
+/// The raw content of the element.
class MessageBodyData {
const MessageBodyData(this.body);
@@ -42,6 +44,7 @@ class MessageBodyData {
}
}
+/// The id attribute of the message stanza.
class MessageIdData {
const MessageIdData(this.id);
@@ -49,60 +52,6 @@ class MessageIdData {
final String id;
}
-typedef MessageSendingCallback = List Function(TypedMap);
-
-/// Data used to build a message stanza.
-///
-/// [setOOBFallbackBody] indicates, when using SFS, whether a OOB fallback should be
-/// added. This is recommended when sharing files but may cause issues when the message
-/// stanza should include a SFS element without any fallbacks.
-class MessageDetails {
- const MessageDetails({
- required this.to,
- this.body,
- this.requestDeliveryReceipt = false,
- this.requestChatMarkers = true,
- this.id,
- this.originId,
- this.quoteBody,
- this.quoteId,
- this.quoteFrom,
- this.chatState,
- this.sfs,
- this.fun,
- this.funReplacement,
- this.funCancellation,
- this.shouldEncrypt = false,
- this.messageRetraction,
- this.lastMessageCorrectionId,
- this.messageReactions,
- this.messageProcessingHints,
- this.stickerPackId,
- this.setOOBFallbackBody = true,
- });
- final String to;
- final String? body;
- final bool requestDeliveryReceipt;
- final bool requestChatMarkers;
- final String? id;
- final String? originId;
- final String? quoteBody;
- final String? quoteId;
- final String? quoteFrom;
- final ChatState? chatState;
- final StatelessFileSharingData? sfs;
- final FileMetadataData? fun;
- final String? funReplacement;
- final String? funCancellation;
- final bool shouldEncrypt;
- final MessageRetractionData? messageRetraction;
- final String? lastMessageCorrectionId;
- final MessageReactions? messageReactions;
- final String? stickerPackId;
- final List? messageProcessingHints;
- final bool setOOBFallbackBody;
-}
-
class MessageManager extends XmppManagerBase {
MessageManager() : super(messageManager);
@@ -179,7 +128,9 @@ class MessageManager extends XmppManagerBase {
return state..done = true;
}
- Future sendMessage2(JID to, TypedMap extensions) async {
+ /// Send an unawaitable message to [to]. [extensions] is a typed map that contains
+ /// data for building the message.
+ Future sendMessage(JID to, TypedMap extensions) async {
await getAttributes().sendStanza(
StanzaDetails(
Stanza.message(
@@ -196,194 +147,6 @@ class MessageManager extends XmppManagerBase {
);
}
- /// Send a message to to with the content body. If deliveryRequest is true, then
- /// the message will also request a delivery receipt from the receiver.
- /// If id is non-null, then it will be the id of the message stanza.
- /// element to this id. If originId is non-null, then it will create an "origin-id"
- /// child in the message stanza and set its id to originId.
- Future sendMessage(MessageDetails details) async {
- assert(
- implies(
- details.quoteBody != null,
- details.quoteFrom != null && details.quoteId != null,
- ),
- 'When quoting a message, then quoteFrom and quoteId must also be non-null',
- );
-
- final stanza = Stanza.message(
- to: details.to,
- type: 'chat',
- id: details.id,
- children: [],
- );
-
- if (details.quoteBody != null) {
- final quote = QuoteData.fromBodies(details.quoteBody!, details.body!);
-
- stanza
- ..addChild(
- XMLNode(tag: 'body', text: quote.body),
- )
- ..addChild(
- XMLNode.xmlns(
- tag: 'reply',
- xmlns: replyXmlns,
- attributes: {'to': details.quoteFrom!, 'id': details.quoteId!},
- ),
- )
- ..addChild(
- XMLNode.xmlns(
- tag: 'fallback',
- xmlns: fallbackXmlns,
- attributes: {'for': replyXmlns},
- children: [
- XMLNode(
- tag: 'body',
- attributes: {
- 'start': '0',
- 'end': '${quote.fallbackLength}',
- },
- )
- ],
- ),
- );
- } else {
- var body = details.body;
- if (details.sfs != null && details.setOOBFallbackBody) {
- // TODO(Unknown): Maybe find a better solution
- final firstSource = details.sfs!.sources.first;
- if (firstSource is StatelessFileSharingUrlSource) {
- body = firstSource.url;
- } else if (firstSource is StatelessFileSharingEncryptedSource) {
- body = firstSource.source.url;
- }
- } else if (details.messageRetraction?.fallback != null) {
- body = details.messageRetraction!.fallback;
- }
-
- if (body != null) {
- stanza.addChild(
- XMLNode(tag: 'body', text: body),
- );
- }
- }
-
- // if (details.requestDeliveryReceipt) {
- // stanza.addChild(makeMessageDeliveryRequest());
- // }
- if (details.requestChatMarkers) {
- stanza.addChild(makeChatMarkerMarkable());
- }
- if (details.originId != null) {
- stanza.addChild(StableIdData(details.originId, null).toOriginIdElement());
- }
-
- if (details.sfs != null) {
- stanza.addChild(details.sfs!.toXML());
-
- final source = details.sfs!.sources.first;
- if (source is StatelessFileSharingUrlSource &&
- details.setOOBFallbackBody) {
- // SFS recommends OOB as a fallback
- stanza.addChild(OOBData(source.url, null).toXML());
- }
- }
-
- if (details.chatState != null) {
- stanza.addChild(
- details.chatState!.toXML(),
- );
- }
-
- if (details.fun != null) {
- stanza.addChild(
- XMLNode.xmlns(
- tag: 'file-upload',
- xmlns: fileUploadNotificationXmlns,
- children: [
- details.fun!.toXML(),
- ],
- ),
- );
- }
-
- if (details.funReplacement != null) {
- stanza.addChild(
- XMLNode.xmlns(
- tag: 'replaces',
- xmlns: fileUploadNotificationXmlns,
- attributes: {
- 'id': details.funReplacement!,
- },
- ),
- );
- }
-
- if (details.messageRetraction != null) {
- stanza.addChild(
- XMLNode.xmlns(
- tag: 'apply-to',
- xmlns: fasteningXmlns,
- attributes: {
- 'id': details.messageRetraction!.id,
- },
- children: [
- XMLNode.xmlns(
- tag: 'retract',
- xmlns: messageRetractionXmlns,
- ),
- ],
- ),
- );
-
- if (details.messageRetraction!.fallback != null) {
- stanza.addChild(
- XMLNode.xmlns(
- tag: 'fallback',
- xmlns: fallbackIndicationXmlns,
- ),
- );
- }
- }
-
- if (details.lastMessageCorrectionId != null) {
- stanza.addChild(
- LastMessageCorrectionData(
- details.lastMessageCorrectionId!,
- ).toXML(),
- );
- }
-
- if (details.messageReactions != null) {
- stanza.addChild(details.messageReactions!.toXML());
- }
-
- if (details.messageProcessingHints != null) {
- for (final hint in details.messageProcessingHints!) {
- stanza.addChild(hint.toXML());
- }
- }
-
- if (details.stickerPackId != null) {
- stanza.addChild(
- XMLNode.xmlns(
- tag: 'sticker',
- xmlns: stickersXmlns,
- attributes: {
- 'pack': details.stickerPackId!,
- },
- ),
- );
- }
-
- await getAttributes().sendStanza(
- StanzaDetails(
- stanza,
- awaitable: false,
- ),
- );
- }
-
List _messageSendingCallback(TypedMap extensions) {
if (extensions.get() != null) {
return [];
diff --git a/packages/moxxmpp/test/xeps/xep_0449_test.dart b/packages/moxxmpp/test/xeps/xep_0449_test.dart
index c58d972..69c777d 100644
--- a/packages/moxxmpp/test/xeps/xep_0449_test.dart
+++ b/packages/moxxmpp/test/xeps/xep_0449_test.dart
@@ -268,7 +268,7 @@ void main() {
SFSManager(),
]);
- await manager.sendMessage2(
+ await manager.sendMessage(
JID.fromString('user@example.org'),
TypedMap()
..set(