diff --git a/docs/CHANGES.md b/docs/CHANGES.md index 5836683e1..dd74bc107 100755 --- a/docs/CHANGES.md +++ b/docs/CHANGES.md @@ -3,6 +3,8 @@ ## 2.0.1 (Unreleased) - Allow the context (i.e. `this` value) to be passed in when registering event listeners with `converse.listen.on` and `converse.listen.once`. [jcbrand] +- New event ['rosterContactsFetched'](https://conversejs.org/docs/html/development.html#rosterContactsFetched) [jcbrand] +- New event ['rosterGroupsFetched'](https://conversejs.org/docs/html/development.html#rosterGroupsFetched) [jcbrand] ## 2.0.0 (2016-09-16) - #656 Online users count not shown initially [amanzur] diff --git a/docs/source/development.rst b/docs/source/development.rst index befeb285b..77d0bb5a5 100644 --- a/docs/source/development.rst +++ b/docs/source/development.rst @@ -996,6 +996,19 @@ When the roster has been received from the XMPP server. See also the `cachedRoster` event further up, which gets called instead of `roster` if its already in `sessionStorage`. +rosterContactsFetched +~~~~~~~~~~~~~~~~~~~~~ + +Triggered once roster contacts have been fetched. Used by the +`converse-rosterview.js` plugin to know when it can start to show the roster. + +rosterGroupsFetched +~~~~~~~~~~~~~~~~~~~ + +Triggered once roster groups have been fetched. Used by the +`converse-rosterview.js` plugin to know when it can start alphabetically +position roster groups. + rosterPush ~~~~~~~~~~ diff --git a/src/converse-core.js b/src/converse-core.js index 1857ff47f..cca9d06bc 100755 --- a/src/converse-core.js +++ b/src/converse-core.js @@ -667,6 +667,19 @@ b64_sha1('converse.roster.groups'+converse.bare_jid)); }; + this.populateRoster = function () { + /* Fetch all the roster groups, and then the roster contacts. + * Emit an event after fetching is done in each case. + */ + converse.rostergroups.fetchRosterGroups().then(function () { + converse.emit('rosterGroupsFetched'); + converse.roster.fetchRosterContacts().then(function () { + converse.emit('rosterContactsFetched'); + converse.sendInitialPresence(); + }); + }); + }; + this.unregisterPresenceHandler = function () { if (typeof converse.presence_ref !== 'undefined') { converse.connection.deleteHandler(converse.presence_ref); @@ -693,6 +706,7 @@ this.onStatusInitialized = function () { this.registerIntervalHandler(); this.initRoster(); + this.populateRoster(); this.chatboxes.onConnected(); this.registerPresenceHandler(); this.giveFeedback(__('Contacts')); diff --git a/src/converse-rosterview.js b/src/converse-rosterview.js index f8120d105..2c092cb48 100644 --- a/src/converse-rosterview.js +++ b/src/converse-rosterview.js @@ -39,10 +39,7 @@ converse.rosterview = new converse.RosterView({ 'model': converse.rostergroups }); - converse.rosterview.render().populate().then(function () { - converse.rosterview.update(); - converse.sendInitialPresence(); - }); + converse.rosterview.render(); }, RosterGroups: { @@ -248,17 +245,13 @@ converse.roster.on("remove", this.update, this); this.model.on("add", this.onGroupAdd, this); this.model.on("reset", this.reset, this); - this.$roster = $(''); - // Create a model on which we can store filter properties - var model = new converse.RosterFilter(); - model.id = b64_sha1('converse.rosterfilter'+converse.bare_jid); - model.browserStorage = new Backbone.BrowserStorage.local(this.filter.id); - this.filter_view = new converse.RosterFilterView({'model': model}); - this.filter_view.model.on('change', this.updateFilter, this); - this.filter_view.model.fetch(); + converse.on('rosterGroupsFetched', this.positionFetchedGroups, this); + converse.on('rosterContactsFetched', this.update, this); + this.createRosterFilter(); }, render: function () { + this.$roster = $(''); this.$el.html(this.filter_view.render()); if (!converse.allow_contact_requests) { // XXX: if we ever support live editing of config then @@ -268,6 +261,16 @@ return this; }, + createRosterFilter: function () { + // Create a model on which we can store filter properties + var model = new converse.RosterFilter(); + model.id = b64_sha1('converse.rosterfilter'+converse.bare_jid); + model.browserStorage = new Backbone.BrowserStorage.local(this.filter.id); + this.filter_view = new converse.RosterFilterView({'model': model}); + this.filter_view.model.on('change', this.updateFilter, this); + this.filter_view.model.fetch(); + }, + updateFilter: _.debounce(function () { /* Filter the roster again. * Called whenever the filter settings have been changed or @@ -310,18 +313,6 @@ return this; }, - populate: function () { - /* Fetch the roster groups, position them and then fetch - * the roster contacts. - */ - var deferred = new $.Deferred(); - this.model.fetchRosterGroups().then(function () { - this.positionFetchedGroups.apply(this, arguments); - converse.roster.fetchRosterContacts().then(deferred.resolve); - }.bind(this)); - return deferred.promise(); - }, - filter: function (query, type) { // First we make sure the filter is restored to its // original state @@ -435,11 +426,8 @@ * positioned aren't already in inserted into the * roster DOM element. */ - if (model.length === 0) { - return; - } - model.sort(); - model.each(function (group, idx) { + this.model.sort(); + this.model.each(function (group, idx) { var view = this.get(group.get('name')); if (!view) { view = new converse.RosterGroupView({model: group});