Переглянути джерело

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

JC Brand 5 роки тому
батько
коміт
555c0966cc

+ 5 - 0
sass/_messages.scss

@@ -220,6 +220,11 @@
                 padding-bottom: 0.25em;
             }
 
+            .chat-msg__error {
+                color: var(--error-color);
+                font-weight: bold;
+            }
+
             .chat-msg__media {
                 margin-top: 0.25rem;
                 word-break: break-all;

+ 45 - 0
spec/muc_messages.js

@@ -5,6 +5,51 @@ const u = converse.env.utils;
 
 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 () {
 
         it("is not rendered as a followup message",

+ 10 - 3
src/headless/converse-muc.js

@@ -619,7 +619,13 @@ converse.plugins.add('converse-muc', {
 
             async handleErrormessageStanza (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', {
                 var references;
                 [text, references] = this.parseTextForReferences(text);
                 const origin_id = u.getUniqueId();
-
+                const body = text ? u.httpToGeoUri(u.shortnameToUnicode(text), _converse) : undefined;
                 return {
+                    body,
                     is_spoiler,
                     origin_id,
                     references,
@@ -991,7 +998,7 @@ converse.plugins.add('converse-muc', {
                     'from': `${this.get('jid')}/${this.get('nick')}`,
                     'fullname': this.get('nick'),
                     'is_only_emojis': text ? u.isOnlyEmojis(text) : false,
-                    'message': text ? u.httpToGeoUri(u.shortnameToUnicode(text), _converse) : undefined,
+                    'message': body,
                     'nick': this.get('nick'),
                     'sender': 'me',
                     'spoiler_hint': is_spoiler ? spoiler_hint : undefined,

+ 3 - 1
src/headless/utils/stanza.js

@@ -281,13 +281,15 @@ function rejectMessage (stanza, text) {
 function getMUCErrorMessage (stanza) {
     if (stanza.getAttribute('type') === 'error') {
         const forbidden = sizzle(`error forbidden[xmlns="${Strophe.NS.STANZAS}"]`, stanza).pop();
+        const text = sizzle(`error text[xmlns="${Strophe.NS.STANZAS}"]`, stanza).pop();
         if (forbidden) {
             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) : '';
             return server_msg ? `${msg} ${server_msg}` : msg;
         } 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.");
+        } else {
+            return text?.textContent;
         }
     }
 }

+ 1 - 0
src/templates/message.html

@@ -33,6 +33,7 @@
                         {[ if (o.is_only_emojis) { ]} chat-msg__text--larger{[ } ]}
                         {[ if (o.is_spoiler) { ]} spoiler collapsed{[ } ]}"><!-- message gets added here via renderMessage --></div>
                     <div class="chat-msg__media"></div>
+                    <div class="chat-msg__error">{{{o.error}}}</div>
                 {[ } ]}
             </div>
             {[ if (o.received && !o.is_me_message && !o.is_groupchat_message) { ]} <span class="fa fa-check chat-msg__receipt"></span> {[ } ]}