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',
|
form_el.addEventListener('submit',
|
||||||
(ev) => {
|
(ev) => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
this.model.saveConfiguration(ev.target).then(
|
this.model.saveConfiguration(ev.target)
|
||||||
this.model.getRoomFeatures.bind(this.model)
|
.then(() => this.model.refreshRoomFeatures());
|
||||||
);
|
|
||||||
this.closeForm();
|
this.closeForm();
|
||||||
},
|
},
|
||||||
false
|
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) {
|
getRoomJIDAndNick (nick) {
|
||||||
/* Utility method to construct the JID for the current user
|
/* Utility method to construct the JID for the current user
|
||||||
* as occupant of the groupchat.
|
* as occupant of the groupchat.
|
||||||
@ -499,43 +483,34 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
parseRoomFeatures (iq) {
|
refreshRoomFeatures () {
|
||||||
/* Parses an IQ stanza containing the groupchat's features.
|
const entity = _converse.disco_entities.get(this.get('jid'));
|
||||||
*
|
if (entity) {
|
||||||
* See http://xmpp.org/extensions/xep-0045.html#disco-roominfo
|
entity.destroy();
|
||||||
*
|
|
||||||
* <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')
|
|
||||||
}
|
}
|
||||||
_.each(iq.querySelectorAll('feature'), function (field) {
|
return this.getRoomFeatures();
|
||||||
const fieldname = field.getAttribute('var');
|
},
|
||||||
|
|
||||||
|
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.startsWith('muc_')) {
|
||||||
if (fieldname === Strophe.NS.MAM) {
|
if (fieldname === Strophe.NS.MAM) {
|
||||||
features.mam_enabled = true;
|
attrs.mam_enabled = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
features[fieldname.replace('muc_', '')] = true;
|
attrs[fieldname.replace('muc_', '')] = true;
|
||||||
});
|
});
|
||||||
const desc_field = iq.querySelector('field[var="muc#roominfo_description"] value');
|
attrs.description = _.get(fields.findWhere({'var': "muc#roominfo_description"}), 'attributes.value');
|
||||||
if (!_.isNull(desc_field)) {
|
this.save(attrs);
|
||||||
features.description = desc_field.textContent;
|
|
||||||
}
|
|
||||||
this.save(features);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
requestMemberList (affiliation) {
|
requestMemberList (affiliation) {
|
||||||
@ -969,7 +944,7 @@
|
|||||||
|
|
||||||
if (configuration_changed || logging_enabled || logging_disabled ||
|
if (configuration_changed || logging_enabled || logging_disabled ||
|
||||||
room_no_longer_anon || room_now_semi_anon || room_now_fully_anon) {
|
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']");
|
const locked_room = pres.querySelector("status[code='201']");
|
||||||
if (locked_room) {
|
if (locked_room) {
|
||||||
if (this.get('auto_configure')) {
|
if (this.get('auto_configure')) {
|
||||||
this.autoConfigureChatRoom().then(this.getRoomFeatures.bind(this));
|
this.autoConfigureChatRoom().then(() => this.refreshRoomFeatures());
|
||||||
} else if (_converse.muc_instant_rooms) {
|
} else if (_converse.muc_instant_rooms) {
|
||||||
// Accept default configuration
|
// Accept default configuration
|
||||||
this.saveConfiguration().then(this.getRoomFeatures.bind(this));
|
this.saveConfiguration().then(() => this.getRoomFeatures());
|
||||||
} else {
|
} else {
|
||||||
this.trigger('configurationNeeded');
|
this.trigger('configurationNeeded');
|
||||||
return; // We haven't yet entered the groupchat, so bail here.
|
return; // We haven't yet entered the groupchat, so bail here.
|
||||||
@ -1068,7 +1043,7 @@
|
|||||||
// otherwise the features would have been fetched in
|
// otherwise the features would have been fetched in
|
||||||
// the "initialize" method already.
|
// the "initialize" method already.
|
||||||
if (this.get('affiliation') === 'owner' && this.get('auto_configure')) {
|
if (this.get('affiliation') === 'owner' && this.get('auto_configure')) {
|
||||||
this.autoConfigureChatRoom().then(this.getRoomFeatures.bind(this));
|
this.autoConfigureChatRoom().then(() => this.refreshRoomFeatures());
|
||||||
} else {
|
} else {
|
||||||
this.getRoomFeatures();
|
this.getRoomFeatures();
|
||||||
}
|
}
|
||||||
|
@ -127,19 +127,44 @@
|
|||||||
|
|
||||||
utils.openAndEnterChatRoom = function (_converse, room, server, nick) {
|
utils.openAndEnterChatRoom = function (_converse, room, server, nick) {
|
||||||
let last_stanza, view;
|
let last_stanza, view;
|
||||||
|
const room_jid = `${room}@${server}`.toLowerCase();
|
||||||
|
|
||||||
return _converse.api.rooms.open(`${room}@${server}`).then(() => {
|
return _converse.api.rooms.open(room_jid).then(() => {
|
||||||
view = _converse.chatboxviews.get((room+'@'+server).toLowerCase());
|
view = _converse.chatboxviews.get(room_jid);
|
||||||
// We pretend this is a new room, so no disco info is returned.
|
return utils.waitUntil(() => _.get(_.filter(
|
||||||
last_stanza = _.last(_converse.connection.IQ_stanzas).nodeTree;
|
_converse.connection.IQ_stanzas,
|
||||||
const IQ_id = last_stanza.getAttribute('id');
|
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({
|
const features_stanza = $iq({
|
||||||
'from': room+'@'+server,
|
'from': room_jid,
|
||||||
'id': IQ_id,
|
'id': stanza.getAttribute('id'),
|
||||||
'to': nick+'@'+server,
|
'to': 'dummy@localhost/desktop',
|
||||||
'type': 'error'
|
'type': 'result'
|
||||||
}).c('error', {'type': 'cancel'})
|
})
|
||||||
.c('item-not-found', {'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas"});
|
.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));
|
_converse.connection._dataRecv(utils.createRequest(features_stanza));
|
||||||
return utils.waitUntil(() => {
|
return utils.waitUntil(() => {
|
||||||
return _.filter(
|
return _.filter(
|
||||||
@ -179,8 +204,11 @@
|
|||||||
}).up()
|
}).up()
|
||||||
.c('status').attrs({code:'110'});
|
.c('status').attrs({code:'110'});
|
||||||
_converse.connection._dataRecv(utils.createRequest(presence));
|
_converse.connection._dataRecv(utils.createRequest(presence));
|
||||||
return utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED);
|
return utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED));
|
||||||
}).catch(_.partial(console.error, _));
|
}).catch(e => {
|
||||||
|
console.error(e);
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
utils.clearBrowserStorage = function () {
|
utils.clearBrowserStorage = function () {
|
||||||
|
Loading…
Reference in New Issue
Block a user