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 @@ ...@@ -35,7 +35,7 @@
muc_respect_autojoin: true, muc_respect_autojoin: true,
muc_show_logs_before_join: true, muc_show_logs_before_join: true,
notify_all_room_messages: ['discuss@conference.conversejs.org'], notify_all_room_messages: ['discuss@conference.conversejs.org'],
persistent_store: 'IndexedDB', persistent_store: 'localStorage',
theme: 'concord', theme: 'concord',
view_mode: 'fullscreen', view_mode: 'fullscreen',
websocket_url: 'wss://conversejs.org/xmpp-websocket', websocket_url: 'wss://conversejs.org/xmpp-websocket',
......
...@@ -344,8 +344,7 @@ describe("A Chat Message", function () { ...@@ -344,8 +344,7 @@ describe("A Chat Message", function () {
keyCode: 13 // Enter keyCode: 13 // Enter
}); });
await new Promise(resolve => view.model.messages.once('rendered', resolve)); await new Promise(resolve => view.model.messages.once('rendered', resolve));
await u.waitUntil(() => textarea.value === '');
expect(textarea.value).toBe('');
const messages = view.el.querySelectorAll('.chat-msg'); const messages = view.el.querySelectorAll('.chat-msg');
expect(messages.length).toBe(3); expect(messages.length).toBe(3);
expect(messages[0].querySelector('.chat-msg__text').textContent) expect(messages[0].querySelector('.chat-msg__text').textContent)
......
/*global mock */ /*global mock, converse */
const { Strophe, $iq } = converse.env; const { Strophe, $iq } = converse.env;
const u = converse.env.utils; const u = converse.env.utils;
......
/* global mock */ /* global mock, converse */
const original_timeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; const original_timeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
......
...@@ -81,6 +81,19 @@ function getHats (model) { ...@@ -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 { export default class MessageHistory extends CustomElement {
static get properties () { static get properties () {
...@@ -104,20 +117,13 @@ export default class MessageHistory extends CustomElement { ...@@ -104,20 +117,13 @@ export default class MessageHistory extends CustomElement {
} }
const day = getDayIndicator(model); const day = getDayIndicator(model);
const templates = day ? [day] : []; const templates = day ? [day] : [];
const is_groupchat = model.get('type') === 'groupchat';
const chatbox = this.chatview.model;
const message = tpl_message( const message = tpl_message(
Object.assign(model.toJSON(), { Object.assign(
'chatview': this.chatview, model.toJSON(),
'has_mentions': is_groupchat && model.get('sender') === 'them' && chatbox.isUserMentioned(model), getDerivedMessageProps(this.chatview.model, model),
'hats': getHats(model), { 'chatview': this.chatview, 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,
}));
return [...templates, message]; return [...templates, message];
} }
} }
......
...@@ -2,6 +2,7 @@ import './message-body.js'; ...@@ -2,6 +2,7 @@ import './message-body.js';
import '../converse-registry'; import '../converse-registry';
import './dropdown.js'; import './dropdown.js';
import './message-actions.js'; import './message-actions.js';
import { getDerivedMessageProps } from './message-history';
import MessageVersionsModal from '../modals/message-versions.js'; import MessageVersionsModal from '../modals/message-versions.js';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import filesize from 'filesize'; import filesize from 'filesize';
...@@ -74,6 +75,21 @@ export default class Message extends CustomElement { ...@@ -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 () { updated () {
// XXX: This is ugly but tests rely on this event. // XXX: This is ugly but tests rely on this event.
// For "normal" chat messages the event is fired in // For "normal" chat messages the event is fired in
......
...@@ -74,7 +74,6 @@ export const ChatBoxView = View.extend({ ...@@ -74,7 +74,6 @@ export const ChatBoxView = View.extend({
// Need to be registered after render has been called. // Need to be registered after render has been called.
this.listenTo(this.model.messages, 'add', this.onMessageAdded); 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, 'remove', this.renderChatHistory);
this.listenTo(this.model.messages, 'rendered', this.maybeScrollDown); this.listenTo(this.model.messages, 'rendered', this.maybeScrollDown);
this.listenTo(this.model.messages, 'reset', this.renderChatHistory); 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