Commit 65ad33ec authored by JC Brand's avatar JC Brand

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).
parent 4ebd3caf
......@@ -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',
......
......@@ -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)
......
/*global mock */
/*global mock, converse */
const { Strophe, $iq } = converse.env;
const u = converse.env.utils;
......
/* global mock */
/* global mock, converse */
const original_timeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
......
......@@ -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];
}
}
......
......@@ -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
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment