Let HeadlinesHeading use CustomElement

This commit is contained in:
JC Brand 2022-06-19 12:36:41 +02:00
parent 7e2dd55c16
commit ba7c6d7a50
7 changed files with 67 additions and 33 deletions

View File

@ -9,8 +9,14 @@ import './styles/chat-head.scss';
export default class ChatHeading extends CustomElement { export default class ChatHeading extends CustomElement {
static get properties () {
return {
'jid': { type: String },
}
}
initialize () { initialize () {
this.model = _converse.chatboxes.get(this.getAttribute('jid')); this.model = _converse.chatboxes.get(this.jid);
this.listenTo(this.model, 'change:status', this.requestUpdate); this.listenTo(this.model, 'change:status', this.requestUpdate);
this.listenTo(this.model, 'vcard:add', this.requestUpdate); this.listenTo(this.model, 'vcard:add', this.requestUpdate);
this.listenTo(this.model, 'vcard:change', this.requestUpdate); this.listenTo(this.model, 'vcard:change', this.requestUpdate);

View File

@ -1,36 +1,31 @@
import tpl_chat_head from './templates/chat-head.js'; import tpl_chat_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 { __ } from 'i18n';
import { _converse, api } from "@converse/headless/core"; import { _converse, api } from "@converse/headless/core.js";
import { getHeadingDropdownItem, getHeadingStandaloneButton } from 'plugins/chatview/utils.js';
import { render } from 'lit';
export default class HeadlinesHeading extends ElementView { export default class HeadlinesHeading extends CustomElement {
async connectedCallback () { static get properties () {
super.connectedCallback(); return {
this.model = _converse.chatboxes.get(this.getAttribute('jid')); 'jid': { type: String },
}
}
async initialize () {
this.model = _converse.chatboxes.get(this.jid);
await this.model.initialized; await this.model.initialized;
this.render(); this.requestUpdate();
} }
async render () { render () {
const tpl = await this.generateHeadingTemplate(); return tpl_chat_head({
render(tpl, this); ...this.model.toJSON(),
} ...{
async generateHeadingTemplate () {
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_chat_head(
Object.assign(this.model.toJSON(), {
'display_name': this.model.getDisplayName(), 'display_name': this.model.getDisplayName(),
'dropdown_btns': dropdown_btns.map(b => getHeadingDropdownItem(b)), 'heading_buttons_promise': this.getHeadingButtons()
'standalone_btns': standalone_btns.map(b => getHeadingStandaloneButton(b)) }
}) });
);
} }
/** /**

View File

@ -1,10 +1,26 @@
import { _converse } from '@converse/headless/core'; import { _converse } from '@converse/headless/core';
import { html } from "lit"; import { html } from "lit";
import { until } from 'lit/directives/until.js'; import { until } from 'lit/directives/until.js';
import { getHeadingDropdownItem, getHeadingStandaloneButton } from 'plugins/chatview/utils.js';
export default (o) => { export default (o) => {
const tpl_standalone_btns = (o) => o.standalone_btns.reverse().map(b => until(b, '')); const standalone_btns_promise = o.heading_buttons_promise.then(
btns => btns
.filter(b => b.standalone)
.map(b => getHeadingStandaloneButton(b))
.reverse()
.map(b => until(b, '')));
const dropdown_btns_promise = o.heading_buttons_promise.then(
btns => {
const dropdown_btns = btns
.filter(b => !b.standalone)
.map(b => getHeadingDropdownItem(b));
return dropdown_btns.length ? html`<converse-dropdown class="dropleft" .items=${dropdown_btns}></converse-dropdown>` : '';
}
);
return html` return html`
<div class="chatbox-title ${ o.status ? '' : "chatbox-title--no-desc"}"> <div class="chatbox-title ${ o.status ? '' : "chatbox-title--no-desc"}">
<div class="chatbox-title--row"> <div class="chatbox-title--row">
@ -12,8 +28,8 @@ 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 class="dropleft" .items=${o.dropdown_btns}></converse-dropdown>` : '' } ${ until(dropdown_btns_promise, '') }
${ o.standalone_btns.length ? tpl_standalone_btns(o) : '' } ${ until(standalone_btns_promise, '') }
</div> </div>
</div> </div>
${ o.status ? html`<p class="chat-head__desc">${ o.status }</p>` : '' } ${ o.status ? html`<p class="chat-head__desc">${ o.status }</p>` : '' }

View File

@ -26,7 +26,9 @@ describe("A headlines box", function () {
.c('nick', {'xmlns': "http://jabber.org/protocol/nick"}).t("-wwdmz").up() .c('nick', {'xmlns': "http://jabber.org/protocol/nick"}).t("-wwdmz").up()
.c('body').t('SORRY FOR THIS ADVERT'); .c('body').t('SORRY FOR THIS ADVERT');
_converse.connection._dataRecv(mock.createRequest(stanza)); _converse.connection._dataRecv(mock.createRequest(stanza));
expect(_converse.api.headlines.get().length === 0); await new Promise(resolve => setTimeout(resolve, 100));
const headlines = await _converse.api.headlines.get();
expect(headlines.length).toBe(0);
})); }));
it("will open and display headline messages", mock.initConverse( it("will open and display headline messages", mock.initConverse(
@ -71,8 +73,8 @@ describe("A headlines box", function () {
await mock.waitForRoster(_converse, 'current', 1); await mock.waitForRoster(_converse, 'current', 1);
await mock.openControlBox(_converse); await mock.openControlBox(_converse);
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit'; const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await mock.openChatBoxFor(_converse, sender_jid); await mock.openChatBoxFor(_converse, sender_jid);
const { u, $msg} = converse.env; const { u, $msg} = converse.env;
/* <message from='notify.example.com' /* <message from='notify.example.com'

View File

@ -75,6 +75,13 @@
color: var(--chatroom-head-color); color: var(--chatroom-head-color);
} }
} }
.chat-head-headline {
background-color: var(--headline-head-bg-color);
a.restore-chat {
color: var(--headline-head-text-color);
}
}
&.minimized { &.minimized {
height: auto; height: auto;
} }

View File

@ -4,7 +4,15 @@ import { __ } from 'i18n';
export default (o) => { export default (o) => {
const i18n_tooltip = __('Click to restore this chat'); const i18n_tooltip = __('Click to restore this chat');
const close_color = o.type === 'chatroom' ? "var(--chatroom-head-color)" : "var(--chat-head-text-color)"; let close_color;
if (o.type === 'chatroom') {
close_color = "var(--chatroom-head-color)";
} else if (o.type === 'headline') {
close_color = "var(--headline-head-text-color)";
} else {
close_color = "var(--chat-head-text-color)";
}
return html` return html`
<div class="chat-head-${o.type} chat-head row no-gutters"> <div class="chat-head-${o.type} chat-head row no-gutters">
<a class="restore-chat w-100 align-self-center" title="${i18n_tooltip}" @click=${o.restore}> <a class="restore-chat w-100 align-self-center" title="${i18n_tooltip}" @click=${o.restore}>

View File

@ -2,7 +2,7 @@ import 'shared/components/icons.js';
import DOMNavigator from "shared/dom-navigator.js"; import DOMNavigator from "shared/dom-navigator.js";
import DropdownBase from 'shared/components/dropdownbase.js'; import DropdownBase from 'shared/components/dropdownbase.js';
import { KEYCODES } from '@converse/headless/shared/constants.js'; import { KEYCODES } from '@converse/headless/shared/constants.js';
import { api } from "@converse/headless/core"; import { api } from "@converse/headless/core.js";
import { html } from 'lit'; import { html } from 'lit';
import { until } from 'lit/directives/until.js'; import { until } from 'lit/directives/until.js';