From 8ccaf36d10d140d1bf670b8a407123c422c2ebfc Mon Sep 17 00:00:00 2001 From: Rodolpho Lima Date: Tue, 7 Nov 2023 13:12:28 +0100 Subject: [PATCH] [FIX] web_editor: abort rpc on ChatGPT dialog close Before this commit, when the ChatGPT prompt dialog was closed while waiting for a response, the "loading" overlay would be present until such response was complete. Moreover, in certain occasions, the rpc callback, called after the component was destroyed, could lead to a traceback due to reading a property of a no longer existing reference to the prompt input element (namely, in the `_unfreezeInput` method). This commit improves the user experience by unfreezing the UI on dialog close, even if a response is pending, and prevents the rpc callbacks from running after the component is destroyed. task-3586380 closes odoo/odoo#141442 Signed-off-by: Nicolas Bayet (nby) --- .../widgets/chatgpt_alternatives_dialog.js | 5 ++++- .../src/js/wysiwyg/widgets/chatgpt_dialog.js | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/chatgpt_alternatives_dialog.js b/addons/web_editor/static/src/js/wysiwyg/widgets/chatgpt_alternatives_dialog.js index ac71dc05a26..bf768dfb341 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/chatgpt_alternatives_dialog.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/chatgpt_alternatives_dialog.js @@ -1,7 +1,7 @@ /** @odoo-module **/ import { ChatGPTDialog } from '@web_editor/js/wysiwyg/widgets/chatgpt_dialog'; -import { useState } from "@odoo/owl"; +import { useState, status } from "@odoo/owl"; export class ChatGPTAlternativesDialog extends ChatGPTDialog { static template = 'web_edior.ChatGPTAlternativesDialog'; @@ -101,6 +101,9 @@ export class ChatGPTAlternativesDialog extends ChatGPTDialog { this.state.messages = []; } }); + if (status(this) === 'destroyed') { + return; + } messageIndex += 1; this.state.messagesInProgress -= 1; if (wasError) { diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/chatgpt_dialog.js b/addons/web_editor/static/src/js/wysiwyg/widgets/chatgpt_dialog.js index 285c86b0e49..3177c66c489 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/chatgpt_dialog.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/chatgpt_dialog.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { Component, useState, markup } from "@odoo/owl"; +import { Component, useState, markup, onWillDestroy, status } from "@odoo/owl"; import { useService } from "@web/core/utils/hooks"; import { Dialog } from "@web/core/dialog/dialog"; import { escape } from "@web/core/utils/strings"; @@ -19,6 +19,7 @@ export class ChatGPTDialog extends Component { setup() { this.rpc = useService('rpc'); this.state = useState({ selectedMessageId: null }); + onWillDestroy(() => this.pendingRpcPromise?.abort()); } //-------------------------------------------------------------------------- @@ -100,11 +101,18 @@ export class ChatGPTDialog extends Component { } } _generate(prompt, callback) { - return this.rpc('/web_editor/generate_text', { + const protectedCallback = (...args) => { + if (status(this) !== 'destroyed') { + delete this.pendingRpcPromise; + return callback(...args); + } + } + this.pendingRpcPromise = this.rpc('/web_editor/generate_text', { prompt, conversation_history: this.state.conversationHistory, - }, { shadow: true }) - .then(content => callback(content)) - .catch(error => callback(_t(error.data?.message || error.message), true)); + }, { shadow: true }); + return this.pendingRpcPromise + .then(content => protectedCallback(content)) + .catch(error => protectedCallback(_t(error.data?.message || error.message), true)); } }