Przeglądaj źródła

Turn the chats into Lit components

Previously they were of type ElementView from @converse/skeletor

The ElementView component is merely a helper to allow us to eventually
migrate everything to Lit
JC Brand 4 lat temu
rodzic
commit
e3612e8c62

+ 8 - 12
src/plugins/chatview/view.js

@@ -1,30 +1,27 @@
 import 'plugins/chatview/heading.js';
 import 'plugins/chatview/bottom-panel.js';
-import { render } from 'lit';
 import BaseChatView from 'shared/chat/baseview.js';
 import tpl_chat from './templates/chat.js';
 import { __ } from 'i18n';
 import { _converse, api } from '@converse/headless/core';
 
 /**
- * The View of an open/ongoing chat conversation.
+ * The view of an open/ongoing chat conversation.
  * @class
  * @namespace _converse.ChatBoxView
  * @memberOf _converse
  */
 export default class ChatView extends BaseChatView {
     length = 200
-    className = 'chatbox hidden'
 
-    async initialize () {
-        const jid = this.getAttribute('jid');
-        _converse.chatboxviews.add(jid, this);
-        this.model = _converse.chatboxes.get(jid);
+    async connectedCallback () {
+        super.connectedCallback();
+        _converse.chatboxviews.add(this.jid, this);
+        this.model = _converse.chatboxes.get(this.jid);
         this.listenTo(_converse, 'windowStateChanged', this.onWindowStateChanged);
         this.listenTo(this.model, 'change:hidden', () => !this.model.get('hidden') && this.afterShown());
-        this.listenTo(this.model, 'change:show_help_messages', this.render);
+        this.listenTo(this.model, 'change:show_help_messages', this.requestUpdate);
         this.listenTo(this.model, 'change:status', this.onStatusMessageChanged);
-        this.render();
 
         await this.model.messages.fetched;
         !this.model.get('hidden') && this.afterShown()
@@ -37,7 +34,7 @@ export default class ChatView extends BaseChatView {
         api.trigger('chatBoxViewInitialized', this);
     }
 
-    toHTML () {
+    render () {
         return tpl_chat(Object.assign({
             'model': this.model,
             'help_messages': this.getHelpMessages(),
@@ -54,10 +51,9 @@ export default class ChatView extends BaseChatView {
         ];
     }
 
-    showControlBox () {
+    showControlBox () { // eslint-disable-line class-methods-use-this
         // Used in mobile view, to navigate back to the controlbox
         _converse.chatboxviews.get('controlbox')?.show();
-        this.hide();
     }
 
     /**

+ 9 - 18
src/plugins/headlines-view/view.js

@@ -1,28 +1,23 @@
 import BaseChatView from 'shared/chat/baseview.js';
 import tpl_headlines from './templates/headlines.js';
 import { _converse, api } from '@converse/headless/core';
-import { render } from 'lit';
 
 
 class HeadlinesView extends BaseChatView {
 
-    async initialize () {
-        const jid = this.getAttribute('jid');
-        _converse.chatboxviews.add(jid, this);
+    async connectedCallback () {
+        super.connectedCallback();
+        _converse.chatboxviews.add(this.jid, this);
 
-        this.model = _converse.chatboxes.get(jid);
+        this.model = _converse.chatboxes.get(this.jid);
         this.model.disable_mam = true; // Don't do MAM queries for this box
+        this.listenTo(_converse, 'windowStateChanged', this.onWindowStateChanged);
         this.listenTo(this.model, 'change:hidden', () => this.afterShown());
         this.listenTo(this.model, 'destroy', this.remove);
         this.listenTo(this.model, 'show', this.show);
-        this.listenTo(_converse, 'windowStateChanged', this.onWindowStateChanged);
-
-        this.render();
-
-        // Need to be registered after render has been called.
-        this.listenTo(this.model.messages, 'add', this.onMessageAdded);
-        this.listenTo(this.model.messages, 'remove', this.renderChatHistory);
-        this.listenTo(this.model.messages, 'reset', this.renderChatHistory);
+        this.listenTo(this.model.messages, 'add', this.requestUpdate);
+        this.listenTo(this.model.messages, 'remove', this.requestUpdate);
+        this.listenTo(this.model.messages, 'reset', this.requestUpdate);
 
         await this.model.messages.fetched;
         this.model.maybeShow();
@@ -37,15 +32,12 @@ class HeadlinesView extends BaseChatView {
     }
 
     render () {
-        this.setAttribute('id', this.model.get('box_id'));
-        const result = tpl_headlines(
+        return tpl_headlines(
             Object.assign(this.model.toJSON(), {
                 show_send_button: false,
                 show_toolbar: false,
             })
         );
-        render(result, this);
-        return this;
     }
 
     async close (ev) {
@@ -58,7 +50,6 @@ class HeadlinesView extends BaseChatView {
         return this;
     }
 
-
     getNotifications () { // eslint-disable-line class-methods-use-this
         // Override method in ChatBox. We don't show notifications for
         // headlines boxes.

+ 8 - 15
src/plugins/muc-views/muc.js

@@ -3,31 +3,25 @@ import log from '@converse/headless/log';
 import tpl_muc from './templates/muc.js';
 import { __ } from 'i18n';
 import { _converse, api, converse } from '@converse/headless/core';
-import { render } from "lit";
 
 
 export default class MUCView extends BaseChatView {
     length = 300
     is_chatroom = true
 
-    async initialize () {
-        const jid = this.getAttribute('jid');
-        this.model = await api.rooms.get(jid);
-        _converse.chatboxviews.add(jid, this);
+    async connectedCallback () {
+        super.connectedCallback();
+        this.model = await api.rooms.get(this.jid);
+        _converse.chatboxviews.add(this.jid, this);
         this.setAttribute('id', this.model.get('box_id'));
 
         this.listenTo(_converse, 'windowStateChanged', this.onWindowStateChanged);
-        this.listenTo(this.model, 'change:composing_spoiler', this.renderMessageForm);
+        this.listenTo(this.model, 'change:composing_spoiler', this.requestUpdateMessageForm);
         this.listenTo(this.model, 'change:hidden', () => this.afterShown());
         this.listenTo(this.model, 'change:minimized', () => this.afterShown());
         this.listenTo(this.model, 'show', this.show);
         this.listenTo(this.model.session, 'change:connection_status', this.updateAfterTransition);
-        this.listenTo(this.model.session, 'change:view', this.render);
-
-        await this.render();
-
-        // Need to be registered after render has been called.
-        this.listenTo(this.model.occupants, 'change:show', this.showJoinOrLeaveNotification);
+        this.listenTo(this.model.session, 'change:view', this.requestUpdate);
 
         this.updateAfterTransition();
         this.model.maybeShow();
@@ -42,8 +36,7 @@ export default class MUCView extends BaseChatView {
     }
 
     render () {
-        render(tpl_muc({ 'model': this.model }), this);
-        !this.model.get('hidden') && this.show();
+        return this.model ? tpl_muc({ 'model': this.model }) : '';
     }
 
     /**
@@ -115,7 +108,7 @@ export default class MUCView extends BaseChatView {
                 'reason': undefined,
             });
         }
-        this.render();
+        this.requestUpdate();
     }
 }
 

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

@@ -1271,6 +1271,10 @@ describe("Groupchats", function () {
 
             view.querySelector('.configure-chatroom-button').click();
 
+            const sent_IQs = _converse.connection.IQ_stanzas;
+            const sel = 'iq query[xmlns="http://jabber.org/protocol/muc#owner"]';
+            const iq = await u.waitUntil(() => sent_IQs.filter(iq => sizzle(sel, iq).length).pop());
+
             /* Check that an IQ is sent out, asking for the
              * configuration form.
              * See: // https://xmpp.org/extensions/xep-0045.html#example-163
@@ -1282,8 +1286,8 @@ describe("Groupchats", function () {
              *  <query xmlns='http://jabber.org/protocol/muc#owner'/>
              *  </iq>
              */
-            expect(Strophe.serialize(sent_IQ)).toBe(
-                `<iq id="`+IQ_id+`" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
+            expect(Strophe.serialize(iq)).toBe(
+                `<iq id="${iq.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
                     `<query xmlns="http://jabber.org/protocol/muc#owner"/>`+
                 `</iq>`);
 
@@ -1291,7 +1295,7 @@ describe("Groupchats", function () {
              * See: // https://xmpp.org/extensions/xep-0045.html#example-165
              */
             const config_stanza = $iq({from: 'coven@chat.shakespeare.lit',
-                'id': IQ_id,
+                'id': iq.getAttribute('id'),
                 'to': 'romeo@montague.lit/desktop',
                 'type': 'result'})
             .c('query', { 'xmlns': 'http://jabber.org/protocol/muc#owner'})

+ 9 - 18
src/shared/chat/baseview.js

@@ -1,16 +1,20 @@
-import log from '@converse/headless/log';
-import { ElementView } from '@converse/skeletor/src/element.js';
+import { CustomElement } from 'shared/components/element.js';
 import { _converse, api, converse } from '@converse/headless/core';
 import { onScrolledDown } from './utils.js';
 
 const u = converse.env.utils;
 
-export default class BaseChatView extends ElementView {
+export default class BaseChatView extends CustomElement {
+
+    static get properties () {
+        return {
+            jid: { type: String }
+        }
+    }
 
     disconnectedCallback () {
         super.disconnectedCallback();
-        const jid = this.getAttribute('jid');
-        _converse.chatboxviews.remove(jid, this);
+        _converse.chatboxviews.remove(this.jid, this);
     }
 
     maybeFocus () {
@@ -24,19 +28,6 @@ export default class BaseChatView extends ElementView {
         }
         return this;
     }
-
-    show () {
-        if (this.model.get('hidden')) {
-            log.debug(`Not showing chat ${this.model.get('jid')} because it's set as hidden`);
-            return;
-        }
-        if (u.isVisible(this)) {
-            this.maybeFocus();
-            return;
-        }
-        this.afterShown();
-    }
-
     emitBlurred (ev) {
         if (this.contains(document.activeElement) || this.contains(ev.relatedTarget)) {
             // Something else in this chatbox is still focused