From 449f25463843767ba41a9a8c2adfdd4ceb2f2e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Maes?= Date: Tue, 11 Aug 2015 10:17:10 +0200 Subject: [REF] mail : include real time, and replace Timeline features This commit add instant messaging features in mail module to make it a real team collaboration tool. Lots of these new features will replace Timeleine view (which is not removed in this commit). Many files have been moved, split or created for a better structure. - My Channels : A user can be member of channel (mail.channel). These are discussion group, but also an aggregate of notification. Setting a channel as document follower, it will receive all the message (of the chatter) in real time, as information stream. - A new Inbox : this aims to replace the timeline view. The user will see its channels grouped by 'slot', and receive the message in real time. Jump to the form view, invite people, create private discussion group, talk directly to another employee, ... are the main features. Your message can still be starred. The 'Inbox' will only contain your needaction. - Needaction concept : a needaction is a message calling you to do something. If you follow a document as a person, the posted message will be 'needaction' for you. It can also be a message where you are mention with a '@my_name' (this feature is not added in this commit). - The chatter doesn't change so much. It still allow you to see the discussion about the document, to star some message, and treat your needaction. - Chat : the only way to have a minified conversation is from the Inbox Client Action. It allow you to keep an eye on a channel when working on document. - Compose Message : it is now common to the Inbox, and the chatter. It offers shortcode substitution, attachments management, and optional subtype. - UI : the chat window has been clean, they have a new look now. To do so, - Chatter code have been completely rewrite, independently of timeline view - Add 'bus' as mail dependency, to insure real time - A mail.message is broadcasted on the bus channel (db, mail.channel, channel_id), and a channel header on (db, res.partner, partner_id) - Extracting mail_thread mixin used for Chatter and ChatMailThread (Inbox client action). This uniformize the programming structure with the server side - Clean CSS style and use LESS instead of CSS - Define a new messafe format (message_format method in mail_message.py), compatible with fetching and broadcasting - Apply guideline coding conventions This commit also break the module im_livechat, since im_chat models don't exists anymore and will be fixed in the next commit. Thanks to Thibault Delavallee (tde) for the long debates and precious advices, Richard Mathot (rim) for the support, Simon Lejeune (sle) for the client action layout, and the Usability Team (apr, lle, bst yti) for the long testing. Conflicts: addons/mail/models/mail_thread.py --- addons/mail/static/src/js/mail_utils.js | 105 +++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 21 deletions(-) (limited to 'addons/mail/static/src/js/mail_utils.js') diff --git a/addons/mail/static/src/js/mail_utils.js b/addons/mail/static/src/js/mail_utils.js index 656dc941a75..a18dc449d6b 100644 --- a/addons/mail/static/src/js/mail_utils.js +++ b/addons/mail/static/src/js/mail_utils.js @@ -5,7 +5,7 @@ odoo.define('mail.utils', function () { * ------------------------------------------------------------ * ChatterUtils * ------------------------------------------------------------ - * + * * This class holds a few tools method for Chatter. * Some regular expressions not used anymore, kept because I want to * - (^|\s)@((\w|@|\.)*): @login@log.log @@ -27,24 +27,6 @@ function parse_email(text) { return [text, false]; } -/** - * Replaces some expressions - * - :name - shortcut to an image - */ -function do_replace_expressions(string) { - var icon_list = ['al', 'pinky']; - /* special shortcut: :name, try to find an icon if in list */ - var regex_login = new RegExp(/(^|\s):((\w)*)/g); - var regex_res = regex_login.exec(string); - while (regex_res !== null) { - var icon_name = regex_res[2]; - if (_.include(icon_list, icon_name)) - string = string.replace(regex_res[0], regex_res[1] + '' + icon_name + ''); - regex_res = regex_login.exec(string); - } - return string; -} - /** * Replaces textarea text into html text (add

, ) * TDE note : should be done server-side, in Python -> use mail.compose.message ? @@ -55,7 +37,7 @@ function get_text2html(text) { .replace(/[\n\r]/g,'
'); } -/* Returns the complete domain with "&" +/* Returns the complete domain with "&" * TDE note: please add some comments to explain how/why */ function expand_domain(domain) { @@ -90,6 +72,8 @@ function breakword(str){ return out; } + +// TODO JEM : remove me in master function bindTooltipTo($el, value, position) { $el.tooltip({ 'title': value, @@ -106,13 +90,92 @@ function bindTooltipTo($el, value, position) { }); } + +/** + * ------------------------------------------------------------ + * MailChat Utils + * ------------------------------------------------------------ + */ + + /** + * Apply the given shortcode to the 'str' message. + * @param str : the text to substitute (html). + * @param shortcodes : dict where key is the shortcode, and the value is the substitution + */ +function shortcode_apply(str, shortcodes){ + var re_escape = function(str){ + return String(str).replace(/([.*+?=^!:${}()|[\]\/\\])/g, '\\$1'); + }; + _.each(_.keys(shortcodes), function(key){ + str = str.replace( new RegExp("(?:^|\\s|<[a-z]*>)(" + re_escape(key) + ")(?:\\s|$|)"), ' '+shortcodes[key]+' '); + }); + return str; +} + +/** + * Transform the list of emoji (shortcode Object) into a key-array representing + * the substitution to apply + * @param {Ojbect[]} emoji_list : list of emoji object + * @returns {Object} mapping between the code (as key) and the substitution (as value) + */ +function shortcode_substitution(emoji_list){ + var emoji_substitution = {}; + _.each(emoji_list, function(emoji){ + emoji_substitution[emoji.source] = emoji.substitution; + }); + return emoji_substitution; +} + +/** + * Associate a font awesome class to a attachment file type + * @param {string} file_type : file type to analyse + * @returns {string} the fa class associated + */ +function attachment_filetype_to_fa_class(file_type){ + var mapping = { + 'text': 'fa fa-file-text-o', + 'document': 'fa fa-file-word-o', + 'audio': 'fa fa-file-audio-o', + 'archive': 'fa fa-file-archive-o', + 'disk': 'fa fa-file-archive-o', + 'image': 'fa fa-file-photo-o', + 'webimage': 'fa fa-file-photo-o', + 'script': 'fa fa-file-code-o', + 'html': 'fa fa-file-code-o', + 'video': 'fa fa-file-movie-o', + 'spreadsheet': 'fa fa-file-excel-o', + 'print': 'fa fa-file-pdf-o', + 'presentation': 'fa fa-file-powerpoint-o', + } + if(_.contains(_.keys(mapping), file_type)){ + return mapping[file_type]; + } + return 'fa fa-file-o'; +} + +/** + * Play the noise 'ting' to notify user + */ +function beep(session){ + if (typeof(Audio) === "undefined") { + return; + } + var audio = new Audio(); + var ext = audio.canPlayType("audio/ogg; codecs=vorbis") ? ".ogg" : ".mp3"; + audio.src = session.url("/mail/static/src/audio/ting") + ext; + audio.play(); +} + return { parse_email: parse_email, - do_replace_expressions: do_replace_expressions, get_text2html: get_text2html, expand_domain: expand_domain, breakword: breakword, bindTooltipTo: bindTooltipTo, + shortcode_apply: shortcode_apply, + shortcode_substitution: shortcode_substitution, + attachment_filetype_to_fa_class: attachment_filetype_to_fa_class, + beep: beep, }; }); -- cgit v1.2.3