From 90dff612c7364585032f571b755aca085b28040c Mon Sep 17 00:00:00 2001 From: JC Brand Date: Fri, 4 Jun 2021 21:42:22 +0200 Subject: [PATCH] Re-initialize chat components when jid attribute changes --- src/plugins/chatview/templates/chat.js | 34 +++++------ src/plugins/chatview/view.js | 6 +- .../headlines-view/templates/headlines.js | 22 ++++---- src/plugins/headlines-view/view.js | 13 ++--- src/plugins/muc-views/muc.js | 8 ++- src/plugins/muc-views/templates/muc.js | 10 ++-- src/plugins/muc-views/tests/component.js | 56 +++++++++++++++++++ src/shared/chat/baseview.js | 10 ++++ 8 files changed, 118 insertions(+), 41 deletions(-) diff --git a/src/plugins/chatview/templates/chat.js b/src/plugins/chatview/templates/chat.js index eacc75aab..754f86401 100644 --- a/src/plugins/chatview/templates/chat.js +++ b/src/plugins/chatview/templates/chat.js @@ -4,23 +4,25 @@ import { _converse } from '@converse/headless/core'; export default (o) => html`
- -
-
- + ${ o.model ? html` + +
+
+ - ${o.show_help_messages ? html`
-
` : '' } + ${o.show_help_messages ? html`
+
` : '' } +
+
- -
+ ` : '' }
`; diff --git a/src/plugins/chatview/view.js b/src/plugins/chatview/view.js index 134505879..d1aa2bfa6 100644 --- a/src/plugins/chatview/view.js +++ b/src/plugins/chatview/view.js @@ -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); diff --git a/src/plugins/headlines-view/templates/headlines.js b/src/plugins/headlines-view/templates/headlines.js index 9f2119ef1..9b5fa8936 100644 --- a/src/plugins/headlines-view/templates/headlines.js +++ b/src/plugins/headlines-view/templates/headlines.js @@ -1,18 +1,18 @@ import '../heading.js'; import { html } from "lit"; -export default (o) => html` +export default (model) => html`
- -
-
- - -
-
-
+ ${ model ? html` + + +
+
+ +
+
` : '' }
`; diff --git a/src/plugins/headlines-view/view.js b/src/plugins/headlines-view/view.js index 7182f5bd8..23e6d8cc1 100644 --- a/src/plugins/headlines-view/view.js +++ b/src/plugins/headlines-view/view.js @@ -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) { diff --git a/src/plugins/muc-views/muc.js b/src/plugins/muc-views/muc.js index 8344d2370..4f2a9f5a1 100644 --- a/src/plugins/muc-views/muc.js +++ b/src/plugins/muc-views/muc.js @@ -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 }); } /** diff --git a/src/plugins/muc-views/templates/muc.js b/src/plugins/muc-views/templates/muc.js index 2667ae1cf..4ac05f2f8 100644 --- a/src/plugins/muc-views/templates/muc.js +++ b/src/plugins/muc-views/templates/muc.js @@ -13,8 +13,10 @@ export default (o) => { return html`
- -
${getChatRoomBodyTemplate(o)}
-
- `; + ${ o.model ? html` + + +
${getChatRoomBodyTemplate(o)}
+ ` : '' } +
`; } diff --git a/src/plugins/muc-views/tests/component.js b/src/plugins/muc-views/tests/component.js index ba5d5c702..f75a1dfac 100644 --- a/src/plugins/muc-views/tests/component.js +++ b/src/plugins/muc-views/tests/component.js @@ -35,4 +35,60 @@ describe("The 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(); + })); }); diff --git a/src/shared/chat/baseview.js b/src/shared/chat/baseview.js index 79814deb3..f56a8b1d6 100644 --- a/src/shared/chat/baseview.js +++ b/src/shared/chat/baseview.js @@ -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