Explorar el Código

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

JC Brand hace 5 años
padre
commit
901f70272e
Se han modificado 3 ficheros con 28 adiciones y 21 borrados
  1. 3 6
      spec/messages.js
  2. 5 1
      src/converse-message-view.js
  3. 20 14
      src/utils/html.js

+ 3 - 6
spec/messages.js

@@ -1000,18 +1000,15 @@
             expect(view.model.sendMessage).toHaveBeenCalled();
             let msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
             expect(msg.innerHTML.trim()).toEqual(
-                '<!-- src/templates/image.html -->\n'+
-                '<a href="'+base_url+'/logo/conversejs-filled.svg" target="_blank" rel="noopener"><img class="chat-image img-thumbnail"'+
-                ' src="' + message + '"></a>');
+                `<a target="_blank" rel="noopener" href="${base_url}/logo/conversejs-filled.svg"><img src="${message}" class="chat-image img-thumbnail"></a>`);
             message += "?param1=val1&param2=val2";
             test_utils.sendMessage(view, message);
             await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length === 2, 1000);
             expect(view.model.sendMessage).toHaveBeenCalled();
             msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
             expect(msg.innerHTML.trim()).toEqual(
-                '<!-- src/templates/image.html -->\n'+
-                '<a href="'+base_url+'/logo/conversejs-filled.svg?param1=val1&amp;param2=val2" target="_blank" rel="noopener"><img'+
-                ' class="chat-image img-thumbnail" src="'+message.replace(/&/g, '&amp;')+'"></a>')
+                '<a target="_blank" rel="noopener" href="'+base_url+'/logo/conversejs-filled.svg?param1=val1&amp;param2=val2"><img'+
+                ' src="'+message.replace(/&/g, '&amp;')+'" class="chat-image img-thumbnail"></a>')
 
             // Test now with two images in one message
             message += ' hello world '+base_url+"/logo/conversejs-filled.svg";

+ 5 - 1
src/converse-message-view.js

@@ -276,7 +276,7 @@ converse.plugins.add('converse-message-view', {
                     if (text && text !== url) {
                         msg_content.innerHTML = await this.transformBodyText(text);
                         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', {
                     this.renderAvatar(msg);
                 }
                 this.replaceElement(msg);
+                this.triggerRendered();
+            },
+
+            triggerRendered () {
                 if (this.model.collection) {
                     // If the model gets destroyed in the meantime, it no
                     // longer has a collection.

+ 20 - 14
src/utils/html.js

@@ -54,14 +54,12 @@ function slideOutWrapup (el) {
 
 function isImage (url) {
     return new Promise((resolve, reject) => {
-        var img = new Image();
-        var timer = window.setTimeout(function () {
-            reject(new Error("Could not determine whether it's an image"));
-            img = null;
-        }, 3000);
+        const err_msg = `Could not determine whether it's an image: ${url}`;
+        const img = new Image();
+        const timer = window.setTimeout(() => reject(new Error(err_msg)), 3000);
         img.onerror = img.onabort = function () {
             clearTimeout(timer);
-            reject(new Error("Could not determine whether it's an image"));
+            reject(new Error(err_msg));
         };
         img.onload = function () {
             clearTimeout(timer);
@@ -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)) {
-        return isImage(img_url)
-            .then(() => sizzle(`a[href="${link_url}"]`, el).forEach(a => (a.outerHTML = tpl_image({'url': img_url}))))
-            .then(callback)
-            .catch(callback);
-    } else {
-        return callback();
+        let img;
+        try {
+            img = await isImage(img_url);
+        } catch (e) {
+            log.error(e);
+            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) {
     const list = el.textContent.match(URL_REGEX) || [];
     return Promise.all(
         list.map(url =>
-            new Promise((resolve) => {
+            new Promise(resolve => {
                 if (url.startsWith('https://imgur.com') && !u.isImageURL(url)) {
                     const imgur_url = url + '.png';
                     renderImage(imgur_url, url, el, resolve);