diff options
| author | Dharmang Soni <dpr@odoo.com> | 2017-04-26 10:51:15 +0530 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2017-09-15 15:25:06 +0200 |
| commit | 4685e4bc7f19f964697bf0dbd7dfdf254b6c5628 (patch) | |
| tree | b852d056ac124aa692dff20f468dd62add05b00e /addons/mail/static/src | |
| parent | a8e7d096b85709ccf52411c450d0574f9238fd6f (diff) | |
[IMP] mail: improve Discuss UI for mobile devices
- Brand new UI for Discuss client action (with tabs for Inbox,
chats, channels...)
- In mobile, conversations always open in Chat Windows
- Chat window UI improved (both mobile and desktop)
- Channels preview (used in the systray menu, and now in the mobile
UI of Discuss) improved
- Other minor less tweaks
Diffstat (limited to 'addons/mail/static/src')
| -rw-r--r-- | addons/mail/static/src/js/chat_manager.js | 3 | ||||
| -rw-r--r-- | addons/mail/static/src/js/chat_window.js | 13 | ||||
| -rw-r--r-- | addons/mail/static/src/js/client_action.js | 237 | ||||
| -rw-r--r-- | addons/mail/static/src/js/composer.js | 2 | ||||
| -rw-r--r-- | addons/mail/static/src/js/systray.js | 5 | ||||
| -rw-r--r-- | addons/mail/static/src/less/chat_window.less | 124 | ||||
| -rw-r--r-- | addons/mail/static/src/less/client_action.less | 271 | ||||
| -rw-r--r-- | addons/mail/static/src/less/composer.less | 14 | ||||
| -rw-r--r-- | addons/mail/static/src/less/extended_chat_window.less | 51 | ||||
| -rw-r--r-- | addons/mail/static/src/less/systray.less | 103 | ||||
| -rw-r--r-- | addons/mail/static/src/less/thread.less | 63 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/chat_window.xml | 5 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/client_action.xml | 96 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/composer.xml | 1 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/extended_chat_window.xml | 2 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/systray.xml | 29 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/thread.xml | 53 |
17 files changed, 978 insertions, 94 deletions
diff --git a/addons/mail/static/src/js/chat_manager.js b/addons/mail/static/src/js/chat_manager.js index 807d5352180..128309bc77d 100644 --- a/addons/mail/static/src/js/chat_manager.js +++ b/addons/mail/static/src/js/chat_manager.js @@ -82,6 +82,8 @@ function add_message (data, options) { _.each(msg.channel_ids, function (channel_id) { var channel = chat_manager.get_channel(channel_id); if (channel) { + // For mobile tabs view, we show recent message for channel. + channel.last_message = msg; add_to_cache(msg, []); if (options.domain && options.domain !== []) { add_to_cache(msg, options.domain); @@ -288,6 +290,7 @@ function make_channel (data, options) { group_based_subscription: data.group_based_subscription, needaction_counter: data.message_needaction_counter || 0, unread_counter: 0, + last_message: data.last_message, last_seen_message_id: data.seen_message_id, cache: {'[]': { all_history_loaded: false, diff --git a/addons/mail/static/src/js/chat_window.js b/addons/mail/static/src/js/chat_window.js index 9f91baee764..9d54a6df0b2 100644 --- a/addons/mail/static/src/js/chat_window.js +++ b/addons/mail/static/src/js/chat_window.js @@ -11,7 +11,7 @@ var QWeb = core.qweb; var _t = core._t; var HEIGHT_OPEN = '400px'; -var HEIGHT_FOLDED = '28px'; +var HEIGHT_FOLDED = '34px'; return Widget.extend({ template: "mail.ChatWindow", @@ -43,6 +43,7 @@ return Widget.extend({ this.status = this.options.status; this.unread_msgs = unread_msgs || 0; this.is_hidden = false; + this.isMobile = config.isMobile; }, start: function () { this.$input = this.$('.o_composer_text_field'); @@ -76,6 +77,13 @@ return Widget.extend({ this.unread_msgs = counter; this.render_header(); }, + + /** + * When user status (online/offline/away) changed, this method update + * user status with last seen and render header again. + * + * @param {string} status + */ update_status: function (status) { this.status = status; this.render_header(); @@ -84,13 +92,14 @@ return Widget.extend({ this.$header.html(QWeb.render('mail.ChatWindowHeaderContent', { status: this.status, title: this.title, + isMobile: this.isMobile, unread_counter: this.unread_msgs, })); }, fold: function () { this.$el.animate({ height: this.folded ? HEIGHT_FOLDED : HEIGHT_OPEN - }); + }, 200); }, toggle_fold: function (fold) { this.folded = _.isBoolean(fold) ? fold : !this.folded; diff --git a/addons/mail/static/src/js/client_action.js b/addons/mail/static/src/js/client_action.js index a27790f9629..4058fbc0924 100644 --- a/addons/mail/static/src/js/client_action.js +++ b/addons/mail/static/src/js/client_action.js @@ -16,6 +16,7 @@ var dom = require('web.dom'); var pyeval = require('web.pyeval'); var SearchView = require('web.SearchView'); var Widget = require('web.Widget'); +var session = require('web.session'); var QWeb = core.qweb; var _t = core._t; @@ -149,10 +150,13 @@ var ChatAction = Widget.extend(ControlPanelMixin, { on_reverse_breadcrumb: this.on_reverse_breadcrumb, }); }, + "click .o_mail_chat_mobile_tab": '_onMobileTabClick', + "click .o_channel_inbox_item": '_onMobileChannelItemClick', + "click .o_mail_tab_pane_item": '_onMobileTabPaneItemClick', }, on_attach_callback: function () { - chat_manager.bus.trigger('client_action_open', true); + chat_manager.bus.trigger('client_action_open', !this.isMobile); if (this.channel) { this.thread.scroll_to({offset: this.channels_scrolltop[this.channel.id]}); } @@ -174,6 +178,8 @@ var ChatAction = Widget.extend(ControlPanelMixin, { this.notification_bar = (window.Notification && window.Notification.permission === "default"); this.selected_message = null; this.composerStates = {}; + this.isMobile = config.isMobile; + this.activeMobileTab = "channel_inbox"; }, willStart: function () { @@ -196,29 +202,26 @@ var ChatAction = Widget.extend(ControlPanelMixin, { action: this.action, disable_groupby: true, }; - var default_channel_id = this.options.active_id || + var defaultChannelId = this.options.active_id || this.action.context.active_id || this.action.params.default_active_id || 'channel_inbox'; - var default_channel = chat_manager.get_channel(default_channel_id) || + var defaultChannel = chat_manager.get_channel(defaultChannelId) || chat_manager.get_channel('channel_inbox'); - + this.activeMobileTab = defaultChannelId; this.searchview = new SearchView(this, this.dataset, this.fields_view, options); this.basic_composer = new composer.BasicComposer(this, {mention_partners_restricted: true}); this.extended_composer = new composer.ExtendedComposer(this, {mention_partners_restricted: true}); this.thread = new ChatThread(this, { - display_help: true, + display_help: true }); - this.$buttons = $(QWeb.render("mail.chat.ControlButtons", {})); + this.$buttons = $(QWeb.render("mail.chat.ControlButtons", {'debug': session.debug})); this.$buttons.find('button').css({display:"inline-block"}); this.$buttons.on('click', '.o_mail_chat_button_invite', this.on_click_button_invite); this.$buttons.on('click', '.o_mail_chat_button_unsubscribe', this.on_click_button_unsubscribe); this.$buttons.on('click', '.o_mail_chat_button_settings', this.on_click_button_settings); - this.$buttons.on('click', '.o_mail_toggle_channels', function () { - self.$('.o_mail_chat_sidebar').slideToggle(200); - }); this.$buttons.on('click', '.o_mail_chat_button_mark_read', function () { chat_manager.mark_all_as_read(self.channel, self.domain); }); @@ -254,10 +257,13 @@ var ChatAction = Widget.extend(ControlPanelMixin, { self.$searchview_buttons = self.searchview.$buttons.contents(); }); + if (this.isMobile) { + this._initMobileView(); + } this.renderSidebar(); return $.when(def1, def2, def3, def4) - .then(this.set_channel.bind(this, default_channel)) + .then(this.set_channel.bind(this, defaultChannel)) .then(function () { chat_manager.bus.on('open_channel', self, self.set_channel); chat_manager.bus.on('new_message', self, self.on_new_message); @@ -309,7 +315,14 @@ var ChatAction = Widget.extend(ControlPanelMixin, { this.selected_message = null; }, + /** + * Rendering main side bar with channels + */ renderSidebar: function () { + if (this.isMobile) { + this._renderTabPanes(); + } + var self = this; var $sidebar = this._renderSidebar({ active_channel_id: this.channel ? this.channel.id: undefined, @@ -452,27 +465,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, { } // Update control panel - self.set("title", '#' + channel.name); - // Hide 'unsubscribe' button in state channels and DM and channels with group-based subscription - self.$buttons - .find('.o_mail_chat_button_unsubscribe') - .toggle(channel.type !== "dm" && channel.type !== 'static' && ! channel.group_based_subscription); - // Hide 'invite', 'unsubscribe' and 'settings' buttons in static channels and DM - self.$buttons - .find('.o_mail_chat_button_invite, .o_mail_chat_button_settings') - .toggle(channel.type !== "dm" && channel.type !== 'static'); - self.$buttons - .find('.o_mail_chat_button_mark_read') - .toggle(channel.id === "channel_inbox"); - self.$buttons - .find('.o_mail_chat_button_unstar_all') - .toggle(channel.id === "channel_starred"); - - self.$('.o_mail_chat_channel_item') - .removeClass('o_active') - .filter('[data-channel-id=' + channel.id + ']') - .removeClass('o_unread_message') - .addClass('o_active'); + self._updateControlPanelButtons(channel); var $new_messages_separator = self.$('.o_thread_new_messages_separator'); if ($new_messages_separator.length) { @@ -578,7 +571,23 @@ var ChatAction = Widget.extend(ControlPanelMixin, { $searchview_buttons: this.$searchview_buttons, }, searchview: this.searchview, + hidden: this.isMobile }); + + if (this.isMobile) { + var self = this; + var $enable_searchview = $('<button/>', {type: 'button'}) + .addClass('o_enable_searchview btn fa fa-search') + .on('click', function() { + self.searchview_displayed = !self.searchview_displayed; + self.searchview.$el.toggleClass('o_hidden', !self.searchview_displayed); + self.$buttons.toggleClass('o_hidden', self.searchview_displayed); + }); + this.$buttons.appendTo(this.mailMobileControlPanel); + this.searchview.$el.appendTo(this.mailMobileControlPanel); + this.$(".o_enable_searchview").remove(); + $enable_searchview.insertAfter(this.searchview.$el); + } }, do_show: function () { @@ -657,7 +666,11 @@ var ChatAction = Widget.extend(ControlPanelMixin, { on_new_channel: function (channel) { this.renderSidebar(); if (channel.autoswitch) { - this.set_channel(channel); + if (this.isMobile) { + chat_manager.detach_channel(channel); + }else { + this.set_channel(channel); + } } }, on_channel_unsubscribed: function (channel_id) { @@ -698,11 +711,169 @@ var ChatAction = Widget.extend(ControlPanelMixin, { }, //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * Initialize control panel, tabs and panel of tab for mobile + * + * @private + */ + _initMobileView: function () { + this.mailMobileControlPanel = $(QWeb.render("mail.chat.MobileControlPanel",{'widget': this})); + this.mailMobileInboxButtons = $(QWeb.render("mail.chat.MobileInboxStarredButtons", {})); + var mailMobileTabs = $(QWeb.render("mail.chat.MobileTabs",{})); + + this.$(".o_mail_chat_mobile_control_panel").remove(); + this.mailMobileControlPanel.insertAfter(this.$(".o_mail_chat_content")); + this.mailMobileInboxButtons.insertAfter(this.mailMobileControlPanel); + mailMobileTabs.insertAfter(this.$('.o_mail_chat_content')); + }, + /** + * Rendering mobile tab panes with channles and dm messages + * + * @private + */ + _renderTabPanes: function () { + var channels = chat_manager.get_channels(); + var paneChannels = [ + {type: "dm", channels: _.where(channels, {type: "dm"})}, + {type: "public", channels: _.where(channels, {type: "public"})}, + {type: "private", channels: _.where(channels, {type: "private"})} + ]; + var $tabPanes = $(QWeb.render("mail.chat.MobileTabPanes", { + channels: paneChannels, + moment: moment, + widget: this, + get_message_body_preview: chat_manager.get_message_body_preview + })); + this.$(".o_mail_chat_tab_pane").remove(); + $tabPanes.insertAfter(this.$(".o_mail_chat_content")); + + if (this.activeMobileTab == 'channel_inbox' || this.activeMobileTab == 'channel_starred') { + this._switchMobileTab(chat_manager.get_channel(this.activeMobileTab)); + } else { + this._switchMobileTab(false, this.activeMobileTab); + } + }, + /** + * Switching mobile tab and changing style state to active, also showing related tab pane + * for active channel tab + * + * @private + * @param {Object} channel + * @param {string} type Value can be (channel_inbox, channel_starred, dm, public, private) + */ + _switchMobileTab: function(channel, type) { + var title; + this.$(".o_mail_chat_tab_pane").hide(); + this.$(".o_mail_chat_content").hide(); + this.$(".o_mail_chat_buttons").find("button").addClass("o_hidden"); + // Updating control panel buttons + this._updateControlPanelButtons(channel); + if (!type && channel) { + type = channel.id == 'channel_starred' ? 'channel_inbox' : channel.id; + title = "#" + channel.name; + this.$(".o_channel_inbox_item").removeClass("btn-primary").addClass("btn-default"); + this.$(".o_channel_inbox_item[data-type=" + channel.id + "]").removeClass("btn-default").addClass("btn-primary"); + this.$(".o_mail_chat_content").show(); + } else { + this.$(".o_mail_chat_tab_pane[data-type=" + type + "]").show(); + this.$(".o_mail_chat_button_" + type).removeClass("o_hidden"); + } + this.$(".o_mail_chat_mobile_tab").removeClass('active'); + this.$(".o_mail_chat_mobile_tab[data-type=" + type + "]").addClass('active'); + }, + /** + * Updating control panel buttons visibility based on channel type + * + * @private + * @param {Object} channel + */ + _updateControlPanelButtons: function (channel) { + this.set("title", '#' + channel.name); + // Hide 'unsubscribe' button in state channels and DM and channels with group-based subscription + this.$buttons + .find('.o_mail_chat_button_unsubscribe') + .toggle(channel.type !== "dm" && channel.type !== 'static' && ! channel.group_based_subscription); + // Hide 'invite', 'unsubscribe' and 'settings' buttons in static channels and DM + this.$buttons + .find('.o_mail_chat_button_invite, .o_mail_chat_button_settings') + .toggle(channel.type !== "dm" && channel.type !== 'static'); + this.$buttons + .find('.o_mail_chat_button_mark_read') + .toggle(channel.id === "channel_inbox") + .removeClass("o_hidden"); + this.$buttons + .find('.o_mail_chat_button_unstar_all') + .toggle(channel.id === "channel_starred") + .removeClass("o_hidden"); + + this.$('.o_mail_chat_channel_item') + .removeClass('o_active') + .filter('[data-channel-id=' + channel.id + ']') + .removeClass('o_unread_message') + .addClass('o_active'); + }, + + //-------------------------------------------------------------------------- // Handlers //-------------------------------------------------------------------------- /** * @private + * @param {MouseEvent} + */ + _onMobileChannelItemClick: function (event) { + event.preventDefault(); + this.$(".o_channel_inbox_item").toggleClass("btn-primary btn-default"); + var btn = this.$(event.currentTarget); + btn.addClass("btn-primary"); + this.activeMobileTab = btn.data('type'); + var channel = chat_manager.get_channel(this.activeMobileTab); + this._switchMobileTab(channel); + this.set_channel(channel); + }, + /** + * @private + * @param {MouseEvent} + */ + _onMobileTabClick: function (event) { + event.preventDefault(); + var self = this; + var tab = this.$(event.currentTarget); + var type = tab.data('type'); + this.activeMobileTab = type; + if (type == 'channel_inbox' || type == 'channel_starred') { + this.mailMobileInboxButtons.show(); + var channel = chat_manager.get_channel(type); + this._switchMobileTab(channel); + this.set_channel(channel); + } else { + this.mailMobileInboxButtons.hide(); + this._switchMobileTab(false, type); + var typeButton = $(".o_mail_chat_button_" + type); + if (typeButton) { + typeButton.off('click'); + typeButton.on('click', function(event) { + event.preventDefault(); + self.$(".o_mail_add_channel[data-type=" + type + "]").show() + .find("input").focus(); + }); + } + } + }, + /** + * @private + * @param {MouseEvent} + */ + _onMobileTabPaneItemClick: function (event) { + event.preventDefault(); + var channelId = $(event.currentTarget).data("channel-id"); + chat_manager.detach_channel(chat_manager.get_channel(channelId)); + }, + /** + * @private * @param {OdooEvent} */ _onSearch: function (event) { @@ -716,7 +887,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, { }, }); - core.action_registry.add('mail.chat.instant_messaging', ChatAction); +return ChatAction; }); diff --git a/addons/mail/static/src/js/composer.js b/addons/mail/static/src/js/composer.js index 2782ff11442..f6773cc7256 100644 --- a/addons/mail/static/src/js/composer.js +++ b/addons/mail/static/src/js/composer.js @@ -6,6 +6,7 @@ var DocumentViewer = require('mail.DocumentViewer'); var utils = require('mail.utils'); var core = require('web.core'); +var config = require('web.config'); var data = require('web.data'); var dom = require('web.dom'); var session = require('web.session'); @@ -374,6 +375,7 @@ var BasicComposer = Widget.extend(chat_mixin, { send_text: _t('Send'), default_body: '', default_mention_selections: {}, + isMobile: config.isMobile }); this.context = this.options.context; diff --git a/addons/mail/static/src/js/systray.js b/addons/mail/static/src/js/systray.js index 5995c635f33..24f2a247cf4 100644 --- a/addons/mail/static/src/js/systray.js +++ b/addons/mail/static/src/js/systray.js @@ -6,6 +6,7 @@ var framework = require('web.framework'); var session = require('web.session'); var SystrayMenu = require('web.SystrayMenu'); var Widget = require('web.Widget'); +var config = require('web.config'); var chat_manager = require('mail.chat_manager'); @@ -27,6 +28,10 @@ var MessagingMenu = Widget.extend({ "click .o_new_message": "on_click_new_message", "click .o_mail_channel_preview": "_onClickChannel", }, + init: function (parent) { + this.isMobile = config.isMobile; + this._super(parent); + }, start: function () { this.$filter_buttons = this.$('.o_filter_button'); this.$channels_preview = this.$('.o_mail_navbar_dropdown_channels'); diff --git a/addons/mail/static/src/less/chat_window.less b/addons/mail/static/src/less/chat_window.less index 3e93945d194..bafe43e2974 100644 --- a/addons/mail/static/src/less/chat_window.less +++ b/addons/mail/static/src/less/chat_window.less @@ -1,7 +1,8 @@ -@o-chat-window-bg: white; +@o-chat-window-bg: #FAFAFA; @o-chat-window-width: 325px; @o-mail-chatter-gap: 10px; // has to be defined here as this file is both in // backend and other assets (livechat) +@o-chat-header-height: 44px; .o_chat_window { .o-flex-display(); @@ -13,13 +14,14 @@ max-height: 100%; font-size: 12px; background-color: @o-chat-window-bg; - border-radius: 3px 3px 0 0; + border-radius: 6px 6px 0 0; z-index: 3; - box-shadow: -5px -5px 20px fade(black, 28%); + box-shadow: -5px -5px 10px fade(black, 18%); @media (max-width: @screen-xs-max) { width: 100%; height: 100%!important; + box-shadow: none; &.o_folded { display: none; } @@ -37,16 +39,26 @@ border-radius: 3px 3px 0 0; border-bottom: 1px solid @odoo-color-silver-dark; // cannot use gray-lighter-dark as this file is also frontend background-color: @odoo-brand-primary; + padding: 8px; @media (max-width: @screen-xs-max) { - height: @navbar-height; - .o_chat_title, .o_chat_window_close { - font-size: 22px; + height: @o-chat-header-height; + padding-top: 10px; + border-radius: 0px; + .o_chat_title { + font-size: 16px; + margin-left: 10px; + } + + .o_chat_window_close { + font-size: 17px; + color: white; } } .o_chat_title { cursor: pointer; + font-weight: bold; .o-flex(1, 1, auto); .o-text-overflow(); } @@ -68,20 +80,112 @@ overflow: auto; border: 1px solid @odoo-color-silver-dark; // cannot use gray-lighter-dark as this file is also frontend border-width: 0 1px; + font-weight: 400; .o_thread_date_separator { margin-top: 0px; - margin-bottom: 15px; - border-color: lightgray; + margin-bottom: 25px; + border-bottom: 1px dashed #cccccc; .o_thread_date { background-color: @o-chat-window-bg; } } .o_thread_message { .o_thread_message_sidebar { - margin-right: 5px; + margin-right: 10px; + + .o_thread_message_avatar { + border-radius: 4px; + border: 1px solid #ebebeb; + max-width: 40px; + } + } + padding: 4px 5px 0px 10px; + + .o_mail_info { + + .o_thread_author, strong a.o_mail_mailto, strong a.o_mail_mailto:hover { + font-weight: 500; + color: #111; + font-size: 11px; + @media (max-width: @screen-xs-max) { + font-size: 13px; + } + margin-top: 5px; + } + .o_mail_timestamp { + font-size: 11px; + color: #aaa; + } + + .o_thread_message_star { + opacity: 1; + } + + .o_document_link { + display: block; + max-width: 90%; + font-size: 12px; + @media (max-width: @screen-xs-max) { + font-size: 14px; + } + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + padding-bottom: 0px; + font-weight: 500; + } + } + + .o_thread_message_content { + font-size: 12px; + padding-right: 10px; + @media (max-width: @screen-xs-max) { + font-size: 14px; + } + color: #333; + p { + margin: 0px 0px 8px; + } + ul.o_mail_thread_message_tracking { + padding-left: 20px; + } + } + } + } + + .o_chat_composer { + .o-flex(0, 0, auto); + border-left: 1px solid #ebebeb; + border-right: 1px solid #ebebeb; + + .o_composer_buttons > button { + border: none; + } + + .o_composer_button { + display: none; + } + + .o_composer_mobile_button { + display: none; + } + + + @media (max-width: @screen-xs-max) { + .o_composer_mobile_button { + display: inline-block; + background-color: @odoo-brand-optional; + color: #fff; } - padding: 4px 5px; + } + + > input { + padding: 5px; + width: 100%; + } + .o_composer_input > textarea { + border-color: transparent; } } } diff --git a/addons/mail/static/src/less/client_action.less b/addons/mail/static/src/less/client_action.less index 78a4f27f21b..367e791295a 100644 --- a/addons/mail/static/src/less/client_action.less +++ b/addons/mail/static/src/less/client_action.less @@ -6,9 +6,277 @@ .o_mail_chat { .o-position-absolute(0, 0, 0, 0); height: 100%; + overflow: hidden; @media (max-width: @screen-xs-max) { height: auto; + + .o_mail_chat_inbox_starred_button { + position: absolute; + width: 100%; + top: 40px; + padding-left: 15px; + padding-right: 15px; + padding-top: 15px; + padding-bottom: 10px; + text-align: center; + background: #ffffff; + + .o_channel_inbox_item { + width: 50%; + border: 1px solid @odoo-brand-optional; + + &:first-child { + border-radius: 4px 0px 0px 4px; + } + &:last-child { + border-radius: 0px 4px 4px 0px; + } + } + } + + .o_mail_chat_content { + padding-top: 80px; + padding-bottom: 55px; + + .o_mail_no_content { + padding-top: 30px; + display: block; + text-align: center; + margin: auto 0px; + position: absolute; + top: 30%; + width: 100%; + } + } + + .o_mail_chat_mobile_tabs { + display: block !important; + } + + .o_mail_chat_tab_pane { + display: none; + position: relative; + height: 100%; + padding-top: 50px; + padding-bottom: 55px; + overflow-x: scroll; + display: block; + background: #ffffff; + + .o_mail_mobile_add_channel { + width: auto; + padding: 5px 0px; // larger padding-left than titles + position: relative; + margin: 10px; + display: none; + border: 1px solid #afafaf; + border-radius: 4px; + + > input { + width: 100%; + padding: 5px 8px; + padding-left: 20px; + border: none; + } + > span { + position: absolute; + top: 10px; + left: 10px; + } + } + + .o_mail_tab_pane_item { + padding: 15px; + border-bottom: 1px solid #ebebeb; + overflow: hidden; + max-height: 100px; + position: relative; + + &:last-child { + border: none; + } + + .item_avatar_status { + display: inline-block; + position: absolute; + top: 15px; + left: 10px; + width: 55px; + vertical-align: top; + + img { + border-radius: 4px; + max-width: 55px; + } + + .o_mail_user_status { + position: absolute; + bottom: 5px; + right: -8px; + font-size: 13px; + color: #cc0000; + border-radius: 30px; + background: #fff; + padding: 2px; + + &.o_user_online { + color: #21b799; + } + } + } + + .chat_user_detail { + display: inline-block; + width: 100%; + vertical-align: middle; + padding-top: 5px; + padding-left: 65px; + + h2 { + font-size: 17px; + display: block; + font-weight: 500; + margin: 0px; + padding: 0px; + color: #414141; + + small { + float: right; + } + + &.unread { + font-weight: 700; + } + } + + p { + display: inline-block; + color: #b3b3b3; + max-height: 27px; + margin-top: 10px; + overflow: hidden; + line-height: 15px; + + &.unread{ + font-weight: 700; + color: #8f8f8f; + } + } + } + } + } + + .o_mail_chat_mobile_control_panel { + display: block !important; + } + } + + .o_mail_chat_mobile_control_panel { + display: none; + position: absolute; + background: #ffffff; + top: 0px; + left: 0px; + width: 100%; + padding: 5px; + min-height: 44px; + box-shadow: 0px 0px 20px #afafaf; + border-bottom: 1px solid #ebebeb; + height: auto; + z-index: 1; + + .o_mail_channel_title { + padding: 5px 10px 5px 0px; + color: #8f8f8f; + font-size: 14px; + } + + .o_searchview { + color: #414141; + background: none; + border-color: transparent; + padding: 5px 5px 0px 5px; + + .o_searchview_input { + width: 250px; + font-size: 15px; + } + } + + .o_enable_searchview, .o_enable_searchview:focus, + .o_enable_searchview:hover, .o_enable_searchview:active { + color: #414141; + background: none; + border-color: transparent; + display: inline-block; + width: auto; + position: absolute; + right: 5px; + top: 5px; + + &::before { + font-size: 15px; + } + } + .o_searchview_more { + display: none; + } + } + + .o_mail_chat_mobile_tabs { + display: none; + background: #fff; + box-shadow: 0px 0px 20px #afafaf; + position: absolute; + bottom: 0px; + left: 0px; + width: 100%; + + .o_mail_chat_mobile_tab { + display: inline-block; + width: 20%; + height: 100%; + min-height: 100%; + padding: 8px 4px; + text-align: center; + float: left; + + &:first-child:nth-last-child(4), + &:first-child:nth-last-child(4) ~ .o_mail_chat_mobile_tab { + width: 25%; + } + + &:first-child:nth-last-child(5), + &:first-child:nth-last-child(5) ~ .o_mail_chat_mobile_tab { + width: 20%; + } + + &:not(:last-child) { + border-right: 1px solid #d7d7d7; + } + + span { + display: block; + &.fa { + font-size: 16px; + } + + &.o_tab_title{ + font-size: 8px; + padding-top: 8px; + } + } + &.active { + span { + color: @odoo-brand-optional; + } + } + } + } + + .o_mail_chat_tab_pane { + display: none; } .o_mail_annoying_notification_bar { @@ -132,6 +400,8 @@ @media (max-width: @screen-xs-max) { margin-left: 0; + display: block; + overflow-x: scroll; } @media (min-width: @screen-lg-min) { @@ -267,7 +537,6 @@ .o_mail_user_status { font-size: 1em; position: relative; - &.o_user_online { color: @brand-success; } diff --git a/addons/mail/static/src/less/composer.less b/addons/mail/static/src/less/composer.less index e32c1167ac2..8144fb860ee 100644 --- a/addons/mail/static/src/less/composer.less +++ b/addons/mail/static/src/less/composer.less @@ -171,19 +171,21 @@ .o_composer_input { .o-flex-display(); .o-flex-flow(row, nowrap); - padding: @o-mail-chatter-gap; textarea.o_composer_text_field { .o-flex(1, 1, auto); - padding-top: @o-mail-chatter-gap*0.5; } .o_chatter_composer_tools { .o-flex(0, 0, auto); } + @media (max-width: @screen-xs-max) { + .o_composer_button_send { + display: inline-block; + } + } } - - .o_composer_button_send, .o_chatter_avatar, .o_composer_button_add_attachment, .o_composer_attachments_list { + .o_composer_button_send, .o_chatter_avatar { display: none; } } @@ -197,8 +199,8 @@ // Emoji .o_mail_emoji { display: inline-block; - width: 24px; - height: 24px; + height: 20px; + width: 20px; > img { width: 100%; diff --git a/addons/mail/static/src/less/extended_chat_window.less b/addons/mail/static/src/less/extended_chat_window.less index 028befebdf9..618211b7718 100644 --- a/addons/mail/static/src/less/extended_chat_window.less +++ b/addons/mail/static/src/less/extended_chat_window.less @@ -24,4 +24,55 @@ display: none; } } + + .o_chat_composer { + background: #fff; + border-top: 1px solid #d9d9d9; + position: relative; + .o_composer { + .o_composer_input { + display: inline-block; + float: left; + width: 70%; + textarea { + display: block; + padding: 10px; + font-size: 13px; + + @media (max-width: @screen-xs-max) { + padding: 15px 10px; + } + } + } + + .o_chatter_composer_tools { + position: absolute; + right: 0px; + top: 0px; + + button { + padding: 10px; + @media (max-width: @screen-xs-max) { + padding: 13px; + } + &.btn-icon{ + font-size: 1.3em; + } + } + } + } + .o_composer_tabs_toggle_button { + display: none; + } + .o_composer_attachments_list { + margin: 0px; + } + .o_composer_attachments_list, .o_composer_buttons { + .o_composer_button_emoji, .o_composer_button_add_attachment { + &:hover, &:focus { + background-color: #FFFFFF !important; + } + } + } + } } diff --git a/addons/mail/static/src/less/systray.less b/addons/mail/static/src/less/systray.less index 1ecb50989aa..584bda51023 100644 --- a/addons/mail/static/src/less/systray.less +++ b/addons/mail/static/src/less/systray.less @@ -22,11 +22,12 @@ .o_notification_counter { background: @odoo-brand-optional; color: white; - padding: 0em 0.3em; + padding: 0em 0.5em; font-size: 0.7em; - top: 19%; + top: 0px; + right: 0px; position: absolute; - margin: 0px 0px 0px 6px; + margin: 0px; } .o_mail_navbar_dropdown { width: 350px; @@ -45,7 +46,9 @@ .o-flex(0, 0, auto); justify-content: space-between; border-bottom: 1px solid lightgray; - + @media (max-width: @screen-xs-max) { + padding: 5px; + } .o_filter_button, .o_new_message { .btn-link; padding: 5px; @@ -80,6 +83,10 @@ cursor: pointer; font-size: 12px; overflow: hidden; + @media (max-width: @screen-xs-max) { + padding: 10px; + height: 85px; + } &~.o_mail_channel_preview { border-top: 1px solid lightgray; } @@ -93,6 +100,12 @@ .o_channel_image { .o-flex(0, 0, 36px); max-height: 36px; + @media (max-width: @screen-xs-max) { + .o-flex(0, 0, 50px); + border-radius: 3px; + margin-right: 10px; + max-height: 50px; + } } .o_channel_info { .o-flex(1, 1, 100%); @@ -105,6 +118,11 @@ .o-flex(1, 1, auto); .o-text-overflow(); color: @odoo-main-text-color; + @media (max-width: @screen-xs-max) { + font-size: 1.4em; + color: #000; + font-weight: 300; + } } .o_last_message_date { .o-flex(0, 0, auto); @@ -133,9 +151,86 @@ opacity: 0.5; padding: 3px; } + + &.o_mail_navbar_mobile { + position: relative; + + .o_mail_navbar_mobile_header { + padding: 5px 5px 5px 0px; + min-height: 44px; + border-bottom: 1px solid #ccc; + background: #ffffff; + } + + .o_mail_navbar_dropdown_channels { + padding-bottom: 55px; + } + + .o_mail_navbar_mobile_tabs { + background: #fff; + box-shadow: 0px 0px 20px #afafaf; + position: fixed; + bottom: 0px; + left: 0px; + width: 100%; + + .o_mail_navbar_mobile_tab { + display: inline-block; + width: 20%; + height: 100%; + min-height: 100%; + padding: 8px 4px; + text-align: center; + float: left; + font-size: 1.2em; + color: #666666; + + &:first-child:nth-last-child(3), + &:first-child:nth-last-child(3) ~ .o_mail_navbar_mobile_tab { + width: 33.33%; + } + + &:first-child:nth-last-child(4), + &:first-child:nth-last-child(4) ~ .o_mail_navbar_mobile_tab { + width: 25%; + } + + &:first-child:nth-last-child(5), + &:first-child:nth-last-child(5) ~ .o_mail_navbar_mobile_tab { + width: 20%; + } + + &:not(:last-child) { + border-right: 1px solid #d7d7d7; + } + + span { + display: block; + &.fa { + font-size: 16px; + } + + &.o_tab_title{ + font-size: 11px; + padding-top: 8px; + } + } + &.o_selected { + span { + color: @odoo-brand-optional; + } + } + } + } + } } } .o_no_chat_window .o_mail_navbar_dropdown .o_new_message { display: none; // hide 'new message' button if chat windows are disabled } + +// Fix for enterprise nav bar +.o_main_navbar .o_menu_systray .o_notification_counter { + top: 5px; +} diff --git a/addons/mail/static/src/less/thread.less b/addons/mail/static/src/less/thread.less index 16e58a8e285..859e9f32fee 100644 --- a/addons/mail/static/src/less/thread.less +++ b/addons/mail/static/src/less/thread.less @@ -96,6 +96,69 @@ cursor: pointer; } + .o_message_attachments { + display: block; + position: relative; + padding: 0px; + margin: 0px; + + .o_attachment { + width: initial; + height: initial; + + .o_image { + position: initial; + top: initial; + left: initial; + bottom: initial; + right: initial; + } + } + + .o_message_attachment { + display: inline-block; + padding: 5px; + border-radius: 4px; + margin: 5px 5px 5px 5px; + position: relative; + background-color: #cccccc; + + .download_icon { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + span { + background: rgba(0, 0, 0, 0.5); + position: absolute; + top: 37%; + left: 37%; + padding: 5px; + border-radius: 30px; + color: #fff; + } + } + + a.o_image { + width: 80px; + height: 60px; + } + + img { + height: 60px; + width: 80px; + opacity: 0.5; + + &.o_image_view { + cursor: pointer; + background-color: #000; + object-fit: none; + } + } + } + } + .o_thread_message_core { .o-flex(1, 1, auto); min-width: 0; diff --git a/addons/mail/static/src/xml/chat_window.xml b/addons/mail/static/src/xml/chat_window.xml index a9117c76bd6..b8e22e99249 100644 --- a/addons/mail/static/src/xml/chat_window.xml +++ b/addons/mail/static/src/xml/chat_window.xml @@ -41,12 +41,15 @@ </t> <t t-name="mail.ChatWindowHeaderContent"> + <span t-if="isMobile"> + <a href="#" class="o_chat_window_close fa fa-1x fa-arrow-left mr4"/> + </span> <span class="o_chat_title"> <t t-if="status" t-call="mail.chat.UserStatus"/> <t t-esc="title"/> <span t-if="unread_counter"> (<t t-esc="unread_counter"/>)</span> </span> - <span class="o_chat_window_buttons"> + <span t-if="!isMobile" class="o_chat_window_buttons"> <a href="#" class="o_chat_window_close fa fa-close"/> </span> </t> diff --git a/addons/mail/static/src/xml/client_action.xml b/addons/mail/static/src/xml/client_action.xml index b4539dd7bb7..7435914f139 100644 --- a/addons/mail/static/src/xml/client_action.xml +++ b/addons/mail/static/src/xml/client_action.xml @@ -6,7 +6,7 @@ <div class="o_mail_chat"> <div class="o_mail_chat_sidebar"/> <div class="o_mail_chat_content"> - <t t-if="widget.notification_bar"> + <t t-if="widget.notification_bar && !widget.isMobile"> <div class="o_mail_annoying_notification_bar"> <span class="o_mail_request_permission">Odoo needs your permission to <a href="#"> enable desktop notifications</a>.</span> <span class="fa fa-close"></span> @@ -129,13 +129,14 @@ <!-- Buttons of the Control Panel --> <t t-name="mail.chat.ControlButtons"> - <div> - <button type="button" class="btn btn-primary btn-sm o_mail_toggle_channels visible-xs-inline" title="Toggle Channels">Channels</button> + <div class="o_mail_chat_buttons"> <button type="button" class="btn btn-primary btn-sm o_mail_chat_button_invite" title="Invite people">Invite</button> - <button type="button" class="btn btn-default btn-sm o_mail_chat_button_mark_read hidden-xs" title="Mark all as read">Mark all read</button> - <button type="button" class="btn btn-primary btn-sm o_mail_chat_button_unstar_all" title="Unstar all messages">Unstar all</button> + <button type="button" class="btn btn-default btn-sm o_mail_chat_button_mark_read" title="Mark all as read">Mark all read</button> + <button type="button" class="btn btn-default btn-sm o_mail_chat_button_unstar_all" title="Unstar all messages">Unstar all</button> <button type="button" class="btn btn-default btn-sm o_mail_chat_button_unsubscribe" title="Unsubscribe from channel">Unsubscribe</button> - <button type="button" class="btn btn-default btn-sm o_mail_chat_button_settings" title="Open channel settings">Settings</button> + <button type="button" class="btn btn-default btn-sm o_mail_chat_button_dm o_hidden visible-xs" title="New Message">New Message</button> + <button t-if="!disable_add_channel" type="button" class="btn btn-default btn-sm o_mail_chat_button_public o_mail_chat_button_private o_hidden visible-xs" title="New Channel">New Channel</button> + <button t-if="debug" type="button" class="btn btn-default btn-sm o_mail_chat_button_settings" title="Open channel settings">Settings</button> </div> </t> @@ -143,4 +144,87 @@ <div t-name="mail.PartnerInviteDialog"> <input type="text" class="o_input o_mail_chat_partner_invite_input" id="mail_search_partners"/> </div> + + <t t-name="mail.chat.MobileInboxStarredButtons"> + <div class="o_mail_chat_inbox_starred_button"> + <button type="button" class="btn btn-primary btn-sm visible-xs-inline o_channel_inbox_item" title="Inbox" data-type="channel_inbox">Inbox</button><button type="button" class="btn btn-default btn-sm visible-xs-inline o_channel_inbox_item" title="Starred" data-type="channel_starred">Starred</button> + </div> + </t> + + <t t-name="mail.chat.MobileControlPanel"> + <div class="o_mail_chat_mobile_control_panel"/> + </t> + + <t t-name="mail.chat.MobileTabs"> + <div class="o_mail_chat_mobile_tabs"> + <div class="o_mail_chat_mobile_tab" data-channel-id="channel_inbox" data-type="channel_inbox"> + <span class="fa fa-envelope"/> + <span class="o_tab_title">Inbox</span> + </div> + <div class="o_mail_chat_mobile_tab" data-type="dm"> + <span class="fa fa-comments"/> + <span class="o_tab_title">Chat</span> + </div> + <div class="o_mail_chat_mobile_tab" data-type="public"> + <span class="fa fa-users"/> + <span class="o_tab_title">Channels</span> + </div> + <div class="o_mail_chat_mobile_tab" data-type="private"> + <span class="fa fa-lock"/> + <span class="o_tab_title">Private&nbsp;Channels</span> + </div> + </div> + </t> + + <t t-name="mail.chat.MobileTabPanes"> + <t t-foreach="channels" t-as="item"> + <div class="o_mail_chat_tab_pane" t-att-data-type="item.type"> + <div t-if="!disable_add_channel" class="o_mail_add_channel o_mail_mobile_add_channel" t-att-data-type="type"> + <span t-if="type == 'private' || type == 'public'">#</span> + <t t-set="input_placeholder" t-if="type == 'private' || 'public'">Add a channel</t> + <t t-set="input_placeholder" t-if="type == 'dm'">Open chat</t> + <input type="text" t-attf-placeholder="#{input_placeholder}"/> + </div> + <t t-foreach="item.channels" t-as="channel"> + <t t-call="mail.chat.MobileTabPaneItems"> + <t t-set="type" t-value="item.type"/> + </t> + </t> + </div> + </t> + </t> + + <t t-name="mail.chat.MobileTabPaneItems"> + <div class="o_mail_tab_pane_item" t-att-data-channel-id="channel.id"> + <div class="item_avatar_status"> + <img t-if="type == 'dm'" t-att-src="'/web/image/res.partner/'+ channel.direct_partner_id+'/image_small'"/> + <img t-if="type != 'dm'" t-att-src="'/web/image/mail.channel/'+ channel.id+'/image_small'"/> + <i t-if="channel.status == 'online'" class="o_mail_user_status o_user_online fa fa-circle" title="Online"/> + <i t-if="channel.status == 'away'" class="o_mail_user_status o_user_idle fa fa-circle" title="Idle"/> + <i t-if="channel.status == 'offline'" class="o_mail_user_status fa fa-circle" title="Offline"/> + </div> + <t t-set="is_author" t-value="channel.last_message && channel.last_message.author_id[0] == partner_id"/> + <t t-set="is_unread" t-value="channel.last_message && channel.last_seen_message_id < channel.last_message.id && !is_author"/> + <div class="chat_user_detail"> + <h2 t-attf-class="#{is_unread ? 'unread' : ''}"><t t-esc="channel.name"/><small class="o_message_timestamp" t-attf-title="#{channel.last_message ? channel.last_message.date : ''}"><t t-if="channel.last_message" t-esc="moment(channel.last_message.date).fromNow()"/></small></h2> + <p t-attf-class="#{is_unread ? 'unread' : ''}"> + <t t-if="channel.last_message"> + <span t-if="is_author" class="fa fa-mail-reply"/> + <t t-if="channel.last_message" t-raw="get_message_body_preview(channel.last_message.body)"/> + <t t-if="channel.last_message.body == ''"> + <t t-if="channel.last_message.attachment_ids.length != 0"> + <t t-esc="channel.last_message.attachment_ids.length"/> attachment(s) + </t> + <t t-if="channel.last_message.tracking_value_ids and channel.last_message.tracking_value_ids.length > 0"> + <t t-if="channel.last_message.subtype_description"> + <strong><t t-esc="channel.last_message.record_name"/></strong> + : <t t-esc="channel.last_message.subtype_description"/> + </t> + </t> + </t> + </t> + </p> + </div> + </div> + </t> </templates> diff --git a/addons/mail/static/src/xml/composer.xml b/addons/mail/static/src/xml/composer.xml index 68c2730707e..9305728ebfe 100644 --- a/addons/mail/static/src/xml/composer.xml +++ b/addons/mail/static/src/xml/composer.xml @@ -13,6 +13,7 @@ <div class="o_chatter_composer_tools"> <button tabindex="4" class="btn btn-sm btn-icon fa fa-smile-o o_composer_button_emoji" type="button" data-toggle="popover"/> <button tabindex="5" class="btn btn-sm btn-icon fa fa-paperclip o_composer_button_add_attachment" type="button"/> + <button t-if="widget.options.isMobile" tabindex="3" class="btn btn-sm btn-icon fa fa-paper-plane-o o_composer_button_send o_composer_mobile_button" type="button"/> </div> </div> </div> diff --git a/addons/mail/static/src/xml/extended_chat_window.xml b/addons/mail/static/src/xml/extended_chat_window.xml index 5548688d462..865bb7c2968 100644 --- a/addons/mail/static/src/xml/extended_chat_window.xml +++ b/addons/mail/static/src/xml/extended_chat_window.xml @@ -12,7 +12,7 @@ <t t-extend="mail.ChatWindowHeaderContent"> <t t-jquery=".o_chat_window_close" t-operation="before"> - <a href="#" class="o_chat_window_expand fa fa-expand" title=" + <a t-if="!isMobile" href="#" class="o_chat_window_expand fa fa-expand" title=" Open in Discuss"/> </t> </t> diff --git a/addons/mail/static/src/xml/systray.xml b/addons/mail/static/src/xml/systray.xml index 8e7e9b161d4..ebc65ecfe2f 100644 --- a/addons/mail/static/src/xml/systray.xml +++ b/addons/mail/static/src/xml/systray.xml @@ -6,8 +6,13 @@ <a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" title="Conversations" href="#"> <i class="fa fa-comments"/> <span class="o_notification_counter badge"/> </a> - <ul class="o_mail_navbar_dropdown dropdown-menu" role="menu"> - <li class="o_mail_navbar_dropdown_top"> + <ul t-att-class="'o_mail_navbar_dropdown dropdown-menu ' + (widget.isMobile ? 'o_mail_navbar_mobile' : '')" role="menu"> + <li t-if="widget.isMobile"> + <div class="o_mail_navbar_mobile_header"> + <button type="button" class="btn btn-default btn-sm o_new_message"> New message </button> + </div> + </li> + <li t-if="!widget.isMobile" class="o_mail_navbar_dropdown_top"> <div> <button type="button" class="btn btn-sm o_filter_button o_selected"> All </button> <button type="button" class="btn btn-sm o_filter_button" data-filter='chat'> Chat </button> @@ -16,6 +21,22 @@ <button type="button" class="btn btn-sm o_new_message"> New message </button> </li> <li class="o_mail_navbar_dropdown_channels"/> + <li t-if="widget.isMobile"> + <div class="o_mail_navbar_mobile_tabs"> + <div class="o_mail_navbar_mobile_tab o_filter_button o_selected"> + <span class="fa fa-envelope"/> + <span class="o_tab_title">All</span> + </div> + <div class="o_mail_navbar_mobile_tab o_filter_button" data-filter='chat'> + <span class="fa fa-comments"/> + <span class="o_tab_title">Chat</span> + </div> + <div class="o_mail_navbar_mobile_tab o_filter_button" data-filter='channels'> + <span class="fa fa-users"/> + <span class="o_tab_title">Channels</span> + </div> + </div> + </li> </ul> </li> </t> @@ -70,8 +91,8 @@ <span t-if="!activity.overdue_count" class="o_no_activity mr16">0 Late </span> <button t-if="activity.today_count" type="button" class="btn btn-link o_activity_filter_button mr16" t-att-data-res_model="activity.model" t-att-data-model_name="activity.name" data-filter='today'> <t t-esc="activity.today_count"/> Today </button> <span t-if="!activity.today_count" class="o_no_activity mr16">0 Today </span> - <button t-if="activity.planned_count" type="button" class="btn btn-link o_activity_filter_button pull-right mr16" t-att-data-res_model="activity.model" t-att-data-model_name="activity.name" data-filter='upcoming_all'> <t t-esc="activity.planned_count"/> Future </button> - <span t-if="!activity.planned_count" class="o_no_activity pull-right mr16">0 Future</span> + <button t-if="activity.planned_count" type="button" class="btn btn-link o_activity_filter_button pull-right" t-att-data-res_model="activity.model" t-att-data-model_name="activity.name" data-filter='upcoming_all'> <t t-esc="activity.planned_count"/> Future </button> + <span t-if="!activity.planned_count" class="o_no_activity pull-right">0 Future</span> </div> </div> </div> diff --git a/addons/mail/static/src/xml/thread.xml b/addons/mail/static/src/xml/thread.xml index 8237658e99e..054576ed923 100644 --- a/addons/mail/static/src/xml/thread.xml +++ b/addons/mail/static/src/xml/thread.xml @@ -3,10 +3,10 @@ <t t-name="mail.ChatThread"> <t t-if="messages.length"> - <t t-if="options.display_load_more && options.display_order == ORDER.ASC" + <t t-if="options.display_load_more and options.display_order == ORDER.ASC" t-call="mail.ChatThread.LoadMore"/> <t t-call="mail.ChatThread.Content"/> - <t t-if="options.display_load_more && options.display_order == ORDER.DESC" + <t t-if="options.display_load_more and options.display_order == ORDER.DESC" t-call="mail.ChatThread.LoadMore"/> </t> <t t-if="options.display_empty_channel"> @@ -133,22 +133,22 @@ <t t-name="mail.ChatThread.Message"> <div t-att-class="'o_thread_message' + (message.expanded ? ' o_message_expanded ' : ' ') + (message.is_selected ? 'o_thread_selected_message' : '')" t-att-data-message-id="message.id"> <div t-if="options.display_avatar" class="o_thread_message_sidebar"> - <t t-if="!message.mailto && message.author_id[0]"> - <img t-if="message.avatar_src && message.display_author" + <t t-if="!message.mailto and message.author_id[0]"> + <img t-if="message.avatar_src and message.display_author" t-att-src="message.avatar_src" data-oe-model="res.partner" t-att-data-oe-id="message.author_redirect ? message.author_id[0] : ''" t-attf-class="o_thread_message_avatar img-circle #{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" + <img t-if="message.avatar_src and message.display_author" t-att-src="message.avatar_src" class="o_thread_message_avatar img-circle"/> </t> <span t-if="!message.display_author" t-att-title="message.date" class="o_thread_message_side_date"> <t t-esc="message.date.format('hh:mm')"/> </span> - <i t-if="!message.display_author && options.display_stars && message.message_type != 'notification'" + <i t-if="!message.display_author and options.display_stars and message.message_type != 'notification'" t-att-class="'fa o_thread_message_star ' + (message.is_starred ? 'fa-star' : 'fa-star-o')" t-att-data-message-id="message.id" title="Mark as Todo"/> </div> @@ -163,23 +163,23 @@ <t t-esc="message.mailto"/> </a> </strong> - <strong t-if="!message.mailto && message.author_id[0]" + <strong t-if="!message.mailto and message.author_id[0]" data-oe-model="res.partner" t-att-data-oe-id="message.author_redirect ? message.author_id[0] : ''" - t-attf-class="#{message.author_redirect ? 'o_mail_redirect' : ''}"> + t-attf-class="o_thread_author #{message.author_redirect ? 'o_mail_redirect' : ''}"> <t t-esc="message.displayed_author"/> </strong> - <strong t-if="!message.mailto && !message.author_id[0]"> + <strong t-if="!message.mailto and !message.author_id[0]" class="o_thread_author"> <t t-esc="message.displayed_author"/> </strong> - <small class="o_mail_timestamp" t-att-title="message.date"><t t-esc="message.hour"/></small> - <t t-if="message.model && (message.model != 'mail.channel') && options.display_document_link"> - on <a t-att-href="message.url" t-att-data-oe-model="message.model" t-att-data-oe-id="message.res_id"><t t-esc="message.record_name"/></a> + <t t-if="message.model and (message.model != 'mail.channel') and options.display_document_link"> + <a t-att-href="message.url" t-att-data-oe-model="message.model" t-att-data-oe-id="message.res_id" class="o_document_link">on <t t-esc="message.record_name"/></a> </t> - <t t-if="message.origin_id && (message.origin_id !== options.channel_id)"> + <t t-if="message.origin_id and (message.origin_id !== options.channel_id)"> (from <a t-att-data-oe-id="message.origin_id" href="#">#<t t-esc="message.origin_name"/></a>) </t> - <span t-if="options.display_email_icon && message.customer_email_data && message.customer_email_data.length" class="o_thread_tooltip_container"> + <span t-if="options.display_email_icon and message.customer_email_data and message.customer_email_data.length" class="o_thread_tooltip_container"> <i t-att-class="'o_thread_tooltip o_thread_message_email o_thread_message_email_' + message.customer_email_status + ' fa fa-envelope-o'"/> <span class="o_thread_tooltip_content"> <t t-foreach="message.customer_email_data" t-as="customer"> @@ -206,19 +206,21 @@ t-att-data-message-id="message.id" title="Mark as Read"/> </span> </p> - <t t-if="message.tracking_value_ids && message.tracking_value_ids.length > 0"> - <t t-if="message.subtype_description"> - <p t-esc="message.subtype_description"/> + <div class="o_thread_message_content"> + <t t-if="message.tracking_value_ids and message.tracking_value_ids.length > 0"> + <t t-if="message.subtype_description"> + <p><t t-esc="message.subtype_description"/></p> + </t> + <t t-call="mail.ChatThread.MessageTracking"/> </t> - <t t-call="mail.ChatThread.MessageTracking"/> - </t> - <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-raw="message.body"/> - </t> - <t t-foreach="message.attachment_ids" t-as="attachment"> - <t t-call="mail.Attachment"/> - </t> + <p t-if="options.display_subject and message.display_subject" class="o_mail_subject">Subject: <t t-esc="message.subject"/></p> + <t t-if="!(message.tracking_value_ids and message.tracking_value_ids.length > 0)"> + <t t-raw="message.body"/> + </t> + <t t-foreach="message.attachment_ids" t-as="attachment"> + <t t-call="mail.Attachment"/> + </t> + </div> </div> </div> <t t-if="options.messages_separator_position == message.id"> @@ -329,5 +331,4 @@ <button class="btn btn-sm btn-link">-------- Show older messages --------</button> </div> </t> - </templates> |
