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 | |
| parent | 0bc2ddae784bf80c4c809d8b7f6d642d576f92a1 (diff) | |
| parent | 4022493c0b85f966e499b6c03ac7cce5556f15e6 (diff) | |
[MERGE] forward port of branch saas-7 up to 4022493
Diffstat (limited to 'addons/mail/static/src')
| -rw-r--r-- | addons/mail/static/src/js/chat_manager.js | 232 | ||||
| -rw-r--r-- | addons/mail/static/src/js/chat_window.js | 13 | ||||
| -rw-r--r-- | addons/mail/static/src/js/chatter.js | 44 | ||||
| -rw-r--r-- | addons/mail/static/src/js/client_action.js | 80 | ||||
| -rw-r--r-- | addons/mail/static/src/js/composer.js | 7 | ||||
| -rw-r--r-- | addons/mail/static/src/js/thread.js | 8 | ||||
| -rw-r--r-- | addons/mail/static/src/js/window_manager.js | 17 | ||||
| -rw-r--r-- | addons/mail/static/src/less/chat_window.less | 2 | ||||
| -rw-r--r-- | addons/mail/static/src/less/chatter.less | 6 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/client_action.xml | 2 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/thread.xml | 6 |
11 files changed, 241 insertions, 176 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 diff --git a/addons/mail/static/src/js/chat_window.js b/addons/mail/static/src/js/chat_window.js index 3936ef956e1..e9fcaa9fe09 100644 --- a/addons/mail/static/src/js/chat_window.js +++ b/addons/mail/static/src/js/chat_window.js @@ -37,9 +37,9 @@ return Widget.extend({ display_needactions: false, display_stars: this.options.display_stars, }); - this.thread.on('toggle_star_status', this, function (message_id) { - this.trigger('toggle_star_status', message_id); - }); + this.thread.on('toggle_star_status', null, this.trigger.bind(this, 'toggle_star_status')); + this.thread.on('redirect_to_channel', null, this.trigger.bind(this, 'redirect_to_channel')); + this.thread.on('redirect', null, this.trigger.bind(this, 'redirect')); this.fold(); var def = this.thread.appendTo(this.$content); @@ -67,8 +67,8 @@ return Widget.extend({ height: this.folded ? "28px" : "333px" }); }, - toggle_fold: function () { - this.folded = !this.folded; + toggle_fold: function (fold) { + this.folded = _.isBoolean(fold) ? fold : !this.folded; if (!this.folded) { this.unread_msgs = 0; this.trigger('messages_read'); @@ -82,10 +82,9 @@ return Widget.extend({ content: this.$input.val(), attachment_ids: [], partner_ids: [], - channel_id: this.channel_id, }; this.$input.val(''); - this.trigger('post_message', message); + this.trigger('post_message', message, this.channel_id); } }, on_click_close: function (event) { diff --git a/addons/mail/static/src/js/chatter.js b/addons/mail/static/src/js/chatter.js index d29312cf6f6..c99e958929e 100644 --- a/addons/mail/static/src/js/chatter.js +++ b/addons/mail/static/src/js/chatter.js @@ -189,14 +189,9 @@ var Followers = form_common.AbstractField.extend({ }, fetch_followers: function (value_) { - var self = this; this.value = value_ || []; return ajax.jsonRpc('/mail/read_followers', 'call', {'follower_ids': this.value}) - .then(function (followers) { - self.trigger('followers_update', followers); - self.display_followers(followers); - self.fetch_generic(); - }) + .then(this.proxy('display_followers'), this.proxy('fetch_generic')) .then(this.proxy('display_buttons')) .then(this.proxy('fetch_subtypes')); }, @@ -237,6 +232,7 @@ var Followers = form_common.AbstractField.extend({ display_followers: function (records) { var self = this; this.followers = records || this.followers; + this.trigger('followers_update', this.followers); // clean and display title var $followers_list = this.$('.o_followers_list').empty(); @@ -272,25 +268,25 @@ var Followers = form_common.AbstractField.extend({ } }, - /** Fetch subtypes, only if current user is follower */ + /** Fetch subtypes, only if current user is follower or if follower_id is given, i.e. if + * the current user is editing the subtypes of another follower + */ fetch_subtypes: function (follower_id) { var self = this; var dialog = false; if (follower_id) { dialog = true; - } - else { + } else { this.$('.o_subtypes_list ul').empty(); - if (! this.message_is_follower) { + if (!this.message_is_follower) { this.$('.o_subtypes_list > .dropdown-toggle').attr('disabled', true); return; - } - else { + } else { this.$('.o_subtypes_list > .dropdown-toggle').attr('disabled', false); } } - if (this.follower_id) { + if (this.follower_id || follower_id) { return ajax.jsonRpc('/mail/read_subscription_data', 'call', { res_model: this.view.model, res_id: this.view.datarecord.id, @@ -305,7 +301,6 @@ var Followers = form_common.AbstractField.extend({ /** Display subtypes: {'name': default, followed} */ display_subtypes:function (data, dialog) { - var self = this; var old_parent_model; var $list; if (dialog) { @@ -316,10 +311,10 @@ var Followers = form_common.AbstractField.extend({ $list.empty(); this.data_subtype = data; - this.records_length = $.map(data, function(value, index) { return index; }).length; + this.records_length = _.map(data, function(value, index) { return index; }).length; if (this.records_length > 1) { - self.display_followers(); + this.display_followers(); } _.each(data, function (record) { @@ -674,6 +669,8 @@ var ChatterComposer = ChatComposer.extend({ }, { on_close: function() { self.trigger('need_refresh'); + var parent = self.getParent(); + chat_manager.get_messages({model: parent.model, res_id: parent.res_id}); }, }); }); @@ -719,6 +716,7 @@ var Chatter = form_common.AbstractField.extend({ display_order: ChatThread.ORDER.DESC, display_document_link: false, display_needactions: false, + squash_close_messages: false, }); this.thread.on('load_more_messages', this, this.load_more_messages); this.thread.on('toggle_star_status', this, function (message_id) { @@ -741,15 +739,18 @@ var Chatter = form_common.AbstractField.extend({ fetch_and_render_thread: function (ids, options) { var self = this; - return chat_manager.fetch_messages(ids, options).then(function (raw_messages) { + options = options || {}; + options.ids = ids; + return chat_manager.get_messages(options).then(function (raw_messages) { self.thread.render(raw_messages, {display_load_more: raw_messages.length < ids.length}); }); }, on_post_message: function (message) { var self = this; + var options = {model: this.model, res_id: this.res_id}; chat_manager - .post_message_in_document(this.model, this.res_id, message) + .post_message(message, options) .then(function () { self.close_composer(); if (message.partner_ids.length) { @@ -781,12 +782,7 @@ var Chatter = form_common.AbstractField.extend({ on_channel_redirect: function (channel_id) { var self = this; - var def; - var channel = chat_manager.get_channel(channel_id); - // If not registered to 'channel' yet, do it - if (!channel) { - def = chat_manager.join_channel(channel_id); - } + var def = chat_manager.join_channel(channel_id); $.when(def).then(function () { // Execute Discuss client action with 'channel' as default channel var discuss_ids = chat_manager.get_discuss_ids(); diff --git a/addons/mail/static/src/js/client_action.js b/addons/mail/static/src/js/client_action.js index b96e9af6777..ae032b4ece1 100644 --- a/addons/mail/static/src/js/client_action.js +++ b/addons/mail/static/src/js/client_action.js @@ -190,14 +190,11 @@ var ChatAction = Widget.extend(ControlPanelMixin, { }); this.$buttons.on('click', '.o_mail_chat_button_unstar_all', chat_manager.unstar_all); - this.thread.on('redirect', this, this.on_redirect); + this.thread.on('redirect', this, function (res_model, res_id) { + chat_manager.redirect(res_model, res_id, this.set_channel.bind(this)); + }); this.thread.on('redirect_to_channel', this, function (channel_id) { - var channel = chat_manager.get_channel(channel_id); - if (channel) { - this.set_channel(channel); - } else { - chat_manager.join_channel(channel_id); - } + chat_manager.join_channel(channel_id).then(this.set_channel.bind(this)); }); this.thread.on('load_more_messages', this, this.load_more_messages); this.thread.on('mark_as_read', this, function (message_id) { @@ -375,7 +372,6 @@ var ChatAction = Widget.extend(ControlPanelMixin, { self.$buttons .find('.o_mail_chat_button_unstar_all') .toggle(channel.id === "channel_starred"); - self.update_cp(); self.$('.o_chat_composer').toggle(channel.type !== 'static'); @@ -393,6 +389,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, { self.$('.o_mail_chat_sidebar').hide(); } + self.update_cp(); self.action_manager.do_push_state({ action: self.action.id, active_id: self.channel.id, @@ -466,7 +463,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, { var oldest_msg_selector = '.o_thread_message[data-message-id="' + oldest_msg_id + '"]'; var offset = -framework.getPosition(document.querySelector(oldest_msg_selector)).top; return chat_manager - .fetch_more(this.channel, this.domain) + .get_messages({channel_id: this.channel.id, domain: this.domain, load_more: true}) .then(function(result) { if (self.messages_separator_position === 'top') { self.messages_separator_position = undefined; // reset value to re-compute separator position @@ -489,6 +486,15 @@ var ChatAction = Widget.extend(ControlPanelMixin, { }); }, + do_show: function () { + this._super.apply(this, arguments); + this.update_cp(); + this.action_manager.do_push_state({ + action: this.action.id, + active_id: this.channel.id, + }); + }, + on_search: function (domains) { var result = pyeval.sync_eval_domains_and_contexts({ domains: domains @@ -498,60 +504,10 @@ var ChatAction = Widget.extend(ControlPanelMixin, { this.fetch_and_render_thread(); }, - /** - * Callback performed on o_mail_redirect element clicked - * - * 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. - */ - on_redirect: function (res_model, res_id) { - var self = this; - var redirect_to_document = function (res_model, res_id) { - self.action_manager.do_push_state({ - model: res_model, - id: res_id, - }); - self.do_action({ - type:'ir.actions.act_window', - view_type: 'form', - view_mode: 'form', - res_model: res_model, - views: [[false, 'form']], - res_id: res_id, - }, { - on_reverse_breadcrumb: self.on_reverse_breadcrumb, - }); - }; - - if (res_model === "res.partner") { - var domain = [["partner_id", "=", res_id]]; - new Model('res.users').call("search", [domain]).then(function (user_ids) { - if (user_ids.length && user_ids[0] !== session.uid) { - chat_manager.create_channel(res_id, 'dm').then(function (channel) { - if (!self.channel || self.channel.id !== channel.id) { - self.set_channel(channel); - } - }); - } else { - redirect_to_document(res_model, res_id); - } - }); - } else { - redirect_to_document(res_model, res_id); - } - }, - on_reverse_breadcrumb: function () { - this.update_cp(); // do not reload the client action, just display it, but a refresh of the control panel is needed. - this.action_manager.do_push_state({ - action: this.action.id, - active_id: this.channel.id, - }); - }, on_post_message: function (message) { - message.channel_id = this.channel.id; + var options = {channel_id: this.channel.id}; chat_manager - .post_message(message) + .post_message(message, options) .fail(function () { // todo: display notification }); @@ -615,8 +571,6 @@ var ChatAction = Widget.extend(ControlPanelMixin, { res_id: this.channel.id, views: [[false, 'form']], target: 'current' - }, { - on_reverse_breadcrumb: this.on_reverse_breadcrumb, }); }, }); diff --git a/addons/mail/static/src/js/composer.js b/addons/mail/static/src/js/composer.js index 24257d1a72a..971c2e99c69 100644 --- a/addons/mail/static/src/js/composer.js +++ b/addons/mail/static/src/js/composer.js @@ -23,6 +23,7 @@ var accented_letters_mapping = { 'oe': 'œ', 'u': '[ùúûűü]', 'y': '[ýÿ]', + ' ': '[()\\[\\]]', }; // The MentionManager allows the Composer to register listeners. For each @@ -218,7 +219,8 @@ var MentionManager = Widget.extend({ */ generate_links: function (s) { var self = this; - var mention_link = "<a href='#' class='%s' data-oe-id='%s' data-oe-model='%s'>%s%s</a>"; + var base_href = session.url("/web"); + var mention_link = "<a href='%s' class='%s' data-oe-id='%s' data-oe-model='%s' target='_blank'>%s%s</a>"; _.each(this.listeners, function (listener) { var selection = listener.selection; if (selection.length) { @@ -229,7 +231,8 @@ var MentionManager = Widget.extend({ var match = matches[i]; var end_index = match.index + match[0].length; var match_name = match[0].substring(1); - var processed_text = _.str.sprintf(mention_link, listener.redirect_classname, selection[i].id, listener.model, listener.delimiter, match_name); + var href = base_href + _.str.sprintf("#model=%s&id=%s", listener.model, selection[i].id); + var processed_text = _.str.sprintf(mention_link, href, listener.redirect_classname, selection[i].id, listener.model, listener.delimiter, match_name); var subtext = s.substring(start_index, end_index).replace(match[0], processed_text); substrings.push(subtext); start_index = end_index; diff --git a/addons/mail/static/src/js/thread.js b/addons/mail/static/src/js/thread.js index a1f8fc8a076..86b34255cf7 100644 --- a/addons/mail/static/src/js/thread.js +++ b/addons/mail/static/src/js/thread.js @@ -34,8 +34,9 @@ var Thread = Widget.extend({ this.$('.o_thread_message').removeClass('o_thread_selected_message'); $(event.currentTarget).toggleClass('o_thread_selected_message', !selected); }, - "click span.oe_mail_expand": function (event) { + "click .oe_mail_expand": function (event) { event.preventDefault(); + event.stopPropagation(); var $source = $(event.currentTarget); $source.parents('.o_thread_message_core').find('.o_mail_body_short').toggle(); $source.parents('.o_thread_message_core').find('.o_mail_body_long').toggle(); @@ -118,12 +119,13 @@ var Thread = Widget.extend({ msg.hour = msg.date.fromNow(); } else if (date === moment().subtract(1, 'days').format('YYYY-MM-DD')) { msg.day = _t("Yesterday"); - msg.hour = msg.date.format('hh:mm'); + msg.hour = msg.date.format('LT'); } else { msg.day = msg.date.format('LL'); - msg.hour = msg.date.format('hh:mm'); + msg.hour = msg.date.format('LT'); } + msg.display_subject = message.subject && message.message_type !== 'notification' && !(message.model && (message.model !== 'mail.channel')); return msg; }, diff --git a/addons/mail/static/src/js/window_manager.js b/addons/mail/static/src/js/window_manager.js index 22eb60f9180..5a62c15ed8b 100644 --- a/addons/mail/static/src/js/window_manager.js +++ b/addons/mail/static/src/js/window_manager.js @@ -37,12 +37,25 @@ function open_chat (session) { chat_manager.fold_channel(channel_id); }); - chat_session.window.on("post_message", null, function (message) { - chat_manager.post_message(message); + chat_session.window.on("post_message", null, function (message, channel_id) { + chat_manager.post_message(message, {channel_id: channel_id}); }); chat_session.window.on("messages_read", null, function () { chat_manager.mark_channel_as_seen(channel); }); + chat_session.window.on("redirect", null, function (res_model, res_id) { + chat_manager.redirect(res_model, res_id, open_chat); + }); + chat_session.window.on("redirect_to_channel", null, function (channel_id) { + var session = _.findWhere(chat_sessions, {id: channel_id}); + if (!session) { + chat_manager.join_channel(channel_id).then(function (channel) { + chat_manager.detach_channel(channel); + }); + } else { + session.window.toggle_fold(false); + } + }); chat_sessions.push(chat_session); chat_session.window.appendTo($('body')) diff --git a/addons/mail/static/src/less/chat_window.less b/addons/mail/static/src/less/chat_window.less index 0172e916ab3..b911ef467ed 100644 --- a/addons/mail/static/src/less/chat_window.less +++ b/addons/mail/static/src/less/chat_window.less @@ -37,6 +37,8 @@ padding: 5px; .o_mail_thread .o_thread_date_separator { + margin-top: 0px; + margin-bottom: 15px; border-color: lightgray; .o_thread_date { background-color: @o-chat-window-bg; diff --git a/addons/mail/static/src/less/chatter.less b/addons/mail/static/src/less/chatter.less index b0eda543c85..35d5b3b7a76 100644 --- a/addons/mail/static/src/less/chatter.less +++ b/addons/mail/static/src/less/chatter.less @@ -128,3 +128,9 @@ .modal .modal-body > li.o_subtype { list-style: none; } + +@media print { + .oe_chatter { + display: none; + } +} diff --git a/addons/mail/static/src/xml/client_action.xml b/addons/mail/static/src/xml/client_action.xml index e3f6e1149e8..1a7c22a1496 100644 --- a/addons/mail/static/src/xml/client_action.xml +++ b/addons/mail/static/src/xml/client_action.xml @@ -83,7 +83,7 @@ <i t-if="channel.mass_mailing" class="fa fa-envelope-o"/> <t t-call="mail.chat.SidebarNeedaction"/> <span t-attf-class="fa fa-times pull-right o_mail_partner_unpin #{counter ? 'hide' : ''}" - t-att-title="_t('Close')" t-att-data-channel-id="channel.id"/> + t-att-title="_t('Leave this channel')" t-att-data-channel-id="channel.id"/> </div> </t> <div t-if="!disable_add_channel" class="o_mail_add_channel" t-attf-data-type="#{channel_type}"> diff --git a/addons/mail/static/src/xml/thread.xml b/addons/mail/static/src/xml/thread.xml index ebf6687c1a3..f1a364999b5 100644 --- a/addons/mail/static/src/xml/thread.xml +++ b/addons/mail/static/src/xml/thread.xml @@ -53,7 +53,7 @@ t-att-src="message.avatar_src" data-oe-model="res.partner" t-att-data-oe-id="message.author_id[0]" - class="o_thread_message_avatar o_mail_redirect"/> + t-attf-class="o_thread_message_avatar #{message.author_redirect ? 'o_mail_redirect' : ''}"/> </t> <t t-if="message.mailto || !message.author_id[0]"> <img t-if="message.avatar_src && message.display_author" @@ -80,7 +80,7 @@ </strong> <strong t-if="!message.mailto && message.author_id[0]" data-oe-model="res.partner" t-att-data-oe-id="message.author_id[0]" - class="o_mail_redirect"> + t-attf-class="#{message.author_redirect ? 'o_mail_redirect' : ''}"> <t t-esc="message.displayed_author"/> </strong> <strong t-if="!message.mailto && !message.author_id[0]"> @@ -111,7 +111,7 @@ </t> <t t-call="mail.ChatThread.MessageTracking"/> </t> - <p t-if="options.display_subject && message.subject && message.message_type != 'notification'" class="o_mail_subject">Subject: <t t-esc="message.subject"/></p> + <p t-if="options.display_subject && message.display_subject" class="o_mail_subject">Subject: <t t-esc="message.subject"/></p> <t t-if="!(message.tracking_value_ids && message.tracking_value_ids.length > 0)"> <t t-if="message.body_short"> <div class="o_mail_body_short"> |
