From 603cd70ecc577407a8e7acfbfd741261c04d7708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20K=C3=BChn?= Date: Fri, 22 Sep 2023 14:59:40 +0200 Subject: [PATCH] [REF] mail: move service.update() to discuss models These `update()` functions are specific to a discuss record, so it's best to be defined in the model rather than another service. Part-of: odoo/odoo#136308 --- .../src/embed/core/thread_model_patch.js | 11 + .../src/embed/core/thread_service_patch.js | 11 - .../src/core/common/attachment_model.js | 37 +++- .../src/core/common/attachment_service.js | 35 --- .../src/core/common/channel_member_model.js | 43 +++- .../src/core/common/channel_member_service.js | 42 ---- .../static/src/core/common/message_model.js | 133 +++++++++++- .../static/src/core/common/message_service.js | 203 +----------------- .../core/common/notification_group_model.js | 31 ++- .../src/core/common/notification_model.js | 30 ++- .../static/src/core/common/persona_model.js | 16 +- .../static/src/core/common/persona_service.js | 15 -- .../static/src/core/common/thread_model.js | 137 +++++++++++- .../static/src/core/common/thread_service.js | 141 +----------- .../src/core/web/thread_service_patch.js | 2 +- .../call/common/call_participant_card.js | 4 +- .../src/discuss/call/common/rtc_service.js | 46 +--- .../discuss/call/common/thread_model_patch.js | 47 ++++ .../common/discuss_core_common_service.js | 2 +- .../message_pin/common/message_pin_service.js | 47 ++-- .../common/attachment_model_patch.js | 6 + .../common/attachment_service_patch.js | 6 - .../static/src/core/persona_model_patch.js | 16 ++ .../static/src/core/persona_service_patch.js | 23 -- .../static/src/core/thread_model_patch.js | 18 ++ .../static/src/core/thread_service_patch.js | 11 - .../static/src/embed/thread_model_patch.js | 12 ++ .../static/src/embed/thread_service_patch.js | 12 -- 28 files changed, 555 insertions(+), 582 deletions(-) create mode 100644 addons/mail/static/src/discuss/call/common/thread_model_patch.js delete mode 100644 addons/website_livechat/static/src/core/persona_service_patch.js create mode 100644 addons/website_livechat/static/src/core/thread_model_patch.js create mode 100644 addons/website_livechat/static/src/embed/thread_model_patch.js delete mode 100644 addons/website_livechat/static/src/embed/thread_service_patch.js diff --git a/addons/im_livechat/static/src/embed/core/thread_model_patch.js b/addons/im_livechat/static/src/embed/core/thread_model_patch.js index 290859e2378..9176ee01ec3 100644 --- a/addons/im_livechat/static/src/embed/core/thread_model_patch.js +++ b/addons/im_livechat/static/src/embed/core/thread_model_patch.js @@ -48,6 +48,17 @@ patch(Thread, { patch(Thread.prototype, { chatbotScriptId: null, + update(data) { + super.update(...arguments); + if (data.operator_pid) { + this.operator = this._store.Persona.insert({ + type: "partner", + id: data.operator_pid[0], + name: data.operator_pid[1], + }); + } + }, + get isChannel() { return this.type === "livechat" || super.isChannel; }, diff --git a/addons/im_livechat/static/src/embed/core/thread_service_patch.js b/addons/im_livechat/static/src/embed/core/thread_service_patch.js index 554707e9fba..1a10f179613 100644 --- a/addons/im_livechat/static/src/embed/core/thread_service_patch.js +++ b/addons/im_livechat/static/src/embed/core/thread_service_patch.js @@ -63,17 +63,6 @@ patch(ThreadService.prototype, { } }, - async update(thread, data) { - super.update(...arguments); - if (data.operator_pid) { - thread.operator = this.store.Persona.insert({ - type: "partner", - id: data.operator_pid[0], - name: data.operator_pid[1], - }); - } - }, - avatarUrl(author, thread) { if (thread.type !== "livechat") { return super.avatarUrl(...arguments); diff --git a/addons/mail/static/src/core/common/attachment_model.js b/addons/mail/static/src/core/common/attachment_model.js index b63a1a8dc61..aae6784b6be 100644 --- a/addons/mail/static/src/core/common/attachment_model.js +++ b/addons/mail/static/src/core/common/attachment_model.js @@ -28,10 +28,45 @@ export class Attachment extends Record { } const attachment = this.get(data) ?? this.new(data); Object.assign(attachment, { id: data.id }); - this.env.services["mail.attachment"].update(attachment, data); + attachment.update(data); return attachment; } + update(data) { + assignDefined(this, data, [ + "checksum", + "create_date", + "filename", + "mimetype", + "name", + "type", + "url", + "uploading", + "extension", + "accessToken", + "tmpUrl", + "message", + "res_name", + ]); + if (!("extension" in data) && data["name"]) { + this.extension = this.name.split(".").pop(); + } + if (data.originThread !== undefined) { + const threadData = Array.isArray(data.originThread) + ? data.originThread[0][1] + : data.originThread; + this.originThread = this._store.Thread.insert({ + model: threadData.model, + id: threadData.id, + }); + const thread = this.originThread; + if (this.notIn(thread.attachments)) { + thread.attachments.push(this); + thread.attachments.sort((a1, a2) => (a1.id < a2.id ? 1 : -1)); + } + } + } + accessToken; checksum; extension; diff --git a/addons/mail/static/src/core/common/attachment_service.js b/addons/mail/static/src/core/common/attachment_service.js index 61bf69a90c0..412768ddc61 100644 --- a/addons/mail/static/src/core/common/attachment_service.js +++ b/addons/mail/static/src/core/common/attachment_service.js @@ -19,41 +19,6 @@ export class AttachmentService { this.rpc = services["rpc"]; } - update(attachment, data) { - assignDefined(attachment, data, [ - "checksum", - "create_date", - "filename", - "mimetype", - "name", - "type", - "url", - "uploading", - "extension", - "accessToken", - "tmpUrl", - "message", - "res_name", - ]); - if (!("extension" in data) && data["name"]) { - attachment.extension = attachment.name.split(".").pop(); - } - if (data.originThread !== undefined) { - const threadData = Array.isArray(data.originThread) - ? data.originThread[0][1] - : data.originThread; - attachment.originThread = this.store.Thread.insert({ - model: threadData.model, - id: threadData.id, - }); - const thread = attachment.originThread; - if (attachment.notIn(thread.attachments)) { - thread.attachments.push(attachment); - thread.attachments.sort((a1, a2) => (a1.id < a2.id ? 1 : -1)); - } - } - } - /** * Remove the given attachment globally. * diff --git a/addons/mail/static/src/core/common/channel_member_model.js b/addons/mail/static/src/core/common/channel_member_model.js index ff2b5e7ca35..1c32f6af1c5 100644 --- a/addons/mail/static/src/core/common/channel_member_model.js +++ b/addons/mail/static/src/core/common/channel_member_model.js @@ -1,6 +1,7 @@ /* @odoo-module */ import { Record } from "@mail/core/common/record"; +import { removeFromArray } from "@mail/utils/common/arrays"; /** * @class ChannelMember @@ -28,10 +29,50 @@ export class ChannelMember extends Record { static insert(data) { const memberData = Array.isArray(data) ? data[1] : data; const member = this.get(memberData) ?? this.new(memberData); - this.env.services["discuss.channel.member"].update(member, data); + member.update(data); return member; } + update(data) { + const [command, memberData] = Array.isArray(data) ? data : ["insert", data]; + this.id = memberData.id; + if ("persona" in memberData) { + this.persona = this._store.Persona.insert({ + ...(memberData.persona.partner ?? memberData.persona.guest), + type: memberData.persona.guest ? "guest" : "partner", + country: memberData.persona.partner?.country, + channelId: memberData.persona.guest ? memberData.channel.id : null, + }); + } + let thread = memberData.thread ?? this.thread; + if (!thread && memberData.channel?.id) { + thread = this._store.Thread.insert({ + id: memberData.channel.id, + model: "discuss.channel", + }); + } + if (thread && !this.thread) { + this.thread = thread; + } + switch (command) { + case "insert": + { + if (this.thread && this.notIn(this.thread.channelMembers)) { + this.thread.channelMembers.push(this); + } + } + break; + case "unlink": + removeFromArray(this._store.ChannelMember.records, this); + // eslint-disable-next-line no-fallthrough + case "insert-and-unlink": + if (this.thread) { + removeFromArray(this.thread.channelMembers, this); + } + break; + } + } + /** @type {number} */ id; persona = Record.one("Persona"); diff --git a/addons/mail/static/src/core/common/channel_member_service.js b/addons/mail/static/src/core/common/channel_member_service.js index b7f5e2172d5..3f741bc8719 100644 --- a/addons/mail/static/src/core/common/channel_member_service.js +++ b/addons/mail/static/src/core/common/channel_member_service.js @@ -1,7 +1,5 @@ /* @odoo-module */ -import { removeFromArray } from "@mail/utils/common/arrays"; - import { registry } from "@web/core/registry"; export class ChannelMemberService { @@ -14,46 +12,6 @@ export class ChannelMemberService { this.store = services["mail.store"]; } - update(member, data) { - const [command, memberData] = Array.isArray(data) ? data : ["insert", data]; - member.id = memberData.id; - if ("persona" in memberData) { - member.persona = this.store.Persona.insert({ - ...(memberData.persona.partner ?? memberData.persona.guest), - type: memberData.persona.guest ? "guest" : "partner", - country: memberData.persona.partner?.country, - channelId: memberData.persona.guest ? memberData.channel.id : null, - }); - } - let thread = memberData.thread ?? member.thread; - if (!thread && memberData.channel?.id) { - thread = this.store.Thread.insert({ - id: memberData.channel.id, - model: "discuss.channel", - }); - } - if (thread && !member.thread) { - member.thread = thread; - } - switch (command) { - case "insert": - { - if (member.thread && member.notIn(member.thread.channelMembers)) { - member.thread.channelMembers.push(member); - } - } - break; - case "unlink": - removeFromArray(this.store.ChannelMember.records, member); - // eslint-disable-next-line no-fallthrough - case "insert-and-unlink": - if (member.thread) { - removeFromArray(member.thread.channelMembers, member); - } - break; - } - } - /** * @param {import("models").ChannelMember} member * @returns {string} diff --git a/addons/mail/static/src/core/common/message_model.js b/addons/mail/static/src/core/common/message_model.js index 45f5ea562a0..e0780e82ad3 100644 --- a/addons/mail/static/src/core/common/message_model.js +++ b/addons/mail/static/src/core/common/message_model.js @@ -1,7 +1,9 @@ /* @odoo-module */ import { Record } from "@mail/core/common/record"; +import { replaceArrayWithCompare } from "@mail/utils/common/arrays"; import { htmlToTextContentInline } from "@mail/utils/common/format"; +import { assignDefined } from "@mail/utils/common/misc"; import { toRaw } from "@odoo/owl"; @@ -36,10 +38,139 @@ export class Message extends Record { }); } const message = this.get(data) ?? this.new(data); - this.env.services["mail.message"].update(message, data); + message.update(data); return message; } + /** @param {Object} data */ + update(data) { + const { + attachment_ids: attachments = this.attachments, + default_subject: defaultSubject = this.defaultSubject, + is_discussion: isDiscussion = this.isDiscussion, + is_note: isNote = this.isNote, + is_transient: isTransient = this.isTransient, + linkPreviews = this.linkPreviews, + message_type: type = this.type, + model: resModel = this.resModel, + module_icon, + notifications = this.notifications, + parentMessage, + recipients = this.recipients, + record_name, + res_id: resId = this.resId, + res_model_name, + subtype_description: subtypeDescription = this.subtypeDescription, + ...remainingData + } = data; + assignDefined(this, remainingData); + assignDefined(this, { + defaultSubject, + isDiscussion, + isNote, + isStarred: this._store.user + ? this.starred_partner_ids.includes(this._store.user.id) + : false, + isTransient, + parentMessage: parentMessage ? this._store.Message.insert(parentMessage) : undefined, + resId, + resModel, + subtypeDescription, + type, + }); + // origin thread before other information (in particular notification insert uses it) + if (this.originThread) { + assignDefined(this.originThread, { + modelName: res_model_name || undefined, + module_icon: module_icon || undefined, + name: + this.originThread.model === "discuss.channel" + ? undefined + : record_name || undefined, + }); + } + replaceArrayWithCompare( + this.attachments, + attachments.map((attachment) => + this._store.Attachment.insert({ message: this, ...attachment }) + ) + ); + if ( + Array.isArray(this.author) && + this.author.some((command) => command.includes("clear")) + ) { + this.author = undefined; + } + if (data.author?.id) { + this.author = this._store.Persona.insert({ + ...data.author, + type: "partner", + }); + } + if (data.guestAuthor?.id) { + this.author = this._store.Persona.insert({ + ...data.guestAuthor, + type: "guest", + channelId: this.originThread.id, + }); + } + replaceArrayWithCompare( + this.linkPreviews, + linkPreviews.map((data) => this._store.LinkPreview.insert({ ...data, message: this })) + ); + replaceArrayWithCompare( + this.notifications, + notifications.map((notification) => + this._store.Notification.insert({ ...notification, message: this }) + ) + ); + replaceArrayWithCompare( + this.recipients, + recipients.map((recipient) => + this._store.Persona.insert({ ...recipient, type: "partner" }) + ) + ); + if ("user_follower_id" in data && data.user_follower_id && this._store.self) { + this.originThread.selfFollower = this._store.Follower.insert({ + followedThread: this.originThread, + id: data.user_follower_id, + isActive: true, + partner: this._store.self, + }); + } + if (data.messageReactionGroups) { + const reactionContentToUnlink = new Set(); + const reactionsToInsert = []; + for (const rawReaction of data.messageReactionGroups) { + const [command, reactionData] = Array.isArray(rawReaction) + ? rawReaction + : ["insert", rawReaction]; + const reaction = this._store.MessageReactions.insert(reactionData); + if (command === "insert") { + reactionsToInsert.push(reaction); + } else { + reactionContentToUnlink.add(reaction.content); + } + } + this.reactions = this.reactions.filter( + ({ content }) => !reactionContentToUnlink.has(content) + ); + reactionsToInsert.forEach((reaction) => { + const idx = this.reactions.findIndex(({ content }) => reaction.content === content); + if (idx !== -1) { + this.reactions[idx] = reaction; + } else { + this.reactions.push(reaction); + } + }); + } + if (this.isNotification && !this.notificationType) { + const parser = new DOMParser(); + const htmlBody = parser.parseFromString(this.body, "text/html"); + this.notificationType = htmlBody.querySelector(".o_mail_notification")?.dataset.oeType; + } + } + attachments = Record.many("Attachment"); author = Record.one("Persona"); /** @type {string} */ diff --git a/addons/mail/static/src/core/common/message_service.js b/addons/mail/static/src/core/common/message_service.js index 38fc997f9fe..c081790ca54 100644 --- a/addons/mail/static/src/core/common/message_service.js +++ b/addons/mail/static/src/core/common/message_service.js @@ -1,8 +1,7 @@ /* @odoo-module */ -import { removeFromArrayWithPredicate, replaceArrayWithCompare } from "@mail/utils/common/arrays"; +import { removeFromArrayWithPredicate } from "@mail/utils/common/arrays"; import { convertBrToLineBreak, prettifyMessageContent } from "@mail/utils/common/format"; -import { assignDefined } from "@mail/utils/common/misc"; import { markup } from "@odoo/owl"; @@ -202,206 +201,6 @@ export class MessageService { } } - /** - * @param {import("models").Message} message - * @param {Object} data - */ - update(message, data) { - const { - attachment_ids: attachments = message.attachments, - default_subject: defaultSubject = message.defaultSubject, - is_discussion: isDiscussion = message.isDiscussion, - is_note: isNote = message.isNote, - is_transient: isTransient = message.isTransient, - linkPreviews = message.linkPreviews, - message_type: type = message.type, - model: resModel = message.resModel, - module_icon, - notifications = message.notifications, - parentMessage, - recipients = message.recipients, - record_name, - res_id: resId = message.resId, - res_model_name, - subtype_description: subtypeDescription = message.subtypeDescription, - ...remainingData - } = data; - assignDefined(message, remainingData); - assignDefined(message, { - defaultSubject, - isDiscussion, - isNote, - isStarred: this.store.user - ? message.starred_partner_ids.includes(this.store.user.id) - : false, - isTransient, - parentMessage: parentMessage ? this.store.Message.insert(parentMessage) : undefined, - resId, - resModel, - subtypeDescription, - type, - }); - // origin thread before other information (in particular notification insert uses it) - if (message.originThread) { - assignDefined(message.originThread, { - modelName: res_model_name || undefined, - module_icon: module_icon || undefined, - name: - message.originThread.model === "discuss.channel" - ? undefined - : record_name || undefined, - }); - } - replaceArrayWithCompare( - message.attachments, - attachments.map((attachment) => - this.store.Attachment.insert({ message, ...attachment }) - ) - ); - if ( - Array.isArray(message.author) && - message.author.some((command) => command.includes("clear")) - ) { - message.author = undefined; - } - if (data.author?.id) { - message.author = this.store.Persona.insert({ - ...data.author, - type: "partner", - }); - } - if (data.guestAuthor?.id) { - message.author = this.store.Persona.insert({ - ...data.guestAuthor, - type: "guest", - channelId: message.originThread.id, - }); - } - replaceArrayWithCompare( - message.linkPreviews, - linkPreviews.map((data) => this.store.LinkPreview.insert({ ...data, message })) - ); - replaceArrayWithCompare( - message.notifications, - notifications.map((notification) => - this.store.Notification.insert({ ...notification, message }) - ) - ); - replaceArrayWithCompare( - message.recipients, - recipients.map((recipient) => - this.store.Persona.insert({ ...recipient, type: "partner" }) - ) - ); - if ("user_follower_id" in data && data.user_follower_id && this.store.self) { - message.originThread.selfFollower = this.env.services["mail.store"].Follower.insert({ - followedThread: message.originThread, - id: data.user_follower_id, - isActive: true, - partner: this.store.self, - }); - } - if (data.messageReactionGroups) { - this._updateReactions(message, data.messageReactionGroups); - } - if (message.isNotification && !message.notificationType) { - const parser = new DOMParser(); - const htmlBody = parser.parseFromString(message.body, "text/html"); - message.notificationType = - htmlBody.querySelector(".o_mail_notification")?.dataset.oeType; - } - this.env.bus.trigger("mail.message/onUpdate", { message, data }); - } - - /** - * @param {import("models").Message} message - */ - _updateReactions(message, reactionGroups) { - const reactionContentToUnlink = new Set(); - const reactionsToInsert = []; - for (const rawReaction of reactionGroups) { - const [command, reactionData] = Array.isArray(rawReaction) - ? rawReaction - : ["insert", rawReaction]; - const reaction = this.store.MessageReactions.insert(reactionData); - if (command === "insert") { - reactionsToInsert.push(reaction); - } else { - reactionContentToUnlink.add(reaction.content); - } - } - message.reactions = message.reactions.filter( - ({ content }) => !reactionContentToUnlink.has(content) - ); - reactionsToInsert.forEach((reaction) => { - const idx = message.reactions.findIndex(({ content }) => reaction.content === content); - if (idx !== -1) { - message.reactions[idx] = reaction; - } else { - message.reactions.push(reaction); - } - }); - } - - updateNotification(notification, data) { - Object.assign(notification, { - message: data.message, - notification_status: data.notification_status, - notification_type: data.notification_type, - failure_type: data.failure_type, - persona: data.res_partner_id - ? this.store.Persona.insert({ - id: data.res_partner_id[0], - displayName: data.res_partner_id[1], - type: "partner", - }) - : undefined, - }); - if (!notification.message.author?.eq(this.store.self)) { - return; - } - const thread = notification.message.originThread; - this.store.NotificationGroup.insert({ - modelName: thread?.modelName, - resId: thread?.id, - resModel: thread?.model, - status: notification.notification_status, - type: notification.notification_type, - notifications: [ - [notification.isFailure ? "insert" : "insert-and-unlink", notification], - ], - }); - } - - updateNotificationGroup(group, data) { - Object.assign(group, { - modelName: data.modelName ?? group.modelName, - resModel: data.resModel ?? group.resModel, - type: data.type ?? group.type, - status: data.status ?? group.status, - }); - const notifications = data.notifications ?? []; - const alreadyKnownNotifications = new Set(group.notifications.map(({ id }) => id)); - const notificationIdsToRemove = new Set(); - for (const [commandName, notification] of notifications) { - if (commandName === "insert" && !alreadyKnownNotifications.has(notification.id)) { - group.notifications.push(notification); - } else if (commandName === "insert-and-unlink") { - notificationIdsToRemove.add(notification.id); - } - } - group.notifications = group.notifications.filter( - ({ id }) => !notificationIdsToRemove.has(id) - ); - group.lastMessage = group.notifications[0]?.message; - for (const notification of group.notifications) { - if (group.lastMessage?.id < notification.message?.id) { - group.lastMessage = notification.message; - } - } - group.resIds.add(data.resId); - } - scheduledDateSimple(message) { return message.scheduledDate.toLocaleString(DateTime.TIME_SIMPLE, { locale: this.userService.lang?.replace("_", "-"), diff --git a/addons/mail/static/src/core/common/notification_group_model.js b/addons/mail/static/src/core/common/notification_group_model.js index 3058075a53b..423e7fb72c2 100644 --- a/addons/mail/static/src/core/common/notification_group_model.js +++ b/addons/mail/static/src/core/common/notification_group_model.js @@ -38,13 +38,42 @@ export class NotificationGroup extends Record { // return reactive group = this.store.NotificationGroup.records.find((g) => g.eq(group)); } - this.env.services["mail.message"].updateNotificationGroup(group, data); + group.update(data); if (group.notifications.length === 0) { removeFromArrayWithPredicate(this.records, (gr) => gr.eq(group)); } return group; } + update(data) { + Object.assign(this, { + modelName: data.modelName ?? this.modelName, + resModel: data.resModel ?? this.resModel, + type: data.type ?? this.type, + status: data.status ?? this.status, + }); + const notifications = data.notifications ?? []; + const alreadyKnownNotifications = new Set(this.notifications.map(({ id }) => id)); + const notificationIdsToRemove = new Set(); + for (const [commandName, notification] of notifications) { + if (commandName === "insert" && !alreadyKnownNotifications.has(notification.id)) { + this.notifications.push(notification); + } else if (commandName === "insert-and-unlink") { + notificationIdsToRemove.add(notification.id); + } + } + this.notifications = this.notifications.filter( + ({ id }) => !notificationIdsToRemove.has(id) + ); + this.lastMessage = this.notifications[0]?.message; + for (const notification of this.notifications) { + if (this.lastMessage?.id < notification.message?.id) { + this.lastMessage = notification.message; + } + } + this.resIds.add(data.resId); + } + notifications = Record.many("Notification"); /** @type {string} */ modelName; diff --git a/addons/mail/static/src/core/common/notification_model.js b/addons/mail/static/src/core/common/notification_model.js index 5984ad0fba0..a1d0c1f1f16 100644 --- a/addons/mail/static/src/core/common/notification_model.js +++ b/addons/mail/static/src/core/common/notification_model.js @@ -23,10 +23,38 @@ export class Notification extends Record { static insert(data) { const notification = this.get(data) ?? this.new(data); Object.assign(notification, { id: data.id }); - this.env.services["mail.message"].updateNotification(notification, data); + notification.update(data); return notification; } + update(data) { + Object.assign(this, { + message: data.message, + notification_status: data.notification_status, + notification_type: data.notification_type, + failure_type: data.failure_type, + persona: data.res_partner_id + ? this._store.Persona.insert({ + id: data.res_partner_id[0], + displayName: data.res_partner_id[1], + type: "partner", + }) + : undefined, + }); + if (!this.message.author?.eq(this._store.self)) { + return; + } + const thread = this.message.originThread; + this._store.NotificationGroup.insert({ + modelName: thread?.modelName, + resId: thread?.id, + resModel: thread?.model, + status: this.notification_status, + type: this.notification_type, + notifications: [[this.isFailure ? "insert" : "insert-and-unlink", this]], + }); + } + /** @type {number} */ id; message = Record.one("Message"); diff --git a/addons/mail/static/src/core/common/persona_model.js b/addons/mail/static/src/core/common/persona_model.js index 87569a59c46..2f6133639c6 100644 --- a/addons/mail/static/src/core/common/persona_model.js +++ b/addons/mail/static/src/core/common/persona_model.js @@ -1,6 +1,7 @@ /* @odoo-module */ import { AND, Record } from "@mail/core/common/record"; +import { assignDefined, nullifyClearCommands } from "@mail/utils/common/misc"; /** * @typedef {'offline' | 'bot' | 'online' | 'away' | 'im_partner' | undefined} ImStatus @@ -30,11 +31,24 @@ export class Persona extends Record { */ static insert(data) { const persona = this.get(data) ?? this.new(data); - this.env.services["mail.persona"].update(persona, data); + persona.update(data); // return reactive version return persona; } + update(data) { + nullifyClearCommands(data); + assignDefined(this, { ...data }); + if ( + this.type === "partner" && + this.im_status !== "im_partner" && + !this.is_public && + !this._store.registeredImStatusPartners?.includes(this.id) + ) { + this._store.registeredImStatusPartners?.push(this.id); + } + } + /** @type {number} */ id; /** @type {boolean | undefined} */ diff --git a/addons/mail/static/src/core/common/persona_service.js b/addons/mail/static/src/core/common/persona_service.js index 5d6cf610a3a..8acb9998e15 100644 --- a/addons/mail/static/src/core/common/persona_service.js +++ b/addons/mail/static/src/core/common/persona_service.js @@ -1,7 +1,5 @@ /* @odoo-module */ -import { assignDefined, nullifyClearCommands } from "@mail/utils/common/misc"; - import { registry } from "@web/core/registry"; import { useSequential } from "@mail/utils/common/hooks"; import { markRaw } from "@odoo/owl"; @@ -38,19 +36,6 @@ export class PersonaService { }); } - update(persona, data) { - nullifyClearCommands(data); - assignDefined(persona, { ...data }); - if ( - persona.type === "partner" && - persona.im_status !== "im_partner" && - !persona.is_public && - !this.store.registeredImStatusPartners?.includes(persona.id) - ) { - this.store.registeredImStatusPartners?.push(persona.id); - } - } - async fetchIsCompany(persona) { if (persona.type !== "partner") { // non-partner persona are always considered as not a company diff --git a/addons/mail/static/src/core/common/thread_model.js b/addons/mail/static/src/core/common/thread_model.js index f114a23c0b7..bb83be4b9cf 100644 --- a/addons/mail/static/src/core/common/thread_model.js +++ b/addons/mail/static/src/core/common/thread_model.js @@ -2,7 +2,8 @@ import { AND, Record } from "@mail/core/common/record"; import { ScrollPosition } from "@mail/core/common/scroll_position"; -import { onChange } from "@mail/utils/common/misc"; +import { replaceArrayWithCompare } from "@mail/utils/common/arrays"; +import { assignDefined, nullifyClearCommands, onChange } from "@mail/utils/common/misc"; import { deserializeDateTime } from "@web/core/l10n/dates"; import { _t } from "@web/core/l10n/translation"; @@ -57,7 +58,7 @@ export class Thread extends Record { } let thread = this.get(data); if (thread) { - this.env.services["mail.thread"].update(thread, data); + thread.update(data); return thread; } thread = this.new(data); @@ -78,12 +79,142 @@ export class Thread extends Record { this.store.discuss.threadLocalId = null; } }); - this.env.services["mail.thread"].update(thread, data); + thread.update(data); this.store.Composer.insert({ thread }); // return reactive version. return thread; } + /** @param {Object} data */ + update(data) { + const { id, name, attachments: attachmentsData, description, ...serverData } = data; + assignDefined(this, { id, name, description }); + if (attachmentsData) { + replaceArrayWithCompare( + this.attachments, + attachmentsData + .map((attachmentData) => this._store.Attachment.insert(attachmentData)) + .sort((a1, a2) => a2.id - a1.id) + ); + } + if (serverData) { + assignDefined(this, serverData, [ + "uuid", + "authorizedGroupFullName", + "description", + "hasWriteAccess", + "is_pinned", + "isLoaded", + "isLoadingAttachments", + "mainAttachment", + "message_unread_counter", + "message_needaction_counter", + "name", + "seen_message_id", + "state", + "type", + "status", + "group_based_subscription", + "last_interest_dt", + "is_editable", + "defaultDisplayMode", + ]); + if (serverData.channel && "message_unread_counter" in serverData.channel) { + this.message_unread_counter = serverData.channel.message_unread_counter; + } + const lastServerMessageId = serverData.last_message_id ?? this.lastServerMessage?.id; + if (this.lastServerMessage?.id !== lastServerMessageId) { + this.lastServerMessage = this._store.Message.insert({ + id: lastServerMessageId, + }); + } + if (this.model === "discuss.channel" && serverData.channel) { + nullifyClearCommands(serverData.channel); + this.channel = assignDefined(this.channel ?? {}, serverData.channel); + } + + this.memberCount = serverData.channel?.memberCount ?? this.memberCount; + if (this.type === "chat" && serverData.channel) { + this.customName = serverData.channel.custom_channel_name; + } + if (serverData.channel?.channelMembers) { + for (const [command, membersData] of serverData.channel.channelMembers) { + const members = Array.isArray(membersData) ? membersData : [membersData]; + for (const memberData of members) { + const member = this._store.ChannelMember.insert([command, memberData]); + if (this.type !== "chat") { + continue; + } + if ( + member.persona.notEq(this._store.user) || + (serverData.channel.channelMembers[0][1].length === 1 && + member.persona?.eq(this._store.user)) + ) { + this.chatPartner = member.persona; + } + } + } + } + if ("invitedMembers" in serverData) { + if (!serverData.invitedMembers) { + this.invitedMemberIds.clear(); + return; + } + const command = serverData.invitedMembers[0][0]; + const members = serverData.invitedMembers[0][1]; + switch (command) { + case "insert": + if (members) { + for (const member of members) { + const record = this._store.ChannelMember.insert(member); + this.invitedMemberIds.add(record.id); + } + } + break; + case "unlink": + case "insert-and-unlink": + // eslint-disable-next-line no-case-declarations + for (const member of members) { + this.invitedMemberIds.delete(member.id); + } + break; + } + } + if ("seen_partners_info" in serverData) { + this.seenInfos = serverData.seen_partners_info.map( + ({ fetched_message_id, partner_id, seen_message_id }) => { + return { + lastFetchedMessage: fetched_message_id + ? this._store.Message.insert({ id: fetched_message_id }) + : undefined, + lastSeenMessage: seen_message_id + ? this._store.Message.insert({ id: seen_message_id }) + : undefined, + partner: this._store.Persona.insert({ + id: partner_id, + type: "partner", + }), + }; + } + ); + } + } + if ( + this.type === "channel" && + !this._store.discuss.channels.threads.includes(this.localId) + ) { + this._store.discuss.channels.threads.push(this.localId); + } else if ( + (this.type === "chat" || this.type === "group") && + !this._store.discuss.chats.threads.includes(this.localId) + ) { + this._store.discuss.chats.threads.push(this.localId); + } + if (!this.type && !["mail.box", "discuss.channel"].includes(this.model)) { + this.type = "chatter"; + } + } + /** @type {number} */ id; /** @type {string} */ diff --git a/addons/mail/static/src/core/common/thread_service.js b/addons/mail/static/src/core/common/thread_service.js index cada4a01b29..8bd093170ba 100644 --- a/addons/mail/static/src/core/common/thread_service.js +++ b/addons/mail/static/src/core/common/thread_service.js @@ -2,9 +2,8 @@ import { loadEmoji } from "@web/core/emoji_picker/emoji_picker"; import { DEFAULT_AVATAR } from "@mail/core/common/persona_service"; -import { removeFromArray, replaceArrayWithCompare } from "@mail/utils/common/arrays"; +import { removeFromArray } from "@mail/utils/common/arrays"; import { prettifyMessageContent } from "@mail/utils/common/format"; -import { assignDefined, nullifyClearCommands } from "@mail/utils/common/misc"; import { markup } from "@odoo/owl"; @@ -120,7 +119,7 @@ export class ThreadService { newUnreadCounter++; } } - this.update(thread, { + thread.update({ seen_message_id: lastSeenId, message_needaction_counter: newNeedactionCounter, message_unread_counter: newUnreadCounter, @@ -203,7 +202,7 @@ export class ThreadService { Object.assign(data, { body: data.body ? markup(data.body) : data.body }) ); }); - this.update(thread, { isLoaded: true }); + thread.update({ isLoaded: true }); return messages; } catch (e) { thread.hasLoadingFailed = true; @@ -663,140 +662,6 @@ export class ThreadService { thread.delete(); } - /** - * @param {import("models").Thread} thread - * @param {Object} data - */ - update(thread, data) { - const { id, name, attachments: attachmentsData, description, ...serverData } = data; - assignDefined(thread, { id, name, description }); - if (attachmentsData) { - replaceArrayWithCompare( - thread.attachments, - attachmentsData.map((attachmentData) => - this.store.Attachment.insert(attachmentData) - ) - ); - } - if (serverData) { - assignDefined(thread, serverData, [ - "uuid", - "authorizedGroupFullName", - "description", - "hasWriteAccess", - "is_pinned", - "isLoaded", - "isLoadingAttachments", - "mainAttachment", - "message_unread_counter", - "message_needaction_counter", - "name", - "seen_message_id", - "state", - "type", - "status", - "group_based_subscription", - "last_interest_dt", - "is_editable", - "defaultDisplayMode", - ]); - if (serverData.channel && "message_unread_counter" in serverData.channel) { - thread.message_unread_counter = serverData.channel.message_unread_counter; - } - const lastServerMessageId = serverData.last_message_id ?? thread.lastServerMessage?.id; - if (thread.lastServerMessage?.id !== lastServerMessageId) { - thread.lastServerMessage = this.store.Message.insert({ - id: lastServerMessageId, - }); - } - if (thread.model === "discuss.channel" && serverData.channel) { - nullifyClearCommands(serverData.channel); - thread.channel = assignDefined(thread.channel ?? {}, serverData.channel); - } - - thread.memberCount = serverData.channel?.memberCount ?? thread.memberCount; - if (thread.type === "chat" && serverData.channel) { - thread.customName = serverData.channel.custom_channel_name; - } - if (serverData.channel?.channelMembers) { - for (const [command, membersData] of serverData.channel.channelMembers) { - const members = Array.isArray(membersData) ? membersData : [membersData]; - for (const memberData of members) { - const member = this.store.ChannelMember.insert([command, memberData]); - if (thread.type !== "chat") { - continue; - } - if ( - member.persona.notEq(thread._store.user) || - (serverData.channel.channelMembers[0][1].length === 1 && - member.persona?.eq(thread._store.user)) - ) { - thread.chatPartner = member.persona; - } - } - } - } - if ("invitedMembers" in serverData) { - if (!serverData.invitedMembers) { - thread.invitedMemberIds.clear(); - return; - } - const command = serverData.invitedMembers[0][0]; - const members = serverData.invitedMembers[0][1]; - switch (command) { - case "insert": - if (members) { - for (const member of members) { - const record = this.store.ChannelMember.insert(member); - thread.invitedMemberIds.add(record.id); - } - } - break; - case "unlink": - case "insert-and-unlink": - // eslint-disable-next-line no-case-declarations - for (const member of members) { - thread.invitedMemberIds.delete(member.id); - } - break; - } - } - if ("seen_partners_info" in serverData) { - thread.seenInfos = serverData.seen_partners_info.map( - ({ fetched_message_id, partner_id, seen_message_id }) => { - return { - lastFetchedMessage: fetched_message_id - ? this.store.Message.insert({ id: fetched_message_id }) - : undefined, - lastSeenMessage: seen_message_id - ? this.store.Message.insert({ id: seen_message_id }) - : undefined, - partner: this.store.Persona.insert({ - id: partner_id, - type: "partner", - }), - }; - } - ); - } - } - if ( - thread.type === "channel" && - !this.store.discuss.channels.threads.includes(thread.localId) - ) { - this.store.discuss.channels.threads.push(thread.localId); - } else if ( - (thread.type === "chat" || thread.type === "group") && - !this.store.discuss.chats.threads.includes(thread.localId) - ) { - this.store.discuss.chats.threads.push(thread.localId); - } - if (!thread.type && !["mail.box", "discuss.channel"].includes(thread.model)) { - thread.type = "chatter"; - } - this.env.bus.trigger("mail.thread/onUpdate", { thread, data }); - } - /** * @param {import("models").Thread} thread * @param {string} body diff --git a/addons/mail/static/src/core/web/thread_service_patch.js b/addons/mail/static/src/core/web/thread_service_patch.js index 705ce189552..367883deeae 100644 --- a/addons/mail/static/src/core/web/thread_service_patch.js +++ b/addons/mail/static/src/core/web/thread_service_patch.js @@ -63,7 +63,7 @@ patch(ThreadService.prototype, { } } if ("attachments" in result) { - this.update(thread, { + thread.update({ areAttachmentsLoaded: true, attachments: result.attachments, isLoadingAttachments: false, diff --git a/addons/mail/static/src/discuss/call/common/call_participant_card.js b/addons/mail/static/src/discuss/call/common/call_participant_card.js index 07dff85d8ea..52968071521 100644 --- a/addons/mail/static/src/discuss/call/common/call_participant_card.js +++ b/addons/mail/static/src/discuss/call/common/call_participant_card.js @@ -141,9 +141,7 @@ export class CallParticipantCard extends Component { channel_id: this.props.thread.id, member_ids: [this.channelMember.id], }); - this.threadService.update(this.props.thread, { - invitedMembers: channelData.invitedMembers, - }); + this.props.thread.update({ invitedMembers: channelData.invitedMembers }); } async onClickReplay() { diff --git a/addons/mail/static/src/discuss/call/common/rtc_service.js b/addons/mail/static/src/discuss/call/common/rtc_service.js index c3b36ad7bac..379fd5ba514 100644 --- a/addons/mail/static/src/discuss/call/common/rtc_service.js +++ b/addons/mail/static/src/discuss/call/common/rtc_service.js @@ -2,7 +2,6 @@ import { BlurManager } from "@mail/discuss/call/common/blur_manager"; import { monitorAudio } from "@mail/discuss/call/common/media_monitoring"; -import { removeFromArray } from "@mail/utils/common/arrays"; import { closeStream, onChange } from "@mail/utils/common/misc"; import { reactive } from "@odoo/owl"; @@ -158,9 +157,6 @@ export class Rtc { await this.resetAudioTrack({ force: true }); } }); - this.env.bus.addEventListener("mail.thread/onUpdate", ({ detail: { thread, data } }) => { - this.onThreadUpdate(thread, data); - }); this.env.bus.addEventListener( "RTC-SERVICE:UPDATE_RTC_SESSIONS", ({ detail: { commands = [], record, thread } }) => { @@ -284,44 +280,6 @@ export class Rtc { ); } - onThreadUpdate(thread, data) { - if ("rtc_inviting_session" in data) { - this.env.bus.trigger("RTC-SERVICE:UPDATE_RTC_SESSIONS", { - thread, - record: data.rtc_inviting_session, - }); - thread.rtcInvitingSession = this.store.RtcSession.insert({ - id: data.rtc_inviting_session.id, - }); - if (!this.store.ringingThreads.includes(thread.localId)) { - this.store.ringingThreads.push(thread.localId); - } - } - if ("rtcInvitingSession" in data) { - if (Array.isArray(data.rtcInvitingSession)) { - if (data.rtcInvitingSession[0][0] === "unlink") { - thread.rtcInvitingSession = undefined; - removeFromArray(this.store.ringingThreads, thread.localId); - } - return; - } - this.env.bus.trigger("RTC-SERVICE:UPDATE_RTC_SESSIONS", { - thread, - record: data.rtcInvitingSession, - }); - thread.rtcInvitingSession = this.store.RtcSession.insert({ - id: data.rtcInvitingSession.id, - }); - this.store.ringingThreads.push(thread.localId); - } - if ("rtcSessions" in data) { - this.env.bus.trigger("RTC-SERVICE:UPDATE_RTC_SESSIONS", { - thread, - commands: data.rtcSessions, - }); - } - } - /** * @param {any} id */ @@ -781,7 +739,7 @@ export class Rtc { this.notification.add(_t("Your browser does not support webRTC."), { type: "warning" }); return; } - const { rtcSessions, iceServers, sessionId, invitedMembers } = await this.rpc( + const { rtcSessions, iceServers, sessionId } = await this.rpc( "/mail/rtc/channel/join_call", { channel_id: channel.id, @@ -795,7 +753,7 @@ export class Rtc { this.clear(); this.state.logs.clear(); this.state.channel = channel; - this.onThreadUpdate(this.state.channel, { rtcSessions, invitedMembers }); + this.state.channel.update({ rtcSessions }); this.state.selfSession = this.store.RtcSession.get(sessionId); this.state.iceServers = iceServers || DEFAULT_ICE_SERVERS; this.state.logs.set("channelId", this.state.channel?.id); diff --git a/addons/mail/static/src/discuss/call/common/thread_model_patch.js b/addons/mail/static/src/discuss/call/common/thread_model_patch.js new file mode 100644 index 00000000000..873978371e6 --- /dev/null +++ b/addons/mail/static/src/discuss/call/common/thread_model_patch.js @@ -0,0 +1,47 @@ +/* @odoo-module */ + +import { Thread } from "@mail/core/common/thread_model"; +import { removeFromArray } from "@mail/utils/common/arrays"; + +import { patch } from "@web/core/utils/patch"; + +patch(Thread.prototype, { + update(data) { + super.update(data); + if ("rtc_inviting_session" in data) { + this.Model.env.bus.trigger("RTC-SERVICE:UPDATE_RTC_SESSIONS", { + thread: this, + record: data.rtc_inviting_session, + }); + this.rtcInvitingSession = this._store.RtcSession.insert({ + id: data.rtc_inviting_session.id, + }); + if (!this._store.ringingThreads.includes(this.localId)) { + this._store.ringingThreads.push(this.localId); + } + } + if ("rtcInvitingSession" in data) { + if (Array.isArray(data.rtcInvitingSession)) { + if (data.rtcInvitingSession[0][0] === "unlink") { + this.rtcInvitingSession = undefined; + removeFromArray(this._store.ringingThreads, this.localId); + } + return; + } + this.Model.env.bus.trigger("RTC-SERVICE:UPDATE_RTC_SESSIONS", { + thread: this, + record: data.rtcInvitingSession, + }); + this.rtcInvitingSession = this._store.RtcSession.insert({ + id: data.rtcInvitingSession.id, + }); + this._store.ringingThreads.push(this.localId); + } + if ("rtcSessions" in data) { + this.Model.env.bus.trigger("RTC-SERVICE:UPDATE_RTC_SESSIONS", { + thread: this, + commands: data.rtcSessions, + }); + } + }, +}); diff --git a/addons/mail/static/src/discuss/core/common/discuss_core_common_service.js b/addons/mail/static/src/discuss/core/common/discuss_core_common_service.js index 6d6095fb06e..e45f550ffb0 100644 --- a/addons/mail/static/src/discuss/core/common/discuss_core_common_service.js +++ b/addons/mail/static/src/discuss/core/common/discuss_core_common_service.js @@ -49,7 +49,7 @@ export class DiscussCoreCommon { const { id, last_interest_dt } = payload; const channel = this.store.Thread.get({ model: "discuss.channel", id }); if (channel) { - this.threadService.update(channel, { last_interest_dt }); + channel.update({ last_interest_dt }); if (channel.type !== "channel") { this.threadService.sortChannels(); } diff --git a/addons/mail/static/src/discuss/message_pin/common/message_pin_service.js b/addons/mail/static/src/discuss/message_pin/common/message_pin_service.js index 1eb2fa61cfb..0157c9caea8 100644 --- a/addons/mail/static/src/discuss/message_pin/common/message_pin_service.js +++ b/addons/mail/static/src/discuss/message_pin/common/message_pin_service.js @@ -29,6 +29,24 @@ patch(MessageModel.prototype, { /** @type {string} */ this.pinnedAt = undefined; }, + update(data) { + super.update(data); + const { pinned_at: pinnedAt } = data; + if ( + this.originThread?.model === "discuss.channel" && + (pinnedAt !== undefined || this.isEmpty) + ) { + if (pinnedAt && !this.isEmpty) { + if (this.notIn(this.originThread.pinnedMessages)) { + this.originThread.pinnedMessages.push(this); + } + this.pinnedAt = pinnedAt; + } else { + delete this.pinnedAt; + this.originThread.pinnedMessages.delete(this); + } + } + }, }); export class MessagePin { @@ -49,13 +67,6 @@ export class MessagePin { this.store = services["mail.store"]; } - setup() { - this.env.bus.addEventListener("mail.message/onUpdate", ({ detail: { message, data } }) => { - this.onMessageUpdate(message, data); - }); - this.busService.start(); - } - /** * @param {import("models").Thread} channel */ @@ -115,27 +126,6 @@ export class MessagePin { return this.getPinnedMessages(channel).length > 0; } - /** - * @param {import("models").Message} - * @param {Object} data - */ - onMessageUpdate(message, { pinned_at: pinnedAt }) { - if ( - message.originThread?.model === "discuss.channel" && - (pinnedAt !== undefined || message.isEmpty) - ) { - if (pinnedAt && !message.isEmpty) { - if (message.notIn(message.originThread.pinnedMessages)) { - message.originThread.pinnedMessages.push(message); - } - message.pinnedAt = pinnedAt; - } else { - delete message.pinnedAt; - message.originThread.pinnedMessages.delete(message); - } - } - } - /** * Prompts the user for confirmation, then sets pinned to true. * @@ -196,7 +186,6 @@ export const messagePinService = { */ start(env, services) { const messagePin = reactive(new MessagePin(env, services)); - messagePin.setup(); return messagePin; }, }; diff --git a/addons/mail/static/src/discuss/voice_message/common/attachment_model_patch.js b/addons/mail/static/src/discuss/voice_message/common/attachment_model_patch.js index 355c528c1a5..979a10fe0f8 100644 --- a/addons/mail/static/src/discuss/voice_message/common/attachment_model_patch.js +++ b/addons/mail/static/src/discuss/voice_message/common/attachment_model_patch.js @@ -4,6 +4,12 @@ import { Attachment } from "@mail/core/common/attachment_model"; import { patch } from "@web/core/utils/patch"; patch(Attachment.prototype, { + update(data) { + super.update(...arguments); + if (data["voice"]) { + this.isVoice = true; + } + }, get isViewable() { return !this.isVoice && super.isViewable; }, diff --git a/addons/mail/static/src/discuss/voice_message/common/attachment_service_patch.js b/addons/mail/static/src/discuss/voice_message/common/attachment_service_patch.js index aa767dc6660..3b4dbe8e01d 100644 --- a/addons/mail/static/src/discuss/voice_message/common/attachment_service_patch.js +++ b/addons/mail/static/src/discuss/voice_message/common/attachment_service_patch.js @@ -9,12 +9,6 @@ patch(AttachmentService.prototype, { /** @type {import("@mail/discuss/voice_message/common/voice_message_service").VoiceMessageService} */ this.voiceMessageService = services["discuss.voice_message"]; }, - update(attachment, data) { - super.update(...arguments); - if (data["voice"]) { - attachment.isVoice = true; - } - }, remove(attachment) { if (attachment.isVoice && attachment.id > 0) { this.voiceMessageService.activePlayer = null; diff --git a/addons/website_livechat/static/src/core/persona_model_patch.js b/addons/website_livechat/static/src/core/persona_model_patch.js index d3abdee2b8f..aedb9954f40 100644 --- a/addons/website_livechat/static/src/core/persona_model_patch.js +++ b/addons/website_livechat/static/src/core/persona_model_patch.js @@ -5,6 +5,22 @@ import { _t } from "@web/core/l10n/translation"; import { patch } from "@web/core/utils/patch"; patch(Persona.prototype, { + update(data) { + super.update(data); + if (this.type === "visitor") { + this.history = data.history ?? this.history; + this.isConnected = data.is_connected ?? this.isConnected; + this.im_status = this.isConnected ? "online" : undefined; + this.langName = data.lang_name ?? this.langName; + this.name = data.display_name ?? this.name; + this.websiteName = data.website_name ?? this.websiteName; + } + if (data.country_id) { + this.country = this.country ?? {}; + this.country.id = data.country_id; + this.country.code = data.country_code ?? this.country.code; + } + }, get countryFlagUrl() { const country = this.partner?.country ?? this.country; return country diff --git a/addons/website_livechat/static/src/core/persona_service_patch.js b/addons/website_livechat/static/src/core/persona_service_patch.js deleted file mode 100644 index 39405dd9017..00000000000 --- a/addons/website_livechat/static/src/core/persona_service_patch.js +++ /dev/null @@ -1,23 +0,0 @@ -/** @odoo-module */ - -import { PersonaService } from "@mail/core/common/persona_service"; -import { patch } from "@web/core/utils/patch"; - -patch(PersonaService.prototype, { - update(persona, data) { - super.update(persona, data); - if (persona.type === "visitor") { - persona.history = data.history ?? persona.history; - persona.isConnected = data.is_connected ?? persona.isConnected; - persona.im_status = persona.isConnected ? "online" : undefined; - persona.langName = data.lang_name ?? persona.langName; - persona.name = data.display_name ?? persona.name; - persona.websiteName = data.website_name ?? persona.websiteName; - } - if (data.country_id) { - persona.country = persona.country ?? {}; - persona.country.id = data.country_id; - persona.country.code = data.country_code ?? persona.country.code; - } - }, -}); diff --git a/addons/website_livechat/static/src/core/thread_model_patch.js b/addons/website_livechat/static/src/core/thread_model_patch.js new file mode 100644 index 00000000000..f657a2f118e --- /dev/null +++ b/addons/website_livechat/static/src/core/thread_model_patch.js @@ -0,0 +1,18 @@ +/** @odoo-module */ + +import { Thread } from "@mail/core/common/thread_model"; +import { assignDefined } from "@mail/utils/common/misc"; +import { patch } from "@web/core/utils/patch"; + +patch(Thread.prototype, { + update(data) { + super.update(data); + if (data?.visitor) { + this.visitor = this._store.Persona.insert({ + ...data.visitor, + type: "visitor", + }); + } + assignDefined(this, data, ["requested_by_operator"]); + }, +}); diff --git a/addons/website_livechat/static/src/core/thread_service_patch.js b/addons/website_livechat/static/src/core/thread_service_patch.js index 4690ec4a3f5..03ab158d0b2 100644 --- a/addons/website_livechat/static/src/core/thread_service_patch.js +++ b/addons/website_livechat/static/src/core/thread_service_patch.js @@ -2,20 +2,9 @@ import { DEFAULT_AVATAR } from "@mail/core/common/persona_service"; import { ThreadService } from "@mail/core/common/thread_service"; -import { assignDefined } from "@mail/utils/common/misc"; import { patch } from "@web/core/utils/patch"; patch(ThreadService.prototype, { - update(thread, data) { - super.update(thread, data); - if (data?.visitor) { - thread.visitor = this.store.Persona.insert({ - ...data.visitor, - type: "visitor", - }); - } - assignDefined(thread, data, ["requested_by_operator"]); - }, /** * @param {import("models").Persona} persona * @param {import("models").Thread} [thread] diff --git a/addons/website_livechat/static/src/embed/thread_model_patch.js b/addons/website_livechat/static/src/embed/thread_model_patch.js new file mode 100644 index 00000000000..eff4fb4be89 --- /dev/null +++ b/addons/website_livechat/static/src/embed/thread_model_patch.js @@ -0,0 +1,12 @@ +/** @odoo-module */ + +import { Thread } from "@mail/core/common/thread_model"; +import { assignDefined } from "@mail/utils/common/misc"; +import { patch } from "@web/core/utils/patch"; + +patch(Thread.prototype, { + update(data) { + super.update(data); + assignDefined(this, data, ["requested_by_operator"]); + }, +}); diff --git a/addons/website_livechat/static/src/embed/thread_service_patch.js b/addons/website_livechat/static/src/embed/thread_service_patch.js deleted file mode 100644 index f5dce30484b..00000000000 --- a/addons/website_livechat/static/src/embed/thread_service_patch.js +++ /dev/null @@ -1,12 +0,0 @@ -/** @odoo-module */ - -import { ThreadService } from "@mail/core/common/thread_service"; -import { assignDefined } from "@mail/utils/common/misc"; -import { patch } from "@web/core/utils/patch"; - -patch(ThreadService.prototype, { - update(thread, data) { - super.update(thread, data); - assignDefined(thread, data, ["requested_by_operator"]); - }, -});