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 babf6c7dca1..0c920eb4382 100644 --- a/addons/im_livechat/static/src/legacy/models/public_livechat.js +++ b/addons/im_livechat/static/src/legacy/models/public_livechat.js @@ -39,8 +39,6 @@ const PublicLivechat = Class.extend(Mixins.EventDispatcherMixin, { this.setParent(params.parent); this.messaging = messaging; - this._id = params.data.id; - /** * Initialize the internal data for typing feature on threads. * @@ -293,7 +291,7 @@ const PublicLivechat = Class.extend(Mixins.EventDispatcherMixin, { toData() { return { folded: this.messaging.publicLivechatGlobal.publicLivechat.isFolded, - id: this._id, + id: this.messaging.publicLivechatGlobal.publicLivechat.id, message_unread_counter: this.messaging.publicLivechatGlobal.publicLivechat.unreadCounter, operator_pid: ( this.messaging.publicLivechatGlobal.publicLivechat.operator 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 2691249db6c..15b01f6e99c 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 @@ -301,15 +301,6 @@ const PublicLivechatMessage = Class.extend({ notif.notification_status === 'bounce' ); }, - /** - * State whether this message originates from a channel. - * By default, messages do not originate from a channel. - * - * @return {boolean} - */ - originatesFromChannel() { - return false; - }, /** * State whether this message has a subject * By default, messages do not have any subject. 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 5fa95daaf87..fe1f0ed83a6 100644 --- a/addons/im_livechat/static/src/legacy/public_livechat_chatbot.js +++ b/addons/im_livechat/static/src/legacy/public_livechat_chatbot.js @@ -7,7 +7,7 @@ import time from 'web.time'; import utils from 'web.utils'; import LivechatButton from '@im_livechat/legacy/widgets/livechat_button'; -import { clear, increment, insertAndReplace } from '@mail/model/model_field_command'; +import { clear, increment, insertAndReplace, replace } from '@mail/model/model_field_command'; const _t = core._t; const QWeb = core.qweb; @@ -107,7 +107,7 @@ const QWeb = core.qweb; _chatbotAddMessage(message, options) { message.body = utils.Markup(message.body); this._addMessage(message, options); - if (this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._thread._folded || !this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.isAtBottom()) { + if (this.messaging.publicLivechatGlobal.publicLivechat.isFolded || !this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.isAtBottom()) { this.messaging.publicLivechatGlobal.publicLivechat.update({ unreadCounter: increment() }); } @@ -167,11 +167,13 @@ const QWeb = core.qweb; chatbot_script_id: this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.scriptId, }); - const welcomeMessagesIds = welcomeMessages.map(welcomeMessage => welcomeMessage._id); + const welcomeMessagesIds = welcomeMessages.map(welcomeMessage => welcomeMessage.id); this.messaging.publicLivechatGlobal.livechatButtonView.update({ - messages: this.messaging.publicLivechatGlobal.livechatButtonView.messages.filter((message) => { - !welcomeMessagesIds.includes(message._id); - }), + messages: replace( + this.messaging.publicLivechatGlobal.livechatButtonView.messages.filter((message) => { + !welcomeMessagesIds.includes(message.id); + }), + ), }); postedWelcomeMessages.reverse(); @@ -444,7 +446,7 @@ const QWeb = core.qweb; this.messaging.publicLivechatGlobal.livechatButtonView.messages.length !== 0 ) { const lastMessage = this.messaging.publicLivechatGlobal.livechatButtonView.messages[this.messaging.publicLivechatGlobal.livechatButtonView.messages.length - 1]; - if (lastMessage.getAuthorID() !== this.messaging.publicLivechatGlobal.publicLivechat.operator.id) { + if (lastMessage.legacyPublicLivechatMessage.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 @@ -542,7 +544,7 @@ const QWeb = core.qweb; */ _getWelcomeMessages() { return this.messaging.publicLivechatGlobal.livechatButtonView.messages.filter((message) => { - return message._id && typeof message._id === 'string' && message._id.startsWith('_welcome_'); + return message.id && typeof message.id === 'string' && message.id.startsWith('_welcome_'); }); }, /** @@ -552,7 +554,7 @@ const QWeb = core.qweb; */ _isLastMessageFromCustomer() { 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; + return lastMessage && lastMessage.legacyPublicLivechatMessage.getAuthorID() !== this.messaging.publicLivechatGlobal.publicLivechat.operator.id; }, //-------------------------------------------------------------------------- @@ -643,8 +645,8 @@ const QWeb = core.qweb; 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()) { + const stepAnswers = lastMessage.legacyPublicLivechatMessage.getChatbotStepAnswers(); + if (stepAnswers && stepAnswers.length !== 0 && !lastMessage.legacyPublicLivechatMessage.getChatbotStepAnswerId()) { this._chatbotDisableInput(_t('Select an option above')); } } @@ -766,7 +768,7 @@ const QWeb = core.qweb; date: time.datetime_to_str(new Date()), model: "mail.channel", message_type: "comment", - res_id: this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id, + res_id: this.messaging.publicLivechatGlobal.publicLivechat.id, }); } @@ -874,12 +876,12 @@ const QWeb = core.qweb; // but here we only care about the very last one (the current step of the script) // reversing the this.messages variable seems like a bad idea because it could have // bad implications for other flows (as the reverse is in-place, not in a copy) - if (message.getChatbotStepId() === stepId) { + if (message.legacyPublicLivechatMessage.getChatbotStepId() === stepId) { stepMessage = message; } } - const messageId = stepMessage.getID(); - stepMessage.setChatbotStepAnswerId(selectedAnswer); + const messageId = stepMessage.id; + stepMessage.legacyPublicLivechatMessage.setChatbotStepAnswerId(selectedAnswer); this.messaging.publicLivechatGlobal.livechatButtonView.chatbot.currentStep.data.chatbot_selected_answer_id = selectedAnswer; this._renderMessages(); this._chatbotSaveSession(); 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 96172c0d993..c96b4277138 100644 --- a/addons/im_livechat/static/src/legacy/widgets/livechat_button.js +++ b/addons/im_livechat/static/src/legacy/widgets/livechat_button.js @@ -9,7 +9,7 @@ import Widget from 'web.Widget'; import PublicLivechatMessage from '@im_livechat/legacy/models/public_livechat_message'; -import { clear, insert, insertAndReplace } from '@mail/model/model_field_command'; +import { clear, insertAndReplace, link, replace } from '@mail/model/model_field_command'; const _t = core._t; const QWeb = core.qweb; @@ -92,34 +92,35 @@ const LivechatButton = Widget.extend({ * @param {Object} [options={}] */ _addMessage(data, options) { - const message = new PublicLivechatMessage(this, this.messaging, data); + const legacyMessage = new PublicLivechatMessage(this, this.messaging, data); const hasAlreadyMessage = _.some(this.messaging.publicLivechatGlobal.livechatButtonView.messages, function (msg) { - return message.getID() === msg.getID(); + return legacyMessage.getID() === msg.id; }); if (hasAlreadyMessage) { return; } + const message = this.messaging.models['PublicLivechatMessage'].insert({ + id: data.id, + legacyPublicLivechatMessage: legacyMessage, + }); if (this.messaging.publicLivechatGlobal.publicLivechat) { this.messaging.publicLivechatGlobal.publicLivechat.update({ - messages: insert({ - id: data.id, - legacyPublicLivechatMessage: message, - }), + messages: link(message), }); } if (this.messaging.publicLivechatGlobal.publicLivechat && this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat) { - this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.addMessage(message); + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.addMessage(legacyMessage); } if (options && options.prepend) { this.messaging.publicLivechatGlobal.livechatButtonView.update({ - messages: [message, ...this.messaging.publicLivechatGlobal.livechatButtonView.messages], + messages: replace([message, ...this.messaging.publicLivechatGlobal.livechatButtonView.messages]), }); } else { this.messaging.publicLivechatGlobal.livechatButtonView.update({ - messages: [...this.messaging.publicLivechatGlobal.livechatButtonView.messages, message], + messages: replace([...this.messaging.publicLivechatGlobal.livechatButtonView.messages, message]), }); } }, @@ -257,8 +258,8 @@ const LivechatButton = Widget.extend({ * @private */ _renderMessages() { - 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; + const shouldScroll = !this.messaging.publicLivechatGlobal.publicLivechat.isFolded && this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.isAtBottom(); + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._messages = this.messaging.publicLivechatGlobal.livechatButtonView.messages.map(message => message.legacyPublicLivechatMessage); this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.render(); if (shouldScroll) { this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow._publicLivechatView.scrollToBottom(); @@ -311,7 +312,7 @@ const LivechatButton = Widget.extend({ body: this.messaging.publicLivechatGlobal.livechatButtonView.defaultMessage, date: time.datetime_to_str(new Date()), model: "mail.channel", - res_id: this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id, + res_id: this.messaging.publicLivechatGlobal.publicLivechat.id, }, { prepend: true }); } }, @@ -328,7 +329,7 @@ const LivechatButton = Widget.extend({ ev.stopPropagation(); 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'; + return message.id !== '_welcome'; }); if (shouldAskFeedback) { this.messaging.publicLivechatGlobal.livechatButtonView.chatWindow.legacyChatWindow.toggleFold(false); diff --git a/addons/im_livechat/static/src/legacy/widgets/public_livechat_view/public_livechat_view.js b/addons/im_livechat/static/src/legacy/widgets/public_livechat_view/public_livechat_view.js index 247919e9a53..08426bd4a8c 100644 --- a/addons/im_livechat/static/src/legacy/widgets/public_livechat_view/public_livechat_view.js +++ b/addons/im_livechat/static/src/legacy/widgets/public_livechat_view/public_livechat_view.js @@ -96,7 +96,6 @@ const PublicLivechatView = Widget.extend({ this._super(); }, /** - * @param {@im_livechat/legacy/models/public_livechat} thread the thread to render. * @param {Object} [options] * @param {integer} [options.displayOrder=ORDER.ASC] order of displaying * messages in the thread: @@ -109,15 +108,15 @@ const PublicLivechatView = Widget.extend({ * @param {boolean} [options.scrollToBottom=false] * @param {boolean} [options.squashCloseMessages] */ - render(thread, options) { + render(options) { let shouldScrollToBottomAfterRendering = false; - if (this._currentThreadID === thread._id && this.isAtBottom()) { + if (this._currentThreadID === this.messaging.publicLivechatGlobal.publicLivechat.id && this.isAtBottom()) { shouldScrollToBottomAfterRendering = true; } - this._currentThreadID = thread._id; + this._currentThreadID = this.messaging.publicLivechatGlobal.publicLivechat.id; // copy so that reverse do not alter order in the thread object - const messages = _.clone(thread.getMessages()); + const messages = _.clone(this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.getMessages()); const modeOptions = options.isCreateMode ? this._disabledOptions : this._enabledOptions; @@ -176,7 +175,7 @@ const PublicLivechatView = Widget.extend({ } this.$el.html(QWeb.render('im_livechat.legacy.mail.widget.Thread', { - thread, + thread: this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat, displayAuthorMessages, options, ORDER, @@ -231,30 +230,6 @@ const PublicLivechatView = Widget.extend({ const bottomHiddenHeight = fullHeight - topHiddenHeight - visibleHeight; return bottomHiddenHeight < 5; }, - /** - * Removes a message and re-renders the thread - * - * @param {integer} [messageID] the id of the removed message - * @param {mail.model.AbstractThread} thread the thread which contains - * updated list of messages (so it does not contain any message with ID - * `messageID`). - * @param {Object} [options] options for the thread rendering - */ - removeMessageAndRender(messageID, thread, options) { - this._currentThreadID = thread._id; - return new Promise((resolve, reject) => { - this.$('.o_thread_message[data-message-id="' + messageID + '"]') - .fadeOut({ - done: () => { - if (this._currentThreadID === thread._id) { - this.render(thread, options); - } - resolve(); - }, - duration: 200, - }); - }); - }, /** * Scroll to the bottom of the thread */ diff --git a/addons/im_livechat/static/src/legacy/widgets/public_livechat_view/public_livechat_view.xml b/addons/im_livechat/static/src/legacy/widgets/public_livechat_view/public_livechat_view.xml index 08cfa0d1b8b..e95655253da 100644 --- a/addons/im_livechat/static/src/legacy/widgets/public_livechat_view/public_livechat_view.xml +++ b/addons/im_livechat/static/src/legacy/widgets/public_livechat_view/public_livechat_view.xml @@ -187,9 +187,6 @@ on - - (from #) - { this._publicLivechatView.scrollToBottom(); }); @@ -228,9 +226,9 @@ const PublicLivechatWindow = Widget.extend({ ev.preventDefault(); if ( this.messaging.publicLivechatGlobal.publicLivechat.unreadCounter > 0 && - !this._thread._folded + !this.messaging.publicLivechatGlobal.publicLivechat.isFolded ) { - this._thread.markAsRead(); + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.markAsRead(); } this.close(); }, @@ -271,7 +269,7 @@ const PublicLivechatWindow = Widget.extend({ */ _onInput() { const isTyping = this.$input.val().length > 0; - this._thread.setMyselfTyping({ typing: isTyping }); + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.setMyselfTyping({ typing: isTyping }); }, /** * Called when typing something on the composer of this thread window. @@ -307,7 +305,7 @@ const PublicLivechatWindow = Widget.extend({ */ _onScroll() { if (this._publicLivechatView.isAtBottom()) { - this._thread.markAsRead(); + this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat.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 6766793d952..77592af7fd8 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 @@ -4,13 +4,13 @@ @param {im_livechat.legacy.PublicLivechatWindow} widget --> -
+
- +
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 706a9cffa2b..3fcaf91eb8a 100644 --- a/addons/im_livechat/static/src/models/livechat_button_view.js +++ b/addons/im_livechat/static/src/models/livechat_button_view.js @@ -1,7 +1,7 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { attr, one } from '@mail/model/model_field'; +import { attr, many, one } from '@mail/model/model_field'; import { clear, insertAndReplace } from '@mail/model/model_field_command'; registerModel({ @@ -263,9 +263,7 @@ registerModel({ localStorageChatbotState: attr({ compute: '_computeLocalStorageChatbotState', }), - messages: attr({ - default: [], - }), + messages: many('PublicLivechatMessage'), publicLivechatGlobalOwner: one('PublicLivechatGlobal', { inverse: 'livechatButtonView', readonly: true, diff --git a/addons/im_livechat/static/src/models/public_livechat.js b/addons/im_livechat/static/src/models/public_livechat.js index cd26ae84105..844166361e7 100644 --- a/addons/im_livechat/static/src/models/public_livechat.js +++ b/addons/im_livechat/static/src/models/public_livechat.js @@ -23,6 +23,16 @@ registerModel({ }, }, recordMethods: { + /** + * @private + * @returns {integer|FieldCommand} + */ + _computeId() { + if (!this.data) { + return clear(); + } + return this.data.id; + }, /** * @private * @returns {FieldCommand|string} @@ -75,6 +85,9 @@ registerModel({ }, fields: { data: attr(), + id: attr({ + compute: '_computeId', + }), isFolded: attr({ default: false, }), 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 index db95dcc5d9d..ca25f5c54c5 100644 --- 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 @@ -27,7 +27,7 @@ registerModel({ _handleNotification({ payload, type }) { switch (type) { case 'im_livechat.history_command': { - if (payload.id !== this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id) { + if (payload.id !== this.messaging.publicLivechatGlobal.publicLivechat.id) { return; } const cookie = utils.get_cookie(this.messaging.publicLivechatGlobal.LIVECHAT_COOKIE_HISTORY); @@ -40,7 +40,7 @@ registerModel({ return; } case 'mail.channel.member/typing_status': { - if (payload.channel_id !== this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id) { + if (payload.channel_id !== this.messaging.publicLivechatGlobal.publicLivechat.id) { return; } const partnerID = payload.partner_id; @@ -56,28 +56,28 @@ registerModel({ return; } case 'mail.channel/new_message': { - if (payload.id !== this.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id) { + if (payload.id !== this.messaging.publicLivechatGlobal.publicLivechat.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)) { + if (this.messaging.publicLivechatGlobal.livechatButtonView.messages.some(message => message.id === 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()) { + if (this.messaging.publicLivechatGlobal.publicLivechat.isFolded || !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); + const message = this.messaging.publicLivechatGlobal.livechatButtonView.messages.find(message => message.id === payload.id); if (!message) { return; } - message._body = utils.Markup(payload.body); + message.legacyPublicLivechatMessage._body = utils.Markup(payload.body); this.messaging.publicLivechatGlobal.livechatButtonView.widget._renderMessages(); return; } 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 7d86ae248b8..9544ea45a2f 100644 --- a/addons/website_livechat/static/tests/tours/website_livechat_common.js +++ b/addons/website_livechat/static/tests/tours/website_livechat_common.js @@ -30,7 +30,7 @@ LivechatButton.include({ self.messaging.publicLivechatGlobal.notificationHandler._handleNotification({ type: 'mail.channel/new_message', payload: { - id: self.messaging.publicLivechatGlobal.publicLivechat.legacyPublicLivechat._id, + id: self.messaging.publicLivechatGlobal.publicLivechat.id, message: { id: self.messaging.publicLivechatGlobal.livechatButtonView.messages.length + 1, author_id: [0, 'Website Visitor Test'],