feat(xep): Implement ignoring the message reflection

This commit is contained in:
2023-09-22 20:42:45 +02:00
parent d7c13abde6
commit fbe3b90200
12 changed files with 139 additions and 45 deletions

View File

@@ -475,7 +475,7 @@ class XmppConnection {
false,
false,
newStanza,
TypedMap(),
details.extensions ?? TypedMap(),
encrypted: details.encrypted,
shouldEncrypt: details.shouldEncrypt,
forceEncryption: details.forceEncryption,

View File

@@ -117,6 +117,7 @@ class MessageManager extends XmppManagerBase {
.flattened
.toList(),
),
extensions: extensions,
awaitable: false,
),
);

View File

@@ -7,6 +7,7 @@ import 'package:moxxmpp/src/util/typed_map.dart';
class StanzaDetails {
const StanzaDetails(
this.stanza, {
this.extensions,
this.addId = true,
this.awaitable = true,
this.shouldEncrypt = true,
@@ -19,6 +20,9 @@ class StanzaDetails {
/// The stanza to send.
final Stanza stanza;
/// The extension data used for constructing the stanza.
final TypedMap<StanzaHandlerExtension>? extensions;
/// Flag indicating whether a stanza id should be added before sending.
final bool addId;

View File

@@ -33,8 +33,13 @@ class RoomInformation {
final String name;
}
/// The used message-id and an optional origin-id.
typedef PendingMessage = (String, String?);
class RoomState {
RoomState({required this.roomJid, this.nick, required this.joined});
RoomState({required this.roomJid, this.nick, required this.joined}) {
pendingMessages = List<PendingMessage>.empty(growable: true);
}
/// The JID of the room.
final JID roomJid;
@@ -45,14 +50,5 @@ class RoomState {
/// Flag whether we're joined and can process messages
bool joined;
RoomState copyWith({
bool? joined,
String? nick,
}) {
return RoomState(
roomJid: roomJid,
joined: joined ?? this.joined,
nick: nick ?? this.nick,
);
}
late final List<PendingMessage> pendingMessages;
}

View File

@@ -11,6 +11,7 @@ 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_0045/errors.dart';
import 'package:moxxmpp/src/xeps/xep_0045/types.dart';
import 'package:moxxmpp/src/xeps/xep_0359.dart';
import 'package:synchronized/extension.dart';
import 'package:synchronized/synchronized.dart';
@@ -33,7 +34,15 @@ class MUCManager extends XmppManagerBase {
callback: _onMessage,
// Before the message handler
priority: -99,
)
),
];
@override
List<StanzaHandler> getOutgoingPreStanzaHandlers() => [
StanzaHandler(
stanzaTag: 'message',
callback: _onMessageSent,
),
];
/// Queries the information of a Multi-User Chat room.
@@ -138,11 +147,33 @@ class MUCManager extends XmppManagerBase {
return const Result(true);
}
Future<StanzaHandlerData> _onMessageSent(
Stanza message,
StanzaHandlerData state,
) async {
if (message.to == null) {
return state;
}
final toJid = JID.fromString(message.to!);
return _cacheLock.synchronized(() {
if (!_mucRoomCache.containsKey(toJid)) {
return state;
}
_mucRoomCache[toJid]!.pendingMessages.add(
(message.id!, state.extensions.get<StableIdData>()?.originId),
);
return state;
});
}
Future<StanzaHandlerData> _onMessage(
Stanza message,
StanzaHandlerData state,
) async {
final roomJid = JID.fromString(message.from!).toBare();
final fromJid = JID.fromString(message.from!);
final roomJid = fromJid.toBare();
return _mucRoomCache.synchronized(() {
final roomState = _mucRoomCache[roomJid];
if (roomState == null) {
@@ -153,7 +184,7 @@ class MUCManager extends XmppManagerBase {
// The room subject marks the end of the join flow.
if (!roomState.joined) {
// Mark the room as joined.
_mucRoomCache[roomJid] = roomState.copyWith(joined: true);
_mucRoomCache[roomJid]!.joined = true;
logger.finest('$roomJid is now joined');
}
@@ -168,7 +199,23 @@ class MUCManager extends XmppManagerBase {
} else {
if (!roomState.joined) {
// Ignore the discussion history.
// TODO: Implement a copyWith method
return StanzaHandlerData(
true,
false,
message,
state.extensions,
);
}
// Check if this is the message reflection.
final pending =
(message.id!, state.extensions.get<StableIdData>()?.originId);
if (fromJid.resource == roomState.nick &&
roomState.pendingMessages.contains(pending)) {
// Silently drop the message.
roomState.pendingMessages.remove(pending);
// TODO(Unknown): Maybe send an event stating that we received the reflection.
return StanzaHandlerData(
true,
false,

View File

@@ -127,7 +127,13 @@ class StableIdManager extends XmppManagerBase {
TypedMap<StanzaHandlerExtension> extensions,
) {
final data = extensions.get<StableIdData>();
return data != null ? data.toXML() : [];
if (data?.originId != null) {
return [
data!.toOriginIdElement(),
];
}
return [];
}
@override

View File

@@ -2,10 +2,10 @@ abstract class OmemoError {}
class UnknownOmemoError extends OmemoError {}
class InvalidAffixElementsException with Exception {}
class InvalidAffixElementsException implements Exception {}
class OmemoNotSupportedForContactException extends OmemoError {}
class EncryptionFailedException with Exception {}
class EncryptionFailedException implements Exception {}
class InvalidEnvelopePayloadException with Exception {}
class InvalidEnvelopePayloadException implements Exception {}

View File

@@ -5,7 +5,7 @@ homepage: https://codeberg.org/moxxy/moxxmpp
publish_to: https://git.polynom.me/api/packages/Moxxy/pub
environment:
sdk: '>=2.17.5 <3.0.0'
sdk: '>=3.0.0 <4.0.0'
dependencies:
collection: ^1.16.0