浏览代码

Use API to get chat/room models in components

JC Brand 4 年之前
父节点
当前提交
6dea5959cc

+ 12 - 3
src/plugins/chatview/bottom-panel.js

@@ -15,17 +15,26 @@ export default class ChatBottomPanel extends ElementView {
         'click .toggle-clear': 'clearMessages'
     };
 
+    constructor () {
+        super();
+        this.debouncedRender = debounce(this.render, 100);
+    }
+
     async connectedCallback () {
         super.connectedCallback();
-        this.debouncedRender = debounce(this.render, 100);
-        this.model = _converse.chatboxes.get(this.getAttribute('jid'));
+        await this.initialize();
+        this.render(); // don't call in initialize, since the MUCBottomPanel subclasses it
+                       // and we want to render after it has finished as wel.
+    }
+
+    async initialize () {
+        this.model = await api.chatboxes.get(this.getAttribute('jid'));
         await this.model.initialized;
         this.listenTo(this.model, 'change:num_unread', this.debouncedRender)
         this.listenTo(this.model, 'emoji-picker-autocomplete', this.autocompleteInPicker);
 
         this.addEventListener('focusin', ev => this.emitFocused(ev));
         this.addEventListener('focusout', ev => this.emitBlurred(ev));
-        this.render();
     }
 
     render () {

+ 2 - 2
src/plugins/chatview/tests/messages.js

@@ -14,8 +14,7 @@ describe("A Chat Message", function () {
         await mock.openChatBoxFor(_converse, contact_jid);
         const view = _converse.chatboxviews.get(contact_jid);
         await _converse.handleMessageStanza(mock.createChatMessage(_converse, contact_jid, 'This message will be read'));
-        const msg_el = await u.waitUntil(() => view.querySelector('converse-chat-message'));
-        expect(msg_el.querySelector('.chat-msg__text').textContent).toBe('This message will be read');
+        await u.waitUntil(() => view.querySelector('converse-chat-message .chat-msg__text')?.textContent === 'This message will be read');
         expect(view.model.get('num_unread')).toBe(0);
 
         _converse.windowState = 'hidden';
@@ -26,6 +25,7 @@ describe("A Chat Message", function () {
         expect(view.model.get('first_unread_id')).toBe(view.model.messages.last().get('id'));
 
         await u.waitUntil(() => view.querySelectorAll('converse-chat-message').length === 2);
+        await u.waitUntil(() => view.querySelector('converse-chat-message:last-child .chat-msg__text')?.textContent === 'This message will be new');
         const last_msg_el = view.querySelector('converse-chat-message:last-child');
         expect(last_msg_el.firstElementChild?.textContent).toBe('New messages');
         done();

+ 2 - 6
src/plugins/muc-views/bottom-panel.js

@@ -1,6 +1,5 @@
 import 'shared/autocomplete/index.js';
 import BottomPanel from 'plugins/chatview/bottom-panel.js';
-import debounce from 'lodash-es/debounce';
 import tpl_muc_bottom_panel from './templates/muc-bottom-panel.js';
 import { _converse, api, converse } from "@converse/headless/core";
 import { render } from 'lit';
@@ -15,17 +14,14 @@ export default class MUCBottomPanel extends BottomPanel {
         'click .send-button': 'sendButtonClicked',
     }
 
-    async connectedCallback () {
-        // this.model gets set in the super method and we also wait there for this.model.initialized
-        await super.connectedCallback();
-        this.debouncedRender = debounce(this.render, 100);
+    async initialize () {
+        await super.initialize();
         this.listenTo(this.model, 'change:hidden_occupants', this.debouncedRender);
         this.listenTo(this.model, 'change:num_unread_general', this.debouncedRender)
         this.listenTo(this.model.features, 'change:moderated', this.debouncedRender);
         this.listenTo(this.model.occupants, 'add', this.renderIfOwnOccupant)
         this.listenTo(this.model.occupants, 'change:role', this.renderIfOwnOccupant);
         this.listenTo(this.model.session, 'change:connection_status', this.debouncedRender);
-        this.render();
     }
 
     render () {

+ 3 - 3
src/plugins/muc-views/tests/emojis.js

@@ -12,7 +12,7 @@ describe("Emojis", function () {
             const muc_jid = 'lounge@montague.lit';
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
             const view = _converse.chatboxviews.get(muc_jid);
-            await u.waitUntil(() => view.querySelector('converse-emoji-dropdown'));
+            await u.waitUntil(() => view.querySelector('converse-emoji-picker'));
             const textarea = view.querySelector('textarea.chat-textarea');
             textarea.value = ':gri';
 
@@ -80,7 +80,7 @@ describe("Emojis", function () {
             await mock.waitForRoster(_converse, 'current', 0);
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
             const view = _converse.chatboxviews.get(muc_jid);
-            await u.waitUntil(() => view.querySelector('converse-emoji-dropdown'));
+            await u.waitUntil(() => view.querySelector('converse-emoji-picker'));
             const textarea = view.querySelector('textarea.chat-textarea');
             textarea.value = ':';
             // Press tab
@@ -130,7 +130,7 @@ describe("Emojis", function () {
             await mock.waitForRoster(_converse, 'current', 0);
             await mock.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
             const view = _converse.chatboxviews.get(muc_jid);
-            await u.waitUntil(() => view.querySelector('converse-emoji-dropdown'));
+            await u.waitUntil(() => view.querySelector('converse-emoji-picker'));
             const textarea = view.querySelector('textarea.chat-textarea');
             textarea.value = ':gri';
 

+ 12 - 3
src/shared/chat/chat-content.js

@@ -1,6 +1,6 @@
 import './message-history';
 import { CustomElement } from 'shared/components/element.js';
-import { _converse, api } from '@converse/headless/core';
+import { api } from '@converse/headless/core';
 import { html } from 'lit';
 import { markScrolled } from './utils.js';
 
@@ -25,8 +25,8 @@ export default class ChatContent extends CustomElement {
         this.removeEventListener('scroll', markScrolled);
     }
 
-    initialize () {
-        this.model = _converse.chatboxes.get(this.jid);
+    async initialize () {
+        await this.setModels();
         this.listenTo(this.model, 'change:hidden_occupants', this.requestUpdate);
         this.listenTo(this.model.messages, 'add', this.requestUpdate);
         this.listenTo(this.model.messages, 'change', this.requestUpdate);
@@ -43,7 +43,16 @@ export default class ChatContent extends CustomElement {
         this.addEventListener('scroll', markScrolled);
     }
 
+    async setModels () {
+        this.model = await api.chatboxes.get(this.jid);
+        await this.model.initialized;
+        this.requestUpdate();
+    }
+
     render () {
+        if (!this.model) {
+            return '';
+        }
         // This element has "flex-direction: reverse", so elements here are
         // shown in reverse order.
         return html`

+ 25 - 14
src/shared/chat/message.js

@@ -28,23 +28,13 @@ export default class Message extends CustomElement {
         }
     }
 
-    render () {
-        if (this.show_spinner) {
-            return tpl_spinner();
-        } else if (this.model.get('file') && !this.model.get('oob_url')) {
-            return this.renderFileProgress();
-        } else if (['error', 'info'].includes(this.model.get('type'))) {
-            return this.renderInfoMessage();
-        } else {
-            return this.renderChatMessage();
-        }
-    }
-
     connectedCallback () {
         super.connectedCallback();
-        this.chatbox = _converse.chatboxes.get(this.jid);
-        this.model = this.chatbox.messages.get(this.mid);
+        this.initialize();
+    }
 
+    async initialize () {
+        await this.setModels();
         this.listenTo(this.chatbox, 'change:first_unread_id', this.requestUpdate);
         this.listenTo(this.model, 'change', this.requestUpdate);
         this.model.vcard && this.listenTo(this.model.vcard, 'change', this.requestUpdate);
@@ -60,6 +50,27 @@ export default class Message extends CustomElement {
         }
     }
 
+    async setModels () {
+        this.chatbox = await api.chatboxes.get(this.jid);
+        await this.chatbox.initialized;
+        this.model = this.chatbox.messages.get(this.mid);
+        this.requestUpdate();
+    }
+
+    render () {
+        if (!this.model) {
+            return '';
+        } else if (this.show_spinner) {
+            return tpl_spinner();
+        } else if (this.model.get('file') && !this.model.get('oob_url')) {
+            return this.renderFileProgress();
+        } else if (['error', 'info'].includes(this.model.get('type'))) {
+            return this.renderInfoMessage();
+        } else {
+            return this.renderChatMessage();
+        }
+    }
+
     getProps () {
         return Object.assign(
             this.model.toJSON(),