feat: Implement XEP-0308
This commit is contained in:
		
							parent
							
								
									138edffb0a
								
							
						
					
					
						commit
						14c48bcc64
					
				@ -74,6 +74,7 @@ class MessageEvent extends XmppEvent {
 | 
			
		||||
    this.funReplacement,
 | 
			
		||||
    this.funCancellation,
 | 
			
		||||
    this.messageRetraction,
 | 
			
		||||
    this.messageCorrectionId,
 | 
			
		||||
  });
 | 
			
		||||
  final StanzaError? error;
 | 
			
		||||
  final String body;
 | 
			
		||||
@ -95,6 +96,7 @@ class MessageEvent extends XmppEvent {
 | 
			
		||||
  final String? funCancellation;
 | 
			
		||||
  final bool encrypted;
 | 
			
		||||
  final MessageRetractionData? messageRetraction;
 | 
			
		||||
  final String? messageCorrectionId;
 | 
			
		||||
  final Map<String, dynamic> other;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -59,6 +59,8 @@ class StanzaHandlerData with _$StanzaHandlerData {
 | 
			
		||||
      // If non-null, then it indicates the origin Id of the message that should be
 | 
			
		||||
      // retracted
 | 
			
		||||
      MessageRetractionData? messageRetraction,
 | 
			
		||||
      // If non-null, then the message is a correction for the specified stanza Id
 | 
			
		||||
      String? lastMessageCorrectionSid,
 | 
			
		||||
    }
 | 
			
		||||
  ) = _StanzaHandlerData;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,8 @@ mixin _$StanzaHandlerData {
 | 
			
		||||
      throw _privateConstructorUsedError; // If non-null, then it indicates the origin Id of the message that should be
 | 
			
		||||
// retracted
 | 
			
		||||
  MessageRetractionData? get messageRetraction =>
 | 
			
		||||
      throw _privateConstructorUsedError;
 | 
			
		||||
      throw _privateConstructorUsedError; // If non-null, then the message is a correction for the specified stanza Id
 | 
			
		||||
  String? get lastMessageCorrectionSid => throw _privateConstructorUsedError;
 | 
			
		||||
 | 
			
		||||
  @JsonKey(ignore: true)
 | 
			
		||||
  $StanzaHandlerDataCopyWith<StanzaHandlerData> get copyWith =>
 | 
			
		||||
@ -92,7 +93,8 @@ abstract class $StanzaHandlerDataCopyWith<$Res> {
 | 
			
		||||
      ExplicitEncryptionType? encryptionType,
 | 
			
		||||
      DelayedDelivery? delayedDelivery,
 | 
			
		||||
      Map<String, dynamic> other,
 | 
			
		||||
      MessageRetractionData? messageRetraction});
 | 
			
		||||
      MessageRetractionData? messageRetraction,
 | 
			
		||||
      String? lastMessageCorrectionSid});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @nodoc
 | 
			
		||||
@ -128,6 +130,7 @@ class _$StanzaHandlerDataCopyWithImpl<$Res>
 | 
			
		||||
    Object? delayedDelivery = freezed,
 | 
			
		||||
    Object? other = freezed,
 | 
			
		||||
    Object? messageRetraction = freezed,
 | 
			
		||||
    Object? lastMessageCorrectionSid = freezed,
 | 
			
		||||
  }) {
 | 
			
		||||
    return _then(_value.copyWith(
 | 
			
		||||
      done: done == freezed
 | 
			
		||||
@ -218,6 +221,10 @@ class _$StanzaHandlerDataCopyWithImpl<$Res>
 | 
			
		||||
          ? _value.messageRetraction
 | 
			
		||||
          : messageRetraction // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
              as MessageRetractionData?,
 | 
			
		||||
      lastMessageCorrectionSid: lastMessageCorrectionSid == freezed
 | 
			
		||||
          ? _value.lastMessageCorrectionSid
 | 
			
		||||
          : lastMessageCorrectionSid // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
              as String?,
 | 
			
		||||
    ));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -251,7 +258,8 @@ abstract class _$$_StanzaHandlerDataCopyWith<$Res>
 | 
			
		||||
      ExplicitEncryptionType? encryptionType,
 | 
			
		||||
      DelayedDelivery? delayedDelivery,
 | 
			
		||||
      Map<String, dynamic> other,
 | 
			
		||||
      MessageRetractionData? messageRetraction});
 | 
			
		||||
      MessageRetractionData? messageRetraction,
 | 
			
		||||
      String? lastMessageCorrectionSid});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @nodoc
 | 
			
		||||
