diff --git a/web_responsive/__manifest__.py b/web_responsive/__manifest__.py
index ddade9160..2ff39a827 100644
--- a/web_responsive/__manifest__.py
+++ b/web_responsive/__manifest__.py
@@ -6,7 +6,7 @@
{
"name": "Web Responsive",
"summary": "Responsive web client, community-supported",
- "version": "13.0.2.0.1",
+ "version": "13.0.2.1.0",
"category": "Website",
"website": "https://github.com/OCA/web",
"author": "LasLabs, Tecnativa, " "Odoo Community Association (OCA)",
@@ -21,5 +21,6 @@
"static/src/xml/form_view.xml",
"static/src/xml/navbar.xml",
"static/src/xml/document_viewer.xml",
+ "static/src/xml/discuss.xml",
],
}
diff --git a/web_responsive/static/src/js/discuss.js b/web_responsive/static/src/js/discuss.js
new file mode 100644
index 000000000..bf516dfeb
--- /dev/null
+++ b/web_responsive/static/src/js/discuss.js
@@ -0,0 +1,300 @@
+/* Copyright Odoo S.A.
+ * Ported to 13.0 by Copyright 2020 Tecnativa - Alexandre Díaz
+ * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
+
+odoo.define("web_responsive.Discuss", function(require) {
+ "use strict";
+
+ const config = require("web.config");
+ if (!config.device.isMobile) {
+ return;
+ }
+
+ const core = require("web.core");
+ const Discuss = require("mail.Discuss");
+
+ const QWeb = core.qweb;
+
+ Discuss.include({
+ contentTemplate: "mail.discuss_mobile",
+ events: Object.assign({}, Discuss.prototype.events, {
+ "click .o_mail_mobile_tab": "_onClickMobileTab",
+ "click .o_mailbox_inbox_item": "_onClickMobileMailboxItem",
+ "click .o_mail_preview": "_onClickMobileMailPreview",
+ }),
+
+ /**
+ * @override
+ */
+ init: function() {
+ this._super.apply(this, arguments);
+ this._currentState = this._defaultThreadID;
+ },
+
+ /**
+ * @override
+ */
+ start: function() {
+ this._$mainContent = this.$(".o_mail_discuss_content");
+ return this._super
+ .apply(this, arguments)
+ .then(this._updateControlPanel.bind(this));
+ },
+
+ /**
+ * @override
+ */
+ on_attach_callback: function() {
+ if (this._thread && this._isInInboxTab()) {
+ this._threadWidget.scrollToPosition(
+ this._threadsScrolltop[this._thread.getID()]
+ );
+ }
+ },
+ /**
+ * @override
+ */
+ on_detach_callback: function() {
+ if (this._isInInboxTab()) {
+ this._threadsScrolltop[
+ this._thread.getID()
+ ] = this._threadWidget.getScrolltop();
+ }
+ },
+
+ // --------------------------------------------------------------------------
+ // Private
+ // --------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @returns {Boolean} true iff we currently are in the Inbox tab
+ */
+ _isInInboxTab: function() {
+ return _.contains(["mailbox_inbox", "mailbox_starred"], this._currentState);
+ },
+ /**
+ * @override
+ * @private
+ */
+ _renderButtons: function() {
+ this._super.apply(this, arguments);
+ _.each(["dm_chat", "multi_user_channel"], type => {
+ const selector = ".o_mail_discuss_button_" + type;
+ this.$buttons.on("click", selector, this._onAddThread.bind(this));
+ });
+ },
+ /**
+ * Overrides to only store the thread state if we are in the Inbox tab, as
+ * this is the only tab in which we actually have a displayed thread
+ *
+ * @override
+ * @private
+ */
+ _restoreThreadState: function() {
+ if (this._isInInboxTab()) {
+ this._super.apply(this, arguments);
+ }
+ },
+ /**
+ * Overrides to toggle the visibility of the tabs when a message is selected
+ *
+ * @override
+ * @private
+ */
+ _selectMessage: function() {
+ this._super.apply(this, arguments);
+ this.$(".o_mail_mobile_tabs").addClass("o_hidden");
+ },
+ /**
+ * @override
+ * @private
+ */
+ _setThread: function(threadID) {
+ const thread = this.call("mail_service", "getThread", threadID);
+ this._thread = thread;
+ if (thread.getType() !== "mailbox") {
+ this.call("mail_service", "openThreadWindow", threadID);
+ return Promise.resolve();
+ }
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * Overrides to only store the thread state if we are in the Inbox tab, as
+ * this is the only tab in which we actually have a displayed thread
+ *
+ * @override
+ * @private
+ */
+ _storeThreadState: function() {
+ if (this._thread && this._isInInboxTab()) {
+ this._super.apply(this, arguments);
+ }
+ },
+ /**
+ * Overrides to toggle the visibility of the tabs when a message is
+ * unselected
+ *
+ * @override
+ * @private
+ */
+ _unselectMessage: function() {
+ this._super.apply(this, arguments);
+ this.$(".o_mail_mobile_tabs").removeClass("o_hidden");
+ },
+ /**
+ * @override
+ * @private
+ */
+ _updateThreads: function() {
+ return this._updateContent(this._currentState);
+ },
+ /**
+ * Redraws the content of the client action according to its current state.
+ *
+ * @private
+ * @param {String} type the thread's type to display (e.g. 'mailbox_inbox',
+ * 'mailbox_starred', 'dm_chat'...).
+ * @returns {Promise}
+ */
+ _updateContent: function(type) {
+ const inMailbox = type === "mailbox_inbox" || type === "mailbox_starred";
+ if (!inMailbox && this._isInInboxTab()) {
+ // We're leaving the inbox, so store the thread scrolltop
+ this._storeThreadState();
+ }
+ const previouslyInInbox = this._isInInboxTab();
+ this._currentState = type;
+
+ // Fetch content to display
+ let def = false;
+ if (inMailbox) {
+ def = this._fetchAndRenderThread();
+ } else {
+ const allChannels = this.call("mail_service", "getChannels");
+ const channels = _.filter(allChannels, function(channel) {
+ return channel.getType() === type;
+ });
+ def = this.call("mail_service", "getChannelPreviews", channels);
+ }
+ return def.then(previews => {
+ // Update content
+ if (inMailbox) {
+ if (!previouslyInInbox) {
+ this.$(".o_mail_discuss_tab_pane").remove();
+ this._$mainContent.append(this._threadWidget.$el);
+ this._$mainContent.append(this._extendedComposer.$el);
+ }
+ this._restoreThreadState();
+ } else {
+ this._threadWidget.$el.detach();
+ this._extendedComposer.$el.detach();
+ const $content = $(
+ QWeb.render("mail.discuss.MobileTabPane", {
+ previews: previews,
+ type: type,
+ })
+ );
+ this._prepareAddThreadInput(
+ $content.find(".o_mail_add_thread input"),
+ type
+ );
+ this._$mainContent.html($content);
+ }
+
+ // Update control panel
+ this.$buttons
+ .find("button")
+ .removeClass("d-block")
+ .addClass("d-none");
+ this.$buttons
+ .find(".o_mail_discuss_button_" + type)
+ .removeClass("d-none")
+ .addClass("d-block");
+ this.$buttons
+ .find(".o_mail_discuss_button_mark_all_read")
+ .toggleClass("d-none", type !== "mailbox_inbox")
+ .toggleClass("d-block", type === "mailbox_inbox");
+ this.$buttons
+ .find(".o_mail_discuss_button_unstar_all")
+ .toggleClass("d-none", type !== "mailbox_starred")
+ .toggleClass("d-block", type === "mailbox_starred");
+
+ // Update Mailbox page buttons
+ if (inMailbox) {
+ this.$(".o_mail_discuss_mobile_mailboxes_buttons").removeClass(
+ "o_hidden"
+ );
+ this.$(".o_mailbox_inbox_item")
+ .removeClass("btn-primary")
+ .addClass("btn-secondary");
+ this.$(".o_mailbox_inbox_item[data-type=" + type + "]")
+ .removeClass("btn-secondary")
+ .addClass("btn-primary");
+ } else {
+ this.$(".o_mail_discuss_mobile_mailboxes_buttons").addClass(
+ "o_hidden"
+ );
+ }
+
+ // Update bottom buttons
+ this.$(".o_mail_mobile_tab").removeClass("active");
+ // Mailbox_inbox and mailbox_starred share the same tab
+ const type_n = type === "mailbox_starred" ? "mailbox_inbox" : type;
+ this.$(".o_mail_mobile_tab[data-type=" + type_n + "]").addClass(
+ "active"
+ );
+ });
+ },
+
+ // --------------------------------------------------------------------------
+ // Handlers
+ // --------------------------------------------------------------------------
+
+ /**
+ * @override
+ * @private
+ */
+ _onAddThread: function() {
+ this.$(".o_mail_add_thread")
+ .show()
+ .find("input")
+ .focus();
+ },
+ /**
+ * Switches to the clicked thread in the Inbox page (Inbox or Starred).
+ *
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onClickMobileMailboxItem: function(ev) {
+ const mailboxID = $(ev.currentTarget).data("type");
+ this._setThread(mailboxID);
+ this._updateContent(this._thread.getID());
+ },
+ /**
+ * Switches to another tab.
+ *
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onClickMobileTab: function(ev) {
+ const type = $(ev.currentTarget).data("type");
+ if (type === "mailbox") {
+ const inbox = this.call("mail_service", "getMailbox", "inbox");
+ this._setThread(inbox);
+ }
+ this._updateContent(type);
+ },
+ /**
+ * Opens a thread in a chat window (full screen in mobile).
+ *
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onClickMobileMailPreview: function(ev) {
+ const threadID = $(ev.currentTarget).data("preview-id");
+ this.call("mail_service", "openThreadWindow", threadID);
+ },
+ });
+});
diff --git a/web_responsive/static/src/xml/discuss.xml b/web_responsive/static/src/xml/discuss.xml
new file mode 100644
index 000000000..2bf74b5a3
--- /dev/null
+++ b/web_responsive/static/src/xml/discuss.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ btn btn-secondary o_mail_discuss_button_multi_user_channel d-md-block d-none
+
+
+
diff --git a/web_responsive/views/assets.xml b/web_responsive/views/assets.xml
index eba787101..d2d3c23b9 100644
--- a/web_responsive/views/assets.xml
+++ b/web_responsive/views/assets.xml
@@ -19,6 +19,10 @@
type="application/javascript"
src="/web_responsive/static/src/js/web_responsive.js"
/>
+