summaryrefslogtreecommitdiff
path: root/addons/mail/static/src
diff options
context:
space:
mode:
Diffstat (limited to 'addons/mail/static/src')
-rw-r--r--addons/mail/static/src/components/discuss/tests/discuss_tests.js4
-rw-r--r--addons/mail/static/src/model/model_field_command.js26
-rw-r--r--addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js77
3 files changed, 64 insertions, 43 deletions
diff --git a/addons/mail/static/src/components/discuss/tests/discuss_tests.js b/addons/mail/static/src/components/discuss/tests/discuss_tests.js
index 59a2b8cc239..dc2005e5ac7 100644
--- a/addons/mail/static/src/components/discuss/tests/discuss_tests.js
+++ b/addons/mail/static/src/components/discuss/tests/discuss_tests.js
@@ -2574,18 +2574,22 @@ QUnit.test('inbox: mark all messages as read', async function (assert) {
body: "not empty",
channel_ids: [20], // link message to channel
id: 100, // random unique id, useful to link notification
+ model: 'mail.channel',
// needaction needs to be set here for message_fetch domain, because
// mocked models don't have computed fields
needaction: true,
+ res_id: 20,
},
// second expected message
{
body: "not empty",
channel_ids: [20], // link message to channel
id: 101, // random unique id, useful to link notification
+ model: 'mail.channel',
// needaction needs to be set here for message_fetch domain, because
// mocked models don't have computed fields
needaction: true,
+ res_id: 20,
}
);
this.data['mail.notification'].records.push(
diff --git a/addons/mail/static/src/model/model_field_command.js b/addons/mail/static/src/model/model_field_command.js
index 89f42651ad9..a6dadb7b983 100644
--- a/addons/mail/static/src/model/model_field_command.js
+++ b/addons/mail/static/src/model/model_field_command.js
@@ -35,11 +35,37 @@ function clear() {
);
}
+/**
+ * Returns a decrement command to give to the model manager at create/update.
+ *
+ * @param {number} [amount=1]
+ */
+function decrement(amount = 1) {
+ return new FieldCommand((field, record, options) => {
+ const oldValue = field.get(record);
+ field.set(record, oldValue - amount, options);
+ });
+}
+
+/**
+ * Returns a increment command to give to the model manager at create/update.
+ *
+ * @param {number} [amount=1]
+ */
+function increment(amount = 1) {
+ return new FieldCommand((field, record, options) => {
+ const oldValue = field.get(record);
+ field.set(record, oldValue + amount, options);
+ });
+}
+
return {
// class
FieldCommand,
// shortcuts
clear,
+ decrement,
+ increment,
};
});
diff --git a/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js b/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js
index f497fa420e6..a63acfb82fe 100644
--- a/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js
+++ b/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js
@@ -3,6 +3,7 @@ odoo.define('mail/static/src/models/messaging_notification_handler/messaging_not
const { registerNewModel } = require('mail/static/src/model/model_core.js');
const { one2one } = require('mail/static/src/model/model_field.js');
+const { decrement, increment } = require('mail/static/src/model/model_field_command.js');
const { htmlToTextContentInline } = require('mail.utils');
const PREVIEW_MSG_MAX_SIZE = 350; // optimal for native English speakers
@@ -222,7 +223,7 @@ function factory(dependencies) {
oldMessageWasModeratedByCurrentPartner
) {
const moderation = this.env.messaging.moderation;
- moderation.update({ counter: moderation.counter - 1 });
+ moderation.update({ counter: decrement() });
}
return;
}
@@ -389,15 +390,10 @@ function factory(dependencies) {
const message = this.env.models['mail.message'].insert(
this.env.models['mail.message'].convertData(data)
);
- const inboxMailbox = this.env.messaging.inbox;
- inboxMailbox.update({ counter: inboxMailbox.counter + 1 });
- for (const thread of message.threads) {
- if (
- thread.channel_type === 'channel' &&
- message.isNeedaction
- ) {
- thread.update({ message_needaction_counter: thread.message_needaction_counter + 1 });
- }
+ this.env.messaging.inbox.update({ counter: increment() });
+ const originThread = message.originThread;
+ if (originThread && message.isNeedaction) {
+ originThread.update({ message_needaction_counter: increment() });
}
// manually force recompute of counter
this.messaging.messagingMenu.update();
@@ -522,7 +518,7 @@ function factory(dependencies) {
message.moderation_status === 'pending_moderation' &&
message.originThread.isModeratedByCurrentPartner
) {
- moderationMailbox.update({ counter: moderationMailbox.counter - 1 });
+ moderationMailbox.update({ counter: decrement() });
}
message.delete();
}
@@ -558,11 +554,9 @@ function factory(dependencies) {
* @param {Object} param0
* @param {integer[]} [param0.channel_ids
* @param {integer[]} [param0.message_ids=[]]
+ * @param {integer} [param0.needaction_inbox_counter]
*/
- _handleNotificationPartnerMarkAsRead({ channel_ids, message_ids = [] }) {
- const inboxMailbox = this.env.messaging.inbox;
-
- // 1. move messages from inbox to history
+ _handleNotificationPartnerMarkAsRead({ channel_ids, message_ids = [], needaction_inbox_counter }) {
for (const message_id of message_ids) {
// We need to ignore all not yet known messages because we don't want them
// to be shown partially as they would be linked directly to mainCache
@@ -570,34 +564,33 @@ function factory(dependencies) {
// but something like last read message_id or something like that.
// (just imagine you mark 1000 messages as read ... )
const message = this.env.models['mail.message'].findFromIdentifyingData({ id: message_id });
- if (message) {
- message.update({
- isNeedaction: false,
- isHistory: true,
- });
+ if (!message) {
+ continue;
}
+ // update thread counter
+ const originThread = message.originThread;
+ if (originThread && message.isNeedaction) {
+ originThread.update({ message_needaction_counter: decrement() });
+ }
+ // move messages from Inbox to history
+ message.update({
+ isHistory: true,
+ isNeedaction: false,
+ });
}
-
- // 2. remove "needaction" from channels
- let channels;
- if (channel_ids) {
- channels = channel_ids
- .map(id => this.env.models['mail.thread'].findFromIdentifyingData({
- id,
- model: 'mail.channel',
- }))
- .filter(thread => !!thread);
+ const inbox = this.env.messaging.inbox;
+ if (needaction_inbox_counter !== undefined) {
+ inbox.update({ counter: needaction_inbox_counter });
} else {
- // flux specific: channel_ids unset means "mark all as read"
- channels = this.env.models['mail.thread'].all(thread =>
- thread.model === 'mail.channel'
- );
+ // kept for compatibility in stable
+ inbox.update({ counter: decrement(message_ids.length) });
}
- for (const channel of channels) {
- channel.update({ message_needaction_counter: 0 });
+ if (inbox.counter > inbox.mainCache.fetchedMessages.length) {
+ // Force refresh Inbox because depending on what was marked as
+ // read the cache might become empty even though there are more
+ // messages on the server.
+ inbox.mainCache.update({ hasToLoadMessages: true });
}
- inboxMailbox.update({ counter: inboxMailbox.counter - message_ids.length });
-
// manually force recompute of counter
this.messaging.messagingMenu.update();
}
@@ -613,7 +606,7 @@ function factory(dependencies) {
);
const moderationMailbox = this.env.messaging.moderation;
if (moderationMailbox) {
- moderationMailbox.update({ counter: moderationMailbox.counter + 1 });
+ moderationMailbox.update({ counter: increment() });
}
// manually force recompute of counter
this.messaging.messagingMenu.update();
@@ -636,9 +629,7 @@ function factory(dependencies) {
}
message.update({ isStarred: starred });
starredMailbox.update({
- counter: starred
- ? starredMailbox.counter + 1
- : starredMailbox.counter - 1,
+ counter: starred ? increment() : decrement(),
});
}
}
@@ -758,7 +749,7 @@ function factory(dependencies) {
}
const notificationContent = htmlToTextContentInline(message.body).substr(0, PREVIEW_MSG_MAX_SIZE);
this.env.services['bus_service'].sendNotification(notificationTitle, notificationContent);
- messaging.update({ outOfFocusUnreadMessageCounter: messaging.outOfFocusUnreadMessageCounter + 1 });
+ messaging.update({ outOfFocusUnreadMessageCounter: increment() });
const titlePattern = messaging.outOfFocusUnreadMessageCounter === 1
? this.env._t("%d Message")
: this.env._t("%d Messages");