ソースを参照

Fix showing of HTML5 notifications for MEP messages

JC Brand 3 年 前
コミット
b78c19f6f2

+ 4 - 2
src/headless/plugins/muc/muc.js

@@ -2112,8 +2112,10 @@ const ChatRoomMixin = {
             return false;
         }
         attrs.activities?.forEach(activity_attrs => {
-            const mdata = Object.assign({ 'msgid': attrs.msgid }, activity_attrs);
-            this.createMessage(mdata)
+            const data = Object.assign({ 'msgid': attrs.msgid, 'from_muc': attrs.from }, activity_attrs);
+            this.createMessage(data)
+            // Trigger so that notifications are shown
+            api.trigger('message', { 'attrs': data, 'chatbox': this });
         });
         return !!attrs.activities.length
     },

+ 1 - 0
src/headless/plugins/muc/parsers.js

@@ -182,6 +182,7 @@ export async function parseMUCMessage (stanza, chatbox, _converse) {
         {
             from,
             nick,
+            'is_forwarded': !!stanza?.querySelector('forwarded'),
             'activities': getMEPActivities(stanza),
             'body': stanza.querySelector('body')?.textContent?.trim(),
             'chat_state': getChatState(stanza),

+ 4 - 24
src/headless/utils/core.js

@@ -143,32 +143,12 @@ u.isEmptyMessage = function (attrs) {
 };
 
 //TODO: Remove
-u.isOnlyChatStateNotification = function (msg) {
-    if (msg instanceof Element) {
-        // See XEP-0085 Chat State Notification
-        return (msg.querySelector('body') === null) && (
-                    (msg.querySelector('active') !== null) ||
-                    (msg.querySelector('composing') !== null) ||
-                    (msg.querySelector('inactive') !== null) ||
-                    (msg.querySelector('paused') !== null) ||
-                    (msg.querySelector('gone') !== null));
-    }
-    if (msg instanceof Model) {
-        msg = msg.attributes;
-    }
-    return msg['chat_state'] && u.isEmptyMessage(msg);
+u.isOnlyChatStateNotification = function (attrs) {
+    return attrs['chat_state'] && u.isEmptyMessage(attrs);
 };
 
-u.isOnlyMessageDeliveryReceipt = function (msg) {
-    if (msg instanceof Element) {
-        // See XEP-0184 Message Delivery Receipts
-        return (msg.querySelector('body') === null) &&
-                    (msg.querySelector('received') !== null);
-    }
-    if (msg instanceof Model) {
-        msg = msg.attributes;
-    }
-    return msg['received'] && u.isEmptyMessage(msg);
+u.isOnlyMessageDeliveryReceipt = function (attrs) {
+    return attrs['received'] && u.isEmptyMessage(attrs);
 };
 
 u.isChatRoom = function (model) {

+ 36 - 14
src/plugins/notifications/utils.js

@@ -40,6 +40,13 @@ export function updateUnreadFavicon () {
     }
 }
 
+
+function isReferenced (references, muc_jid, nick) {
+    const check = r => [_converse.bare_jid, `${muc_jid}/${nick}`].includes(r.uri.replace(/^xmpp:/, ''));
+    return references.reduce((acc, r) => acc || check(r), false);
+}
+
+
 /**
  * Is this a group message for which we should notify the user?
  * @private
@@ -63,16 +70,11 @@ export async function shouldNotifyOfGroupMessage (attrs) {
         is_mentioned = new RegExp(`\\b${nick}\\b`).test(attrs.body);
     }
 
-    const references_me = r => {
-        const jid = r.uri.replace(/^xmpp:/, '');
-        return jid == _converse.bare_jid || jid === `${muc_jid}/${nick}`;
-    };
-    const is_referenced = attrs.references.reduce((acc, r) => acc || references_me(r), false);
     const is_not_mine = sender !== nick;
     const should_notify_user =
         notify_all === true ||
         (Array.isArray(notify_all) && notify_all.includes(muc_jid)) ||
-        is_referenced ||
+        isReferenced(attrs.references, muc_jid, nick) ||
         is_mentioned;
 
     if (is_not_mine && !!should_notify_user) {
@@ -91,27 +93,47 @@ export async function shouldNotifyOfGroupMessage (attrs) {
     return false;
 }
 
+async function shouldNotifyOfInfoMessage (attrs) {
+    if (!attrs.from_muc) {
+        return false;
+    }
+    const room = await api.rooms.get(attrs.from_muc);
+    if (!room) {
+        return false;
+    }
+    const nick = room.get('nick');
+    const muc_jid = attrs.from_muc;
+    const notify_all = api.settings.get('notify_all_room_messages');
+    return (
+        notify_all === true ||
+        (Array.isArray(notify_all) && notify_all.includes(muc_jid)) ||
+        isReferenced(attrs.references, muc_jid, nick)
+    );
+}
+
 /**
  * @private
+ * @async
  * @method shouldNotifyOfMessage
  * @param { MessageData|MUCMessageData } data
  */
-async function shouldNotifyOfMessage (data) {
-    const { attrs, stanza } = data;
-    if (!attrs || stanza.querySelector('forwarded') !== null) {
+function shouldNotifyOfMessage (data) {
+    const { attrs } = data;
+    if (!attrs || attrs.is_forwarded) {
         return false;
     }
     if (attrs['type'] === 'groupchat') {
-        const result = await shouldNotifyOfGroupMessage(attrs);
-        return result;
+        return shouldNotifyOfGroupMessage(attrs);
+    } else if (attrs['type'] === 'info') {
+        return shouldNotifyOfInfoMessage(attrs);
     } else if (attrs.is_headline) {
         // We want to show notifications for headline messages.
         return isMessageToHiddenChat(attrs);
     }
     const is_me = Strophe.getBareJidFromJid(attrs.from) === _converse.bare_jid;
     return (
-        !u.isOnlyChatStateNotification(stanza) &&
-        !u.isOnlyMessageDeliveryReceipt(stanza) &&
+        !u.isOnlyChatStateNotification(attrs) &&
+        !u.isOnlyMessageDeliveryReceipt(attrs) &&
         !is_me &&
         (api.settings.get('show_desktop_notifications') === 'all' || isMessageToHiddenChat(attrs))
     );
@@ -266,7 +288,7 @@ export async function handleMessageNotification (data) {
      * message has will be made.
      * @event _converse#messageNotification
      * @type { MessageData|MUCMessageData}
-     * @example _converse.api.listen.on('messageNotification', stanza => { ... });
+     * @example _converse.api.listen.on('messageNotification', data => { ... });
      */
     api.trigger('messageNotification', data);
     playSoundNotification();