From 9a66619db33fca5f0cb81d9f6bfeb0fb0290cf68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20K=C3=BChn?= Date: Tue, 17 Sep 2019 15:10:01 +0000 Subject: [PATCH] [FIX] mail: no wait init_messaging before loading webclient MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this commit, discuss widgets had to wait for the route `mail/init_messaging`. This behaviour slowed down the loading of the web client. This commit solves the issue by rendering discuss widgets even when `mail/init_messaging` hasn't been resolved. For instance, the messaging menu displays a spinner until messaging becomes ready. Task-Id 2072835 closes odoo/odoo#37031 Signed-off-by: Alexandre Kühn (aku) --- addons/mail/static/src/js/discuss.js | 134 ++++++++++-------- .../services/mail_document_thread_manager.js | 2 +- .../static/src/js/services/mail_manager.js | 7 +- .../src/js/systray/systray_activity_menu.js | 3 - .../src/js/systray/systray_messaging_menu.js | 25 +++- addons/mail/static/src/js/thread_field.js | 26 +++- addons/mail/static/src/scss/discuss.scss | 12 ++ addons/mail/static/src/xml/discuss.xml | 9 +- addons/mail/static/src/xml/systray.xml | 2 +- addons/mail/static/tests/discuss_tests.js | 50 +++++++ .../systray/systray_messaging_menu_tests.js | 47 ++++++ 11 files changed, 241 insertions(+), 76 deletions(-) diff --git a/addons/mail/static/src/js/discuss.js b/addons/mail/static/src/js/discuss.js index 0c1a39e7b9f..483a1e99d29 100644 --- a/addons/mail/static/src/js/discuss.js +++ b/addons/mail/static/src/js/discuss.js @@ -281,6 +281,8 @@ var Discuss = AbstractAction.extend({ this.options.channelQuickSearchThreshold = 20; } + this._isMessagingReady = this.call('mail_service', 'isReady'); + this._isStarted = false; this._threadsScrolltop = {}; this._composerStates = {}; this._defaultThreadID = this.options.active_id || @@ -292,68 +294,20 @@ var Discuss = AbstractAction.extend({ this._updateThreads.bind(this), 100, { leading: false }); this.controlPanelParams.modelName = 'mail.message'; - }, - /** - * @override - */ - willStart: function () { - return Promise.all([this._super(), this.call('mail_service', 'isReady')]); + this.call('mail_service', 'getMailBus').on('messaging_ready', this, this._onMessagingReady); }, /** * @override */ start: function () { var self = this; - - this._basicComposer = new BasicComposer(this, { - mentionPartnersRestricted: true, - showTyping: true, + this._isStarted = true; + return this._super.apply(this, arguments).then(function () { + if (!self._isMessagingReady) { + return; + } + return self._initRender(); }); - this._extendedComposer = new ExtendedComposer(this, { - mentionPartnersRestricted: true, - showTyping: true, - }); - this._basicComposer - .on('post_message', this, this._onPostMessage) - .on('input_focused', this, this._onComposerFocused); - this._extendedComposer - .on('post_message', this, this._onPostMessage) - .on('input_focused', this, this._onComposerFocused); - this._renderButtons(); - - var defs = []; - defs.push( - this._renderThread() - ); - defs.push( - this._basicComposer.appendTo(this.$('.o_mail_discuss_content'))); - defs.push( - this._extendedComposer.appendTo(this.$('.o_mail_discuss_content'))); - defs.push(this._super.apply(this, arguments)); - - return Promise.all(defs) - .then(function () { - return self._setThread(self._defaultThreadID); - }) - .then(function () { - self._initThreads(); - self._startListening(); - self._threadWidget.$el.on('scroll', null, _.debounce(function () { - if ( - self._threadWidget.getScrolltop() < 20 && - !self._threadWidget.$('.o_mail_no_content').length && - !self._thread.isAllHistoryLoaded(self.domain) - ) { - self._loadMoreMessages(); - } - if ( - self._threadWidget.isAtBottom() && - self._thread.getType() !== 'mailbox' - ) { - self._thread.markAsRead(); - } - }, 100)); - }); }, /** * @override @@ -382,8 +336,8 @@ var Discuss = AbstractAction.extend({ this.call('mail_service', 'getMailBus').trigger('discuss_open', true); if (this._thread) { this._threadWidget.scrollToPosition(this._threadsScrolltop[this._thread.getID()]); + this._loadEnoughMessages(); } - this._loadEnoughMessages(); }, /** * @override @@ -547,6 +501,60 @@ var Discuss = AbstractAction.extend({ } } }, + /** + * @private + */ + _initRender: function () { + var self = this; + this._basicComposer = new BasicComposer(this, { + mentionPartnersRestricted: true, + showTyping: true, + }); + this._extendedComposer = new ExtendedComposer(this, { + mentionPartnersRestricted: true, + showTyping: true, + }); + this._basicComposer + .on('post_message', this, this._onPostMessage) + .on('input_focused', this, this._onComposerFocused); + this._extendedComposer + .on('post_message', this, this._onPostMessage) + .on('input_focused', this, this._onComposerFocused); + this._renderButtons(); + + var defs = []; + defs.push( + this._renderThread() + ); + defs.push( + this._basicComposer.appendTo(this.$('.o_mail_discuss_content'))); + defs.push( + this._extendedComposer.appendTo(this.$('.o_mail_discuss_content'))); + + return Promise.all(defs) + .then(function () { + return self._setThread(self._defaultThreadID); + }) + .then(function () { + self._initThreads(); + self._startListening(); + self._threadWidget.$el.on('scroll', null, _.debounce(function () { + if ( + self._threadWidget.getScrolltop() < 20 && + !self._threadWidget.$('.o_mail_no_content').length && + !self._thread.isAllHistoryLoaded(self.domain) + ) { + self._loadMoreMessages(); + } + if ( + self._threadWidget.isAtBottom() && + self._thread.getType() !== 'mailbox' + ) { + self._thread.markAsRead(); + } + }, 100)); + }); + }, /** * Renders the mainside bar with current threads * @@ -1401,6 +1409,20 @@ var Discuss = AbstractAction.extend({ this._fetchAndRenderThread(); } }, + /** + * @private + */ + _onMessagingReady: function () { + if (this._isMessagingReady) { + return; + } + this._isMessagingReady = true; + if (!this._isStarted) { + return; + } + this.$('.o_mail_discuss_loading').remove(); + this._initRender(); + }, /** * @private * @param {MouseEvent} ev diff --git a/addons/mail/static/src/js/services/mail_document_thread_manager.js b/addons/mail/static/src/js/services/mail_document_thread_manager.js index 6bb66b1b439..652567baf14 100644 --- a/addons/mail/static/src/js/services/mail_document_thread_manager.js +++ b/addons/mail/static/src/js/services/mail_document_thread_manager.js @@ -34,7 +34,7 @@ MailManager.include({ this.call('local_storage', 'getItem', key); } } - this.isReady().then(this._updateDocumentThreadWindows.bind(this, this._documentThreadWindowStates)); + this._mailBus.on('messaging_ready', this, this._updateDocumentThreadWindows.bind(this, this._documentThreadWindowStates)); // listen to localStorage changes to synchronize DocumentThread's // windows between tabs this.call('local_storage', 'onStorage', this, this._onStorage); diff --git a/addons/mail/static/src/js/services/mail_manager.js b/addons/mail/static/src/js/services/mail_manager.js index 3ed4031abeb..950ac8c5cd6 100644 --- a/addons/mail/static/src/js/services/mail_manager.js +++ b/addons/mail/static/src/js/services/mail_manager.js @@ -46,6 +46,7 @@ var PREVIEW_MSG_MAX_SIZE = 350; // optimal for native english speakers var MailManager = AbstractService.extend({ dependencies: ['ajax', 'bus_service', 'local_storage'], + _isReady: false, _ODOOBOT_ID: ["ODOOBOT", "ODOOBOT"], // authorID for transient messages /** @@ -294,7 +295,7 @@ var MailManager = AbstractService.extend({ * This is the case when it has fetched the initial state from the server, * by means of the route 'mail/init_messaging' * - * @returns {Promise} + * @returns {boolean} */ isReady: function () { return this._isReady; @@ -636,7 +637,7 @@ var MailManager = AbstractService.extend({ */ _fetchMailStateFromServer: function () { var self = this; - this._isReady = session.is_bound.then(function () { + session.is_bound.then(function () { var context = _.extend( { isMobile: config.device.isMobile }, session.user_context @@ -648,6 +649,8 @@ var MailManager = AbstractService.extend({ }).then(function (result) { self._updateInternalStateFromServer(result); self.call('bus_service', 'startPolling'); + self._isReady = true; + self._mailBus.trigger('messaging_ready'); }); }, /** diff --git a/addons/mail/static/src/js/systray/systray_activity_menu.js b/addons/mail/static/src/js/systray/systray_activity_menu.js index 641ff4be1bc..8afa88d7e20 100644 --- a/addons/mail/static/src/js/systray/systray_activity_menu.js +++ b/addons/mail/static/src/js/systray/systray_activity_menu.js @@ -19,9 +19,6 @@ var ActivityMenu = Widget.extend({ 'click .o_mail_preview': '_onActivityFilterClick', 'show.bs.dropdown': '_onActivityMenuShow', }, - willStart: function () { - return Promise.resolve(this.call('mail_service', 'isReady')); - }, start: function () { this._$activitiesPreview = this.$('.o_mail_systray_dropdown_items'); this.call('mail_service', 'getMailBus').on('activity_updated', this, this._updateCounter); diff --git a/addons/mail/static/src/js/systray/systray_messaging_menu.js b/addons/mail/static/src/js/systray/systray_messaging_menu.js index 4dacae435d4..93024b3b057 100644 --- a/addons/mail/static/src/js/systray/systray_messaging_menu.js +++ b/addons/mail/static/src/js/systray/systray_messaging_menu.js @@ -26,12 +26,6 @@ var MessagingMenu = Widget.extend({ 'click .o_mail_preview_mark_as_read': '_onClickPreviewMarkAsRead', 'show.bs.dropdown': '_onShowDropdown', }, - /** - * @override - */ - willStart: function () { - return Promise.all([this._super.apply(this, arguments), this.call('mail_service', 'isReady')]); - }, /** * @override */ @@ -39,8 +33,10 @@ var MessagingMenu = Widget.extend({ this._$filterButtons = this.$('.o_filter_button'); this._$previews = this.$('.o_mail_systray_dropdown_items'); this._filter = false; + this._isMessagingReady = this.call('mail_service', 'isReady'); this._updateCounter(); var mailBus = this.call('mail_service', 'getMailBus'); + mailBus.on('messaging_ready', this, this._onMessagingReady); mailBus.on('update_needaction', this, this._updateCounter); mailBus.on('new_channel', this, this._updateCounter); mailBus.on('update_thread_unread_counter', this, this._updateCounter); @@ -206,6 +202,9 @@ var MessagingMenu = Widget.extend({ _updatePreviews: function () { // Display spinner while waiting for conversations preview this._$previews.html(QWeb.render('Spinner')); + if (!this._isMessagingReady) { + return; + } this._getPreviews() .then(this._renderPreviews.bind(this)); }, @@ -228,7 +227,11 @@ var MessagingMenu = Widget.extend({ * @private */ _updateCounter: function () { + if (!this._isMessagingReady) { + return; + } var counter = this._computeCounter(); + this.$('.o_mail_messaging_menu_icon').removeClass('fa-spinner fa-spin'); this.$('.o_notification_counter').text(counter); this.$el.toggleClass('o_no_notification', !counter); if (this._isShown()) { @@ -324,6 +327,16 @@ var MessagingMenu = Widget.extend({ } } }, + /** + * @private + */ + _onMessagingReady: function () { + if (this._isMessagingReady) { + return; + } + this._isMessagingReady = true; + this._updateCounter(); + }, }); // Systray menu items display order matches order in the list diff --git a/addons/mail/static/src/js/thread_field.js b/addons/mail/static/src/js/thread_field.js index ab8023b06ad..c8a59850016 100644 --- a/addons/mail/static/src/js/thread_field.js +++ b/addons/mail/static/src/js/thread_field.js @@ -20,23 +20,21 @@ var ThreadField = AbstractField.extend({ */ init: function () { this._super.apply(this, arguments); + this._isMessagingReady = this.call('mail_service', 'isReady'); + this._isStarted = false; + this.call('mail_service', 'getMailBus').on('messaging_ready', this, this._onMessagingReady); // Used to automatically mark document thread as read at the moment we // access the document and render the thread. this._markAsReadOnNextRender = false; this._setDocumentThread(); }, - /** - * @override - */ - willStart: function () { - return this.alive(this.call('mail_service', 'isReady')); - }, /** * @override */ start: function () { var self = this; + this._isStarted = true; this.dp = new concurrency.DropPrevious(); this._threadWidget = new ThreadWidget(this, { @@ -159,6 +157,9 @@ var ThreadField = AbstractField.extend({ * If it is a new document in create mode, unset the document thread. */ _setDocumentThread: function () { + if (!this._isMessagingReady) { + return; + } var params = { messageIDs: this.value.res_ids, name: this.recordData.display_name, @@ -185,6 +186,19 @@ var ThreadField = AbstractField.extend({ _onLoadMoreMessages: function () { this._fetchAndRenderThread({ forceFetch: true }); }, + /** + * @private + */ + _onMessagingReady: function () { + if (this._isMessagingReady) { + return; + } + this._isMessagingReady = true; + if (!this._isStarted) { + return; + } + this._setDocumentThread(); + }, /** * @private * @param {mail.model.Message} diff --git a/addons/mail/static/src/scss/discuss.scss b/addons/mail/static/src/scss/discuss.scss index 0c76829d732..6096d2003cf 100644 --- a/addons/mail/static/src/scss/discuss.scss +++ b/addons/mail/static/src/scss/discuss.scss @@ -7,6 +7,18 @@ height: 100%; overflow: hidden; + .o_mail_discuss_loading { + display: flex; + flex: 1 1 auto; + align-items: center; + justify-content: center; + min-height: 100%; + + > i { + margin-right: 5px; + } + } + .o_mail_discuss_sidebar { width: $o-mail-chat-sidebar-width; height: 100%; diff --git a/addons/mail/static/src/xml/discuss.xml b/addons/mail/static/src/xml/discuss.xml index a4637ad9e02..87d98bc3c49 100644 --- a/addons/mail/static/src/xml/discuss.xml +++ b/addons/mail/static/src/xml/discuss.xml @@ -8,8 +8,15 @@ -->
-
+
+
+ Please wait... +
+
+
+ Please wait... +
diff --git a/addons/mail/static/src/xml/systray.xml b/addons/mail/static/src/xml/systray.xml index db591b31c59..a5677f9da9f 100644 --- a/addons/mail/static/src/xml/systray.xml +++ b/addons/mail/static/src/xml/systray.xml @@ -7,7 +7,7 @@