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