Turn heading into a lit component

This commit is contained in:
JC Brand 2021-06-15 10:33:33 +02:00
parent 8907adc236
commit 969b2f2e11
2 changed files with 56 additions and 50 deletions

View File

@ -1,36 +1,38 @@
import UserDetailsModal from 'modals/user-details.js';
import debounce from 'lodash-es/debounce';
import tpl_chatbox_head from './templates/chat-head.js';
import { ElementView } from '@converse/skeletor/src/element.js';
import { CustomElement } from 'shared/components/element.js';
import { __ } from 'i18n';
import { _converse, api } from "@converse/headless/core";
import { getHeadingDropdownItem, getHeadingStandaloneButton } from 'plugins/chatview/utils.js';
import { render } from 'lit';
import './styles//chat-head.scss';
export default class ChatHeading extends ElementView {
async render () {
const tpl = await this.generateHeadingTemplate();
render(tpl, this);
}
export default class ChatHeading extends CustomElement {
connectedCallback () {
super.connectedCallback();
this.initialize();
}
initialize () {
this.model = _converse.chatboxes.get(this.getAttribute('jid'));
this.debouncedRender = debounce(this.render, 100);
this.listenTo(this.model, 'change:status', this.debouncedRender);
this.listenTo(this.model, 'vcard:change', this.debouncedRender);
this.listenTo(this.model, 'change:status', this.requestUpdate);
this.listenTo(this.model, 'vcard:change', this.requestUpdate);
if (this.model.contact) {
this.listenTo(this.model.contact, 'destroy', this.debouncedRender);
this.listenTo(this.model.contact, 'destroy', this.requestUpdate);
}
this.model.rosterContactAdded?.then(() => {
this.listenTo(this.model.contact, 'change:nickname', this.debouncedRender);
this.debouncedRender();
this.listenTo(this.model.contact, 'change:nickname', this.requestUpdate);
this.requestUpdate();
});
this.render();
}
render () {
return tpl_chatbox_head(Object.assign(this.model.toJSON(), {
'heading_buttons_promise': this.getHeadingButtons(),
'model': this.model,
'showUserDetailsModal': ev => this.showUserDetailsModal(ev),
}));
}
showUserDetailsModal (ev) {
@ -94,33 +96,6 @@ export default class ChatHeading extends ElementView {
return buttons; // Happens during tests
}
}
async generateHeadingTemplate () {
const vcard = this.model?.vcard;
const vcard_json = vcard ? vcard.toJSON() : {};
const i18n_profile = __("The User's Profile Image");
const avatar_data = Object.assign(
{
'alt_text': i18n_profile,
'extra_classes': '',
'height': 40,
'width': 40
},
vcard_json
);
const heading_btns = await this.getHeadingButtons();
const standalone_btns = heading_btns.filter(b => b.standalone);
const dropdown_btns = heading_btns.filter(b => !b.standalone);
return tpl_chatbox_head(
Object.assign(this.model.toJSON(), {
avatar_data,
'display_name': this.model.getDisplayName(),
'dropdown_btns': dropdown_btns.map(b => getHeadingDropdownItem(b)),
'showUserDetailsModal': ev => this.showUserDetailsModal(ev),
'standalone_btns': standalone_btns.map(b => getHeadingStandaloneButton(b))
})
);
}
}
api.elements.define('converse-chat-heading', ChatHeading);

View File

@ -1,13 +1,44 @@
import { __ } from 'i18n';
import { _converse } from '@converse/headless/core';
import { getHeadingDropdownItem, getHeadingStandaloneButton } from 'plugins/chatview/utils.js';
import { html } from "lit";
import { renderAvatar } from 'shared/directives/avatar.js';
import { until } from 'lit/directives/until.js';
export default (o) => {
const tpl_standalone_btns = (o) => o.standalone_btns.reverse().map(b => until(b, ''));
async function getStandaloneButtons (promise) {
const heading_btns = await promise;
const standalone_btns = heading_btns.filter(b => b.standalone);
return standalone_btns.map(b => getHeadingStandaloneButton(b))
}
const avatar = html`<span class="mr-2">${renderAvatar(o.avatar_data)}</span>`;
async function getDropdownButtons (promise) {
const heading_btns = await promise;
const dropdown_btns = heading_btns.filter(b => !b.standalone);
return dropdown_btns.map(b => getHeadingDropdownItem(b));
}
export default (o) => {
const vcard = o.model?.vcard;
const vcard_json = vcard ? vcard.toJSON() : {};
const i18n_profile = __("The User's Profile Image");
const avatar_data = Object.assign(
{
'alt_text': i18n_profile,
'extra_classes': '',
'height': 40,
'width': 40
},
vcard_json
);
const avatar = html`<span class="mr-2">${renderAvatar(avatar_data)}</span>`;
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>` : '');
const tpl_standalone_btns = () => getStandaloneButtons(o.heading_buttons_promise)
.then(btns => btns.reverse().map(b => until(b, '')));
return html`
<div class="chatbox-title ${ o.status ? '' : "chatbox-title--no-desc"}">
@ -15,12 +46,12 @@ export default (o) => {
${ (!_converse.api.settings.get("singleton")) ? html`<converse-controlbox-navback jid="${o.jid}"></converse-controlbox-navback>` : '' }
${ (o.type !== _converse.HEADLINES_TYPE) ? html`<a class="show-msg-author-modal" @click=${o.showUserDetailsModal}>${ avatar }</a>` : '' }
<div class="chatbox-title__text" title="${o.jid}">
${ (o.type !== _converse.HEADLINES_TYPE) ? html`<a class="user show-msg-author-modal" @click=${o.showUserDetailsModal}>${ o.display_name }</a>` : o.display_name }
${ (o.type !== _converse.HEADLINES_TYPE) ? html`<a class="user show-msg-author-modal" @click=${o.showUserDetailsModal}>${ display_name }</a>` : 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.standalone_btns.length ? tpl_standalone_btns(o) : '' }
${ until(tpl_dropdown_btns(), '') }
${ until(tpl_standalone_btns(), '') }
</div>
</div>
${ o.status ? html`<p class="chat-head__desc">${ o.status }</p>` : '' }