diff options
Diffstat (limited to 'addons/mail/static/src')
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"); |
