feat: Implement XEP-0444
This commit is contained in:
parent
0ae13acca0
commit
d9e4a3c1d4
@ -75,6 +75,7 @@ export 'package:moxxmpp/src/xeps/xep_0384/xep_0384.dart';
|
||||
export 'package:moxxmpp/src/xeps/xep_0385.dart';
|
||||
export 'package:moxxmpp/src/xeps/xep_0414.dart';
|
||||
export 'package:moxxmpp/src/xeps/xep_0424.dart';
|
||||
export 'package:moxxmpp/src/xeps/xep_0444.dart';
|
||||
export 'package:moxxmpp/src/xeps/xep_0446.dart';
|
||||
export 'package:moxxmpp/src/xeps/xep_0447.dart';
|
||||
export 'package:moxxmpp/src/xeps/xep_0448.dart';
|
||||
|
@ -9,6 +9,7 @@ import 'package:moxxmpp/src/xeps/xep_0085.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_0461.dart';
|
||||
@ -75,6 +76,7 @@ class MessageEvent extends XmppEvent {
|
||||
this.funCancellation,
|
||||
this.messageRetraction,
|
||||
this.messageCorrectionId,
|
||||
this.messageReactions,
|
||||
});
|
||||
final StanzaError? error;
|
||||
final String body;
|
||||
@ -97,6 +99,7 @@ class MessageEvent extends XmppEvent {
|
||||
final bool encrypted;
|
||||
final MessageRetractionData? messageRetraction;
|
||||
final String? messageCorrectionId;
|
||||
final MessageReactions? messageReactions;
|
||||
final Map<String, dynamic> other;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import 'package:moxxmpp/src/xeps/xep_0359.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0380.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_0461.dart';
|
||||
@ -61,6 +62,8 @@ class StanzaHandlerData with _$StanzaHandlerData {
|
||||
MessageRetractionData? messageRetraction,
|
||||
// If non-null, then the message is a correction for the specified stanza Id
|
||||
String? lastMessageCorrectionSid,
|
||||
// Reactions data
|
||||
MessageReactions? messageReactions,
|
||||
}
|
||||
) = _StanzaHandlerData;
|
||||
}
|
||||
|
@ -59,7 +59,9 @@ mixin _$StanzaHandlerData {
|
||||
// retracted
|
||||
MessageRetractionData? get messageRetraction =>
|
||||
throw _privateConstructorUsedError; // If non-null, then the message is a correction for the specified stanza Id
|
||||
String? get lastMessageCorrectionSid => throw _privateConstructorUsedError;
|
||||
String? get lastMessageCorrectionSid =>
|
||||
throw _privateConstructorUsedError; // Reactions data
|
||||
MessageReactions? get messageReactions => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
$StanzaHandlerDataCopyWith<StanzaHandlerData> get copyWith =>
|
||||
@ -94,7 +96,8 @@ abstract class $StanzaHandlerDataCopyWith<$Res> {
|
||||
DelayedDelivery? delayedDelivery,
|
||||
Map<String, dynamic> other,
|
||||
MessageRetractionData? messageRetraction,
|
||||
String? lastMessageCorrectionSid});
|
||||
String? lastMessageCorrectionSid,
|
||||
MessageReactions? messageReactions});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@ -131,6 +134,7 @@ class _$StanzaHandlerDataCopyWithImpl<$Res>
|
||||
Object? other = freezed,
|
||||
Object? messageRetraction = freezed,
|
||||
Object? lastMessageCorrectionSid = freezed,
|
||||
Object? messageReactions = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
done: done == freezed
|
||||
@ -225,6 +229,10 @@ class _$StanzaHandlerDataCopyWithImpl<$Res>
|
||||
? _value.lastMessageCorrectionSid
|
||||
: lastMessageCorrectionSid // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
messageReactions: messageReactions == freezed
|
||||
? _value.messageReactions
|
||||
: messageReactions // ignore: cast_nullable_to_non_nullable
|
||||
as MessageReactions?,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -259,7 +267,8 @@ abstract class _$$_StanzaHandlerDataCopyWith<$Res>
|
||||
DelayedDelivery? delayedDelivery,
|
||||
Map<String, dynamic> other,
|
||||
MessageRetractionData? messageRetraction,
|
||||
String? lastMessageCorrectionSid});
|
||||
String? lastMessageCorrectionSid,
|
||||
MessageReactions? messageReactions});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@ -298,6 +307,7 @@ class __$$_StanzaHandlerDataCopyWithImpl<$Res>
|
||||
Object? other = freezed,
|
||||
Object? messageRetraction = freezed,
|
||||
Object? lastMessageCorrectionSid = freezed,
|
||||
Object? messageReactions = freezed,
|
||||
}) {
|
||||
return _then(_$_StanzaHandlerData(
|
||||
done == freezed
|
||||
@ -392,6 +402,10 @@ class __$$_StanzaHandlerDataCopyWithImpl<$Res>
|
||||
? _value.lastMessageCorrectionSid
|
||||
: lastMessageCorrectionSid // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
messageReactions: messageReactions == freezed
|
||||
? _value.messageReactions
|
||||
: messageReactions // ignore: cast_nullable_to_non_nullable
|
||||
as MessageReactions?,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -418,7 +432,8 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
|
||||
this.delayedDelivery,
|
||||
final Map<String, dynamic> other = const <String, dynamic>{},
|
||||
this.messageRetraction,
|
||||
this.lastMessageCorrectionSid})
|
||||
this.lastMessageCorrectionSid,
|
||||
this.messageReactions})
|
||||
: _other = other;
|
||||
|
||||
// Indicates to the runner that processing is now done. This means that all
|
||||
@ -501,10 +516,13 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
|
||||
// If non-null, then the message is a correction for the specified stanza Id
|
||||
@override
|
||||
final String? lastMessageCorrectionSid;
|
||||
// Reactions data
|
||||
@override
|
||||
final MessageReactions? messageReactions;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'StanzaHandlerData(done: $done, cancel: $cancel, cancelReason: $cancelReason, stanza: $stanza, retransmitted: $retransmitted, sims: $sims, sfs: $sfs, oob: $oob, stableId: $stableId, reply: $reply, chatState: $chatState, isCarbon: $isCarbon, deliveryReceiptRequested: $deliveryReceiptRequested, isMarkable: $isMarkable, fun: $fun, funReplacement: $funReplacement, funCancellation: $funCancellation, encrypted: $encrypted, encryptionType: $encryptionType, delayedDelivery: $delayedDelivery, other: $other, messageRetraction: $messageRetraction, lastMessageCorrectionSid: $lastMessageCorrectionSid)';
|
||||
return 'StanzaHandlerData(done: $done, cancel: $cancel, cancelReason: $cancelReason, stanza: $stanza, retransmitted: $retransmitted, sims: $sims, sfs: $sfs, oob: $oob, stableId: $stableId, reply: $reply, chatState: $chatState, isCarbon: $isCarbon, deliveryReceiptRequested: $deliveryReceiptRequested, isMarkable: $isMarkable, fun: $fun, funReplacement: $funReplacement, funCancellation: $funCancellation, encrypted: $encrypted, encryptionType: $encryptionType, delayedDelivery: $delayedDelivery, other: $other, messageRetraction: $messageRetraction, lastMessageCorrectionSid: $lastMessageCorrectionSid, messageReactions: $messageReactions)';
|
||||
}
|
||||
|
||||
@override
|
||||
@ -544,7 +562,9 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.messageRetraction, messageRetraction) &&
|
||||
const DeepCollectionEquality().equals(
|
||||
other.lastMessageCorrectionSid, lastMessageCorrectionSid));
|
||||
other.lastMessageCorrectionSid, lastMessageCorrectionSid) &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.messageReactions, messageReactions));
|
||||
}
|
||||
|
||||
@override
|
||||
@ -572,7 +592,8 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
|
||||
const DeepCollectionEquality().hash(delayedDelivery),
|
||||
const DeepCollectionEquality().hash(_other),
|
||||
const DeepCollectionEquality().hash(messageRetraction),
|
||||
const DeepCollectionEquality().hash(lastMessageCorrectionSid)
|
||||
const DeepCollectionEquality().hash(lastMessageCorrectionSid),
|
||||
const DeepCollectionEquality().hash(messageReactions)
|
||||
]);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@ -603,7 +624,8 @@ abstract class _StanzaHandlerData implements StanzaHandlerData {
|
||||
final DelayedDelivery? delayedDelivery,
|
||||
final Map<String, dynamic> other,
|
||||
final MessageRetractionData? messageRetraction,
|
||||
final String? lastMessageCorrectionSid}) = _$_StanzaHandlerData;
|
||||
final String? lastMessageCorrectionSid,
|
||||
final MessageReactions? messageReactions}) = _$_StanzaHandlerData;
|
||||
|
||||
@override // Indicates to the runner that processing is now done. This means that all
|
||||
// pre-processing is done and no other handlers should be consulted.
|
||||
@ -658,6 +680,8 @@ abstract class _StanzaHandlerData implements StanzaHandlerData {
|
||||
MessageRetractionData? get messageRetraction;
|
||||
@override // If non-null, then the message is a correction for the specified stanza Id
|
||||
String? get lastMessageCorrectionSid;
|
||||
@override // Reactions data
|
||||
MessageReactions? get messageReactions;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$_StanzaHandlerDataCopyWith<_$_StanzaHandlerData> get copyWith =>
|
||||
|
@ -26,3 +26,4 @@ const cryptographicHashManager = 'org.moxxmpp.cryptographichashmanager';
|
||||
const delayedDeliveryManager = 'org.moxxmpp.delayeddeliverymanager';
|
||||
const messageRetractionManager = 'org.moxxmpp.messageretractionmanager';
|
||||
const lastMessageCorrectionManager = 'org.moxxmpp.lastmessagecorrectionmanager';
|
||||
const messageReactionsManager = 'org.moxxmpp.messagereactionsmanager';
|
||||
|
@ -15,6 +15,7 @@ import 'package:moxxmpp/src/xeps/xep_0308.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0333.dart';
|
||||
import 'package:moxxmpp/src/xeps/xep_0359.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';
|
||||
@ -38,6 +39,7 @@ class MessageDetails {
|
||||
this.shouldEncrypt = false,
|
||||
this.messageRetraction,
|
||||
this.lastMessageCorrectionId,
|
||||
this.messageReactions,
|
||||
});
|
||||
final String to;
|
||||
final String? body;
|
||||
@ -56,6 +58,7 @@ class MessageDetails {
|
||||
final bool shouldEncrypt;
|
||||
final MessageRetractionData? messageRetraction;
|
||||
final String? lastMessageCorrectionId;
|
||||
final MessageReactions? messageReactions;
|
||||
}
|
||||
|
||||
class MessageManager extends XmppManagerBase {
|
||||
@ -102,6 +105,7 @@ class MessageManager extends XmppManagerBase {
|
||||
encrypted: state.encrypted,
|
||||
messageRetraction: state.messageRetraction,
|
||||
messageCorrectionId: state.lastMessageCorrectionSid,
|
||||
messageReactions: state.messageReactions,
|
||||
other: state.other,
|
||||
error: StanzaError.fromStanza(message),
|
||||
),);
|
||||
@ -261,6 +265,10 @@ class MessageManager extends XmppManagerBase {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (details.messageReactions != null) {
|
||||
stanza.addChild(details.messageReactions!.toXml());
|
||||
}
|
||||
|
||||
getAttributes().sendStanza(stanza, awaitable: false);
|
||||
}
|
||||
|
@ -123,9 +123,12 @@ const fasteningXmlns = 'urn:xmpp:fasten:0';
|
||||
// XEP-0424
|
||||
const messageRetractionXmlns = 'urn:xmpp:message-retract:0';
|
||||
|
||||
// XEp-0428
|
||||
// XEP-0428
|
||||
const fallbackIndicationXmlns = 'urn:xmpp:fallback:0';
|
||||
|
||||
// XEP-0444
|
||||
const messageReactionsXmlns = 'urn:xmpp:reactions:0';
|
||||
|
||||
// XEP-0446
|
||||
const fileMetadataXmlns = 'urn:xmpp:file:metadata:0';
|
||||
|
||||
|
68
packages/moxxmpp/lib/src/xeps/xep_0444.dart
Normal file
68
packages/moxxmpp/lib/src/xeps/xep_0444.dart
Normal file
@ -0,0 +1,68 @@
|
||||
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/namespaces.dart';
|
||||
import 'package:moxxmpp/src/stanza.dart';
|
||||
import 'package:moxxmpp/src/stringxml.dart';
|
||||
|
||||
class MessageReactions {
|
||||
const MessageReactions(this.messageId, this.emojis);
|
||||
final String messageId;
|
||||
final List<String> emojis;
|
||||
|
||||
XMLNode toXml() {
|
||||
return XMLNode.xmlns(
|
||||
tag: 'reactions',
|
||||
xmlns: messageReactionsXmlns,
|
||||
attributes: <String, String>{
|
||||
'id': messageId,
|
||||
},
|
||||
children: emojis.map((emoji) {
|
||||
return XMLNode(
|
||||
tag: 'reaction',
|
||||
text: emoji,
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MessageReactionsManager extends XmppManagerBase {
|
||||
@override
|
||||
List<String> getDiscoFeatures() => [ messageReactionsXmlns ];
|
||||
|
||||
@override
|
||||
String getName() => 'MessageReactionsManager';
|
||||
|
||||
@override
|
||||
String getId() => messageReactionsManager;
|
||||
|
||||
@override
|
||||
List<StanzaHandler> getIncomingStanzaHandlers() => [
|
||||
StanzaHandler(
|
||||
stanzaTag: 'message',
|
||||
tagName: 'reactions',
|
||||
tagXmlns: messageReactionsXmlns,
|
||||
callback: _onReactionsReceived,
|
||||
// Before the message handler
|
||||
priority: -99,
|
||||
),
|
||||
];
|
||||
|
||||
@override
|
||||
Future<bool> isSupported() async => true;
|
||||
|
||||
Future<StanzaHandlerData> _onReactionsReceived(Stanza message, StanzaHandlerData state) async {
|
||||
final reactionsElement = message.firstTag('reactions', xmlns: messageReactionsXmlns)!;
|
||||
return state.copyWith(
|
||||
messageReactions: MessageReactions(
|
||||
reactionsElement.attributes['id']! as String,
|
||||
reactionsElement.children
|
||||
.where((c) => c.tag == 'reaction')
|
||||
.map((c) => c.innerText())
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user