[REF] mail: add missing 'Model.insert()' in store

That way all models are in store with a relatively similar shape.
Any improvements on models will apply to all of them.

Part-of: odoo/odoo#133658
This commit is contained in:
Alexandre Kühn
2023-08-31 17:27:50 +00:00
parent 68197fde9a
commit a770d7aa33
10 changed files with 110 additions and 103 deletions
@@ -1,12 +1,41 @@
/* @odoo-module */
import { Record } from "@mail/core/common/record";
import { Record, modelRegistry } from "@mail/core/common/record";
/**
* @typedef {{partnerIds: Set<number>, threadIds: Set<number>}} 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);
@@ -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);
@@ -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)
);
}
}
@@ -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,
@@ -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);
@@ -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,
@@ -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;
}
@@ -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} */
@@ -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];
}
@@ -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