diff options
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 |
