[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
This commit is contained in:
committed by
Aaron Bohy
parent
a8e7d096b8
commit
4685e4bc7f
@@ -354,6 +354,11 @@ class Channel(models.Model):
|
||||
.channel_partner_ids
|
||||
.filtered(lambda p: p.id != self.env.user.partner_id.id)
|
||||
.read(['id', 'name', 'im_status']))
|
||||
|
||||
last_message = channel.channel_fetch_preview()
|
||||
if last_message:
|
||||
info['last_message'] = last_message[0].get('last_message')
|
||||
|
||||
# add user session state, if available and if user is logged
|
||||
if partner_channels.ids:
|
||||
partner_channel = partner_channels.filtered(lambda c: channel.id == c.channel_id.id)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
@@ -697,10 +710,168 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// 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}
|
||||
@@ -716,7 +887,7 @@ var ChatAction = Widget.extend(ControlPanelMixin, {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
core.action_registry.add('mail.chat.instant_messaging', ChatAction);
|
||||
|
||||
return ChatAction;
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
> input {
|
||||
padding: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
.o_composer_input > textarea {
|
||||
border-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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%;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
odoo.define('mail.client_action_test', function (require) {
|
||||
"use strict";
|
||||
|
||||
var ActionManager = require('web.ActionManager');
|
||||
var core = require('web.core');
|
||||
var testUtils = require('web.test_utils');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var ChatAction = require("mail.chat_client_action");
|
||||
|
||||
QUnit.module('mail', {}, function () {
|
||||
|
||||
QUnit.module('ChatAction', {
|
||||
beforeEach: function () {
|
||||
this.data = {
|
||||
"mail.message": {
|
||||
fields: {
|
||||
id: {type: 'integer', string: 'ID'}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Mobile Test case
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
QUnit.test('mobile basic rendering', function (assert) {
|
||||
assert.expect(11);
|
||||
|
||||
function createParent (params) {
|
||||
var actionManager = new ActionManager();
|
||||
testUtils.addMockEnvironment(actionManager, params);
|
||||
return actionManager;
|
||||
}
|
||||
|
||||
var action = {
|
||||
id: 1,
|
||||
context: {'active_channel_id': 'channel_inbox', 'active_ids': ['channel_inbox']},
|
||||
params: {'default_active_id': 'channel_inbox'}
|
||||
};
|
||||
|
||||
var parent = createParent({
|
||||
data: {},
|
||||
});
|
||||
|
||||
testUtils.addMockEnvironment(parent, {
|
||||
data: this.data,
|
||||
config: {
|
||||
isMobile: true
|
||||
},
|
||||
archs: {
|
||||
'mail.message,false,search': '<search/>',
|
||||
}
|
||||
});
|
||||
|
||||
var chatAction = new ChatAction(parent, action, {});
|
||||
chatAction.set_cp_bus(new Widget());
|
||||
|
||||
chatAction.appendTo($('#qunit-fixture'));
|
||||
|
||||
// test for basic view rendering for mobile
|
||||
assert.equal(chatAction.$(".o_mail_chat_mobile_control_panel").length, 1, "Mobile control panel created");
|
||||
assert.equal(chatAction.$(".o_mail_chat_mobile_tab").length, 4, "Four mobile tabs created");
|
||||
assert.equal(chatAction.$('.o_mail_chat_content').length, 1, "One default chat content pane created");
|
||||
assert.equal(chatAction.$(".o_mail_chat_tab_pane").length, 3, "Three mobile tab panes created");
|
||||
|
||||
// Inbox
|
||||
assert.equal(chatAction.activeMobileTab, "channel_inbox", "'channel_inbox' is default active tab");
|
||||
assert.ok(chatAction.$(".o_channel_inbox_item:nth(0)").hasClass("btn-primary"), "Showing 'Inbox'");
|
||||
|
||||
// Starred
|
||||
chatAction.mailMobileInboxButtons.find(".o_channel_inbox_item[data-type='channel_starred']").click();
|
||||
assert.ok(chatAction.$(".o_channel_inbox_item:nth(1)").hasClass("btn-primary"), "Clicked on 'Starred'");
|
||||
|
||||
assert.ok(chatAction.$(".o_mail_chat_content").is(":visible"), "Default main content pane visible");
|
||||
|
||||
chatAction.$(".o_mail_chat_mobile_tab[data-type='dm']").click();
|
||||
assert.equal(chatAction.activeMobileTab, "dm", "After click on 'Conversation', is now active tab");
|
||||
|
||||
assert.ok(!chatAction.$(".o_mail_chat_content").is(":visible"), "none", "'Main' content pane is invisible");
|
||||
assert.ok(chatAction.$(".o_mail_chat_tab_pane:nth(0)").is(":visible"), "'Conversation' pane is visible");
|
||||
|
||||
chatAction.destroy();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
<template id="qunit_suite" name="mail_tests" inherit_id="web.qunit_suite">
|
||||
<xpath expr="//t[@t-set='head']" position="inside">
|
||||
<script type="text/javascript" src="/mail/static/tests/client_action_tests.js"></script>
|
||||
<script type="text/javascript" src="/mail/static/tests/chatter_tests.js"></script>
|
||||
<script type="text/javascript" src="/mail/static/tests/systray_tests.js"></script>
|
||||
<script type="text/javascript" src="/mail/static/tests/chat_window_test.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user