summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/models/composer/composer.js
diff options
context:
space:
mode:
authorSébastien Theys <seb@odoo.com>2020-11-30 15:48:12 +0000
committerSébastien Theys <seb@odoo.com>2020-11-30 15:48:12 +0000
commit661f687256995452756d6396308bcc167a5dcb9f (patch)
tree81c2186d0ad14858ad57cbd488d117148fd7c1e1 /addons/mail/static/src/models/composer/composer.js
parentd9aa362914945e6cb095b04fa94cfb3469abd907 (diff)
[FIX] mail: fix mention suggestion order and skip intermediate rpc
task-2387825 closes odoo/odoo#62393 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Diffstat (limited to 'addons/mail/static/src/models/composer/composer.js')
-rw-r--r--addons/mail/static/src/models/composer/composer.js63
1 files changed, 59 insertions, 4 deletions
diff --git a/addons/mail/static/src/models/composer/composer.js b/addons/mail/static/src/models/composer/composer.js
index 49ed975d70e..d838d066778 100644
--- a/addons/mail/static/src/models/composer/composer.js
+++ b/addons/mail/static/src/models/composer/composer.js
@@ -16,6 +16,34 @@ function factory(dependencies) {
class Composer extends dependencies['mail.model'] {
+ /**
+ * @override
+ */
+ _willCreate() {
+ const res = super._willCreate(...arguments);
+ /**
+ * Determines whether there is a mention RPC currently in progress.
+ * Useful to queue a new call if there is already one pending.
+ */
+ this._hasMentionRpcInProgress = false;
+ /**
+ * Determines the next function to execute after the current mention
+ * RPC is done, if any.
+ */
+ this._nextMentionRpcFunction = undefined;
+ return res;
+ }
+
+ /**
+ * @override
+ */
+ _willDelete() {
+ // Clears the mention queue on deleting the record to prevent
+ // unnecessary RPC.
+ this._nextMentionRpcFunction = undefined;
+ return super._willDelete(...arguments);
+ }
+
//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------
@@ -63,7 +91,7 @@ function factory(dependencies) {
mainSuggestedRecordsListName: "mainSuggestedPartners",
suggestionModelName: "mail.partner",
});
- this._updateSuggestedPartners(mentionKeyword);
+ this._executeOrQueueFunction(() => this._updateSuggestedPartners(mentionKeyword));
break;
case ':':
this.update({
@@ -71,7 +99,7 @@ function factory(dependencies) {
mainSuggestedRecordsListName: "suggestedCannedResponses",
suggestionModelName: "mail.canned_response",
});
- this._updateSuggestedCannedResponses(mentionKeyword);
+ this._executeOrQueueFunction(() => this._updateSuggestedCannedResponses(mentionKeyword));
break;
case '/':
this.update({
@@ -79,7 +107,7 @@ function factory(dependencies) {
mainSuggestedRecordsListName: "suggestedChannelCommands",
suggestionModelName: "mail.channel_command",
});
- this._updateSuggestedChannelCommands(mentionKeyword);
+ this._executeOrQueueFunction(() => this._updateSuggestedChannelCommands(mentionKeyword));
break;
case '#':
this.update({
@@ -87,7 +115,7 @@ function factory(dependencies) {
mainSuggestedRecordsListName: "suggestedChannels",
suggestionModelName: "mail.thread",
});
- this._updateSuggestedChannels(mentionKeyword);
+ this._executeOrQueueFunction(() => this._updateSuggestedChannels(mentionKeyword));
break;
}
} else {
@@ -567,6 +595,33 @@ function factory(dependencies) {
}
/**
+ * Executes the given async function, only when the last function
+ * executed by this method terminates. If there is already a pending
+ * function it is replaced by the new one. This ensures the result of
+ * these function come in the same order as the call order, and it also
+ * allows to skip obsolete intermediate calls.
+ *
+ * @private
+ * @param {function} func
+ */
+ async _executeOrQueueFunction(func) {
+ if (this._hasMentionRpcInProgress) {
+ this._nextMentionRpcFunction = func;
+ return;
+ }
+ this._hasMentionRpcInProgress = true;
+ this._nextMentionRpcFunction = undefined;
+ try {
+ await this.async(func);
+ } finally {
+ this._hasMentionRpcInProgress = false;
+ if (this._nextMentionRpcFunction) {
+ this._executeOrQueueFunction(this._nextMentionRpcFunction);
+ }
+ }
+ }
+
+ /**
* @private
* @param {string} htmlString
* @returns {string}