diff --git a/mail_ux/__manifest__.py b/mail_ux/__manifest__.py index 9980c4cb..228404f0 100644 --- a/mail_ux/__manifest__.py +++ b/mail_ux/__manifest__.py @@ -30,6 +30,7 @@ "assets": { "web.assets_backend": [ "mail_ux/static/src/core/common/**/*", + "mail_ux/static/src/views/composer_onchange.js", ], }, "depends": [ diff --git a/mail_ux/static/src/views/composer_onchange.js b/mail_ux/static/src/views/composer_onchange.js new file mode 100644 index 00000000..86a71d54 --- /dev/null +++ b/mail_ux/static/src/views/composer_onchange.js @@ -0,0 +1,27 @@ +import { ORM } from "@web/core/orm_service"; +import { patch } from "@web/core/utils/patch"; + +// The composer dialog is rebuilt when an overlay (e.g. a tooltip) changes while it loads, +// which sends the same initial onchange again: reuse the pending one. +const pendingComposerOnchanges = new Map(); + +patch(ORM.prototype, { + call(model, method, args = [], kwargs = {}) { + const isInitialComposerOnchange = + model === "mail.compose.message" && + method === "onchange" && + Array.isArray(args[2]) && + !args[2].length; + if (!isInitialComposerOnchange) { + return super.call(...arguments); + } + const key = JSON.stringify([args, kwargs]); + let prom = pendingComposerOnchanges.get(key); + if (!prom) { + prom = super.call(...arguments); + pendingComposerOnchanges.set(key, prom); + prom.finally(() => pendingComposerOnchanges.delete(key)).catch(() => {}); + } + return prom.then((result) => structuredClone(result)); + }, +});