diff --git a/src/headless/plugins/chat/parsers.js b/src/headless/plugins/chat/parsers.js index 06a1e32bbc..b191cb90f4 100644 --- a/src/headless/plugins/chat/parsers.js +++ b/src/headless/plugins/chat/parsers.js @@ -121,7 +121,6 @@ export async function parseMessage (stanza) { 'is_marker': !!marker, 'is_unstyled': !!sizzle(`unstyled[xmlns="${Strophe.NS.STYLING}"]`, stanza).length, 'marker_id': marker && marker.getAttribute('id'), - 'msgid': stanza.getAttribute('id') || original_stanza.getAttribute('id'), 'nick': contact?.attributes?.nickname, 'receipt_id': getReceiptId(stanza), 'received': new Date().toISOString(), diff --git a/src/headless/plugins/disco/api.js b/src/headless/plugins/disco/api.js index 0dd870cb7c..01af9b7282 100644 --- a/src/headless/plugins/disco/api.js +++ b/src/headless/plugins/disco/api.js @@ -359,7 +359,6 @@ export default { return api.disco.features.has(feature, jid); } catch (e) { log.error(e); - debugger; return false; } }, diff --git a/src/headless/plugins/muc/parsers.js b/src/headless/plugins/muc/parsers.js index b6e0242441..3c243f587d 100644 --- a/src/headless/plugins/muc/parsers.js +++ b/src/headless/plugins/muc/parsers.js @@ -267,7 +267,6 @@ export async function parseMUCMessage(original_stanza, chatbox) { 'is_marker': !!marker, 'is_unstyled': !!sizzle(`message > unstyled[xmlns="${Strophe.NS.STYLING}"]`, stanza).length, 'marker_id': marker && marker.getAttribute('id'), - 'msgid': stanza.getAttribute('id') || original_stanza.getAttribute('id'), 'nick': Strophe.unescapeNode(Strophe.getResourceFromJid(from)), 'occupant_id': getOccupantID(stanza, chatbox), 'receipt_id': getReceiptId(stanza), diff --git a/src/headless/shared/model-with-messages.js b/src/headless/shared/model-with-messages.js index c3f7c98fe0..d9652b5459 100644 --- a/src/headless/shared/model-with-messages.js +++ b/src/headless/shared/model-with-messages.js @@ -846,13 +846,17 @@ export default function ModelWithMessages(BaseModel) { if (attrs.retracted) { if (attrs.is_tombstone) return false; - const message = this.messages.findWhere({ origin_id: attrs.retracted_id, from: attrs.from }); - if (!message) { - attrs['dangling_retraction'] = true; - await this.createMessage(attrs); - return true; + for (const m of this.messages.models) { + if (m.get('from') !== attrs.from) continue; + if (m.get('origin_id') === attrs.retracted_id || + m.get('msgid') === attrs.retracted_id) { + m.save(pick(attrs, RETRACTION_ATTRIBUTES)); + return true; + } } - message.save(pick(attrs, RETRACTION_ATTRIBUTES)); + + attrs['dangling_retraction'] = true; + await this.createMessage(attrs); return true; } else { // Check if we have dangling retraction diff --git a/src/headless/shared/parsers.js b/src/headless/shared/parsers.js index 33255f6cd6..136d74c1ff 100644 --- a/src/headless/shared/parsers.js +++ b/src/headless/shared/parsers.js @@ -96,14 +96,21 @@ export async function parseErrorStanza(stanza) { * @returns {Object} */ export function getStanzaIDs (stanza, original_stanza) { - const attrs = {}; - // Store generic stanza ids + // Generic stanza ids const sids = sizzle(`stanza-id[xmlns="${Strophe.NS.SID}"]`, stanza); const sid_attrs = sids.reduce((acc, s) => { acc[`stanza_id ${s.getAttribute('by')}`] = s.getAttribute('id'); return acc; }, {}); - Object.assign(attrs, sid_attrs); + + // Origin id + const origin_id = sizzle(`origin-id[xmlns="${Strophe.NS.SID}"]`, stanza).pop()?.getAttribute('id'); + + const attrs = { + origin_id, + msgid: stanza.getAttribute('id') || original_stanza.getAttribute('id'), + ...sid_attrs, + }; // Store the archive id const result = sizzle(`message > result[xmlns="${Strophe.NS.MAM}"]`, original_stanza).pop(); @@ -113,11 +120,6 @@ export function getStanzaIDs (stanza, original_stanza) { attrs[`stanza_id ${by_jid}`] = result.getAttribute('id'); } - // Store the origin id - const origin_id = sizzle(`origin-id[xmlns="${Strophe.NS.SID}"]`, stanza).pop(); - if (origin_id) { - attrs['origin_id'] = origin_id.getAttribute('id'); - } return attrs; } diff --git a/src/plugins/chatview/tests/retractions.js b/src/plugins/chatview/tests/retractions.js index fea9af914d..370a6b70ae 100644 --- a/src/plugins/chatview/tests/retractions.js +++ b/src/plugins/chatview/tests/retractions.js @@ -224,7 +224,6 @@ describe('A message retraction', function () { - 😊 @@ -238,7 +237,6 @@ describe('A message retraction', function () { - @@ -253,9 +251,9 @@ describe('A message retraction', function () { - - - + + + /me retracted a previous message, but it's unsupported by your client. @@ -285,8 +283,8 @@ describe('A message retraction', function () { expect(await view.model.handleRetraction.calls.all()[2].returnValue).toBe(true); await u.waitUntil(() => view.querySelectorAll('.chat-msg').length === 2); expect(view.querySelectorAll('.chat-msg--retracted').length).toBe(1); - const el = view.querySelector('.chat-msg--retracted .chat-msg__message div'); - expect(el.textContent.trim()).toBe('Mercutio has removed this message'); + const el = view.querySelector('.chat-msg--retracted .chat-msg__message .retraction'); + expect(el.firstElementChild.textContent.trim()).toBe('Mercutio has removed a message'); expect(u.hasClass('chat-msg--followup', el.parentElement)).toBe(false); }) ); diff --git a/src/shared/chat/templates/message.js b/src/shared/chat/templates/message.js index ae7a38350a..c8a4179919 100644 --- a/src/shared/chat/templates/message.js +++ b/src/shared/chat/templates/message.js @@ -32,7 +32,6 @@ export default (el) => { const username = el.model.getDisplayName(); const is_action = is_me_message || is_retracted; - debugger; const should_show_header = !is_action && !is_followup; const should_show_avatar = el.shouldShowAvatar() && should_show_header;