Commit e3899134 authored by JC Brand's avatar JC Brand

Better service discovery support

Features are saved to localStorage so that service discovery doesn't have to
happen during every request.
parent ade26978
...@@ -718,11 +718,10 @@ ...@@ -718,11 +718,10 @@
this.on('update-rooms-list', function (ev) { this.on('update-rooms-list', function (ev) {
this.updateRoomsList(); this.updateRoomsList();
}); });
this.trigger('update-rooms-list');
}, },
updateRoomsList: function () { updateRoomsList: function () {
converse.connection.muc.listRooms(converse.muc_domain, $.proxy(function (iq) { converse.connection.muc.listRooms(this.muc_domain, $.proxy(function (iq) {
var name, jid, i, var name, jid, i,
rooms = $(iq).find('query').find('item'), rooms = $(iq).find('query').find('item'),
rooms_length = rooms.length, rooms_length = rooms.length,
...@@ -752,7 +751,7 @@ ...@@ -752,7 +751,7 @@
name = input.val().trim().toLowerCase(); name = input.val().trim().toLowerCase();
input.val(''); // Clear the input input.val(''); // Clear the input
if (name) { if (name) {
jid = Strophe.escapeNode(name) + '@' + converse.muc_domain; jid = Strophe.escapeNode(name) + '@' + this.muc_domain;
} else { } else {
return; return;
} }
...@@ -780,8 +779,16 @@ ...@@ -780,8 +779,16 @@
initialize: function () { initialize: function () {
this.$el.appendTo(converse.chatboxesview.$el); this.$el.appendTo(converse.chatboxesview.$el);
this.model.on('change', $.proxy(function (item, changed) { this.model.on('change', $.proxy(function (item, changed) {
var i;
if (_.has(item.changed, 'connected')) { if (_.has(item.changed, 'connected')) {
this.render(); this.render();
converse.features.on('add', $.proxy(this.featureAdded, this));
// Features could have been added before the controlbox was
// initialized. Currently we're only interested in MUC
var feature = converse.features.findWhere({'var': 'http://jabber.org/protocol/muc'});
if (feature) {
this.featureAdded(feature);
}
} }
if (_.has(item.changed, 'visible')) { if (_.has(item.changed, 'visible')) {
if (item.changed.visible === true) { if (item.changed.visible === true) {
...@@ -789,7 +796,6 @@ ...@@ -789,7 +796,6 @@
} }
} }
}, this)); }, this));
this.model.on('show', this.show, this); this.model.on('show', this.show, this);
this.model.on('destroy', this.hide, this); this.model.on('destroy', this.hide, this);
this.model.on('hide', this.hide, this); this.model.on('hide', this.hide, this);
...@@ -798,6 +804,17 @@ ...@@ -798,6 +804,17 @@
} }
}, },
featureAdded: function (feature) {
if (feature.get('var') == 'http://jabber.org/protocol/muc') {
if (!this.roomspanel) {
this.roomspanel = new converse.RoomsPanel();
this.roomspanel.muc_domain = feature.get('from');
this.roomspanel.$parent = this.$el;
this.roomspanel.render().trigger('update-rooms-list');
}
}
},
template: _.template( template: _.template(
'<div class="chat-head oc-chat-head">'+ '<div class="chat-head oc-chat-head">'+
'<ul id="controlbox-tabs"></ul>'+ '<ul id="controlbox-tabs"></ul>'+
...@@ -839,15 +856,6 @@ ...@@ -839,15 +856,6 @@
this.contactspanel.render(); this.contactspanel.render();
} }
return this; return this;
},
addRoomsPanel: function () {
// XXX: We might to ensure that render was already called
if (!this.roomspanel) {
this.roomspanel = new converse.RoomsPanel();
this.roomspanel.$parent = this.$el;
this.roomspanel.render();
}
} }
}); });
...@@ -1848,34 +1856,50 @@ ...@@ -1848,34 +1856,50 @@
} }
}); });
converse.ServiceDiscovery = Backbone.Model.extend({ converse.Feature = Backbone.Model.extend();
converse.Features = Backbone.Collection.extend({
/* This collection stores Feature Models, representing features
* provided by available XMPP entities (e.g. servers)
*
* See XEP-0030 for more details: http://xmpp.org/extensions/xep-0030.html
*/
model: converse.Feature,
initialize: function () { initialize: function () {
this.localStorage = new Backbone.LocalStorage(
hex_sha1('converse.features'+converse.bare_jid));
if (this.localStorage.records.length === 0) {
// localStorage is empty, so we've likely never queried this
// domain for features yet
converse.connection.disco.info(converse.domain, null, this.onInfo, this.onError); converse.connection.disco.info(converse.domain, null, this.onInfo, this.onError);
converse.connection.disco.items(converse.domain, null, $.proxy(this.onItems, this), $.proxy(this.onError, this)); converse.connection.disco.items(converse.domain, null, $.proxy(this.onItems, this), $.proxy(this.onError, this));
} else {
this.fetch({add:true});
}
}, },
onItems: function (stanza) { onItems: function (stanza) {
var that = this; $(stanza).find('query item').each($.proxy(function (idx, item) {
$(stanza).find('query item').each(function () { converse.connection.disco.info(
converse.connection.disco.info($(this).attr('jid'), null, that.onInfo, that.onError); $(item).attr('jid'),
}); null,
$.proxy(this.onInfo, this),
$.proxy(this.onError, this));
}, this));
}, },
onInfo: function (stanza) { onInfo: function (stanza) {
var $stanza = $(stanza); var $stanza = $(stanza);
if ($(stanza).find('identity[category=conference][type=text]').length < 1) { if (($stanza.find('identity[category=server][type=im]').length === 0) &&
($stanza.find('identity[category=conference][type=text]').length === 0)) {
// This isn't an IM server component // This isn't an IM server component
return; return;
} }
$stanza.find('feature').each(function (idx, feature) { $stanza.find('feature').each($.proxy(function (idx, feature) {
if ($(this).attr('var') == 'http://jabber.org/protocol/muc') { this.create({
// This component supports MUC 'var': $(feature).attr('var'),
converse.muc_domain = $stanza.attr('from'); 'from': $stanza.attr('from')
// XXX: It would probably make sense to refactor a
// controlbox to be a Collection of Panel objects
converse.chatboxesview.views.controlbox.addRoomsPanel();
}
}); });
}, this));
}, },
onError: function (stanza) { onError: function (stanza) {
...@@ -1975,6 +1999,7 @@ ...@@ -1975,6 +1999,7 @@
template.find('form').append(this.bosh_url_input); template.find('form').append(this.bosh_url_input);
} }
this.$parent.find('#controlbox-panes').append(this.$el.html(template)); this.$parent.find('#controlbox-panes').append(this.$el.html(template));
this.$el.find('input#jid').focus();
return this; return this;
} }
}); });
...@@ -2018,9 +2043,7 @@ ...@@ -2018,9 +2043,7 @@
this.connection.xmlOutput = function (body) { console.log(body); }; this.connection.xmlOutput = function (body) { console.log(body); };
this.bare_jid = Strophe.getBareJidFromJid(this.connection.jid); this.bare_jid = Strophe.getBareJidFromJid(this.connection.jid);
this.domain = Strophe.getDomainFromJid(this.connection.jid); this.domain = Strophe.getDomainFromJid(this.connection.jid);
this.features = new this.Features();
// Sevice discovery
this.disco = new this.ServiceDiscovery();
// Set up the roster // Set up the roster
this.roster = new this.RosterItems(); this.roster = new this.RosterItems();
......
...@@ -43,18 +43,19 @@ ...@@ -43,18 +43,19 @@
<h2>Features</h2> <h2>Features</h2>
<ul> <ul>
<li>Single and multi-user chat</li> <li>Single-user chat</li>
<li>Multi-user chat in chatrooms (<a href="http://xmpp.org/extensions/xep-0045.html">XEP 45</a>)</li>
<li>vCard support (<a href="http://xmpp.org/extensions/xep-0054.html">XEP 54</a>)</li>
<li>Service discovery (<a href="http://xmpp.org/extensions/xep-0030.html">XEP 30</a>)</li>
<li>Contact rosters</li> <li>Contact rosters</li>
<li>Manually or automically subscribe to other contacts</li> <li>Manually or automically subscribe to other contacts</li>
<li>Roster item exchange (<a href="http://xmpp.org/extensions/tmp/xep-0144-1.1.html">XEP 144</a>)</li>
<li>Accept or decline contact requests</li> <li>Accept or decline contact requests</li>
<li>Roster item exchange (<a href="http://xmpp.org/extensions/tmp/xep-0144-1.1.html">XEP 144</a>)</li>
<li>Chat statuses (online, busy, away, offline)</li> <li>Chat statuses (online, busy, away, offline)</li>
<li>Custom status messages</li> <li>Custom status messages</li>
<li>Typing notifications</li> <li>Typing notifications</li>
<li>Third person messages (/me )</li> <li>Third person messages (/me )</li>
<li>Multi-user chat in chatrooms (<a href="http://xmpp.org/extensions/xep-0045.html">XEP 45</a>)</li>
<li>Chatroom Topics</li> <li>Chatroom Topics</li>
<li>vCard support (<a href="http://xmpp.org/extensions/xep-0054.html">XEP 54</a>)</li>
</ul> </ul>
<h2>CMS Integration</h2> <h2>CMS Integration</h2>
...@@ -76,7 +77,7 @@ ...@@ -76,7 +77,7 @@
<h2>Demo</h2> <h2>Demo</h2>
<p><a href="#" class="chat toggle-online-users">Click this link</a> or click the link on the bottom right corner of this page.</a></p> <p><a href="#" class="chat toggle-online-users">Click this link</a> or click the link on the bottom right corner of this page.</a></p>
<p> <pbraries/strophe.js>
You can log in with any existing federated Jabber/XMPP account, or create a new one at any of these providers: You can log in with any existing federated Jabber/XMPP account, or create a new one at any of these providers:
<ul> <ul>
<li><a href="http://jabber.org" target="_blank">jabber.org</a></li> <li><a href="http://jabber.org" target="_blank">jabber.org</a></li>
......
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