summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/models/thread_cache/thread_cache.js
diff options
context:
space:
mode:
authorSébastien Theys <seb@odoo.com>2020-10-09 10:55:21 +0000
committerSébastien Theys <seb@odoo.com>2020-10-09 12:04:01 +0000
commitaa006658ea25abaa2b8d03003f1d4f9214fb6468 (patch)
tree06ba9046da4f2c4d6382c88a3075f3ec912b7ff9 /addons/mail/static/src/models/thread_cache/thread_cache.js
parentde62d7bae2c466b74b0d9a83398c5f031233afdb (diff)
[FIX] mail: fix discuss search filters and related issues
- don't reset `stringifiedDomain` when changing thread (this led to the control panel displaying obsolete filters) - refresh non-main cache that are currently displayed when there is a known change of messages in the same thread's main cache - refresh non-main-cache on displaying them, to fetch potentially new messages - fix discuss "select all" conditions task-2171873 task-2282374 closes odoo/odoo#59631 X-original-commit: b89dc5f949b3ad062fc4197a4152066c207e1bf9 Related: odoo/enterprise#13958 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Diffstat (limited to 'addons/mail/static/src/models/thread_cache/thread_cache.js')
-rw-r--r--addons/mail/static/src/models/thread_cache/thread_cache.js107
1 files changed, 92 insertions, 15 deletions
diff --git a/addons/mail/static/src/models/thread_cache/thread_cache.js b/addons/mail/static/src/models/thread_cache/thread_cache.js
index 080040981f2..4e2bb5208e2 100644
--- a/addons/mail/static/src/models/thread_cache/thread_cache.js
+++ b/addons/mail/static/src/models/thread_cache/thread_cache.js
@@ -20,7 +20,7 @@ function factory(dependencies) {
return;
}
if (!this.isLoaded) {
- this.update({ hasToLoadMessages: true });
+ this.update({ isCacheRefreshRequested: true });
return;
}
this.update({ isLoadingMore: true });
@@ -31,7 +31,7 @@ function factory(dependencies) {
limit,
}));
for (const threadView of this.threadViews) {
- threadView.addComponentHint('more-messages-loaded');
+ threadView.addComponentHint('more-messages-loaded', { fetchedMessages });
}
this.update({ isLoadingMore: false });
if (fetchedMessages.length < limit) {
@@ -48,14 +48,18 @@ function factory(dependencies) {
return;
}
if (!this.isLoaded) {
- this.update({ hasToLoadMessages: true });
+ this.update({ isCacheRefreshRequested: true });
return;
}
const messageIds = this.fetchedMessages.map(message => message.id);
- return this._loadMessages({
+ const fetchedMessages = this._loadMessages({
extraDomain: [['id', '>', Math.max(...messageIds)]],
limit: false,
});
+ for (const threadView of this.threadViews) {
+ threadView.addComponentHint('new-messages-loaded', { fetchedMessages });
+ }
+ return fetchedMessages;
}
//----------------------------------------------------------------------
@@ -140,8 +144,6 @@ function factory(dependencies) {
}
let messages = this.fetchedMessages;
if (this.stringifiedDomain !== '[]') {
- // AKU TODO: flag for invalidation if there are newer messages
- // in thread. task-2171873
return [['replace', messages]];
}
// main cache: adjust with newer messages
@@ -178,13 +180,34 @@ function factory(dependencies) {
* @returns {boolean}
*/
_computeHasToLoadMessages() {
- return (
- this.thread &&
- !this.thread.isTemporary &&
- this.threadViews.length > 0 &&
- !this.isLoaded &&
- !this.isLoading
- );
+ if (!this.thread) {
+ // happens during destroy or compute executed in wrong order
+ return false;
+ }
+ const wasCacheRefreshRequested = this.isCacheRefreshRequested;
+ // mark hint as processed
+ this.update({ isCacheRefreshRequested: false });
+ if (this.thread.isTemporary) {
+ // temporary threads don't exist on the server
+ return false;
+ }
+ if (!wasCacheRefreshRequested && this.threadViews.length === 0) {
+ // don't load message that won't be used
+ return false;
+ }
+ if (!wasCacheRefreshRequested && (this.isLoaded || this.isLoading)) {
+ // avoid duplicate RPC
+ return false;
+ }
+ const isMainCache = this.thread.mainCache === this;
+ if (isMainCache && (this.isLoaded || this.isLoading)) {
+ // Ignore request on the main cache if it is already loaded or
+ // loading. Indeed the main cache is automatically sync with
+ // server updates already, so there is never a need to refresh
+ // it past the first time.
+ return false;
+ }
+ return true;
}
/**
@@ -279,7 +302,31 @@ function factory(dependencies) {
if (!this.hasToLoadMessages) {
return;
}
- this._loadMessages();
+ this._loadMessages().then(fetchedMessages => {
+ for (const threadView of this.threadViews) {
+ threadView.addComponentHint('messages-loaded', { fetchedMessages });
+ }
+ });
+ }
+
+ /**
+ * Handles change of messages on this thread cache. This is useful to
+ * refresh non-main caches that are currently displayed when the main
+ * cache receives updates. This is necessary because only the main cache
+ * is aware of changes in real time.
+ */
+ _onMessagesChanged() {
+ if (!this.thread) {
+ return;
+ }
+ if (this.thread.mainCache !== this) {
+ return;
+ }
+ for (const threadView of this.thread.threadViews) {
+ if (threadView.threadCache) {
+ threadView.threadCache.update({ isCacheRefreshRequested: true });
+ }
+ }
}
}
@@ -315,15 +362,19 @@ function factory(dependencies) {
dependencies: ['threadMessages'],
}),
/**
- * Determines whether `this` should load initial messages.
+ * Determines whether `this` should load initial messages. This field is
+ * computed and should be considered read-only.
+ * @see `isCacheRefreshRequested` to request manual refresh of messages.
*/
hasToLoadMessages: attr({
compute: '_computeHasToLoadMessages',
dependencies: [
+ 'isCacheRefreshRequested',
'isLoaded',
'isLoading',
'thread',
'threadIsTemporary',
+ 'threadMainCache',
'threadViews',
],
}),
@@ -340,6 +391,14 @@ function factory(dependencies) {
default: false,
}),
/**
+ * Determines whether `this` should consider refreshing its messages.
+ * This field is a hint that may or may not lead to an actual refresh.
+ * @see `hasToLoadMessages`
+ */
+ isCacheRefreshRequested: attr({
+ default: false,
+ }),
+ /**
* Last message that has been fetched by this thread cache.
*
* This DOES NOT necessarily mean the last message linked to this thread
@@ -379,6 +438,18 @@ function factory(dependencies) {
],
}),
/**
+ * Not a real field, used to trigger `_onMessagesChanged` when one of
+ * the dependencies changes.
+ */
+ onMessagesChanged: attr({
+ compute: '_onMessagesChanged',
+ dependencies: [
+ 'messages',
+ 'thread',
+ 'threadMainCache',
+ ],
+ }),
+ /**
* Ordered list of messages that have been fetched by this cache.
*
* This DOES NOT necessarily includes all messages linked to this thread
@@ -408,6 +479,12 @@ function factory(dependencies) {
threadIsTemporary: attr({
related: 'thread.isTemporary',
}),
+ /**
+ * Serves as compute dependency.
+ */
+ threadMainCache: many2one('mail.thread_cache', {
+ related: 'thread.mainCache',
+ }),
threadMessages: many2many('mail.message', {
related: 'thread.messages',
}),