summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/js/chat_manager.js
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2015-12-10 13:05:58 +0100
committerChristophe Simonis <chs@odoo.com>2015-12-10 13:05:58 +0100
commit82a495eed52a9f42e5b88caa52c20a85f8d81ce3 (patch)
tree6c5e8cc0247d5fe08d24e9abae38fe353fbebc56 /addons/mail/static/src/js/chat_manager.js
parent0bc2ddae784bf80c4c809d8b7f6d642d576f92a1 (diff)
parent4022493c0b85f966e499b6c03ac7cce5556f15e6 (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.js232
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