MUC: Use converse-disco to query for room features
By doing so we create a new DiscoEntity for the room, which allows us to query for features via the disco API. We also avoid duplication of functionality between converse-muc and converse-disco
This commit is contained in:
parent
197451db54
commit
6457bc765a
@ -1141,9 +1141,8 @@
|
||||
form_el.addEventListener('submit',
|
||||
(ev) => {
|
||||
ev.preventDefault();
|
||||
this.model.saveConfiguration(ev.target).then(
|
||||
this.model.getRoomFeatures.bind(this.model)
|
||||
);
|
||||
this.model.saveConfiguration(ev.target)
|
||||
.then(() => this.model.refreshRoomFeatures());
|
||||
this.closeForm();
|
||||
},
|
||||
false
|
||||
|
@ -403,22 +403,6 @@
|
||||
};
|
||||
},
|
||||
|
||||
getRoomFeatures () {
|
||||
/* Fetch the groupchat disco info, parse it and then save it.
|
||||
*/
|
||||
// XXX: Currently we store disco info on the room itself.
|
||||
// A better design would probably be to create a
|
||||
// DiscoEntity for this room, and then to let
|
||||
// converse-disco manage all disco-related tasks.
|
||||
// Then we can also use _converse.api.disco.supports.
|
||||
return _converse.api.disco.info(this.get('jid'), null)
|
||||
.then(stanza => this.parseRoomFeatures(stanza))
|
||||
.catch(err => {
|
||||
_converse.log("Could not parse the groupchat features", Strophe.LogLevel.WARN);
|
||||
_converse.log(err, Strophe.LogLevel.WARN);
|
||||
});
|
||||
},
|
||||
|
||||
getRoomJIDAndNick (nick) {
|
||||
/* Utility method to construct the JID for the current user
|
||||
* as occupant of the groupchat.
|
||||
@ -499,43 +483,34 @@
|
||||
});
|
||||
},
|
||||
|
||||
parseRoomFeatures (iq) {
|
||||
/* Parses an IQ stanza containing the groupchat's features.
|
||||
*
|
||||
* See http://xmpp.org/extensions/xep-0045.html#disco-roominfo
|
||||
*
|
||||
* <identity
|
||||
* category='conference'
|
||||
* name='A Dark Cave'
|
||||
* type='text'/>
|
||||
* <feature var='http://jabber.org/protocol/muc'/>
|
||||
* <feature var='muc_passwordprotected'/>
|
||||
* <feature var='muc_hidden'/>
|
||||
* <feature var='muc_temporary'/>
|
||||
* <feature var='muc_open'/>
|
||||
* <feature var='muc_unmoderated'/>
|
||||
* <feature var='muc_nonanonymous'/>
|
||||
* <feature var='urn:xmpp:mam:0'/>
|
||||
*/
|
||||
const features = {
|
||||
'features_fetched': moment().format(),
|
||||
'name': iq.querySelector('identity').getAttribute('name')
|
||||
refreshRoomFeatures () {
|
||||
const entity = _converse.disco_entities.get(this.get('jid'));
|
||||
if (entity) {
|
||||
entity.destroy();
|
||||
}
|
||||
_.each(iq.querySelectorAll('feature'), function (field) {
|
||||
const fieldname = field.getAttribute('var');
|
||||
return this.getRoomFeatures();
|
||||
},
|
||||
|
||||
async getRoomFeatures () {
|
||||
const features = await _converse.api.disco.getFeatures(this.get('jid')),
|
||||
fields = await _converse.api.disco.getFields(this.get('jid')),
|
||||
identity = await _converse.api.disco.getIdentity('conference', 'text', this.get('jid')),
|
||||
attrs = {
|
||||
'features_fetched': moment().format(),
|
||||
'name': identity && identity.get('name')
|
||||
};
|
||||
features.each(feature => {
|
||||
const fieldname = feature.get('var');
|
||||
if (!fieldname.startsWith('muc_')) {
|
||||
if (fieldname === Strophe.NS.MAM) {
|
||||
features.mam_enabled = true;
|
||||
attrs.mam_enabled = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
features[fieldname.replace('muc_', '')] = true;
|
||||
attrs[fieldname.replace('muc_', '')] = true;
|
||||
});
|
||||
const desc_field = iq.querySelector('field[var="muc#roominfo_description"] value');
|
||||
if (!_.isNull(desc_field)) {
|
||||
features.description = desc_field.textContent;
|
||||
}
|
||||
this.save(features);
|
||||
attrs.description = _.get(fields.findWhere({'var': "muc#roominfo_description"}), 'attributes.value');
|
||||
this.save(attrs);
|
||||
},
|
||||
|
||||
requestMemberList (affiliation) {
|
||||
@ -969,7 +944,7 @@
|
||||
|
||||
if (configuration_changed || logging_enabled || logging_disabled ||
|
||||
room_no_longer_anon || room_now_semi_anon || room_now_fully_anon) {
|
||||
this.getRoomFeatures();
|
||||
this.refreshRoomFeatures();
|
||||
}
|
||||
},
|
||||
|
||||
@ -1053,10 +1028,10 @@
|
||||
const locked_room = pres.querySelector("status[code='201']");
|
||||
if (locked_room) {
|
||||
if (this.get('auto_configure')) {
|
||||
this.autoConfigureChatRoom().then(this.getRoomFeatures.bind(this));
|
||||
this.autoConfigureChatRoom().then(() => this.refreshRoomFeatures());
|
||||
} else if (_converse.muc_instant_rooms) {
|
||||
// Accept default configuration
|
||||
this.saveConfiguration().then(this.getRoomFeatures.bind(this));
|
||||
this.saveConfiguration().then(() => this.getRoomFeatures());
|
||||
} else {
|
||||
this.trigger('configurationNeeded');
|
||||
return; // We haven't yet entered the groupchat, so bail here.
|
||||
@ -1068,7 +1043,7 @@
|
||||
// otherwise the features would have been fetched in
|
||||
// the "initialize" method already.
|
||||
if (this.get('affiliation') === 'owner' && this.get('auto_configure')) {
|
||||
this.autoConfigureChatRoom().then(this.getRoomFeatures.bind(this));
|
||||
this.autoConfigureChatRoom().then(() => this.refreshRoomFeatures());
|
||||
} else {
|
||||
this.getRoomFeatures();
|
||||
}
|
||||
|
@ -127,19 +127,44 @@
|
||||
|
||||
utils.openAndEnterChatRoom = function (_converse, room, server, nick) {
|
||||
let last_stanza, view;
|
||||
const room_jid = `${room}@${server}`.toLowerCase();
|
||||
|
||||
return _converse.api.rooms.open(`${room}@${server}`).then(() => {
|
||||
view = _converse.chatboxviews.get((room+'@'+server).toLowerCase());
|
||||
// We pretend this is a new room, so no disco info is returned.
|
||||
last_stanza = _.last(_converse.connection.IQ_stanzas).nodeTree;
|
||||
const IQ_id = last_stanza.getAttribute('id');
|
||||
return _converse.api.rooms.open(room_jid).then(() => {
|
||||
view = _converse.chatboxviews.get(room_jid);
|
||||
return utils.waitUntil(() => _.get(_.filter(
|
||||
_converse.connection.IQ_stanzas,
|
||||
iq => iq.nodeTree.querySelector(
|
||||
`iq[to="coven@chat.shakespeare.lit"] query[xmlns="http://jabber.org/protocol/disco#info"]`
|
||||
)
|
||||
).pop(), 'nodeTree'));
|
||||
}).then(stanza => {
|
||||
const features_stanza = $iq({
|
||||
'from': room+'@'+server,
|
||||
'id': IQ_id,
|
||||
'to': nick+'@'+server,
|
||||
'type': 'error'
|
||||
}).c('error', {'type': 'cancel'})
|
||||
.c('item-not-found', {'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas"});
|
||||
'from': room_jid,
|
||||
'id': stanza.getAttribute('id'),
|
||||
'to': 'dummy@localhost/desktop',
|
||||
'type': 'result'
|
||||
})
|
||||
.c('query', { 'xmlns': 'http://jabber.org/protocol/disco#info'})
|
||||
.c('identity', {
|
||||
'category': 'conference',
|
||||
'name': 'A Dark Cave',
|
||||
'type': 'text'
|
||||
}).up()
|
||||
.c('feature', {'var': 'http://jabber.org/protocol/muc'}).up()
|
||||
.c('feature', {'var': 'jabber:iq:register'}).up()
|
||||
.c('feature', {'var': 'muc_passwordprotected'}).up()
|
||||
.c('feature', {'var': 'muc_hidden'}).up()
|
||||
.c('feature', {'var': 'muc_temporary'}).up()
|
||||
.c('feature', {'var': 'muc_open'}).up()
|
||||
.c('feature', {'var': 'muc_unmoderated'}).up()
|
||||
.c('feature', {'var': 'muc_nonanonymous'})
|
||||
.c('x', { 'xmlns':'jabber:x:data', 'type':'result'})
|
||||
.c('field', {'var':'FORM_TYPE', 'type':'hidden'})
|
||||
.c('value').t('http://jabber.org/protocol/muc#roominfo').up().up()
|
||||
.c('field', {'type':'text-single', 'var':'muc#roominfo_description', 'label':'Description'})
|
||||
.c('value').t('This is the description').up().up()
|
||||
.c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'})
|
||||
.c('value').t(0);
|
||||
_converse.connection._dataRecv(utils.createRequest(features_stanza));
|
||||
return utils.waitUntil(() => {
|
||||
return _.filter(
|
||||
@ -179,8 +204,11 @@
|
||||
}).up()
|
||||
.c('status').attrs({code:'110'});
|
||||
_converse.connection._dataRecv(utils.createRequest(presence));
|
||||
return utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED);
|
||||
}).catch(_.partial(console.error, _));
|
||||
return utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED));
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
throw e;
|
||||
});
|
||||
};
|
||||
|
||||
utils.clearBrowserStorage = function () {
|
||||
|
Loading…
Reference in New Issue
Block a user