From 13b852d2e271f9fe1bef39ca344cf879c9c0bc11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20K=C3=BChn?= Date: Tue, 29 Aug 2023 16:19:46 +0200 Subject: [PATCH] [REF] mail: move imp of `service.insert()` to `Model.insert()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation to clean code of models, e.g. by simplifying model insertion and reducing side-effects in record insertion. This commit moves the implementation of the `insert()` in discuss services to the models, and drop support of the service methods `insert()`. The only way to insert a model is through the store entry, e.g. `store.Thread.insert()`. closes odoo/odoo#133509 Related: odoo/enterprise#46499 Signed-off-by: Alexandre Kühn (aku) --- .../src/activity/activity_model_patch.js | 15 ++ .../src/activity/activity_service_patch.js | 9 -- .../static/src/core/thread_model_patch.js | 25 +++ .../static/src/core/thread_service_patch.js | 22 --- .../src/embed/core/message_model_patch.js | 12 ++ .../src/embed/core/message_service_patch.js | 17 -- .../src/embed/core/thread_model_patch.js | 54 +++++++ .../src/embed/core/thread_service_patch.js | 51 ------ .../src/core/common/attachment_model.js | 25 ++- .../src/core/common/attachment_service.js | 15 -- .../src/core/common/canned_response_model.js | 24 ++- .../src/core/common/channel_member_model.js | 22 ++- .../src/core/common/channel_member_service.js | 17 -- .../src/core/common/chat_window_model.js | 44 +++++- .../src/core/common/chat_window_service.js | 46 ------ .../static/src/core/common/follower_model.js | 26 ++- .../static/src/core/common/message_model.js | 31 +++- .../static/src/core/common/message_service.js | 62 -------- .../src/core/common/messaging_service.js | 15 -- .../core/common/notification_group_model.js | 29 +++- .../src/core/common/notification_model.js | 20 ++- .../static/src/core/common/persona_model.js | 25 ++- .../static/src/core/common/persona_service.js | 25 +-- addons/mail/static/src/core/common/record.js | 13 ++ .../static/src/core/common/store_service.js | 149 +++++------------- .../static/src/core/common/thread_model.js | 44 +++++- .../static/src/core/common/thread_service.js | 44 +----- .../src/core/web/activity_list_popover.js | 3 +- .../static/src/core/web/activity_model.js | 29 +++- .../static/src/core/web/activity_service.js | 24 --- .../src/core/web/thread_service_patch.js | 24 +-- .../src/discuss/call/common/rtc_service.js | 33 ---- .../discuss/call/common/rtc_session_model.js | 38 ++++- addons/mail/static/src/utils/common/misc.js | 1 - .../tests/core/attachment_model_tests.js | 2 +- 35 files changed, 509 insertions(+), 526 deletions(-) create mode 100644 addons/calendar/static/src/activity/activity_model_patch.js delete mode 100644 addons/im_livechat/static/src/embed/core/message_service_patch.js diff --git a/addons/calendar/static/src/activity/activity_model_patch.js b/addons/calendar/static/src/activity/activity_model_patch.js new file mode 100644 index 00000000000..9500c9232ff --- /dev/null +++ b/addons/calendar/static/src/activity/activity_model_patch.js @@ -0,0 +1,15 @@ +/** @odoo-module */ + +import { Activity } from "@mail/core/web/activity_model"; +import { patch } from "@web/core/utils/patch"; + +patch(Activity, { + insert(data) { + const activity = super.insert(...arguments); + const { calendar_event_id: calendarEventId } = data; + if (calendarEventId) { + activity["calendar_event_id"] = calendarEventId; + } + return activity; + }, +}); diff --git a/addons/calendar/static/src/activity/activity_service_patch.js b/addons/calendar/static/src/activity/activity_service_patch.js index b1197765dc4..a5be3632cec 100644 --- a/addons/calendar/static/src/activity/activity_service_patch.js +++ b/addons/calendar/static/src/activity/activity_service_patch.js @@ -4,15 +4,6 @@ import { ActivityService } from "@mail/core/web/activity_service"; import { patch } from "@web/core/utils/patch"; patch(ActivityService.prototype, { - insert(data) { - const activity = super.insert(...arguments); - const { calendar_event_id: calendarEventId } = data; - if (calendarEventId) { - activity["calendar_event_id"] = calendarEventId; - } - return activity; - }, - async rescheduleMeeting(activityId) { const action = await this.orm.call("mail.activity", "action_create_calendar_event", [ [activityId], diff --git a/addons/im_livechat/static/src/core/thread_model_patch.js b/addons/im_livechat/static/src/core/thread_model_patch.js index cd79dff07ea..669c8e16c0a 100644 --- a/addons/im_livechat/static/src/core/thread_model_patch.js +++ b/addons/im_livechat/static/src/core/thread_model_patch.js @@ -2,9 +2,34 @@ import { DEFAULT_AVATAR } from "@mail/core/common/persona_service"; import { Thread } from "@mail/core/common/thread_model"; +import { assignDefined, createLocalId } from "@mail/utils/common/misc"; import { patch } from "@web/core/utils/patch"; +patch(Thread, { + insert(data) { + const isUnknown = !(createLocalId(data.model, data.id) in this.records); + const thread = super.insert(data); + if (thread.type === "livechat") { + if (data?.channel) { + assignDefined(thread, data.channel, ["anonymous_name"]); + } + if (data?.operator_pid) { + thread.operator = this.store.Persona.insert({ + type: "partner", + id: data.operator_pid[0], + displayName: data.operator_pid[1], + }); + } + if (isUnknown) { + this.store.discuss.livechat.threads.push(thread.localId); + this.env.services["mail.thread"].sortChannels(); + } + } + return thread; + }, +}); + patch(Thread.prototype, { get isChannel() { return this.type === "livechat" || super.isChannel; diff --git a/addons/im_livechat/static/src/core/thread_service_patch.js b/addons/im_livechat/static/src/core/thread_service_patch.js index 4cb507649a2..ce8d0295bdb 100644 --- a/addons/im_livechat/static/src/core/thread_service_patch.js +++ b/addons/im_livechat/static/src/core/thread_service_patch.js @@ -2,32 +2,10 @@ import { ThreadService } from "@mail/core/common/thread_service"; import { removeFromArray } from "@mail/utils/common/arrays"; -import { assignDefined, createLocalId } from "@mail/utils/common/misc"; import { patch } from "@web/core/utils/patch"; patch(ThreadService.prototype, { - insert(data) { - const isUnknown = !(createLocalId(data.model, data.id) in this.store.Thread.records); - const thread = super.insert(data); - if (thread.type === "livechat") { - if (data?.channel) { - assignDefined(thread, data.channel, ["anonymous_name"]); - } - if (data?.operator_pid) { - thread.operator = this.store.Persona.insert({ - type: "partner", - id: data.operator_pid[0], - displayName: data.operator_pid[1], - }); - } - if (isUnknown) { - this.store.discuss.livechat.threads.push(thread.localId); - this.sortChannels(); - } - } - return thread; - }, /** * @override * @param {import("@mail/core/common/thread_model").Thread} thread diff --git a/addons/im_livechat/static/src/embed/core/message_model_patch.js b/addons/im_livechat/static/src/embed/core/message_model_patch.js index 2bbabb3b442..0b21af55da8 100644 --- a/addons/im_livechat/static/src/embed/core/message_model_patch.js +++ b/addons/im_livechat/static/src/embed/core/message_model_patch.js @@ -1,10 +1,22 @@ /* @odoo-module */ +import { ChatbotStep } from "@im_livechat/embed/chatbot/chatbot_step_model"; + import { Message } from "@mail/core/common/message_model"; import { patch } from "@web/core/utils/patch"; import { session } from "@web/session"; +patch(Message, { + insert(data) { + const message = super.insert(data); + if (data.chatbotStep) { + message.chatbotStep = new ChatbotStep(data.chatbotStep); + } + return message; + }, +}); + patch(Message.prototype, { get isSelfAuthored() { if (this.originThread.type !== "livechat") { diff --git a/addons/im_livechat/static/src/embed/core/message_service_patch.js b/addons/im_livechat/static/src/embed/core/message_service_patch.js deleted file mode 100644 index ec539614d70..00000000000 --- a/addons/im_livechat/static/src/embed/core/message_service_patch.js +++ /dev/null @@ -1,17 +0,0 @@ -/* @odoo-module */ - -import { ChatbotStep } from "@im_livechat/embed/chatbot/chatbot_step_model"; - -import { MessageService } from "@mail/core/common/message_service"; - -import { patch } from "@web/core/utils/patch"; - -patch(MessageService.prototype, { - insert(data) { - const message = super.insert(data); - if (data.chatbotStep) { - message.chatbotStep = new ChatbotStep(data.chatbotStep); - } - return message; - }, -}); 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 4c5cb825512..3782206e62d 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 @@ -1,9 +1,63 @@ /* @odoo-module */ import { Thread } from "@mail/core/common/thread_model"; +import { createLocalId, onChange } from "@mail/utils/common/misc"; import { patch } from "@web/core/utils/patch"; import { session } from "@web/session"; +import { SESSION_STATE } from "./livechat_service"; + +patch(Thread, { + insert(data) { + const isUnknown = !(createLocalId(data.model, data.id) in this.records); + const thread = super.insert(...arguments); + const livechatService = this.env.services["im_livechat.livechat"]; + const chatbotService = this.env.services["im_livechat.chatbot"]; + const messageService = this.env.services["mail.message"]; + if (thread.type === "livechat" && isUnknown) { + if (livechatService.displayWelcomeMessage && !chatbotService.isChatbotThread(thread)) { + livechatService.welcomeMessage = this.store.Message.insert({ + id: messageService.getNextTemporaryId(), + body: livechatService.options.default_message, + res_id: thread.id, + model: thread.model, + author: thread.operator, + }); + } + if (chatbotService.isChatbotThread(thread)) { + chatbotService.typingMessage = this.store.Message.insert({ + id: messageService.getNextTemporaryId(), + res_id: thread.id, + model: thread.model, + author: thread.operator, + }); + } + onChange(thread, "state", () => { + if (![SESSION_STATE.CLOSED, SESSION_STATE.NONE].includes(livechatService.state)) { + livechatService.updateSession({ + state: thread.state, + }); + } + }); + onChange(thread, "seen_message_id", () => { + if (![SESSION_STATE.CLOSED, SESSION_STATE.NONE].includes(livechatService.state)) { + livechatService.updateSession({ + seen_message_id: thread.seen_message_id, + }); + } + }); + onChange(thread, "message_unread_counter", () => { + if (![SESSION_STATE.CLOSED, SESSION_STATE.NONE].includes(livechatService.state)) { + livechatService.updateSession({ + channel: thread.channel, + }); + } + }); + this.store.livechatThread = thread; + } + return thread; + }, +}); patch(Thread.prototype, { chatbotScriptId: null, 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 623986009b7..3f994b2ba4e 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 @@ -4,7 +4,6 @@ import { SESSION_STATE } from "@im_livechat/embed/core/livechat_service"; import { ThreadService, threadService } from "@mail/core/common/thread_service"; import { prettifyMessageContent } from "@mail/utils/common/format"; -import { createLocalId, onChange } from "@mail/utils/common/misc"; import { markup } from "@odoo/owl"; @@ -110,56 +109,6 @@ patch(ThreadService.prototype, { } }, - insert(data) { - const isUnknown = !(createLocalId(data.model, data.id) in this.store.Thread.records); - const thread = super.insert(...arguments); - if (thread.type === "livechat" && isUnknown) { - if ( - this.livechatService.displayWelcomeMessage && - !this.chatbotService.isChatbotThread(thread) - ) { - this.livechatService.welcomeMessage = this.store.Message.insert({ - id: this.messageService.getNextTemporaryId(), - body: this.livechatService.options.default_message, - res_id: thread.id, - model: thread.model, - author: thread.operator, - }); - } - if (this.chatbotService.isChatbotThread(thread)) { - this.chatbotService.typingMessage = this.store.Message.insert({ - id: this.messageService.getNextTemporaryId(), - res_id: thread.id, - model: thread.model, - author: thread.operator, - }); - } - onChange(thread, "state", () => { - if ( - ![SESSION_STATE.CLOSED, SESSION_STATE.NONE].includes(this.livechatService.state) - ) { - this.livechatService.updateSession({ state: thread.state }); - } - }); - onChange(thread, "seen_message_id", () => { - if ( - ![SESSION_STATE.CLOSED, SESSION_STATE.NONE].includes(this.livechatService.state) - ) { - this.livechatService.updateSession({ seen_message_id: thread.seen_message_id }); - } - }); - onChange(thread, "message_unread_counter", () => { - if ( - ![SESSION_STATE.CLOSED, SESSION_STATE.NONE].includes(this.livechatService.state) - ) { - this.livechatService.updateSession({ channel: thread.channel }); - } - }); - this.store.livechatThread = thread; - } - return thread; - }, - async update(thread, data) { super.update(...arguments); if (data.operator_pid) { diff --git a/addons/mail/static/src/core/common/attachment_model.js b/addons/mail/static/src/core/common/attachment_model.js index c6e1a11bc35..869c9317ed7 100644 --- a/addons/mail/static/src/core/common/attachment_model.js +++ b/addons/mail/static/src/core/common/attachment_model.js @@ -1,12 +1,33 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; import { assignDefined } from "@mail/utils/common/misc"; import { deserializeDateTime } from "@web/core/l10n/dates"; import { url } from "@web/core/utils/urls"; export class Attachment extends Record { + /** @type {Object.} */ + static records = {}; + + /** + * @param {Object} data + * @returns {Attachment} + */ + static insert(data) { + if (!("id" in data)) { + throw new Error("Cannot insert attachment: id is missing in data"); + } + let attachment = this.records[data.id]; + if (!attachment) { + this.records[data.id] = new Attachment(); + attachment = this.records[data.id]; + Object.assign(attachment, { _store: this.store, id: data.id }); + } + this.env.services["mail.attachment"].update(attachment, data); + return attachment; + } + /** @type {import("@mail/core/common/store_service").Store} */ _store; accessToken; @@ -151,3 +172,5 @@ export class Attachment extends Record { ); } } + +modelRegistry.add(Attachment.name, Attachment); diff --git a/addons/mail/static/src/core/common/attachment_service.js b/addons/mail/static/src/core/common/attachment_service.js index d8966b97904..73f06033f03 100644 --- a/addons/mail/static/src/core/common/attachment_service.js +++ b/addons/mail/static/src/core/common/attachment_service.js @@ -1,6 +1,5 @@ /* @odoo-module */ -import { Attachment } from "@mail/core/common/attachment_model"; import { removeFromArrayWithPredicate } from "@mail/utils/common/arrays"; import { assignDefined, createLocalId } from "@mail/utils/common/misc"; @@ -21,20 +20,6 @@ export class AttachmentService { this.rpc = services["rpc"]; } - insert(data) { - if (!("id" in data)) { - throw new Error("Cannot insert attachment: id is missing in data"); - } - let attachment = this.store.Attachment.records[data.id]; - if (!attachment) { - this.store.Attachment.records[data.id] = new Attachment(); - attachment = this.store.Attachment.records[data.id]; - Object.assign(attachment, { _store: this.store, id: data.id }); - } - this.update(attachment, data); - return attachment; - } - update(attachment, data) { assignDefined(attachment, data, [ "checksum", diff --git a/addons/mail/static/src/core/common/canned_response_model.js b/addons/mail/static/src/core/common/canned_response_model.js index 620b33bf620..b9dc741eae1 100644 --- a/addons/mail/static/src/core/common/canned_response_model.js +++ b/addons/mail/static/src/core/common/canned_response_model.js @@ -1,8 +1,28 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; export class CannedResponse extends Record { + /** @type {Object.} */ + static records = {}; + /** + * @param {Object} data + * @returns {CannedResponse} + */ + static insert(data) { + let cannedResponse = this.records[data.id]; + if (!cannedResponse) { + this.records[data.id] = new CannedResponse(); + cannedResponse = this.records[data.id]; + } + Object.assign(cannedResponse, { + id: data.id, + name: data.source, + substitution: data.substitution, + }); + return cannedResponse; + } + /** @type {number} */ id; /** @type {string} */ @@ -10,3 +30,5 @@ export class CannedResponse extends Record { /** @type {string} */ substitution; } + +modelRegistry.add(CannedResponse.name, CannedResponse); 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 23ce29c3a07..2ade49431bd 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,6 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; import { createLocalId } from "@mail/utils/common/misc"; /** @@ -11,6 +11,24 @@ import { createLocalId } from "@mail/utils/common/misc"; * @property {number} threadId */ export class ChannelMember extends Record { + /** @type {Object.} */ + static records = {}; + /** + * @param {Object|Array} data + * @returns {ChannelMember} + */ + static insert(data) { + const memberData = Array.isArray(data) ? data[1] : data; + let member = this.records[memberData.id]; + if (!member) { + this.records[memberData.id] = new ChannelMember(); + member = this.records[memberData.id]; + member._store = this.store; + } + this.env.services["discuss.channel.member"].update(member, data); + return member; + } + /** @type {number} */ id; personaLocalId; @@ -42,3 +60,5 @@ export class ChannelMember extends Record { return this.persona.lang_name; } } + +modelRegistry.add(ChannelMember.name, ChannelMember); 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 ea72de8c4ba..260c6c3aafa 100644 --- a/addons/mail/static/src/core/common/channel_member_service.js +++ b/addons/mail/static/src/core/common/channel_member_service.js @@ -1,6 +1,5 @@ /* @odoo-module */ -import { ChannelMember } from "@mail/core/common/channel_member_model"; import { removeFromArray } from "@mail/utils/common/arrays"; import { registry } from "@web/core/registry"; @@ -15,22 +14,6 @@ export class ChannelMemberService { this.store = services["mail.store"]; } - /** - * @param {Object|Array} data - * @returns {ChannelMember} - */ - insert(data) { - const memberData = Array.isArray(data) ? data[1] : data; - let member = this.store.ChannelMember.records[memberData.id]; - if (!member) { - this.store.ChannelMember.records[memberData.id] = new ChannelMember(); - member = this.store.ChannelMember.records[memberData.id]; - member._store = this.store; - } - this.update(member, data); - return member; - } - update(member, data) { const [command, memberData] = Array.isArray(data) ? data : ["insert", data]; member.id = memberData.id; diff --git a/addons/mail/static/src/core/common/chat_window_model.js b/addons/mail/static/src/core/common/chat_window_model.js index 59ef3e4511e..0f130b38119 100644 --- a/addons/mail/static/src/core/common/chat_window_model.js +++ b/addons/mail/static/src/core/common/chat_window_model.js @@ -1,12 +1,52 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; +import { assignDefined } from "@mail/utils/common/misc"; import { _t } from "@web/core/l10n/translation"; /** @typedef {{ thread?: import("@mail/core/common/thread_model").Thread, folded?: boolean, replaceNewMessageChatWindow?: boolean }} ChatWindowData */ export class ChatWindow extends Record { + /** @type {ChatWindow[]} */ + static records = []; + /** + * @param {ChatWindowData} [data] + * @returns {ChatWindow} + */ + static insert(data = {}) { + const chatWindow = this.records.find((c) => c.threadLocalId === data.thread?.localId); + if (!chatWindow) { + const chatWindow = new ChatWindow(this.store, data); + assignDefined(chatWindow, data); + let index; + const visible = this.env.services["mail.chat_window"].visible; + const maxVisible = this.env.services["mail.chat_window"].maxVisible; + if (!data.replaceNewMessageChatWindow) { + if (maxVisible <= this.records.length) { + const swaped = visible[visible.length - 1]; + index = visible.length - 1; + this.env.services["mail.chat_window"].hide(swaped); + } else { + index = this.records.length; + } + } else { + const newMessageChatWindowIndex = this.records.findIndex((cw) => !cw.thread); + index = + newMessageChatWindowIndex !== -1 + ? newMessageChatWindowIndex + : this.records.length; + } + this.records.splice(index, data.replaceNewMessageChatWindow ? 1 : 0, chatWindow); + return this.records[index]; // return reactive version + } + if (chatWindow.hidden) { + this.env.services["mail.chat_window"].makeVisible(chatWindow); + } + assignDefined(chatWindow, data); + return chatWindow; + } + /** @type {import("@mail/core/common/store_service").Store} */ _store; @@ -45,3 +85,5 @@ export class ChatWindow extends Record { return !this.folded && !this.hidden; } } + +modelRegistry.add(ChatWindow.name, ChatWindow); diff --git a/addons/mail/static/src/core/common/chat_window_service.js b/addons/mail/static/src/core/common/chat_window_service.js index 82689dcd3fb..e3b0162b75c 100644 --- a/addons/mail/static/src/core/common/chat_window_service.js +++ b/addons/mail/static/src/core/common/chat_window_service.js @@ -1,8 +1,5 @@ /* @odoo-module */ -import { ChatWindow } from "@mail/core/common/chat_window_model"; -import { assignDefined } from "@mail/utils/common/misc"; - import { browser } from "@web/core/browser/browser"; import { registry } from "@web/core/registry"; @@ -82,49 +79,6 @@ export class ChatWindowService { return maxAmountWithoutHidden; } - /** - * @param {ChatWindowData} [data] - * @returns {ChatWindow} - */ - insert(data = {}) { - const chatWindow = this.store.ChatWindow.records.find( - (c) => c.threadLocalId === data.thread?.localId - ); - if (!chatWindow) { - const chatWindow = new ChatWindow(this.store, data); - assignDefined(chatWindow, data); - let index; - if (!data.replaceNewMessageChatWindow) { - if (this.maxVisible <= this.store.ChatWindow.records.length) { - const swaped = this.visible[this.visible.length - 1]; - index = this.visible.length - 1; - this.hide(swaped); - } else { - index = this.store.ChatWindow.records.length; - } - } else { - const newMessageChatWindowIndex = this.store.ChatWindow.records.findIndex( - (chatWindow) => !chatWindow.thread - ); - index = - newMessageChatWindowIndex !== -1 - ? newMessageChatWindowIndex - : this.store.ChatWindow.records.length; - } - this.store.ChatWindow.records.splice( - index, - data.replaceNewMessageChatWindow ? 1 : 0, - chatWindow - ); - return this.store.ChatWindow.records[index]; // return reactive version - } - if (chatWindow.hidden) { - this.makeVisible(chatWindow); - } - assignDefined(chatWindow, data); - return chatWindow; - } - focus(chatWindow) { chatWindow.autofocus++; } diff --git a/addons/mail/static/src/core/common/follower_model.js b/addons/mail/static/src/core/common/follower_model.js index 29c13fbcb6b..8e9c9ab2785 100644 --- a/addons/mail/static/src/core/common/follower_model.js +++ b/addons/mail/static/src/core/common/follower_model.js @@ -1,6 +1,6 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; /** * @typedef Data @@ -11,6 +11,28 @@ import { Record } from "@mail/core/common/record"; */ export class Follower extends Record { + /** @type {Object.} */ + static records = {}; + /** + * @param {Data} data + * @returns {Follower} + */ + static insert(data) { + let follower = this.records[data.id]; + if (!follower) { + this.records[data.id] = new Follower(); + follower = this.records[data.id]; + } + Object.assign(follower, { + followedThread: data.followedThread, + id: data.id, + isActive: data.is_active, + partner: this.store.Persona.insert({ ...data.partner, type: "partner" }), + _store: this.store, + }); + return follower; + } + /** @type {import("@mail/core/common/thread_model").Thread} */ followedThread; /** @type {number} */ @@ -32,3 +54,5 @@ export class Follower extends Record { : hasWriteAccess; } } + +modelRegistry.add(Follower.name, Follower); diff --git a/addons/mail/static/src/core/common/message_model.js b/addons/mail/static/src/core/common/message_model.js index 65205f00272..4d746408d22 100644 --- a/addons/mail/static/src/core/common/message_model.js +++ b/addons/mail/static/src/core/common/message_model.js @@ -1,6 +1,6 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; import { htmlToTextContentInline } from "@mail/utils/common/format"; import { createLocalId } from "@mail/utils/common/misc"; @@ -14,6 +14,33 @@ import { url } from "@web/core/utils/urls"; const { DateTime } = luxon; export class Message extends Record { + /** @type {Object.} */ + static records = {}; + /** + * @param {Object} data + * @returns {Message} + */ + static insert(data) { + let message; + if (data.res_id) { + this.store.Thread.insert({ + model: data.model, + id: data.res_id, + }); + } + if (data.id in this.records) { + message = this.records[data.id]; + } else { + message = new Message(); + message._store = this.store; + this.records[data.id] = message; + message = this.records[data.id]; + } + this.env.services["mail.message"].update(message, data); + // return reactive version + return message; + } + /** @type {Object[]} */ attachments = []; /** @type {import("@mail/core/common/persona_model").Persona} */ @@ -243,3 +270,5 @@ export class Message extends Record { ); } } + +modelRegistry.add(Message.name, Message); diff --git a/addons/mail/static/src/core/common/message_service.js b/addons/mail/static/src/core/common/message_service.js index 14db8cf974a..83923369064 100644 --- a/addons/mail/static/src/core/common/message_service.js +++ b/addons/mail/static/src/core/common/message_service.js @@ -1,10 +1,7 @@ /* @odoo-module */ import { LinkPreview } from "@mail/core/common/link_preview_model"; -import { Message } from "@mail/core/common/message_model"; import { MessageReactions } from "@mail/core/common/message_reactions_model"; -import { NotificationGroup } from "@mail/core/common/notification_group_model"; -import { Notification } from "@mail/core/common/notification_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"; @@ -207,31 +204,6 @@ export class MessageService { } } - /** - * @param {Object} data - * @returns {Message} - */ - insert(data) { - let message; - if (data.res_id) { - this.store.Thread.insert({ - model: data.model, - id: data.res_id, - }); - } - if (data.id in this.store.Message.records) { - message = this.store.Message.records[data.id]; - } else { - message = new Message(); - message._store = this.store; - this.store.Message.records[data.id] = message; - message = this.store.Message.records[data.id]; - } - this.update(message, data); - // return reactive version - return message; - } - /** * @param {import("@mail/core/common/message_model").Message} message * @param {Object} data @@ -426,20 +398,6 @@ export class MessageService { return reaction; } - /** - * @param {Object} data - * @returns {Notification} - */ - insertNotification(data) { - let notification = this.store.Notification.records[data.id]; - if (!notification) { - this.store.Notification.records[data.id] = new Notification(this.store, data); - notification = this.store.Notification.records[data.id]; - } - this.updateNotification(notification, data); - return notification; - } - updateNotification(notification, data) { Object.assign(notification, { messageId: data.messageId, @@ -470,26 +428,6 @@ export class MessageService { }); } - insertNotificationGroups(data) { - let group = this.store.NotificationGroup.records.find((group) => { - return ( - group.resModel === data.resModel && - group.type === data.type && - (group.resModel !== "discuss.channel" || group.resIds.has(data.resId)) - ); - }); - if (!group) { - group = new NotificationGroup(this.store); - } - this.updateNotificationGroup(group, data); - if (group.notifications.length === 0) { - removeFromArrayWithPredicate(this.store.NotificationGroup.records, (gr) => - gr.eq(group) - ); - } - return group; - } - updateNotificationGroup(group, data) { Object.assign(group, { modelName: data.modelName ?? group.modelName, diff --git a/addons/mail/static/src/core/common/messaging_service.js b/addons/mail/static/src/core/common/messaging_service.js index cb00d1f95e1..85ac9206dea 100644 --- a/addons/mail/static/src/core/common/messaging_service.js +++ b/addons/mail/static/src/core/common/messaging_service.js @@ -1,6 +1,5 @@ /* @odoo-module */ -import { CannedResponse } from "@mail/core/common/canned_response_model"; import { cleanTerm } from "@mail/utils/common/format"; import { reactive } from "@odoo/owl"; @@ -157,20 +156,6 @@ export class Messaging { res_id: id, }); } - - insertCannedResponse(data) { - let cannedResponse = this.store.CannedResponse.records[data.id]; - if (!cannedResponse) { - this.store.CannedResponse.records[data.id] = new CannedResponse(); - cannedResponse = this.store.CannedResponse.records[data.id]; - } - Object.assign(cannedResponse, { - id: data.id, - name: data.source, - substitution: data.substitution, - }); - return cannedResponse; - } } export const messagingService = { 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 6d8d6b40104..07c7513a458 100644 --- a/addons/mail/static/src/core/common/notification_group_model.js +++ b/addons/mail/static/src/core/common/notification_group_model.js @@ -1,11 +1,36 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; +import { removeFromArrayWithPredicate } from "@mail/utils/common/arrays"; import { _t } from "@web/core/l10n/translation"; let nextId = 1; export class NotificationGroup extends Record { + /** @type {NotificationGroup[]} */ + static records = []; + /** + * @param {Object} data + * @returns {NotificationGroup} + */ + static insert(data) { + let group = this.records.find((group) => { + return ( + group.resModel === data.resModel && + group.type === data.type && + (group.resModel !== "discuss.channel" || group.resIds.has(data.resId)) + ); + }); + if (!group) { + group = new NotificationGroup(this.store); + } + this.env.services["mail.message"].updateNotificationGroup(group, data); + if (group.notifications.length === 0) { + removeFromArrayWithPredicate(this.records, (gr) => gr.eq(group)); + } + return group; + } + /** @type {import("@mail/core/common/notification_model").Notification[]} */ notifications = []; /** @type {string} */ @@ -46,3 +71,5 @@ export class NotificationGroup extends Record { return this.lastMessage?.datetime; } } + +modelRegistry.add(NotificationGroup.name, NotificationGroup); diff --git a/addons/mail/static/src/core/common/notification_model.js b/addons/mail/static/src/core/common/notification_model.js index 2220d234e8d..21af43a677b 100644 --- a/addons/mail/static/src/core/common/notification_model.js +++ b/addons/mail/static/src/core/common/notification_model.js @@ -1,10 +1,26 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; import { _t } from "@web/core/l10n/translation"; export class Notification extends Record { + /** @type {Object.} */ + static records = {}; + /** + * @param {Object} data + * @returns {Notification} + */ + static insert(data) { + let notification = this.records[data.id]; + if (!notification) { + this.records[data.id] = new Notification(this.store, data); + notification = this.records[data.id]; + } + this.env.services["mail.message"].updateNotification(notification, data); + return notification; + } + /** @type {number} */ id; /** @type {number} */ @@ -79,3 +95,5 @@ export class Notification extends Record { return ""; } } + +modelRegistry.add(Notification.name, Notification); diff --git a/addons/mail/static/src/core/common/persona_model.js b/addons/mail/static/src/core/common/persona_model.js index 583a9badafb..3b0426d4349 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 { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; +import { createLocalId } from "@mail/utils/common/misc"; /** * @typedef {'offline' | 'bot' | 'online' | 'away' | 'im_partner' | undefined} ImStatus @@ -13,6 +14,26 @@ import { Record } from "@mail/core/common/record"; */ export class Persona extends Record { + /** @type {Object.} */ + static records = {}; + /** + * @param {Data} data + * @returns {Persona} + */ + static insert(data) { + const localId = createLocalId(data.type, data.id); + let persona = this.records[localId]; + if (!persona) { + persona = new Persona(); + persona._store = this.store; + persona.localId = localId; + this.records[localId] = persona; + } + this.env.services["mail.persona"].update(persona, data); + // return reactive version + return this.records[localId]; + } + /** @type {string} */ localId; /** @type {number} */ @@ -45,3 +66,5 @@ export class Persona extends Record { return this.email.substring(0, this.email.lastIndexOf("@")); } } + +modelRegistry.add(Persona.name, Persona); diff --git a/addons/mail/static/src/core/common/persona_service.js b/addons/mail/static/src/core/common/persona_service.js index e71bbd41c68..8d3c04c8539 100644 --- a/addons/mail/static/src/core/common/persona_service.js +++ b/addons/mail/static/src/core/common/persona_service.js @@ -1,7 +1,6 @@ /* @odoo-module */ -import { Persona } from "@mail/core/common/persona_model"; -import { assignDefined, createLocalId, nullifyClearCommands } from "@mail/utils/common/misc"; +import { assignDefined, nullifyClearCommands } from "@mail/utils/common/misc"; import { registry } from "@web/core/registry"; import { useSequential } from "@mail/utils/common/hooks"; @@ -39,24 +38,6 @@ export class PersonaService { }); } - /** - * @param {import("@mail/core/common/persona_model").Data} data - * @returns {import("@mail/core/common/persona_model").Persona} - */ - insert(data) { - const localId = createLocalId(data.type, data.id); - let persona = this.store.Persona.records[localId]; - if (!persona) { - persona = new Persona(); - persona._store = this.store; - persona.localId = localId; - this.store.Persona.records[localId] = persona; - } - this.update(persona, data); - // return reactive version - return this.store.Persona.records[localId]; - } - update(persona, data) { nullifyClearCommands(data); assignDefined(persona, { ...data }); @@ -96,13 +77,13 @@ export class PersonaService { } ); for (const { id, is_company } of partnerData) { - this.insert({ id, is_company, type: "partner" }); + this.store.Persona.insert({ id, is_company, type: "partner" }); ongoing.delete(id); this._sQueue.todo.delete(id); } for (const id of ongoing) { // no is_company found => assumes persona is not a company - this.insert({ id, is_company: false, type: "partner" }); + this.store.Persona.insert({ id, is_company: false, type: "partner" }); this._sQueue.todo.delete(id); } }); diff --git a/addons/mail/static/src/core/common/record.js b/addons/mail/static/src/core/common/record.js index b63dbe633a0..34f0bf25986 100644 --- a/addons/mail/static/src/core/common/record.js +++ b/addons/mail/static/src/core/common/record.js @@ -1,8 +1,19 @@ /* @odoo-module */ import { toRaw } from "@odoo/owl"; +import { registry } from "@web/core/registry"; + +export const modelRegistry = registry.category("discuss.model"); export class Record { + static records = {}; + + /** + * @param {Object} data + * @returns {Record} + */ + static insert(data) {} + /** @param {Record} record */ eq(record) { return toRaw(this) === toRaw(record); @@ -23,3 +34,5 @@ export class Record { return !this.in(list); } } + +modelRegistry.add(Record.name, Record); diff --git a/addons/mail/static/src/core/common/store_service.js b/addons/mail/static/src/core/common/store_service.js index 80e17b8cbed..45fa7ce0593 100644 --- a/addons/mail/static/src/core/common/store_service.js +++ b/addons/mail/static/src/core/common/store_service.js @@ -7,119 +7,33 @@ import { reactive } from "@odoo/owl"; import { _t } from "@web/core/l10n/translation"; import { registry } from "@web/core/registry"; import { debounce } from "@web/core/utils/timing"; +import { modelRegistry } from "./record"; export class Store { - Activity = { - /** @type {Object.} */ - records: {}, - /** - * @param {import("@mail/core/web/activity_model").Data} data - * @param {Object} [param1] - * @param {boolean} param1.broadcast - * @returns {import("@mail/core/web/activity_model").Activity} - */ - insert: (data, { broadcast = true } = {}) => - this.env.services["mail.activity"].insert(data, { broadcast }), - }; - Attachment = { - /** @type {Object.} */ - records: {}, - /** - * @param {Object} data - * @returns {import("@mail/core/common/attachment_model").Attachment} - */ - insert: (data) => this.env.services["mail.attachment"].insert(data), - }; - CannedResponse = { - /** @type {Object.} */ - records: {}, - /** - * @param {Object} data - * @returns {import("@mail/core/common/canned_response_model").CannedResponse} - */ - insert: (data) => this.env.services["mail.messaging"].insertCannedResponse(data), - }; - ChannelMember = { - /** @type {Object.} */ - records: {}, - /** - * @param {Object|Array} data - * @returns {import("@mail/core/common/channel_member_model").ChannelMember} - */ - insert: (data) => this.env.services["discuss.channel.member"].insert(data), - }; - ChatWindow = { - /** @type {import("@mail/core/common/chat_window_model").ChatWindow[]} */ - records: [], - /** - * @param {ChatWindowData} [data] - * @returns {import("@mail/core/common/chat_window_model").ChatWindow} - */ - insert: (data = {}) => this.env.services["mail.chat_window"].insert(data), - }; - Follower = { - /** @type {Object.} */ - records: {}, - /** - * @param {import("@mail/core/common/follower_model").Data} data - * @returns {import("@mail/core/common/follower_model").Follower} - */ - insert: (data) => this.env.services["mail.thread"].insertFollower(data), - }; - Message = { - /** @type {Object.} */ - records: {}, - /** - * @param {Object} data - * @returns {import("@mail/core/common/message_model").Message} - */ - insert: (data) => this.env.services["mail.message"].insert(data), - }; - Notification = { - /** @type {Object.} */ - records: {}, - /** - * @param {Object} data - * @returns {import("@mail/core/common/notification_model").Notification} - */ - insert: (data) => this.env.services["mail.message"].insertNotification(data), - }; - NotificationGroup = { - /** @type {import("@mail/core/common/notification_group_model").NotificationGroup[]} */ - records: [], - /** - * @param {Object} data - * @returns {import("@mail/core/common/notification_group_model").NotificationGroup} - */ - insert: (data) => this.env.services["mail.message"].insertNotificationGroups(data), - }; - Persona = { - /** @type {Object.} */ - records: {}, - /** - * @param {import("@mail/core/common/persona_model").Data} data - * @returns {import("@mail/core/common/persona_model").Persona} - */ - insert: (data) => this.env.services["mail.persona"].insert(data), - }; - RtcSession = { - /** @type {Object.} */ - records: {}, - /** - * @param {Object} data - * @returns {number, import("@mail/discuss/call/common/rtc_session_model").RtcSession} - */ - insert: (data) => this.env.services["discuss.rtc"].insertSession(data), - }; - Thread = { - /** @type {Object.} */ - records: {}, - /** - * @param {Object} data - * @returns {import("@mail/core/common/thread_model").Thread} - */ - insert: (data) => this.env.services["mail.thread"].insert(data), - }; + /** @type {typeof import("@mail/core/web/activity_model").Activity} */ + Activity; + /** @type {typeof import("@mail/core/common/attachment_model").Attachment} */ + Attachment; + /** @type {typeof import("@mail/core/common/canned_response_model").CannedResponse} */ + CannedResponse; + /** @type {typeof import("@mail/core/common/channel_member_model").ChannelMember} */ + ChannelMember; + /** @type {typeof import("@mail/core/common/chat_window_model").ChatWindow} */ + ChatWindow; + /** @type {typeof import("@mail/core/common/follower_model").Follower} */ + Follower; + /** @type {typeof import("@mail/core/common/message_model").Message} */ + Message; + /** @type {typeof import("@mail/core/common/notification_model").Notification} */ + Notification; + /** @type {typeof import("@mail/core/common/notification_group_model").NotificationGroup} */ + NotificationGroup; + /** @type {typeof import("@mail/core/common/persona_model").Persona} */ + Persona; + /** @type {typeof import("@mail/discuss/call/common/rtc_session_model").RtcSession} */ + RtcSession; + /** @type {typeof import("@mail/core/common/thread_model").Thread} */ + Thread; /** * @param {import("@web/env").OdooEnv} env @@ -257,6 +171,19 @@ export const storeService = { */ start(env, services) { const res = reactive(new Store(env, services)); + for (const [name, Model] of modelRegistry.getEntries()) { + if (res[name]) { + throw new Error( + `There must be no duplicated Model Names (duplicate found: ${name})` + ); + } + // classes cannot be made reactive because they are functions and they are not supported. + // work-around: make an object whose prototype is the class, so that static props become + // instance props. + const entry = Object.assign(Object.create(Model), { env, store: res }); + entry.records = JSON.parse(JSON.stringify(Model.records)); + res[name] = entry; + } onChange(res.Thread, "records", () => res.updateBusSubscription()); services.ui.bus.addEventListener("resize", () => { if (!services.ui.isSmall) { diff --git a/addons/mail/static/src/core/common/thread_model.js b/addons/mail/static/src/core/common/thread_model.js index c25c3512242..234b35483c8 100644 --- a/addons/mail/static/src/core/common/thread_model.js +++ b/addons/mail/static/src/core/common/thread_model.js @@ -1,8 +1,8 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; import { ScrollPosition } from "@mail/core/common/scroll_position_model"; -import { createLocalId } from "@mail/utils/common/misc"; +import { createLocalId, onChange } from "@mail/utils/common/misc"; import { deserializeDateTime } from "@web/core/l10n/dates"; import { _t } from "@web/core/l10n/translation"; @@ -22,6 +22,44 @@ import { Deferred } from "@web/core/utils/concurrency"; */ export class Thread extends Record { + /** @type {Object.} */ + static records = {}; + /** + * @param {Object} data + * @returns {Thread} + */ + static insert(data) { + if (!("id" in data)) { + throw new Error("Cannot insert thread: id is missing in data"); + } + if (!("model" in data)) { + throw new Error("Cannot insert thread: model is missing in data"); + } + const localId = createLocalId(data.model, data.id); + if (localId in this.records) { + const thread = this.records[localId]; + this.env.services["mail.thread"].update(thread, data); + return thread; + } + const thread = new Thread(this.store, data); + onChange(thread, "message_unread_counter", () => { + if (thread.channel) { + thread.channel.message_unread_counter = thread.message_unread_counter; + } + }); + onChange(thread, "isLoaded", () => thread.isLoadedDeferred.resolve()); + onChange(thread, "channelMembers", () => this.store.updateBusSubscription()); + onChange(thread, "is_pinned", () => { + if (!thread.is_pinned && this.store.discuss.threadLocalId === thread.localId) { + this.store.discuss.threadLocalId = null; + } + }); + this.env.services["mail.thread"].update(thread, data); + this.env.services["mail.thread"].insertComposer({ thread }); + // return reactive version. + return this.records[thread.localId]; + } + /** @type {number} */ id; /** @type {string} */ @@ -461,3 +499,5 @@ export class Thread extends Record { return this._store.Message.records[Math.max(...previousMessages.map((m) => m.id))]; } } + +modelRegistry.add(Thread.name, Thread); diff --git a/addons/mail/static/src/core/common/thread_service.js b/addons/mail/static/src/core/common/thread_service.js index 4219f75f69d..f1dc99a6990 100644 --- a/addons/mail/static/src/core/common/thread_service.js +++ b/addons/mail/static/src/core/common/thread_service.js @@ -3,19 +3,13 @@ import { Composer } from "@mail/core/common/composer_model"; import { loadEmoji } from "@web/core/emoji_picker/emoji_picker"; import { DEFAULT_AVATAR } from "@mail/core/common/persona_service"; -import { Thread } from "@mail/core/common/thread_model"; import { removeFromArray, removeFromArrayWithPredicate, replaceArrayWithCompare, } from "@mail/utils/common/arrays"; import { prettifyMessageContent } from "@mail/utils/common/format"; -import { - assignDefined, - createLocalId, - onChange, - nullifyClearCommands, -} from "@mail/utils/common/misc"; +import { assignDefined, createLocalId, nullifyClearCommands } from "@mail/utils/common/misc"; import { markup } from "@odoo/owl"; @@ -803,42 +797,6 @@ export class ThreadService { this.env.bus.trigger("mail.thread/onUpdate", { thread, data }); } - /** - * @param {Object} data - * @returns {Thread} - */ - insert(data) { - if (!("id" in data)) { - throw new Error("Cannot insert thread: id is missing in data"); - } - if (!("model" in data)) { - throw new Error("Cannot insert thread: model is missing in data"); - } - const localId = createLocalId(data.model, data.id); - if (localId in this.store.Thread.records) { - const thread = this.store.Thread.records[localId]; - this.update(thread, data); - return thread; - } - const thread = new Thread(this.store, data); - onChange(thread, "message_unread_counter", () => { - if (thread.channel) { - thread.channel.message_unread_counter = thread.message_unread_counter; - } - }); - onChange(thread, "isLoaded", () => thread.isLoadedDeferred.resolve()); - onChange(thread, "channelMembers", () => this.store.updateBusSubscription()); - onChange(thread, "is_pinned", () => { - if (!thread.is_pinned && this.store.discuss.threadLocalId === thread.localId) { - this.store.discuss.threadLocalId = null; - } - }); - this.update(thread, data); - this.insertComposer({ thread }); - // return reactive version. - return this.store.Thread.records[thread.localId]; - } - /** * @param {Object} data * @returns {Composer} diff --git a/addons/mail/static/src/core/web/activity_list_popover.js b/addons/mail/static/src/core/web/activity_list_popover.js index f7ff32462a7..771385d904f 100644 --- a/addons/mail/static/src/core/web/activity_list_popover.js +++ b/addons/mail/static/src/core/web/activity_list_popover.js @@ -31,7 +31,6 @@ export class ActivityListPopover extends Component { setup() { this.orm = useService("orm"); this.user = useService("user"); - this.activity = useService("mail.activity"); this.store = useState(useService("mail.store")); this.updateFromProps(this.props); onWillUpdateProps((props) => this.updateFromProps(props)); @@ -84,7 +83,7 @@ export class ActivityListPopover extends Component { } ); for (const activityData of activitiesData) { - this.activity.insert(activityData); + this.store.Activity.insert(activityData); } } } diff --git a/addons/mail/static/src/core/web/activity_model.js b/addons/mail/static/src/core/web/activity_model.js index 8dbfd3068d0..26897f517c2 100644 --- a/addons/mail/static/src/core/web/activity_model.js +++ b/addons/mail/static/src/core/web/activity_model.js @@ -1,6 +1,7 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; +import { assignDefined } from "@mail/utils/common/misc"; /** * @typedef Data @@ -33,6 +34,30 @@ import { Record } from "@mail/core/common/record"; */ export class Activity extends Record { + /** @type {Object.} */ + static records = {}; + + /** + * @param {Data} data + * @param {Object} [param1] + * @param {boolean} param1.broadcast + * @returns {Activity} + */ + static insert(data, { broadcast = true } = {}) { + const activity = this.records[data.id] ?? new Activity(this.store, data.id); + if (data.request_partner_id) { + data.request_partner_id = data.request_partner_id[0]; + } + assignDefined(activity, data); + if (broadcast) { + this.env.services["mail.activity"].broadcastChannel?.postMessage({ + type: "insert", + payload: this.env.services["mail.activity"]._serialize(activity), + }); + } + return activity; + } + /** @type {string} */ activity_category; /** @type {[number, string]} */ @@ -105,3 +130,5 @@ export class Activity extends Record { return store.Activity.records[id]; } } + +modelRegistry.add(Activity.name, Activity); diff --git a/addons/mail/static/src/core/web/activity_service.js b/addons/mail/static/src/core/web/activity_service.js index eb6ad68f464..1cee861c51a 100644 --- a/addons/mail/static/src/core/web/activity_service.js +++ b/addons/mail/static/src/core/web/activity_service.js @@ -1,8 +1,5 @@ /* @odoo-module */ -import { Activity } from "@mail/core/web/activity_model"; -import { assignDefined } from "@mail/utils/common/misc"; - import { _t } from "@web/core/l10n/translation"; import { registry } from "@web/core/registry"; import { browser } from "@web/core/browser/browser"; @@ -80,27 +77,6 @@ export class ActivityService { }); } - /** - * @param {import("@mail/core/web/activity_model").Data} data - * @param {Object} [param1] - * @param {boolean} param1.broadcast - * @returns {import("@mail/core/web/activity_model").Activity} - */ - insert(data, { broadcast = true } = {}) { - const activity = this.store.Activity.records[data.id] ?? new Activity(this.store, data.id); - if (data.request_partner_id) { - data.request_partner_id = data.request_partner_id[0]; - } - assignDefined(activity, data); - if (broadcast) { - this.broadcastChannel?.postMessage({ - type: "insert", - payload: this._serialize(activity), - }); - } - return activity; - } - delete(activity, { broadcast = true } = {}) { delete this.store.Activity.records[activity.id]; if (broadcast) { 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 841be326ec9..10ecff6ced0 100644 --- a/addons/mail/static/src/core/web/thread_service_patch.js +++ b/addons/mail/static/src/core/web/thread_service_patch.js @@ -1,6 +1,5 @@ /* @odoo-module */ -import { Follower } from "@mail/core/common/follower_model"; import { ThreadService, threadService } from "@mail/core/common/thread_service"; import { parseEmail } from "@mail/js/utils"; import { createLocalId } from "@mail/utils/common/misc"; @@ -44,7 +43,7 @@ patch(ThreadService.prototype, { if ("attachments" in result) { result["attachments"] = result["attachments"].map((attachment) => ({ ...attachment, - originThread: this.insert(attachment.originThread[0][1]), + originThread: this.store.Thread.insert(attachment.originThread[0][1]), })); } thread.canPostOnReadonly = result.canPostOnReadonly; @@ -111,7 +110,7 @@ patch(ThreadService.prototype, { // to force a reload this.store.Thread.records[localId].status = "new"; } - const thread = this.insert({ + const thread = this.store.Thread.insert({ id: resId, model: resModel, type: "chatter", @@ -132,25 +131,6 @@ patch(ThreadService.prototype, { } return thread; }, - /** - * @param {import("@mail/core/common/follower_model").Data} data - * @returns {import("@mail/core/common/follower_model").Follower} - */ - insertFollower(data) { - let follower = this.store.Follower.records[data.id]; - if (!follower) { - this.store.Follower.records[data.id] = new Follower(); - follower = this.store.Follower.records[data.id]; - } - Object.assign(follower, { - followedThread: data.followedThread, - id: data.id, - isActive: data.is_active, - partner: this.store.Persona.insert({ ...data.partner, type: "partner" }), - _store: this.store, - }); - return follower; - }, /** * @param {import("@mail/core/common/thread_model").Thread} thread * @param {import("@mail/core/web/suggested_recipient").SuggestedRecipient[]} dataList 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 2b4830ee0cf..0cdb25bc5e5 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 { RtcSession } from "@mail/discuss/call/common/rtc_session_model"; import { removeFromArray } from "@mail/utils/common/arrays"; import { closeStream, createLocalId, onChange } from "@mail/utils/common/misc"; @@ -1397,38 +1396,6 @@ export class Rtc { await this.refreshAudioStatus(); } - /** - * @param {Object} data - * @returns {RtcSession} - */ - insertSession(data) { - let session; - if (this.store.RtcSession.records[data.id]) { - session = this.store.RtcSession.records[data.id]; - } else { - session = new RtcSession(); - session._store = this.store; - } - const { channelMember, ...remainingData } = data; - for (const key in remainingData) { - session[key] = remainingData[key]; - } - if (channelMember?.channel) { - session.channelId = channelMember.channel.id; - } - if (channelMember) { - const channelMemberRecord = this.store.ChannelMember.insert(channelMember); - channelMemberRecord.rtcSessionId = session.id; - session.channelMemberId = channelMemberRecord.id; - if (channelMemberRecord.thread) { - channelMemberRecord.thread.rtcSessions[session.id] = session; - } - } - this.store.RtcSession.records[session.id] = session; - // return reactive version - return this.store.RtcSession.records[session.id]; - } - /** * @param {import("@mail/discuss/call/common/rtc_session_model").id} id */ diff --git a/addons/mail/static/src/discuss/call/common/rtc_session_model.js b/addons/mail/static/src/discuss/call/common/rtc_session_model.js index 5fb6cb09d00..e119f60ce58 100644 --- a/addons/mail/static/src/discuss/call/common/rtc_session_model.js +++ b/addons/mail/static/src/discuss/call/common/rtc_session_model.js @@ -1,9 +1,43 @@ /* @odoo-module */ -import { Record } from "@mail/core/common/record"; +import { Record, modelRegistry } from "@mail/core/common/record"; import { createLocalId } from "@mail/utils/common/misc"; export class RtcSession extends Record { + /** @type {Object.} */ + static records = {}; + /** + * @param {Object} data + * @returns {number, RtcSession} + */ + static insert(data) { + let session; + if (this.records[data.id]) { + session = this.records[data.id]; + } else { + session = new RtcSession(); + session._store = this.store; + } + const { channelMember, ...remainingData } = data; + for (const key in remainingData) { + session[key] = remainingData[key]; + } + if (channelMember?.channel) { + session.channelId = channelMember.channel.id; + } + if (channelMember) { + const channelMemberRecord = this.store.ChannelMember.insert(channelMember); + channelMemberRecord.rtcSessionId = session.id; + session.channelMemberId = channelMemberRecord.id; + if (channelMemberRecord.thread) { + channelMemberRecord.thread.rtcSessions[session.id] = session; + } + } + this.records[session.id] = session; + // return reactive version + return this.records[session.id]; + } + // Server data channelId; channelMemberId; @@ -141,3 +175,5 @@ export class RtcSession extends Record { } } } + +modelRegistry.add(RtcSession.name, RtcSession); diff --git a/addons/mail/static/src/utils/common/misc.js b/addons/mail/static/src/utils/common/misc.js index b8813c48d8f..4b91565cb88 100644 --- a/addons/mail/static/src/utils/common/misc.js +++ b/addons/mail/static/src/utils/common/misc.js @@ -39,7 +39,6 @@ export function isDragSourceExternalFile(dataTransfer) { return false; } - /** * @param {Object} target * @param {string} key diff --git a/addons/mail/static/tests/core/attachment_model_tests.js b/addons/mail/static/tests/core/attachment_model_tests.js index 6dc380effd1..8f8342cd094 100644 --- a/addons/mail/static/tests/core/attachment_model_tests.js +++ b/addons/mail/static/tests/core/attachment_model_tests.js @@ -7,7 +7,7 @@ QUnit.module("attachment model test", {}); QUnit.test("Attachment model properties", async (assert) => { const { env } = await start(); - const attachment = env.services["mail.attachment"].insert({ + const attachment = env.services["mail.store"].Attachment.insert({ filename: "test.txt", id: 750, mimetype: "text/plain",