diff --git a/spec/messages.js b/spec/messages.js index 4db9ffdf5..ff79ffb26 100644 --- a/spec/messages.js +++ b/spec/messages.js @@ -2273,6 +2273,76 @@ done(); })); + it("keeps track of the sender's role and affiliation", + mock.initConverse( + null, ['rosterGroupsFetched'], {}, + async function (done, _converse) { + + await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy'); + const view = _converse.api.chatviews.get('lounge@localhost'); + let msg = $msg({ + from: 'lounge@localhost/dummy', + id: (new Date()).getTime(), + to: 'dummy@localhost', + type: 'groupchat' + }).c('body').t('I wrote this message!').tree(); + await view.model.onMessage(msg); + await new Promise((resolve, reject) => view.once('messageInserted', resolve)); + expect(view.model.messages.last().get('affiliation')).toBe('owner'); + expect(view.model.messages.last().get('role')).toBe('moderator'); + expect(view.el.querySelectorAll('.chat-msg').length).toBe(1); + expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author chat-msg__me moderator'); + + let presence = $pres({ + to:'dummy@localhost/resource', + from:'lounge@localhost/dummy', + id: u.getUniqueId() + }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'}) + .c('item').attrs({ + affiliation: 'member', + jid: 'dummy@localhost/resource', + role: 'participant' + }).up() + .c('status').attrs({code:'110'}).up() + .c('status').attrs({code:'210'}).nodeTree; + _converse.connection._dataRecv(test_utils.createRequest(presence)); + + msg = $msg({ + from: 'lounge@localhost/dummy', + id: (new Date()).getTime(), + to: 'dummy@localhost', + type: 'groupchat' + }).c('body').t('Another message!').tree(); + await view.model.onMessage(msg); + await new Promise((resolve, reject) => view.once('messageInserted', resolve)); + expect(view.model.messages.last().get('affiliation')).toBe('member'); + expect(view.model.messages.last().get('role')).toBe('participant'); + expect(view.el.querySelectorAll('.chat-msg').length).toBe(2); + expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author chat-msg__me participant'); + + presence = $pres({ + to:'dummy@localhost/resource', + from:'lounge@localhost/dummy', + id: u.getUniqueId() + }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'}) + .c('item').attrs({ + affiliation: 'owner', + jid: 'dummy@localhost/resource', + role: 'moderator' + }).up() + .c('status').attrs({code:'110'}).up() + .c('status').attrs({code:'210'}).nodeTree; + _converse.connection._dataRecv(test_utils.createRequest(presence)); + view.model.sendMessage('hello world'); + await new Promise((resolve, reject) => view.once('messageInserted', resolve)); + expect(view.model.messages.last().get('affiliation')).toBe('owner'); + expect(view.model.messages.last().get('role')).toBe('moderator'); + expect(view.el.querySelectorAll('.chat-msg').length).toBe(3); + expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author chat-msg__me moderator'); + done(); + })); + + it("keeps track whether you are the sender or not", mock.initConverse( null, ['rosterGroupsFetched'], {}, @@ -2287,6 +2357,7 @@ type: 'groupchat' }).c('body').t('I wrote this message!').tree(); await view.model.onMessage(msg); + await new Promise((resolve, reject) => view.once('messageInserted', resolve)); expect(view.model.messages.last().get('sender')).toBe('me'); done(); })); diff --git a/src/headless/converse-muc.js b/src/headless/converse-muc.js index 2db7bf501..e96493173 100644 --- a/src/headless/converse-muc.js +++ b/src/headless/converse-muc.js @@ -431,7 +431,7 @@ converse.plugins.add('converse-muc', { [text, references] = this.parseTextForReferences(text); const origin_id = _converse.connection.getUniqueId(); - return { + return this.addOccupantData({ 'msgid': origin_id, 'origin_id': origin_id, 'from': `${this.get('jid')}/${this.get('nick')}`, @@ -444,7 +444,7 @@ converse.plugins.add('converse-muc', { 'sender': 'me', 'spoiler_hint': is_spoiler ? spoiler_hint : undefined, 'type': 'groupchat' - }; + }); }, getRoomJIDAndNick (nick) { @@ -1068,6 +1068,17 @@ converse.plugins.add('converse-muc', { } }, + addOccupantData (attrs) { + if (attrs.nick) { + const occupant = this.occupants.findOccupant({'nick': attrs.nick}); + if (occupant) { + attrs['affiliation'] = occupant.get('affiliation'); + attrs['role'] = occupant.get('role'); + } + } + return attrs; + }, + /** * Handler for all MUC messages sent to this groupchat. * @private @@ -1092,14 +1103,14 @@ converse.plugins.add('converse-muc', { this.isChatMarker(stanza)) { return _converse.api.trigger('message', {'stanza': original_stanza}); } - const attrs = await this.getMessageAttributesFromStanza(stanza, original_stanza); + const attrs = await this.getMessageAttributesFromStanza(stanza, original_stanza); if (attrs.nick && !this.subjectChangeHandled(attrs) && !this.ignorableCSN(attrs) && (attrs['chat_state'] || !u.isEmptyMessage(attrs))) { - const msg = this.messages.create(attrs); + const msg = this.messages.create(this.addOccupantData(attrs)); this.incrementUnreadMsgCounter(msg); if (forwarded && msg && msg.get('sender') === 'me') { msg.save({'received': (new Date()).toISOString()}); diff --git a/src/templates/message.html b/src/templates/message.html index 11bb5c8dd..73e588c4f 100644 --- a/src/templates/message.html +++ b/src/templates/message.html @@ -6,7 +6,7 @@
{[ if (o.is_me_message) { ]}{[ } ]} - {[ if (o.is_me_message) { ]}**{[ }; ]}{{{o.username}}} + {[ if (o.is_me_message) { ]}**{[ }; ]}{{{o.username}}} {[ if (!o.is_me_message) { ]} {[o.roles.forEach(function (role) { ]} {{{role}}} {[ }); ]}