浏览代码

New configuration setting: notify_nicknames_without_references

Ariel Fuggini 4 年之前
父节点
当前提交
fce337e352

+ 1 - 0
CHANGES.md

@@ -50,6 +50,7 @@ Soon we'll deprecate the latter, so prepare now.
 - New config option [modtools_disable_query](https://conversejs.org/docs/html/configuration.html#modtools-disable-query)
 - New config option [muc_hats_from_vcard](https://conversejs.org/docs/html/configuration.html#muc-hats-from-vcard).
 - New config option [muc_send_probes](https://conversejs.org/docs/html/configuration.html#muc-send-probes).
+- New config option [notify_nicknames_without_references](https://conversejs.org/docs/html/configuration.html#notify-nicknames-without-references).
 - New config option [show_message_avatar](https://conversejs.org/docs/html/configuration.html#show-message-avatar).
 - New public API [converse.insertInto](https://conversejs.org/docs/html/api/converse.html#.insertInto)
 

+ 10 - 0
docs/source/configuration.rst

@@ -1366,6 +1366,16 @@ notification_icon
 This option specifies which icon is shown in HTML5 notifications, as provided
 by the ``src/converse-notification.js`` plugin.
 
+notify_nicknames_without_references
+-----------------------------------
+
+* Default: ``false``
+
+Enables notifications for nicknames in messages that don't have associated
+XEP-0372 references linking them to the JID of the person being mentioned.
+
+In Converse, these would be nicknames that weren't mentioned via the ``@`` sign.
+
 oauth_providers
 ---------------
 

+ 29 - 9
spec/notification.js

@@ -56,19 +56,38 @@ describe("Notifications", function () {
                     spyOn(_converse, 'showMessageNotification').and.callThrough();
                     spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
 
-                    const message = 'romeo: This message will show a desktop notification';
-                    const nick = mock.chatroom_names[0],
-                        msg = $msg({
-                            from: 'lounge@montague.lit/'+nick,
-                            id: u.getUniqueId(),
-                            to: 'romeo@montague.lit',
-                            type: 'groupchat'
-                        }).c('body').t(message).tree();
-                    _converse.connection._dataRecv(mock.createRequest(msg));
+                    // Test mention with setting false
+                    const nick = mock.chatroom_names[0];
+                    const makeMsg = text => $msg({
+                        from: 'lounge@montague.lit/'+nick,
+                        id: u.getUniqueId(),
+                        to: 'romeo@montague.lit',
+                        type: 'groupchat'
+                    }).c('body').t(text).tree();
+                    _converse.connection._dataRecv(mock.createRequest(makeMsg('romeo: this will NOT show a notification')));
                     await new Promise(resolve => view.model.messages.once('rendered', resolve));
+                    await u.waitUntil(() => _converse.areDesktopNotificationsEnabled.calls.count() === 0);
+                    expect(_converse.showMessageNotification).not.toHaveBeenCalled();
 
+                    // Test reference
+                    const message_with_ref = $msg({
+                        from: 'lounge@montague.lit/'+nick,
+                        id: u.getUniqueId(),
+                        to: 'romeo@montague.lit',
+                        type: 'groupchat'
+                    }).c('body').t('romeo: this will show a notification').up()
+                    .c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'0', 'end':'5', 'type':'mention', 'uri':'xmpp:romeo@montague.lit'}).tree();
+                    _converse.connection._dataRecv(mock.createRequest(message_with_ref));
+                    await new Promise(resolve => view.model.messages.once('rendered', resolve));
                     await u.waitUntil(() => _converse.areDesktopNotificationsEnabled.calls.count() === 1);
                     expect(_converse.showMessageNotification).toHaveBeenCalled();
+
+                    // Test mention with setting true
+                    _converse.api.settings.set('notify_all_room_messages', true);
+                    _converse.connection._dataRecv(mock.createRequest(makeMsg('romeo: this will show a notification')));
+                    await new Promise(resolve => view.model.messages.once('rendered', resolve));
+                    await u.waitUntil(() => _converse.areDesktopNotificationsEnabled.calls.count() === 2);
+                    expect(_converse.showMessageNotification).toHaveBeenCalled();
                     if (no_notification) {
                         delete window.Notification;
                     }
@@ -172,6 +191,7 @@ describe("Notifications", function () {
                     to: 'romeo@montague.lit',
                     type: 'groupchat'
                 }).c('body').t(text);
+                _converse.api.settings.set('notify_all_room_messages', true);
                 await view.model.handleMessageStanza(message.nodeTree);
                 await u.waitUntil(() => _converse.playSoundNotification.calls.count());
                 expect(_converse.playSoundNotification).toHaveBeenCalled();

+ 25 - 23
src/converse-notification.js

@@ -32,32 +32,34 @@ converse.plugins.add('converse-notification', {
             play_sounds: true,
             sounds_path: api.settings.get("assets_path")+'/sounds/',
             notification_icon: 'logo/conversejs-filled.svg',
-            notification_delay: 5000
+            notification_delay: 5000,
+            notify_nicknames_without_references: false
         });
 
-        _converse.shouldNotifyOfGroupMessage = function (message) {
+        _converse.shouldNotifyOfGroupMessage = function (message, data) {
             /* Is this a group message worthy of notification?
              */
-            let notify_all = api.settings.get('notify_all_room_messages');
-            const jid = message.getAttribute('from'),
-                resource = Strophe.getResourceFromJid(jid),
-                room_jid = Strophe.getBareJidFromJid(jid),
-                sender = resource && Strophe.unescapeNode(resource) || '';
-            if (sender === '' || message.querySelectorAll('delay').length > 0) {
-                return false;
-            }
+            const jid = message.getAttribute('from');
+            const room_jid = Strophe.getBareJidFromJid(jid);
+            const notify_all = api.settings.get('notify_all_room_messages');
             const room = _converse.chatboxes.get(room_jid);
-            const body = message.querySelector('body');
-            if (body === null) {
-                return false;
-            }
-            const mentioned = (new RegExp(`\\b${room.get('nick')}\\b`)).test(body.textContent);
-            notify_all = notify_all === true ||
-                (Array.isArray(notify_all) && notify_all.includes(room_jid));
-            if (sender === room.get('nick') || (!notify_all && !mentioned)) {
-                return false;
+            const resource = Strophe.getResourceFromJid(jid);
+            const sender = resource && Strophe.unescapeNode(resource) || '';
+            let is_mentioned = false;
+            const nick = room.get('nick');
+
+            if (api.settings.get('notify_nicknames_without_references')) {
+                const body = message.querySelector('body');
+                is_mentioned = (new RegExp(`\\b${nick}\\b`)).test(body.textContent);
             }
-            return true;
+
+            const is_referenced = data.attrs.references.map(r => r.value).includes(nick);
+            const is_not_mine = sender !== nick;
+            const should_notify_user = notify_all === true
+                || (Array.isArray(notify_all) && notify_all.includes(room_jid))
+                || is_referenced
+                || is_mentioned;
+            return is_not_mine && !!should_notify_user;
         };
 
         _converse.isMessageToHiddenChat = function (message) {
@@ -72,12 +74,12 @@ converse.plugins.add('converse-notification', {
             return _converse.windowState === 'hidden';
         }
 
-        _converse.shouldNotifyOfMessage = function (message) {
+        _converse.shouldNotifyOfMessage = function (message, data) {
             const forwarded = message.querySelector('forwarded');
             if (forwarded !== null) {
                 return false;
             } else if (message.getAttribute('type') === 'groupchat') {
-                return _converse.shouldNotifyOfGroupMessage(message);
+                return _converse.shouldNotifyOfGroupMessage(message, data);
             } else if (st.isHeadline(message)) {
                 // We want to show notifications for headline messages.
                 return _converse.isMessageToHiddenChat(message);
@@ -251,7 +253,7 @@ converse.plugins.add('converse-notification', {
              * to play sounds and show HTML5 notifications.
              */
             const message = data.stanza;
-            if (!_converse.shouldNotifyOfMessage(message)) {
+            if (!_converse.shouldNotifyOfMessage(message, data)) {
                 return false;
             }
             /**

+ 1 - 1
src/headless/converse-chat.js

@@ -1223,7 +1223,7 @@ converse.plugins.add('converse-chat', {
              * @property { XMLElement } stanza
              * @example _converse.api.listen.on('message', obj => { ... });
              */
-            api.trigger('message', {'stanza': stanza});
+            api.trigger('message', {stanza, attrs});
         }
 
 

+ 1 - 1
src/headless/converse-headlines.js

@@ -98,7 +98,7 @@ converse.plugins.add('converse-headlines', {
                 });
                 const attrs = await st.parseMessage(stanza, _converse);
                 await chatbox.createMessage(attrs);
-                api.trigger('message', {'chatbox': chatbox, 'stanza': stanza});
+                api.trigger('message', {chatbox, stanza, attrs});
             }
         }
 

+ 1 - 1
src/headless/converse-muc.js

@@ -669,10 +669,10 @@ converse.plugins.add('converse-muc', {
                     // they shouldn't have a `type` attribute.
                     return log.warn(`Received a MAM message with type "groupchat"`);
                 }
-                api.trigger('message', {'stanza': stanza});
                 this.createInfoMessages(stanza);
                 this.fetchFeaturesIfConfigurationChanged(stanza);
                 const attrs = await st.parseMUCMessage(stanza, this, _converse);
+                api.trigger('message', {stanza, attrs});
                 return attrs && this.queueMessage(attrs);
             },