diff --git a/addons/mail/static/src/core/common/composer_model.js b/addons/mail/static/src/core/common/composer_model.js index 915a7a7f36a..bf061b1f998 100644 --- a/addons/mail/static/src/core/common/composer_model.js +++ b/addons/mail/static/src/core/common/composer_model.js @@ -1,12 +1,41 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; /** * @typedef {{partnerIds: Set, threadIds: Set}} RawMentions */ export class Composer extends Record { + /** + * @param {Object} data + * @returns {Composer} + */ + static insert(data) { + const { message, thread } = data; + if (Boolean(message) === Boolean(thread)) { + throw new Error("Composer shall have a thread xor a message."); + } + let composer = (thread ?? message)?.composer; + if (!composer) { + composer = new Composer(this.store, data); + } + if ("textInputContent" in data) { + composer.textInputContent = data.textInputContent; + } + if ("selection" in data) { + Object.assign(composer.selection, data.selection); + } + if ("mentions" in data) { + for (const mention of data.mentions) { + if (mention.type === "partner") { + composer.rawMentions.partnerIds.add(mention.id); + } + } + } + return composer; + } + /** @type {import("@mail/core/common/attachment_model").Attachment[]} */ attachments = []; /** @type {import("@mail/core/common/message_model").Message} */ @@ -50,3 +79,5 @@ export class Composer extends Record { }); } } + +modelRegistry.add(Composer.name, Composer); diff --git a/addons/mail/static/src/core/common/link_preview_model.js b/addons/mail/static/src/core/common/link_preview_model.js index 27109fc93de..fca2711a15f 100644 --- a/addons/mail/static/src/core/common/link_preview_model.js +++ b/addons/mail/static/src/core/common/link_preview_model.js @@ -1,8 +1,22 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; export class LinkPreview extends Record { + /** + * @param {Object} data + * @returns {LinkPreview} + */ + static insert(data) { + const linkPreview = data.message.linkPreviews.find( + (linkPreview) => linkPreview.id === data.id + ); + if (linkPreview) { + return Object.assign(linkPreview, data); + } + return new LinkPreview(data); + } + /** @type {number} */ id; /** @type {Object} */ @@ -47,3 +61,5 @@ export class LinkPreview extends Record { return !this.isImage && !this.isVideo; } } + +modelRegistry.add(LinkPreview.name, LinkPreview); diff --git a/addons/mail/static/src/core/common/mail_core_common_service.js b/addons/mail/static/src/core/common/mail_core_common_service.js index b8d72c88c42..a4748d32f65 100644 --- a/addons/mail/static/src/core/common/mail_core_common_service.js +++ b/addons/mail/static/src/core/common/mail_core_common_service.js @@ -102,7 +102,7 @@ export class MailCoreCommon { if (linkPreviews) { for (const linkPreview of linkPreviews) { this.store.Message.records[linkPreview.message.id]?.linkPreviews.push( - new LinkPreview(linkPreview) + this.store.LinkPreview.insert(linkPreview) ); } } diff --git a/addons/mail/static/src/core/common/message.js b/addons/mail/static/src/core/common/message.js index 3649f756ab7..7a49fa4ecee 100644 --- a/addons/mail/static/src/core/common/message.js +++ b/addons/mail/static/src/core/common/message.js @@ -387,7 +387,7 @@ export class Message extends Component { enterEditMode() { const messageContent = convertBrToLineBreak(this.props.message.body); - this.threadService.insertComposer({ + this.store.Composer.insert({ mentions: this.props.message.recipients, message: this.props.message, textInputContent: messageContent, diff --git a/addons/mail/static/src/core/common/message_reactions_model.js b/addons/mail/static/src/core/common/message_reactions_model.js index bd6dc374e50..dc9be28efa5 100644 --- a/addons/mail/static/src/core/common/message_reactions_model.js +++ b/addons/mail/static/src/core/common/message_reactions_model.js @@ -1,8 +1,53 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; export class MessageReactions extends Record { + /** + * @param {Object} data + * @returns {MessageReactions} + */ + static insert(data) { + let reaction = this.store.Message.records[data.message.id]?.reactions.find( + ({ content }) => content === data.content + ); + if (!reaction) { + reaction = new MessageReactions(); + reaction._store = this.store; + } + const personasToUnlink = new Set(); + const alreadyKnownPersonaIds = new Set(reaction.personaLocalIds); + for (const rawPartner of data.partners) { + const [command, partnerData] = Array.isArray(rawPartner) + ? rawPartner + : ["insert", rawPartner]; + const persona = this.store.Persona.insert({ ...partnerData, type: "partner" }); + if (command === "insert" && !alreadyKnownPersonaIds.has(persona.localId)) { + reaction.personaLocalIds.push(persona.localId); + } else if (command !== "insert") { + personasToUnlink.add(persona.localId); + } + } + for (const rawGuest of data.guests) { + const [command, guestData] = Array.isArray(rawGuest) ? rawGuest : ["insert", rawGuest]; + const persona = this.store.Persona.insert({ ...guestData, type: "guest" }); + if (command === "insert" && !alreadyKnownPersonaIds.has(persona.localId)) { + reaction.personaLocalIds.push(persona.localId); + } else if (command !== "insert") { + personasToUnlink.add(persona.localId); + } + } + Object.assign(reaction, { + count: data.count, + content: data.content, + messageId: data.message.id, + personaLocalIds: reaction.personaLocalIds.filter( + (localId) => !personasToUnlink.has(localId) + ), + }); + return reaction; + } + /** @type {string} */ content; /** @type {number} */ @@ -19,3 +64,5 @@ export class MessageReactions extends Record { return this.personaLocalIds.map((localId) => this._store.Persona.records[localId]); } } + +modelRegistry.add(MessageReactions.name, MessageReactions); diff --git a/addons/mail/static/src/core/common/message_service.js b/addons/mail/static/src/core/common/message_service.js index 83923369064..738418ad20a 100644 --- a/addons/mail/static/src/core/common/message_service.js +++ b/addons/mail/static/src/core/common/message_service.js @@ -1,7 +1,5 @@ /* @odoo-module */ -import { LinkPreview } from "@mail/core/common/link_preview_model"; -import { MessageReactions } from "@mail/core/common/message_reactions_model"; import { removeFromArrayWithPredicate, replaceArrayWithCompare } from "@mail/utils/common/arrays"; import { convertBrToLineBreak, prettifyMessageContent } from "@mail/utils/common/format"; import { assignDefined, createLocalId } from "@mail/utils/common/misc"; @@ -278,7 +276,7 @@ export class MessageService { } replaceArrayWithCompare( message.linkPreviews, - linkPreviews.map((data) => this.insertLinkPreview({ ...data, message })) + linkPreviews.map((data) => this.store.LinkPreview.insert({ ...data, message })) ); replaceArrayWithCompare( message.notifications, @@ -319,7 +317,7 @@ export class MessageService { const [command, reactionData] = Array.isArray(rawReaction) ? rawReaction : ["insert", rawReaction]; - const reaction = this.insertReactions(reactionData); + const reaction = this.store.MessageReactions.insert(reactionData); if (command === "insert") { reactionsToInsert.push(reaction); } else { @@ -339,65 +337,6 @@ export class MessageService { }); } - /** - * @param {Object} data - * @returns {LinkPreview} - */ - insertLinkPreview(data) { - const linkPreview = data.message.linkPreviews.find( - (linkPreview) => linkPreview.id === data.id - ); - if (linkPreview) { - return Object.assign(linkPreview, data); - } - return new LinkPreview(data); - } - - /** - * @param {Object} data - * @returns {MessageReactions} - */ - insertReactions(data) { - let reaction = this.store.Message.records[data.message.id]?.reactions.find( - ({ content }) => content === data.content - ); - if (!reaction) { - reaction = new MessageReactions(); - reaction._store = this.store; - } - const personasToUnlink = new Set(); - const alreadyKnownPersonaIds = new Set(reaction.personaLocalIds); - for (const rawPartner of data.partners) { - const [command, partnerData] = Array.isArray(rawPartner) - ? rawPartner - : ["insert", rawPartner]; - const persona = this.store.Persona.insert({ ...partnerData, type: "partner" }); - if (command === "insert" && !alreadyKnownPersonaIds.has(persona.localId)) { - reaction.personaLocalIds.push(persona.localId); - } else if (command !== "insert") { - personasToUnlink.add(persona.localId); - } - } - for (const rawGuest of data.guests) { - const [command, guestData] = Array.isArray(rawGuest) ? rawGuest : ["insert", rawGuest]; - const persona = this.store.Persona.insert({ ...guestData, type: "guest" }); - if (command === "insert" && !alreadyKnownPersonaIds.has(persona.localId)) { - reaction.personaLocalIds.push(persona.localId); - } else if (command !== "insert") { - personasToUnlink.add(persona.localId); - } - } - Object.assign(reaction, { - count: data.count, - content: data.content, - messageId: data.message.id, - personaLocalIds: reaction.personaLocalIds.filter( - (localId) => !personasToUnlink.has(localId) - ), - }); - return reaction; - } - updateNotification(notification, data) { Object.assign(notification, { messageId: data.messageId, diff --git a/addons/mail/static/src/core/common/scroll_position_model.js b/addons/mail/static/src/core/common/scroll_position.js similarity index 75% rename from addons/mail/static/src/core/common/scroll_position_model.js rename to addons/mail/static/src/core/common/scroll_position.js index 2060ae1adb6..af6546af3f4 100644 --- a/addons/mail/static/src/core/common/scroll_position_model.js +++ b/addons/mail/static/src/core/common/scroll_position.js @@ -1,15 +1,12 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; - -export class ScrollPosition extends Record { +export class ScrollPosition { /** @type {number|undefined} */ top; /** @type {number|undefined} */ left; constructor(top, left) { - super(); this.top = top; this.left = left; } diff --git a/addons/mail/static/src/core/common/store_service.js b/addons/mail/static/src/core/common/store_service.js index 45fa7ce0593..eda06a5e0a7 100644 --- a/addons/mail/static/src/core/common/store_service.js +++ b/addons/mail/static/src/core/common/store_service.js @@ -20,10 +20,16 @@ export class Store { ChannelMember; /** @type {typeof import("@mail/core/common/chat_window_model").ChatWindow} */ ChatWindow; + /** @type {typeof import("@mail/core/common/composer_model").Composer} */ + Composer; /** @type {typeof import("@mail/core/common/follower_model").Follower} */ Follower; + /** @type {typeof import("@mail/core/common/link_preview_model").LinkPreview} */ + LinkPreview; /** @type {typeof import("@mail/core/common/message_model").Message} */ Message; + /** @type {typeof import("@mail/core/common/message_reactions_model").MessageReactions} */ + MessageReactions; /** @type {typeof import("@mail/core/common/notification_model").Notification} */ Notification; /** @type {typeof import("@mail/core/common/notification_group_model").NotificationGroup} */ diff --git a/addons/mail/static/src/core/common/thread_model.js b/addons/mail/static/src/core/common/thread_model.js index 234b35483c8..9de43fa6f81 100644 --- a/addons/mail/static/src/core/common/thread_model.js +++ b/addons/mail/static/src/core/common/thread_model.js @@ -1,7 +1,7 @@ /* @odoo-module */ import { Record, modelRegistry } from "@mail/core/common/record"; -import { ScrollPosition } from "@mail/core/common/scroll_position_model"; +import { ScrollPosition } from "@mail/core/common/scroll_position"; import { createLocalId, onChange } from "@mail/utils/common/misc"; import { deserializeDateTime } from "@web/core/l10n/dates"; @@ -55,7 +55,7 @@ export class Thread extends Record { } }); this.env.services["mail.thread"].update(thread, data); - this.env.services["mail.thread"].insertComposer({ thread }); + this.store.Composer.insert({ thread }); // return reactive version. return this.records[thread.localId]; } diff --git a/addons/mail/static/src/core/common/thread_service.js b/addons/mail/static/src/core/common/thread_service.js index f1dc99a6990..9ee5bf863dc 100644 --- a/addons/mail/static/src/core/common/thread_service.js +++ b/addons/mail/static/src/core/common/thread_service.js @@ -797,35 +797,6 @@ export class ThreadService { this.env.bus.trigger("mail.thread/onUpdate", { thread, data }); } - /** - * @param {Object} data - * @returns {Composer} - */ - insertComposer(data) { - const { message, thread } = data; - if (Boolean(message) === Boolean(thread)) { - throw new Error("Composer shall have a thread xor a message."); - } - let composer = (thread ?? message)?.composer; - if (!composer) { - composer = new Composer(this.store, data); - } - if ("textInputContent" in data) { - composer.textInputContent = data.textInputContent; - } - if ("selection" in data) { - Object.assign(composer.selection, data.selection); - } - if ("mentions" in data) { - for (const mention of data.mentions) { - if (mention.type === "partner") { - composer.rawMentions.partnerIds.add(mention.id); - } - } - } - return composer; - } - /** * @param {Thread} thread * @param {string} body