summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/js
diff options
context:
space:
mode:
authorMartin Trigaux <mat@odoo.com>2015-12-01 10:54:51 +0100
committerMartin Trigaux <mat@odoo.com>2015-12-01 10:54:51 +0100
commit87f96c942ab4381b489db5b6bf5de959f0ec3d7f (patch)
treee9302d09e1fce1d4544e7fa92d4465105ded0140 /addons/mail/static/src/js
parentd025251c7e4ee4c26462e61b5d63e5c5d58689f8 (diff)
parent90254beedbb6a9bdf055ae582af866073eab4f2c (diff)
[MERGE] forward port of branch saas-7 up to 90254bee
Diffstat (limited to 'addons/mail/static/src/js')
-rw-r--r--addons/mail/static/src/js/chat_manager.js130
-rw-r--r--addons/mail/static/src/js/chatter.js39
-rw-r--r--addons/mail/static/src/js/client_action.js14
-rw-r--r--addons/mail/static/src/js/composer.js124
-rw-r--r--addons/mail/static/src/js/thread.js38
5 files changed, 231 insertions, 114 deletions
diff --git a/addons/mail/static/src/js/chat_manager.js b/addons/mail/static/src/js/chat_manager.js
index f297a751fa9..e8a2ad3951e 100644
--- a/addons/mail/static/src/js/chat_manager.js
+++ b/addons/mail/static/src/js/chat_manager.js
@@ -6,6 +6,7 @@ var core = require('web.core');
var data = require('web.data');
var Model = require('web.Model');
var session = require('web.session');
+var time = require('web.time');
var web_client = require('web.web_client');
var _t = core._t;
@@ -23,6 +24,7 @@ var channel_defs = {};
var emojis = [];
var emoji_substitutions = {};
var needaction_counter = 0;
+var mention_partner_suggestions = [];
var discuss_ids = {};
// Message and channel manipulation helpers
@@ -39,6 +41,13 @@ 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);
+
+ if (channel) {
+ add_to_cache(msg, []);
+ if (options.domain && options.domain !== []) {
+ add_to_cache(msg, options.domain);
+ }
+ }
if (channel && channel.hidden) {
channel.hidden = false;
chat_manager.bus.trigger('new_channel', channel);
@@ -61,6 +70,8 @@ function add_message (data, options) {
if (!options.silent) {
chat_manager.bus.trigger('new_message', msg);
}
+ } else if (options.domain && options.domain !== []) {
+ add_to_cache(msg, options.domain);
}
return msg;
}
@@ -71,7 +82,7 @@ function make_message (data) {
author_id: data.author_id,
body_short: data.body_short || "",
body: data.body || "",
- date: data.date,
+ date: moment(time.str_to_datetime(data.date)),
message_type: data.message_type,
subtype_description: data.subtype_description,
is_note: data.is_note,
@@ -118,13 +129,38 @@ function make_message (data) {
if (_.contains(data.starred_partner_ids, session.partner_id)) {
msg.is_starred = true;
}
- var real_channels = _.without(msg.channel_ids, 'channel_inbox', 'channel_starred');
- var origin = real_channels.length ? real_channels[0] : undefined;
- var channel = origin && chat_manager.get_channel(origin);
- if (channel) {
- msg.origin_id = origin;
- msg.origin_name = channel.name;
+ if (msg.model === 'mail.channel') {
+ var real_channels = _.without(msg.channel_ids, 'channel_inbox', 'channel_starred');
+ var origin = real_channels.length === 1 ? real_channels[0] : undefined;
+ var channel = origin && chat_manager.get_channel(origin);
+ if (channel) {
+ msg.origin_id = origin;
+ msg.origin_name = channel.name;
+ }
+ }
+
+ // Compute displayed author name or email
+ if ((!msg.author_id || !msg.author_id[0]) && msg.email_from) {
+ msg.mailto = msg.email_from;
+ } else {
+ msg.displayed_author = msg.author_id && msg.author_id[1] ||
+ msg.email_from || _t('Anonymous');
}
+
+ // 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";
+ } else if (msg.message_type === 'email') {
+ msg.avatar_src = "/mail/static/src/img/email_icon.png";
+ } else {
+ msg.avatar_src = "/mail/static/src/img/smiley/avatar.jpg";
+ }
+
+ // Compute url of attachments
+ _.each(msg.attachment_ids, function(a) {
+ a.url = '/web/content/' + a.id + '?download=true';
+ });
+
return msg;
}
@@ -207,7 +243,7 @@ function make_channel (data, options) {
cache: {'[]': {
all_history_loaded: false,
loaded: false,
- message_ids: [],
+ messages: [],
}},
};
if (channel.type === "channel" && data.public !== "private") {
@@ -229,17 +265,39 @@ function get_channel_cache (channel, domain) {
channel.cache[stringified_domain] = {
all_history_loaded: false,
loaded: false,
- message_ids: [],
+ messages: [],
};
}
return channel.cache[stringified_domain];
}
+function invalidate_caches(channel_ids) {
+ _.each(channel_ids, function (channel_id) {
+ var channel = chat_manager.get_channel(channel_id);
+ if (channel) {
+ channel.cache = { '[]': channel.cache['[]']};
+ }
+ });
+}
+
+function add_to_cache(message, domain) {
+ _.each(message.channel_ids, function (channel_id) {
+ var channel = chat_manager.get_channel(channel_id);
+ if (channel) {
+ var channel_cache = get_channel_cache(channel, domain);
+ var index = _.sortedIndex(channel_cache.messages, message, 'id');
+ if (channel_cache.messages[index] !== message) {
+ channel_cache.messages.splice(index, 0, message);
+ }
+ }
+ });
+}
+
function remove_message_from_channel (channel_id, message) {
message.channel_ids = _.without(message.channel_ids, channel_id);
var channel = _.findWhere(channels, { id: channel_id });
_.each(channel.cache, function (cache) {
- cache.message_ids = _.without(cache.message_ids, message.id);
+ cache.messages = _.without(cache.messages, message);
});
}
@@ -256,28 +314,21 @@ function fetch_from_channel (channel, options) {
domain = new data.CompoundDomain(domain, options.domain || []);
}
if (options.load_more) {
- var min_message_id = _.chain(messages)
- .filter(function (msg) { return _.contains(cache.message_ids, msg.id); })
- .pluck("id")
- .min()
- .value();
-
+ var min_message_id = cache.messages[0].id;
domain = new data.CompoundDomain([['id', '<', min_message_id]], domain);
}
return MessageModel.call('message_fetch', [domain], {limit: LIMIT}).then(function (msgs) {
- cache.message_ids = _.uniq(cache.message_ids.concat(_.pluck(msgs, 'id')));
if (!cache.all_history_loaded) {
cache.all_history_loaded = msgs.length < LIMIT;
}
cache.loaded = true;
_.each(msgs, function (msg) {
- add_message(msg, {channel_id: channel.id, silent: true});
- });
- return _.filter(messages, function (m) {
- return _.contains(cache.message_ids, m.id);
+ add_message(msg, {channel_id: channel.id, silent: true, domain: options.domain});
});
+ var channel_cache = get_channel_cache(channel, options.domain || []);
+ return channel_cache.messages;
});
}
@@ -335,6 +386,7 @@ function on_notification (notification) {
function on_needaction_notification (message) {
message = add_message(message, { channel_id: 'channel_inbox', show_notification: true} );
+ invalidate_caches(message.channel_ids);
needaction_counter++;
_.each(message.channel_ids, function (channel_id) {
var channel = chat_manager.get_channel(channel_id);
@@ -360,6 +412,7 @@ function on_channel_notification (message) {
}
});
add_message(message, { show_notification: true });
+ invalidate_caches(message.channel_ids);
});
}
@@ -382,6 +435,7 @@ function on_toggle_star_notification (data) {
_.each(data.message_ids, function (msg_id) {
var message = _.findWhere(messages, { id: msg_id });
if (message) {
+ invalidate_caches(message.channel_ids);
message.is_starred = data.starred;
if (!message.is_starred) {
remove_message_from_channel("channel_starred", message);
@@ -395,6 +449,7 @@ function on_mark_as_read_notification (data) {
_.each(data.message_ids, function (msg_id) {
var message = _.findWhere(messages, { id: msg_id });
if (message) {
+ invalidate_caches(message.channel_ids);
remove_message_from_channel("channel_inbox", message);
chat_manager.bus.trigger('update_message', message);
}
@@ -419,6 +474,7 @@ function on_mark_as_unread_notification (data) {
_.each(data.message_ids, function (message_id) {
var message = _.findWhere(messages, { id: message_id });
if (message) {
+ invalidate_caches(message.channel_ids);
add_channel_to_message(message, 'channel_inbox');
}
});
@@ -433,10 +489,10 @@ function on_mark_as_unread_notification (data) {
}
function on_chat_session_notification (chat_session) {
- if ((chat_session.channel_type === "channel") && (chat_session.public === "private") && (chat_session.state === "open")) {
+ if ((chat_session.channel_type === "channel") && (chat_session.state === "open")) {
add_channel(chat_session, {autoswitch: false});
- if (!chat_session.is_minimized) {
- web_client.do_notify(_t("Private Channel"), _t("You have been invited to: ") + chat_session.name);
+ if (!chat_session.is_minimized && chat_session.info !== 'creation') {
+ web_client.do_notify(_t("Invitation"), _t("You have been invited to: ") + chat_session.name);
}
}
// partner specific change (open a detached window for example)
@@ -460,9 +516,7 @@ var chat_manager = {
var channel = this.get_channel(options.channel_id);
var channel_cache = get_channel_cache(channel, options.domain);
if (channel_cache.loaded) {
- return $.when(_.filter(messages, function (message) {
- return _.contains(message.channel_ids, options.channel_id);
- }));
+ return $.when(channel_cache.messages);
} else {
return fetch_from_channel(channel, {domain: options.domain});
}
@@ -531,6 +585,27 @@ var chat_manager = {
return get_channel_cache(channel, domain).all_history_loaded;
},
+ get_mention_partner_suggestions: function (channel) {
+ if (!channel) {
+ return mention_partner_suggestions;
+ }
+ if (!channel.members_deferred) {
+ channel.members_deferred = ChannelModel
+ .call("channel_fetch_listeners", [channel.uuid])
+ .then(function (members) {
+ var suggestions = [];
+ _.each(mention_partner_suggestions, function (partners) {
+ suggestions.push(_.filter(partners, function (partner) {
+ return !_.findWhere(members, { id: partner.id });
+ }));
+ });
+
+ return [members].concat(suggestions);
+ });
+ }
+ return channel.members_deferred;
+ },
+
get_emojis: function() {
return emojis;
},
@@ -618,6 +693,7 @@ function init () {
_.each(channels, add_channel);
});
needaction_counter = result.needaction_inbox_counter;
+ mention_partner_suggestions = result.mention_partner_suggestions;
});
var load_emojis = session.rpc("/mail/chat_init").then(function (result) {
diff --git a/addons/mail/static/src/js/chatter.js b/addons/mail/static/src/js/chatter.js
index f8c9f1e032e..d29312cf6f6 100644
--- a/addons/mail/static/src/js/chatter.js
+++ b/addons/mail/static/src/js/chatter.js
@@ -37,6 +37,7 @@ var Followers = form_common.AbstractField.extend({
this.value = [];
this.followers = [];
+ this.followers_fetched = $.Deferred();
this.data_subtype = {};
this.view_is_editable = this.__parentedParent.is_action_enabled('edit');
@@ -188,9 +189,14 @@ 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(this.proxy('display_followers'), this.proxy('fetch_generic'))
+ .then(function (followers) {
+ self.trigger('followers_update', followers);
+ self.display_followers(followers);
+ self.fetch_generic();
+ })
.then(this.proxy('display_buttons'))
.then(this.proxy('fetch_subtypes'));
},
@@ -706,6 +712,7 @@ var Chatter = form_common.AbstractField.extend({
if (this.followers) {
this.$('.o_chatter_topbar').append(this.followers.$el);
this.followers.on('redirect', this, this.on_redirect);
+ this.followers.on('followers_update', this, this.on_followers_update);
}
this.thread = new ChatThread(this, {
@@ -798,6 +805,30 @@ var Chatter = form_common.AbstractField.extend({
});
},
+ on_followers_update: function (followers) {
+ this.mention_suggestions = [];
+ var self = this;
+ var prefetched_partners = chat_manager.get_mention_partner_suggestions();
+ var follower_suggestions = [];
+ _.each(followers, function (follower) {
+ if (follower.res_model === 'res.partner') {
+ follower_suggestions.push({
+ id: follower.res_id,
+ name: follower.name,
+ email: follower.email,
+ });
+ }
+ });
+ if (follower_suggestions.length) {
+ this.mention_suggestions.push(follower_suggestions);
+ }
+ _.each(prefetched_partners, function (partners) {
+ self.mention_suggestions.push(_.filter(partners, function (partner) {
+ return !_.findWhere(follower_suggestions, { id: partner.id });
+ }));
+ });
+ },
+
load_more_messages: function () {
this.fetch_and_render_thread(this.msg_ids, {force_fetch: true});
},
@@ -854,9 +885,9 @@ var Chatter = form_common.AbstractField.extend({
internal_subtypes: this.options.internal_subtypes,
is_log: options && options.is_log,
record_name: this.record_name,
- get_channel_info: function () {
- return { res_id: self.res_id, res_model: self.model };
- },
+ });
+ this.composer.on('input_focused', this, function () {
+ this.composer.mention_set_prefetched_partners(this.mention_suggestions || []);
});
this.composer.insertBefore(this.$('.o_mail_thread')).then(function () {
// destroy existing composer
diff --git a/addons/mail/static/src/js/client_action.js b/addons/mail/static/src/js/client_action.js
index 20078af06a2..b96e9af6777 100644
--- a/addons/mail/static/src/js/client_action.js
+++ b/addons/mail/static/src/js/client_action.js
@@ -171,11 +171,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
this.searchview = new SearchView(this, dataset, view_id, {}, options);
this.searchview.on('search_data', this, this.on_search);
- this.composer = new ChatComposer(this, {
- get_channel_info: function () {
- return { channel_id: self.channel.id };
- },
- });
+ this.composer = new ChatComposer(this);
this.thread = new ChatThread(this, {
display_help: true
});
@@ -211,6 +207,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
chat_manager.toggle_star_status(message_id);
});
this.composer.on('post_message', this, this.on_post_message);
+ this.composer.on('input_focused', this, this.on_composer_input_focused);
var def1 = this.thread.prependTo(this.$('.o_mail_chat_content'));
var def2 = this.composer.appendTo(this.$('.o_mail_chat_content'));
@@ -436,6 +433,9 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
display_needactions: this.channel.display_needactions,
messages_separator_position: this.messages_separator_position,
squash_close_messages: this.channel.type !== 'static',
+ 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",
};
},
@@ -592,6 +592,10 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
this.set_channel(channel);
}
},
+ on_composer_input_focused: function () {
+ var suggestions = chat_manager.get_mention_partner_suggestions(this.channel);
+ this.composer.mention_set_prefetched_partners(suggestions);
+ },
on_click_button_invite: function () {
var title = _.str.sprintf(_t('Invite people to %s'), this.channel.name);
diff --git a/addons/mail/static/src/js/composer.js b/addons/mail/static/src/js/composer.js
index bfbf3618a98..24257d1a72a 100644
--- a/addons/mail/static/src/js/composer.js
+++ b/addons/mail/static/src/js/composer.js
@@ -12,6 +12,19 @@ var Widget = require('web.Widget');
var QWeb = core.qweb;
var _t = core._t;
+var accented_letters_mapping = {
+ 'a': '[àáâãäå]',
+ 'ae': 'æ',
+ 'c': 'ç',
+ 'e': '[èéêë]',
+ 'i': '[ìíîï]',
+ 'n': 'ñ',
+ 'o': '[òóôõö]',
+ 'oe': 'œ',
+ 'u': '[ùúûűü]',
+ 'y': '[ýÿ]',
+};
+
// 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
@@ -63,16 +76,14 @@ var MentionManager = Widget.extend({
};
// add the selected suggestion to the list
- var selection = this.active_listener.selection;
- if (selection.length && this.active_listener.sort_selection) {
+ if (this.active_listener.selection.length) {
// get mention matches (ordered by index in the text)
var matches = this._get_match(text_input, this.active_listener);
var index = get_mention_index(matches, this._get_selection_positions().start);
- selection.splice(index, 0, selected_suggestion);
+ this.active_listener.selection.splice(index, 0, selected_suggestion);
} else {
- selection = selection.concat([selected_suggestion]);
+ this.active_listener.selection.push(selected_suggestion);
}
- this._update_listener_selection(this.active_listener, selection);
// update input text, and reset dropdown
var cursor_position = this._get_selection_positions().start;
@@ -90,10 +101,7 @@ var MentionManager = Widget.extend({
* @param {char} [delimiter] the mention delimiter
* @param {function} [fetch_callback] the callback to fetch mention suggestions
* @param {string} [model] the model used for redirection
- * @param {boolean} [notify_selection_changed] true to trigger an event when the selection changes
* @param {string} [redirect_classname] the classname of the <a> wrapping the mention
- * @param {boolean} [sort_selection] true if the selection must be sorted
- * @param {string} [suggestions_template] the QWeb template to render suggestions
*/
register: function (listener) {
this.listeners.push(_.extend(listener, {
@@ -137,7 +145,6 @@ var MentionManager = Widget.extend({
*/
detect_delimiter: function () {
var self = this;
- var options = this.options;
var text_val = this.composer.$input.val();
var cursor_position = this._get_selection_positions().start;
var left_string = text_val.substring(0, cursor_position);
@@ -146,7 +153,7 @@ var MentionManager = Widget.extend({
var pattern = "(^"+delimiter+"|(^\\s"+delimiter+"))";
var regex_start = new RegExp(pattern, "g");
search_str = search_str.replace(/^\s\s*|^[\n\r]/g, '');
- if (regex_start.test(search_str) && search_str.length > options.min_length) {
+ if (regex_start.test(search_str) && search_str.length > self.options.min_length) {
search_str = search_str.replace(pattern, '');
return search_str.indexOf(' ') < 0 && !/[\r\n]/.test(search_str) ? search_str.replace(delimiter, '') : false;
}
@@ -164,19 +171,19 @@ var MentionManager = Widget.extend({
}
}
- if (this.active_listener) {
- // start a timeout to fetch data with the current 'mention word'. The timer avoid to start
- // an RPC for each pushed key when the user is still typing.
- // The 'typing_speed' option should approach the time for a human to type a letter.
- clearTimeout(this.mention_fetch_timer);
- this.mention_fetch_timer = setTimeout(function () {
- $.when(listener.fetch_callback(self.mention_word, self.active_listener)).then(function (suggestions) {
+ // start a timeout to fetch data with the current 'mention word'. The timer avoid to start
+ // an RPC for each pushed key when the user is still typing.
+ // The 'typing_speed' option should approach the time for a human to type a letter.
+ clearTimeout(this.mention_fetch_timer);
+ this.mention_fetch_timer = setTimeout(function () {
+ if (self.active_listener) {
+ $.when(listener.fetch_callback(self.mention_word)).then(function (suggestions) {
self.set('mention_suggestions', suggestions);
});
- }, this.options.typing_speed);
- } else {
- this.set('mention_suggestions', []); // close the dropdown
- }
+ } else {
+ self.set('mention_suggestions', []); // close the dropdown
+ }
+ }, this.options.typing_speed);
},
/**
@@ -201,7 +208,7 @@ var MentionManager = Widget.extend({
}
}
if (to_remove.length) {
- self._update_listener_selection(listener, _.difference(mention_selection, to_remove));
+ listener.selection = _.difference(mention_selection, to_remove);
}
});
},
@@ -235,9 +242,8 @@ var MentionManager = Widget.extend({
},
reset_selections: function () {
- var self = this;
_.each(this.listeners, function (listener) {
- self._update_listener_selection(listener, []);
+ listener.selection = [];
});
},
@@ -269,7 +275,7 @@ var MentionManager = Widget.extend({
},
_render_suggestions: function () {
if (_.flatten(this.get('mention_suggestions')).length) {
- this.$el.html(QWeb.render(this.active_listener.suggestions_template, {
+ this.$el.html(QWeb.render('mail.ChatComposer.MentionSuggestions', {
suggestions: this.get('mention_suggestions'),
}));
this.$el
@@ -282,12 +288,6 @@ var MentionManager = Widget.extend({
this.open = false;
}
},
- _update_listener_selection: function (listener, selection) {
- listener.selection = selection;
- if (listener.notify_selection_changed) {
- this.trigger('selection_changed', listener);
- }
- },
// Cursor position and selection utils
_get_selection_positions: function () {
@@ -327,10 +327,8 @@ var Composer = Widget.extend({
input_max_height: 150,
input_min_height: 28,
mention_fetch_limit: 8,
- get_channel_info: function () {},
});
this.context = this.options.context;
- this.get_channel_info = this.options.get_channel_info;
// Attachments
this.AttachmentDataSet = new data.DataSetSearch(this, 'ir.attachment', this.context);
@@ -343,19 +341,14 @@ var Composer = Widget.extend({
delimiter: '@',
fetch_callback: this.mention_fetch_partners.bind(this),
model: 'res.partner',
- notify_selection_changed: true,
redirect_classname: 'o_mail_redirect',
- sort_selection: true,
- suggestions_template: 'mail.ChatComposer.MentionPartnerSuggestions',
});
this.mention_manager.register({
delimiter: '#',
fetch_callback: this.mention_fetch_channels.bind(this),
model: 'mail.channel',
redirect_classname: 'o_channel_redirect',
- suggestions_template: 'mail.ChatComposer.MentionChannelSuggestions'
});
- this.mention_manager.on('selection_changed', this, this.mention_render_selection);
this.PartnerModel = new Model('res.partner');
this.ChannelModel = new Model('mail.channel');
},
@@ -365,8 +358,10 @@ var Composer = Widget.extend({
this.$attachment_button = this.$(".o_composer_button_add_attachment");
this.$attachments_list = this.$('.o_composer_attachments_list');
- this.$mention_partner_tags = this.$('.o_composer_mentioned_partners');
this.$input = this.$('.o_composer_input');
+ this.$input.focus(function () {
+ self.trigger('input_focused');
+ });
this.resize_input();
// Attachments
@@ -403,7 +398,7 @@ var Composer = Widget.extend({
return $.when({
content: this.mention_manager.generate_links(value),
attachment_ids: _.pluck(this.get('attachment_ids'), 'id'),
- partner_ids: _.pluck(this.mention_manager.get_listener_selection('@'), 'id'),
+ partner_ids: _.uniq(_.pluck(this.mention_manager.get_listener_selection('@'), 'id')),
});
},
@@ -607,19 +602,38 @@ var Composer = Widget.extend({
});
});
},
- mention_fetch_partners: function (search, listener) {
- var kwargs = {
- channel: this.get_channel_info(),
- exclude: listener ? _.pluck(listener.selection, 'id') : [],
- limit: this.options.mention_fetch_limit,
- search: search,
- };
- return this.PartnerModel.call('get_mention_suggestions', kwargs);
+ mention_fetch_partners: function (search) {
+ var self = this;
+ return $.when(this.mention_prefetched_partners).then(function (prefetched_partners) {
+ // filter prefetched partners with the given search string
+ var suggestions = [];
+ var limit = self.options.mention_fetch_limit;
+ var search_regexp = new RegExp(self.unaccent(search), 'i');
+ _.each(prefetched_partners, function (partners) {
+ if (limit > 0) {
+ var filtered_partners = _.filter(partners, function (partner) {
+ return partner.email && partner.email.search(search_regexp) !== -1 ||
+ partner.name && self.unaccent(partner.name).search(search_regexp) !== -1;
+ });
+ if (filtered_partners.length) {
+ suggestions.push(filtered_partners.slice(0, limit));
+ limit -= filtered_partners.length;
+ }
+ }
+ });
+ if (!suggestions.length) {
+ // no result found among prefetched partners, fetch other suggestions
+ var kwargs = {
+ limit: limit,
+ search: search,
+ };
+ suggestions = self.PartnerModel.call('get_mention_suggestions', kwargs);
+ }
+ return suggestions;
+ });
},
- mention_render_selection: function (listener) {
- this.$mention_partner_tags.html(QWeb.render('mail.ChatComposer.MentionTags', {
- partners: listener.selection,
- }));
+ mention_set_prefetched_partners: function (prefetched_partners) {
+ this.mention_prefetched_partners = prefetched_partners;
},
// Others
@@ -629,6 +643,12 @@ var Composer = Widget.extend({
focus: function () {
this.$input.focus();
},
+ unaccent: function (str) {
+ _.each(accented_letters_mapping, function (value, key) {
+ str = str.replace(new RegExp(value, 'g'), key);
+ });
+ return str;
+ },
});
return Composer;
diff --git a/addons/mail/static/src/js/thread.js b/addons/mail/static/src/js/thread.js
index 6fd5838aa48..a1f8fc8a076 100644
--- a/addons/mail/static/src/js/thread.js
+++ b/addons/mail/static/src/js/thread.js
@@ -2,7 +2,6 @@ odoo.define('mail.ChatThread', function (require) {
"use strict";
var core = require('web.core');
-var time = require('web.time');
var Widget = require('web.Widget');
var QWeb = core.qweb;
@@ -49,7 +48,6 @@ var Thread = Widget.extend({
display_order: ORDER.ASC,
display_needactions: true,
display_stars: true,
- default_username: _t('Anonymous'),
display_document_link: true,
display_avatar: true,
squash_close_messages: true,
@@ -67,7 +65,7 @@ var Thread = Widget.extend({
// one are both comments wrote by the same author at the same minute
var prev_msg;
_.each(msgs, function (msg) {
- if (!prev_msg || (Math.abs(moment(msg.date).diff(prev_msg.date)) > 60000) ||
+ if (!prev_msg || (Math.abs(msg.date.diff(prev_msg.date)) > 60000) ||
prev_msg.message_type !== 'comment' || msg.message_type !== 'comment' ||
(prev_msg.author_id[0] !== msg.author_id[0])) {
msg.display_author = true;
@@ -79,7 +77,7 @@ var Thread = Widget.extend({
this.$el.html(QWeb.render('mail.ChatThread', {
messages: msgs,
- options: _.extend({}, this.options, options),
+ options: options,
ORDER: ORDER,
}));
},
@@ -113,31 +111,19 @@ var Thread = Widget.extend({
var msg = _.extend({}, message);
// Set the date in the browser timezone
- msg.date = moment(time.str_to_datetime(msg.date)).format('YYYY-MM-DD HH:mm:ss');
-
- // Compute displayed author name or email
- if ((!msg.author_id || !msg.author_id[0]) && msg.email_from) {
- msg.mailto = msg.email_from;
- } else {
- msg.displayed_author = msg.author_id && msg.author_id[1] ||
- msg.email_from ||
- this.options.default_username;
- }
-
- // 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";
- } else if (msg.message_type === 'email') {
- msg.avatar_src = "/mail/static/src/img/email_icon.png";
+ var date = msg.date.format('YYYY-MM-DD');
+
+ if (date === moment().format('YYYY-MM-DD')) {
+ msg.day = _t("Today");
+ 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');
} else {
- msg.avatar_src = "/mail/static/src/img/smiley/avatar.jpg";
+ msg.day = msg.date.format('LL');
+ msg.hour = msg.date.format('hh:mm');
}
- // Compute url of attachments
- _.each(msg.attachment_ids, function(a) {
- a.url = '/web/content/' + a.id + '?download=true';
- });
-
return msg;
},