Browse Source

Add ability to let dropdown appear at the top, left-aligned

And use that for the last message in the chat history, otherwise the
dropdown is obscured.
JC Brand 4 years ago
parent
commit
3d8852950d

+ 1 - 1
src/plugins/chatview/templates/chat-head.js

@@ -35,7 +35,7 @@ export default (o) => {
     const display_name = o.model.getDisplayName();
     const display_name = o.model.getDisplayName();
 
 
     const tpl_dropdown_btns = () => getDropdownButtons(o.heading_buttons_promise)
     const tpl_dropdown_btns = () => getDropdownButtons(o.heading_buttons_promise)
-        .then(btns => btns.length ? html`<converse-dropdown .items=${btns}></converse-dropdown>` : '');
+        .then(btns => btns.length ? html`<converse-dropdown class="dropleft" .items=${btns}></converse-dropdown>` : '');
 
 
     const tpl_standalone_btns = () => getStandaloneButtons(o.heading_buttons_promise)
     const tpl_standalone_btns = () => getStandaloneButtons(o.heading_buttons_promise)
         .then(btns => btns.reverse().map(b => until(b, '')));
         .then(btns => btns.reverse().map(b => until(b, '')));

+ 1 - 1
src/plugins/headlines-view/templates/chat-head.js

@@ -12,7 +12,7 @@ export default (o) => {
                 <div class="chatbox-title__text" title="${o.jid}">${ o.display_name }</div>
                 <div class="chatbox-title__text" title="${o.jid}">${ o.display_name }</div>
             </div>
             </div>
             <div class="chatbox-title__buttons row no-gutters">
             <div class="chatbox-title__buttons row no-gutters">
-                ${ o.dropdown_btns.length ? html`<converse-dropdown .items=${o.dropdown_btns}></converse-dropdown>` : '' }
+                ${ o.dropdown_btns.length ? html`<converse-dropdown class="dropleft" .items=${o.dropdown_btns}></converse-dropdown>` : '' }
                 ${ o.standalone_btns.length ? tpl_standalone_btns(o) : '' }
                 ${ o.standalone_btns.length ? tpl_standalone_btns(o) : '' }
             </div>
             </div>
         </div>
         </div>

+ 1 - 1
src/plugins/muc-views/templates/muc-head.js

@@ -20,7 +20,7 @@ export default (o) => {
             </div>
             </div>
             <div class="chatbox-title__buttons row no-gutters">
             <div class="chatbox-title__buttons row no-gutters">
                 ${ o.standalone_btns.length ? tpl_standalone_btns(o) : '' }
                 ${ o.standalone_btns.length ? tpl_standalone_btns(o) : '' }
-                ${ o.dropdown_btns.length ? html`<converse-dropdown .items=${o.dropdown_btns}></converse-dropdown>` : '' }
+                ${ o.dropdown_btns.length ? html`<converse-dropdown class="dropleft" .items=${o.dropdown_btns}></converse-dropdown>` : '' }
             </div>
             </div>
         </div>
         </div>
         ${ show_subject ? html`<p class="chat-head__desc" title="${i18n_hide_topic}">
         ${ show_subject ? html`<p class="chat-head__desc" title="${i18n_hide_topic}">

+ 4 - 1
src/shared/chat/message-actions.js

@@ -15,6 +15,7 @@ class MessageActions extends CustomElement {
             correcting: { type: Boolean },
             correcting: { type: Boolean },
             editable: { type: Boolean },
             editable: { type: Boolean },
             hide_url_previews: { type: Boolean },
             hide_url_previews: { type: Boolean },
+            is_newest_message: { type: Boolean },
             is_retracted: { type: Boolean },
             is_retracted: { type: Boolean },
             message_type: { type: String },
             message_type: { type: String },
             model: { type: Object },
             model: { type: Object },
@@ -30,7 +31,9 @@ class MessageActions extends CustomElement {
         const buttons = await this.getActionButtons();
         const buttons = await this.getActionButtons();
         const items = buttons.map(b => MessageActions.getActionsDropdownItem(b));
         const items = buttons.map(b => MessageActions.getActionsDropdownItem(b));
         if (items.length) {
         if (items.length) {
-            return html`<converse-dropdown class="chat-msg__actions" .items=${ items }></converse-dropdown>`;
+            return html`<converse-dropdown
+                class="chat-msg__actions ${this.is_newest_message ? 'dropup dropup--left' : 'dropleft'}"
+                .items=${ items }></converse-dropdown>`;
         } else {
         } else {
             return '';
             return '';
         }
         }

+ 1 - 0
src/shared/chat/message.js

@@ -200,6 +200,7 @@ export default class Message extends CustomElement {
     getDerivedMessageProps () {
     getDerivedMessageProps () {
         const format = api.settings.get('time_format');
         const format = api.settings.get('time_format');
         return {
         return {
+            'is_newest_message': this.model === this.model.collection.last(),
             'pretty_time': dayjs(this.model.get('edited') || this.model.get('time')).format(format),
             'pretty_time': dayjs(this.model.get('edited') || this.model.get('time')).format(format),
             'has_mentions': this.hasMentions(),
             'has_mentions': this.hasMentions(),
             'hats': getHats(this.model),
             'hats': getHats(this.model),

+ 5 - 4
src/shared/chat/templates/message.js

@@ -36,10 +36,11 @@ export default (el, o) => {
                     </div>
                     </div>
                     <converse-message-actions
                     <converse-message-actions
                         .model=${el.model}
                         .model=${el.model}
-                        ?correcting="${o.correcting}"
-                        ?editable="${o.editable}"
-                        ?is_retracted="${o.is_retracted}"
-                        ?hide_url_previews="${el.model.get('hide_url_previews')}"
+                        ?correcting=${o.correcting}
+                        ?editable=${o.editable}
+                        ?hide_url_previews=${el.model.get('hide_url_previews')}
+                        ?is_newest_message=${o.is_newest_message}
+                        ?is_retracted=${o.is_retracted}
                         unfurls="${el.model.get('ogp_metadata')?.length}"
                         unfurls="${el.model.get('ogp_metadata')?.length}"
                         message_type="${o.message_type}"></converse-message-actions>
                         message_type="${o.message_type}"></converse-message-actions>
                 </div>
                 </div>

+ 1 - 1
src/shared/chat/toolbar.js

@@ -55,7 +55,7 @@ export class ChatToolbar extends CustomElement {
 
 
         if (this.show_emoji_button) {
         if (this.show_emoji_button) {
             const chatview = _converse.chatboxviews.get(this.model.get('jid'));
             const chatview = _converse.chatboxviews.get(this.model.get('jid'));
-            buttons.push(html`<converse-emoji-dropdown .chatview=${chatview}></converse-dropdown>`);
+            buttons.push(html`<converse-emoji-dropdown .chatview=${chatview}></converse-emoji-dropdown>`);
         }
         }
 
 
         if (this.show_call_button) {
         if (this.show_call_button) {

+ 5 - 7
src/shared/components/dropdown.js

@@ -17,13 +17,11 @@ export default class Dropdown extends DropdownBase {
     render () {
     render () {
         const icon_classes = this.icon_classes || "fa fa-bars";
         const icon_classes = this.icon_classes || "fa fa-bars";
         return html`
         return html`
-            <div class="dropleft">
-                <button type="button" class="btn btn--transparent btn--standalone" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-                    <i class="${icon_classes} only-icon"></i>
-                </button>
-                <div class="dropdown-menu">
-                    ${ this.items.map(b => until(b, '')) }
-                </div>
+            <button type="button" class="btn btn--transparent btn--standalone" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                <i class="${icon_classes} only-icon"></i>
+            </button>
+            <div class="dropdown-menu">
+                ${ this.items.map(b => until(b, '')) }
             </div>
             </div>
         `;
         `;
     }
     }

+ 3 - 4
src/shared/components/dropdownbase.js

@@ -19,10 +19,9 @@ export default class DropdownBase extends CustomElement {
     firstUpdated () {
     firstUpdated () {
         super.firstUpdated();
         super.firstUpdated();
         this.menu = this.querySelector('.dropdown-menu');
         this.menu = this.querySelector('.dropdown-menu');
-        this.dropdown = this.firstElementChild;
-        this.button = this.dropdown.querySelector('button');
-        this.dropdown.addEventListener('click', ev => this.toggleMenu(ev));
-        this.dropdown.addEventListener('keyup', ev => this.handleKeyUp(ev));
+        this.button = this.querySelector('button');
+        this.addEventListener('click', ev => this.toggleMenu(ev));
+        this.addEventListener('keyup', ev => this.handleKeyUp(ev));
     }
     }
 
 
     _clickOutside(ev) {
     _clickOutside(ev) {

+ 9 - 0
src/shared/styles/_core.scss

@@ -10,6 +10,15 @@
     direction: ltr;
     direction: ltr;
     z-index: 1031; // One more than bootstrap navbar
     z-index: 1031; // One more than bootstrap navbar
 
 
+    .dropup {
+        &.dropup--left {
+            .dropdown-menu {
+                right: 100%;
+                left: auto;
+            }
+        }
+    }
+
     textarea:disabled {
     textarea:disabled {
         background-color: #EEE !important;
         background-color: #EEE !important;
     }
     }