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 182294d0bba..9474d82f776 100644 --- a/addons/im_livechat/static/src/legacy/public_livechat_chatbot.js +++ b/addons/im_livechat/static/src/legacy/public_livechat_chatbot.js @@ -52,17 +52,16 @@ const QWeb = core.qweb; async willStart() { const superResult = await this._super(...arguments); - this._isChatbot = false; this.chatbotState = null; if (this._rule && !!this._rule.chatbot) { - this._isChatbot = true; + this.messaging.livechatButtonView.update({ isChatbot: true }); this.chatbotState = 'init'; } else if (this._history !== null && this._history.length === 0) { this._livechatInit = await session.rpc('/im_livechat/init', {channel_id: this.options.channel_id}); if (this._livechatInit.rule.chatbot) { - this._isChatbot = true; + this.messaging.livechatButtonView.update({ isChatbot: true }); this.chatbotState = 'welcome'; } } else if (this._history !== null && this._history.length !== 0) { @@ -70,18 +69,12 @@ const QWeb = core.qweb; if (sessionCookie) { const sessionKey = 'im_livechat.chatbot.state.uuid_' + JSON.parse(sessionCookie).uuid; if (localStorage.getItem(sessionKey)) { - this._isChatbot = true; + this.messaging.livechatButtonView.update({ isChatbot: true }); this.chatbotState = 'restore_session'; } } } - if (this._isChatbot) { - // void the default livechat placeholder in the user input - // as we use it for specific things (e.g: showing "please select an option above") - this.options.input_placeholder = ''; - } - if (this.chatbotState === 'init') { // we landed on a website page where a channel rule is configured to run a chatbot.script // -> initialize necessary state @@ -100,7 +93,7 @@ const QWeb = core.qweb; this._history = null; this._rule = this._livechatInit.rule; this._chatbot = this._livechatInit.rule.chatbot; - this._isChatbot = true; + this.messaging.livechatButtonView.update({ isChatbot: true }); this._chatbotBatchWelcomeMessages = true; } else if (this.chatbotState === 'restore_session') { // we landed on a website page and a chatbot script is currently running @@ -125,7 +118,7 @@ const QWeb = core.qweb; _chatbotAddMessage(message, options) { message.body = utils.Markup(message.body); this._addMessage(message, options); - if (this._chatWindow.isFolded() || !this._chatWindow.isAtBottom()) { + if (this.messaging.livechatButtonView.chatWindow.isFolded() || !this.messaging.livechatButtonView.chatWindow.isAtBottom()) { this._livechat.incrementUnreadCounter(); } @@ -208,7 +201,7 @@ const QWeb = core.qweb; * @private */ _chatbotDisableInput(disableText) { - this._chatWindow.$('.o_composer_text_field') + this.messaging.livechatButtonView.chatWindow.$('.o_composer_text_field') .prop('disabled', true) .addClass('text-center font-italic bg-200') .val(disableText); @@ -218,7 +211,7 @@ const QWeb = core.qweb; * @private */ _chatbotEnableInput() { - const $composerTextField = this._chatWindow.$('.o_composer_text_field'); + const $composerTextField = this.messaging.livechatButtonView.chatWindow.$('.o_composer_text_field'); $composerTextField .prop('disabled', false) .removeClass('text-center font-italic bg-200') @@ -241,9 +234,9 @@ const QWeb = core.qweb; * @private */ _chatbotEndScript() { - this._chatWindow.$('.o_composer_text_field').addClass('d-none'); - this._chatWindow.$('.o_livechat_chatbot_end').show(); - this._chatWindow.$('.o_livechat_chatbot_restart').one('click', + this.messaging.livechatButtonView.chatWindow.$('.o_composer_text_field').addClass('d-none'); + this.messaging.livechatButtonView.chatWindow.$('.o_livechat_chatbot_end').show(); + this.messaging.livechatButtonView.chatWindow.$('.o_livechat_chatbot_restart').one('click', this._onChatbotRestartScript.bind(this)); }, @@ -256,7 +249,7 @@ const QWeb = core.qweb; * @private */ _chatbotDisplayRestartButton() { - return this._isChatbot && (!this._chatbotCurrentStep || + return this.messaging.livechatButtonView.isChatbot && (!this._chatbotCurrentStep || (this._chatbotCurrentStep.chatbot_step_type !== 'forward_operator' || !this._chatbotCurrentStep.chatbot_operator_found)); }, @@ -327,7 +320,7 @@ const QWeb = core.qweb; if (triggerNextStep) { let nextStepDelay = this._chatbotMessageDelay; - if (this._chatWindow.$('.o_livechat_chatbot_typing').length !== 0) { + if (this.messaging.livechatButtonView.chatWindow.$('.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 @@ -343,7 +336,7 @@ const QWeb = core.qweb; } if (!this._chatbotDisplayRestartButton()) { - this._chatWindow.$('.o_livechat_chatbot_main_restart').addClass('d-none'); + this.messaging.livechatButtonView.chatWindow.$('.o_livechat_chatbot_main_restart').addClass('d-none'); } }, /** @@ -374,7 +367,7 @@ const QWeb = core.qweb; if (chatbotState) { chatbotState = JSON.parse(chatbotState); - this._isChatbot = true; + this.messaging.livechatButtonView.update({ isChatbot: true }); this._chatbot = chatbotState._chatbot; this._chatbotCurrentStep = chatbotState._chatbotCurrentStep; } @@ -408,7 +401,7 @@ const QWeb = core.qweb; this._chatbotDisableInput(''); this.isTypingTimeout = setTimeout(() => { - this._chatWindow.$('.o_mail_thread_content').append( + this.messaging.livechatButtonView.chatWindow.$('.o_mail_thread_content').append( $(QWeb.render('im_livechat.legacy.chatbot.is_typing_message', { 'chatbotImageSrc': `/im_livechat/operator/${this._livechat.getOperatorPID()[0]}/avatar`, 'chatbotName': this._chatbot.chatbot_name, @@ -416,7 +409,7 @@ const QWeb = core.qweb; })) ); - this._chatWindow.scrollToBottom(); + this.messaging.livechatButtonView.chatWindow.scrollToBottom(); }, this._chatbotMessageDelay / 3); }, /** @@ -564,9 +557,9 @@ const QWeb = core.qweb; _askFeedback() { this._super(...arguments); - this._chatWindow.$('.o_livechat_chatbot_main_restart').addClass('d-none'); - this._chatWindow.$('.o_livechat_chatbot_end').hide(); - this._chatWindow.$('.o_composer_text_field') + this.messaging.livechatButtonView.chatWindow.$('.o_livechat_chatbot_main_restart').addClass('d-none'); + this.messaging.livechatButtonView.chatWindow.$('.o_livechat_chatbot_end').hide(); + this.messaging.livechatButtonView.chatWindow.$('.o_composer_text_field') .removeClass('d-none') .val(''); }, @@ -584,8 +577,8 @@ const QWeb = core.qweb; _openChatWindow() { return this._super(...arguments).then(() => { window.addEventListener('resize', () => { - if (this._chatWindow) { - this._chatWindow.scrollToBottom(); + if (this.messaging.livechatButtonView.chatWindow) { + this.messaging.livechatButtonView.chatWindow.scrollToBottom(); } }); @@ -601,7 +594,7 @@ const QWeb = core.qweb; _prepareGetSessionParameters() { const parameters = this._super(...arguments); - if (this._isChatbot) { + if (this.messaging.livechatButtonView.isChatbot) { parameters.chatbot_script_id = this._chatbot.chatbot_script_id; } @@ -615,11 +608,11 @@ const QWeb = core.qweb; const self = this; - this._chatWindow.$('.o_thread_message:last .o_livechat_chatbot_options li').each(function () { + this.messaging.livechatButtonView.chatWindow.$('.o_thread_message:last .o_livechat_chatbot_options li').each(function () { $(this).on('click', self._onChatbotOptionClicked.bind(self)); }); - this._chatWindow.$('.o_livechat_chatbot_main_restart').on('click', + this.messaging.livechatButtonView.chatWindow.$('.o_livechat_chatbot_main_restart').on('click', this._onChatbotRestartScript.bind(this)); if (this._messages.length !== 0) { @@ -652,7 +645,7 @@ const QWeb = core.qweb; const superArguments = arguments; const superMethod = this._super; - if (this._isChatbot && this._chatbotCurrentStep) { + if (this.messaging.livechatButtonView.isChatbot && this._chatbotCurrentStep) { await this._chatbotPostWelcomeMessages(); } @@ -661,7 +654,7 @@ const QWeb = core.qweb; return; } - if (this._isChatbot && this._chatbotCurrentStep) { + if (this.messaging.livechatButtonView.isChatbot && this._chatbotCurrentStep) { if (this._chatbotCurrentStep.chatbot_step_type === 'forward_operator' && this._chatbotCurrentStep.chatbot_operator_found) { return; // operator has taken over the conversation, let them speak @@ -684,7 +677,7 @@ const QWeb = core.qweb; * @private */ _sendWelcomeMessage() { - if (this._isChatbot) { + if (this.messaging.livechatButtonView.isChatbot) { this._sendWelcomeChatbotMessage( 0, this._chatbotBatchWelcomeMessages ? 0 : this._chatbotMessageDelay, @@ -769,8 +762,8 @@ const QWeb = core.qweb; * @private */ async _onChatbotRestartScript(ev) { - this._chatWindow.$('.o_composer_text_field').removeClass('d-none'); - this._chatWindow.$('.o_livechat_chatbot_end').hide(); + this.messaging.livechatButtonView.chatWindow.$('.o_composer_text_field').removeClass('d-none'); + this.messaging.livechatButtonView.chatWindow.$('.o_livechat_chatbot_end').hide(); if (this.nextStepTimeout) { clearTimeout(this.nextStepTimeout); diff --git a/addons/im_livechat/static/src/legacy/website_livechat_message_chatbot.js b/addons/im_livechat/static/src/legacy/website_livechat_message_chatbot.js index f3ea176f7f9..1ad25dfcc55 100644 --- a/addons/im_livechat/static/src/legacy/website_livechat_message_chatbot.js +++ b/addons/im_livechat/static/src/legacy/website_livechat_message_chatbot.js @@ -19,7 +19,7 @@ WebsiteLivechatMessage.include({ init(parent, data, options) { this._super(...arguments); - if (parent._isChatbot) { + if (parent.messaging.livechatButtonView.isChatbot) { this._chatbotId = parent._chatbot.chatbot_script_id; this._chatbotName = parent._chatbot.chatbot_name; this._chatbotOperatorPartnerId = parent._chatbot.chatbot_operator_partner_id; 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 23d8e693872..15d8f9b7814 100644 --- a/addons/im_livechat/static/src/legacy/widgets/livechat_button.js +++ b/addons/im_livechat/static/src/legacy/widgets/livechat_button.js @@ -32,17 +32,12 @@ const LivechatButton = Widget.extend({ this._super(parent); this.messaging = messaging; this.options = _.defaults(this.messaging.publicLivechatOptions || {}, { - input_placeholder: _t("Ask something ..."), default_username: _t("Visitor"), - button_text: _t("Chat with one of our collaborators"), - default_message: _t("How may I help you?"), }); this._history = null; // livechat model this._livechat = null; - // livechat window - this._chatWindow = null; this._messages = []; this._serverURL = this.messaging.publicLivechatServerUrl; }, @@ -62,15 +57,16 @@ const LivechatButton = Widget.extend({ return this._loadQWebTemplate(); }, start() { - this.$el.text(this.options.button_text); + this.$el.text(this.messaging.livechatButtonView.buttonText); if (this._history) { this._history.forEach(m => this._addMessage(m)); this._openChat(); } else if (!config.device.isMobile && this._rule.action === 'auto_popup') { const autoPopupCookie = utils.get_cookie('im_livechat_auto_popup'); if (!autoPopupCookie || JSON.parse(autoPopupCookie)) { - this._autoPopupTimeout = - setTimeout(this._openChat.bind(this), this._rule.auto_popup_timer * 1000); + this.messaging.livechatButtonView.update({ + autoOpenChatTimeout: setTimeout(this._openChat.bind(this), this._rule.auto_popup_timer * 1000), + }); } } this.call('bus_service', 'onNotification', this, this._onNotification); @@ -127,10 +123,10 @@ const LivechatButton = Widget.extend({ * @private */ _askFeedback() { - this._chatWindow.$('.o_thread_composer input').prop('disabled', true); + this.messaging.livechatButtonView.chatWindow.$('.o_thread_composer input').prop('disabled', true); const feedback = new Feedback(this, this._livechat); - this._chatWindow.replaceContentWith(feedback); + this.messaging.livechatButtonView.chatWindow.replaceContentWith(feedback); feedback.on('send_message', this, this._sendMessage); feedback.on('feedback_sent', this, this._closeChat); @@ -139,7 +135,7 @@ const LivechatButton = Widget.extend({ * @private */ _closeChat() { - this._chatWindow.destroy(); + this.messaging.livechatButtonView.chatWindow.destroy(); utils.set_cookie('im_livechat_session', "", -1); // remove cookie }, /** @@ -190,7 +186,7 @@ const LivechatButton = Widget.extend({ } notificationData.body = utils.Markup(notificationData.body); this._addMessage(notificationData); - if (this._chatWindow.isFolded() || !this._chatWindow.isAtBottom()) { + if (this.messaging.livechatButtonView.chatWindow.isFolded() || !this.messaging.livechatButtonView.chatWindow.isAtBottom()) { this._livechat.incrementUnreadCounter(); } this._renderMessages(); @@ -221,13 +217,14 @@ const LivechatButton = Widget.extend({ * @private */ _openChat: _.debounce(function () { - if (this._openingChat) { + if (this.messaging.livechatButtonView.isOpeningChat) { return; } const cookie = utils.get_cookie('im_livechat_session'); let def; this._openingChat = true; - clearTimeout(this._autoPopupTimeout); + this.messaging.livechatButtonView.update({ isOpeningChat: true }); + clearTimeout(this.messaging.livechatButtonView.autoOpenChatTimeout); if (cookie) { def = Promise.resolve(JSON.parse(cookie)); } else { @@ -280,9 +277,9 @@ const LivechatButton = Widget.extend({ }); } }).then(() => { - this._openingChat = false; + this.messaging.livechatButtonView.update({ isOpeningChat: false }); }).guardedCatch(() => { - this._openingChat = false; + this.messaging.livechatButtonView.update({ isOpeningChat: false }); }); }, 200, true), /** @@ -311,14 +308,16 @@ const LivechatButton = Widget.extend({ const options = { displayStars: false, headerBackgroundColor: this.options.header_background_color, - placeholder: this.options.input_placeholder || "", + placeholder: this.messaging.livechatButtonView.inputPlaceholder, titleColor: this.options.title_color, }; - this._chatWindow = new WebsiteLivechatWindow(this, this._livechat, options); - return this._chatWindow.appendTo($('body')).then(() => { + this.messaging.livechatButtonView.update({ + chatWindow: new WebsiteLivechatWindow(this, this._livechat, options), + }); + return this.messaging.livechatButtonView.chatWindow.appendTo($('body')).then(() => { const cssProps = { bottom: 0 }; cssProps[_t.database.parameters.direction === 'rtl' ? 'left' : 'right'] = 0; - this._chatWindow.$el.css(cssProps); + this.messaging.livechatButtonView.chatWindow.$el.css(cssProps); this.$el.hide(); }); }, @@ -336,11 +335,11 @@ const LivechatButton = Widget.extend({ * @private */ _renderMessages() { - const shouldScroll = !this._chatWindow.isFolded() && this._chatWindow.isAtBottom(); + const shouldScroll = !this.messaging.livechatButtonView.chatWindow.isFolded() && this.messaging.livechatButtonView.chatWindow.isAtBottom(); this._livechat.setMessages(this._messages); - this._chatWindow.render(); + this.messaging.livechatButtonView.chatWindow.render(); if (shouldScroll) { - this._chatWindow.scrollToBottom(); + this.messaging.livechatButtonView.chatWindow.scrollToBottom(); } }, /** @@ -372,19 +371,19 @@ const LivechatButton = Widget.extend({ } this._closeChat(); } - this._chatWindow.scrollToBottom(); + this.messaging.livechatButtonView.chatWindow.scrollToBottom(); }); }, /** * @private */ _sendWelcomeMessage() { - if (this.options.default_message) { + if (this.messaging.livechatButtonView.defaultMessage) { this._addMessage({ id: '_welcome', attachment_ids: [], author_id: this._livechat.getOperatorPID(), - body: this.options.default_message, + body: this.messaging.livechatButtonView.defaultMessage, date: time.datetime_to_str(new Date()), model: "mail.channel", res_id: this._livechat.getID(), @@ -402,12 +401,12 @@ const LivechatButton = Widget.extend({ */ _onCloseChatWindow(ev) { ev.stopPropagation(); - const isComposerDisabled = this._chatWindow.$('.o_thread_composer input').prop('disabled'); + const isComposerDisabled = this.messaging.livechatButtonView.chatWindow.$('.o_thread_composer input').prop('disabled'); const shouldAskFeedback = !isComposerDisabled && this._messages.find(function (message) { return message.getID() !== '_welcome'; }); if (shouldAskFeedback) { - this._chatWindow.toggleFold(false); + this.messaging.livechatButtonView.chatWindow.toggleFold(false); this._askFeedback(); } else { this._closeChat(); @@ -450,7 +449,7 @@ const LivechatButton = Widget.extend({ */ _onUpdatedTypingPartners(ev) { ev.stopPropagation(); - this._chatWindow.renderHeader(); + this.messaging.livechatButtonView.chatWindow.renderHeader(); }, /** * @private @@ -458,7 +457,7 @@ const LivechatButton = Widget.extend({ */ _onUpdatedUnreadCounter(ev) { ev.stopPropagation(); - this._chatWindow.renderHeader(); + this.messaging.livechatButtonView.chatWindow.renderHeader(); }, /** * @private 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 23e8957e8d9..366b51d51a6 100644 --- a/addons/im_livechat/static/src/models/livechat_button_view.js +++ b/addons/im_livechat/static/src/models/livechat_button_view.js @@ -1,8 +1,69 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; +import { attr } from '@mail/model/model_field'; +import { clear } from '@mail/model/model_field_command'; registerModel({ name: 'LivechatButtonView', identifyingFields: ['messaging'], + recordMethods: { + /** + * @returns {string} + */ + _computeButtonText() { + if (this.messaging.publicLivechatOptions.button_text) { + return this.messaging.publicLivechatOptions.button_text; + } + return this.env._t("Chat with one of our collaborators"); + }, + /** + * @private + * @returns {string} + */ + _computeDefaultMessage() { + if (this.messaging.publicLivechatOptions.default_message) { + return this.messaging.publicLivechatOptions.default_message; + } + return this.env._t("How may I help you?"); + }, + /** + * @private + * @returns {string|FieldCommand} + */ + _computeInputPlaceholder() { + if (this.isChatbot) { + // void the default livechat placeholder in the user input + // as we use it for specific things (e.g: showing "please select an option above") + return clear(); + } + if (this.messaging.publicLivechatOptions.input_placeholder) { + return this.messaging.publicLivechatOptions.input_placeholder; + } + return this.env._t("Ask something ..."); + }, + }, + fields: { + autoOpenChatTimeout: attr(), + buttonText: attr({ + compute: '_computeButtonText', + }), + // livechat window + chatWindow: attr({ + default: null, + }), + defaultMessage: attr({ + compute: '_computeDefaultMessage', + }), + inputPlaceholder: attr({ + compute: '_computeInputPlaceholder', + default: '', + }), + isChatbot: attr({ + default: false, + }), + isOpeningChat: attr({ + default: false, + }), + }, }); diff --git a/addons/website_livechat/static/src/legacy/public_livechat.js b/addons/website_livechat/static/src/legacy/public_livechat.js index 9b063681f86..09c5736a122 100644 --- a/addons/website_livechat/static/src/legacy/public_livechat.js +++ b/addons/website_livechat/static/src/legacy/public_livechat.js @@ -31,8 +31,8 @@ LivechatButton.include({ $(window).trigger('resize'); await this._super(...arguments); this.el.innerHTML = ""; - if (this.options.button_text && !config.device.touch) { - this.el.dataset.content = this.options.button_text; + if (this.messaging.livechatButtonView.buttonText && !config.device.touch) { + this.el.dataset.content = this.messaging.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 6412c872155..3774ff0c345 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 @@ -28,10 +28,8 @@ const LivechatButtonTestChatbot = LivechatButton.extend({ this._chatbotCurrentStep = this._chatbot.chatbot_welcome_steps[ this._chatbot.chatbot_welcome_steps.length - 1]; this._channelData = chatbotData.channel; - this._isChatbot = true; + this.messaging.livechatButtonView.update({ isChatbot: true }); this._serverURL = chatbotData.serverUrl; - - this.options.input_placeholder = ''; }, /** @@ -66,7 +64,7 @@ const LivechatButtonTestChatbot = LivechatButton.extend({ this.call('bus_service', 'addChannel', this._livechat.getUUID()); this.call('bus_service', 'startPolling'); utils.set_cookie('im_livechat_session', utils.unaccent(JSON.stringify(this._livechat.toData()), true), 60 * 60); - this._openingChat = false; + this.messaging.livechatButtonView.update({ isOpeningChat: false }); }); }, });