summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/js
diff options
context:
space:
mode:
authorDharmang Soni <dpr@odoo.com>2017-04-26 10:51:15 +0530
committerAaron Bohy <aab@odoo.com>2017-09-15 15:25:06 +0200
commit4685e4bc7f19f964697bf0dbd7dfdf254b6c5628 (patch)
treeb852d056ac124aa692dff20f468dd62add05b00e /addons/mail/static/src/js
parenta8e7d096b85709ccf52411c450d0574f9238fd6f (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/js')
-rw-r--r--addons/mail/static/src/js/chat_manager.js3
-rw-r--r--addons/mail/static/src/js/chat_window.js13
-rw-r--r--addons/mail/static/src/js/client_action.js237
-rw-r--r--addons/mail/static/src/js/composer.js2
-rw-r--r--addons/mail/static/src/js/systray.js5
5 files changed, 225 insertions, 35 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');