Re-initialize chat components when jid attribute changes

This commit is contained in:
JC Brand 2021-06-04 21:42:22 +02:00
parent 9e4a4ba2ff
commit 90dff612c7
8 changed files with 118 additions and 41 deletions

View File

@ -4,23 +4,25 @@ import { _converse } from '@converse/headless/core';
export default (o) => html`
<div class="flyout box-flyout">
<converse-dragresize></converse-dragresize>
<converse-chat-heading jid="${o.jid}" class="chat-head chat-head-chatbox row no-gutters"></converse-chat-heading>
<div class="chat-body">
<div class="chat-content ${ o.show_send_button ? 'chat-content-sendbutton' : '' }" aria-live="polite">
<converse-chat-content
class="chat-content__messages"
jid="${o.jid}"></converse-chat-content>
${ o.model ? html`
<converse-chat-heading jid="${o.jid}" class="chat-head chat-head-chatbox row no-gutters"></converse-chat-heading>
<div class="chat-body">
<div class="chat-content ${ o.show_send_button ? 'chat-content-sendbutton' : '' }" aria-live="polite">
<converse-chat-content
class="chat-content__messages"
jid="${o.jid}"></converse-chat-content>
${o.show_help_messages ? html`<div class="chat-content__help">
<converse-chat-help
.model=${o.model}
.messages=${o.help_messages}
?hidden=${!o.show_help_messages}
type="info"
chat_type="${_converse.CHATROOMS_TYPE}"
></converse-chat-help></div>` : '' }
${o.show_help_messages ? html`<div class="chat-content__help">
<converse-chat-help
.model=${o.model}
.messages=${o.help_messages}
?hidden=${!o.show_help_messages}
type="info"
chat_type="${_converse.CHATROOMS_TYPE}"
></converse-chat-help></div>` : '' }
</div>
<converse-chat-bottom-panel jid="${o.jid}" class="bottom-panel"> </converse-chat-bottom-panel>
</div>
<converse-chat-bottom-panel jid="${o.jid}" class="bottom-panel"> </converse-chat-bottom-panel>
</div>
` : '' }
</div>
`;

View File

