From 3751379f1e9a4c215fb6eb898b4ccc67659b9ace Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 10 May 2022 21:51:50 +0700 Subject: initial commit 2 --- .../chat_window_hidden_menu.js | 141 +++++++++++++++++++++ .../chat_window_hidden_menu.scss | 90 +++++++++++++ .../chat_window_hidden_menu.xml | 31 +++++ 3 files changed, 262 insertions(+) create mode 100644 addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.js create mode 100644 addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.scss create mode 100644 addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.xml (limited to 'addons/mail/static/src/components/chat_window_hidden_menu') diff --git a/addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.js b/addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.js new file mode 100644 index 00000000..926ca083 --- /dev/null +++ b/addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.js @@ -0,0 +1,141 @@ +odoo.define('mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.js', function (require) { +'use strict'; + +const components = { + ChatWindowHeader: require('mail/static/src/components/chat_window_header/chat_window_header.js'), +}; +const useShouldUpdateBasedOnProps = require('mail/static/src/component_hooks/use_should_update_based_on_props/use_should_update_based_on_props.js'); +const useStore = require('mail/static/src/component_hooks/use_store/use_store.js'); + +const { Component } = owl; +const { useRef } = owl.hooks; + +class ChatWindowHiddenMenu extends Component { + + /** + * @override + */ + constructor(...args) { + super(...args); + useStore(props => { + const chatWindowManager = this.env.messaging.chatWindowManager; + const device = this.env.messaging.device; + const locale = this.env.messaging.locale; + return { + chatWindowManager: chatWindowManager ? chatWindowManager.__state : undefined, + device: device ? device.__state : undefined, + localeTextDirection: locale ? locale.textDirection : undefined, + }; + }); + this._onClickCaptureGlobal = this._onClickCaptureGlobal.bind(this); + /** + * Reference of the dropup list. Useful to auto-set max height based on + * browser screen height. + */ + this._listRef = useRef('list'); + /** + * The intent of the toggle button depends on the last rendered state. + */ + this._wasMenuOpen; + } + + mounted() { + this._apply(); + document.addEventListener('click', this._onClickCaptureGlobal, true); + } + + patched() { + this._apply(); + } + + willUnmount() { + document.removeEventListener('click', this._onClickCaptureGlobal, true); + } + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + */ + _apply() { + this._applyListHeight(); + this._applyOffset(); + this._wasMenuOpen = this.env.messaging.chatWindowManager.isHiddenMenuOpen; + } + + /** + * @private + */ + _applyListHeight() { + const device = this.env.messaging.device; + const height = device.globalWindowInnerHeight / 2; + this._listRef.el.style['max-height'] = `${height}px`; + } + + /** + * @private + */ + _applyOffset() { + const textDirection = this.env.messaging.locale.textDirection; + const offsetFrom = textDirection === 'rtl' ? 'left' : 'right'; + const oppositeFrom = offsetFrom === 'right' ? 'left' : 'right'; + const offset = this.env.messaging.chatWindowManager.visual.hidden.offset; + this.el.style[offsetFrom] = `${offset}px`; + this.el.style[oppositeFrom] = 'auto'; + } + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Closes the menu when clicking outside. + * Must be done as capture to avoid stop propagation. + * + * @private + * @param {MouseEvent} ev + */ + _onClickCaptureGlobal(ev) { + if (this.el.contains(ev.target)) { + return; + } + this.env.messaging.chatWindowManager.closeHiddenMenu(); + } + + /** + * @private + * @param {MouseEvent} ev + */ + _onClickToggle(ev) { + if (this._wasMenuOpen) { + this.env.messaging.chatWindowManager.closeHiddenMenu(); + } else { + this.env.messaging.chatWindowManager.openHiddenMenu(); + } + } + + /** + * @private + * @param {CustomEvent} ev + * @param {Object} ev.detail + * @param {mail.chat_window} ev.detail.chatWindow + */ + _onClickedChatWindow(ev) { + const chatWindow = ev.detail.chatWindow; + chatWindow.makeActive(); + this.env.messaging.chatWindowManager.closeHiddenMenu(); + } + +} + +Object.assign(ChatWindowHiddenMenu, { + components, + props: {}, + template: 'mail.ChatWindowHiddenMenu', +}); + +return ChatWindowHiddenMenu; + +}); diff --git a/addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.scss b/addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.scss new file mode 100644 index 00000000..119d6184 --- /dev/null +++ b/addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.scss @@ -0,0 +1,90 @@ +// ------------------------------------------------------------------ +// Layout +// ------------------------------------------------------------------ + +.o_ChatWindowHiddenMenu { + position: fixed; + bottom: 0; + display: flex; + width: 50px; + height: 28px; + align-items: stretch; +} + +.o_ChatWindowHiddenMenu_chatWindowHeader { + max-width: 200px; +} + +.o_ChatWindowHiddenMenu_dropdownToggle { + display: flex; + align-items: center; + justify-content: center; + flex: 1 1 auto; + max-width: 100%; +} + +.o_ChatWindowHiddenMenu_dropdownToggleIcon { + margin-right: 1px; +} + +.o_ChatWindowHiddenMenu_dropdownToggleItem { + margin: 0 3px; +} + +.o_ChatWindowHiddenMenu_list { + overflow: auto; + margin: 0; + padding: 0; +} + +.o_ChatWindowHiddenMenu_listItem { + + &:not(:last-child) { + margin-bottom: 1px; + } +} + +.o_ChatWindowHiddenMenu_unreadCounter { + position: absolute; + right: 0; + top: 0; + transform: translate(50%, -50%); + z-index: 1001; // on top of bootstrap dropup menu +} + +.o_ChatWindowHiddenMenu_windowCounter { + overflow: hidden; + text-overflow: ellipsis; + margin-left: 1px; +} + +// ------------------------------------------------------------------ +// Style +// ------------------------------------------------------------------ + +.o_ChatWindowHiddenMenu { + background-color: gray('900'); + border-radius: 6px 6px 0 0; + color: white; + cursor: pointer; +} + +.o_ChatWindowHiddenMenu_chatWindowHeader { + opacity: 0.95; + + &:hover { + opacity: 1; + } +} + +.o_ChatWindowHiddenMenu_dropdownToggle.show { + opacity: 0.5; +} + +.o_ChatWindowHiddenMenu_unreadCounter { + background-color: $o-brand-primary; +} + +.o_ChatWindowHiddenMenu_windowCounter { + user-select: none; +} diff --git a/addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.xml b/addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.xml new file mode 100644 index 00000000..943fc71d --- /dev/null +++ b/addons/mail/static/src/components/chat_window_hidden_menu/chat_window_hidden_menu.xml @@ -0,0 +1,31 @@ + + + + +
+ + + + -- cgit v1.2.3