From 68b839d0d18e3d81a108c64db995d244b7388e30 Mon Sep 17 00:00:00 2001 From: JC Brand Date: Thu, 22 Feb 2018 12:46:10 +0100 Subject: [PATCH 1/4] Add `onMultipleEvents` utility method. And use it instead of listening to multiple Promises. Promises get resolved once, which means using them doesn't work for cases where the user logs out, and then in again (because the handlers don't get called upon 2nd login). --- CHANGES.md | 1 + src/converse-bookmarks.js | 26 +++++++++----------------- src/converse-roomslist.js | 24 ++++++++++++------------ src/utils.js | 22 ++++++++++++++++++++++ 4 files changed, 44 insertions(+), 29 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 099879dd1..2c725b39a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ - Avoid `eval` (via `_.template` from lodash). - Bugfix. Avatars weren't being shown. +- Bugfix. Bookmarks list and open rooms list weren't recreated after logging in for a 2nd time (without reloading the browser). - Add LibreJS support ## 3.3.3 (2018-02-14) diff --git a/src/converse-bookmarks.js b/src/converse-bookmarks.js index f68ebccfa..8857f4431 100644 --- a/src/converse-bookmarks.js +++ b/src/converse-bookmarks.js @@ -546,25 +546,17 @@ return; } _converse.bookmarks = new _converse.Bookmarks(); - _converse.bookmarks.fetchBookmarks().then(() => { - _converse.bookmarksview = new _converse.BookmarksView( - {'model': _converse.bookmarks} - ); - }).catch(_.partial(_converse.log, _, Strophe.LogLevel.ERROR)) - .then(() => { - _converse.emit('bookmarksInitialized'); - }); - }).catch((e) => { - _converse.log(e, Strophe.LogLevel.ERROR); - _converse.emit('bookmarksInitialized'); + _converse.bookmarksview = new _converse.BookmarksView({'model': _converse.bookmarks}); + _converse.bookmarks.fetchBookmarks() + .catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)) + .then(() => _converse.emit('bookmarksInitialized')); }); - }; + } - Promise.all([ - _converse.api.waitUntil('chatBoxesFetched'), - _converse.api.waitUntil('roomsPanelRendered') - ]).then(initBookmarks) - .catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)); + u.onMultipleEvents([ + {'object': _converse, 'event': 'chatBoxesFetched'}, + {'object': _converse, 'event': 'roomsPanelRendered'} + ], initBookmarks); _converse.on('connected', () => { // Add a handler for bookmarks pushed from other connected clients diff --git a/src/converse-roomslist.js b/src/converse-roomslist.js index 73bf1fdce..ad6311c3a 100644 --- a/src/converse-roomslist.js +++ b/src/converse-roomslist.js @@ -237,18 +237,18 @@ ); }; - Promise.all([ - _converse.api.waitUntil('chatBoxesFetched'), - _converse.api.waitUntil('roomsPanelRendered') - ]).then(() => { - if (_converse.allow_bookmarks) { - _converse.api.waitUntil('bookmarksInitialized').then( - initRoomsListView - ); - } else { - initRoomsListView(); - } - }); + if (_converse.allow_bookmarks) { + u.onMultipleEvents([ + {'object': _converse, 'event': 'chatBoxesFetched'}, + {'object': _converse, 'event': 'roomsPanelRendered'}, + {'object': _converse, 'event': 'bookmarksInitialized'} + ], initRoomsListView); + } else { + u.onMultipleEvents([ + {'object': _converse, 'event': 'chatBoxesFetched'}, + {'object': _converse, 'event': 'roomsPanelRendered'} + ], initRoomsListView); + } _converse.api.listen.on('reconnected', initRoomsListView); } diff --git a/src/utils.js b/src/utils.js index 4b5278a2c..8f325b7de 100644 --- a/src/utils.js +++ b/src/utils.js @@ -654,6 +654,28 @@ }); }; + u.onMultipleEvents = function (events=[], callback) { + /* Call the callback once all the events have been triggered + * + * Parameters: + * (Array) events: An array of objects, with keys `object` and + * `event`, representing the event name and the object it's + * triggered upon. + * (Function) callback: The function to call once all events have + * been triggered. + */ + let triggered = []; + + function handler (result) { + triggered.push(result) + if (events.length === triggered.length) { + callback(triggered); + triggered = []; + } + } + _.each(events, (map) => map.object.on(map.event, handler)); + }; + u.safeSave = function (model, attributes) { if (u.isPersistableModel(model)) { model.save(attributes); From 33cfe07331e63972ba5fbb533048e9de99e4f5a0 Mon Sep 17 00:00:00 2001 From: JC Brand Date: Thu, 22 Feb 2018 13:26:06 +0100 Subject: [PATCH 2/4] Recreate promises upon logout. --- src/converse-core.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/converse-core.js b/src/converse-core.js index b2c7a1102..387d47b89 100644 --- a/src/converse-core.js +++ b/src/converse-core.js @@ -654,6 +654,9 @@ } else { _converse._tearDown(); } + // Recreate all the promises + _.each(_.keys(_converse.promises), addPromise); + _converse.emit('logout'); }; From 5e320d031d26f351cc22f60ec47143ce5a22d632 Mon Sep 17 00:00:00 2001 From: JC Brand Date: Thu, 22 Feb 2018 13:30:58 +0100 Subject: [PATCH 3/4] Don't remove the minimized chats element upon logout --- src/converse-minimize.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/converse-minimize.js b/src/converse-minimize.js index 1c1b421e6..cae24581c 100644 --- a/src/converse-minimize.js +++ b/src/converse-minimize.js @@ -536,7 +536,6 @@ const new_html = tpl_chatbox_minimize( {info_minimize: __('Minimize this chat box')} ); - const el = view.el.querySelector('.toggle-chatbox-button'); if (el) { el.outerHTML = new_html; @@ -553,11 +552,6 @@ _converse.chatboxviews.trimChats(chatbox); } }); - - const logOut = function () { - _converse.minimized_chats.remove(); - }; - _converse.on('logout', logOut); } }); })); From 1e5b6243be73733516a63c1abd75f5123ec462bf Mon Sep 17 00:00:00 2001 From: JC Brand Date: Thu, 22 Feb 2018 13:55:17 +0100 Subject: [PATCH 4/4] Don't show bookmark toggles when PEP bookmarking not supported by the XMPP server --- CHANGES.md | 1 + src/converse-bookmarks.js | 40 +++++++++++++++++++++------------------ src/converse-roomslist.js | 6 +++++- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2c725b39a..4c6f18152 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ - Avoid `eval` (via `_.template` from lodash). - Bugfix. Avatars weren't being shown. - Bugfix. Bookmarks list and open rooms list weren't recreated after logging in for a 2nd time (without reloading the browser). +- Don't show bookmark toggles when PEP bookmarking not supported by the XMPP server. - Add LibreJS support ## 3.3.3 (2018-02-14) diff --git a/src/converse-bookmarks.js b/src/converse-bookmarks.js index 8857f4431..57c09348d 100644 --- a/src/converse-bookmarks.js +++ b/src/converse-bookmarks.js @@ -87,11 +87,10 @@ this.__super__.renderHeading.apply(this, arguments); const { _converse } = this.__super__; if (_converse.allow_bookmarks) { - _converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid).then((identity) => { - if (_.isNil(identity)) { - return; + _converse.checkBookmarksSupport().then((supported) => { + if (supported) { + this.renderBookmarkToggle(); } - this.renderBookmarkToggle(); }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)); } }, @@ -530,26 +529,31 @@ } }); + _converse.checkBookmarksSupport = function () { + return new Promise((resolve, reject) => { + Promise.all([ + _converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid), + _converse.api.disco.supports(Strophe.NS.PUBSUB+'#publish-options', _converse.bare_jid) + ]).then((args) => { + resolve(args[0] && (args[1].supported || _converse.allow_public_bookmarks)); + }); + }); + } + const initBookmarks = function () { if (!_converse.allow_bookmarks) { return; } - Promise.all([ - _converse.api.disco.getIdentity('pubsub', 'pep', _converse.bare_jid), - _converse.api.disco.supports(Strophe.NS.PUBSUB+'#publish-options', _converse.bare_jid) - ]).then((args) => { - const identity = args[0], - options_support = args[1]; - - if (_.isNil(identity) || (!options_support.supported && !_converse.allow_public_bookmarks)) { + _converse.checkBookmarksSupport().then((supported) => { + if (supported) { + _converse.bookmarks = new _converse.Bookmarks(); + _converse.bookmarksview = new _converse.BookmarksView({'model': _converse.bookmarks}); + _converse.bookmarks.fetchBookmarks() + .catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)) + .then(() => _converse.emit('bookmarksInitialized')); + } else { _converse.emit('bookmarksInitialized'); - return; } - _converse.bookmarks = new _converse.Bookmarks(); - _converse.bookmarksview = new _converse.BookmarksView({'model': _converse.bookmarks}); - _converse.bookmarks.fetchBookmarks() - .catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL)) - .then(() => _converse.emit('bookmarksInitialized')); }); } diff --git a/src/converse-roomslist.js b/src/converse-roomslist.js index ad6311c3a..519e4822d 100644 --- a/src/converse-roomslist.js +++ b/src/converse-roomslist.js @@ -118,7 +118,11 @@ toHTML () { return tpl_rooms_list_item( _.extend(this.model.toJSON(), { - 'allow_bookmarks': _converse.allow_bookmarks, + // XXX: By the time this renders, the _converse.bookmarks + // collection should already exist if bookmarks are + // supported by the XMPP server. So we can use it + // as a check for support (other ways of checking are async). + 'allow_bookmarks': _converse.allow_bookmarks && _converse.bookmarks, 'info_leave_room': __('Leave this room'), 'info_remove_bookmark': __('Unbookmark this room'), 'info_add_bookmark': __('Bookmark this room'),