summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/js
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2016-02-02 14:52:15 +0100
committerChristophe Simonis <chs@odoo.com>2016-02-02 14:52:15 +0100
commit469e04e97c2aa60d9d41bd430e0aeba77ee6f9dd (patch)
tree0119f59009274d2c569920432c9a7fabafde0974 /addons/mail/static/src/js
parent78d20b552b4374b94aec7097c0e6a48a3dd2d961 (diff)
parent2611a8198eaac60cf424742e4dc411700e439352 (diff)
[MERGE] forward port of branch saas-8 up to 2611a81
Diffstat (limited to 'addons/mail/static/src/js')
-rw-r--r--addons/mail/static/src/js/chat_manager.js23
-rw-r--r--addons/mail/static/src/js/chat_window.js7
-rw-r--r--addons/mail/static/src/js/chatter.js23
-rw-r--r--addons/mail/static/src/js/client_action.js4
-rw-r--r--addons/mail/static/src/js/composer.js29
-rw-r--r--addons/mail/static/src/js/systray.js61
-rw-r--r--addons/mail/static/src/js/thread.js23
-rw-r--r--addons/mail/static/src/js/window_manager.js3
8 files changed, 126 insertions, 47 deletions
diff --git a/addons/mail/static/src/js/chat_manager.js b/addons/mail/static/src/js/chat_manager.js
index 6fd85e33719..2db02429d7a 100644
--- a/addons/mail/static/src/js/chat_manager.js
+++ b/addons/mail/static/src/js/chat_manager.js
@@ -25,6 +25,7 @@ var channels = [];
var channels_preview_def;
var channel_defs = {};
var chat_unread_counter = 0;
+var unread_conversation_counter = 0;
var emojis = [];
var emoji_substitutions = {};
var needaction_counter = 0;
@@ -146,7 +147,7 @@ function add_message (data, options) {
channel.hidden = false;
chat_manager.bus.trigger('new_channel', channel);
}
- if (!msg.author_id || msg.author_id[0] !== session.partner_id) {
+ if (channel.type !== 'static' && !msg.is_author && !msg.is_system_notification) {
if (options.increment_unread) {
update_channel_unread_counter(channel, channel.unread_counter+1);
}
@@ -176,7 +177,9 @@ function make_message (data) {
date: moment(time.str_to_datetime(data.date)),
message_type: data.message_type,
subtype_description: data.subtype_description,
+ is_author: data.author_id && data.author_id[0] === session.partner_id,
is_note: data.is_note,
+ is_system_notification: data.message_type === 'notification' && data.model === 'mail.channel',
attachment_ids: data.attachment_ids,
subject: data.subject,
email_from: data.email_from,
@@ -240,11 +243,7 @@ function make_message (data) {
}
// 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;
- }
+ msg.author_redirect = !msg.is_author;
// Compute the avatar_url
if (msg.author_id && msg.author_id[0]) {
@@ -449,8 +448,13 @@ function fetch_document_messages (ids, options) {
}
function update_channel_unread_counter (channel, counter) {
+ if (channel.unread_counter > 0 && counter === 0) {
+ unread_conversation_counter = Math.max(0, unread_conversation_counter-1);
+ } else if (channel.unread_counter === 0 && counter > 0) {
+ unread_conversation_counter++;
+ }
if (channel.is_chat) {
- chat_unread_counter = chat_unread_counter - channel.unread_counter + counter;
+ chat_unread_counter = Math.max(0, chat_unread_counter - channel.unread_counter + counter);
}
channel.unread_counter = counter;
chat_manager.bus.trigger("update_channel_unread_counter", channel);
@@ -807,6 +811,9 @@ var chat_manager = {
get_chat_unread_counter: function () {
return chat_unread_counter;
},
+ get_unread_conversation_counter: function () {
+ return unread_conversation_counter;
+ },
get_last_seen_message: function (channel) {
if (channel.last_seen_message_id) {
@@ -814,7 +821,7 @@ var chat_manager = {
var msg = _.findWhere(messages, {id: channel.last_seen_message_id});
if (msg) {
var i = _.sortedIndex(messages, msg, 'id') + 1;
- while (i < messages.length && messages[i].author_id && messages[i].author_id[0] === session.partner_id) {
+ while (i < messages.length && (messages[i].is_author || messages[i].is_system_notification)) {
msg = messages[i];
i++;
}
diff --git a/addons/mail/static/src/js/chat_window.js b/addons/mail/static/src/js/chat_window.js
index 95ac9dd8897..0e0289c394e 100644
--- a/addons/mail/static/src/js/chat_window.js
+++ b/addons/mail/static/src/js/chat_window.js
@@ -15,7 +15,9 @@ var HEIGHT_FOLDED = '28px';
return Widget.extend({
template: "mail.ChatWindow",
events: {
+ "click .o_chat_input": "focus_input", // focus even if jquery's blockUI is enabled
"keydown .o_chat_input": "on_keydown",
+ "keypress .o_chat_input": "on_keypress",
"click .o_chat_window_close": "on_click_close",
"click .o_chat_title": "on_click_fold",
},
@@ -28,6 +30,7 @@ return Widget.extend({
this.options = _.defaults(options || {}, {
display_stars: true,
placeholder: _t("Say something"),
+ input_less: false,
});
this.unread_msgs = unread_msgs || 0;
this.is_hidden = false;
@@ -90,7 +93,11 @@ return Widget.extend({
this.is_hidden = _.isBoolean(display) ? !display : !this.is_hidden;
this._super.apply(this, arguments);
},
+ on_keypress: function (event) {
+ event.stopPropagation(); // to prevent jquery's blockUI to cancel event
+ },
on_keydown: function (event) {
+ event.stopPropagation(); // to prevent jquery's blockUI to cancel event
// ENTER key (avoid requiring jquery ui for external livechat)
if (event.which === 13) {
var content = _.str.trim(this.$input.val());
diff --git a/addons/mail/static/src/js/chatter.js b/addons/mail/static/src/js/chatter.js
index dc528b2b1aa..fb39b595415 100644
--- a/addons/mail/static/src/js/chatter.js
+++ b/addons/mail/static/src/js/chatter.js
@@ -451,7 +451,6 @@ var ChatterComposer = composer.BasicComposer.extend({
record_name: false,
is_log: false,
internal_subtypes: [],
- default_body: '',
});
if (this.options.is_log) {
this.options.send_text = _('Log');
@@ -468,13 +467,6 @@ var ChatterComposer = composer.BasicComposer.extend({
return $.when(this._super.apply(this, arguments), this.message_get_suggested_recipients());
},
- start: function () {
- var self = this;
- return this._super().then(function () {
- self.$input.val(self.options.default_body);
- });
- },
-
should_send: function () {
return false;
},
@@ -726,6 +718,16 @@ var Chatter = form_common.AbstractField.extend({
start: function () {
var self = this;
+ // Hide the chatter in 'create' mode
+ this.view.on("change:actual_mode", this, this.check_visibility);
+ this.check_visibility();
+ var $container = this.$el.parent();
+ if ($container.hasClass('oe_chatter')) {
+ this.$el
+ .addClass($container.attr("class"))
+ .unwrap();
+ }
+
// Move the follower's widget (if any) inside the chatter
this.followers = this.field_manager.fields.message_follower_ids;
if (this.followers) {
@@ -759,6 +761,10 @@ var Chatter = form_common.AbstractField.extend({
});
},
+ check_visibility: function () {
+ this.set({"force_invisible": this.view.get("actual_mode") === "create"});
+ },
+
fetch_and_render_thread: function (ids, options) {
var self = this;
options = options || {};
@@ -906,6 +912,7 @@ var Chatter = form_common.AbstractField.extend({
is_log: options && options.is_log,
record_name: this.record_name,
default_body: old_composer && old_composer.$input.val(),
+ default_mention_selections: old_composer && old_composer.mention_get_listener_selections(),
});
this.composer.on('input_focused', this, function () {
this.composer.mention_set_prefetched_partners(this.mention_suggestions || []);
diff --git a/addons/mail/static/src/js/client_action.js b/addons/mail/static/src/js/client_action.js
index d6a5b5ac128..174092887ee 100644
--- a/addons/mail/static/src/js/client_action.js
+++ b/addons/mail/static/src/js/client_action.js
@@ -371,7 +371,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
// Hide 'detach' button in static channels
self.$buttons
.find('.o_mail_chat_button_detach')
- .toggle(channel.type !== "static" && !channel.mass_mailing);
+ .toggle(channel.type !== "static");
// Hide 'invite', 'unsubscribe' and 'settings' buttons in static channels and DM
self.$buttons
.find('.o_mail_chat_button_invite, .o_mail_chat_button_unsubscribe, .o_mail_chat_button_settings')
@@ -446,7 +446,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
display_load_more: !chat_manager.all_history_loaded(this.channel, this.domain),
display_needactions: this.channel.display_needactions,
messages_separator_position: this.messages_separator_position,
- squash_close_messages: this.channel.type !== 'static',
+ squash_close_messages: this.channel.type !== 'static' && !this.channel.mass_mailing,
display_empty_channel: !messages.length && !this.domain.length,
display_no_match: !messages.length && this.domain.length,
display_subject: this.channel.mass_mailing || this.channel.id === "channel_inbox",
diff --git a/addons/mail/static/src/js/composer.js b/addons/mail/static/src/js/composer.js
index 5d6de2bad50..92bac153267 100644
--- a/addons/mail/static/src/js/composer.js
+++ b/addons/mail/static/src/js/composer.js
@@ -27,6 +27,9 @@ var accented_letters_mapping = {
' ': '[()\\[\\]]',
};
+var MENTION_PARTNER_DELIMITER = '@';
+var MENTION_CHANNEL_DELIMITER = '#';
+
// The MentionManager allows the Composer to register listeners. For each
// listener, it detects if the user is currently typing a mention (starting by a
// given delimiter). If so, if fetches mention suggestions and renders them. On
@@ -106,7 +109,7 @@ var MentionManager = Widget.extend({
* @param {string} [redirect_classname] the classname of the <a> wrapping the mention
*/
register: function (listener) {
- this.listeners.push(_.extend(listener, {
+ this.listeners.push(_.defaults(listener, {
selection: [],
}));
},
@@ -123,6 +126,14 @@ var MentionManager = Widget.extend({
return listener ? listener.selection : [];
},
+ get_listener_selections: function () {
+ var selections = {};
+ _.each(this.listeners, function (listener) {
+ selections[listener.delimiter] = listener.selection;
+ });
+ return selections;
+ },
+
proposition_navigation: function (keycode) {
var $active = this.$('.o_mention_proposition.active');
if (keycode === $.ui.keyCode.ENTER) { // selecting proposition
@@ -333,6 +344,8 @@ var BasicComposer = Widget.extend({
mention_fetch_limit: 8,
mention_partners_restricted: false, // set to true to only suggest prefetched partners
send_text: _('Send'),
+ default_body: '',
+ default_mention_selections: {},
});
this.context = this.options.context;
@@ -344,16 +357,18 @@ var BasicComposer = Widget.extend({
// Mention
this.mention_manager = new MentionManager(this);
this.mention_manager.register({
- delimiter: '@',
+ delimiter: MENTION_PARTNER_DELIMITER,
fetch_callback: this.mention_fetch_partners.bind(this),
model: 'res.partner',
redirect_classname: 'o_mail_redirect',
+ selection: this.options.default_mention_selections[MENTION_PARTNER_DELIMITER],
});
this.mention_manager.register({
- delimiter: '#',
+ delimiter: MENTION_CHANNEL_DELIMITER,
fetch_callback: this.mention_fetch_channels.bind(this),
model: 'mail.channel',
redirect_classname: 'o_channel_redirect',
+ selection: this.options.default_mention_selections[MENTION_CHANNEL_DELIMITER],
});
// Emojis
@@ -372,6 +387,7 @@ var BasicComposer = Widget.extend({
this.$input.focus(function () {
self.trigger('input_focused');
});
+ this.$input.val(this.options.default_body);
dom_utils.autoresize(this.$input, {parent: this, min_height: this.options.input_min_height});
// Attachments
@@ -635,6 +651,9 @@ var BasicComposer = Widget.extend({
mention_set_prefetched_partners: function (prefetched_partners) {
this.mention_prefetched_partners = prefetched_partners;
},
+ mention_get_listener_selections: function () {
+ return this.mention_manager.get_listener_selections();
+ },
// Others
is_empty: function () {
@@ -679,6 +698,10 @@ var ExtendedComposer = BasicComposer.extend({
should_send: function () {
return false;
},
+
+ focus: function () {
+ this.$subject_input.focus();
+ },
});
return {
diff --git a/addons/mail/static/src/js/systray.js b/addons/mail/static/src/js/systray.js
index 21d22a12eac..3929947acbb 100644
--- a/addons/mail/static/src/js/systray.js
+++ b/addons/mail/static/src/js/systray.js
@@ -10,6 +10,42 @@ var chat_manager = require('mail.chat_manager');
var QWeb = core.qweb;
/**
+ * Menu item appended in the systray part of the navbar, redirects to the Inbox in Discuss
+ * Also displays the needaction counter (= Inbox counter)
+ */
+var InboxItem = Widget.extend({
+ template:'mail.chat.InboxItem',
+ events: {
+ "click": "on_click",
+ },
+ start: function () {
+ this.$needaction_counter = this.$('.o_notification_counter');
+ chat_manager.bus.on("update_needaction", this, this.update_counter);
+ this.update_counter();
+ return this._super();
+ },
+ update_counter: function () {
+ var counter = chat_manager.get_needaction_counter();
+ this.$needaction_counter.text(counter);
+ this.$el.toggleClass('o_no_notification', !counter);
+ },
+ on_click: function (event) {
+ event.preventDefault();
+ this.discuss_redirect();
+ },
+ discuss_redirect: _.debounce(function () {
+ var self = this;
+ var discuss_ids = chat_manager.get_discuss_ids();
+ this.do_action(discuss_ids.action_id, {clear_breadcrumbs: true}).then(function () {
+ self.trigger_up('hide_app_switcher');
+ core.bus.trigger('change_menu_section', discuss_ids.menu_id);
+ });
+ }, 1000, true),
+});
+
+SystrayMenu.Items.push(InboxItem);
+
+/**
* Menu item appended in the systray part of the navbar
*
* The menu item indicates the counter of needactions + unread messages in chat channels. When
@@ -24,13 +60,11 @@ var MessagingMenu = Widget.extend({
"click .o_filter_button": "on_click_filter_button",
"click .o_new_message": "on_click_new_message",
"click .o_mail_channel_preview": "on_click_channel",
- "click .o_redirect_to_discuss": "on_click_redirect_to_discuss",
},
start: function () {
this.$filter_buttons = this.$('.o_filter_button');
this.$channels_preview = this.$('.o_mail_navbar_dropdown_channels');
this.filter = false;
- chat_manager.bus.on("update_needaction", this, this.update_counter);
chat_manager.bus.on("update_channel_unread_counter", this, this.update_counter);
this.update_counter();
return this._super();
@@ -39,9 +73,10 @@ var MessagingMenu = Widget.extend({
return this.$el.hasClass('open');
},
update_counter: function () {
- var counter = chat_manager.get_needaction_counter() + chat_manager.get_chat_unread_counter();
+ var counter = chat_manager.get_unread_conversation_counter();
this.$('.o_notification_counter').text(counter);
this.$el.toggleClass('o_no_notification', !counter);
+ this.$el.toggleClass('o_unread_chat', !!chat_manager.get_chat_unread_counter());
if (this.is_open()) {
this.render_channels_preview();
}
@@ -52,15 +87,13 @@ var MessagingMenu = Widget.extend({
if (self.filter === 'chat') {
return channel.is_chat;
} else if (self.filter === 'channels') {
- return !channel.is_chat && channel.type !== 'static' && !channel.mass_mailing;
+ return !channel.is_chat && channel.type !== 'static';
} else {
- return channel.type !== 'static' && !channel.mass_mailing;
+ return channel.type !== 'static';
}
});
- // Update inbox counter and display spinner while waiting for channels preview
- var inbox_counter = chat_manager.get_needaction_counter();
- this.$('.o_inbox_counter').html(inbox_counter ? '(' + inbox_counter + ')' : '');
+ // Display spinner while waiting for channels preview
this.$channels_preview.html(QWeb.render('mail.chat.Spinner'));
chat_manager.get_channels_preview(channels).then(function (channels_preview) {
@@ -111,18 +144,6 @@ var MessagingMenu = Widget.extend({
chat_manager.bus.trigger('detach_channel', channel);
}
},
- on_click_redirect_to_discuss: function (event) {
- event.preventDefault();
- this.discuss_redirect();
- },
- discuss_redirect: _.debounce(function () {
- var self = this;
- var discuss_ids = chat_manager.get_discuss_ids();
- this.do_action(discuss_ids.action_id, {clear_breadcrumbs: true}).then(function () {
- self.trigger_up('hide_app_switcher');
- core.bus.trigger('change_menu_section', discuss_ids.menu_id);
- });
- }, 1000, true),
});
SystrayMenu.Items.push(MessagingMenu);
diff --git a/addons/mail/static/src/js/thread.js b/addons/mail/static/src/js/thread.js
index 439b1a8beb3..aee712ea905 100644
--- a/addons/mail/static/src/js/thread.js
+++ b/addons/mail/static/src/js/thread.js
@@ -38,9 +38,9 @@ var Thread = Widget.extend({
"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();
+ var $message = $(event.currentTarget).parents('.o_thread_message');
+ $message.addClass('o_message_expanded');
+ this.expanded_msg_ids.push($message.data('message-id'));
},
},
@@ -55,9 +55,12 @@ var Thread = Widget.extend({
shorten_messages: true,
squash_close_messages: true,
});
+ this.expanded_msg_ids = [];
},
render: function (messages, options) {
+ clearTimeout(this.auto_render_timeout);
+ var self = this;
var msgs = _.map(messages, this._preprocess_message.bind(this));
if (this.options.display_order === ORDER.DESC) {
msgs.reverse();
@@ -83,6 +86,12 @@ var Thread = Widget.extend({
options: options,
ORDER: ORDER,
}));
+
+ this.auto_render_timeout = setTimeout(function () {
+ if (!self.isDestroyed()) {
+ self.render(messages, options);
+ }
+ }, 1000*60); // re-render the thread every minute to update dates
},
on_click_redirect: function (event) {
@@ -110,7 +119,7 @@ var Thread = Widget.extend({
_preprocess_message: function (message) {
var msg = _.extend({}, message);
- // Set the date in the browser timezone
+ msg.date = moment.min(msg.date, moment());
var date = msg.date.format('YYYY-MM-DD');
if (date === moment().format('YYYY-MM-DD')) {
@@ -124,7 +133,11 @@ var Thread = Widget.extend({
msg.hour = msg.date.format('LT');
}
- msg.display_subject = message.subject && message.message_type !== 'notification' && !(message.model && (message.model !== 'mail.channel'));
+ if (_.contains(this.expanded_msg_ids, message.id)) {
+ msg.expanded = true;
+ }
+
+ msg.display_subject = message.subject && !message.is_system_notification;
return msg;
},
diff --git a/addons/mail/static/src/js/window_manager.js b/addons/mail/static/src/js/window_manager.js
index 65488129884..3ee3007a7ea 100644
--- a/addons/mail/static/src/js/window_manager.js
+++ b/addons/mail/static/src/js/window_manager.js
@@ -39,11 +39,12 @@ function open_chat (session) {
var chat_session = _.findWhere(chat_sessions, {id: session.id});
if (!chat_session) {
var prefix = !session.is_chat ? "#" : "";
+ var options = { input_less: session.mass_mailing };
chat_session = {
id: session.id,
uuid: session.uuid,
name: session.name,
- window: new ExtendedChatWindow(web_client, session.id, prefix + session.name, session.is_folded, session.unread_counter),
+ window: new ExtendedChatWindow(web_client, session.id, prefix + session.name, session.is_folded, session.unread_counter, options),
};
chat_session.window.on("close_chat_session", null, function () {
close_chat(chat_session);