@ -289,6 +297,7 @@ class __$$_StanzaHandlerDataCopyWithImpl<$Res>
 | 
			
		||||
    Object? delayedDelivery = freezed,
 | 
			
		||||
    Object? other = freezed,
 | 
			
		||||
    Object? messageRetraction = freezed,
 | 
			
		||||
    Object? lastMessageCorrectionSid = freezed,
 | 
			
		||||
  }) {
 | 
			
		||||
    return _then(_$_StanzaHandlerData(
 | 
			
		||||
      done == freezed
 | 
			
		||||
@ -379,6 +388,10 @@ class __$$_StanzaHandlerDataCopyWithImpl<$Res>
 | 
			
		||||
          ? _value.messageRetraction
 | 
			
		||||
          : messageRetraction // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
              as MessageRetractionData?,
 | 
			
		||||
      lastMessageCorrectionSid: lastMessageCorrectionSid == freezed
 | 
			
		||||
          ? _value.lastMessageCorrectionSid
 | 
			
		||||
          : lastMessageCorrectionSid // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
              as String?,
 | 
			
		||||
    ));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -404,7 +417,8 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
 | 
			
		||||
      this.encryptionType,
 | 
			
		||||
      this.delayedDelivery,
 | 
			
		||||
      final Map<String, dynamic> other = const <String, dynamic>{},
 | 
			
		||||
      this.messageRetraction})
 | 
			
		||||
      this.messageRetraction,
 | 
			
		||||
      this.lastMessageCorrectionSid})
 | 
			
		||||
      : _other = other;
 | 
			
		||||
 | 
			
		||||
// Indicates to the runner that processing is now done. This means that all
 | 
			
		||||
@ -484,10 +498,13 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
 | 
			
		||||
// retracted
 | 
			
		||||
  @override
 | 
			
		||||
  final MessageRetractionData? messageRetraction;
 | 
			
		||||
// If non-null, then the message is a correction for the specified stanza Id
 | 
			
		||||
  @override
 | 
			
		||||
  final String? lastMessageCorrectionSid;
 | 
			
		||||
 | 
			
		||||
  @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)';
 | 
			
		||||
    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)';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
@ -525,7 +542,9 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
 | 
			
		||||
                .equals(other.delayedDelivery, delayedDelivery) &&
 | 
			
		||||
            const DeepCollectionEquality().equals(other._other, this._other) &&
 | 
			
		||||
            const DeepCollectionEquality()
 | 
			
		||||
                .equals(other.messageRetraction, messageRetraction));
 | 
			
		||||
                .equals(other.messageRetraction, messageRetraction) &&
 | 
			
		||||
            const DeepCollectionEquality().equals(
 | 
			
		||||
                other.lastMessageCorrectionSid, lastMessageCorrectionSid));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
@ -552,7 +571,8 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
 | 
			
		||||
        const DeepCollectionEquality().hash(encryptionType),
 | 
			
		||||
        const DeepCollectionEquality().hash(delayedDelivery),
 | 
			
		||||
        const DeepCollectionEquality().hash(_other),
 | 
			
		||||
        const DeepCollectionEquality().hash(messageRetraction)
 | 
			
		||||
        const DeepCollectionEquality().hash(messageRetraction),
 | 
			
		||||
        const DeepCollectionEquality().hash(lastMessageCorrectionSid)
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
  @JsonKey(ignore: true)
 | 
			
		||||
@ -582,7 +602,8 @@ abstract class _StanzaHandlerData implements StanzaHandlerData {
 | 
			
		||||
      final ExplicitEncryptionType? encryptionType,
 | 
			
		||||
      final DelayedDelivery? delayedDelivery,
 | 
			
		||||
      final Map<String, dynamic> other,
 | 
			
		||||
      final MessageRetractionData? messageRetraction}) = _$_StanzaHandlerData;
 | 
			
		||||
      final MessageRetractionData? messageRetraction,
 | 
			
		||||
      final String? lastMessageCorrectionSid}) = _$_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.
 | 
			
		||||
@ -635,6 +656,8 @@ abstract class _StanzaHandlerData implements StanzaHandlerData {
 | 
			
		||||
  @override // If non-null, then it indicates the origin Id of the message that should be
 | 
			
		||||
// retracted
 | 
			
		||||
  MessageRetractionData? get messageRetraction;
 | 
			
		||||
  @override // If non-null, then the message is a correction for the specified stanza Id
 | 
			
		||||
  String? get lastMessageCorrectionSid;
 | 
			
		||||
  @override
 | 
			
		||||
  @JsonKey(ignore: true)
 | 
			
		||||
  _$$_StanzaHandlerDataCopyWith<_$_StanzaHandlerData> get copyWith =>
 | 
			
		||||
 | 
			
		||||
@ -25,3 +25,4 @@ const emeManager = 'org.moxxmpp.ememanager';
 | 
			
		||||
const cryptographicHashManager = 'org.moxxmpp.cryptographichashmanager';
 | 
			
		||||
const delayedDeliveryManager = 'org.moxxmpp.delayeddeliverymanager';
 | 
			
		||||
const messageRetractionManager = 'org.moxxmpp.messageretractionmanager';
 | 
			
		||||
const lastMessageCorrectionManager = 'org.moxxmpp.lastmessagecorrectionmanager';
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,7 @@ import 'package:moxxmpp/src/xeps/staging/file_upload_notification.dart';
 | 
			
		||||
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_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';
 | 
			
		||||
@ -36,6 +37,7 @@ class MessageDetails {
 | 
			
		||||
    this.funCancellation,
 | 
			
		||||
    this.shouldEncrypt = false,
 | 
			
		||||
    this.messageRetraction,
 | 
			
		||||
    this.lastMessageCorrectionId,
 | 
			
		||||
  });
 | 
			
		||||
  final String to;
 | 
			
		||||
  final String? body;
 | 
			
		||||
