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 [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)

View File

@ -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
---------------

View File

@ -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();

View File

@ -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 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);
}
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;
}
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;
}
/**

View File

@ -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});
}

View File

@ -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});
}
}

View File

@ -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);
},