@ -14,8 +14,12 @@ import { _converse, api } from '@converse/headless/core';
export default class ChatView extends BaseChatView {
length = 200
async connectedCallback () {
connectedCallback () {
super.connectedCallback();
this.initialize();
}
async initialize() {
_converse.chatboxviews.add(this.jid, this);
this.model = _converse.chatboxes.get(this.jid);
this.listenTo(_converse, 'windowStateChanged', this.onWindowStateChanged);

View File

@ -1,18 +1,18 @@
import '../heading.js';
import { html } from "lit";
export default (o) => html`
export default (model) => html`
<div class="flyout box-flyout">
<converse-dragresize></converse-dragresize>
<converse-headlines-heading jid="${o.jid}" class="chat-head chat-head-chatbox row no-gutters"></converse-headlines-heading>
<div class="chat-body">
<div class="chat-content ${ o.show_send_button ? 'chat-content-sendbutton' : '' }" aria-live="polite">
<converse-chat-content
class="chat-content__messages"
jid="${o.jid}"></converse-chat-content>
<div class="chat-content__help"></div>
</div>
</div>
${ model ? html`
<converse-headlines-heading jid="${model.get('jid')}" class="chat-head chat-head-chatbox row no-gutters">
</converse-headlines-heading>
<div class="chat-body">
<div class="chat-content" aria-live="polite">
<converse-chat-content
class="chat-content__messages"
jid="${model.get('jid')}"></converse-chat-content>
</div>
</div>` : '' }
</div>
`;

View File

@ -5,8 +5,12 @@ import { _converse, api } from '@converse/headless/core';
class HeadlinesView extends BaseChatView {
async connectedCallback () {
connectedCallback () {
super.connectedCallback();
this.initialize();
}
async initialize() {
_converse.chatboxviews.add(this.jid, this);
this.model = _converse.chatboxes.get(this.jid);
@ -32,12 +36,7 @@ class HeadlinesView extends BaseChatView {
}
render () {
return tpl_headlines(
Object.assign(this.model.toJSON(), {
show_send_button: false,
show_toolbar: false,
})
);
return tpl_headlines(this.model);
}
async close (ev) {

View File

@ -9,8 +9,12 @@ export default class MUCView extends BaseChatView {
length = 300
is_chatroom = true
async connectedCallback () {
connectedCallback () {
super.connectedCallback();
this.initialize();
}
async initialize () {
this.model = await api.rooms.get(this.jid);
_converse.chatboxviews.add(this.jid, this);
this.setAttribute('id', this.model.get('box_id'));
@ -36,7 +40,7 @@ export default class MUCView extends BaseChatView {
}
render () {
return this.model ? tpl_muc({ 'model': this.model }) : '';
return tpl_muc({ 'model': this.model });
}
/**

View File

@ -13,8 +13,10 @@ export default (o) => {
return html`
<div class="flyout box-flyout">
<converse-dragresize></converse-dragresize>
<converse-muc-heading jid="${o.model.get('jid')}" class="chat-head chat-head-chatroom row no-gutters"></converse-muc-heading>
<div class="chat-body chatroom-body row no-gutters">${getChatRoomBodyTemplate(o)}</div>
</div>
`;
${ o.model ? html`
<converse-muc-heading jid="${o.model.get('jid')}" class="chat-head chat-head-chatroom row no-gutters">
</converse-muc-heading>
<div class="chat-body chatroom-body row no-gutters">${getChatRoomBodyTemplate(o)}</div>
` : '' }
</div>`;
}

View File

@ -35,4 +35,60 @@ describe("The <converse-muc> component", function () {
expect(true).toBe(true);
done();
}));
it("will update correctly when the jid property changes",
mock.initConverse([], {'auto_insert': false}, async function (done, _converse) {
const { api } = _converse;
const muc_jid = 'lounge@montague.lit';
const nick = 'romeo';
const muc_creation_promise = await api.rooms.open(muc_jid, {nick, 'hidden': true}, false);
await mock.getRoomFeatures(_converse, muc_jid, []);
await mock.receiveOwnMUCPresence(_converse, muc_jid, nick);
await muc_creation_promise;
const model = _converse.chatboxes.get(muc_jid);
await u.waitUntil(() => (model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED));
const affs = _converse.muc_fetch_members;
const all_affiliations = Array.isArray(affs) ? affs : (affs ? ['member', 'admin', 'owner'] : []);
await mock.returnMemberLists(_converse, muc_jid, [], all_affiliations);
await model.messages.fetched;
model.sendMessage('hello from the lounge!');
const span_el = document.createElement('span');
span_el.classList.add('conversejs');
span_el.classList.add('converse-embedded');
const muc_el = document.createElement('converse-muc');
muc_el.classList.add('chatbox');
muc_el.classList.add('chatroom');
muc_el.setAttribute('jid', muc_jid);
span_el.appendChild(muc_el);
const body = document.querySelector('body');
body.appendChild(span_el);
await u.waitUntil(() => muc_el.querySelector('converse-muc-bottom-panel'));
muc_el.querySelector('.box-flyout').setAttribute('style', 'height: 80vh');
const message = await u.waitUntil(() => muc_el.querySelector('converse-chat-message'));
expect(message.model.get('body')).toBe('hello from the lounge!');
const muc2_jid = 'bar@montague.lit';
const muc2_creation_promise = await api.rooms.open(muc2_jid, {nick, 'hidden': true}, false);
await mock.getRoomFeatures(_converse, muc2_jid, []);
await mock.receiveOwnMUCPresence(_converse, muc2_jid, nick);
await muc2_creation_promise;
const model2 = _converse.chatboxes.get(muc2_jid);
await u.waitUntil(() => (model.session.get('connection_status') === converse.ROOMSTATUS.ENTERED));
await mock.returnMemberLists(_converse, muc2_jid, [], all_affiliations);
await model.messages.fetched;
model2.sendMessage('hello from the bar!');
muc_el.setAttribute('jid', muc2_jid);
await u.waitUntil(() => muc_el.querySelector('converse-chat-message-body').textContent.trim() === 'hello from the bar!');
body.removeChild(span_el);
done();
}));
});

View File

@ -17,6 +17,15 @@ export default class BaseChatView extends CustomElement {
_converse.chatboxviews.remove(this.jid, this);
}
updated () {
if (this.model && this.jid !== this.model.get('jid')) {
this.stopListening();
delete this.model;
this.requestUpdate();
this.initialize();
}
}
maybeFocus () {
api.settings.get('auto_focus') && this.focus();
}
@ -28,6 +37,7 @@ export default class BaseChatView extends CustomElement {
}
return this;
}
emitBlurred (ev) {
if (this.contains(document.activeElement) || this.contains(ev.relatedTarget)) {
// Something else in this chatbox is still focused