diff options
| author | Xavier Dubuc <xdu@odoo.com> | 2020-09-03 16:24:19 +0000 |
|---|---|---|
| committer | Sébastien Theys <seb@odoo.com> | 2020-09-04 14:59:01 +0000 |
| commit | 8d3413ff647de8d98c6858062dd07dde4160af95 (patch) | |
| tree | 3dc134e83c874d5c7f7bf739f13a88ab986ddb1b /addons/mail/static/src/models/thread_view/thread_viewer.js | |
| parent | a5ab687be4e7890262ce9429e18dd011021513d5 (diff) | |
[FIX] mail, sms, snailmail: prevent message_fetch for hidden threads
Automatically load messages from a thread cache only if the thread cache is used
in at least one thread view.
Ensure thread viewer don't keep thread view records alive when they are not
displayed.
This change is particularly important for performance, to avoid spamming RPC at
init if many threads are opened in chat windows.
task-2310623
closes odoo/odoo#57061
X-original-commit: dd6981c7812134e0588f80a157eaba45512cd68e
Related: odoo/enterprise#12936
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Diffstat (limited to 'addons/mail/static/src/models/thread_view/thread_viewer.js')
| -rw-r--r-- | addons/mail/static/src/models/thread_view/thread_viewer.js | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/addons/mail/static/src/models/thread_view/thread_viewer.js b/addons/mail/static/src/models/thread_view/thread_viewer.js new file mode 100644 index 00000000000..da546338ca3 --- /dev/null +++ b/addons/mail/static/src/models/thread_view/thread_viewer.js @@ -0,0 +1,257 @@ +odoo.define('mail/static/src/models/thread_viewer/thread_viewer.js', function (require) { +'use strict'; + +const { registerNewModel } = require('mail/static/src/model/model_core.js'); +const { attr, many2one, one2one } = require('mail/static/src/model/model_field.js'); + +function factory(dependencies) { + + class ThreadViewer extends dependencies['mail.model'] { + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + /** + * @param {string} scrollTop + */ + saveThreadCacheScrollPositionsAsInitial(scrollTop) { + if (!this.threadCache) { + return; + } + this.update({ + threadCacheInitialScrollPositions: Object.assign({}, this.threadCacheInitialScrollPositions, { + [this.threadCache.localId]: scrollTop, + }), + }); + } + + //---------------------------------------------------------------------- + // Private + //---------------------------------------------------------------------- + + /** + * @private + * @returns {boolean} + */ + _computeHasThreadView() { + if (this.chatter) { + return this.chatter.hasThreadView; + } + if (this.chatWindow) { + return this.chatWindow.hasThreadView; + } + if (this.discuss) { + return this.discuss.hasThreadView; + } + return this.hasThreadView; + } + + /** + * @private + * @returns {string} + */ + _computeStringifiedDomain() { + if (this.chatter) { + return '[]'; + } + if (this.chatWindow) { + return '[]'; + } + if (this.discuss) { + return this.discuss.stringifiedDomain; + } + return this.stringifiedDomain; + } + + /** + * @private + * @returns {mail.thread|undefined} + */ + _computeThread() { + if (this.chatter) { + if (!this.chatter.thread) { + return [['unlink']]; + } + return [['link', this.chatter.thread]]; + } + if (this.chatWindow) { + if (!this.chatWindow.thread) { + return [['unlink']]; + } + return [['link', this.chatWindow.thread]]; + } + if (this.discuss) { + if (!this.discuss.thread) { + return [['unlink']]; + } + return [['link', this.discuss.thread]]; + } + return []; + } + + /** + * @private + * @returns {mail.thread_cache|undefined} + */ + _computeThreadCache() { + if (!this.thread) { + return [['unlink']]; + } + return [['link', this.thread.cache(this.stringifiedDomain)]]; + } + + /** + * @private + * @returns {mail.thread_viewer|undefined} + */ + _computeThreadView() { + if (!this.hasThreadView) { + return [['unlink']]; + } + if (this.threadView) { + return []; + } + return [['create']]; + } + + } + + ThreadViewer.fields = { + /** + * States the `mail.chatter` managing `this`. This field is computed + * through the inverse relation and should be considered read-only. + */ + chatter: one2one('mail.chatter', { + inverse: 'threadViewer', + }), + /** + * Serves as compute dependency. + */ + chatterHasThreadView: attr({ + related: 'chatter.hasThreadView', + }), + /** + * Serves as compute dependency. + */ + chatterThread: many2one('mail.thread', { + related: 'chatter.thread', + }), + /** + * States the `mail.chat_window` managing `this`. This field is computed + * through the inverse relation and should be considered read-only. + */ + chatWindow: one2one('mail.chat_window', { + inverse: 'threadViewer', + }), + /** + * Serves as compute dependency. + */ + chatWindowHasThreadView: attr({ + related: 'chatWindow.hasThreadView', + }), + /** + * Serves as compute dependency. + */ + chatWindowThread: many2one('mail.thread', { + related: 'chatWindow.thread', + }), + /** + * States the `mail.discuss` managing `this`. This field is computed + * through the inverse relation and should be considered read-only. + */ + discuss: one2one('mail.discuss', { + inverse: 'threadViewer', + }), + /** + * Serves as compute dependency. + */ + discussHasThreadView: attr({ + related: 'discuss.hasThreadView', + }), + /** + * Serves as compute dependency. + */ + discussStringifiedDomain: attr({ + related: 'discuss.stringifiedDomain', + }), + /** + * Serves as compute dependency. + */ + discussThread: many2one('mail.thread', { + related: 'discuss.thread', + }), + /** + * Determines whether `this.thread` should be displayed. + */ + hasThreadView: attr({ + compute: '_computeHasThreadView', + default: false, + dependencies: [ + 'chatterHasThreadView', + 'chatWindowHasThreadView', + 'discussHasThreadView', + ], + }), + /** + * Determines the domain to apply when fetching messages for `this.thread`. + */ + stringifiedDomain: attr({ + compute: '_computeStringifiedDomain', + default: '[]', + dependencies: [ + 'discussStringifiedDomain', + ], + }), + /** + * Determines the `mail.thread` that should be displayed by `this`. + */ + thread: many2one('mail.thread', { + compute: '_computeThread', + dependencies: [ + 'chatterThread', + 'chatWindowThread', + 'discussThread', + ], + }), + /** + * States the `mail.thread_cache` that should be displayed by `this`. + */ + threadCache: many2one('mail.thread_cache', { + compute: '_computeThreadCache', + dependencies: [ + 'stringifiedDomain', + 'thread', + ], + }), + /** + * 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 + * the thread cache, because scroll position may change fast so + * save is already throttled. + */ + threadCacheInitialScrollPositions: attr({ + default: {}, + }), + /** + * States the `mail.thread_view` currently displayed and managed by `this`. + */ + threadView: one2one('mail.thread_view', { + compute: '_computeThreadView', + dependencies: [ + 'hasThreadView', + ], + inverse: 'threadViewer', + isCausal: true, + }), + }; + + ThreadViewer.modelName = 'mail.thread_viewer'; + + return ThreadViewer; +} + +registerNewModel('mail.thread_viewer', factory); + +}); |
