瀏覽代碼

Let message component listen for changes...

and render directly from those

Instead of doing it higher up in the chat view (which requires more
function calls and iterating through all messages).
JC Brand 4 年之前
父節點
當前提交
65ad33ec81
共有 7 個文件被更改,包括 39 次插入19 次删除
  1. 1 1
      dev.html
  2. 1 2
      spec/messages.js
  3. 1 1
      spec/retractions.js
  4. 1 1
      spec/spoilers.js
  5. 19 13
      src/components/message-history.js
  6. 16 0
      src/components/message.js
  7. 0 1
      src/converse-chatview.js

+ 1 - 1
dev.html

@@ -35,7 +35,7 @@
         muc_respect_autojoin: true,
         muc_show_logs_before_join: true,
         notify_all_room_messages: ['discuss@conference.conversejs.org'],
-        persistent_store: 'IndexedDB',
+        persistent_store: 'localStorage',
         theme: 'concord',
         view_mode: 'fullscreen',
         websocket_url: 'wss://conversejs.org/xmpp-websocket',

+ 1 - 2
spec/messages.js

@@ -344,8 +344,7 @@ describe("A Chat Message", function () {
             keyCode: 13 // Enter
         });
         await new Promise(resolve => view.model.messages.once('rendered', resolve));
-
-        expect(textarea.value).toBe('');
+        await u.waitUntil(() => textarea.value === '');
         const messages = view.el.querySelectorAll('.chat-msg');
         expect(messages.length).toBe(3);
         expect(messages[0].querySelector('.chat-msg__text').textContent)

+ 1 - 1
spec/retractions.js

@@ -1,4 +1,4 @@
-/*global mock */
+/*global mock, converse */
 
 const { Strophe, $iq } = converse.env;
 const u = converse.env.utils;

+ 1 - 1
spec/spoilers.js

@@ -1,4 +1,4 @@
-/* global mock */
+/* global mock, converse */
 
 const original_timeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
 

+ 19 - 13
src/components/message-history.js

@@ -81,6 +81,19 @@ function getHats (model) {
 }
 
 
+export function getDerivedMessageProps (chatbox, model) {
+    const is_groupchat = model.get('type') === 'groupchat';
+    return {
+        'has_mentions': is_groupchat && model.get('sender') === 'them' && chatbox.isUserMentioned(model),
+        'hats': getHats(model),
+        'is_first_unread': chatbox.get('first_unread_id') === model.get('id'),
+        'is_me_message': model.isMeCommand(),
+        'is_retracted': model.get('retracted') || model.get('moderated') === 'retracted',
+        'username': model.getDisplayName(),
+    }
+}
+
+
 export default class MessageHistory extends CustomElement {
 
     static get properties () {
@@ -104,20 +117,13 @@ export default class MessageHistory extends CustomElement {
         }
         const day = getDayIndicator(model);
         const templates = day ? [day] : [];
-        const is_groupchat = model.get('type') === 'groupchat';
-        const chatbox = this.chatview.model;
         const message = tpl_message(
-            Object.assign(model.toJSON(), {
-                'chatview': this.chatview,
-                'has_mentions': is_groupchat && model.get('sender') === 'them' && chatbox.isUserMentioned(model),
-                'hats': getHats(model),
-                'is_first_unread': chatbox.get('first_unread_id') === model.get('id'),
-                'is_me_message': model.isMeCommand(),
-                'is_retracted': model.get('retracted') || model.get('moderated') === 'retracted',
-                'occupant': model.occupant,
-                'username': model.getDisplayName(),
-                model,
-            }));
+            Object.assign(
+                model.toJSON(),
+                getDerivedMessageProps(this.chatview.model, model),
+                { 'chatview': this.chatview, model }
+            )
+        );
         return [...templates, message];
     }
 }

+ 16 - 0
src/components/message.js

@@ -2,6 +2,7 @@ import './message-body.js';
 import '../converse-registry';
 import './dropdown.js';
 import './message-actions.js';
+import { getDerivedMessageProps } from './message-history';
 import MessageVersionsModal from '../modals/message-versions.js';
 import dayjs from 'dayjs';
 import filesize from 'filesize';
@@ -74,6 +75,21 @@ export default class Message extends CustomElement {
         }
     }
 
+    connectedCallback () {
+        super.connectedCallback();
+        // Listen to changes and update properties (which will trigger a
+        // re-render if necessary).
+        this.listenTo(this.model, 'change', (model) => {
+            const chatbox = this.model.collection.chatbox;
+            Object.assign(this, getDerivedMessageProps(chatbox, this.model));
+            Object.keys(model.changed)
+                .filter(p => Object.keys(Message.properties).includes(p))
+                .forEach(p => (this[p] = model.changed[p]));
+        });
+        const vcard = this.model.vcard;
+        vcard && this.listenTo(vcard, 'change', () => this.requestUpdate());
+    }
+
     updated () {
         // XXX: This is ugly but tests rely on this event.
         // For "normal" chat messages the event is fired in

+ 0 - 1
src/converse-chatview.js

@@ -74,7 +74,6 @@ export const ChatBoxView = View.extend({
 
         // Need to be registered after render has been called.
         this.listenTo(this.model.messages, 'add', this.onMessageAdded);
-        this.listenTo(this.model.messages, 'change', this.renderChatHistory);
         this.listenTo(this.model.messages, 'remove', this.renderChatHistory);
         this.listenTo(this.model.messages, 'rendered', this.maybeScrollDown);
         this.listenTo(this.model.messages, 'reset', this.renderChatHistory);