From 38db959e1112a74c31ae1097ecc9765ed2761715 Mon Sep 17 00:00:00 2001 From: JC Brand Date: Wed, 2 Nov 2016 13:13:49 +0000 Subject: [PATCH] Reconnection fixes. Fixes #712 - Remove groupviews, so that they'll get recreated upon reconnection - Don't call `clearSession` when reconnecting. We want to reuse the Backbone collections. - Emit `rosterInitialized` event and use that in converse-rosterview.js (instead of overriding). - Refactor `onReconnected` to emit `rosterReadyAfterReconnection`, call `converse.populateRoster()` and `converse.chatboxes.onConnected()`. - Recreate the roster view on the `rosterReadyAfterReconnection` event. --- docs/CHANGES.md | 1 + docs/source/events.rst | 15 +++++++++++++ src/converse-controlbox.js | 6 +++++- src/converse-core.js | 43 ++++++++++++++++++++------------------ src/converse-rosterview.js | 25 ++++++++++++---------- 5 files changed, 58 insertions(+), 32 deletions(-) diff --git a/docs/CHANGES.md b/docs/CHANGES.md index ac192132b..306d8a9dd 100755 --- a/docs/CHANGES.md +++ b/docs/CHANGES.md @@ -10,6 +10,7 @@ - Add support for XEP-0048, chat room bookmarks [jcbrand] - New configuration setting [connection_options](https://conversejs.org/docs/html/configuration.html#connection_options) [jcbrand] - #203 New configuration setting [muc_domain](https://conversejs.org/docs/html/configuration.html#muc_domain) [jcbrand] +- #712 Controlbox clicks stop responding after auto-reconnect [jcbrand] ## 2.0.0 (2016-09-16) - #656 Online users count not shown initially [amanzur] diff --git a/docs/source/events.rst b/docs/source/events.rst index 93ecad74b..0af22547d 100644 --- a/docs/source/events.rst +++ b/docs/source/events.rst @@ -196,6 +196,14 @@ Triggered once roster groups have been fetched. Used by the `converse-rosterview.js` plugin to know when it can start alphabetically position roster groups. +rosterInitialized +~~~~~~~~~~~~~~~~~ + +The Backbone collections `RosterContacts` and `RosterGroups` have been created, +but not yet populated with data. + +This event is useful when you want to create views for these collections. + rosterPush ~~~~~~~~~~ @@ -203,6 +211,13 @@ When the roster receives a push event from server. (i.e. New entry in your buddy ``converse.listen.on('rosterPush', function (event, items) { ... });`` +rosterReadyAfterReconnection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Similar to `rosterInitialized`, but instead pertaining to reconnection. This +event indicates that the Backbone collections representing the roster and its +groups are now again available after converse.js has reconnected. + statusInitialized ~~~~~~~~~~~~~~~~~ diff --git a/src/converse-controlbox.js b/src/converse-controlbox.js index f8375a720..be9dca45b 100644 --- a/src/converse-controlbox.js +++ b/src/converse-controlbox.js @@ -121,7 +121,11 @@ this.rosterview.unregisterHandlers(); // Removes roster groups this.rosterview.model.off().reset(); - this.rosterview.undelegateEvents().remove(); + this.rosterview.each(function (groupview) { + groupview.removeAll(); + groupview.remove(); + }); + this.rosterview.remove(); } }, diff --git a/src/converse-core.js b/src/converse-core.js index ede2869db..9597e7abb 100755 --- a/src/converse-core.js +++ b/src/converse-core.js @@ -399,7 +399,6 @@ converse.connection.reconnecting = true; converse.connection.disconnect('re-connecting'); converse.connection.reset(); - converse.clearSession(); converse._tearDown(); if (converse.authentication !== "prebind") { converse.autoLogin(); @@ -597,25 +596,6 @@ } }; - this.afterReconnected = function () { - this.registerPresenceHandler(); - this.chatboxes.registerMessageHandler(); - this.xmppstatus.sendPresence(); - this.giveFeedback(__('Contacts')); - }; - - this.onReconnected = function () { - // We need to re-register all the event handlers on the newly - // created connection. - var deferred = new $.Deferred(); - converse.initStatus().done(function () { - converse.afterReconnected(); - deferred.resolve(); - }); - converse.emit('reconnected'); - return deferred.promise(); - }; - this.enableCarbons = function () { /* Ask the XMPP server to enable Message Carbons * See XEP-0280 https://xmpp.org/extensions/xep-0280.html#enabling @@ -641,12 +621,16 @@ }; this.initRoster = function () { + /* Initialize the Bakcbone collections that represent the contats + * roster and the roster groups. + */ converse.roster = new converse.RosterContacts(); converse.roster.browserStorage = new Backbone.BrowserStorage.session( b64_sha1('converse.contacts-'+converse.bare_jid)); converse.rostergroups = new converse.RosterGroups(); converse.rostergroups.browserStorage = new Backbone.BrowserStorage.session( b64_sha1('converse.roster.groups'+converse.bare_jid)); + converse.emit('rosterInitialized'); }; this.populateRoster = function () { @@ -736,6 +720,25 @@ converse.emit('ready'); // BBB: Will be removed. }; + this.onReconnected = function () { + /* Called when converse has succesfully reconnected to the XMPP + * server after the session was dropped. + * Similar to the `onConnected` method, but skips a few unnecessary + * steps. + */ + converse.setUserJid(); + converse.registerPresenceHandler(); + converse.chatboxes.registerMessageHandler(); + // Give event handlers a chance to register views for the roster + // and its groups, before we start populating. + converse.emit('rosterReadyAfterReconnection'); + converse.populateRoster(); + converse.chatboxes.onConnected(); + converse.xmppstatus.sendPresence(); + converse.emit('reconnected'); + converse.giveFeedback(__('Contacts')); + }; + this.RosterContact = Backbone.Model.extend({ initialize: function (attributes, options) { diff --git a/src/converse-rosterview.js b/src/converse-rosterview.js index ecc52b7c2..81c2f0e50 100644 --- a/src/converse-rosterview.js +++ b/src/converse-rosterview.js @@ -52,17 +52,6 @@ this.__super__.afterReconnected.apply(this, arguments); }, - initRoster: function () { - /* Create an instance of RosterView once the RosterGroups - * collection has been created (in converse-core.js) - */ - this.__super__.initRoster.apply(this, arguments); - converse.rosterview = new converse.RosterView({ - 'model': converse.rostergroups - }); - converse.rosterview.render(); - }, - RosterGroups: { comparator: function () { // RosterGroupsComparator only gets set later (once i18n is @@ -900,6 +889,20 @@ } } }); + + /* -------- Event Handlers ----------- */ + + var initRoster = function () { + /* Create an instance of RosterView once the RosterGroups + * collection has been created (in converse-core.js) + */ + converse.rosterview = new converse.RosterView({ + 'model': converse.rostergroups + }); + converse.rosterview.render(); + }; + converse.on('rosterInitialized', initRoster); + converse.on('rosterReadyAfterReconnection', initRoster); } }); }));