From cc8c355ecb2ac3daa4ef7ea76707e84828185d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Tue, 29 Dec 2015 10:13:55 +0100 Subject: [PATCH] [IMP] mail, bus: display native notifications if user away This commit introduces native notifications (if available) to the discuss application. Those notifications will only appear if the user grants the permission for that. A notification bar will appear in the discuss application if necessary to prompt the user. Also, it always is the master bus that will be the one sending the notification. For this change, it was necessary to be able to detect if the user has the focus on some other odoo tabs. For this reason, the bus was extended. --- addons/bus/static/src/js/bus.js | 20 ++++--- addons/mail/static/src/js/chat_manager.js | 57 +++++++++---------- addons/mail/static/src/js/client_action.js | 9 +++ .../mail/static/src/less/client_action.less | 29 ++++++++++ addons/mail/static/src/xml/client_action.xml | 6 ++ 5 files changed, 85 insertions(+), 36 deletions(-) diff --git a/addons/bus/static/src/js/bus.js b/addons/bus/static/src/js/bus.js index 58ff9c216ea..b36a620afb3 100644 --- a/addons/bus/static/src/js/bus.js +++ b/addons/bus/static/src/js/bus.js @@ -32,8 +32,9 @@ bus.Bus = Widget.extend({ this.trigger('window_focus', this.is_master); } }); - $(window).on("focus", _.bind(this.window_focus, this)); - $(window).on("blur", _.bind(this.window_blur, this)); + $(window).on("focus", _.bind(this.focus_change, this, true)); + $(window).on("blur", _.bind(this.focus_change, this, false)); + $(window).on("unload", _.bind(this.focus_change, this, false)); _.each('click,keydown,keyup'.split(','), function(evtype) { $(window).on(evtype, function() { self.last_presence = new Date().getTime(); @@ -93,11 +94,8 @@ bus.Bus = Widget.extend({ this.channels = _.without(this.channels, channel); }, // bus presence : window focus/unfocus - window_focus: function() { - this.set("window_focus", true); - }, - window_blur: function() { - this.set("window_focus", false); + focus_change: function(focus) { + this.set("window_focus", focus); }, is_odoo_focused: function () { return this.get("window_focus"); @@ -211,6 +209,10 @@ var CrossTabBus = bus.Bus.extend({ if(e.key === 'bus.options'){ this.options = JSON.parse(value); } + // update focus + if(e.key === 'bus.focus'){ + this.set('window_focus', JSON.parse(value)); + } }, add_channel: function(){ this._super.apply(this, arguments); @@ -231,6 +233,10 @@ var CrossTabBus = bus.Bus.extend({ this._super.apply(this, arguments); setItem('bus.options', this.options); }, + focus_change: function(focus) { + this._super.apply(this, arguments); + setItem('bus.focus', focus); + }, }); diff --git a/addons/mail/static/src/js/chat_manager.js b/addons/mail/static/src/js/chat_manager.js index 4f3a039b63d..7796226da10 100644 --- a/addons/mail/static/src/js/chat_manager.js +++ b/addons/mail/static/src/js/chat_manager.js @@ -11,7 +11,7 @@ var web_client = require('web.web_client'); var _t = core._t; var LIMIT = 100; -var preview_msg_max_size = 200; +var preview_msg_max_size = 350; // optimal for native english speakers var MessageModel = new Model('mail.message', session.context); var ChannelModel = new Model('mail.channel', session.context); @@ -44,25 +44,36 @@ var beep = (function () { bus.on("window_focus", null, function() { global_unread_counter = 0; - notify(); + web_client.set_title_part("_chat"); }); -function increment_global_unread_counter () { - if (!bus.is_odoo_focused()) { - global_unread_counter++; - notify(bus.is_master); +function notify_incoming_message (msg, options) { + var title = _t('New message'); + if (msg.author_id[1]) { + title += _t(' from ') + _.escape(msg.author_id[1]); } -} + var content = $(msg.body).text().substr(0, preview_msg_max_size); -function notify (play_sound) { - var title; - if (global_unread_counter > 0) { - title = _.str.sprintf(_t("%d Messages"), global_unread_counter); - if (play_sound) { - beep(); + if (bus.is_odoo_focused()) { + if (!options.is_displayed) { + web_client.do_notify(title, content); + } + } else { + global_unread_counter++; + var tab_title = _.str.sprintf(_t("%d Messages"), global_unread_counter); + web_client.set_title_part("_chat", tab_title); + + if (Notification && Notification.permission === "granted") { + if (bus.is_master) { + new Notification(title, {body: content, icon: "/web/static/src/img/odoo.png", silent: false}); + } + } else { + web_client.do_notify(title, content); + if (bus.is_master) { + beep(); + } } } - web_client.set_title_part("_chat", title); } // Message and channel manipulation helpers @@ -93,22 +104,10 @@ function add_message (data, options) { channel.hidden = false; chat_manager.bus.trigger('new_channel', channel); } - if (is_chat && options.show_notification) { - var query = { is_displayed: false }; + if (is_chat && options.show_notification && (!msg.author_id || msg.author_id[0] !== session.partner_id)) { + var query = {is_displayed: false}; chat_manager.bus.trigger('anyone_listening', channel, query); - if (!query.is_displayed) { - var title = _t('New message'); - if (msg.author_id[1]) { - title += _t(' from ') + _.escape(msg.author_id[1]); - } - var trunc_text = function (t, limit) { - return (t.length > limit) ? t.substr(0, limit-1)+'…' : t; - }; - web_client.do_notify(title, trunc_text(msg.body, preview_msg_max_size)); - } - } - if (is_chat && options.increment_unread && (!msg.author_id || msg.author_id[0] !== session.partner_id)) { - increment_global_unread_counter(); + notify_incoming_message(msg, query); } }); if (!options.silent) { diff --git a/addons/mail/static/src/js/client_action.js b/addons/mail/static/src/js/client_action.js index a369687c8e2..ce505e569c1 100644 --- a/addons/mail/static/src/js/client_action.js +++ b/addons/mail/static/src/js/client_action.js @@ -116,6 +116,14 @@ var ChatAction = Widget.extend(ControlPanelMixin, { chat_manager.undo_mark_as_read(msgs_ids, channel); }); }, + "click .o_mail_annoying_notification_bar .fa-close": function (event) { + this.$(".o_mail_annoying_notification_bar").slideUp(); + }, + "click .o_mail_request_permission": function (event) { + event.preventDefault(); + this.$(".o_mail_annoying_notification_bar").slideUp(); + window.Notification.requestPermission(); + }, }, on_attach_callback: function () { @@ -135,6 +143,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, { this.options = options || {}; this.channels_scrolltop = {}; this.throttled_render_sidebar = _.throttle(this.render_sidebar.bind(this), 100, { leading: false }); + this.notification_bar = (window.Notification.permission === "default"); }, willStart: function () { diff --git a/addons/mail/static/src/less/client_action.less b/addons/mail/static/src/less/client_action.less index f6c42c16b8d..8ab1c9f221c 100644 --- a/addons/mail/static/src/less/client_action.less +++ b/addons/mail/static/src/less/client_action.less @@ -10,6 +10,35 @@ height: auto; } + .o_mail_annoying_notification_bar { + height: 40px; + background-color: #DFA941; + color: white; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.25); + .o-flex-display(); + border-bottom: 1px solid @odoo-main-color-muted; + + .o_mail_request_permission { + .o-flex-display(); + justify-content: center; + .o-flex(1,1, auto); + } + > span { + font-size: 16px; + line-height: 40px; + > a { + color: white; + margin-left: 5px; + text-decoration: underline; + } + + &.fa-close { + margin-right: 10px; + cursor: pointer; + } + } + } + .o_mail_chat_sidebar { width: @mail-chat-sidebar-width; height: 100%; diff --git a/addons/mail/static/src/xml/client_action.xml b/addons/mail/static/src/xml/client_action.xml index 0c254e7cf7f..f2b22d5587a 100644 --- a/addons/mail/static/src/xml/client_action.xml +++ b/addons/mail/static/src/xml/client_action.xml @@ -4,6 +4,12 @@
+ +
+ Odoo needs your permission to enable desktop notifications. + +
+