diff options
| author | Sébastien Theys <seb@odoo.com> | 2020-11-30 15:48:12 +0000 |
|---|---|---|
| committer | Sébastien Theys <seb@odoo.com> | 2020-11-30 15:48:12 +0000 |
| commit | 661f687256995452756d6396308bcc167a5dcb9f (patch) | |
| tree | 81c2186d0ad14858ad57cbd488d117148fd7c1e1 /addons/mail/static/src/models/composer/composer.js | |
| parent | d9aa362914945e6cb095b04fa94cfb3469abd907 (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.js | 63 |
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} |
