diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/mail/static/src/components/chat_window_hidden_menu | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/mail/static/src/components/chat_window_hidden_menu')
3 files changed, 262 insertions, 0 deletions
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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates xml:space="preserve"> + + <t t-name="mail.ChatWindowHiddenMenu" owl="1"> + <div class="dropup o_ChatWindowHiddenMenu"> + <div class="dropdown-toggle o_ChatWindowHiddenMenu_dropdownToggle" t-att-class="{ show: env.messaging.chatWindowManager.isHiddenMenuOpen }" t-on-click="_onClickToggle"> + <div class="fa fa-comments-o o_ChatWindowHiddenMenu_dropdownToggleIcon o_ChatWindowHiddenMenu_dropdownToggleItem"/> + <div class="o_ChatWindowHiddenMenu_dropdownToggleItem o_ChatWindowHiddenMenu_windowCounter"> + <t t-esc="env.messaging.chatWindowManager.allOrderedHidden.length"/> + </div> + </div> + <ul class="dropdown-menu dropdown-menu-right o_ChatWindowHiddenMenu_list" t-att-class="{ show: env.messaging.chatWindowManager.isHiddenMenuOpen }" role="menu" t-ref="list"> + <t t-foreach="env.messaging.chatWindowManager.allOrderedHidden" t-as="chatWindow" t-key="chatWindow.localId"> + <li class="o_ChatWindowHiddenMenu_listItem" role="menuitem"> + <ChatWindowHeader + class="o_ChatWindowHiddenMenu_chatWindowHeader" + chatWindowLocalId="chatWindow.localId" + t-on-o-clicked="_onClickedChatWindow" + /> + </li> + </t> + </ul> + <t t-if="env.messaging.chatWindowManager.unreadHiddenConversationAmount > 0"> + <div class="badge badge-pill o_ChatWindowHiddenMenu_unreadCounter"> + <t t-esc="env.messaging.chatWindowManager.unreadHiddenConversationAmount"/> + </div> + </t> + </div> + </t> + +</templates> |
