Commit 555c0966 authored by JC Brand's avatar JC Brand

muc: save error response to a sent message onto the original model

parent e6723063
...@@ -220,6 +220,11 @@ ...@@ -220,6 +220,11 @@
padding-bottom: 0.25em; padding-bottom: 0.25em;
} }
.chat-msg__error {
color: var(--error-color);
font-weight: bold;
}
.chat-msg__media { .chat-msg__media {
margin-top: 0.25rem; margin-top: 0.25rem;
word-break: break-all; word-break: break-all;
......
...@@ -5,6 +5,51 @@ const u = converse.env.utils; ...@@ -5,6 +5,51 @@ const u = converse.env.utils;
describe("A Groupchat Message", function () { describe("A Groupchat Message", function () {
describe("which is succeeded by an error message", function () {
it("will have the error displayed below it",
mock.initConverse(
['rosterGroupsFetched'], {},
async function (done, _converse) {
const muc_jid = 'lounge@montague.lit';
await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const view = _converse.api.chatviews.get(muc_jid);
const textarea = view.el.querySelector('textarea.chat-textarea');
textarea.value = 'hello world'
const enter_event = {
'target': textarea,
'preventDefault': function preventDefault () {},
'stopPropagation': function stopPropagation () {},
'keyCode': 13 // Enter
}
view.onKeyDown(enter_event);
await new Promise(resolve => view.once('messageInserted', resolve));
const msg = view.model.messages.at(0);
const err_msg_text = "Message rejected because you're sending messages too quickly";
const error = u.toStanza(`
<message xmlns="jabber:client" id="${msg.get('msgid')}" from="${muc_jid}" to="${_converse.jid}" type="error">
<error type="wait">
<policy-violation xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">${err_msg_text}</text>
</error>
<body>hello world</body>
</message>
`);
_converse.connection._dataRecv(mock.createRequest(error));
expect(await u.waitUntil(() => view.el.querySelector('.chat-msg__error')?.textContent?.trim())).toBe(err_msg_text);
expect(view.model.messages.length).toBe(1);
const message = view.model.messages.at(0);
expect(message.get('received')).toBeUndefined();
expect(message.get('body')).toBe('hello world');
expect(message.get('error')).toBe(err_msg_text);
done();
}));
});
describe("an info message", function () { describe("an info message", function () {
it("is not rendered as a followup message", it("is not rendered as a followup message",
......
...@@ -619,7 +619,13 @@ converse.plugins.add('converse-muc', { ...@@ -619,7 +619,13 @@ converse.plugins.add('converse-muc', {
async handleErrormessageStanza (stanza) { async handleErrormessageStanza (stanza) {
if (await this.shouldShowErrorMessage(stanza)) { if (await this.shouldShowErrorMessage(stanza)) {
this.createMessage(await st.parseMUCMessage(stanza, this, _converse)); const attrs = await st.parseMUCMessage(stanza, this, _converse);
const message = attrs.msgid && this.messages.findWhere({'msgid': attrs.msgid});
if (message) {
message.save({'error': attrs.error});
} else {
this.createMessage(attrs);
}
} }
}, },
...@@ -981,8 +987,9 @@ converse.plugins.add('converse-muc', { ...@@ -981,8 +987,9 @@ converse.plugins.add('converse-muc', {
var references; var references;
[text, references] = this.parseTextForReferences(text); [text, references] = this.parseTextForReferences(text);
const origin_id = u.getUniqueId(); const origin_id = u.getUniqueId();
const body = text ? u.httpToGeoUri(u.shortnameToUnicode(text), _converse) : undefined;
return { return {
body,
is_spoiler, is_spoiler,
origin_id, origin_id,
references, references,
...@@ -991,7 +998,7 @@ converse.plugins.add('converse-muc', { ...@@ -991,7 +998,7 @@ converse.plugins.add('converse-muc', {
'from': `${this.get('jid')}/${this.get('nick')}`, 'from': `${this.get('jid')}/${this.get('nick')}`,
'fullname': this.get('nick'), 'fullname': this.get('nick'),
'is_only_emojis': text ? u.isOnlyEmojis(text) : false, 'is_only_emojis': text ? u.isOnlyEmojis(text) : false,
'message': text ? u.httpToGeoUri(u.shortnameToUnicode(text), _converse) : undefined, 'message': body,
'nick': this.get('nick'), 'nick': this.get('nick'),
'sender': 'me', 'sender': 'me',
'spoiler_hint': is_spoiler ? spoiler_hint : undefined, 'spoiler_hint': is_spoiler ? spoiler_hint : undefined,
......
...@@ -281,13 +281,15 @@ function rejectMessage (stanza, text) { ...@@ -281,13 +281,15 @@ function rejectMessage (stanza, text) {
function getMUCErrorMessage (stanza) { function getMUCErrorMessage (stanza) {
if (stanza.getAttribute('type') === 'error') { if (stanza.getAttribute('type') === 'error') {
const forbidden = sizzle(`error forbidden[xmlns="${Strophe.NS.STANZAS}"]`, stanza).pop(); const forbidden = sizzle(`error forbidden[xmlns="${Strophe.NS.STANZAS}"]`, stanza).pop();
const text = sizzle(`error text[xmlns="${Strophe.NS.STANZAS}"]`, stanza).pop();
if (forbidden) { if (forbidden) {
const msg = __("Your message was not delivered because you weren't allowed to send it."); const msg = __("Your message was not delivered because you weren't allowed to send it.");
const text = sizzle(`error text[xmlns="${Strophe.NS.STANZAS}"]`, stanza).pop();
const server_msg = text ? __('The message from the server is: "%1$s"', text.textContent) : ''; const server_msg = text ? __('The message from the server is: "%1$s"', text.textContent) : '';
return server_msg ? `${msg} ${server_msg}` : msg; return server_msg ? `${msg} ${server_msg}` : msg;
} else if (sizzle(`not-acceptable[xmlns="${Strophe.NS.STANZAS}"]`, stanza).length) { } else if (sizzle(`not-acceptable[xmlns="${Strophe.NS.STANZAS}"]`, stanza).length) {
return __("Your message was not delivered because you're not present in the groupchat."); return __("Your message was not delivered because you're not present in the groupchat.");
} else {
return text?.textContent;
} }
} }
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
{[ if (o.is_only_emojis) { ]} chat-msg__text--larger{[ } ]} {[ if (o.is_only_emojis) { ]} chat-msg__text--larger{[ } ]}
{[ if (o.is_spoiler) { ]} spoiler collapsed{[ } ]}"><!-- message gets added here via renderMessage --></div> {[ if (o.is_spoiler) { ]} spoiler collapsed{[ } ]}"><!-- message gets added here via renderMessage --></div>
<div class="chat-msg__media"></div> <div class="chat-msg__media"></div>
<div class="chat-msg__error">{{{o.error}}}</div>
{[ } ]} {[ } ]}
</div> </div>
{[ if (o.received && !o.is_me_message && !o.is_groupchat_message) { ]} <span class="fa fa-check chat-msg__receipt"></span> {[ } ]} {[ if (o.received && !o.is_me_message && !o.is_groupchat_message) { ]} <span class="fa fa-check chat-msg__receipt"></span> {[ } ]}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment