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.
This commit is contained in:
JC Brand 2021-07-01 15:02:00 +02:00
parent e675c853f3
commit 3d8852950d
10 changed files with 31 additions and 20 deletions

View File

@ -35,7 +35,7 @@ export default (o) => {
const display_name = o.model.getDisplayName();
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)
.then(btns => btns.reverse().map(b => until(b, '')));

View File

@ -12,7 +12,7 @@ export default (o) => {
<div class="chatbox-title__text" title="${o.jid}">${ o.display_name }</div>
</div>
<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) : '' }
</div>
</div>

View File

@ -20,7 +20,7 @@ export default (o) => {
</div>
<div class="chatbox-title__buttons row no-gutters">
${ 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>
${ show_subject ? html`<p class="chat-head__desc" title="${i18n_hide_topic}">

View File

@ -15,6 +15,7 @@ class MessageActions extends CustomElement {
correcting: { type: Boolean },
editable: { type: Boolean },
hide_url_previews: { type: Boolean },
is_newest_message: { type: Boolean },
is_retracted: { type: Boolean },
message_type: { type: String },
model: { type: Object },
@ -30,7 +31,9 @@ class MessageActions extends CustomElement {
const buttons = await this.getActionButtons();
const items = buttons.map(b => MessageActions.getActionsDropdownItem(b));
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 {
return '';
}

View File

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

View File

@ -36,10 +36,11 @@ export default (el, o) => {
</div>
<converse-message-actions
.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}"
message_type="${o.message_type}"></converse-message-actions>
</div>

View File

@ -55,7 +55,7 @@ export class ChatToolbar extends CustomElement {
if (this.show_emoji_button) {
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) {

View File

@ -17,13 +17,11 @@ export default class Dropdown extends DropdownBase {
render () {
const icon_classes = this.icon_classes || "fa fa-bars";
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>
`;
}

View File

@ -19,10 +19,9 @@ export default class DropdownBase extends CustomElement {
firstUpdated () {
super.firstUpdated();
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) {

View File

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