New configuration setting: notify_nicknames_without_references

This commit is contained in:
Ariel Fuggini 2020-08-25 17:02:53 -05:00 committed by JC Brand
parent e705b038f8
commit fce337e352
7 changed files with 68 additions and 35 deletions

View File

@ -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 [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_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 [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 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) - New public API [converse.insertInto](https://conversejs.org/docs/html/api/converse.html#.insertInto)

View File

@ -1366,6 +1366,16 @@ notification_icon
This option specifies which icon is shown in HTML5 notifications, as provided This option specifies which icon is shown in HTML5 notifications, as provided
by the ``src/converse-notification.js`` plugin. 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 oauth_providers
--------------- ---------------

View File

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

View File

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

View File

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

View File

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

View File

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