diff options
| author | Sébastien Theys <seb@odoo.com> | 2020-10-23 11:03:09 +0000 |
|---|---|---|
| committer | Sébastien Theys <seb@odoo.com> | 2020-10-23 11:03:10 +0000 |
| commit | 91ce61ba568d83190e7ed2c168fd56101474683b (patch) | |
| tree | 474e1da8fefde0a147ccc68c0f5868eeff250a45 /addons/mail/static/src/models | |
| parent | 50b8e83597ec07e091e1a4b62184e148ddcfb6c5 (diff) | |
[FIX] mail: do not return members of channels in channel_info
This PR has 3 parts:
The members fix itself, which is necessary for performance reasons especially
at init messaging, as per described in the task.
Adding the partner name in the typing payload, because due to not knowing all
members anymore, it is necessary to properly display who is typing.
Restrict restoring scroll position only if the corresponding scroll height is
available, to make the scroll feature and particularly the corresponding tests
more robust.
task-2360020
closes odoo/odoo#60091
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Diffstat (limited to 'addons/mail/static/src/models')
4 files changed, 87 insertions, 7 deletions
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 9fc0c052448..f0ed367d092 100644 --- a/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js +++ b/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js @@ -153,9 +153,17 @@ function factory(dependencies) { // 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))); - const channel = this.env.models['mail.thread'].insert( - this.env.models['mail.thread'].convertData(channelData) - ); + const convertedData = this.env.models['mail.thread'].convertData(channelData); + if (!convertedData.members) { + // channel_info does not return all members of channel for + // performance reasons, but code is expecting to know at + // least if the current partner is member of it. + // (e.g. to know when to display "invited" notification) + // Current partner can always be assumed to be a member of + // channels received at init. + convertedData.members = [['link', this.env.messaging.currentPartner]]; + } + const channel = this.env.models['mail.thread'].insert(convertedData); // flux specific: channels received at init have to be // considered pinned. task-2284357 if (!channel.isPinned) { diff --git a/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js b/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js index 4b3baded714..783b43e4f20 100644 --- a/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js +++ b/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js @@ -108,6 +108,7 @@ function factory(dependencies) { is_typing, last_message_id, partner_id, + partner_name, } = data; switch (info) { case 'channel_fetched': @@ -124,6 +125,7 @@ function factory(dependencies) { return this._handleNotificationChannelTypingStatus(channelId, { is_typing, partner_id, + partner_name, }); default: return this._handleNotificationChannelMessage(channelId, data); @@ -344,8 +346,9 @@ function factory(dependencies) { * @param {Object} param1 * @param {boolean} param1.is_typing * @param {integer} param1.partner_id + * @param {string} param1.partner_name */ - _handleNotificationChannelTypingStatus(channelId, { is_typing, partner_id }) { + _handleNotificationChannelTypingStatus(channelId, { is_typing, partner_id, partner_name }) { const channel = this.env.models['mail.thread'].findFromIdentifyingData({ id: channelId, model: 'mail.channel', @@ -353,7 +356,10 @@ function factory(dependencies) { if (!channel) { return; } - const partner = this.env.models['mail.partner'].insert({ id: partner_id }); + const partner = this.env.models['mail.partner'].insert({ + id: partner_id, + name: partner_name, + }); if (partner === this.env.messaging.currentPartner) { // Ignore management of current partner is typing notification. return; @@ -469,7 +475,15 @@ function factory(dependencies) { const convertedData = this.env.models['mail.thread'].convertData( Object.assign({ model: 'mail.channel' }, data) ); - + if (!convertedData.members) { + // channel_info does not return all members of channel for + // performance reasons, but code is expecting to know at + // least if the current partner is member of it. + // (e.g. to know when to display "invited" notification) + // Current partner can always be assumed to be a member of + // channels received through this notification. + convertedData.members = [['link', this.env.messaging.currentPartner]]; + } let channel = this.env.models['mail.thread'].findFromIdentifyingData(convertedData); const wasCurrentPartnerMember = ( channel && diff --git a/addons/mail/static/src/models/thread_view/thread_view.js b/addons/mail/static/src/models/thread_view/thread_view.js index 0c6cdf6d458..f381f3d86f9 100644 --- a/addons/mail/static/src/models/thread_view/thread_view.js +++ b/addons/mail/static/src/models/thread_view/thread_view.js @@ -80,6 +80,21 @@ function factory(dependencies) { * @private * @returns {integer|undefined} */ + _computeThreadCacheInitialScrollHeight() { + if (!this.threadCache) { + return clear(); + } + const threadCacheInitialScrollHeight = this.threadCacheInitialScrollHeights[this.threadCache.localId]; + if (threadCacheInitialScrollHeight !== undefined) { + return threadCacheInitialScrollHeight; + } + return clear(); + } + + /** + * @private + * @returns {integer|undefined} + */ _computeThreadCacheInitialScrollPosition() { if (!this.threadCache) { return clear(); @@ -264,6 +279,13 @@ function factory(dependencies) { inverse: 'threadViews', related: 'threadViewer.threadCache', }), + threadCacheInitialScrollHeight: attr({ + compute: '_computeThreadCacheInitialScrollHeight', + dependencies: [ + 'threadCache', + 'threadCacheInitialScrollHeights', + ], + }), threadCacheInitialScrollPosition: attr({ compute: '_computeThreadCacheInitialScrollPosition', dependencies: [ @@ -278,6 +300,13 @@ function factory(dependencies) { related: 'threadCache.isLoading', }), /** + * List of saved initial scroll heights of thread caches. + */ + threadCacheInitialScrollHeights: attr({ + default: {}, + related: 'threadViewer.threadCacheInitialScrollHeights', + }), + /** * List of saved initial scroll positions of thread caches. */ threadCacheInitialScrollPositions: attr({ diff --git a/addons/mail/static/src/models/thread_view/thread_viewer.js b/addons/mail/static/src/models/thread_view/thread_viewer.js index 3c643339eff..1e48e4ad805 100644 --- a/addons/mail/static/src/models/thread_view/thread_viewer.js +++ b/addons/mail/static/src/models/thread_view/thread_viewer.js @@ -13,7 +13,27 @@ function factory(dependencies) { //---------------------------------------------------------------------- /** - * @param {string} scrollTop + * @param {integer} scrollHeight + */ + saveThreadCacheScrollHeightAsInitial(scrollHeight) { + if (!this.threadCache) { + return; + } + if (this.chatter) { + // Initial scroll height is disabled for chatter because it is + // too complex to handle correctly and less important + // functionally. + return; + } + this.update({ + threadCacheInitialScrollHeights: Object.assign({}, this.threadCacheInitialScrollHeights, { + [this.threadCache.localId]: scrollHeight, + }), + }); + } + + /** + * @param {integer} scrollTop */ saveThreadCacheScrollPositionsAsInitial(scrollTop) { if (!this.threadCache) { @@ -231,6 +251,15 @@ function factory(dependencies) { ], }), /** + * Determines the initial scroll height of thread caches, which is the + * scroll height at the time the last scroll position was saved. + * Useful to only restore scroll position when the corresponding height + * is available, otherwise the restore makes no sense. + */ + threadCacheInitialScrollHeights: attr({ + default: {}, + }), + /** * Determines the initial scroll positions of thread caches. * Useful to restore scroll position on changing back to this * thread cache. Note that this is only applied when opening |
