浏览代码

Re-initialize chat components when jid attribute changes

JC Brand 4 年之前
父节点
当前提交
90dff612c7

+ 18 - 16
src/plugins/chatview/templates/chat.js

@@ -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>
 `;

+ 5 - 1
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);

+ 11 - 11
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`
     <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>
 `;

+ 6 - 7
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) {

+ 6 - 2
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 });
     }
 
     /**

+ 6 - 4
src/plugins/muc-views/templates/muc.js

@@ -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>`;
 }

+ 56 - 0
src/plugins/muc-views/tests/component.js

@@ -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();
+    }));
 });

+ 10 - 0
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