fix: Fix message quote generation
This commit is contained in:
parent
6517065a1a
commit
d7723615fe
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:moxlib/moxlib.dart';
|
||||||
import 'package:moxxmpp/src/events.dart';
|
import 'package:moxxmpp/src/events.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';
|
||||||
@ -20,6 +21,7 @@ import 'package:moxxmpp/src/xeps/xep_0444.dart';
|
|||||||
import 'package:moxxmpp/src/xeps/xep_0446.dart';
|
import 'package:moxxmpp/src/xeps/xep_0446.dart';
|
||||||
import 'package:moxxmpp/src/xeps/xep_0447.dart';
|
import 'package:moxxmpp/src/xeps/xep_0447.dart';
|
||||||
import 'package:moxxmpp/src/xeps/xep_0448.dart';
|
import 'package:moxxmpp/src/xeps/xep_0448.dart';
|
||||||
|
import 'package:moxxmpp/src/xeps/xep_0461.dart';
|
||||||
|
|
||||||
/// Data used to build a message stanza.
|
/// Data used to build a message stanza.
|
||||||
///
|
///
|
||||||
@ -140,6 +142,11 @@ class MessageManager extends XmppManagerBase {
|
|||||||
/// element to this id. If originId is non-null, then it will create an "origin-id"
|
/// 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.
|
/// child in the message stanza and set its id to originId.
|
||||||
void sendMessage(MessageDetails details) {
|
void sendMessage(MessageDetails details) {
|
||||||
|
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(
|
final stanza = Stanza.message(
|
||||||
to: details.to,
|
to: details.to,
|
||||||
type: 'chat',
|
type: 'chat',
|
||||||
@ -148,11 +155,11 @@ class MessageManager extends XmppManagerBase {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (details.quoteBody != null) {
|
if (details.quoteBody != null) {
|
||||||
final fallback = '> ${details.quoteBody!}';
|
final quote = QuoteData.fromBodies(details.quoteBody!, details.body!);
|
||||||
|
|
||||||
stanza
|
stanza
|
||||||
..addChild(
|
..addChild(
|
||||||
XMLNode(tag: 'body', text: '$fallback\n${details.body}'),
|
XMLNode(tag: 'body', text: quote.body),
|
||||||
)
|
)
|
||||||
..addChild(
|
..addChild(
|
||||||
XMLNode.xmlns(
|
XMLNode.xmlns(
|
||||||
@ -176,7 +183,7 @@ class MessageManager extends XmppManagerBase {
|
|||||||
tag: 'body',
|
tag: 'body',
|
||||||
attributes: <String, String>{
|
attributes: <String, String>{
|
||||||
'start': '0',
|
'start': '0',
|
||||||
'end': '${fallback.length}'
|
'end': '${quote.fallbackLength}',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:meta/meta.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';
|
||||||
@ -5,6 +6,7 @@ import 'package:moxxmpp/src/managers/namespaces.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';
|
||||||
|
|
||||||
|
/// Data summarizing the XEP-0461 data.
|
||||||
class ReplyData {
|
class ReplyData {
|
||||||
const ReplyData({
|
const ReplyData({
|
||||||
required this.to,
|
required this.to,
|
||||||
@ -12,12 +14,57 @@ class ReplyData {
|
|||||||
this.start,
|
this.start,
|
||||||
this.end,
|
this.end,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// The bare JID to whom the reply applies to
|
||||||
final String to;
|
final String to;
|
||||||
|
|
||||||
|
/// The stanza ID of the message that is replied to
|
||||||
final String id;
|
final String id;
|
||||||
|
|
||||||
|
/// The start of the fallback body (inclusive)
|
||||||
final int? start;
|
final int? start;
|
||||||
|
|
||||||
|
/// The end of the fallback body (exclusive)
|
||||||
final int? end;
|
final int? end;
|
||||||
|
|
||||||
|
/// Applies the metadata to the received body [body] in order to remove the fallback.
|
||||||
|
/// If either [ReplyData.start] or [ReplyData.end] are null, then body is returned as
|
||||||
|
/// is.
|
||||||
|
String removeFallback(String body) {
|
||||||
|
if (start == null || end == null) return body;
|
||||||
|
|
||||||
|
return body.replaceRange(start!, end, '');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Internal class describing how to build a message with a quote fallback body.
|
||||||
|
@visibleForTesting
|
||||||
|
class QuoteData {
|
||||||
|
const QuoteData(this.body, this.fallbackLength);
|
||||||
|
|
||||||
|
/// Takes the body of the message we want to quote [quoteBody] and the content of
|
||||||
|
/// the reply [body] and computes the fallback body and its length.
|
||||||
|
factory QuoteData.fromBodies(String quoteBody, String body) {
|
||||||
|
final fallback = quoteBody
|
||||||
|
.split('\n')
|
||||||
|
.map((line) => '> $line\n')
|
||||||
|
.join();
|
||||||
|
|
||||||
|
return QuoteData(
|
||||||
|
'$fallback$body',
|
||||||
|
fallback.length,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The new body with fallback data at the beginning
|
||||||
|
final String body;
|
||||||
|
|
||||||
|
/// The length of the fallback data
|
||||||
|
final int fallbackLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A manager implementing support for parsing XEP-0461 metadata. The
|
||||||
|
/// MessageRepliesManager itself does not modify the body of the message.
|
||||||
class MessageRepliesManager extends XmppManagerBase {
|
class MessageRepliesManager extends XmppManagerBase {
|
||||||
@override
|
@override
|
||||||
String getName() => 'MessageRepliesManager';
|
String getName() => 'MessageRepliesManager';
|
||||||
|
44
packages/moxxmpp/test/xeps/xep_0461_test.dart
Normal file
44
packages/moxxmpp/test/xeps/xep_0461_test.dart
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import 'package:moxxmpp/moxxmpp.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('Test building a singleline quote', () {
|
||||||
|
final quote = QuoteData.fromBodies('Hallo Welt', 'Hello Earth!');
|
||||||
|
|
||||||
|
expect(quote.body, '> Hallo Welt\nHello Earth!');
|
||||||
|
expect(quote.fallbackLength, 13);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test building a multiline quote', () {
|
||||||
|
final quote = QuoteData.fromBodies('Hallo Welt\nHallo Erde', 'How are you?');
|
||||||
|
|
||||||
|
expect(quote.body, '> Hallo Welt\n> Hallo Erde\nHow are you?');
|
||||||
|
expect(quote.fallbackLength, 26);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Applying a singleline quote', () {
|
||||||
|
final body = '> Hallo Welt\nHello right back!';
|
||||||
|
final reply = ReplyData(
|
||||||
|
to: '',
|
||||||
|
id: '',
|
||||||
|
start: 0,
|
||||||
|
end: 13,
|
||||||
|
);
|
||||||
|
|
||||||
|
final bodyWithoutFallback = reply.removeFallback(body);
|
||||||
|
expect(bodyWithoutFallback, 'Hello right back!');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Applying a multiline quote', () {
|
||||||
|
final body = "> Hallo Welt\n> How are you?\nI'm fine.\nThank you!";
|
||||||
|
final reply = ReplyData(
|
||||||
|
to: '',
|
||||||
|
id: '',
|
||||||
|
start: 0,
|
||||||
|
end: 28,
|
||||||
|
);
|
||||||
|
|
||||||
|
final bodyWithoutFallback = reply.removeFallback(body);
|
||||||
|
expect(bodyWithoutFallback, "I'm fine.\nThank you!");
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user