diff --git a/addons/bus/static/src/js/bus.js b/addons/bus/static/src/js/bus.js index b36a620afb3..a8de43dd9fa 100644 --- a/addons/bus/static/src/js/bus.js +++ b/addons/bus/static/src/js/bus.js @@ -66,7 +66,7 @@ bus.Bus = Widget.extend({ } var data = {channels: self.channels, last: self.last, options: options}; session.rpc('/longpolling/poll', data, {shadow : true}).then(function(result) { - self._notification_receive(result); + self.on_notification(result); if(!self.stop){ self.poll(); } @@ -77,14 +77,15 @@ bus.Bus = Widget.extend({ setTimeout(_.bind(self.poll, self), bus.ERROR_DELAY + (Math.floor((Math.random()*20)+1)*1000)); }); }, - _notification_receive: function(notifications){ - _.each(notifications, this.on_notification); - }, - on_notification: function(notification) { - if (notification.id > this.last) { - this.last = notification.id; - } - this.trigger("notification", [notification.channel, notification.message]); + on_notification: function(notifications) { + var self = this; + var notifs = _.map(notifications, function (notif) { + if (notif.id > self.last) { + self.last = notif.id; + } + return [notif.channel, notif.message]; + }); + this.trigger("notification", notifs); }, add_channel: function(channel){ this.channels.push(channel); @@ -173,7 +174,7 @@ var CrossTabBus = bus.Bus.extend({ this._super.apply(this, arguments); } }, - _notification_receive: function(notifications){ + on_notification: function(notifications){ if(this.is_master) { // broadcast to other tabs var last = getItem('bus.last', -1); var max_id = Math.max(last, 0); @@ -199,7 +200,7 @@ var CrossTabBus = bus.Bus.extend({ // notifications changed if(e.key === 'bus.notification'){ var notifs = JSON.parse(value); - _.each(notifs, this.on_notification); + this.on_notification(notifs); } // update channels if(e.key === 'bus.channels'){ diff --git a/addons/im_livechat/static/src/js/im_livechat.js b/addons/im_livechat/static/src/js/im_livechat.js index a9302451a32..9ccb50c10f8 100644 --- a/addons/im_livechat/static/src/js/im_livechat.js +++ b/addons/im_livechat/static/src/js/im_livechat.js @@ -64,14 +64,17 @@ var LivechatButton = Widget.extend({ this.auto_popup_timeout = setTimeout(this.open_chat.bind(this), this.rule.auto_popup_timer*1000); } } - bus.on('notification', this, function (notification) { - if (this.channel && (notification[0] === this.channel.uuid)) { - this.add_message(notification[1]); - this.render_messages(); - if (this.chat_window.folded || !this.chat_window.thread.is_at_bottom()) { - this.chat_window.update_unread(this.chat_window.unread_msgs+1); + bus.on('notification', this, function (notifications) { + var self = this; + _.each(notifications, function (notification) { + if (self.channel && (notification[0] === self.channel.uuid)) { + self.add_message(notification[1]); + self.render_messages(); + if (self.chat_window.folded || !self.chat_window.thread.is_at_bottom()) { + self.chat_window.update_unread(self.chat_window.unread_msgs+1); + } } - } + }); }); return this._super(); }, diff --git a/addons/mail/static/src/js/chat_manager.js b/addons/mail/static/src/js/chat_manager.js index 17462d8f6d4..aff51c721cf 100644 --- a/addons/mail/static/src/js/chat_manager.js +++ b/addons/mail/static/src/js/chat_manager.js @@ -464,21 +464,35 @@ var channel_seen = _.throttle(function (channel) { // Notification handlers // --------------------------------------------------------------------------------- -function on_notification (notification) { - var model = notification[0][1]; - if (model === 'ir.needaction') { - // new message in the inbox - on_needaction_notification(notification[1]); - } else if (model === 'mail.channel') { - // new message in a channel - on_channel_notification(notification[1]); - } else if (model === 'res.partner') { - // channel joined/left, message marked as read/(un)starred, chat open/closed - on_partner_notification(notification[1]); - } else if (model === 'bus.presence') { - // update presence of users - on_presence_notification(notification[1]); +function on_notification (notifications) { + // sometimes, the web client receives unsubscribe notification and an extra + // notification on that channel. This is then followed by an attempt to + // rejoin the channel that we just left. The next few lines remove the + // extra notification to prevent that situation to occur. + var unsubscribed_notif = _.find(notifications, function (notif) { + return notif[1].info === "unsubscribe"; + }); + if (unsubscribed_notif) { + notifications = _.reject(notifications, function (notif) { + return notif[0][1] === "mail.channel" && notif[0][2] === unsubscribed_notif[1].id; + }); } + _.each(notifications, function (notification) { + var model = notification[0][1]; + if (model === 'ir.needaction') { + // new message in the inbox + on_needaction_notification(notification[1]); + } else if (model === 'mail.channel') { + // new message in a channel + on_channel_notification(notification[1]); + } else if (model === 'res.partner') { + // channel joined/left, message marked as read/(un)starred, chat open/closed + on_partner_notification(notification[1]); + } else if (model === 'bus.presence') { + // update presence of users + on_presence_notification(notification[1]); + } + }); } function on_needaction_notification (message) {