Ver código fonte

Better service discovery support

Features are saved to localStorage so that service discovery doesn't have to
happen during every request.
JC Brand 12 anos atrás
pai
commit
e389913444
2 arquivos alterados com 62 adições e 38 exclusões
  1. 56 33
      converse.js
  2. 6 5
      index.html

+ 56 - 33
converse.js

@@ -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 @@
                 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 @@
         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 @@
                     }
                     }
                 }
                 }
             }, 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 @@
             }
             }
         },
         },
 
 
+        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 @@
                 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 @@
         }
         }
     });
     });
 
 
-    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 () {
-            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));
+            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.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(function () {
-                converse.connection.disco.info($(this).attr('jid'), null, that.onInfo, that.onError);
-            });
+            $(stanza).find('query item').each($.proxy(function (idx, item) {
+                converse.connection.disco.info(
+                    $(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) {
-                if ($(this).attr('var') == 'http://jabber.org/protocol/muc') {
-                    // This component supports MUC
-                    converse.muc_domain = $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();
-                }
-            });
+            $stanza.find('feature').each($.proxy(function (idx, feature) {
+                this.create({
+                    'var': $(feature).attr('var'),
+                    'from': $stanza.attr('from')
+                });
+            }, this));
         },
         },
 
 
         onError: function (stanza) {
         onError: function (stanza) {
@@ -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 @@
         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);
-
-        // Sevice discovery
-        this.disco = new this.ServiceDiscovery();
+        this.features = new this.Features();
 
 
         // Set up the roster
         // Set up the roster
         this.roster = new this.RosterItems();
         this.roster = new this.RosterItems();

+ 6 - 5
index.html

@@ -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 @@
 
 
     <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>