Commit 901f7027 authored by JC Brand's avatar JC Brand

message-view: Re-use image element and fix autoscroll after image loads

parent 685c9585
...@@ -1000,18 +1000,15 @@ ...@@ -1000,18 +1000,15 @@
expect(view.model.sendMessage).toHaveBeenCalled(); expect(view.model.sendMessage).toHaveBeenCalled();
let msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop(); let msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
expect(msg.innerHTML.trim()).toEqual( expect(msg.innerHTML.trim()).toEqual(
'<!-- src/templates/image.html -->\n'+ `<a target="_blank" rel="noopener" href="${base_url}/logo/conversejs-filled.svg"><img src="${message}" class="chat-image img-thumbnail"></a>`);
'<a href="'+base_url+'/logo/conversejs-filled.svg" target="_blank" rel="noopener"><img class="chat-image img-thumbnail"'+
' src="' + message + '"></a>');
message += "?param1=val1&param2=val2"; message += "?param1=val1&param2=val2";
test_utils.sendMessage(view, message); test_utils.sendMessage(view, message);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length === 2, 1000); await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length === 2, 1000);
expect(view.model.sendMessage).toHaveBeenCalled(); expect(view.model.sendMessage).toHaveBeenCalled();
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop(); msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
expect(msg.innerHTML.trim()).toEqual( expect(msg.innerHTML.trim()).toEqual(
'<!-- src/templates/image.html -->\n'+ '<a target="_blank" rel="noopener" href="'+base_url+'/logo/conversejs-filled.svg?param1=val1&amp;param2=val2"><img'+
'<a href="'+base_url+'/logo/conversejs-filled.svg?param1=val1&amp;param2=val2" target="_blank" rel="noopener"><img'+ ' src="'+message.replace(/&/g, '&amp;')+'" class="chat-image img-thumbnail"></a>')
' class="chat-image img-thumbnail" src="'+message.replace(/&/g, '&amp;')+'"></a>')
// Test now with two images in one message // Test now with two images in one message
message += ' hello world '+base_url+"/logo/conversejs-filled.svg"; message += ' hello world '+base_url+"/logo/conversejs-filled.svg";
......
...@@ -276,7 +276,7 @@ converse.plugins.add('converse-message-view', { ...@@ -276,7 +276,7 @@ converse.plugins.add('converse-message-view', {
if (text && text !== url) { if (text && text !== url) {
msg_content.innerHTML = await this.transformBodyText(text); msg_content.innerHTML = await this.transformBodyText(text);
if (_converse.show_images_inline) { if (_converse.show_images_inline) {
await u.renderImageURLs(_converse, msg_content); u.renderImageURLs(_converse, msg_content).then(() => this.triggerRendered());
} }
} }
} }
...@@ -284,6 +284,10 @@ converse.plugins.add('converse-message-view', { ...@@ -284,6 +284,10 @@ converse.plugins.add('converse-message-view', {
this.renderAvatar(msg); this.renderAvatar(msg);
} }
this.replaceElement(msg); this.replaceElement(msg);
this.triggerRendered();
},
triggerRendered () {
if (this.model.collection) { if (this.model.collection) {
// If the model gets destroyed in the meantime, it no // If the model gets destroyed in the meantime, it no
// longer has a collection. // longer has a collection.
......
...@@ -54,14 +54,12 @@ function slideOutWrapup (el) { ...@@ -54,14 +54,12 @@ function slideOutWrapup (el) {
function isImage (url) { function isImage (url) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var img = new Image(); const err_msg = `Could not determine whether it's an image: ${url}`;
var timer = window.setTimeout(function () { const img = new Image();
reject(new Error("Could not determine whether it's an image")); const timer = window.setTimeout(() => reject(new Error(err_msg)), 3000);
img = null;
}, 3000);
img.onerror = img.onabort = function () { img.onerror = img.onabort = function () {
clearTimeout(timer); clearTimeout(timer);
reject(new Error("Could not determine whether it's an image")); reject(new Error(err_msg));
}; };
img.onload = function () { img.onload = function () {
clearTimeout(timer); clearTimeout(timer);
...@@ -182,15 +180,23 @@ u.applyDragResistance = function (value, default_value) { ...@@ -182,15 +180,23 @@ u.applyDragResistance = function (value, default_value) {
}; };
function renderImage (img_url, link_url, el, callback) { async function renderImage (img_url, link_url, el, callback) {
if (u.isImageURL(img_url)) { if (u.isImageURL(img_url)) {
return isImage(img_url) let img;
.then(() => sizzle(`a[href="${link_url}"]`, el).forEach(a => (a.outerHTML = tpl_image({'url': img_url})))) try {
.then(callback) img = await isImage(img_url);
.catch(callback); } catch (e) {
} else { log.error(e);
return callback(); return callback();
}
sizzle(`a[href="${link_url}"]`, el).forEach(a => {
a.innerHTML = "";
u.addClass('chat-image', img);
u.addClass('img-thumbnail', img);
a.insertAdjacentElement('afterBegin', img);
});
} }
callback();
} }
...@@ -208,7 +214,7 @@ u.renderImageURLs = function (_converse, el) { ...@@ -208,7 +214,7 @@ u.renderImageURLs = function (_converse, el) {
const list = el.textContent.match(URL_REGEX) || []; const list = el.textContent.match(URL_REGEX) || [];
return Promise.all( return Promise.all(
list.map(url => list.map(url =>
new Promise((resolve) => { new Promise(resolve => {
if (url.startsWith('https://imgur.com') && !u.isImageURL(url)) { if (url.startsWith('https://imgur.com') && !u.isImageURL(url)) {
const imgur_url = url + '.png'; const imgur_url = url + '.png';
renderImage(imgur_url, url, el, resolve); renderImage(imgur_url, url, el, resolve);
......
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