[REF] mail: move discuss.channel/new_message to discuss folder

Part of task-3265211

Part-of: odoo/odoo#128593
This commit is contained in:
Sébastien Theys
2023-07-17 18:13:38 +02:00
parent bcc420e5d4
commit adae210696
6 changed files with 223 additions and 121 deletions
@@ -27,8 +27,6 @@ export class Messaging {
this.store = services["mail.store"];
this.rpc = services.rpc;
this.orm = services.orm;
/** @type {import("@mail/core/common/channel_member_service").ChannelMemberService} */
this.channelMemberService = services["discuss.channel.member"];
/** @type {import("@mail/core/common/attachment_service").AttachmentService} */
this.attachmentService = services["mail.attachment"];
this.notificationService = services.notification;
@@ -40,11 +38,8 @@ export class Messaging {
this.messageService = services["mail.message"];
/** @type {import("@mail/core/common/persona_service").PersonaService} */
this.personaService = services["mail.persona"];
/** @type {import("@mail/core/common/out_of_focus_service").OutOfFocusService} */
this.outOfFocusService = services["mail.out_of_focus"];
this.router = services.router;
this.bus = services.bus_service;
this.presence = services.presence;
this.isReady = new Deferred();
this.imStatusService = services.im_status;
const user = services.user;
@@ -158,14 +153,6 @@ export class Messaging {
// -------------------------------------------------------------------------
handleNotification(notifications) {
const channelsLeft = new Set(
notifications.reduce((channelIds, notification) => {
if (notification.type === "discuss.channel/leave") {
channelIds.push(notification.payload.id);
}
return channelIds;
}, [])
);
for (const notif of notifications) {
switch (notif.type) {
case "mail.activity/updated":
@@ -176,17 +163,6 @@ export class Messaging {
this.store.activityCounter--;
}
break;
case "discuss.channel/new_message":
if (channelsLeft.has(notif.payload.id)) {
// Do not handle new message notification if the channel
// was just left. This issue occurs because the
// "discuss.channel/leave" and the
// "discuss.channel/new_message" notifications come from
// the bus as a batch.
break;
}
this._handleNotificationNewMessage(notif);
break;
case "discuss.channel/leave":
{
const thread = this.threadService.insert({
@@ -446,87 +422,6 @@ export class Messaging {
}
}
async _handleNotificationNewMessage(notif) {
const { id, message: messageData } = notif.payload;
let channel = this.store.threads[createLocalId("discuss.channel", id)];
if (!channel || !channel.type) {
const [channelData] = await this.rpc("/discuss/channel/info", { channel_id: id });
channel = this.threadService.insert({
model: "discuss.channel",
type: channelData.channel.channel_type,
...channelData,
});
}
if (!channel.is_pinned) {
this.threadService.pin(channel);
}
removeFromArrayWithPredicate(channel.messages, ({ id }) => id === messageData.temporary_id);
delete this.store.messages[messageData.temporary_id];
messageData.temporary_id = null;
if ("parentMessage" in messageData && messageData.parentMessage.body) {
messageData.parentMessage.body = markup(messageData.parentMessage.body);
}
const data = Object.assign(messageData, {
body: markup(messageData.body),
});
const message = this.messageService.insert({
...data,
res_id: channel.id,
model: channel.model,
});
if (!channel.messages.includes(message)) {
if (!channel.loadNewer) {
channel.messages.push(message);
} else if (channel.state === "loading") {
channel.pendingNewMessages.push(message);
}
if (message.isSelfAuthored) {
channel.seen_message_id = message.id;
} else {
if (notif.id > this.store.initBusId) {
channel.message_unread_counter++;
}
if (message.isNeedaction) {
const inbox = this.store.discuss.inbox;
if (!inbox.messages.includes(message)) {
inbox.messages.push(message);
if (notif.id > this.store.initBusId) {
inbox.counter++;
}
}
if (!channel.needactionMessages.includes(message)) {
channel.needactionMessages.push(message);
if (notif.id > this.store.initBusId) {
channel.message_needaction_counter++;
}
}
}
}
}
if (channel.chatPartnerId !== this.store.odoobot?.id) {
if (!this.presence.isOdooFocused() && channel.isChatChannel) {
this.outOfFocusService.notify(message, channel);
}
if (channel.type !== "channel" && !this.store.guest) {
// disabled on non-channel threads and
// on "channel" channels for performance reasons
this.threadService.markAsFetched(channel);
}
}
if (
!channel.loadNewer &&
!message.isSelfAuthored &&
channel.composer.isFocused &&
channel.newestPersistentMessage &&
!this.store.guest &&
channel.newestPersistentMessage === channel.newestMessage
) {
this.threadService.markAsRead(channel);
}
}
_handleNotificationRecordInsert(notif) {
if (notif.payload.Thread) {
this.threadService.insert(notif.payload.Thread);
@@ -652,7 +547,6 @@ export class Messaging {
export const messagingService = {
dependencies: [
"mail.store",
"discuss.channel.member",
"rpc",
"orm",
"user",
@@ -660,13 +554,11 @@ export const messagingService = {
"bus_service",
"im_status",
"notification",
"presence",
"mail.attachment",
"mail.user_settings",
"mail.thread",
"mail.message",
"mail.persona",
"mail.out_of_focus",
],
start(env, services) {
const messaging = new Messaging(env, services);
@@ -1,7 +1,6 @@
/* @odoo-module */
import { Messaging, messagingService } from "@mail/core/common/messaging_service";
import { createLocalId } from "@mail/utils/common/misc";
import { _t } from "@web/core/l10n/translation";
import { patch } from "@web/core/utils/patch";
@@ -42,18 +41,6 @@ patch(Messaging.prototype, "mail/core/web", {
}
this._super(data);
},
async _handleNotificationNewMessage(notif) {
await this._super(notif);
const channel = this.store.threads[createLocalId("discuss.channel", notif.payload.id)];
const message = this.store.messages[notif.payload.message.id];
if (
!this.ui.isSmall &&
channel.correspondent !== this.store.odoobot &&
!message.isSelfAuthored
) {
this.chatWindowService.insert({ thread: channel });
}
},
});
patch(messagingService, "mail/core/web", {
@@ -0,0 +1,152 @@
/* @odoo-module */
import { removeFromArrayWithPredicate } from "@mail/utils/common/arrays";
import { createLocalId } from "@mail/utils/common/misc";
import { markup, reactive } from "@odoo/owl";
import { registry } from "@web/core/registry";
export class DiscussCoreCommon {
constructor(env, services) {
Object.assign(this, {
busService: services.bus_service,
env,
presence: services.presence,
rpc: services.rpc,
});
/** @type {import("@mail/core/common/message_service").MessageService} */
this.messageService = services["mail.message"];
/** @type {import("@mail/core/common/messaging_service").Messaging} */
this.messagingService = services["mail.messaging"];
/** @type {import("@mail/core/common/out_of_focus_service").OutOfFocusService} */
this.outOfFocusService = services["mail.out_of_focus"];
/** @type {import("@mail/core/common/thread_service").ThreadService} */
this.threadService = services["mail.thread"];
/** @type {import("@mail/core/common/store_service").Store} */
this.store = services["mail.store"];
}
setup() {
this.messagingService.isReady.then(() => {
this.busService.addEventListener("notification", ({ detail: notifications }) => {
// Do not handle new message notification if the channel was just left. This issue
// occurs because the "discuss.channel/leave" and the "discuss.channel/new_message"
// notifications come from the bus as a batch.
const channelsLeft = new Set(
notifications
.filter(({ type }) => type === "discuss.channel/leave")
.map(({ payload }) => payload.id)
);
for (const notif of notifications.filter(
({ payload, type }) =>
type === "discuss.channel/new_message" && !channelsLeft.has(payload.id)
)) {
this._handleNotificationNewMessage(notif);
}
});
this.busService.start();
});
}
async _handleNotificationNewMessage(notif) {
const { id, message: messageData } = notif.payload;
let channel = this.store.threads[createLocalId("discuss.channel", id)];
if (!channel || !channel.type) {
const [channelData] = await this.rpc("/discuss/channel/info", { channel_id: id });
channel = this.threadService.insert({
model: "discuss.channel",
type: channelData.channel.channel_type,
...channelData,
});
}
if (!channel.is_pinned) {
this.threadService.pin(channel);
}
removeFromArrayWithPredicate(channel.messages, ({ id }) => id === messageData.temporary_id);
delete this.store.messages[messageData.temporary_id];
messageData.temporary_id = null;
if ("parentMessage" in messageData && messageData.parentMessage.body) {
messageData.parentMessage.body = markup(messageData.parentMessage.body);
}
const data = Object.assign(messageData, {
body: markup(messageData.body),
});
const message = this.messageService.insert({
...data,
res_id: channel.id,
model: channel.model,
});
if (!channel.messages.includes(message)) {
if (!channel.loadNewer) {
channel.messages.push(message);
} else if (channel.state === "loading") {
channel.pendingNewMessages.push(message);
}
if (message.isSelfAuthored) {
channel.seen_message_id = message.id;
} else {
if (notif.id > this.store.initBusId) {
channel.message_unread_counter++;
}
if (message.isNeedaction) {
const inbox = this.store.discuss.inbox;
if (!inbox.messages.includes(message)) {
inbox.messages.push(message);
if (notif.id > this.store.initBusId) {
inbox.counter++;
}
}
if (!channel.needactionMessages.includes(message)) {
channel.needactionMessages.push(message);
if (notif.id > this.store.initBusId) {
channel.message_needaction_counter++;
}
}
}
}
}
if (channel.chatPartnerId !== this.store.odoobot?.id) {
if (!this.presence.isOdooFocused() && channel.isChatChannel) {
this.outOfFocusService.notify(message, channel);
}
if (channel.type !== "channel" && !this.store.guest) {
// disabled on non-channel threads and
// on "channel" channels for performance reasons
this.threadService.markAsFetched(channel);
}
}
if (
!channel.loadNewer &&
!message.isSelfAuthored &&
channel.composer.isFocused &&
channel.newestPersistentMessage &&
!this.store.guest &&
channel.newestPersistentMessage === channel.newestMessage
) {
this.threadService.markAsRead(channel);
}
this.env.bus.trigger("discuss.channel/new_message", { channel, message });
}
}
export const discussCoreCommon = {
dependencies: [
"bus_service",
"mail.message",
"mail.messaging",
"mail.out_of_focus",
"mail.store",
"mail.thread",
"presence",
"rpc",
],
start(env, services) {
const discussCoreCommon = reactive(new DiscussCoreCommon(env, services));
discussCoreCommon.setup();
return discussCoreCommon;
},
};
registry.category("services").add("discuss.core.common", discussCoreCommon);
@@ -0,0 +1,41 @@
/* @odoo-module */
import { reactive } from "@odoo/owl";
import { registry } from "@web/core/registry";
export class DiscussCoreWeb {
constructor(env, services) {
Object.assign(this, { env, ui: services.ui });
/** @type {import("@mail/core/common/chat_window_service").ChatWindowService} */
this.chatWindowService = services["mail.chat_window"];
/** @type {import("@mail/core/common/store_service").Store} */
this.store = services["mail.store"];
}
setup() {
this.env.bus.addEventListener(
"discuss.channel/new_message",
({ detail: { channel, message } }) => {
if (
!this.ui.isSmall &&
channel.correspondent !== this.store.odoobot &&
!message.isSelfAuthored
) {
this.chatWindowService.insert({ thread: channel });
}
}
);
}
}
export const discussCoreWeb = {
dependencies: ["mail.chat_window", "mail.store", "ui"],
start(env, services) {
const discussCoreWeb = reactive(new DiscussCoreWeb(env, services));
discussCoreWeb.setup();
return discussCoreWeb;
},
};
registry.category("services").add("discuss.core.web", discussCoreWeb);
@@ -0,0 +1,15 @@
/* @odoo-module */
import { discussCoreCommon } from "@mail/discuss/core/common/discuss_core_common_service";
import { setupManager } from "@mail/../tests/helpers/webclient_setup";
import { patch } from "@web/core/utils/patch";
patch(setupManager, "discuss/core/common", {
setupServices(...args) {
return {
...this._super(...args),
"discuss.core.common": discussCoreCommon,
};
},
});
@@ -0,0 +1,15 @@
/* @odoo-module */
import { discussCoreWeb } from "@mail/discuss/core/web/discuss_core_web_service";
import { setupManager } from "@mail/../tests/helpers/webclient_setup";
import { patch } from "@web/core/utils/patch";
patch(setupManager, "discuss/core/web", {
setupServices(...args) {
return {
...this._super(...args),
"discuss.core.web": discussCoreWeb,
};
},
});