diff options
| author | Sébastien Theys <seb@odoo.com> | 2020-08-06 09:28:57 +0000 |
|---|---|---|
| committer | Sébastien Theys <seb@odoo.com> | 2020-08-06 13:27:38 +0000 |
| commit | bab20931099beda872aa17e5bb0ddd18cffd83ed (patch) | |
| tree | 44bf347191bc6473d9c7eea6a8244b8831834d54 /addons/mail/static/src | |
| parent | 7b51aaa1cac3b640861456888773d926bdc501f4 (diff) | |
[FIX] mail: process result of init messaging asynchronously
Part of task-2308312
closes odoo/odoo#55562
X-original-commit: bdc2a9f516562c854837248e7d0898e5cfc8dec1
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Diffstat (limited to 'addons/mail/static/src')
3 files changed, 44 insertions, 28 deletions
diff --git a/addons/mail/static/src/components/chat_window_manager/chat_window_manager.xml b/addons/mail/static/src/components/chat_window_manager/chat_window_manager.xml index 3ced7210da1..42405e9056b 100644 --- a/addons/mail/static/src/components/chat_window_manager/chat_window_manager.xml +++ b/addons/mail/static/src/components/chat_window_manager/chat_window_manager.xml @@ -3,17 +3,19 @@ <t t-name="mail.ChatWindowManager" owl="1"> <div class="o_ChatWindowManager"> - <!-- Note: DOM elements are ordered from left to right --> - <t t-if="env.messaging.chatWindowManager.hasHiddenChatWindows"> - <ChatWindowHiddenMenu class="o_ChatWindowManager_hiddenMenu"/> - </t> - <t t-foreach="env.messaging.chatWindowManager.allOrderedVisible" t-as="chatWindow" t-key="chatWindow.localId"> - <ChatWindow - chatWindowLocalId="chatWindow.localId" - hasCloseAsBackButton="env.messaging.device.isMobile" - isExpandable="!env.messaging.device.isMobile and !!chatWindow.thread" - isFullscreen="env.messaging.device.isMobile" - /> + <t t-if="env.messaging.isInitialized"> + <!-- Note: DOM elements are ordered from left to right --> + <t t-if="env.messaging.chatWindowManager.hasHiddenChatWindows"> + <ChatWindowHiddenMenu class="o_ChatWindowManager_hiddenMenu"/> + </t> + <t t-foreach="env.messaging.chatWindowManager.allOrderedVisible" t-as="chatWindow" t-key="chatWindow.localId"> + <ChatWindow + chatWindowLocalId="chatWindow.localId" + hasCloseAsBackButton="env.messaging.device.isMobile" + isExpandable="!env.messaging.device.isMobile and !!chatWindow.thread" + isFullscreen="env.messaging.device.isMobile" + /> + </t> </t> </div> </t> diff --git a/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js b/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js index 6da45ac49ca..38d72b4bdf0 100644 --- a/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js +++ b/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js @@ -50,7 +50,7 @@ function factory(dependencies) { route: '/mail/init_messaging', params: { context: context } })); - this._init(data); + await this.async(() => this._init(data)); if (discuss.isOpen) { discuss.openInitThread(); } @@ -78,7 +78,7 @@ function factory(dependencies) { * @param {Object[]} [param0.shortcodes=[]] * @param {integer} [param0.starred_counter=0] */ - _init({ + async _init({ channel_slots, commands = [], is_moderator = false, @@ -94,22 +94,28 @@ function factory(dependencies) { starred_counter = 0 }) { const discuss = this.messaging.discuss; + // partners first because the rest of the code relies on them this._initPartners({ moderation_channel_ids, partner_root, public_partner, }); - this._initChannels(channel_slots); - this._initCommands(commands); + // mailboxes after partners and before other initializers that might + // manipulate threads or messages this._initMailboxes({ is_moderator, moderation_counter, needaction_inbox_counter, starred_counter, }); - this._initMailFailures(mail_failures); + // various suggestions in no particular order this._initCannedResponses(shortcodes); - this._initMentionPartnerSuggestions(mention_partner_suggestions); + this._initCommands(commands); + await this.async(() => this._initMentionPartnerSuggestions(mention_partner_suggestions)); + // channels when the rest of messaging is ready + await this.async(() => this._initChannels(channel_slots)); + // failures after channels + this._initMailFailures(mail_failures); discuss.update({ menu_id }); } @@ -138,15 +144,20 @@ function factory(dependencies) { * @param {Object[]} [param0.channel_direct_message=[]] * @param {Object[]} [param0.channel_private_group=[]] */ - _initChannels({ + async _initChannels({ channel_channel = [], channel_direct_message = [], channel_private_group = [], } = {}) { const channelsData = channel_channel.concat(channel_direct_message, channel_private_group); - this.env.models['mail.thread'].insert(channelsData.map( - channelData => this.env.models['mail.thread'].convertData(channelData) - )); + for (const channelData of channelsData) { + // there might be a lot of channels, insert each of them one by + // one asynchronously to avoid blocking the UI + await this.async(() => new Promise(resolve => setTimeout(resolve))); + this.env.models['mail.thread'].insert( + this.env.models['mail.thread'].convertData(channelData) + ); + } } /** @@ -221,9 +232,12 @@ function factory(dependencies) { * @private * @param {Object[]} mentionPartnerSuggestionsData */ - _initMentionPartnerSuggestions(mentionPartnerSuggestionsData) { + async _initMentionPartnerSuggestions(mentionPartnerSuggestionsData) { for (const suggestions of mentionPartnerSuggestionsData) { for (const suggestion of suggestions) { + // there might be a lot of partners, insert each of them one + // by one asynchronously to avoid blocking the UI + await this.async(() => new Promise(resolve => setTimeout(resolve))); const { email, id, name } = suggestion; this.env.models['mail.partner'].insert({ email, id, name }); } diff --git a/addons/mail/static/src/utils/test_utils.js b/addons/mail/static/src/utils/test_utils.js index d5eec350e01..dd305be0a49 100644 --- a/addons/mail/static/src/utils/test_utils.js +++ b/addons/mail/static/src/utils/test_utils.js @@ -66,9 +66,9 @@ function _useChatWindow(callbacks) { destroy: prevDestroy, } = callbacks; return Object.assign({}, callbacks, { - mount: prevMount.concat(() => { + mount: prevMount.concat(async () => { // trigger mounting of chat window manager - Component.env.services['chat_window']._onWebClientReady(); + await Component.env.services['chat_window']._onWebClientReady(); }), destroy: prevDestroy.concat(() => { Component.env.services['chat_window'].destroy(); @@ -91,9 +91,9 @@ function _useDialog(callbacks) { destroy: prevDestroy, } = callbacks; return Object.assign({}, callbacks, { - mount: prevMount.concat(() => { + mount: prevMount.concat(async () => { // trigger mounting of dialog manager - Component.env.services['dialog']._onWebClientReady(); + await Component.env.services['dialog']._onWebClientReady(); }), destroy: prevDestroy.concat(() => { Component.env.services['dialog'].destroy(); @@ -137,7 +137,7 @@ function _useDiscuss(callbacks) { discussWidget = new DiscussWidget(widget, state.discussData); await discussWidget.appendTo($(selector)); if (state.autoOpenDiscuss) { - discussWidget.on_attach_callback(); + await discussWidget.on_attach_callback(); } }), return: prevReturn.concat(result => { @@ -165,7 +165,7 @@ function _useMessagingMenu(callbacks) { mount: prevMount.concat(async ({ selector, widget }) => { messagingMenuWidget = new MessagingMenuWidget(widget, {}); await messagingMenuWidget.appendTo($(selector)); - messagingMenuWidget.on_attach_callback(); + await messagingMenuWidget.on_attach_callback(); }), return: prevReturn.concat(result => { Object.assign(result, { messagingMenuWidget }); |
