diff --git a/addons/im_livechat/static/src/components/discuss/discuss.js b/addons/im_livechat/static/src/components/discuss/discuss.js
deleted file mode 100644
index 2a18e8c1621..00000000000
--- a/addons/im_livechat/static/src/components/discuss/discuss.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/** @odoo-module **/
-
-import { Discuss } from '@mail/components/discuss/discuss';
-
-import { patch } from 'web.utils';
-
-const components = { Discuss };
-
-patch(components.Discuss.prototype, 'im_livechat/static/src/components/discuss/discuss.js', {
-
- //--------------------------------------------------------------------------
- // Public
- //--------------------------------------------------------------------------
-
- /**
- * @override
- */
- mobileNavbarTabs(...args) {
- return [...this._super(...args), {
- icon: 'fa fa-comments',
- id: 'livechat',
- label: this.env._t("Livechat"),
- }];
- }
-
-});
diff --git a/addons/im_livechat/static/src/models/messaging/messaging.js b/addons/im_livechat/static/src/models/messaging/messaging.js
new file mode 100644
index 00000000000..49e116c21f5
--- /dev/null
+++ b/addons/im_livechat/static/src/models/messaging/messaging.js
@@ -0,0 +1,16 @@
+/** @odoo-module **/
+
+import { addFields } from '@mail/model/model_core';
+import { one2many } from '@mail/model/model_field';
+// ensure that the model definition is loaded before the patch
+import '@mail/models/messaging/messaging';
+
+addFields('Messaging', {
+ /**
+ * All pinned livechats that are known.
+ */
+ pinnedLivechats: one2many('Thread', {
+ inverse: 'messagingAsPinnedLivechat',
+ readonly: true,
+ }),
+});
diff --git a/addons/im_livechat/static/src/models/mobile_messaging_navbar_view/mobile_messaging_navbar_view.js b/addons/im_livechat/static/src/models/mobile_messaging_navbar_view/mobile_messaging_navbar_view.js
new file mode 100644
index 00000000000..be26bf92e80
--- /dev/null
+++ b/addons/im_livechat/static/src/models/mobile_messaging_navbar_view/mobile_messaging_navbar_view.js
@@ -0,0 +1,22 @@
+/** @odoo-module **/
+
+import { patchRecordMethods } from '@mail/model/model_core';
+// ensure that the model definition is loaded before the patch
+import '@mail/models/mobile_messaging_navbar_view/mobile_messaging_navbar_view';
+
+patchRecordMethods('MobileMessagingNavbarView', {
+ /**
+ * @override
+ */
+ _computeTabs() {
+ const res = this._super();
+ if (this.messaging.pinnedLivechats.length > 0) {
+ return [...res, {
+ icon: 'fa fa-comments',
+ id: 'livechat',
+ label: this.env._t("Livechat"),
+ }];
+ }
+ return res;
+ },
+});
diff --git a/addons/im_livechat/static/src/models/thread/thread.js b/addons/im_livechat/static/src/models/thread/thread.js
index 1bc92847a5e..8c20a97a34c 100644
--- a/addons/im_livechat/static/src/models/thread/thread.js
+++ b/addons/im_livechat/static/src/models/thread/thread.js
@@ -1,10 +1,34 @@
/** @odoo-module **/
-import { patchModelMethods, patchRecordMethods } from '@mail/model/model_core';
-import { insert, link, unlink } from '@mail/model/model_field_command';
+import { addFields, addRecordMethods, patchModelMethods, patchRecordMethods } from '@mail/model/model_core';
+import { many2one } from '@mail/model/model_field';
+import { clear, insert, link, replace, unlink } from '@mail/model/model_field_command';
// ensure that the model definition is loaded before the patch
import '@mail/models/thread/thread';
+addFields('Thread', {
+ /**
+ * If set, current thread is a livechat.
+ */
+ messagingAsPinnedLivechat: many2one('Messaging', {
+ compute: '_computeMessagingAsPinnedLivechat',
+ inverse: 'pinnedLivechats',
+ }),
+});
+
+addRecordMethods('Thread', {
+ /**
+ * @private
+ * @returns {FieldCommand}
+ */
+ _computeMessagingAsPinnedLivechat() {
+ if (!this.messaging || this.channel_type !== 'livechat' || !this.isPinned) {
+ return clear();
+ }
+ return replace(this.messaging);
+ },
+});
+
patchModelMethods('Thread', {
/**
* @override
diff --git a/addons/mail/static/src/components/discuss/discuss.js b/addons/mail/static/src/components/discuss/discuss.js
index e83ddb1a4c0..352fdc0fb10 100644
--- a/addons/mail/static/src/components/discuss/discuss.js
+++ b/addons/mail/static/src/components/discuss/discuss.js
@@ -21,7 +21,6 @@ export class Discuss extends Component {
useUpdate({ func: () => this._update() });
onWillUnmount(() => this._willUnmount());
this._onHideMobileAddItemHeader = this._onHideMobileAddItemHeader.bind(this);
- this._onSelectMobileNavbarTab = this._onSelectMobileNavbarTab.bind(this);
}
_update() {
@@ -78,25 +77,6 @@ export class Discuss extends Component {
return this.messaging && this.messaging.discuss;
}
- /**
- * @returns {Object[]}
- */
- mobileNavbarTabs() {
- return [{
- icon: 'fa fa-inbox',
- id: 'mailbox',
- label: this.env._t("Mailboxes"),
- }, {
- icon: 'fa fa-user',
- id: 'chat',
- label: this.env._t("Chat"),
- }, {
- icon: 'fa fa-users',
- id: 'channel',
- label: this.env._t("Channel"),
- }];
- }
-
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
@@ -169,33 +149,6 @@ export class Discuss extends Component {
}
}
- /**
- * @private
- * @param {Object} detail
- * @param {string} detail.tabId
- */
- _onSelectMobileNavbarTab(detail) {
- if (this.discuss.activeMobileNavbarTabId === detail.tabId) {
- return;
- }
- this.discuss.update({ activeMobileNavbarTabId: detail.tabId });
- if (
- this.discuss.activeMobileNavbarTabId === 'mailbox' &&
- (!this.discuss.thread || this.discuss.thread.model !== 'mailbox')
- ) {
- this.discuss.update({ thread: link(this.messaging.inbox) });
- }
- if (this.discuss.activeMobileNavbarTabId !== 'mailbox') {
- this.discuss.update({ thread: unlink() });
- }
- if (this.discuss.activeMobileNavbarTabId !== 'chat') {
- this.discuss.update({ isAddingChat: false });
- }
- if (this.discuss.activeMobileNavbarTabId !== 'channel') {
- this.discuss.update({ isAddingChannel: false });
- }
- }
-
}
Object.assign(Discuss, {
diff --git a/addons/mail/static/src/components/discuss/discuss.xml b/addons/mail/static/src/components/discuss/discuss.xml
index c95ef4995e1..6a9a03bc3c1 100644
--- a/addons/mail/static/src/components/discuss/discuss.xml
+++ b/addons/mail/static/src/components/discuss/discuss.xml
@@ -76,12 +76,10 @@
filter="discuss.activeMobileNavbarTabId"
/>
-
+
diff --git a/addons/mail/static/src/components/messaging_menu/messaging_menu.js b/addons/mail/static/src/components/messaging_menu/messaging_menu.js
index 41bf9e654ed..6a6269c258e 100644
--- a/addons/mail/static/src/components/messaging_menu/messaging_menu.js
+++ b/addons/mail/static/src/components/messaging_menu/messaging_menu.js
@@ -23,7 +23,6 @@ export class MessagingMenu extends Component {
this._onMobileNewMessageInputSource = this._onMobileNewMessageInputSource.bind(this);
this._onClickCaptureGlobal = this._onClickCaptureGlobal.bind(this);
this._onHideMobileNewMessage = this._onHideMobileNewMessage.bind(this);
- this._onSelectMobileNavbarTab = this._onSelectMobileNavbarTab.bind(this);
onMounted(() => this._mounted());
onWillUnmount(() => this._willUnmount());
}
@@ -54,25 +53,6 @@ export class MessagingMenu extends Component {
return this.env._t("Search user...");
}
- /**
- * @returns {Object[]}
- */
- get tabs() {
- return [{
- icon: 'fa fa-envelope',
- id: 'all',
- label: this.env._t("All"),
- }, {
- icon: 'fa fa-user',
- id: 'chat',
- label: this.env._t("Chat"),
- }, {
- icon: 'fa fa-users',
- id: 'channel',
- label: this.env._t("Channel"),
- }];
- }
-
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
@@ -171,15 +151,6 @@ export class MessagingMenu extends Component {
});
}
- /**
- * @private
- * @param {Object} detail
- * @param {string} detail.tabId
- */
- _onSelectMobileNavbarTab(detail) {
- this.messagingMenu.update({ activeTabId: detail.tabId });
- }
-
}
Object.assign(MessagingMenu, {
diff --git a/addons/mail/static/src/components/messaging_menu/messaging_menu.xml b/addons/mail/static/src/components/messaging_menu/messaging_menu.xml
index 8ea24d7613c..91ed07d5313 100644
--- a/addons/mail/static/src/components/messaging_menu/messaging_menu.xml
+++ b/addons/mail/static/src/components/messaging_menu/messaging_menu.xml
@@ -54,12 +54,10 @@
classNameObj="{ 'o-mobile': messaging.device.isMobile }"
filter="messagingMenu.activeTabId"
/>
-
+
diff --git a/addons/mail/static/src/components/mobile_messaging_navbar/mobile_messaging_navbar.js b/addons/mail/static/src/components/mobile_messaging_navbar/mobile_messaging_navbar.js
index 98b7dceca18..fd9e5e4854d 100644
--- a/addons/mail/static/src/components/mobile_messaging_navbar/mobile_messaging_navbar.js
+++ b/addons/mail/static/src/components/mobile_messaging_navbar/mobile_messaging_navbar.js
@@ -6,50 +6,20 @@ const { Component } = owl;
export class MobileMessagingNavbar extends Component {
- //--------------------------------------------------------------------------
- // Handlers
- //--------------------------------------------------------------------------
-
/**
- * @private
- * @param {MouseEvent} ev
+ * @returns {MobileMessagingNavbarView}
*/
- _onClick(ev) {
- if (this.props.onSelectMobileMessagingNavbarTab) {
- this.props.onSelectMobileMessagingNavbarTab({
- tabId: ev.currentTarget.dataset.tabId,
- });
- }
+ get mobileMessagingNavbarView() {
+ return this.messaging && this.messaging.models['MobileMessagingNavbarView'].get(this.props.mobileMessagingNavbarViewLocalId);
}
}
Object.assign(MobileMessagingNavbar, {
- defaultProps: {
- tabs: [],
- },
props: {
- activeTabId: String,
- onSelectMobileMessagingNavbarTab: {
- type: Function,
- optional: true,
- },
- tabs: {
- type: Array,
- element: {
- type: Object,
- shape: {
- icon: {
- type: String,
- optional: true,
- },
- id: String,
- label: String,
- },
- },
- },
+ mobileMessagingNavbarViewLocalId: String,
},
template: 'mail.MobileMessagingNavbar',
});
-registerMessagingComponent(MobileMessagingNavbar, { propsCompareDepth: { tabs: 2 } });
+registerMessagingComponent(MobileMessagingNavbar);
diff --git a/addons/mail/static/src/components/mobile_messaging_navbar/mobile_messaging_navbar.xml b/addons/mail/static/src/components/mobile_messaging_navbar/mobile_messaging_navbar.xml
index 8dd1bd4b31e..7b5d16cade5 100644
--- a/addons/mail/static/src/components/mobile_messaging_navbar/mobile_messaging_navbar.xml
+++ b/addons/mail/static/src/components/mobile_messaging_navbar/mobile_messaging_navbar.xml
@@ -3,13 +3,15 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/addons/mail/static/src/models/discuss/discuss.js b/addons/mail/static/src/models/discuss/discuss.js
index 338be2dfde2..c186f3b0ea1 100644
--- a/addons/mail/static/src/models/discuss/discuss.js
+++ b/addons/mail/static/src/models/discuss/discuss.js
@@ -285,6 +285,20 @@ registerModel({
}
return this.isAddingChat;
},
+ /**
+ * @private
+ * @returns {FieldCommand}
+ */
+ _computeMobileMessagingNavbarView() {
+ if (
+ this.messaging.device &&
+ this.messaging.device.isMobile &&
+ !(this.threadView && this.threadView.replyingToMessageView)
+ ) {
+ return insertAndReplace();
+ }
+ return clear();
+ },
/**
* Only pinned threads are allowed in discuss.
*
@@ -387,6 +401,15 @@ registerModel({
menu_id: attr({
default: null,
}),
+ /**
+ * The navbar view on the discuss app when in mobile and when not
+ * replying to a message from inbox.
+ */
+ mobileMessagingNavbarView: one2one('MobileMessagingNavbarView', {
+ compute: '_computeMobileMessagingNavbarView',
+ inverse: 'discuss',
+ isCausal: true,
+ }),
/**
* Quick search input value in the discuss sidebar (desktop). Useful
* to filter channels and chats based on this input content.
diff --git a/addons/mail/static/src/models/messaging_menu/messaging_menu.js b/addons/mail/static/src/models/messaging_menu/messaging_menu.js
index a0e7b77aa65..73dfa549ad2 100644
--- a/addons/mail/static/src/models/messaging_menu/messaging_menu.js
+++ b/addons/mail/static/src/models/messaging_menu/messaging_menu.js
@@ -1,7 +1,8 @@
/** @odoo-module **/
import { registerModel } from '@mail/model/model_core';
-import { attr, one2many } from '@mail/model/model_field';
+import { attr, one2many, one2one } from '@mail/model/model_field';
+import { clear, insertAndReplace } from '@mail/model/model_field_command';
registerModel({
name: 'MessagingMenu',
@@ -48,6 +49,16 @@ registerModel({
const notificationPemissionCounter = this.messaging.isNotificationPermissionDefault ? 1 : 0;
return inboxCounter + unreadChannelsCounter + notificationGroupsCounter + notificationPemissionCounter;
},
+ /**
+ * @private
+ * @returns {MobileMessagingNavbarView|FieldCommand}
+ */
+ _computeMobileMessagingNavbarView() {
+ if (this.messaging.device && this.messaging.device.isMobile) {
+ return insertAndReplace();
+ }
+ return clear();
+ },
},
fields: {
/**
@@ -77,10 +88,18 @@ registerModel({
isOpen: attr({
default: false,
}),
+ /**
+ * The navbar view on the messaging menu when in mobile.
+ */
+ mobileMessagingNavbarView: one2one('MobileMessagingNavbarView', {
+ compute: '_computeMobileMessagingNavbarView',
+ inverse: 'messagingMenu',
+ isCausal: true,
+ }),
/**
* States all the pinned channels that have unread messages.
*/
- pinnedAndUnreadChannels: one2many('Thread', {
+ pinnedAndUnreadChannels: one2many('Thread', {
inverse: 'messagingMenuAsPinnedAndUnreadChannel',
readonly: true,
}),
diff --git a/addons/mail/static/src/models/mobile_messaging_navbar_view/mobile_messaging_navbar_view.js b/addons/mail/static/src/models/mobile_messaging_navbar_view/mobile_messaging_navbar_view.js
new file mode 100644
index 00000000000..4146aed094a
--- /dev/null
+++ b/addons/mail/static/src/models/mobile_messaging_navbar_view/mobile_messaging_navbar_view.js
@@ -0,0 +1,120 @@
+/** @odoo-module **/
+
+import { registerModel } from '@mail/model/model_core';
+import { attr, one2one } from '@mail/model/model_field';
+import { clear, replace } from '@mail/model/model_field_command';
+
+registerModel({
+ name: 'MobileMessagingNavbarView',
+ identifyingFields: [['discuss', 'messagingMenu']],
+ recordMethods: {
+ /**
+ * @param {string} tabId
+ */
+ onClick(tabId) {
+ if (this.discuss) {
+ if (this.discuss.activeMobileNavbarTabId === tabId) {
+ return;
+ }
+ this.discuss.update({ activeMobileNavbarTabId: tabId });
+ if (
+ this.discuss.activeMobileNavbarTabId === 'mailbox' &&
+ (!this.discuss.thread || this.discuss.thread.model !== 'mailbox')
+ ) {
+ this.discuss.update({ thread: replace(this.messaging.inbox) });
+ }
+ if (this.discuss.activeMobileNavbarTabId !== 'mailbox') {
+ this.discuss.update({ thread: clear() });
+ }
+ if (this.discuss.activeMobileNavbarTabId !== 'chat') {
+ this.discuss.update({ isAddingChat: false });
+ }
+ if (this.discuss.activeMobileNavbarTabId !== 'channel') {
+ this.discuss.update({ isAddingChannel: false });
+ }
+ }
+ if (this.messagingMenu) {
+ this.messagingMenu.update({ activeTabId: tabId });
+ }
+ },
+ /**
+ * @private
+ * @returns {string|FieldCommand}
+ */
+ _computeActiveTabId() {
+ if (this.discuss) {
+ return this.discuss.activeMobileNavbarTabId;
+ }
+ if (this.messagingMenu) {
+ return this.messagingMenu.activeTabId;
+ }
+ return clear();
+ },
+ /**
+ * @private
+ * @returns {Object[]}
+ */
+ _computeTabs() {
+ if (this.discuss) {
+ return [{
+ icon: 'fa fa-inbox',
+ id: 'mailbox',
+ label: this.env._t("Mailboxes"),
+ }, {
+ icon: 'fa fa-user',
+ id: 'chat',
+ label: this.env._t("Chat"),
+ }, {
+ icon: 'fa fa-users',
+ id: 'channel',
+ label: this.env._t("Channel"),
+ }];
+ }
+ if (this.messagingMenu) {
+ return [{
+ icon: 'fa fa-envelope',
+ id: 'all',
+ label: this.env._t("All"),
+ }, {
+ icon: 'fa fa-user',
+ id: 'chat',
+ label: this.env._t("Chat"),
+ }, {
+ icon: 'fa fa-users',
+ id: 'channel',
+ label: this.env._t("Channel"),
+ }];
+ }
+ return [];
+ },
+ },
+ fields: {
+ /**
+ * Tab selected in this navbar.
+ * Either 'all', 'mailbox', 'chat' or 'channel'.
+ */
+ activeTabId: attr({
+ compute: '_computeActiveTabId',
+ }),
+ discuss: one2one('Discuss', {
+ inverse: 'mobileMessagingNavbarView',
+ readonly: true,
+ }),
+ messagingMenu: one2one('MessagingMenu', {
+ inverse: 'mobileMessagingNavbarView',
+ readonly: true,
+ }),
+ /**
+ * Ordered list of tabs that this navbar has.
+ * Format of tab:
+ * {
+ * icon:
+ * id:
+ * label:
+ * }
+ */
+ tabs: attr({
+ compute: '_computeTabs',
+ }),
+ },
+});