2
0
Эх сурвалжийг харах

Fixes #3007

Bugfix: Links in message become text when the message is edited
JC Brand 2 жил өмнө
parent
commit
ca3c8fc10b

+ 1 - 0
CHANGES.md

@@ -16,6 +16,7 @@
 - #2925: Fix missing disco-items in browser storage.
 - #2936: Fix documentation about enable_smacks option, which is true by default.
 - #3005: Fix MUC messages with a fallback body not rendering.
+- #3007: Fix links becoming text when a message is edited
 
 ## 9.1.1 (2022-05-05)
 

+ 10 - 11
src/headless/plugins/chat/model.js

@@ -927,19 +927,18 @@ const ChatBox = ModelWithContact.extend({
             const older_versions = message.get('older_versions') || {};
             const edited_time = message.get('edited') || message.get('time');
             older_versions[edited_time] = message.getMessageText();
-            const plaintext = attrs.is_encrypted ? attrs.message : undefined;
 
             message.save({
-                'body': attrs.body,
-                'message': attrs.body,
-                'correcting': false,
-                'edited': (new Date()).toISOString(),
-                'is_only_emojis':  attrs.is_only_emojis,
-                'origin_id': u.getUniqueId(),
-                'received': undefined,
-                'references': attrs.references,
-                older_versions,
-                plaintext,
+                ...pick(attrs, ['body', 'is_only_emojis', 'media_urls', 'references', 'is_encrypted']),
+                ...{
+                    'correcting': false,
+                    'edited': (new Date()).toISOString(),
+                    'message': attrs.body,
+                    'origin_id': u.getUniqueId(),
+                    'received': undefined,
+                    older_versions,
+                    plaintext: attrs.is_encrypted ? attrs.message : undefined,
+                }
             });
         } else {
             this.setEditable(attrs, (new Date()).toISOString());

+ 1 - 1
src/headless/plugins/chat/utils.js

@@ -28,7 +28,7 @@ async function handleErrorMessage (stanza) {
         return;
     }
     const chatbox = await api.chatboxes.get(from_jid);
-    if (chatbox.get('type') === _converse.PRIVATE_CHAT_TYPE) {
+    if (chatbox?.get('type') === _converse.PRIVATE_CHAT_TYPE) {
         chatbox?.handleErrorMessageStanza(stanza);
     }
 }

+ 3 - 5
src/headless/shared/chat/utils.js

@@ -60,10 +60,8 @@ export function getMediaURLs (arr, text, offset=0) {
 
 
 /**
- * Determines whether the passed in message attributes represent a
- * message which corrects a previously received message, or an
- * older message which has already been corrected.
- * In both cases, update the corrected message accordingly.
+ * Determines whether the given attributes of an incoming message
+ * represent a XEP-0308 correction and, if so, handles it appropriately.
  * @private
  * @method _converse.ChatBox#handleCorrection
  * @param { _converse.ChatBox | _converse.ChatRoom }
@@ -84,7 +82,7 @@ export async function handleCorrection (model, attrs) {
 
     const message = model.messages.models.find(query);
     if (!message) {
-        attrs['older_versions'] = [];
+        attrs['older_versions'] = {};
         return await model.createMessage(attrs); // eslint-disable-line no-return-await
     }
 

+ 97 - 0
src/plugins/chatview/tests/styling.js

@@ -418,3 +418,100 @@ describe("An incoming chat Message", function () {
         expect(true).toBe(true);
     }));
 });
+
+
+describe("An XEP-0393 styled message ", function () {
+
+    it("can be replaced with a correction and will still render properly",
+        mock.initConverse(['chatBoxesFetched'], {},
+            async function (_converse) {
+
+        await mock.waitForRoster(_converse, 'current', 1);
+        const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
+        await mock.openChatBoxFor(_converse, contact_jid);
+        const view = _converse.chatboxviews.get(contact_jid);
+
+        const msg_text = `https://conversejs.org\nhttps://opkode.com`;
+        const msg_id = u.getUniqueId();
+        _converse.handleMessageStanza($msg({
+                'from': contact_jid,
+                'to': _converse.connection.jid,
+                'type': 'chat',
+                'id': msg_id,
+            }).c('body').t(msg_text).tree());
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
+        expect(view.querySelectorAll('.chat-msg').length).toBe(1);
+        expect(view.querySelector('.chat-msg__text').textContent)
+            .toBe('https://conversejs.org\nhttps://opkode.com');
+
+        await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length === 1);
+        const msg_el = view.querySelector('converse-chat-message-body');
+        await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
+            '<a target="_blank" rel="noopener" href="https://conversejs.org/">https://conversejs.org</a>\n'+
+            '<a target="_blank" rel="noopener" href="https://opkode.com/">https://opkode.com</a>'
+        );
+
+        _converse.handleMessageStanza($msg({
+                'from': contact_jid,
+                'to': _converse.connection.jid,
+                'type': 'chat',
+                'id': u.getUniqueId(),
+            }).c('body').t(`A\nhttps://conversejs.org\n\nhttps://opkode.com`).up()
+            .c('replace', {'id': msg_id, 'xmlns': 'urn:xmpp:message-correct:0'}).tree());
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
+
+        expect(view.querySelectorAll('.chat-msg__text').length).toBe(1);
+        await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
+            'A\n<a target="_blank" rel="noopener" href="https://conversejs.org/">https://conversejs.org</a>\n\n'+
+            '<a target="_blank" rel="noopener" href="https://opkode.com/">https://opkode.com</a>'
+        );
+    }));
+
+    it("can be sent as a correction by using the up arrow",
+            mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) {
+
+        await mock.waitForRoster(_converse, 'current', 1);
+        await mock.openControlBox(_converse);
+        const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
+        await mock.openChatBoxFor(_converse, contact_jid)
+        const view = _converse.chatboxviews.get(contact_jid);
+        const textarea = view.querySelector('textarea.chat-textarea');
+        const message_form = view.querySelector('converse-message-form');
+
+        textarea.value = `https://conversejs.org\nhttps://opkode.com`;
+        message_form.onKeyDown({
+            target: textarea,
+            preventDefault: function preventDefault () {},
+            keyCode: 13 // Enter
+        });
+        await u.waitUntil(() => view.querySelectorAll('.chat-msg__text').length);
+
+        expect(view.querySelectorAll('.chat-msg').length).toBe(1);
+        const msg_el = view.querySelector('converse-chat-message-body');
+        expect(msg_el.innerHTML.replace(/<!-.*?->/g, '')).toBe(
+            '<a target="_blank" rel="noopener" href="https://conversejs.org/">https://conversejs.org</a>\n'+
+            '<a target="_blank" rel="noopener" href="https://opkode.com/">https://opkode.com</a>'
+        );
+
+        expect(textarea.value).toBe('');
+        message_form.onKeyDown({
+            target: textarea,
+            keyCode: 38 // Up arrow
+        });
+
+        textarea.value = `A\nhttps://conversejs.org\n\nhttps://opkode.com`;
+        message_form.onKeyDown({
+            target: textarea,
+            preventDefault: function preventDefault () {},
+            keyCode: 13 // Enter
+        });
+        await new Promise(resolve => view.model.messages.once('rendered', resolve));
+
+        expect(view.querySelectorAll('.chat-msg__text').length).toBe(1);
+        await u.waitUntil(() => msg_el.innerHTML.replace(/<!-.*?->/g, '') ===
+            'A\n<a target="_blank" rel="noopener" href="https://conversejs.org/">https://conversejs.org</a>\n\n'+
+            '<a target="_blank" rel="noopener" href="https://opkode.com/">https://opkode.com</a>'
+        );
+    }));
+
+});