Associate ChatRoomOccupant
to ChatRoomMessage
and use promises to indicate when an occupant or contact has been set
This commit is contained in:
parent
e7178fed31
commit
67bcc00f10
|
@ -233,7 +233,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"prefer-numeric-literals": "error",
|
"prefer-numeric-literals": "error",
|
||||||
"prefer-promise-reject-errors": "error",
|
"prefer-promise-reject-errors": "off",
|
||||||
"prefer-reflect": "off",
|
"prefer-reflect": "off",
|
||||||
"prefer-rest-params": "off",
|
"prefer-rest-params": "off",
|
||||||
"prefer-spread": "off",
|
"prefer-spread": "off",
|
||||||
|
|
|
@ -2374,8 +2374,8 @@
|
||||||
}).c('body').t('I wrote this message!').tree();
|
}).c('body').t('I wrote this message!').tree();
|
||||||
await view.model.onMessage(msg);
|
await view.model.onMessage(msg);
|
||||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||||
expect(view.model.messages.last().get('affiliation')).toBe('owner');
|
expect(view.model.messages.last().occupant.get('affiliation')).toBe('owner');
|
||||||
expect(view.model.messages.last().get('role')).toBe('moderator');
|
expect(view.model.messages.last().occupant.get('role')).toBe('moderator');
|
||||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||||
expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author moderator');
|
expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author moderator');
|
||||||
|
|
||||||
|
@ -2401,8 +2401,8 @@
|
||||||
}).c('body').t('Another message!').tree();
|
}).c('body').t('Another message!').tree();
|
||||||
await view.model.onMessage(msg);
|
await view.model.onMessage(msg);
|
||||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||||
expect(view.model.messages.last().get('affiliation')).toBe('member');
|
expect(view.model.messages.last().occupant.get('affiliation')).toBe('member');
|
||||||
expect(view.model.messages.last().get('role')).toBe('participant');
|
expect(view.model.messages.last().occupant.get('role')).toBe('participant');
|
||||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
|
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
|
||||||
expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author participant');
|
expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author participant');
|
||||||
|
|
||||||
|
@ -2422,8 +2422,8 @@
|
||||||
view.model.sendMessage('hello world');
|
view.model.sendMessage('hello world');
|
||||||
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 3);
|
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 3);
|
||||||
|
|
||||||
expect(view.model.messages.last().get('affiliation')).toBe('owner');
|
expect(view.model.messages.last().occupant.get('affiliation')).toBe('owner');
|
||||||
expect(view.model.messages.last().get('role')).toBe('moderator');
|
expect(view.model.messages.last().occupant.get('role')).toBe('moderator');
|
||||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(3);
|
expect(view.el.querySelectorAll('.chat-msg').length).toBe(3);
|
||||||
expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author moderator');
|
expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author moderator');
|
||||||
done();
|
done();
|
||||||
|
@ -2969,6 +2969,7 @@
|
||||||
async function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'montague.lit', 'tom');
|
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'montague.lit', 'tom');
|
||||||
|
|
||||||
const view = _converse.api.chatviews.get('lounge@montague.lit');
|
const view = _converse.api.chatviews.get('lounge@montague.lit');
|
||||||
['z3r0', 'mr.robot', 'gibson', 'sw0rdf1sh'].forEach((nick) => {
|
['z3r0', 'mr.robot', 'gibson', 'sw0rdf1sh'].forEach((nick) => {
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(
|
_converse.connection._dataRecv(test_utils.createRequest(
|
||||||
|
@ -3023,7 +3024,7 @@
|
||||||
await test_utils.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
|
await test_utils.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
|
||||||
'hello z3r0 gibson sw0rdf1sh, how are you?', 500);
|
'hello z3r0 gibson sw0rdf1sh, how are you?', 500);
|
||||||
|
|
||||||
const correction = _converse.connection.send.calls.all()[1].args[0];
|
const correction = _converse.connection.send.calls.all()[2].args[0];
|
||||||
expect(correction.toLocaleString())
|
expect(correction.toLocaleString())
|
||||||
.toBe(`<message from="romeo@montague.lit/orchard" id="${correction.nodeTree.getAttribute("id")}" `+
|
.toBe(`<message from="romeo@montague.lit/orchard" id="${correction.nodeTree.getAttribute("id")}" `+
|
||||||
`to="lounge@montague.lit" type="groupchat" `+
|
`to="lounge@montague.lit" type="groupchat" `+
|
||||||
|
|
16
spec/muc.js
16
spec/muc.js
|
@ -1443,25 +1443,25 @@
|
||||||
await test_utils.waitUntil(() => view.el.querySelectorAll('form.chatroom-form').length)
|
await test_utils.waitUntil(() => view.el.querySelectorAll('form.chatroom-form').length)
|
||||||
expect(view.el.querySelectorAll('form.chatroom-form').length).toBe(1);
|
expect(view.el.querySelectorAll('form.chatroom-form').length).toBe(1);
|
||||||
expect(view.el.querySelectorAll('form.chatroom-form fieldset').length).toBe(2);
|
expect(view.el.querySelectorAll('form.chatroom-form fieldset').length).toBe(2);
|
||||||
var membersonly = view.el.querySelectorAll('input[name="muc#roomconfig_membersonly"]');
|
const membersonly = view.el.querySelectorAll('input[name="muc#roomconfig_membersonly"]');
|
||||||
expect(membersonly.length).toBe(1);
|
expect(membersonly.length).toBe(1);
|
||||||
expect(membersonly[0].getAttribute('type')).toBe('checkbox');
|
expect(membersonly[0].getAttribute('type')).toBe('checkbox');
|
||||||
membersonly[0].checked = true;
|
membersonly[0].checked = true;
|
||||||
|
|
||||||
var moderated = view.el.querySelectorAll('input[name="muc#roomconfig_moderatedroom"]');
|
const moderated = view.el.querySelectorAll('input[name="muc#roomconfig_moderatedroom"]');
|
||||||
expect(moderated.length).toBe(1);
|
expect(moderated.length).toBe(1);
|
||||||
expect(moderated[0].getAttribute('type')).toBe('checkbox');
|
expect(moderated[0].getAttribute('type')).toBe('checkbox');
|
||||||
moderated[0].checked = true;
|
moderated[0].checked = true;
|
||||||
|
|
||||||
var password = view.el.querySelectorAll('input[name="muc#roomconfig_roomsecret"]');
|
const password = view.el.querySelectorAll('input[name="muc#roomconfig_roomsecret"]');
|
||||||
expect(password.length).toBe(1);
|
expect(password.length).toBe(1);
|
||||||
expect(password[0].getAttribute('type')).toBe('password');
|
expect(password[0].getAttribute('type')).toBe('password');
|
||||||
|
|
||||||
var allowpm = view.el.querySelectorAll('select[name="muc#roomconfig_allowpm"]');
|
const allowpm = view.el.querySelectorAll('select[name="muc#roomconfig_allowpm"]');
|
||||||
expect(allowpm.length).toBe(1);
|
expect(allowpm.length).toBe(1);
|
||||||
allowpm[0].value = 'moderators';
|
allowpm[0].value = 'moderators';
|
||||||
|
|
||||||
var presencebroadcast = view.el.querySelectorAll('select[name="muc#roomconfig_presencebroadcast"]');
|
const presencebroadcast = view.el.querySelectorAll('select[name="muc#roomconfig_presencebroadcast"]');
|
||||||
expect(presencebroadcast.length).toBe(1);
|
expect(presencebroadcast.length).toBe(1);
|
||||||
presencebroadcast[0].value = ['moderator'];
|
presencebroadcast[0].value = ['moderator'];
|
||||||
|
|
||||||
|
@ -4167,9 +4167,9 @@
|
||||||
|
|
||||||
// Check in reverse order that we requested all three lists
|
// Check in reverse order that we requested all three lists
|
||||||
// (member, owner and admin).
|
// (member, owner and admin).
|
||||||
var admin_iq_id = IQ_ids.pop();
|
const admin_iq_id = IQ_ids.pop();
|
||||||
var owner_iq_id = IQ_ids.pop();
|
const owner_iq_id = IQ_ids.pop();
|
||||||
var member_iq_id = IQ_ids.pop();
|
const member_iq_id = IQ_ids.pop();
|
||||||
|
|
||||||
expect(sent_IQs.pop().toLocaleString()).toBe(
|
expect(sent_IQs.pop().toLocaleString()).toBe(
|
||||||
`<iq id="${admin_iq_id}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
|
`<iq id="${admin_iq_id}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
|
||||||
|
|
|
@ -78,90 +78,50 @@
|
||||||
it("allows you to automatically register your nickname when joining a room",
|
it("allows you to automatically register your nickname when joining a room",
|
||||||
mock.initConverse(
|
mock.initConverse(
|
||||||
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true},
|
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {'auto_register_muc_nickname': true},
|
||||||
function (done, _converse) {
|
async function (done, _converse) {
|
||||||
|
|
||||||
let view;
|
|
||||||
const IQ_stanzas = _converse.connection.IQ_stanzas;
|
const IQ_stanzas = _converse.connection.IQ_stanzas;
|
||||||
const room_jid = 'coven@chat.shakespeare.lit';
|
const room_jid = 'coven@chat.shakespeare.lit';
|
||||||
_converse.api.rooms.open(room_jid, {'nick': 'romeo'})
|
await test_utils.openAndEnterChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'romeo');
|
||||||
.then(() => {
|
const view = _converse.chatboxviews.get(room_jid);
|
||||||
return test_utils.waitUntil(() => _.filter(
|
|
||||||
IQ_stanzas,
|
let stanza = await test_utils.waitUntil(() => _.filter(
|
||||||
iq => iq.querySelector(
|
_converse.connection.IQ_stanzas,
|
||||||
`iq[to="${room_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
|
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="get"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||||
)).pop());
|
).pop());
|
||||||
}).then(stanza => {
|
|
||||||
const features_stanza = $iq({
|
expect(Strophe.serialize(stanza))
|
||||||
'from': room_jid,
|
.toBe(`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" `+
|
||||||
'id': stanza.getAttribute('id'),
|
`type="get" xmlns="jabber:client">`+
|
||||||
'to': 'romeo@montague.lit/desktop',
|
`<query xmlns="jabber:iq:register"/></iq>`);
|
||||||
'type': 'result'
|
const result = $iq({
|
||||||
}).c('query', { 'xmlns': 'http://jabber.org/protocol/disco#info'})
|
'from': view.model.get('jid'),
|
||||||
.c('identity', {
|
'id': stanza.getAttribute('id'),
|
||||||
'category': 'conference',
|
'to': _converse.bare_jid,
|
||||||
'name': 'A Dark Cave',
|
'type': 'result',
|
||||||
'type': 'text'
|
}).c('query', {'type': 'jabber:iq:register'})
|
||||||
}).up()
|
.c('x', {'xmlns': 'jabber:x:data', 'type': 'form'})
|
||||||
.c('feature', {'var': 'http://jabber.org/protocol/muc'}).up()
|
.c('field', {
|
||||||
.c('feature', {'var': 'jabber:iq:register'});
|
'label': 'Desired Nickname',
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
|
'type': 'text-single',
|
||||||
view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
|
'var': 'muc#register_roomnick'
|
||||||
return test_utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
|
}).c('required');
|
||||||
}).then(stanza => {
|
_converse.connection._dataRecv(test_utils.createRequest(result));
|
||||||
// The user has just entered the room (because join was called)
|
stanza = await test_utils.waitUntil(() => _.filter(
|
||||||
// and receives their own presence from the server.
|
_converse.connection.IQ_stanzas,
|
||||||
// See example 24: https://xmpp.org/extensions/xep-0045.html#enter-pres
|
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
|
||||||
const presence = $pres({
|
).pop());
|
||||||
to: _converse.connection.jid,
|
|
||||||
from: room_jid,
|
expect(Strophe.serialize(stanza)).toBe(
|
||||||
id: u.getUniqueId()
|
`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
|
||||||
}).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
|
`<query xmlns="jabber:iq:register">`+
|
||||||
.c('item').attrs({
|
`<x type="submit" xmlns="jabber:x:data">`+
|
||||||
affiliation: 'owner',
|
`<field var="FORM_TYPE"><value>http://jabber.org/protocol/muc#register</value></field>`+
|
||||||
jid: _converse.bare_jid,
|
`<field var="muc#register_roomnick"><value>romeo</value></field>`+
|
||||||
role: 'moderator'
|
`</x>`+
|
||||||
}).up()
|
`</query>`+
|
||||||
.c('status').attrs({code:'110'});
|
`</iq>`);
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
done();
|
||||||
return test_utils.waitUntil(() => _.filter(
|
|
||||||
_converse.connection.IQ_stanzas,
|
|
||||||
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="get"] query[xmlns="jabber:iq:register"]`, iq).length
|
|
||||||
).pop());
|
|
||||||
}).then(stanza => {
|
|
||||||
expect(Strophe.serialize(stanza))
|
|
||||||
.toBe(`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" `+
|
|
||||||
`type="get" xmlns="jabber:client">`+
|
|
||||||
`<query xmlns="jabber:iq:register"/></iq>`);
|
|
||||||
view = _converse.chatboxviews.get(room_jid);
|
|
||||||
const result = $iq({
|
|
||||||
'from': view.model.get('jid'),
|
|
||||||
'id': stanza.getAttribute('id'),
|
|
||||||
'to': _converse.bare_jid,
|
|
||||||
'type': 'result',
|
|
||||||
}).c('query', {'type': 'jabber:iq:register'})
|
|
||||||
.c('x', {'xmlns': 'jabber:x:data', 'type': 'form'})
|
|
||||||
.c('field', {
|
|
||||||
'label': 'Desired Nickname',
|
|
||||||
'type': 'text-single',
|
|
||||||
'var': 'muc#register_roomnick'
|
|
||||||
}).c('required');
|
|
||||||
_converse.connection._dataRecv(test_utils.createRequest(result));
|
|
||||||
return test_utils.waitUntil(() => _.filter(
|
|
||||||
_converse.connection.IQ_stanzas,
|
|
||||||
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
|
|
||||||
).pop());
|
|
||||||
}).then(stanza => {
|
|
||||||
expect(Strophe.serialize(stanza)).toBe(
|
|
||||||
`<iq from="romeo@montague.lit/orchard" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
|
|
||||||
`<query xmlns="jabber:iq:register">`+
|
|
||||||
`<x type="submit" xmlns="jabber:x:data">`+
|
|
||||||
`<field var="FORM_TYPE"><value>http://jabber.org/protocol/muc#register</value></field>`+
|
|
||||||
`<field var="muc#register_roomnick"><value>romeo</value></field>`+
|
|
||||||
`</x>`+
|
|
||||||
`</query>`+
|
|
||||||
`</iq>`);
|
|
||||||
done();
|
|
||||||
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,9 +35,8 @@
|
||||||
}).t(spoiler_hint)
|
}).t(spoiler_hint)
|
||||||
.tree();
|
.tree();
|
||||||
await _converse.chatboxes.onMessage(msg);
|
await _converse.chatboxes.onMessage(msg);
|
||||||
|
|
||||||
await test_utils.waitUntil(() => _converse.api.chats.get().length === 2);
|
|
||||||
const view = _converse.chatboxviews.get(sender_jid);
|
const view = _converse.chatboxviews.get(sender_jid);
|
||||||
|
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||||
await test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
|
await test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
|
||||||
expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Mercutio');
|
expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Mercutio');
|
||||||
const message_content = view.el.querySelector('.chat-msg__text');
|
const message_content = view.el.querySelector('.chat-msg__text');
|
||||||
|
@ -70,8 +69,8 @@
|
||||||
'xmlns': 'urn:xmpp:spoiler:0',
|
'xmlns': 'urn:xmpp:spoiler:0',
|
||||||
}).tree();
|
}).tree();
|
||||||
await _converse.chatboxes.onMessage(msg);
|
await _converse.chatboxes.onMessage(msg);
|
||||||
await test_utils.waitUntil(() => _converse.api.chats.get().length === 2);
|
|
||||||
const view = _converse.chatboxviews.get(sender_jid);
|
const view = _converse.chatboxviews.get(sender_jid);
|
||||||
|
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||||
await test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
|
await test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
|
||||||
expect(_.includes(view.el.querySelector('.chat-msg__author').textContent, 'Mercutio')).toBeTruthy();
|
expect(_.includes(view.el.querySelector('.chat-msg__author').textContent, 'Mercutio')).toBeTruthy();
|
||||||
const message_content = view.el.querySelector('.chat-msg__text');
|
const message_content = view.el.querySelector('.chat-msg__text');
|
||||||
|
|
|
@ -171,10 +171,12 @@ converse.plugins.add('converse-chatview', {
|
||||||
if (this.model.vcard) {
|
if (this.model.vcard) {
|
||||||
this.model.vcard.on('change', this.debouncedRender, this);
|
this.model.vcard.on('change', this.debouncedRender, this);
|
||||||
}
|
}
|
||||||
this.model.on('rosterContactAdded', () => {
|
if (this.model.rosterContactAdded) {
|
||||||
this.model.contact.on('change:nickname', this.debouncedRender, this);
|
this.model.rosterContactAdded.then(() => {
|
||||||
this.debouncedRender();
|
this.model.contact.on('change:nickname', this.debouncedRender, this);
|
||||||
});
|
this.debouncedRender();
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
@ -222,7 +224,7 @@ converse.plugins.add('converse-chatview', {
|
||||||
|
|
||||||
initialize () {
|
initialize () {
|
||||||
_converse.BootstrapModal.prototype.initialize.apply(this, arguments);
|
_converse.BootstrapModal.prototype.initialize.apply(this, arguments);
|
||||||
this.model.on('rosterContactAdded', this.registerContactEventHandlers, this);
|
this.model.rosterContactAdded.then(() => this.registerContactEventHandlers());
|
||||||
this.model.on('change', this.render, this);
|
this.model.on('change', this.render, this);
|
||||||
this.registerContactEventHandlers();
|
this.registerContactEventHandlers();
|
||||||
/**
|
/**
|
||||||
|
@ -798,10 +800,8 @@ converse.plugins.add('converse-chatview', {
|
||||||
async showMessage (message) {
|
async showMessage (message) {
|
||||||
const view = this.add(message.get('id'), new _converse.MessageView({'model': message}));
|
const view = this.add(message.get('id'), new _converse.MessageView({'model': message}));
|
||||||
await view.render();
|
await view.render();
|
||||||
|
|
||||||
// Clear chat state notifications
|
// Clear chat state notifications
|
||||||
sizzle(`.chat-state-notification[data-csn="${message.get('from')}"]`, this.content).forEach(u.removeElement);
|
sizzle(`.chat-state-notification[data-csn="${message.get('from')}"]`, this.content).forEach(u.removeElement);
|
||||||
|
|
||||||
this.insertMessage(view);
|
this.insertMessage(view);
|
||||||
this.insertDayIndicator(view.el);
|
this.insertDayIndicator(view.el);
|
||||||
this.setScrollPosition(view.el);
|
this.setScrollPosition(view.el);
|
||||||
|
|
|
@ -89,13 +89,26 @@ converse.plugins.add('converse-message-view', {
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
||||||
if (this.model.vcard) {
|
if (this.model.vcard) {
|
||||||
this.model.vcard.on('change', this.debouncedRender, this);
|
this.model.vcard.on('change', this.debouncedRender, this);
|
||||||
}
|
}
|
||||||
this.model.on('rosterContactAdded', () => {
|
|
||||||
this.model.contact.on('change:nickname', this.debouncedRender, this);
|
if (this.model.rosterContactAdded) {
|
||||||
this.debouncedRender();
|
this.model.rosterContactAdded.then(() => {
|
||||||
});
|
this.model.contact.on('change:nickname', this.debouncedRender, this);
|
||||||
|
this.debouncedRender();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.model.occupantAdded) {
|
||||||
|
this.model.occupantAdded.then(() => {
|
||||||
|
this.model.occupant.on('change:role', this.debouncedRender, this);
|
||||||
|
this.model.occupant.on('change:affiliation', this.debouncedRender, this);
|
||||||
|
this.debouncedRender();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.model.on('change', this.onChanged, this);
|
this.model.on('change', this.onChanged, this);
|
||||||
this.model.on('destroy', this.fadeOut, this);
|
this.model.on('destroy', this.fadeOut, this);
|
||||||
},
|
},
|
||||||
|
@ -170,16 +183,17 @@ converse.plugins.add('converse-message-view', {
|
||||||
},
|
},
|
||||||
|
|
||||||
async renderChatMessage () {
|
async renderChatMessage () {
|
||||||
const is_me_message = this.isMeCommand(),
|
const is_me_message = this.isMeCommand();
|
||||||
time = dayjs(this.model.get('time')),
|
const time = dayjs(this.model.get('time'));
|
||||||
role = this.model.vcard ? this.model.vcard.get('role') : null,
|
const role = this.model.vcard ? this.model.vcard.get('role') : null;
|
||||||
roles = role ? role.split(',') : [];
|
const roles = role ? role.split(',') : [];
|
||||||
|
|
||||||
const msg = u.stringToElement(tpl_message(
|
const msg = u.stringToElement(tpl_message(
|
||||||
Object.assign(
|
Object.assign(
|
||||||
this.model.toJSON(), {
|
this.model.toJSON(), {
|
||||||
'__': __,
|
'__': __,
|
||||||
'is_groupchat_message': this.model.get('type') === 'groupchat',
|
'is_groupchat_message': this.model.get('type') === 'groupchat',
|
||||||
|
'occupant': this.model.occupant,
|
||||||
'is_me_message': is_me_message,
|
'is_me_message': is_me_message,
|
||||||
'roles': roles,
|
'roles': roles,
|
||||||
'pretty_time': time.format(_converse.time_format),
|
'pretty_time': time.format(_converse.time_format),
|
||||||
|
|
|
@ -59,12 +59,16 @@ converse.plugins.add('converse-chatboxes', {
|
||||||
|
|
||||||
const ModelWithContact = Backbone.Model.extend({
|
const ModelWithContact = Backbone.Model.extend({
|
||||||
|
|
||||||
|
initialize () {
|
||||||
|
this.rosterContactAdded = u.getResolveablePromise();
|
||||||
|
},
|
||||||
|
|
||||||
async setRosterContact (jid) {
|
async setRosterContact (jid) {
|
||||||
const contact = await _converse.api.contacts.get(jid);
|
const contact = await _converse.api.contacts.get(jid);
|
||||||
if (contact) {
|
if (contact) {
|
||||||
this.contact = contact;
|
this.contact = contact;
|
||||||
this.set('nickname', contact.get('nickname'));
|
this.set('nickname', contact.get('nickname'));
|
||||||
this.trigger('rosterContactAdded');
|
this.rosterContactAdded.resolve();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -88,10 +92,13 @@ converse.plugins.add('converse-chatboxes', {
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize () {
|
initialize () {
|
||||||
|
ModelWithContact.prototype.initialize.apply(this, arguments);
|
||||||
|
|
||||||
if (this.get('type') === 'chat') {
|
if (this.get('type') === 'chat') {
|
||||||
this.setVCard();
|
this.setVCard();
|
||||||
this.setRosterContact(Strophe.getBareJidFromJid(this.get('from')));
|
this.setRosterContact(Strophe.getBareJidFromJid(this.get('from')));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.get('file')) {
|
if (this.get('file')) {
|
||||||
this.on('change:put', this.uploadFile, this);
|
this.on('change:put', this.uploadFile, this);
|
||||||
}
|
}
|
||||||
|
@ -259,6 +266,8 @@ converse.plugins.add('converse-chatboxes', {
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize () {
|
initialize () {
|
||||||
|
ModelWithContact.prototype.initialize.apply(this, arguments);
|
||||||
|
|
||||||
const jid = this.get('jid');
|
const jid = this.get('jid');
|
||||||
if (!jid) {
|
if (!jid) {
|
||||||
// XXX: The `validate` method will prevent this model
|
// XXX: The `validate` method will prevent this model
|
||||||
|
|
|
@ -247,11 +247,38 @@ converse.plugins.add('converse-muc', {
|
||||||
*/
|
*/
|
||||||
_converse.ChatRoomMessage = _converse.Message.extend({
|
_converse.ChatRoomMessage = _converse.Message.extend({
|
||||||
|
|
||||||
getVCardForChatroomOccupant () {
|
initialize () {
|
||||||
const chatbox = this.collection.chatbox,
|
if (this.get('file')) {
|
||||||
nick = Strophe.getResourceFromJid(this.get('from'));
|
this.on('change:put', this.uploadFile, this);
|
||||||
|
}
|
||||||
|
if (this.isEphemeral()) {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
try {
|
||||||
|
this.destroy()
|
||||||
|
} catch (e) {
|
||||||
|
_converse.log(e, Strophe.LogLevel.ERROR);
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
} else {
|
||||||
|
this.occupantAdded = u.getResolveablePromise();
|
||||||
|
this.setOccupant();
|
||||||
|
this.setVCard();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
if (chatbox.get('nick') === nick) {
|
setOccupant () {
|
||||||
|
const chatbox = _.get(this, 'collection.chatbox');
|
||||||
|
if (!chatbox) { return; }
|
||||||
|
const nick = Strophe.getResourceFromJid(this.get('from'));
|
||||||
|
this.occupant = chatbox.occupants.findWhere({'nick': nick});
|
||||||
|
this.occupantAdded.resolve();
|
||||||
|
},
|
||||||
|
|
||||||
|
getVCardForChatroomOccupant () {
|
||||||
|
const chatbox = _.get(this, 'collection.chatbox');
|
||||||
|
const nick = Strophe.getResourceFromJid(this.get('from'));
|
||||||
|
|
||||||
|
if (chatbox && chatbox.get('nick') === nick) {
|
||||||
return _converse.xmppstatus.vcard;
|
return _converse.xmppstatus.vcard;
|
||||||
} else {
|
} else {
|
||||||
let vcard;
|
let vcard;
|
||||||
|
@ -260,14 +287,21 @@ converse.plugins.add('converse-muc', {
|
||||||
}
|
}
|
||||||
if (!vcard) {
|
if (!vcard) {
|
||||||
let jid;
|
let jid;
|
||||||
const occupant = chatbox.occupants.findWhere({'nick': nick});
|
if (this.occupant && this.occupant.get('jid')) {
|
||||||
if (occupant && occupant.get('jid')) {
|
jid = this.occupant.get('jid');
|
||||||
jid = occupant.get('jid');
|
|
||||||
this.save({'vcard_jid': jid}, {'silent': true});
|
this.save({'vcard_jid': jid}, {'silent': true});
|
||||||
} else {
|
} else {
|
||||||
jid = this.get('from');
|
jid = this.get('from');
|
||||||
}
|
}
|
||||||
vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid});
|
if (jid) {
|
||||||
|
vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid});
|
||||||
|
} else {
|
||||||
|
_converse.log(
|
||||||
|
`Could not assign VCard for message because no JID found! msgid: ${this.get('msgid')}`,
|
||||||
|
Strophe.LogLevel.ERROR
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return vcard;
|
return vcard;
|
||||||
}
|
}
|
||||||
|
@ -278,7 +312,7 @@ converse.plugins.add('converse-muc', {
|
||||||
// VCards aren't supported
|
// VCards aren't supported
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.get('type') === 'error') {
|
if (['error', 'info'].includes(this.get('type'))) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
this.vcard = this.getVCardForChatroomOccupant();
|
this.vcard = this.getVCardForChatroomOccupant();
|
||||||
|
@ -389,7 +423,6 @@ converse.plugins.add('converse-muc', {
|
||||||
|
|
||||||
if (_converse.auto_register_muc_nickname &&
|
if (_converse.auto_register_muc_nickname &&
|
||||||
await _converse.api.disco.supports(Strophe.NS.MUC_REGISTER, this.get('jid'))) {
|
await _converse.api.disco.supports(Strophe.NS.MUC_REGISTER, this.get('jid'))) {
|
||||||
|
|
||||||
this.registerNickname()
|
this.registerNickname()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -641,7 +674,7 @@ converse.plugins.add('converse-muc', {
|
||||||
[text, references] = this.parseTextForReferences(text);
|
[text, references] = this.parseTextForReferences(text);
|
||||||
const origin_id = _converse.connection.getUniqueId();
|
const origin_id = _converse.connection.getUniqueId();
|
||||||
|
|
||||||
return this.addOccupantData({
|
return {
|
||||||
'id': origin_id,
|
'id': origin_id,
|
||||||
'msgid': origin_id,
|
'msgid': origin_id,
|
||||||
'origin_id': origin_id,
|
'origin_id': origin_id,
|
||||||
|
@ -655,7 +688,7 @@ converse.plugins.add('converse-muc', {
|
||||||
'sender': 'me',
|
'sender': 'me',
|
||||||
'spoiler_hint': is_spoiler ? spoiler_hint : undefined,
|
'spoiler_hint': is_spoiler ? spoiler_hint : undefined,
|
||||||
'type': 'groupchat'
|
'type': 'groupchat'
|
||||||
});
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1426,17 +1459,6 @@ 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.
|
* Handler for all MUC messages sent to this groupchat.
|
||||||
* @private
|
* @private
|
||||||
|
@ -1460,13 +1482,12 @@ converse.plugins.add('converse-muc', {
|
||||||
this.isChatMarker(stanza)) {
|
this.isChatMarker(stanza)) {
|
||||||
return _converse.api.trigger('message', {'stanza': original_stanza});
|
return _converse.api.trigger('message', {'stanza': original_stanza});
|
||||||
}
|
}
|
||||||
let attrs = await this.getMessageAttributesFromStanza(stanza, original_stanza);
|
const attrs = await this.getMessageAttributesFromStanza(stanza, original_stanza);
|
||||||
if (attrs.nick &&
|
if (attrs.nick &&
|
||||||
!this.subjectChangeHandled(attrs) &&
|
!this.subjectChangeHandled(attrs) &&
|
||||||
!this.ignorableCSN(attrs) &&
|
!this.ignorableCSN(attrs) &&
|
||||||
(attrs['chat_state'] || !u.isEmptyMessage(attrs))) {
|
(attrs['chat_state'] || !u.isEmptyMessage(attrs))) {
|
||||||
|
|
||||||
attrs = this.addOccupantData(attrs);
|
|
||||||
const msg = this.correctMessage(attrs) || this.messages.create(attrs);
|
const msg = this.correctMessage(attrs) || this.messages.create(attrs);
|
||||||
this.incrementUnreadMsgCounter(msg);
|
this.incrementUnreadMsgCounter(msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,8 +130,10 @@ converse.plugins.add('converse-vcard', {
|
||||||
|
|
||||||
_converse.api.listen.on('statusInitialized', () => {
|
_converse.api.listen.on('statusInitialized', () => {
|
||||||
const vcards = _converse.vcards;
|
const vcards = _converse.vcards;
|
||||||
const jid = _converse.session.get('bare_jid');
|
if (_converse.session) {
|
||||||
_converse.xmppstatus.vcard = vcards.findWhere({'jid': jid}) || vcards.create({'jid': jid});
|
const jid = _converse.session.get('bare_jid');
|
||||||
|
_converse.xmppstatus.vcard = vcards.findWhere({'jid': jid}) || vcards.create({'jid': jid});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,7 +167,7 @@ converse.plugins.add('converse-vcard', {
|
||||||
* // Failure
|
* // Failure
|
||||||
* }).
|
* }).
|
||||||
*/
|
*/
|
||||||
'set' (jid, data) {
|
set (jid, data) {
|
||||||
return setVCard(jid, data);
|
return setVCard(jid, data);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="chat-msg__content chat-msg__content--{{{o.sender}}} {{{o.is_me_message ? 'chat-msg__content--action' : ''}}}">
|
<div class="chat-msg__content chat-msg__content--{{{o.sender}}} {{{o.is_me_message ? 'chat-msg__content--action' : ''}}}">
|
||||||
<span class="chat-msg__heading">
|
<span class="chat-msg__heading">
|
||||||
{[ if (o.is_me_message) { ]}<time timestamp="{{{o.isodate}}}" class="chat-msg__time">{{{o.pretty_time}}}</time>{[ } ]}
|
{[ if (o.is_me_message) { ]}<time timestamp="{{{o.isodate}}}" class="chat-msg__time">{{{o.pretty_time}}}</time>{[ } ]}
|
||||||
<span class="chat-msg__author {{{o.is_groupchat_message && o.role ? o.role : ''}}}">{[ if (o.is_me_message) { ]}**{[ }; ]}{{{o.username}}}</span>
|
<span class="chat-msg__author {{{o.is_groupchat_message && o.occupant && o.occupant.get('role') ? o.occupant.get('role') : ''}}}">{[ if (o.is_me_message) { ]}**{[ }; ]}{{{o.username}}}</span>
|
||||||
{[ if (!o.is_me_message) { ]}
|
{[ if (!o.is_me_message) { ]}
|
||||||
{[o.roles.forEach(function (role) { ]} <span class="badge badge-secondary">{{{role}}}</span> {[ }); ]}
|
{[o.roles.forEach(function (role) { ]} <span class="badge badge-secondary">{{{role}}}</span> {[ }); ]}
|
||||||
<time timestamp="{{{o.isodate}}}" class="chat-msg__time">{{{o.pretty_time}}}</time>
|
<time timestamp="{{{o.isodate}}}" class="chat-msg__time">{{{o.pretty_time}}}</time>
|
||||||
|
|
|
@ -194,7 +194,7 @@
|
||||||
// The user has just entered the room (because join was called)
|
// The user has just entered the room (because join was called)
|
||||||
// and receives their own presence from the server.
|
// and receives their own presence from the server.
|
||||||
// See example 24: https://xmpp.org/extensions/xep-0045.html#enter-pres
|
// See example 24: https://xmpp.org/extensions/xep-0045.html#enter-pres
|
||||||
var presence = $pres({
|
const presence = $pres({
|
||||||
to: _converse.connection.jid,
|
to: _converse.connection.jid,
|
||||||
from: `${room_jid}/${nick}`,
|
from: `${room_jid}/${nick}`,
|
||||||
id: u.getUniqueId()
|
id: u.getUniqueId()
|
||||||
|
@ -207,6 +207,43 @@
|
||||||
.c('status').attrs({code:'110'});
|
.c('status').attrs({code:'110'});
|
||||||
_converse.connection._dataRecv(utils.createRequest(presence));
|
_converse.connection._dataRecv(utils.createRequest(presence));
|
||||||
await utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED));
|
await utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED));
|
||||||
|
|
||||||
|
// Now we return the (empty) member lists
|
||||||
|
const member_IQ = await utils.waitUntil(() => _.filter(
|
||||||
|
stanzas,
|
||||||
|
s => sizzle(`iq[to="${room_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="member"]`, s).length
|
||||||
|
).pop());
|
||||||
|
const member_list_stanza = $iq({
|
||||||
|
'from': 'coven@chat.shakespeare.lit',
|
||||||
|
'id': member_IQ.getAttribute('id'),
|
||||||
|
'to': 'romeo@montague.lit/orchard',
|
||||||
|
'type': 'result'
|
||||||
|
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN});
|
||||||
|
_converse.connection._dataRecv(utils.createRequest(member_list_stanza));
|
||||||
|
|
||||||
|
const admin_IQ = await utils.waitUntil(() => _.filter(
|
||||||
|
stanzas,
|
||||||
|
s => sizzle(`iq[to="${room_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="admin"]`, s).length
|
||||||
|
).pop());
|
||||||
|
const admin_list_stanza = $iq({
|
||||||
|
'from': 'coven@chat.shakespeare.lit',
|
||||||
|
'id': admin_IQ.getAttribute('id'),
|
||||||
|
'to': 'romeo@montague.lit/orchard',
|
||||||
|
'type': 'result'
|
||||||
|
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN});
|
||||||
|
_converse.connection._dataRecv(utils.createRequest(admin_list_stanza));
|
||||||
|
|
||||||
|
const owner_IQ = await utils.waitUntil(() => _.filter(
|
||||||
|
stanzas,
|
||||||
|
s => sizzle(`iq[to="${room_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="owner"]`, s).length
|
||||||
|
).pop());
|
||||||
|
const owner_list_stanza = $iq({
|
||||||
|
'from': 'coven@chat.shakespeare.lit',
|
||||||
|
'id': owner_IQ.getAttribute('id'),
|
||||||
|
'to': 'romeo@montague.lit/orchard',
|
||||||
|
'type': 'result'
|
||||||
|
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN});
|
||||||
|
_converse.connection._dataRecv(utils.createRequest(owner_list_stanza));
|
||||||
};
|
};
|
||||||
|
|
||||||
utils.clearBrowserStorage = function () {
|
utils.clearBrowserStorage = function () {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user