Commit 81879bc0 authored by JC Brand's avatar JC Brand

converse-muc: Cache the room disco information

Instead of the room configuration.
This is because non-owners have access to the former, but not the latter.
parent 0f4efac0
......@@ -109,7 +109,7 @@
100: __('This room is not anonymous'),
102: __('This room now shows unavailable members'),
103: __('This room does not show unavailable members'),
104: __('Non-privacy-related room configuration has changed'),
104: __('The room configuration has changed'),
170: __('Room logging is now enabled'),
171: __('Room logging is now disabled'),
172: __('This room is now no longer anonymous'),
......@@ -742,6 +742,16 @@
if (is_mam) {
return true;
}
var configuration_changed = stanza.querySelector("status[code='104']");
var logging_enabled = stanza.querySelector("status[code='170']");
var logging_disabled = stanza.querySelector("status[code='171']");
var room_no_longer_anon = stanza.querySelector("status[code='172']");
var room_now_semi_anon = stanza.querySelector("status[code='173']");
var room_now_fully_anon = stanza.querySelector("status[code='173']");
if (configuration_changed || logging_enabled || logging_disabled ||
room_no_longer_anon || room_now_semi_anon || room_now_fully_anon) {
this.cacheRoomFeatures();
}
_.compose(this.onChatRoomMessage.bind(this), this.showStatusMessages.bind(this))(stanza);
return true;
},
......@@ -1042,29 +1052,45 @@
return deferred.promise();
},
cacheRoomConfiguration: function () {
/* Fetch the room configuration, parse it and then
cacheRoomFeatures: function () {
/* Fetch the room disco info, parse it and then
* save it on the Backbone.Model of this chat rooms.
*
* See http://xmpp.org/extensions/xep-0045.html#disco-roominfo
*/
var that = this;
this.fetchRoomConfiguration().then(function (iq) {
var roomconfig = {};
_.each(iq.querySelectorAll('field'), function (field) {
var type = field.getAttribute('type');
if (type === 'hidden' && type === 'fixed') { return; }
var fieldname = field.getAttribute('var').replace('muc#roomconfig_', '');
var value = _.propertyOf(field.querySelector('value') || {})('textContent');
/* Unfortunately we don't have enough information
* to determine which values are actually integers, only
* booleans.
converse.connection.disco.info(this.model.get('jid'), null,
function (iq) {
/* <iq from='coven@chat.shakespeare.lit'
* id='ik3vs715'
* to='hag66@shakespeare.lit/pda'
* type='result'>
* <query xmlns='http://jabber.org/protocol/disco#info'>
* <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'/>
* </query>
* </iq>
*/
if (type === "boolean") {
value = parseInt(value, 10);
}
roomconfig[fieldname] = value;
});
that.model.save(roomconfig);
});
var features = [];
_.each(iq.querySelectorAll('feature'), function (field) {
var fieldname = field.getAttribute('var');
if (!fieldname.startsWith('muc_')) {
return;
}
features.push(fieldname.replace('muc_', ''));
});
that.model.save({'features': features});
}
);
},
configureChatRoom: function (ev) {
......@@ -1084,16 +1110,12 @@
*/
var that = this;
if (_.isUndefined(ev) && this.model.get('auto_configure')) {
this.fetchRoomConfiguration().then(function (iq) {
that.autoConfigureChatRoom(iq).then(that.cacheRoomConfiguration.bind(that));
});
this.fetchRoomConfiguration().then(that.autoConfigureChatRoom.bind(that));
} else {
if (typeof ev !== 'undefined' && ev.preventDefault) {
ev.preventDefault();
}
this.fetchRoomConfiguration().then(function (iq) {
that.renderConfigurationForm(iq).then(that.cacheRoomConfiguration.bind(that));
});
this.fetchRoomConfiguration().then(that.renderConfigurationForm.bind(that));
}
},
......@@ -1449,9 +1471,9 @@
/* Sends an empty IQ config stanza to inform the server that the
* room should be created with its default configuration.
*
* See * http://xmpp.org/extensions/xep-0045.html#createroom-instant
* See http://xmpp.org/extensions/xep-0045.html#createroom-instant
*/
this.sendConfiguration().then(this.cacheRoomConfiguration.bind(this));
this.sendConfiguration().then(this.cacheRoomFeatures.bind(this));
},
onChatRoomPresence: function (pres) {
......@@ -1460,44 +1482,43 @@
* Parameters:
* (XMLElement) pres: The stanza
*/
var $presence = $(pres), is_self, new_room;
var show_status_messages = true;
if ($presence.attr('type') === 'error') {
if (pres.getAttribute('type') === 'error') {
this.model.set('connection_status', Strophe.Status.DISCONNECTED);
this.showErrorMessage(pres);
} else {
is_self = $presence.find("status[code='110']").length;
new_room = $presence.find("status[code='201']").length;
if (is_self) {
this.findAndSaveOwnAffiliation(pres);
}
if (is_self && new_room) {
// This is a new room. It will now be configured
// and the configuration cached on the
// Backbone.Model.
if (converse.muc_instant_rooms) {
this.createInstantRoom(); // Accept default configuration
} else {
this.configureChatRoom();
if (!this.model.get('auto_configure')) {
// We don't show status messages if the
// configuration form is being shown.
show_status_messages = false;
}
return true;
}
var show_status_messages = true;
var is_self = pres.querySelector("status[code='110']");
var new_room = pres.querySelector("status[code='201']");
if (is_self) {
this.findAndSaveOwnAffiliation(pres);
}
if (is_self && new_room) {
// This is a new room. It will now be configured
// and the configuration cached on the
// Backbone.Model.
if (converse.muc_instant_rooms) {
this.createInstantRoom(); // Accept default configuration
} else {
this.configureChatRoom();
if (!this.model.get('auto_configure')) {
// We don't show status messages if the
// configuration form is being shown.
show_status_messages = false;
}
} else if (this.model.get('connection_status') !== Strophe.Status.CONNECTED) {
// This is not a new room, and this is the first
// presence received for this room (hence the
// "connection_status" check), so we now cache the
// room configuration.
this.cacheRoomConfiguration();
}
if (show_status_messages) {
this.hideSpinner().showStatusMessages(pres);
}
this.occupantsview.updateOccupantsOnPresence(pres);
this.model.set('connection_status', Strophe.Status.CONNECTED);
} else if (this.model.get('connection_status') !== Strophe.Status.CONNECTED) {
// This is not a new room, and this is the first
// presence received or the room config has
// changed.
this.cacheRoomFeatures();
}
if (show_status_messages) {
this.hideSpinner().showStatusMessages(pres);
}
this.occupantsview.updateOccupantsOnPresence(pres);
this.model.set('connection_status', Strophe.Status.CONNECTED);
return true;
},
......@@ -1512,16 +1533,22 @@
this.scrollDown();
},
onChatRoomMessage: function (message) {
var $message = $(message),
onChatRoomMessage: function (msg) {
/* Given a <message> stanza, create a message
* Backbone.Model if appropriate.
*
* Parameters:
* (XMLElement) msg: The received message stanza
*/
var $message = $(msg),
$forwarded = $message.find('forwarded'),
$delay;
if ($forwarded.length) {
$message = $forwarded.children('message');
$delay = $forwarded.children('delay');
}
var jid = $message.attr('from'),
msgid = $message.attr('id'),
var jid = msg.getAttribute('from'),
msgid = msg.getAttribute('id'),
resource = Strophe.getResourceFromJid(jid),
sender = resource && Strophe.unescapeNode(resource) || '',
subject = $message.children('subject').text(),
......@@ -1541,10 +1568,10 @@
if (sender === '') {
return true;
}
this.model.createMessage($message, $delay, message);
this.model.createMessage($message, $delay, msg);
if (sender !== this.model.get('nick')) {
// We only emit an event if it's not our own message
converse.emit('message', message);
converse.emit('message', msg);
}
return true;
},
......@@ -1903,12 +1930,18 @@
this.updateRoomsList();
},
insertRoomInfo: function ($parent, stanza) {
insertRoomInfo: function (el, stanza) {
/* Insert room info (based on returned #disco IQ stanza)
*
* Parameters:
* (HTMLElement) el: The HTML DOM element that should
* contain the info.
* (XMLElement) stanza: The IQ stanza containing the room
* info.
*/
var $stanza = $(stanza);
// All MUC features found here: http://xmpp.org/registrar/disco-features.html
$parent.find('span.spinner').replaceWith(
$(el).find('span.spinner').replaceWith(
converse.templates.room_description({
'desc': $stanza.find('field[var="muc#roominfo_description"] value').text(),
'occ': $stanza.find('field[var="muc#roominfo_occupants"] value').text(),
......@@ -1953,7 +1986,7 @@
$parent.find('span.spinner').remove();
$parent.append('<span class="spinner hor_centered"/>');
converse.connection.disco.info(
$(target).attr('data-room-jid'), null, _.partial(this.insertRoomInfo, $parent)
$(target).attr('data-room-jid'), null, _.partial(this.insertRoomInfo, $parent[0])
);
}
},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment