Fix showing of HTML5 notifications for MEP messages

This commit is contained in:
JC Brand 2021-09-08 17:30:30 +02:00
parent 8aa16ea0be
commit b78c19f6f2
4 changed files with 45 additions and 40 deletions

View File

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

View File

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

View File

@ -143,32 +143,12 @@ u.isEmptyMessage = function (attrs) {
}; };
//TODO: Remove //TODO: Remove
u.isOnlyChatStateNotification = function (msg) { u.isOnlyChatStateNotification = function (attrs) {
if (msg instanceof Element) { return attrs['chat_state'] && u.isEmptyMessage(attrs);
// 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.isOnlyMessageDeliveryReceipt = function (msg) { u.isOnlyMessageDeliveryReceipt = function (attrs) {
if (msg instanceof Element) { return attrs['received'] && u.isEmptyMessage(attrs);
// 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.isChatRoom = function (model) { u.isChatRoom = function (model) {

View File

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