diff --git a/spec/corrections.js b/spec/corrections.js
index ca676168a..5375549cc 100644
--- a/spec/corrections.js
+++ b/spec/corrections.js
@@ -146,6 +146,9 @@ describe("A Chat Message", function () {
keyCode: 13 // Enter
});
await u.waitUntil(() => textarea.value === '');
+ await u.waitUntil(() => Array.from(view.querySelectorAll('.chat-msg__text')).filter(
+ m => m.textContent === 'It is the east, and Juliet is the sun.').length);
+
const messages = view.querySelectorAll('.chat-msg');
expect(messages.length).toBe(3);
expect(messages[0].querySelector('.chat-msg__text').textContent)
@@ -244,9 +247,9 @@ describe("A Chat Message", function () {
action = view.querySelector('.chat-msg .chat-msg__action');
action.style.opacity = 1;
action.click();
- expect(textarea.value).toBe('');
expect(view.model.messages.at(0).get('correcting')).toBe(false);
expect(view.querySelectorAll('.chat-msg').length).toBe(1);
+ expect(textarea.value).toBe('');
await u.waitUntil(() => (u.hasClass('correcting', view.querySelector('.chat-msg')) === false), 500);
// Test that messages from other users don't have the pencil icon
diff --git a/src/components/chat_content.js b/src/components/chat_content.js
index 527811abf..9ef6a789a 100644
--- a/src/components/chat_content.js
+++ b/src/components/chat_content.js
@@ -1,41 +1,56 @@
import "./message-history";
-import xss from "xss/dist/xss";
import { CustomElement } from './element.js';
+import { _converse, api } from "@converse/headless/core";
import { html } from 'lit-element';
-import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
-import { api } from "@converse/headless/core";
export default class ChatContent extends CustomElement {
static get properties () {
return {
- chatview: { type: Object}
+ jid: { type: String }
}
}
connectedCallback () {
super.connectedCallback();
- const model = this.chatview.model;
- this.listenTo(model.messages, 'add', this.requestUpdate);
- this.listenTo(model.messages, 'change', this.requestUpdate);
- this.listenTo(model.messages, 'remove', this.requestUpdate);
- this.listenTo(model.messages, 'reset', this.requestUpdate);
- this.listenTo(model.notifications, 'change', this.requestUpdate);
- if (model.occupants) {
- this.listenTo(model.occupants, 'change', this.requestUpdate);
+ this.model = _converse.chatboxes.get(this.jid);
+ this.listenTo(this.model.messages, 'add', this.requestUpdate);
+ this.listenTo(this.model.messages, 'change', this.requestUpdate);
+ this.listenTo(this.model.messages, 'remove', this.requestUpdate);
+ this.listenTo(this.model.messages, 'reset', this.requestUpdate);
+ this.listenTo(this.model.notifications, 'change', this.requestUpdate);
+ if (this.model.occupants) {
+ this.listenTo(this.model.occupants, 'change', this.requestUpdate);
}
+
+ // We jot down whether we were scrolled down before rendering, because when an
+ // image loads, it triggers 'scroll' and the chat will be marked as scrolled,
+ // which is technically true, but not what we want because the user
+ // didn't initiate the scrolling.
+ this.was_scrolled_up = this.model.get('scrolled');
+ this.addEventListener('imageLoaded', () => {
+ !this.was_scrolled_up && this.scrollDown();
+ });
}
render () {
- const notifications = xss.filterXSS(this.chatview.getNotifications(), {'whiteList': {}});
return html`
+ .model=${this.model}
+ .messages=${[...this.model.messages.models]}>
-
${unsafeHTML(notifications)}
+ ${this.model.getNotificationsText()}
`;
}
+
+ scrollDown () {
+ if (this.scrollTo) {
+ const behavior = this.scrollTop ? 'smooth' : 'auto';
+ this.scrollTo({ 'top': this.scrollHeight, behavior });
+ } else {
+ this.scrollTop = this.scrollHeight;
+ }
+ }
}
api.elements.define('converse-chat-content', ChatContent);
diff --git a/src/components/message-actions.js b/src/components/message-actions.js
index 0864ca8ce..63b5217fe 100644
--- a/src/components/message-actions.js
+++ b/src/components/message-actions.js
@@ -1,15 +1,17 @@
+import log from '@converse/headless/log';
import { CustomElement } from './element.js';
import { __ } from '../i18n';
-import { api } from "@converse/headless/core";
+import { _converse, api, converse } from "@converse/headless/core";
import { html } from 'lit-element';
import { until } from 'lit-html/directives/until.js';
+const { Strophe, u } = converse.env;
+
class MessageActions extends CustomElement {
static get properties () {
return {
- chatview: { type: Object },
model: { type: Object },
editable: { type: Boolean },
correcting: { type: Boolean },
@@ -22,6 +24,16 @@ class MessageActions extends CustomElement {
return html`${ until(this.renderActions(), '') }`;
}
+ async renderActions () {
+ const buttons = await this.getActionButtons();
+ const items = buttons.map(b => MessageActions.getActionsDropdownItem(b));
+ if (items.length) {
+ return html``;
+ } else {
+ return '';
+ }
+ }
+
static getActionsDropdownItem (o) {
return html`