diff --git a/addons/mail/static/src/components/discuss_container/discuss_container.js b/addons/mail/static/src/components/discuss_container/discuss_container.js index 0105ab33d19..936de438be2 100644 --- a/addons/mail/static/src/components/discuss_container/discuss_container.js +++ b/addons/mail/static/src/components/discuss_container/discuss_container.js @@ -1,12 +1,12 @@ /** @odoo-module **/ import { useModels } from '@mail/component_hooks/use_models'; -import { useUpdate } from '@mail/component_hooks/use_update'; // ensure component is registered before-hand import '@mail/components/discuss/discuss'; +import { insertAndReplace } from '@mail/model/model_field_command'; import { getMessagingComponent } from "@mail/utils/messaging_component"; -const { Component, onWillUnmount } = owl; +const { Component, onWillDestroy } = owl; export class DiscussContainer extends Component { @@ -19,26 +19,57 @@ export class DiscussContainer extends Component { this.env = Component.env; useModels(); super.setup(); - useUpdate({ func: () => this._update() }); - onWillUnmount(() => this._willUnmount()); + onWillDestroy(() => this._willDestroy()); + this.env.services.messaging.modelManager.messagingCreatedPromise.then(async () => { + const { action } = this.props; + const initActiveId = + (action.context && action.context.active_id) || + (action.params && action.params.default_active_id) || + 'mail.box_inbox'; + this.discuss = this.messaging.discuss; + this.discuss.update({ + discussView: insertAndReplace({ + actionId: action.id, + actionManager: this.props.actionManager, + }), + initActiveId, + }); + // Wait for messaging to be initialized to make sure the system + // knows of the "init thread" if it exists. + await this.messaging.initializedPromise; + if (!this.discuss.isInitThreadHandled) { + this.discuss.update({ isInitThreadHandled: true }); + if (!this.discuss.thread) { + this.discuss.openInitThread(); + } + } + }); + /** + * When executing the discuss action while it's already opened, the + * action manager first mounts the newest DiscussContainer, then + * unmounts the oldest one. The issue is that messaging.discussView is + * updated on setup but is cleared during the unmount. This leads to + * errors because there is no discussView anymore. In order to handle + * this situation, let's keep a reference to the currentInstance so that + * we can check we're deleting the discussView only when there is no + * incoming DiscussContainer. + */ + DiscussContainer.currentInstance = this; } - _update() { - if (!this.messaging || !this.messaging.discuss) { - return; - } - this.messaging.discuss.open(); - } - - _willUnmount() { - if (this.messaging && this.messaging.discuss) { - this.messaging.discuss.close(); + _willDestroy() { + if (this.discuss && DiscussContainer.currentInstance === this) { + this.discuss.close(); } } } Object.assign(DiscussContainer, { + props: { + action: Object, + actionManager: Object, + }, components: { Discuss: getMessagingComponent('Discuss') }, template: 'mail.DiscussContainer', }); diff --git a/addons/mail/static/src/widgets/discuss/discuss.js b/addons/mail/static/src/widgets/discuss/discuss.js index 6f5a968b2f8..3da180743bb 100644 --- a/addons/mail/static/src/widgets/discuss/discuss.js +++ b/addons/mail/static/src/widgets/discuss/discuss.js @@ -1,11 +1,10 @@ /** @odoo-module **/ import { DiscussContainer } from "@mail/components/discuss_container/discuss_container"; -import { insertAndReplace } from '@mail/model/model_field_command'; import AbstractAction from 'web.AbstractAction'; -const { App, Component } = owl; +const { App } = owl; export const DiscussWidget = AbstractAction.extend({ template: 'mail.widgets.Discuss', @@ -23,31 +22,8 @@ export const DiscussWidget = AbstractAction.extend({ this._super(...arguments); this.app = undefined; - - Component.env.services.messaging.modelManager.messagingCreatedPromise.then(async () => { - const messaging = Component.env.services.messaging.modelManager.messaging; - const initActiveId = options.active_id || - (action.context && action.context.active_id) || - (action.params && action.params.default_active_id) || - 'mail.box_inbox'; - const discuss = messaging.discuss; - discuss.update({ - discussView: insertAndReplace({ - actionId: action.id, - actionManager: parent, - }), - initActiveId, - }); - // Wait for messaging to be initialized to make sure the system - // knows of the "init thread" if it exists. - await messaging.initializedPromise; - if (!discuss.isInitThreadHandled) { - discuss.update({ isInitThreadHandled: true }); - if (!discuss.thread) { - discuss.openInitThread(); - } - } - }); + this.action = action; + this.actionManager = parent; }, /** * @override {web.AbstractAction} @@ -78,6 +54,10 @@ export const DiscussWidget = AbstractAction.extend({ dev: owl.Component.env.isDebug(), translateFn: owl.Component.env._t, translatableAttributes: ["data-tooltip"], + props: { + action: this.action, + actionManager: this.actionManager, + }, }); await this.app.mount(this.el); },