diff options
| author | Christophe Simonis <chs@odoo.com> | 2015-12-10 13:05:58 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2015-12-10 13:05:58 +0100 |
| commit | 82a495eed52a9f42e5b88caa52c20a85f8d81ce3 (patch) | |
| tree | 6c5e8cc0247d5fe08d24e9abae38fe353fbebc56 /addons/mail/static/src/js/chat_manager.js | |
| parent | 0bc2ddae784bf80c4c809d8b7f6d642d576f92a1 (diff) | |
| parent | 4022493c0b85f966e499b6c03ac7cce5556f15e6 (diff) | |
[MERGE] forward port of branch saas-7 up to 4022493
Diffstat (limited to 'addons/mail/static/src/js/chat_manager.js')
| -rw-r--r-- | addons/mail/static/src/js/chat_manager.js | 232 |
1 files changed, 161 insertions, 71 deletions
diff --git a/addons/mail/static/src/js/chat_manager.js b/addons/mail/static/src/js/chat_manager.js index e8a2ad3951e..2261b961410 100644 --- a/addons/mail/static/src/js/chat_manager.js +++ b/addons/mail/static/src/js/chat_manager.js @@ -15,6 +15,7 @@ var preview_msg_max_size = 50; var MessageModel = new Model('mail.message', session.context); var ChannelModel = new Model('mail.channel', session.context); +var UserModel = new Model('res.users', session.context); // Private model //---------------------------------------------------------------------------------- @@ -26,6 +27,42 @@ var emoji_substitutions = {}; var needaction_counter = 0; var mention_partner_suggestions = []; var discuss_ids = {}; +var global_unread_counter = 0; + +// Window focus/unfocus, beep and title +//---------------------------------------------------------------------------------- +var beep = (function () { + if (typeof(Audio) === "undefined") { + return function () {}; + } + var audio = new Audio(); + var ext = audio.canPlayType("audio/ogg; codecs=vorbis") ? ".ogg" : ".mp3"; + audio.src = session.url("/mail/static/src/audio/ting" + ext); + return function () { audio.play(); }; +})(); + +bus.on("window_focus", null, function() { + global_unread_counter = 0; + notify(); +}); + +function increment_global_unread_counter () { + if (!bus.is_odoo_focused()) { + global_unread_counter++; + notify(bus.is_master); + } +} + +function notify (play_sound) { + var title; + if (global_unread_counter > 0) { + title = _.str.sprintf(_t("%d Messages"), global_unread_counter); + if (play_sound) { + beep(); + } + } + web_client.set_title_part("_chat", title); +} // Message and channel manipulation helpers //---------------------------------------------------------------------------------- @@ -41,18 +78,21 @@ function add_message (data, options) { messages.splice(_.sortedIndex(messages, msg, 'id'), 0, msg); _.each(msg.channel_ids, function (channel_id) { var channel = chat_manager.get_channel(channel_id); - + var is_chat = channel && !_.contains(["public", "private"], channel.type); if (channel) { add_to_cache(msg, []); if (options.domain && options.domain !== []) { add_to_cache(msg, options.domain); } + if (options.increment_unread) { + update_channel_unread_counter(channel, channel.unread_counter+1); + } } if (channel && channel.hidden) { channel.hidden = false; chat_manager.bus.trigger('new_channel', channel); } - if (channel && !_.contains(["public", "private"], channel.type) && (options.show_notification)) { + if (is_chat && options.show_notification) { var query = { is_displayed: false }; chat_manager.bus.trigger('anyone_listening', channel, query); if (!query.is_displayed) { @@ -66,6 +106,9 @@ function add_message (data, options) { 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(); + } }); if (!options.silent) { chat_manager.bus.trigger('new_message', msg); @@ -147,6 +190,13 @@ function make_message (data) { msg.email_from || _t('Anonymous'); } + // Don't redirect on author clicked of self-posted messages + if (msg.author_id && msg.author_id[0] === session.partner_id) { + msg.author_redirect = false; + } else { + msg.author_redirect = true; + } + // Compute the avatar_url if (msg.author_id && msg.author_id[0]) { msg.avatar_src = "/web/image/res.partner/" + msg.author_id[0] + "/image_small"; @@ -169,39 +219,6 @@ function add_channel_to_message (message, channel_id) { message.channel_ids = _.uniq(message.channel_ids); } -function post_channel_message (data) { - return ChannelModel.call('message_post', [data.channel_id], { - message_type: 'comment', - content_subtype: 'html', - partner_ids: data.partner_ids, - body: _.str.trim(data.content), - subtype: 'mail.mt_comment', - attachment_ids: data.attachment_ids, - }); -} - -function post_document_message (model_name, res_id, data) { - var values = { - attachment_ids: data.attachment_ids, - body: _.str.trim(data.content), - content_subtype: data.content_subtype, - context: data.context, - message_type: data.message_type, - partner_ids: data.partner_ids, - subtype: data.subtype, - subtype_id: data.subtype_id, - }; - - var model = new Model(model_name); - return model.call('message_post', [res_id], values).then(function (msg_id) { - return MessageModel.call('message_format', [msg_id]).then(function (msgs) { - msgs[0].model = model_name; - msgs[0].res_id = res_id; - add_message(msgs[0]); - }); - }); -} - function add_channel (data, options) { options = typeof options === "object" ? options : {}; var channel = chat_manager.get_channel(data.id); @@ -399,19 +416,13 @@ function on_needaction_notification (message) { function on_channel_notification (message) { var def; - if ((message.channel_ids.length === 1) && !chat_manager.get_channel(message.channel_ids[0])) { + if (message.channel_ids.length === 1) { def = chat_manager.join_channel(message.channel_ids[0], {autoswitch: false}); } else { def = $.when(); } def.then(function () { - _.each(message.channel_ids, function (channel_id) { - var channel = chat_manager.get_channel(channel_id); - if (channel) { - update_channel_unread_counter(channel, channel.unread_counter+1); - } - }); - add_message(message, { show_notification: true }); + add_message(message, { show_notification: true, increment_unread: true }); invalidate_caches(message.channel_ids); }); } @@ -508,35 +519,75 @@ function on_chat_session_notification (chat_session) { // Public interface //---------------------------------------------------------------------------------- var chat_manager = { - post_message: post_channel_message, - post_message_in_document: post_document_message, + post_message: function (data, options) { + options = options || {}; + var msg = { + partner_ids: data.partner_ids, + body: _.str.trim(data.content), + attachment_ids: data.attachment_ids, + }; + if ('channel_id' in options) { + // post a message in a channel + return ChannelModel.call('message_post', [options.channel_id], _.extend(msg, { + message_type: 'comment', + content_subtype: 'html', + subtype: 'mail.mt_comment', + })); + } + if ('model' in options && 'res_id' in options) { + // post a message in a chatter + _.extend(msg, { + content_subtype: data.content_subtype, + context: data.context, + message_type: data.message_type, + subtype: data.subtype, + subtype_id: data.subtype_id, + }); + + var model = new Model(options.model); + return model.call('message_post', [options.res_id], msg).then(function (msg_id) { + return MessageModel.call('message_format', [msg_id]).then(function (msgs) { + msgs[0].model = options.model; + msgs[0].res_id = options.res_id; + add_message(msgs[0]); + }); + }); + } + }, get_messages: function (options) { - if ('channel_id' in options) { // channel message - var channel = this.get_channel(options.channel_id); + var channel; + + if ('channel_id' in options && options.load_more) { + // get channel messages, force load_more + channel = this.get_channel(options.channel_id); + return fetch_from_channel(channel, {domain: options.domain || {}, load_more: true}); + } + if ('channel_id' in options) { + // channel message, check in cache first + channel = this.get_channel(options.channel_id); var channel_cache = get_channel_cache(channel, options.domain); if (channel_cache.loaded) { return $.when(channel_cache.messages); } else { return fetch_from_channel(channel, {domain: options.domain}); } - } else { // chatter message } - }, - fetch: function (channel, domain) { - return fetch_from_channel(channel, {domain: domain}); - }, - fetch_more: function (channel, domain) { - return fetch_from_channel(channel, {domain: domain, load_more: true}); - }, - /** - * Fetches chatter messages from their ids - */ - fetch_messages: function (message_ids, options) { - return fetch_document_messages(message_ids, options).then(function(result) { - chat_manager.mark_as_read(message_ids); - return result; - }); + if ('ids' in options) { + // get messages from their ids (chatter is the main use case) + return fetch_document_messages(options.ids, options).then(function(result) { + chat_manager.mark_as_read(options.ids); + return result; + }); + } + if ('model' in options && 'res_id' in options) { + // get messages for a chatter, when it doesn't know the ids (use + // case is when using the full composer) + var domain = [['model', '=', options.model], ['res_id', '=', options.res_id]]; + MessageModel.call('message_fetch', [domain], {limit: 30}).then(function (msgs) { + return _.map(msgs, add_message); + }); + } }, toggle_star_status: function (message_id) { var msg = _.findWhere(messages, { id: message_id }); @@ -549,7 +600,8 @@ var chat_manager = { mark_as_read: function (message_ids) { var ids = _.filter(message_ids, function (id) { var message = _.findWhere(messages, {id: id}); - return message.is_needaction; + // If too many messages, not all are fetched, and some might not be found + return !message || message.is_needaction; }); if (ids.length) { return MessageModel.call('set_message_done', [ids]); @@ -638,15 +690,21 @@ var chat_manager = { }, join_channel: function (channel_id, options) { if (channel_id in channel_defs) { + // prevents concurrent calls to channel_join_and_get_info return channel_defs[channel_id]; } - var def = ChannelModel - .call('channel_join_and_get_info', [[channel_id]]) - .then(function (result) { - add_channel(result, options); - }); - channel_defs[channel_id] = def; - return def; + var channel = this.get_channel(channel_id); + if (channel) { + // channel already joined + channel_defs[channel_id] = $.when(channel); + } else { + channel_defs[channel_id] = ChannelModel + .call('channel_join_and_get_info', [[channel_id]]) + .then(function (result) { + return add_channel(result, options); + }); + } + return channel_defs[channel_id]; }, unsubscribe: function (channel) { @@ -671,6 +729,38 @@ var chat_manager = { channel.is_folded = !channel.is_folded; }); }, + /** + * Special redirection handling for given model and id + * + * If the model is res.partner, and there is a user associated with this + * partner which isn't the current user, open the DM with this user. + * Otherwhise, open the record's form view, if this is not the current user's. + */ + redirect: function (res_model, res_id, dm_redirection_callback) { + var self = this; + var redirect_to_document = function (res_model, res_id) { + web_client.do_action({ + type:'ir.actions.act_window', + view_type: 'form', + view_mode: 'form', + res_model: res_model, + views: [[false, 'form']], + res_id: res_id, + }); + }; + if (res_model === "res.partner") { + var domain = [["partner_id", "=", res_id]]; + UserModel.call("search", [domain]).then(function (user_ids) { + if (user_ids.length && user_ids[0] !== session.uid) { + self.create_channel(res_id, 'dm').then(dm_redirection_callback || function () {}); + } else if (!user_ids.length) { + redirect_to_document(res_model, res_id); + } + }); + } else { + redirect_to_document(res_model, res_id); + } + }, }; // Initialization |