@ -53,6 +55,7 @@ class MessageDetails {
 | 
			
		||||
  final String? funCancellation;
 | 
			
		||||
  final bool shouldEncrypt;
 | 
			
		||||
  final MessageRetractionData? messageRetraction;
 | 
			
		||||
  final String? lastMessageCorrectionId;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class MessageManager extends XmppManagerBase {
 | 
			
		||||
@ -98,6 +101,7 @@ class MessageManager extends XmppManagerBase {
 | 
			
		||||
      funCancellation: state.funCancellation,
 | 
			
		||||
      encrypted: state.encrypted,
 | 
			
		||||
      messageRetraction: state.messageRetraction,
 | 
			
		||||
      messageCorrectionId: state.lastMessageCorrectionSid,
 | 
			
		||||
      other: state.other,
 | 
			
		||||
      error: StanzaError.fromStanza(message),
 | 
			
		||||
    ),);
 | 
			
		||||
@ -249,6 +253,14 @@ class MessageManager extends XmppManagerBase {
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (details.lastMessageCorrectionId != null) {
 | 
			
		||||
      stanza.addChild(
 | 
			
		||||
        makeLastMessageCorrectionEdit(
 | 
			
		||||
          details.lastMessageCorrectionId!,
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    getAttributes().sendStanza(stanza, awaitable: false);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -76,6 +76,9 @@ const hashSha3512 = 'sha3-512';
 | 
			
		||||
const hashBlake2b256 = 'blake2b-256';
 | 
			
		||||
const hashBlake2b512 = 'blake2b-512';
 | 
			
		||||
 | 
			
		||||
// XEP-0308
 | 
			
		||||
const lmcXmlns = 'urn:xmpp:message-correct:0';
 | 
			
		||||
 | 
			
		||||
// XEP-0333
 | 
			
		||||
const chatMarkersXmlns = 'urn:xmpp:chat-markers:0';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										52
									
								
								packages/moxxmpp/lib/src/xeps/xep_0308.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								packages/moxxmpp/lib/src/xeps/xep_0308.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,52 @@
 | 
			
		||||
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';
 | 
			
		||||
 | 
			
		||||
XMLNode makeLastMessageCorrectionEdit(String id) {
 | 
			
		||||
  return XMLNode.xmlns(
 | 
			
		||||
    tag: 'replace',
 | 
			
		||||
    xmlns: lmcXmlns,
 | 
			
		||||
    attributes: <String, String>{
 | 
			
		||||
      'id': id,
 | 
			
		||||
    },
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class LastMessageCorrectionManager extends XmppManagerBase {
 | 
			
		||||
  @override
 | 
			
		||||
  String getName() => 'LastMessageCorrectionManager';
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  String getId() => lastMessageCorrectionManager;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  List<String> getDiscoFeatures() => [ lmcXmlns ];
 | 
			
		||||
  
 | 
			
		||||
  @override
 | 
			
		||||
  List<StanzaHandler> getIncomingStanzaHandlers() => [
 | 
			
		||||
    StanzaHandler(
 | 
			
		||||
      stanzaTag: 'message',
 | 
			
		||||
      tagName: 'reply',
 | 
			
		||||
      tagXmlns: replyXmlns,
 | 
			
		||||
      callback: _onMessage,
 | 
			
		||||
      // Before the message handler
 | 
			
		||||
      priority: -99,
 | 
			
		||||
    )
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Future<bool> isSupported() async => true;
 | 
			
		||||
  
 | 
			
		||||
  Future<StanzaHandlerData> _onMessage(Stanza stanza, StanzaHandlerData state) async {
 | 
			
		||||
    final edit = stanza.firstTag('replace', xmlns: lmcXmlns);
 | 
			
		||||
    if (edit == null) return state;
 | 
			
		||||
 | 
			
		||||
    return state.copyWith(
 | 
			
		||||
      lastMessageCorrectionSid: edit.attributes['id']! as String,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user