Skip to content

Commit

Permalink
[FIX] mail: opening chat with deleted new message should mark as read
Browse files Browse the repository at this point in the history
Before this commit, when a user of in chat posted a message and
deleted it, all other users kept the chat as unread.

Steps to reproduce:
- Connect as Admin and March Demo
- Send a message to Admin as Demo in DM chat
- Demo deletes this message
- Marc opens the chat
=> the unread counter is 1 and cannot be removed

This happens because when a message is deleted, there's still a
trace of it but the message is empty. However, empty messages could
not be candidate of setting the last message being seing by a member,
thus members were unable to mark the chat as read until someone else
posted a newer message (and did not delete it).

This commit fixes the issue by taking empty messages into account for
setting last message message of member, which allow to mark thread as
read even when newer messages have been deleted.

opw-3764410

closes #159362

X-original-commit: 7c7634e
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
  • Loading branch information
alexkuhn committed Mar 28, 2024
1 parent d2a3438 commit 6d0f79f
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 8 deletions.
20 changes: 16 additions & 4 deletions addons/mail/static/src/core/common/thread_model.js
Expand Up @@ -442,13 +442,25 @@ export class Thread extends Record {
return [...this.messages].reverse().find((msg) => Number.isInteger(msg.id));
}

newestPersistentNotEmptyOfAllMessage = Record.one("Message", {
newestPersistentAllMessages = Record.many("Message", {
compute() {
const allPersistentMessages = this.allMessages.filter(
(message) => Number.isInteger(message.id) && !message.isEmpty
const allPersistentMessages = this.allMessages.filter((message) =>
Number.isInteger(message.id)
);
allPersistentMessages.sort((m1, m2) => m2.id - m1.id);
return allPersistentMessages[0];
return allPersistentMessages;
},
});

newestPersistentOfAllMessage = Record.one("Message", {
compute() {
return this.newestPersistentAllMessages[0];
},
});

newestPersistentNotEmptyOfAllMessage = Record.one("Message", {
compute() {
return this.newestPersistentAllMessages.find((message) => !message.isEmpty);
},
});

Expand Down
4 changes: 2 additions & 2 deletions addons/mail/static/src/core/common/thread_service.js
Expand Up @@ -62,7 +62,7 @@ export class ThreadService {
* @param {import("models").Thread} thread
*/
markAsRead(thread) {
const newestPersistentMessage = thread.newestPersistentNotEmptyOfAllMessage;
const newestPersistentMessage = thread.newestPersistentOfAllMessage;
if (!newestPersistentMessage && !thread.isLoaded) {
thread.isLoadedDeferred
.then(() => new Promise(setTimeout))
Expand Down Expand Up @@ -96,7 +96,7 @@ export class ThreadService {
}
}

updateSeen(thread, lastSeen = thread.newestPersistentNotEmptyOfAllMessage) {
updateSeen(thread, lastSeen = thread.newestPersistentOfAllMessage) {
const lastReadIndex = thread.messages.findIndex((message) => message.eq(lastSeen));
let newNeedactionCounter = 0;
let newUnreadCounter = 0;
Expand Down
43 changes: 41 additions & 2 deletions addons/mail/static/tests/discuss_app/discuss.test.js
Expand Up @@ -1193,7 +1193,7 @@ test("should auto-pin chat when receiving a new DM", async () => {
Command.create({
unpin_dt: "2021-01-01 12:00:00",
last_interest_dt: "2021-01-01 10:00:00",
partner_id: serverState.partnerId
partner_id: serverState.partnerId,
}),
Command.create({ partner_id: partnerId }),
],
Expand Down Expand Up @@ -1738,7 +1738,7 @@ test("sidebar: cannot unpin channel group_based_subscription: mandatorily pinned
Command.create({
unpin_dt: "2021-01-01 12:00:00",
last_interest_dt: "2021-01-01 10:00:00",
partner_id: serverState.partnerId
partner_id: serverState.partnerId,
}),
],
group_ids: [Command.create({ name: "test" })],
Expand Down Expand Up @@ -2052,3 +2052,42 @@ test("Newly created chat should be at the top of the direct message list", async
before: [".o-mail-DiscussSidebar-item", { text: "Albert" }],
});
});

test("Read of unread chat where new message is deleted should mark as read.", async () => {
const pyEnv = await startServer();
const partnerId = pyEnv["res.partner"].create({ name: "Marc Demo" });
const channelId = pyEnv["discuss.channel"].create({
channel_member_ids: [
Command.create({ partner_id: serverState.partnerId }),
Command.create({ partner_id: partnerId }),
],
channel_type: "chat",
});
const messageId = pyEnv["mail.message"].create({
author_id: partnerId,
body: "Heyo",
model: "discuss.channel",
res_id: channelId,
message_type: "comment",
});
const [memberId] = pyEnv["discuss.channel.member"].search([
["channel_id", "=", channelId],
["partner_id", "=", serverState.partnerId],
]);
pyEnv["discuss.channel.member"].write([memberId], {
seen_message_id: messageId,
message_unread_counter: 1,
});
const env = await start();
rpc = rpcWithEnv(env);
await openDiscuss();
await contains("button", { text: "Marc Demo", contains: [".badge", { text: "1" }] });
// simulate deleted message
rpc("/mail/message/update_content", {
message_id: messageId,
body: "",
attachment_ids: [],
});
await click("button", { text: "Marc Demo" });
await contains("button", { text: "Marc Demo", contains: [".badge", { count: 0 }] });
});

0 comments on commit 6d0f79f

Please sign in to comment.