From d27546064a96daec4b764eb3bd220377ba35870c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20K=C3=BChn?= Date: Thu, 30 Jun 2022 15:13:55 +0000 Subject: [PATCH] [IMP] im_livechat, *: Refactor JS Public Livechat (step 9) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *: website_livechat This commit is a step towards refactoring the JS of public livechat, so that it reuses the same architecture as the code of Discuss. This implies code that uses JS models and OWL components. Task-2928837 closes odoo/odoo#96690 Signed-off-by: Alexandre Kühn (aku) --- addons/im_livechat/__manifest__.py | 4 - .../src/legacy/models/public_livechat.js | 57 ++-- .../legacy/models/public_livechat_message.js | 13 +- .../src/legacy/public_livechat_chatbot.js | 269 +++++++++--------- .../src/legacy/public_livechat_constants.js | 20 -- .../public_livechat_history_tracking.js | 23 -- .../src/legacy/widgets/feedback/feedback.js | 13 +- .../src/legacy/widgets/livechat_button.js | 219 +++++--------- .../public_livechat_window.js | 38 +-- .../public_livechat_window.xml | 8 +- .../static/src/models/livechat_button_view.js | 9 +- .../static/src/models/livechat_operator.js | 16 ++ .../static/src/models/messaging.js | 21 +- .../static/src/models/public_livechat.js | 71 ++++- .../models/public_livechat_feedback_view.js | 44 +++ .../src/models/public_livechat_global.js | 65 ++++- ...ic_livechat_global_notification_handler.js | 104 +++++++ .../src/models/public_livechat_window.js | 23 +- .../src/services/public_livechat_service.js | 2 +- .../static/src/legacy/public_livechat.js | 8 +- .../website_livechat_chatbot_test_script.js | 22 +- .../tours/website_livechat_chatbot_flow.js | 4 +- .../tests/tours/website_livechat_common.js | 6 +- 23 files changed, 599 insertions(+), 460 deletions(-) delete mode 100644 addons/im_livechat/static/src/legacy/public_livechat_constants.js delete mode 100644 addons/im_livechat/static/src/legacy/public_livechat_history_tracking.js create mode 100644 addons/im_livechat/static/src/models/livechat_operator.js create mode 100644 addons/im_livechat/static/src/models/public_livechat_feedback_view.js create mode 100644 addons/im_livechat/static/src/models/public_livechat_global_notification_handler.js diff --git a/addons/im_livechat/__manifest__.py b/addons/im_livechat/__manifest__.py index 564f52e7c22..e768ff89eb1 100644 --- a/addons/im_livechat/__manifest__.py +++ b/addons/im_livechat/__manifest__.py @@ -52,7 +52,6 @@ Help your customers with this chat, and analyse their feedback. 'web.assets_frontend': [ 'im_livechat/static/src/public/main.js', 'im_livechat/static/src/services/*.js', - 'im_livechat/static/src/legacy/public_livechat_history_tracking.js', 'im_livechat/static/src/legacy/public_livechat_chatbot.js', 'im_livechat/static/src/legacy/public_livechat.scss', 'im_livechat/static/src/legacy/public_livechat_chatbot.scss', @@ -74,7 +73,6 @@ Help your customers with this chat, and analyse their feedback. ], 'web.qunit_suite_tests': [ 'im_livechat/static/tests/qunit_suite_tests/components/**/*.js', - 'im_livechat/static/src/legacy/public_livechat_history_tracking.js', 'im_livechat/static/src/legacy/public_livechat_chatbot.js', ], 'web.assets_tests': [ @@ -85,7 +83,6 @@ Help your customers with this chat, and analyse their feedback. ], 'mail.assets_messaging': [ 'im_livechat/static/src/legacy/models/*', - 'im_livechat/static/src/legacy/public_livechat_constants.js', 'im_livechat/static/src/legacy/widgets/*', 'im_livechat/static/src/legacy/widgets/*/*', 'im_livechat/static/src/models/*.js', @@ -185,7 +182,6 @@ Help your customers with this chat, and analyse their feedback. 'bus/static/src/services/bus_service.js', 'bus/static/src/multi_tab_service.js', 'mail/static/src/js/utils.js', - 'im_livechat/static/src/legacy/public_livechat_history_tracking.js', 'im_livechat/static/src/legacy/public_livechat_chatbot.js', ('include', 'web._assets_helpers'), diff --git a/addons/im_livechat/static/src/legacy/models/public_livechat.js b/addons/im_livechat/static/src/legacy/models/public_livechat.js index 097060295ad..babf6c7dca1 100644 --- a/addons/im_livechat/static/src/legacy/models/public_livechat.js +++ b/addons/im_livechat/static/src/legacy/models/public_livechat.js @@ -39,10 +39,7 @@ const PublicLivechat = Class.extend(Mixins.EventDispatcherMixin, { this.setParent(params.parent); this.messaging = messaging; - this._folded = false; // threads are unfolded by default this._id = params.data.id; - this._name = params.data.name; - this._status = params.data.status || ''; /** * Initialize the internal data for typing feature on threads. @@ -112,26 +109,27 @@ const PublicLivechat = Class.extend(Mixins.EventDispatcherMixin, { this.on('message_added', this, this._onTypingMessageAdded); this.on('message_posted', this, this._onTypingMessagePosted); - - this._operatorPID = params.data.operator_pid; // Necessary for thread typing mixin to display is typing notification // bar text (at least, for the operator in the members). - this._members = [{ - id: this._operatorPID[0], - name: this._operatorPID[1] - }]; - this._uuid = params.data.uuid; + this._members = ( + this.messaging.publicLivechatGlobal.publicLivechat.operator + ? [{ + id: this.messaging.publicLivechatGlobal.publicLivechat.operator.id, + name: this.messaging.publicLivechatGlobal.publicLivechat.operator.name, + }] + : [] + ); if (params.data.message_unread_counter !== undefined) { - this.messaging.livechatButtonView.publicLivechat.update({ + this.messaging.publicLivechatGlobal.publicLivechat.update({ unreadCounter: params.data.message_unread_counter }); } if (_.isBoolean(params.data.folded)) { - this._folded = params.data.folded; + this.messaging.publicLivechatGlobal.publicLivechat.update({ isFolded: params.data.folded }); } else { - this._folded = params.data.state === 'folded'; + this.messaging.publicLivechatGlobal.publicLivechat.update({ isFolded: params.data.state === 'folded' }); } }, @@ -147,14 +145,6 @@ const PublicLivechat = Class.extend(Mixins.EventDispatcherMixin, { addMessage(message) { this.trigger('message_added', message); }, - /** - * Updates the folded state of the thread - * - * @param {boolean} folded - */ - fold(folded) { - this._folded = folded; - }, /** * @override * @returns {@im_livechat/legacy/models/public_livechat_message[]} @@ -234,8 +224,8 @@ const PublicLivechat = Class.extend(Mixins.EventDispatcherMixin, { * @returns {Promise} */ markAsRead() { - if (this.messaging.livechatButtonView.publicLivechat.unreadCounter > 0) { - this.messaging.livechatButtonView.publicLivechat.update({ unreadCounter: 0 }); + if (this.messaging.publicLivechatGlobal.publicLivechat.unreadCounter > 0) { + this.messaging.publicLivechatGlobal.publicLivechat.update({ unreadCounter: 0 }); this.trigger_up('updated_unread_counter'); return Promise.resolve(); } @@ -302,12 +292,19 @@ const PublicLivechat = Class.extend(Mixins.EventDispatcherMixin, { */ toData() { return { - folded: this._folded, + folded: this.messaging.publicLivechatGlobal.publicLivechat.isFolded, id: this._id, - message_unread_counter: this.messaging.livechatButtonView.publicLivechat.unreadCounter, - operator_pid: this._operatorPID, - name: this._name, - uuid: this._uuid, + message_unread_counter: this.messaging.publicLivechatGlobal.publicLivechat.unreadCounter, + operator_pid: ( + this.messaging.publicLivechatGlobal.publicLivechat.operator + ? [ + this.messaging.publicLivechatGlobal.publicLivechat.operator.id, + this.messaging.publicLivechatGlobal.publicLivechat.operator.name, + ] + : [] + ), + name: this.messaging.publicLivechatGlobal.publicLivechat.name, + uuid: this.messaging.publicLivechatGlobal.publicLivechat.uuid, }; }, /** @@ -345,7 +342,7 @@ const PublicLivechat = Class.extend(Mixins.EventDispatcherMixin, { */ _notifyMyselfTyping(params) { return session.rpc('/im_livechat/notify_typing', { - uuid: this._uuid, + uuid: this.messaging.publicLivechatGlobal.publicLivechat.uuid, is_typing: params.typing, }, { shadow: true }); }, @@ -433,7 +430,7 @@ const PublicLivechat = Class.extend(Mixins.EventDispatcherMixin, { * @param {mail.model.AbstractMessage} message */ _onTypingMessageAdded(message) { - const operatorID = this._operatorPID[0]; + const operatorID = this.messaging.publicLivechatGlobal.publicLivechat.operator.id; if (message.hasAuthor() && message.getAuthorID() === operatorID) { this.unregisterTyping({ partnerID: operatorID }); } diff --git a/addons/im_livechat/static/src/legacy/models/public_livechat_message.js b/addons/im_livechat/static/src/legacy/models/public_livechat_message.js index 90026ed771d..2691249db6c 100644 --- a/addons/im_livechat/static/src/legacy/models/public_livechat_message.js +++ b/addons/im_livechat/static/src/legacy/models/public_livechat_message.js @@ -18,6 +18,7 @@ const PublicLivechatMessage = Class.extend({ /** * @param {@im_livechat/legacy/widgets/livechat_button} parent + * @param {Messaging} messaging * @param {Object} data * @param {Array} [data.attachment_ids=[]] * @param {Array} [data.author_id] @@ -28,11 +29,9 @@ const PublicLivechatMessage = Class.extend({ * @param {boolean} [data.is_discussion = false] * @param {boolean} [data.is_notification = false] * @param {string} [data.message_type = undefined] - * @param {Object} options - * @param {string} options.default_username - * @param {string} options.serverURL */ - init(parent, data, options) { + init(parent, messaging, data) { + this.messaging = messaging; // Attachments are not supported in (public) livechat. // We ignore data from server, otherwise field commands // will be wrongly considered as unamed attachments. @@ -50,10 +49,10 @@ const PublicLivechatMessage = Class.extend({ this._attachmentIDs.forEach(function (attachment) { attachment.filename = attachment.filename || attachment.name || _t("unnamed"); }); - this._defaultUsername = options.default_username; - this._serverURL = options.serverURL; + this._defaultUsername = this.messaging.publicLivechatGlobal.options.default_username; + this._serverURL = this.messaging.publicLivechatGlobal.livechatButtonView.serverUrl; - if (parent.messaging.livechatButtonView.isChatbot) { + if (parent.messaging.publicLivechatGlobal.livechatButtonView.isChatbot) { this._chatbotStepId = data.chatbot_script_step_id; this._chatbotStepAnswers = data.chatbot_step_answers; this._chatbotStepAnswerId = data.chatbot_selected_answer_id; diff --git a/addons/im_livechat/static/src/legacy/public_livechat_chatbot.js b/addons/im_livechat/static/src/legacy/public_livechat_chatbot.js index 96a5af9ac29..5fa95daaf87 100644 --- a/addons/im_livechat/static/src/legacy/public_livechat_chatbot.js +++ b/addons/im_livechat/static/src/legacy/public_livechat_chatbot.js @@ -51,40 +51,40 @@ const QWeb = core.qweb; async willStart() { const superResult = await this._super(...arguments); - if (this.messaging.livechatButtonView.rule && !!this.messaging.livechatButtonView.rule.chatbot) { + if (this.messaging.publicLivechatGlobal.livechatButtonView.rule && !!this.messaging.publicLivechatGlobal.livechatButtonView.rule.chatbot) { // noop - } else if (this.messaging.livechatButtonView.history !== null && this.messaging.livechatButtonView.history.length === 0) { - this.messaging.livechatButtonView.update({ livechatInit: await session.rpc('/im_livechat/init', {channel_id: this.messaging.livechatButtonView.channelId}) }); - } else if (this.messaging.livechatButtonView.history !== null && this.messaging.livechatButtonView.history.length !== 0) { + } else if (this.messaging.publicLivechatGlobal.livechatButtonView.history !== null && this.messaging.publicLivechatGlobal.livechatButtonView.history.length === 0) { + this.messaging.publicLivechatGlobal.livechatButtonView.update({ livechatInit: await session.rpc('/im_livechat/init', {channel_id: this.messaging.publicLivechatGlobal.livechatButtonView.channelId}) }); + } else if (this.messaging.publicLivechatGlobal.livechatButtonView.history !== null && this.messaging.publicLivechatGlobal.livechatButtonView.history.length !== 0) { const sessionCookie = utils.get_cookie('im_livechat_session'); if (sessionCookie) { - this.messaging.livechatButtonView.update({ sessionCookie }); - if (localStorage.getItem(this.messaging.livechatButtonView.chatbotSessionCookieKey)) { - this.messaging.livechatButtonView.update({ chatbotState: 'restore_session' }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ sessionCookie }); + if (localStorage.getItem(this.messaging.publicLivechatGlobal.livechatButtonView.chatbotSessionCookieKey)) { + this.messaging.publicLivechatGlobal.livechatButtonView.update({ chatbotState: 'restore_session' }); } } } - if (this.messaging.livechatButtonView.chatbotState === 'init') { + if (this.messaging.publicLivechatGlobal.livechatButtonView.chatbotState === 'init') { // we landed on a website page where a channel rule is configured to run a chatbot.script // -> initialize necessary state - if (this.messaging.livechatButtonView.rule.chatbot_welcome_steps && this.messaging.livechatButtonView.rule.chatbot_welcome_steps.length !== 0) { - this.messaging.livechatButtonView.chatbot.update({ + if (this.messaging.publicLivechatGlobal.livechatButtonView.rule.chatbot_welcome_steps && this.messaging.publicLivechatGlobal.livechatButtonView.rule.chatbot_welcome_steps.length !== 0) { + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.update({ currentStep: insertAndReplace({ - data: this.messaging.livechatButtonView.chatbot.lastWelcomeStep, + data: this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.lastWelcomeStep, }), }); } - } else if (this.messaging.livechatButtonView.chatbotState === 'welcome') { + } else if (this.messaging.publicLivechatGlobal.livechatButtonView.chatbotState === 'welcome') { // we landed on a website page and a chatbot script was initialized on a previous one // however the end-user did not interact with the bot ( :( ) // -> remove cookie to force opening the popup again // -> initialize necessary state // -> batch welcome message (see '_sendWelcomeChatbotMessage') utils.set_cookie('im_livechat_auto_popup', '', -1); - this.messaging.livechatButtonView.update({ history: clear() }); - this.messaging.livechatButtonView.update({ rule: this.messaging.livechatButtonView.livechatInit.rule }); - } else if (this.messaging.livechatButtonView.chatbotState === 'restore_session') { + this.messaging.publicLivechatGlobal.livechatButtonView.update({ history: clear() }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ rule: this.messaging.publicLivechatGlobal.livechatButtonView.livechatInit.rule }); + } else if (this.messaging.publicLivechatGlobal.livechatButtonView.chatbotState === 'restore_session') { // we landed on a website page and a chatbot script is currently running // -> restore the user's session (see '_chatbotRestoreSession') this._chatbotRestoreSession(); @@ -107,8 +107,8 @@ const QWeb = core.qweb; _chatbotAddMessage(message, options) { message.body = utils.Markup(message.body); this._addMessage(message, options); - if (this.messaging.livechatButtonView.chatWindow.legacyChatWindow._thread._folded || !this.messaging.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.isAtBottom()) { - this.messaging.livechatButtonView.publicLivechat.update({ unreadCounter: increment() }); + if (this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._thread._folded || !this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.isAtBottom()) { + this.messaging.publicLivechatGlobal.publicLivechat.update({ unreadCounter: increment() }); } if (!options || !options.skipRenderMessages) { @@ -136,7 +136,7 @@ const QWeb = core.qweb; } else { this._chatbotSetIsTyping(); this.nextStepTimeout = setTimeout( - this._chatbotTriggerNextStep.bind(this), this.messaging.livechatButtonView.chatbot.messageDelay); + this._chatbotTriggerNextStep.bind(this), this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.messageDelay); } } }, @@ -163,13 +163,13 @@ const QWeb = core.qweb; } const postedWelcomeMessages = await session.rpc('/chatbot/post_welcome_steps', { - channel_uuid: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._uuid, - chatbot_script_id: this.messaging.livechatButtonView.chatbot.scriptId, + channel_uuid: this.messaging.publicLivechatGlobal.publicLivechat.uuid, + chatbot_script_id: this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.scriptId, }); const welcomeMessagesIds = welcomeMessages.map(welcomeMessage => welcomeMessage._id); - this.messaging.livechatButtonView.update({ - messages: this.messaging.livechatButtonView.messages.filter((message) => { + this.messaging.publicLivechatGlobal.livechatButtonView.update({ + messages: this.messaging.publicLivechatGlobal.livechatButtonView.messages.filter((message) => { !welcomeMessagesIds.includes(message._id); }), }); @@ -192,7 +192,7 @@ const QWeb = core.qweb; * @private */ _chatbotDisableInput(disableText) { - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_composer_text_field') + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_composer_text_field') .prop('disabled', true) .addClass('text-center fst-italic bg-200') .val(disableText); @@ -202,7 +202,7 @@ const QWeb = core.qweb; * @private */ _chatbotEnableInput() { - const $composerTextField = this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_composer_text_field'); + const $composerTextField = this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_composer_text_field'); $composerTextField .prop('disabled', false) .removeClass('text-center fst-italic bg-200') @@ -213,7 +213,7 @@ const QWeb = core.qweb; $composerTextField.off('keydown', this.chatbotInputKeyDownHandler); } - if (this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'free_input_multi') { + if (this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'free_input_multi') { this.chatbotInputKeyDownHandler = this._onChatbotInputKeyDown.bind(this); $composerTextField.on('keydown', this.chatbotInputKeyDownHandler); } @@ -226,17 +226,17 @@ const QWeb = core.qweb; */ _chatbotEndScript() { if ( - this.messaging.livechatButtonView.chatbot.currentStep && - this.messaging.livechatButtonView.chatbot.currentStep.data && - this.messaging.livechatButtonView.chatbot.currentStep.data.conversation_closed + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.conversation_closed ) { // don't touch anything if the user has closed the conversation, let the chat window // handle the display return; } - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_composer_text_field').addClass('d-none'); - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_end').show(); - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_restart').one('click', + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_composer_text_field').addClass('d-none'); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_end').show(); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_restart').one('click', this._onChatbotRestartScript.bind(this)); }, @@ -249,9 +249,9 @@ const QWeb = core.qweb; * @private */ _chatbotDisplayRestartButton() { - return this.messaging.livechatButtonView.isChatbot && (!this.messaging.livechatButtonView.chatbot.currentStep || - (this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type !== 'forward_operator' || - !this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_operator_found)); + return this.messaging.publicLivechatGlobal.livechatButtonView.isChatbot && (!this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep || + (this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type !== 'forward_operator' || + !this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_operator_found)); }, /** * Works as a hook since other modules can add their own step types. @@ -264,7 +264,7 @@ const QWeb = core.qweb; 'question_email', 'free_input_single', 'free_input_multi', - ].includes(this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type); + ].includes(this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type); }, /** * Processes the step, depending on the current state of the script and the author of the last @@ -296,21 +296,21 @@ const QWeb = core.qweb; _chatbotProcessStep() { if (this._chatbotShouldEndScript()) { this._chatbotEndScript(); - } else if (this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'forward_operator' - && this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_operator_found) { + } else if (this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'forward_operator' + && this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_operator_found) { this._chatbotEnableInput(); } else if (this._chatbotIsExpectingUserInput()) { if (this._isLastMessageFromCustomer()) { // user has already typed a message in -> trigger next step this._chatbotSetIsTyping(); this.nextStepTimeout = setTimeout( - this._chatbotTriggerNextStep.bind(this), this.messaging.livechatButtonView.chatbot.messageDelay); + this._chatbotTriggerNextStep.bind(this), this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.messageDelay); } else { this._chatbotEnableInput(); } } else { let triggerNextStep = true; - if (this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'question_selection') { + if (this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'question_selection') { if (!this._isLastMessageFromCustomer()) { // if there is no last message or if the last message is from the bot // -> don't trigger the next step, we are waiting for the user to pick an option @@ -319,8 +319,8 @@ const QWeb = core.qweb; } if (triggerNextStep) { - let nextStepDelay = this.messaging.livechatButtonView.chatbot.messageDelay; - if (this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_typing').length !== 0) { + let nextStepDelay = this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.messageDelay; + if (this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_typing').length !== 0) { // special case where we already have a "is typing" message displayed // can happen when the previous step did not trigger any message posted from the bot // e.g: previous step was "forward_operator" and no-one is available @@ -336,7 +336,7 @@ const QWeb = core.qweb; } if (!this._chatbotDisplayRestartButton()) { - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_main_restart').addClass('d-none'); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_main_restart').addClass('d-none'); } }, /** @@ -356,16 +356,16 @@ const QWeb = core.qweb; if (browserLocalStorage && browserLocalStorage.length) { for (let i = 0; i < browserLocalStorage.length; i++) { const key = browserLocalStorage.key(i); - if (key.startsWith('im_livechat.chatbot.state.uuid_') && key !== this.messaging.livechatButtonView.chatbotSessionCookieKey) { + if (key.startsWith('im_livechat.chatbot.state.uuid_') && key !== this.messaging.publicLivechatGlobal.livechatButtonView.chatbotSessionCookieKey) { browserLocalStorage.removeItem(key); } } } - let chatbotState = localStorage.getItem(this.messaging.livechatButtonView.chatbotSessionCookieKey); + let chatbotState = localStorage.getItem(this.messaging.publicLivechatGlobal.livechatButtonView.chatbotSessionCookieKey); if (chatbotState) { - this.messaging.livechatButtonView.chatbot.update({ currentStep: insertAndReplace({ data: this.messaging.livechatButtonView.localStorageChatbotState._chatbotCurrentStep }) }); + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.update({ currentStep: insertAndReplace({ data: this.messaging.publicLivechatGlobal.livechatButtonView.localStorageChatbotState._chatbotCurrentStep }) }); } }, /** @@ -378,9 +378,9 @@ const QWeb = core.qweb; * @private */ _chatbotSaveSession() { - localStorage.setItem('im_livechat.chatbot.state.uuid_' + this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._uuid, JSON.stringify({ - '_chatbot': this.messaging.livechatButtonView.chatbot.data, - '_chatbotCurrentStep': this.messaging.livechatButtonView.chatbot.currentStep.data, + localStorage.setItem('im_livechat.chatbot.state.uuid_' + this.messaging.publicLivechatGlobal.publicLivechat.uuid, JSON.stringify({ + '_chatbot': this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.data, + '_chatbotCurrentStep': this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data, })); }, /** @@ -389,26 +389,26 @@ const QWeb = core.qweb; * @private */ _chatbotSetIsTyping(isWelcomeMessage=false) { - if (this.messaging.livechatButtonView.isTypingTimeout) { + if (this.messaging.publicLivechatGlobal.livechatButtonView.isTypingTimeout) { clearTimeout(this.isTypingTimeout); } this._chatbotDisableInput(''); - this.messaging.livechatButtonView.update({ + this.messaging.publicLivechatGlobal.livechatButtonView.update({ isTypingTimeout: setTimeout(() => { - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_mail_thread_content').append( + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_mail_thread_content').append( $(QWeb.render('im_livechat.legacy.chatbot.is_typing_message', { 'chatbotImageSrc': `/im_livechat/operator/${ - this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._operatorPID[0] + this.messaging.publicLivechatGlobal.publicLivechat.operator.id }/avatar`, - 'chatbotName': this.messaging.livechatButtonView.chatbot.name, + 'chatbotName': this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.name, 'isWelcomeMessage': isWelcomeMessage, })) ); - this.messaging.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.scrollToBottom(); - }, this.messaging.livechatButtonView.chatbot.messageDelay / 3), + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.scrollToBottom(); + }, this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.messageDelay / 3), }); }, /** @@ -426,25 +426,25 @@ const QWeb = core.qweb; * @private */ _chatbotShouldEndScript() { - if (this.messaging.livechatButtonView.chatbot.currentStep.data.conversation_closed) { + if (this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.conversation_closed) { return true; } - if (this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_is_last && - (this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type !== 'forward_operator' || - !this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_operator_found) + if (this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_is_last && + (this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type !== 'forward_operator' || + !this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_operator_found) ) { - if (this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'question_email' - && !this.messaging.livechatButtonView.chatbot.currentStep.data.is_email_valid + if (this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'question_email' + && !this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.is_email_valid ) { // email is not (yet) valid, let the user answer / try again return false; } else if ( (this._chatbotIsExpectingUserInput() || - this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'question_selection') && - this.messaging.livechatButtonView.messages.length !== 0 + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'question_selection') && + this.messaging.publicLivechatGlobal.livechatButtonView.messages.length !== 0 ) { - const lastMessage = this.messaging.livechatButtonView.messages[this.messaging.livechatButtonView.messages.length - 1]; - if (lastMessage.getAuthorID() !== this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._operatorPID[0]) { + const lastMessage = this.messaging.publicLivechatGlobal.livechatButtonView.messages[this.messaging.publicLivechatGlobal.livechatButtonView.messages.length - 1]; + if (lastMessage.getAuthorID() !== this.messaging.publicLivechatGlobal.publicLivechat.operator.id) { // we are on the last step of the script, expect a user input and the user has // already answered // -> end the script @@ -472,11 +472,11 @@ const QWeb = core.qweb; */ async _chatbotValidateEmail() { let emailValidResult = await session.rpc('/chatbot/step/validate_email', { - channel_uuid: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._uuid, + channel_uuid: this.messaging.publicLivechatGlobal.publicLivechat.uuid, }); if (emailValidResult.success) { - this.messaging.livechatButtonView.chatbot.currentStep.data.is_email_valid = true; + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.is_email_valid = true; this._chatbotSaveSession(); return true; @@ -499,9 +499,9 @@ const QWeb = core.qweb; async _chatbotTriggerNextStep() { let triggerNextStep = true; if ( - this.messaging.livechatButtonView.chatbot.currentStep && - this.messaging.livechatButtonView.chatbot.currentStep.data && - this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'question_email' + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'question_email' ) { triggerNextStep = await this._chatbotValidateEmail(); } @@ -511,8 +511,8 @@ const QWeb = core.qweb; } const nextStep = await session.rpc('/chatbot/step/trigger', { - channel_uuid: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._uuid, - chatbot_script_id: this.messaging.livechatButtonView.chatbot.scriptId, + channel_uuid: this.messaging.publicLivechatGlobal.publicLivechat.uuid, + chatbot_script_id: this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.scriptId, }); if (nextStep) { @@ -520,12 +520,12 @@ const QWeb = core.qweb; this._chatbotAddMessage(nextStep.chatbot_posted_message); } - this.messaging.livechatButtonView.chatbot.update({ currentStep: insertAndReplace({ data: nextStep.chatbot_step }) }); + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.update({ currentStep: insertAndReplace({ data: nextStep.chatbot_step }) }); this._chatbotProcessStep(); } else { // did not find next step -> end the script - this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_is_last = true; + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_is_last = true; this._renderMessages(); this._chatbotEndScript(); } @@ -535,13 +535,13 @@ const QWeb = core.qweb; return nextStep; }, /** - * Returns the 'this.messaging.livechatButtonView.messages' filtered on our special 'welcome' ones. + * Returns the 'this.messaging.publicLivechatGlobal.livechatButtonView.messages' filtered on our special 'welcome' ones. * See '_sendWelcomeChatbotMessage'. * * @private */ _getWelcomeMessages() { - return this.messaging.livechatButtonView.messages.filter((message) => { + return this.messaging.publicLivechatGlobal.livechatButtonView.messages.filter((message) => { return message._id && typeof message._id === 'string' && message._id.startsWith('_welcome_'); }); }, @@ -551,8 +551,8 @@ const QWeb = core.qweb; * @private */ _isLastMessageFromCustomer() { - const lastMessage = this.messaging.livechatButtonView.messages.length !== 0 ? this.messaging.livechatButtonView.messages[this.messaging.livechatButtonView.messages.length - 1] : null; - return lastMessage && lastMessage.getAuthorID() !== this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._operatorPID[0]; + const lastMessage = this.messaging.publicLivechatGlobal.livechatButtonView.messages.length !== 0 ? this.messaging.publicLivechatGlobal.livechatButtonView.messages[this.messaging.publicLivechatGlobal.livechatButtonView.messages.length - 1] : null; + return lastMessage && lastMessage.getAuthorID() !== this.messaging.publicLivechatGlobal.publicLivechat.operator.id; }, //-------------------------------------------------------------------------- @@ -570,16 +570,16 @@ const QWeb = core.qweb; this._super(...arguments); if ( - this.messaging.livechatButtonView.chatbot && - this.messaging.livechatButtonView.chatbot.currentStep && - this.messaging.livechatButtonView.chatbot.currentStep.data + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data ) { - this.messaging.livechatButtonView.chatbot.currentStep.data.conversation_closed = true; + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.conversation_closed = true; this._chatbotSaveSession(); } - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_main_restart').addClass('d-none'); - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_end').hide(); - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_composer_text_field') + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_main_restart').addClass('d-none'); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_end').hide(); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_composer_text_field') .removeClass('d-none') .val(''); }, @@ -597,17 +597,17 @@ const QWeb = core.qweb; _openChatWindow() { return this._super(...arguments).then(() => { window.addEventListener('resize', () => { - if (this.messaging.livechatButtonView.chatWindow) { - this.messaging.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.scrollToBottom(); + if (this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow) { + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.scrollToBottom(); } }); if ( - this.messaging.livechatButtonView.chatbot && - this.messaging.livechatButtonView.chatbot.currentStep && - this.messaging.livechatButtonView.chatbot.currentStep.data && - this.messaging.livechatButtonView.messages && - this.messaging.livechatButtonView.messages.length !== 0 + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data && + this.messaging.publicLivechatGlobal.livechatButtonView.messages && + this.messaging.publicLivechatGlobal.livechatButtonView.messages.length !== 0 ) { this._chatbotProcessStep(); } @@ -620,8 +620,8 @@ const QWeb = core.qweb; _prepareGetSessionParameters() { const parameters = this._super(...arguments); - if (this.messaging.livechatButtonView.isChatbot) { - parameters.chatbot_script_id = this.messaging.livechatButtonView.chatbot.scriptId; + if (this.messaging.publicLivechatGlobal.livechatButtonView.isChatbot) { + parameters.chatbot_script_id = this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.scriptId; } return parameters; @@ -634,15 +634,15 @@ const QWeb = core.qweb; const self = this; - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_thread_message:last .o_livechat_chatbot_options li').each(function () { + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_thread_message:last .o_livechat_chatbot_options li').each(function () { $(this).on('click', self._onChatbotOptionClicked.bind(self)); }); - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_main_restart').on('click', + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_main_restart').on('click', this._onChatbotRestartScript.bind(this)); - if (this.messaging.livechatButtonView.messages.length !== 0) { - const lastMessage = this.messaging.livechatButtonView.messages[this.messaging.livechatButtonView.messages.length - 1]; + if (this.messaging.publicLivechatGlobal.livechatButtonView.messages.length !== 0) { + const lastMessage = this.messaging.publicLivechatGlobal.livechatButtonView.messages[this.messaging.publicLivechatGlobal.livechatButtonView.messages.length - 1]; const stepAnswers = lastMessage.getChatbotStepAnswers(); if (stepAnswers && stepAnswers.length !== 0 && !lastMessage.getChatbotStepAnswerId()) { this._chatbotDisableInput(_t('Select an option above')); @@ -672,34 +672,34 @@ const QWeb = core.qweb; const superMethod = this._super; if ( - this.messaging.livechatButtonView.isChatbot && - this.messaging.livechatButtonView.chatbot.currentStep && - this.messaging.livechatButtonView.chatbot.currentStep.data + this.messaging.publicLivechatGlobal.livechatButtonView.isChatbot && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data ) { await this._chatbotPostWelcomeMessages(); } return superMethod.apply(this, superArguments).then(() => { - if (this.messaging.livechatButtonView.isChatbotRedirecting) { + if (this.messaging.publicLivechatGlobal.livechatButtonView.isChatbotRedirecting) { return; } if ( - this.messaging.livechatButtonView.isChatbot && - this.messaging.livechatButtonView.chatbot.currentStep && - this.messaging.livechatButtonView.chatbot.currentStep.data + this.messaging.publicLivechatGlobal.livechatButtonView.isChatbot && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data ) { if ( - this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'forward_operator' && - this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_operator_found + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'forward_operator' && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_operator_found ) { return; // operator has taken over the conversation, let them speak - } else if (this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'free_input_multi') { + } else if (this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'free_input_multi') { this._debouncedChatbotAwaitUserInput(); } else if (!this._chatbotShouldEndScript()) { this._chatbotSetIsTyping(); this.nextStepTimeout = setTimeout( - this._chatbotTriggerNextStep.bind(this), this.messaging.livechatButtonView.chatbot.messageDelay); + this._chatbotTriggerNextStep.bind(this), this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.messageDelay); } else { this._chatbotEndScript(); } @@ -713,10 +713,10 @@ const QWeb = core.qweb; * @private */ _sendWelcomeMessage() { - if (this.messaging.livechatButtonView.isChatbot) { + if (this.messaging.publicLivechatGlobal.livechatButtonView.isChatbot) { this._sendWelcomeChatbotMessage( 0, - this.messaging.livechatButtonView.chatbotState === 'welcome' ? 0 : this.messaging.livechatButtonView.chatbot.messageDelay, + this.messaging.publicLivechatGlobal.livechatButtonView.chatbotState === 'welcome' ? 0 : this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.messageDelay, ); } else { this._super(...arguments); @@ -744,26 +744,33 @@ const QWeb = core.qweb; * @private */ _sendWelcomeChatbotMessage(stepIndex, welcomeMessageDelay) { - const chatbotStep = this.messaging.livechatButtonView.chatbot.welcomeSteps[stepIndex]; - this.messaging.livechatButtonView.chatbot.update({ currentStep: insertAndReplace({ data: chatbotStep }) }); + const chatbotStep = this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.welcomeSteps[stepIndex]; + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.update({ currentStep: insertAndReplace({ data: chatbotStep }) }); if (chatbotStep.chatbot_step_message) { this._addMessage({ id: '_welcome_' + stepIndex, is_discussion: true, // important for css style -> we only want white background for chatbot attachment_ids: [], - author_id: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._operatorPID, + author_id: ( + this.messaging.publicLivechatGlobal.publicLivechat.operator + ? [ + this.messaging.publicLivechatGlobal.publicLivechat.operator.id, + this.messaging.publicLivechatGlobal.publicLivechat.operator.name, + ] + : [] + ), body: utils.Markup(chatbotStep.chatbot_step_message), chatbot_script_step_id: chatbotStep.chatbot_script_step_id, chatbot_step_answers: chatbotStep.chatbot_step_answers, date: time.datetime_to_str(new Date()), model: "mail.channel", message_type: "comment", - res_id: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._id, + res_id: this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id, }); } - if (stepIndex + 1 < this.messaging.livechatButtonView.chatbot.welcomeSteps.length) { + if (stepIndex + 1 < this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.welcomeSteps.length) { if (welcomeMessageDelay !== 0) { this._chatbotSetIsTyping(true); } @@ -773,7 +780,7 @@ const QWeb = core.qweb; this._renderMessages(); }, welcomeMessageDelay); } else { - if (this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'forward_operator') { + if (this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'forward_operator') { // special case when the last welcome message is a forward to an operator // we need to save the welcome messages before continuing the script // indeed, if there are no operator available, the script will continue @@ -798,8 +805,8 @@ const QWeb = core.qweb; * @private */ async _onChatbotRestartScript(ev) { - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_composer_text_field').removeClass('d-none'); - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_end').hide(); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_composer_text_field').removeClass('d-none'); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_livechat_chatbot_end').hide(); if (this.nextStepTimeout) { clearTimeout(this.nextStepTimeout); @@ -810,25 +817,25 @@ const QWeb = core.qweb; } const postedMessage = await session.rpc('/chatbot/restart', { - channel_uuid: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._uuid, - chatbot_script_id: this.messaging.livechatButtonView.chatbot.scriptId, + channel_uuid: this.messaging.publicLivechatGlobal.publicLivechat.uuid, + chatbot_script_id: this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.scriptId, }); if (postedMessage) { this._chatbotAddMessage(postedMessage); } - this.messaging.livechatButtonView.chatbot.update({ currentStep: clear() }); + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.update({ currentStep: clear() }); this._chatbotSetIsTyping(); this.nextStepTimeout = setTimeout( - this._chatbotTriggerNextStep.bind(this), this.messaging.livechatButtonView.chatbot.messageDelay); + this._chatbotTriggerNextStep.bind(this), this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.messageDelay); }, _onChatbotInputKeyDown() { if ( - this.messaging.livechatButtonView.chatbot.currentStep && - this.messaging.livechatButtonView.chatbot.currentStep.data && - this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'free_input_multi' + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data && + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_step_type === 'free_input_multi' ) { this._debouncedChatbotAwaitUserInput(); } @@ -836,7 +843,7 @@ const QWeb = core.qweb; /** * Saves the selected chatbot.script.answer onto our chatbot.message. - * Will update the state of the related message (in this.messaging.livechatButtonView.messages) to set the selected option + * Will update the state of the related message (in this.messaging.publicLivechatGlobal.livechatButtonView.messages) to set the selected option * as well which will in turn adapt the display to not show options anymore. * * This method also handles an optional redirection link placed on the chatbot.script.answer and @@ -853,14 +860,14 @@ const QWeb = core.qweb; const selectedAnswer = $target.data('chatbotStepAnswerId'); const redirectLink = $target.data('chatbotStepRedirectLink'); - this.messaging.livechatButtonView.update({ isChatbotRedirecting: !!redirectLink }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ isChatbotRedirecting: !!redirectLink }); await this._sendMessage({ content: $target.text().trim(), }); let stepMessage = null; - for (const message of this.messaging.livechatButtonView.messages) { + for (const message of this.messaging.publicLivechatGlobal.livechatButtonView.messages) { // we do NOT want to use a 'find' here because we want the LAST message that respects // this condition. // indeed, if you restart the script, you can have multiple messages with the same step id, @@ -873,12 +880,12 @@ const QWeb = core.qweb; } const messageId = stepMessage.getID(); stepMessage.setChatbotStepAnswerId(selectedAnswer); - this.messaging.livechatButtonView.chatbot.currentStep.data.chatbot_selected_answer_id = selectedAnswer; + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_selected_answer_id = selectedAnswer; this._renderMessages(); this._chatbotSaveSession(); const saveAnswerPromise = session.rpc('/chatbot/answer/save', { - channel_uuid: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._uuid, + channel_uuid: this.messaging.publicLivechatGlobal.publicLivechat.uuid, message_id: messageId, selected_answer_id: selectedAnswer, }); diff --git a/addons/im_livechat/static/src/legacy/public_livechat_constants.js b/addons/im_livechat/static/src/legacy/public_livechat_constants.js deleted file mode 100644 index 84dcde07d23..00000000000 --- a/addons/im_livechat/static/src/legacy/public_livechat_constants.js +++ /dev/null @@ -1,20 +0,0 @@ -odoo.define('im_livechat.legacy.im_livechat.Constants', function (require) { -"use strict"; - -// Constants -const LIVECHAT_COOKIE_HISTORY = 'im_livechat_history'; -const HISTORY_LIMIT = 15; - -const RATING_TO_EMOJI = { - "5": "😊", - "3": "😐", - "1": "😞" -}; - -return { - LIVECHAT_COOKIE_HISTORY, - HISTORY_LIMIT, - RATING_TO_EMOJI, -}; - -}); diff --git a/addons/im_livechat/static/src/legacy/public_livechat_history_tracking.js b/addons/im_livechat/static/src/legacy/public_livechat_history_tracking.js deleted file mode 100644 index 67780d95af9..00000000000 --- a/addons/im_livechat/static/src/legacy/public_livechat_history_tracking.js +++ /dev/null @@ -1,23 +0,0 @@ -odoo.define('im_livechat.legacy.im_livechat.HistoryTracking', function (require) { -"use strict"; - -const utils = require('web.utils'); - -const { HISTORY_LIMIT, LIVECHAT_COOKIE_HISTORY } = require ("im_livechat.legacy.im_livechat.Constants"); - -// History tracking -const page = window.location.href.replace(/^.*\/\/[^/]+/, ''); -const pageHistory = utils.get_cookie(LIVECHAT_COOKIE_HISTORY); -let urlHistory = []; -if (pageHistory) { - urlHistory = JSON.parse(pageHistory) || []; -} -if (!_.contains(urlHistory, page)) { - urlHistory.push(page); - while (urlHistory.length > HISTORY_LIMIT) { - urlHistory.shift(); - } - utils.set_cookie(LIVECHAT_COOKIE_HISTORY, JSON.stringify(urlHistory), 60 * 60 * 24); // 1 day cookie -} - -}); diff --git a/addons/im_livechat/static/src/legacy/widgets/feedback/feedback.js b/addons/im_livechat/static/src/legacy/widgets/feedback/feedback.js index 0284f9008a9..7bc8b8f88fc 100644 --- a/addons/im_livechat/static/src/legacy/widgets/feedback/feedback.js +++ b/addons/im_livechat/static/src/legacy/widgets/feedback/feedback.js @@ -6,8 +6,6 @@ import session from 'web.session'; import utils from 'web.utils'; import Widget from 'web.Widget'; -import { RATING_TO_EMOJI } from 'im_livechat.legacy.im_livechat.Constants'; - const _t = core._t; /* * Rating for Livechat @@ -28,11 +26,12 @@ const Feedback = Widget.extend({ /** * @param {?} parent + * @param {Messaging} messaging * @param {@im_livechat/legacy/models/public_livechat} livechat */ - init(parent, livechat) { + init(parent, messaging, livechat) { this._super(parent); - this._livechat = livechat; + this.messaging = messaging; this.server_origin = session.origin; this.rating = undefined; this.dp = new concurrency.DropPrevious(); @@ -48,12 +47,12 @@ const Feedback = Widget.extend({ */ _sendFeedback(reason) { const args = { - uuid: this._livechat._uuid, + uuid: this.messaging.publicLivechatGlobal.publicLivechat.uuid, rate: this.rating, reason, }; this.dp.add(session.rpc('/im_livechat/feedback', args)).then((response) => { - const emoji = RATING_TO_EMOJI[this.rating] || "??"; + const emoji = this.messaging.publicLivechatGlobal.RATING_TO_EMOJI[this.rating] || "??"; let content; if (!reason) { content = utils.sprintf(_t("Rating: %s"), emoji); @@ -125,7 +124,7 @@ const Feedback = Widget.extend({ this._rpc({ route: '/im_livechat/email_livechat_transcript', params: { - uuid: this._livechat._uuid, + uuid: this.messaging.publicLivechatGlobal.publicLivechat.uuid, email: $email.val(), } }).then(() => { diff --git a/addons/im_livechat/static/src/legacy/widgets/livechat_button.js b/addons/im_livechat/static/src/legacy/widgets/livechat_button.js index a274002d179..96172c0d993 100644 --- a/addons/im_livechat/static/src/legacy/widgets/livechat_button.js +++ b/addons/im_livechat/static/src/legacy/widgets/livechat_button.js @@ -7,11 +7,9 @@ import time from 'web.time'; import utils from 'web.utils'; import Widget from 'web.Widget'; -import { LIVECHAT_COOKIE_HISTORY } from 'im_livechat.legacy.im_livechat.Constants'; -import Feedback from '@im_livechat/legacy/widgets/feedback/feedback'; import PublicLivechatMessage from '@im_livechat/legacy/models/public_livechat_message'; -import { clear, increment, insert, insertAndReplace } from '@mail/model/model_field_command'; +import { clear, insert, insertAndReplace } from '@mail/model/model_field_command'; const _t = core._t; const QWeb = core.qweb; @@ -31,49 +29,47 @@ const LivechatButton = Widget.extend({ init(parent, messaging) { this._super(parent); this.messaging = messaging; - this.options = _.defaults(this.messaging.publicLivechatGlobal.options || {}); }, async willStart() { - this.messaging.livechatButtonView.update({ widget: this }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ widget: this }); const cookie = utils.get_cookie('im_livechat_session'); if (cookie) { const channel = JSON.parse(cookie); const history = await session.rpc('/mail/chat_history', {uuid: channel.uuid, limit: 100}); history.reverse(); - this.messaging.livechatButtonView.update({ history }); - for (const message of this.messaging.livechatButtonView.history) { + this.messaging.publicLivechatGlobal.livechatButtonView.update({ history }); + for (const message of this.messaging.publicLivechatGlobal.livechatButtonView.history) { message.body = utils.Markup(message.body); } } else { - const result = await session.rpc('/im_livechat/init', {channel_id: this.messaging.livechatButtonView.channelId}); + const result = await session.rpc('/im_livechat/init', {channel_id: this.messaging.publicLivechatGlobal.livechatButtonView.channelId}); if (!result.available_for_me) { return Promise.reject(); } - this.messaging.livechatButtonView.update({ rule: result.rule }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ rule: result.rule }); } return this._loadQWebTemplate(); }, start() { - this.$el.text(this.messaging.livechatButtonView.buttonText); - if (this.messaging.livechatButtonView.history) { - for (const m of this.messaging.livechatButtonView.history) { + this.$el.text(this.messaging.publicLivechatGlobal.livechatButtonView.buttonText); + if (this.messaging.publicLivechatGlobal.livechatButtonView.history) { + for (const m of this.messaging.publicLivechatGlobal.livechatButtonView.history) { this._addMessage(m); } this._openChat(); - } else if (!config.device.isMobile && this.messaging.livechatButtonView.rule.action === 'auto_popup') { + } else if (!config.device.isMobile && this.messaging.publicLivechatGlobal.livechatButtonView.rule.action === 'auto_popup') { const autoPopupCookie = utils.get_cookie('im_livechat_auto_popup'); if (!autoPopupCookie || JSON.parse(autoPopupCookie)) { - this.messaging.livechatButtonView.update({ - autoOpenChatTimeout: setTimeout(this._openChat.bind(this), this.messaging.livechatButtonView.rule.auto_popup_timer * 1000), + this.messaging.publicLivechatGlobal.livechatButtonView.update({ + autoOpenChatTimeout: setTimeout(this._openChat.bind(this), this.messaging.publicLivechatGlobal.livechatButtonView.rule.auto_popup_timer * 1000), }); } } - this.call('bus_service', 'addEventListener', 'notification', this._onNotification.bind(this)); - if (this.messaging.livechatButtonView.buttonBackgroundColor) { - this.$el.css('background-color', this.messaging.livechatButtonView.buttonBackgroundColor); + if (this.messaging.publicLivechatGlobal.livechatButtonView.buttonBackgroundColor) { + this.$el.css('background-color', this.messaging.publicLivechatGlobal.livechatButtonView.buttonBackgroundColor); } - if (this.messaging.livechatButtonView.buttonTextColor) { - this.$el.css('color', this.messaging.livechatButtonView.buttonTextColor); + if (this.messaging.publicLivechatGlobal.livechatButtonView.buttonTextColor) { + this.$el.css('color', this.messaging.publicLivechatGlobal.livechatButtonView.buttonTextColor); } // If website_event_track installed, put the livechat banner above the PWA banner. @@ -96,19 +92,16 @@ const LivechatButton = Widget.extend({ * @param {Object} [options={}] */ _addMessage(data, options) { - options = Object.assign({}, this.options, options, { - serverURL: this.messaging.livechatButtonView.serverUrl, - }); - const message = new PublicLivechatMessage(this, data, options); + const message = new PublicLivechatMessage(this, this.messaging, data); - const hasAlreadyMessage = _.some(this.messaging.livechatButtonView.messages, function (msg) { + const hasAlreadyMessage = _.some(this.messaging.publicLivechatGlobal.livechatButtonView.messages, function (msg) { return message.getID() === msg.getID(); }); if (hasAlreadyMessage) { return; } - if (this.messaging.livechatButtonView.publicLivechat) { - this.messaging.livechatButtonView.publicLivechat.update({ + if (this.messaging.publicLivechatGlobal.publicLivechat) { + this.messaging.publicLivechatGlobal.publicLivechat.update({ messages: insert({ id: data.id, legacyPublicLivechatMessage: message, @@ -116,17 +109,17 @@ const LivechatButton = Widget.extend({ }); } - if (this.messaging.livechatButtonView.publicLivechat && this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat) { - this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat.addMessage(message); + if (this.messaging.publicLivechatGlobal.publicLivechat && this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat) { + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.addMessage(message); } if (options && options.prepend) { - this.messaging.livechatButtonView.update({ - messages: [message, ...this.messaging.livechatButtonView.messages], + this.messaging.publicLivechatGlobal.livechatButtonView.update({ + messages: [message, ...this.messaging.publicLivechatGlobal.livechatButtonView.messages], }); } else { - this.messaging.livechatButtonView.update({ - messages: [...this.messaging.livechatButtonView.messages, message], + this.messaging.publicLivechatGlobal.livechatButtonView.update({ + messages: [...this.messaging.publicLivechatGlobal.livechatButtonView.messages, message], }); } }, @@ -134,86 +127,16 @@ const LivechatButton = Widget.extend({ * @private */ _askFeedback() { - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_thread_composer input').prop('disabled', true); - - const feedback = new Feedback(this, this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat); - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.replaceContentWith(feedback); - - feedback.on('send_message', this, this._sendMessage); - feedback.on('feedback_sent', this, this._closeChat); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_thread_composer input').prop('disabled', true); + this.messaging.publicLivechatGlobal.update({ feedbackView: insertAndReplace() }); }, /** * @private */ _closeChat() { - this.messaging.livechatButtonView.update({ chatWindow: clear() }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ chatWindow: clear() }); utils.set_cookie('im_livechat_session', "", -1); // remove cookie }, - /** - * @private - * @param {Object} notification - * @param {Object} notification.payload - * @param {string} notification.type - */ - _handleNotification({ payload, type }) { - switch (type) { - case 'im_livechat.history_command': { - if (payload.id !== this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._id) { - return; - } - const cookie = utils.get_cookie(LIVECHAT_COOKIE_HISTORY); - const history = cookie ? JSON.parse(cookie) : []; - session.rpc('/im_livechat/history', { - pid: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._operatorPID[0], - channel_uuid: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._uuid, - page_history: history, - }); - return; - } - case 'mail.channel.member/typing_status': { - if (payload.channel_id !== this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._id) { - return; - } - const partnerID = payload.partner_id; - if (partnerID === this.messaging.livechatButtonView.currentPartnerId) { - // ignore typing display of current partner. - return; - } - if (payload.is_typing) { - this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat.registerTyping({ partnerID }); - } else { - this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat.unregisterTyping({ partnerID }); - } - return; - } - case 'mail.channel/new_message': { - if (payload.id !== this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._id) { - return; - } - const notificationData = payload.message; - // If message from notif is already in chatter messages, stop handling - if (this.messaging.livechatButtonView.messages.some(message => message.getID() === notificationData.id)) { - return; - } - notificationData.body = utils.Markup(notificationData.body); - this._addMessage(notificationData); - if (this.messaging.livechatButtonView.chatWindow.legacyChatWindow._thread._folded || !this.messaging.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.isAtBottom()) { - this.messaging.livechatButtonView.publicLivechat.update({ unreadCounter: increment() }); - } - this._renderMessages(); - return; - } - case 'mail.message/insert': { - const message = this.messaging.livechatButtonView.messages.find(message => message._id === payload.id); - if (!message) { - return; - } - message._body = utils.Markup(payload.body); - this._renderMessages(); - return; - } - } - }, /** * @private */ @@ -228,18 +151,18 @@ const LivechatButton = Widget.extend({ * @private */ _openChat: _.debounce(function () { - if (this.messaging.livechatButtonView.isOpeningChat) { + if (this.messaging.publicLivechatGlobal.livechatButtonView.isOpeningChat) { return; } const cookie = utils.get_cookie('im_livechat_session'); let def; - this.messaging.livechatButtonView.update({ isOpeningChat: true }); - clearTimeout(this.messaging.livechatButtonView.autoOpenChatTimeout); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ isOpeningChat: true }); + clearTimeout(this.messaging.publicLivechatGlobal.livechatButtonView.autoOpenChatTimeout); if (cookie) { def = Promise.resolve(JSON.parse(cookie)); } else { // re-initialize messages cache - this.messaging.livechatButtonView.update({ messages: clear() }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ messages: clear() }); def = session.rpc( '/im_livechat/get_session', this._prepareGetSessionParameters(), @@ -264,32 +187,29 @@ const LivechatButton = Widget.extend({ console.warn(_t("No available collaborator, please try again later.")); } } else { - this.messaging.livechatButtonView.update({ + this.messaging.publicLivechatGlobal.update({ publicLivechat: insertAndReplace({ data: livechatData }), }); return this._openChatWindow().then(() => { - if (!this.messaging.livechatButtonView.history) { + if (!this.messaging.publicLivechatGlobal.livechatButtonView.history) { this._sendWelcomeMessage(); } this._renderMessages(); - this.call('bus_service', 'addChannel', this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._uuid); - this.call('bus_service', 'startPolling'); + this.messaging.publicLivechatGlobal.update({ notificationHandler: insertAndReplace() }); - utils.set_cookie('im_livechat_session', utils.unaccent(JSON.stringify(this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat.toData()), true), 60 * 60); + utils.set_cookie('im_livechat_session', utils.unaccent(JSON.stringify(this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.toData()), true), 60 * 60); utils.set_cookie('im_livechat_auto_popup', JSON.stringify(false), 60 * 60); - if (livechatData.operator_pid[0]) { - // livechatData.operator_pid contains a tuple (id, name) - // we are only interested in the id - const operatorPidId = livechatData.operator_pid[0]; + if (this.messaging.publicLivechatGlobal.publicLivechat.operator) { + const operatorPidId = this.messaging.publicLivechatGlobal.publicLivechat.operator.id; const oneWeek = 7 * 24 * 60 * 60; utils.set_cookie('im_livechat_previous_operator_pid', operatorPidId, oneWeek); } }); } }).then(() => { - this.messaging.livechatButtonView.update({ isOpeningChat: false }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ isOpeningChat: false }); }).guardedCatch(() => { - this.messaging.livechatButtonView.update({ isOpeningChat: false }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ isOpeningChat: false }); }); }, 200, true), /** @@ -315,11 +235,11 @@ const LivechatButton = Widget.extend({ * @return {Promise} */ _openChatWindow() { - this.messaging.livechatButtonView.update({ chatWindow: insertAndReplace() }); - return this.messaging.livechatButtonView.chatWindow.legacyChatWindow.appendTo($('body')).then(() => { + this.messaging.publicLivechatGlobal.livechatButtonView.update({ chatWindow: insertAndReplace() }); + return this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.appendTo($('body')).then(() => { const cssProps = { bottom: 0 }; cssProps[_t.database.parameters.direction === 'rtl' ? 'left' : 'right'] = 0; - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$el.css(cssProps); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$el.css(cssProps); this.$el.hide(); }); }, @@ -328,8 +248,8 @@ const LivechatButton = Widget.extend({ */ _prepareGetSessionParameters() { return { - channel_id: this.messaging.livechatButtonView.channelId, - anonymous_name: this.messaging.livechatButtonView.defaultUsername, + channel_id: this.messaging.publicLivechatGlobal.livechatButtonView.channelId, + anonymous_name: this.messaging.publicLivechatGlobal.livechatButtonView.defaultUsername, previous_operator_id: this._get_previous_operator_id(), }; }, @@ -337,11 +257,11 @@ const LivechatButton = Widget.extend({ * @private */ _renderMessages() { - const shouldScroll = !this.messaging.livechatButtonView.chatWindow.legacyChatWindow._thread._folded && this.messaging.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.isAtBottom(); - this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._messages = this.messaging.livechatButtonView.messages; - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.render(); + const shouldScroll = !this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._thread._folded && this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.isAtBottom(); + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._messages = this.messaging.publicLivechatGlobal.livechatButtonView.messages; + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.render(); if (shouldScroll) { - this.messaging.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.scrollToBottom(); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.scrollToBottom(); } }, /** @@ -350,9 +270,9 @@ const LivechatButton = Widget.extend({ * @return {Promise} */ _sendMessage(message) { - this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._notifyMyselfTyping({ typing: false }); + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._notifyMyselfTyping({ typing: false }); return session - .rpc('/mail/chat_post', { uuid: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._uuid, message_content: message.content }) + .rpc('/mail/chat_post', { uuid: this.messaging.publicLivechatGlobal.publicLivechat.uuid, message_content: message.content }) .then((messageId) => { if (!messageId) { try { @@ -373,22 +293,25 @@ const LivechatButton = Widget.extend({ } this._closeChat(); } - this.messaging.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.scrollToBottom(); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.scrollToBottom(); }); }, /** * @private */ _sendWelcomeMessage() { - if (this.messaging.livechatButtonView.defaultMessage) { + if (this.messaging.publicLivechatGlobal.livechatButtonView.defaultMessage) { this._addMessage({ id: '_welcome', attachment_ids: [], - author_id: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._operatorPID, - body: this.messaging.livechatButtonView.defaultMessage, + author_id: [ + this.messaging.publicLivechatGlobal.publicLivechat.operator.id, + this.messaging.publicLivechatGlobal.publicLivechat.operator.name, + ], + body: this.messaging.publicLivechatGlobal.livechatButtonView.defaultMessage, date: time.datetime_to_str(new Date()), model: "mail.channel", - res_id: this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._id, + res_id: this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id, }, { prepend: true }); } }, @@ -403,28 +326,18 @@ const LivechatButton = Widget.extend({ */ _onCloseChatWindow(ev) { ev.stopPropagation(); - const isComposerDisabled = this.messaging.livechatButtonView.chatWindow.legacyChatWindow.$('.o_thread_composer input').prop('disabled'); - const shouldAskFeedback = !isComposerDisabled && this.messaging.livechatButtonView.messages.find(function (message) { + const isComposerDisabled = this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.$('.o_thread_composer input').prop('disabled'); + const shouldAskFeedback = !isComposerDisabled && this.messaging.publicLivechatGlobal.livechatButtonView.messages.find(function (message) { return message.getID() !== '_welcome'; }); if (shouldAskFeedback) { - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.toggleFold(false); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.toggleFold(false); this._askFeedback(); } else { this._closeChat(); } this._visitorLeaveSession(); }, - /** - * @private - * @param {CustomEvent} ev - * @param {Array[]} [ev.detail] Notifications coming from the bus. - */ - _onNotification({ detail: notifications }) { - for (let notification of notifications) { - this._handleNotification(notification); - } - }, /** * @private * @param {OdooEvent} ev @@ -444,7 +357,7 @@ const LivechatButton = Widget.extend({ */ _onSaveChatWindow(ev) { ev.stopPropagation(); - utils.set_cookie('im_livechat_session', utils.unaccent(JSON.stringify(this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat.toData()), true), 60 * 60); + utils.set_cookie('im_livechat_session', utils.unaccent(JSON.stringify(this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.toData()), true), 60 * 60); }, /** * @private @@ -452,7 +365,7 @@ const LivechatButton = Widget.extend({ */ _onUpdatedTypingPartners(ev) { ev.stopPropagation(); - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.renderHeader(); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.renderHeader(); }, /** * @private @@ -460,7 +373,7 @@ const LivechatButton = Widget.extend({ */ _onUpdatedUnreadCounter(ev) { ev.stopPropagation(); - this.messaging.livechatButtonView.chatWindow.legacyChatWindow.renderHeader(); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.renderHeader(); }, /** * @private diff --git a/addons/im_livechat/static/src/legacy/widgets/public_livechat_window/public_livechat_window.js b/addons/im_livechat/static/src/legacy/widgets/public_livechat_window/public_livechat_window.js index e2c0a303b63..a727f95c3f0 100644 --- a/addons/im_livechat/static/src/legacy/widgets/public_livechat_window/public_livechat_window.js +++ b/addons/im_livechat/static/src/legacy/widgets/public_livechat_window/public_livechat_window.js @@ -32,16 +32,13 @@ const PublicLivechatWindow = Widget.extend({ * @param {Widget} parent * @param {Messaging} messaging * @param {@im_livechat/legacy/models/public_livechat} thread - * @param {Object} [options={}] - * @param {string} [options.headerBackgroundColor] - * @param {string} [options.titleColor] + * @param {Object} options + * @param {string} options.titleColor */ init(parent, messaging, thread, options) { this._super(parent); this.messaging = messaging; - this.options = _.defaults(options || {}, { - placeholder: _t("Say something"), - }); + this.options = options; this._thread = thread; @@ -77,8 +74,8 @@ const PublicLivechatWindow = Widget.extend({ this._publicLivechatView.$el.on('scroll', this, this._debouncedOnScroll); }); await Promise.all([this._super(), def]); - if (this.options.headerBackgroundColor) { - this.$('.o_thread_window_header').css('background-color', this.options.headerBackgroundColor); + if (this.messaging.publicLivechatGlobal.livechatButtonView.headerBackgroundColor) { + this.$('.o_thread_window_header').css('background-color', this.messaging.publicLivechatGlobal.livechatButtonView.headerBackgroundColor); } if (this.options.titleColor) { this.$('.o_thread_window_header').css('color', this.options.titleColor); @@ -122,10 +119,10 @@ const PublicLivechatWindow = Widget.extend({ renderHeader() { this.$header.html( qweb.render('im_livechat.legacy.PublicLivechatWindow.HeaderContent', { - status: this._thread._status, + status: this.messaging.publicLivechatGlobal.publicLivechat.status, thread: this._thread, - title: this._thread._name, - unreadCounter: this.messaging.livechatButtonView.publicLivechat.unreadCounter, + title: this.messaging.publicLivechatGlobal.publicLivechat.name, + unreadCounter: this.messaging.publicLivechatGlobal.publicLivechat.unreadCounter, widget: this, }) ); @@ -150,9 +147,9 @@ const PublicLivechatWindow = Widget.extend({ */ toggleFold(folded) { if (!_.isBoolean(folded)) { - folded = !this._thread._folded; + folded = !this.messaging.publicLivechatGlobal.publicLivechat.isFolded; } - this._updateThreadFoldState(folded); + this.messaging.publicLivechatGlobal.publicLivechat.update({ isFolded: folded }); this.trigger_up('save_chat_window'); this.updateVisualFoldState(); }, @@ -214,19 +211,6 @@ const PublicLivechatWindow = Widget.extend({ this._publicLivechatView.scrollToBottom(); }); }, - /** - * Update the fold state of the thread. - * - * This function is called when toggling the fold state of this window. - * If there is no thread linked to this window, it means this is the - * "blank" thread window, therefore we use the internal state 'folded' - * - * @private - * @param {boolean} folded - */ - _updateThreadFoldState(folded) { - this._thread.fold(folded); - }, //-------------------------------------------------------------------------- // Handlers @@ -243,7 +227,7 @@ const PublicLivechatWindow = Widget.extend({ ev.stopPropagation(); ev.preventDefault(); if ( - this.messaging.livechatButtonView.publicLivechat.unreadCounter > 0 && + this.messaging.publicLivechatGlobal.publicLivechat.unreadCounter > 0 && !this._thread._folded ) { this._thread.markAsRead(); diff --git a/addons/im_livechat/static/src/legacy/widgets/public_livechat_window/public_livechat_window.xml b/addons/im_livechat/static/src/legacy/widgets/public_livechat_window/public_livechat_window.xml index 59fa678ace4..6766793d952 100644 --- a/addons/im_livechat/static/src/legacy/widgets/public_livechat_window/public_livechat_window.xml +++ b/addons/im_livechat/static/src/legacy/widgets/public_livechat_window/public_livechat_window.xml @@ -7,16 +7,16 @@
- - - + + +
- +
diff --git a/addons/im_livechat/static/src/models/livechat_button_view.js b/addons/im_livechat/static/src/models/livechat_button_view.js index 9e5c78c7a8b..706a9cffa2b 100644 --- a/addons/im_livechat/static/src/models/livechat_button_view.js +++ b/addons/im_livechat/static/src/models/livechat_button_view.js @@ -6,7 +6,7 @@ import { clear, insertAndReplace } from '@mail/model/model_field_command'; registerModel({ name: 'LivechatButtonView', - identifyingFields: ['messaging'], + identifyingFields: ['publicLivechatGlobalOwner'], recordMethods: { /** * @private @@ -266,9 +266,10 @@ registerModel({ messages: attr({ default: [], }), - publicLivechat: one('PublicLivechat', { - inverse: 'livechatButtonOwner', - isCausal: true, + publicLivechatGlobalOwner: one('PublicLivechatGlobal', { + inverse: 'livechatButtonView', + readonly: true, + required: true, }), rule: attr(), serverUrl: attr({ diff --git a/addons/im_livechat/static/src/models/livechat_operator.js b/addons/im_livechat/static/src/models/livechat_operator.js new file mode 100644 index 00000000000..4bfdf0c11bd --- /dev/null +++ b/addons/im_livechat/static/src/models/livechat_operator.js @@ -0,0 +1,16 @@ +/** @odoo-module **/ + +import { registerModel } from '@mail/model/model_core'; +import { attr } from '@mail/model/model_field'; + +registerModel({ + name: 'LivechatOperator', + identifyingFields: ['id'], + fields: { + id: attr({ + readonly: true, + required: true, + }), + name: attr(), + }, +}); diff --git a/addons/im_livechat/static/src/models/messaging.js b/addons/im_livechat/static/src/models/messaging.js index 8d845ab7ae1..dd2d624339f 100644 --- a/addons/im_livechat/static/src/models/messaging.js +++ b/addons/im_livechat/static/src/models/messaging.js @@ -1,16 +1,12 @@ /** @odoo-module **/ -import { addFields, addRecordMethods, patchRecordMethods } from '@mail/model/model_core'; +import { addFields, patchRecordMethods } from '@mail/model/model_core'; import { many, one } from '@mail/model/model_field'; -import { clear, insertAndReplace } from '@mail/model/model_field_command'; +import { clear } from '@mail/model/model_field_command'; // ensure that the model definition is loaded before the patch import '@mail/models/messaging'; addFields('Messaging', { - livechatButtonView: one('LivechatButtonView', { - compute: '_computeLivechatButtonView', - isCausal: true, - }), /** * All pinned livechats that are known. */ @@ -23,19 +19,6 @@ addFields('Messaging', { }), }); -addRecordMethods('Messaging', { - /** - * @private - * @returns {FieldCommand} - */ - _computeLivechatButtonView() { - if (this.publicLivechatGlobal && this.publicLivechatGlobal.isAvailable) { - return insertAndReplace(); - } - return clear(); - }, -}); - patchRecordMethods('Messaging', { /** * @override diff --git a/addons/im_livechat/static/src/models/public_livechat.js b/addons/im_livechat/static/src/models/public_livechat.js index c9e49744b04..cd26ae84105 100644 --- a/addons/im_livechat/static/src/models/public_livechat.js +++ b/addons/im_livechat/static/src/models/public_livechat.js @@ -4,15 +4,16 @@ import PublicLivechat from '@im_livechat/legacy/models/public_livechat'; import { registerModel } from '@mail/model/model_core'; import { attr, many, one } from '@mail/model/model_field'; +import { clear, insertAndReplace } from '@mail/model/model_field_command'; registerModel({ name: 'PublicLivechat', - identifyingFields: ['livechatButtonOwner'], + identifyingFields: ['publicLivechatGlobalOwner'], lifecycleHooks: { _created() { this.update({ legacyPublicLivechat: new PublicLivechat(this.messaging, { - parent: this.livechatButtonOwner.widget, + parent: this.publicLivechatGlobalOwner.livechatButtonView.widget, data: this.data, }), }); @@ -22,19 +23,83 @@ registerModel({ }, }, recordMethods: { + /** + * @private + * @returns {FieldCommand|string} + */ + _computeName() { + if (!this.data) { + return clear(); + } + return this.data.name; + }, + /** + * @private + * @returns {FieldCommand} + */ + _computeOperator() { + if (!this.data) { + return clear(); + } + if (!this.data.operator_pid) { + return clear(); + } + if (!this.data.operator_pid[0]) { + return clear(); + } + return insertAndReplace({ + id: this.data.operator_pid[0], + name: this.data.operator_pid[1], + }); + }, + /** + * @private + * @returns {FieldCommand|string} + */ + _computeStatus() { + if (!this.data) { + return clear(); + } + return this.data.status || ''; + }, + /** + * @private + * @returns {FieldCommand|string} + */ + _computeUuid() { + if (!this.data) { + return clear(); + } + return this.data.uuid; + }, }, fields: { data: attr(), + isFolded: attr({ + default: false, + }), legacyPublicLivechat: attr(), - livechatButtonOwner: one('LivechatButtonView', { + publicLivechatGlobalOwner: one('PublicLivechatGlobal', { inverse: 'publicLivechat', readonly: true, required: true, }), messages: many('PublicLivechatMessage'), + name: attr({ + compute: '_computeName', + }), + operator: one('LivechatOperator', { + compute: '_computeOperator', + }), + status: attr({ + compute: '_computeStatus', + }), // amount of messages that have not yet been read on this chat unreadCounter: attr({ default: 0, }), + uuid: attr({ + compute: '_computeUuid', + }), }, }); diff --git a/addons/im_livechat/static/src/models/public_livechat_feedback_view.js b/addons/im_livechat/static/src/models/public_livechat_feedback_view.js new file mode 100644 index 00000000000..661486c379d --- /dev/null +++ b/addons/im_livechat/static/src/models/public_livechat_feedback_view.js @@ -0,0 +1,44 @@ +/** @odoo-module **/ + +import Feedback from '@im_livechat/legacy/widgets/feedback/feedback'; + +import { registerModel } from '@mail/model/model_core'; +import { attr, one } from '@mail/model/model_field'; + +registerModel({ + name: 'PublicLivechatFeedbackView', + identifyingFields: ['publicLivechatGlobalOwner'], + lifecycleHooks: { + _created() { + this.update({ + widget: new Feedback( + this.messaging.publicLivechatGlobal.livechatButtonView.widget, + this.messaging, + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat, + ), + }); + this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.replaceContentWith(this.widget); + this.widget.on('feedback_sent', null, this._onFeedbackSent); + this.widget.on('send_message', null, this._onSendMessage); + }, + _willDelete() { + this.widget.destroy(); + }, + }, + recordMethods: { + _onFeedbackSent(...args) { + this.messaging.publicLivechatGlobal.livechatButtonView.widget._closeChat(...args); + }, + _onSendMessage(...args) { + this.messaging.publicLivechatGlobal.livechatButtonView.widget._sendMessage(...args); + }, + }, + fields: { + publicLivechatGlobalOwner: one('PublicLivechatGlobal', { + inverse: 'feedbackView', + readonly: true, + required: true, + }), + widget: attr(), + }, +}); diff --git a/addons/im_livechat/static/src/models/public_livechat_global.js b/addons/im_livechat/static/src/models/public_livechat_global.js index ba551eae407..7300b053cbe 100644 --- a/addons/im_livechat/static/src/models/public_livechat_global.js +++ b/addons/im_livechat/static/src/models/public_livechat_global.js @@ -1,19 +1,82 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { attr } from '@mail/model/model_field'; +import { attr, one } from '@mail/model/model_field'; +import { clear, insertAndReplace } from '@mail/model/model_field_command'; + +import utils from 'web.utils'; registerModel({ name: 'PublicLivechatGlobal', identifyingFields: ['messaging'], + lifecycleHooks: { + _created() { + // History tracking + const page = window.location.href.replace(/^.*\/\/[^/]+/, ''); + const pageHistory = utils.get_cookie(this.LIVECHAT_COOKIE_HISTORY); + let urlHistory = []; + if (pageHistory) { + urlHistory = JSON.parse(pageHistory) || []; + } + if (!_.contains(urlHistory, page)) { + urlHistory.push(page); + while (urlHistory.length > this.HISTORY_LIMIT) { + urlHistory.shift(); + } + utils.set_cookie(this.LIVECHAT_COOKIE_HISTORY, JSON.stringify(urlHistory), 60 * 60 * 24); // 1 day cookie + } + }, + }, + recordMethods: { + /** + * @private + * @returns {FieldCommand} + */ + _computeLivechatButtonView() { + if (this.isAvailable) { + return insertAndReplace(); + } + return clear(); + }, + }, fields: { + HISTORY_LIMIT: attr({ + default: 15, + }), + LIVECHAT_COOKIE_HISTORY: attr({ + default: 'im_livechat_history', + }), + RATING_TO_EMOJI: attr({ + default: { + 5: "😊", + 3: "😐", + 1: "😞", + }, + }), chatbotServerUrl: attr(), + feedbackView: one('PublicLivechatFeedbackView', { + inverse: 'publicLivechatGlobalOwner', + isCausal: true, + }), isAvailable: attr({ default: false, }), + livechatButtonView: one('LivechatButtonView', { + compute: '_computeLivechatButtonView', + inverse: 'publicLivechatGlobalOwner', + isCausal: true, + }), + notificationHandler: one('PublicLivechatGlobalNotificationHandler', { + inverse: 'publicLivechatGlobalOwner', + isCausal: true, + }), options: attr({ default: {}, }), + publicLivechat: one('PublicLivechat', { + inverse: 'publicLivechatGlobalOwner', + isCausal: true, + }), serverUrl: attr({ default: '', }), diff --git a/addons/im_livechat/static/src/models/public_livechat_global_notification_handler.js b/addons/im_livechat/static/src/models/public_livechat_global_notification_handler.js new file mode 100644 index 00000000000..db95dcc5d9d --- /dev/null +++ b/addons/im_livechat/static/src/models/public_livechat_global_notification_handler.js @@ -0,0 +1,104 @@ +/** @odoo-module **/ + +import { registerModel } from '@mail/model/model_core'; +import { one } from '@mail/model/model_field'; +import { increment } from '@mail/model/model_field_command'; + +import session from 'web.session'; +import utils from 'web.utils'; + +registerModel({ + name: 'PublicLivechatGlobalNotificationHandler', + identifyingFields: ['publicLivechatGlobalOwner'], + lifecycleHooks: { + _created() { + this.env.services['bus_service'].addChannel(this.messaging.publicLivechatGlobal.publicLivechat.uuid); + this.env.services['bus_service'].startPolling(); + this.env.services['bus_service'].addEventListener('notification', this._onNotification); + }, + }, + recordMethods: { + /** + * @private + * @param {Object} notification + * @param {Object} notification.payload + * @param {string} notification.type + */ + _handleNotification({ payload, type }) { + switch (type) { + case 'im_livechat.history_command': { + if (payload.id !== this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id) { + return; + } + const cookie = utils.get_cookie(this.messaging.publicLivechatGlobal.LIVECHAT_COOKIE_HISTORY); + const history = cookie ? JSON.parse(cookie) : []; + session.rpc('/im_livechat/history', { + pid: this.messaging.publicLivechatGlobal.publicLivechat.operator.id, + channel_uuid: this.messaging.publicLivechatGlobal.publicLivechat.uuid, + page_history: history, + }); + return; + } + case 'mail.channel.member/typing_status': { + if (payload.channel_id !== this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id) { + return; + } + const partnerID = payload.partner_id; + if (partnerID === this.messaging.publicLivechatGlobal.livechatButtonView.currentPartnerId) { + // ignore typing display of current partner. + return; + } + if (payload.is_typing) { + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.registerTyping({ partnerID }); + } else { + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.unregisterTyping({ partnerID }); + } + return; + } + case 'mail.channel/new_message': { + if (payload.id !== this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id) { + return; + } + const notificationData = payload.message; + // If message from notif is already in chatter messages, stop handling + if (this.messaging.publicLivechatGlobal.livechatButtonView.messages.some(message => message.getID() === notificationData.id)) { + return; + } + notificationData.body = utils.Markup(notificationData.body); + this.messaging.publicLivechatGlobal.livechatButtonView.widget._addMessage(notificationData); + if (this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._thread._folded || !this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.isAtBottom()) { + this.messaging.publicLivechatGlobal.publicLivechat.update({ unreadCounter: increment() }); + } + this.messaging.publicLivechatGlobal.livechatButtonView.widget._renderMessages(); + return; + } + case 'mail.message/insert': { + const message = this.messaging.publicLivechatGlobal.livechatButtonView.messages.find(message => message._id === payload.id); + if (!message) { + return; + } + message._body = utils.Markup(payload.body); + this.messaging.publicLivechatGlobal.livechatButtonView.widget._renderMessages(); + return; + } + } + }, + /** + * @private + * @param {CustomEvent} ev + * @param {Array[]} [ev.detail] Notifications coming from the bus. + */ + _onNotification({ detail: notifications }) { + for (const notification of notifications) { + this._handleNotification(notification); + } + }, + }, + fields: { + publicLivechatGlobalOwner: one('PublicLivechatGlobal', { + inverse: 'notificationHandler', + readonly: true, + required: true, + }), + }, +}); diff --git a/addons/im_livechat/static/src/models/public_livechat_window.js b/addons/im_livechat/static/src/models/public_livechat_window.js index cc69ef41179..95eb56ad1da 100644 --- a/addons/im_livechat/static/src/models/public_livechat_window.js +++ b/addons/im_livechat/static/src/models/public_livechat_window.js @@ -14,12 +14,8 @@ registerModel({ legacyChatWindow: new PublicLivechatWindow( this.livechatButtonViewOwner.widget, this.messaging, - this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat, - { - headerBackgroundColor: this.livechatButtonViewOwner.headerBackgroundColor, - placeholder: this.livechatButtonViewOwner.inputPlaceholder, - titleColor: this.livechatButtonViewOwner.titleColor, - }, + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat, + { titleColor: this.livechatButtonViewOwner.titleColor }, ), }); }, @@ -27,7 +23,22 @@ registerModel({ this.legacyChatWindow.destroy(); }, }, + recordMethods: { + /** + * @private + * @returns {string} + */ + _computeInputPlaceholder() { + if (this.messaging.publicLivechatGlobal.livechatButtonView.inputPlaceholder) { + return this.messaging.publicLivechatGlobal.livechatButtonView.inputPlaceholder; + } + return this.env._t("Say something"); + }, + }, fields: { + inputPlaceholder: attr({ + compute: '_computeInputPlaceholder', + }), legacyChatWindow: attr({ default: null, }), diff --git a/addons/im_livechat/static/src/services/public_livechat_service.js b/addons/im_livechat/static/src/services/public_livechat_service.js index 74da48b285f..f614a7af63f 100644 --- a/addons/im_livechat/static/src/services/public_livechat_service.js +++ b/addons/im_livechat/static/src/services/public_livechat_service.js @@ -8,7 +8,7 @@ export const publicLivechatService = { dependencies: ['messaging'], async start(env, { messaging: messagingService }) { const messaging = await messagingService.get(); - if (messaging.livechatButtonView) { + if (messaging.publicLivechatGlobal.livechatButtonView) { const livechatButton = new LivechatButton(rootWidget, messaging); livechatButton.appendTo(document.body); } diff --git a/addons/website_livechat/static/src/legacy/public_livechat.js b/addons/website_livechat/static/src/legacy/public_livechat.js index 09c5736a122..294ab60aee4 100644 --- a/addons/website_livechat/static/src/legacy/public_livechat.js +++ b/addons/website_livechat/static/src/legacy/public_livechat.js @@ -17,8 +17,8 @@ LivechatButton.include({ * from backend to a website visitor. */ willStart: function () { - if (this.options.chat_request_session) { - utils.set_cookie('im_livechat_session', JSON.stringify(this.options.chat_request_session), 60*60); + if (this.messaging.publicLivechatGlobal.options.chat_request_session) { + utils.set_cookie('im_livechat_session', JSON.stringify(this.messaging.publicLivechatGlobal.options.chat_request_session), 60*60); } return this._super(); }, @@ -31,8 +31,8 @@ LivechatButton.include({ $(window).trigger('resize'); await this._super(...arguments); this.el.innerHTML = ""; - if (this.messaging.livechatButtonView.buttonText && !config.device.touch) { - this.el.dataset.content = this.messaging.livechatButtonView.buttonText; + if (this.messaging.publicLivechatGlobal.livechatButtonView.buttonText && !config.device.touch) { + this.el.dataset.content = this.messaging.publicLivechatGlobal.livechatButtonView.buttonText; this.el.dataset.toggle = "popover"; this.el.dataset.trigger = "hover"; this.$el.popover({ diff --git a/addons/website_livechat/static/src/legacy/website_livechat_chatbot_test_script.js b/addons/website_livechat/static/src/legacy/website_livechat_chatbot_test_script.js index 2aed88feef3..47ff9e09c1c 100644 --- a/addons/website_livechat/static/src/legacy/website_livechat_chatbot_test_script.js +++ b/addons/website_livechat/static/src/legacy/website_livechat_chatbot_test_script.js @@ -21,20 +21,20 @@ const LivechatButtonTestChatbot = LivechatButton.extend({ init: function (parent, messaging, chatbotData) { this._super(...arguments); - this.messaging.livechatButtonView.update({ + this.messaging.publicLivechatGlobal.livechatButtonView.update({ rule: { 'action': 'auto_popup', 'auto_popup_timer': 0, }, }); - this.messaging.livechatButtonView.update({ isTestChatbot: true }); - this.messaging.livechatButtonView.update({ testChatbotData: chatbotData.chatbot }); - this.messaging.livechatButtonView.chatbot.update({ + this.messaging.publicLivechatGlobal.livechatButtonView.update({ isTestChatbot: true }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ testChatbotData: chatbotData.chatbot }); + this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.update({ currentStep: insertAndReplace({ - data: this.messaging.livechatButtonView.chatbot.lastWelcomeStep, + data: this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.lastWelcomeStep, }), }); - this._channelData = this.messaging.livechatButtonView.testChatbotData.channel; + this._channelData = this.messaging.publicLivechatGlobal.livechatButtonView.testChatbotData.channel; }, /** @@ -58,17 +58,17 @@ const LivechatButtonTestChatbot = LivechatButton.extend({ * @override */ _openChat: function () { - this.messaging.livechatButtonView.update({ + this.messaging.publicLivechatGlobal.update({ publicLivechat: insertAndReplace({ data: this._channelData }), }); return this._openChatWindow().then(() => { this._sendWelcomeMessage(); this._renderMessages(); - this.call('bus_service', 'addChannel', this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._uuid); + this.call('bus_service', 'addChannel', this.messaging.publicLivechatGlobal.publicLivechat.uuid); this.call('bus_service', 'startPolling'); - utils.set_cookie('im_livechat_session', utils.unaccent(JSON.stringify(this.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat.toData()), true), 60 * 60); - this.messaging.livechatButtonView.update({ isOpeningChat: false }); + utils.set_cookie('im_livechat_session', utils.unaccent(JSON.stringify(this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.toData()), true), 60 * 60); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ isOpeningChat: false }); }); }, }); @@ -87,7 +87,7 @@ publicWidget.registry.livechatChatbotTestScript = publicWidget.Widget.extend({ utils.set_cookie('im_livechat_auto_popup', '', -1); utils.set_cookie('im_livechat_history', '', -1); utils.set_cookie('im_livechat_previous_operator_pid', '', -1); - const messaging = this.env.services.messaging.get(); + const messaging = await this.env.services.messaging.get(); return this._super(...arguments).then(() => { messaging.update({ publicLivechatGlobal: insertAndReplace({ isAvailable: true, chatbotServerUrl: this.$el.data().serverUrl }), diff --git a/addons/website_livechat/static/tests/tours/website_livechat_chatbot_flow.js b/addons/website_livechat/static/tests/tours/website_livechat_chatbot_flow.js index 0783f0a7a08..afaf892985d 100644 --- a/addons/website_livechat/static/tests/tours/website_livechat_chatbot_flow.js +++ b/addons/website_livechat/static/tests/tours/website_livechat_chatbot_flow.js @@ -11,7 +11,7 @@ LivechatButton.include({ * Let us also debounce waiting for more user inputs for only 500ms. */ start: function () { - this.messaging.livechatButtonView.update({ isWebsiteLivechatChatbotFlow: true }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ isWebsiteLivechatChatbotFlow: true }); this._debouncedChatbotAwaitUserInput = _.debounce( this._chatbotAwaitUserInput.bind(this), @@ -25,7 +25,7 @@ LivechatButton.include({ * the thread and making it hard to write proper jQuery selectors in the tour. */ _onChatbotRestartScript: function () { - this.messaging.livechatButtonView.update({ messages: clear() }); + this.messaging.publicLivechatGlobal.livechatButtonView.update({ messages: clear() }); this._renderMessages(); this._super(...arguments); diff --git a/addons/website_livechat/static/tests/tours/website_livechat_common.js b/addons/website_livechat/static/tests/tours/website_livechat_common.js index 2876a25a6cb..7d86ae248b8 100644 --- a/addons/website_livechat/static/tests/tours/website_livechat_common.js +++ b/addons/website_livechat/static/tests/tours/website_livechat_common.js @@ -27,12 +27,12 @@ LivechatButton.include({ else { session.rpc('/bus/test_mode_activated', {}).then(function (in_test_mode) { if (in_test_mode) { - self._handleNotification({ + self.messaging.publicLivechatGlobal.notificationHandler._handleNotification({ type: 'mail.channel/new_message', payload: { - id: self.messaging.livechatButtonView.publicLivechat.legacyPublicLivechat._id, + id: self.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id, message: { - id: self.messaging.livechatButtonView.messages.length + 1, + id: self.messaging.publicLivechatGlobal.livechatButtonView.messages.length + 1, author_id: [0, 'Website Visitor Test'], email_from: 'Website Visitor Test', body: utils.Markup('

' + message.content + '

'),