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;