chatview: display images and youtube links

Display images and youtube videos links in the message.

Change-Id: Ic47f210fb13287e72561570bb689a3cb07eedcef
Reviewed-by: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>
diff --git a/web/chatview.html b/web/chatview.html
index 6490020..6cc74df 100644
--- a/web/chatview.html
+++ b/web/chatview.html
@@ -135,18 +135,98 @@
         return div.innerHTML;
     }
 
-    /**
-     * Returns HTML message from the message text.
-     * Cleaned and linkified.
-     */
-    function getMessageHtml(message_text)
-    {
-        var escaped_message = escapeHtml(message_text),
-            linkified_message = linkifyHtml(escaped_message, {});
 
-        return "<pre>" + linkified_message + "</pre>";
+    /**
+     * Get the youtube video id from a URI
+     */
+    function youtube_id(url) {
+        const regExp = /^.*(youtu\.be\/|v\/|\/u\/w|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
+        const match = url.match(regExp);
+        return (match && match[2].length == 11) ? match[2] : null;
     }
 
+
+    /**
+     * Show images/videos from links in a message.
+     */
+    function displayLinks(messageNode)
+    {
+        const finalMsg = document.createElement('div');
+        finalMsg.setAttribute('id', 'msg_content');
+        finalMsg.innerHTML = messageNode.outerHTML;
+
+        const parser = new DOMParser();
+        const DOMMsg = parser.parseFromString(messageNode.innerHTML, 'text/xml');
+        const links = DOMMsg.querySelectorAll('a');
+
+        const availableProtocols = ['http:', 'https:'];
+        const videoHostname = ['youtube.com', 'www.youtube.com', 'youtu.be'];
+
+        const cardElt = document.createElement('div');
+        cardElt.setAttribute('id', 'cardWrapper');
+
+        if (links.length) {
+            const link = links[0].getAttribute('href');
+            const urlParser = document.createElement('a');
+            urlParser.href = link;
+
+            // Parse videos
+            if (availableProtocols.includes(urlParser.protocol) && videoHostname.includes(urlParser.hostname)) {
+                // Youtube
+                const ytid = youtube_id(link)
+                if (ytid) {
+                    const linkElt = document.createElement('a');
+                    linkElt.href = link;
+                    const containerElt = document.createElement('div');
+                    containerElt.setAttribute('id', 'containerVideo');
+                    const imageElt = document.createElement('img');
+                    imageElt.src = `http://img.youtube.com/vi/${ytid}/0.jpg`;
+                    const playDiv = document.createElement('div');
+                    playDiv.setAttribute('id', 'playVideo');
+                    playDiv.innerHTML = '<svg fill="#ffffff" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">\
+                        <path d="M8 5v14l11-7z"/>\
+                        <path d="M0 0h24v24H0z" fill="none"/>\
+                    </svg>'
+                    linkElt.appendChild(imageElt);
+                    linkElt.appendChild(playDiv);
+                    containerElt.appendChild(linkElt);
+                    cardElt.appendChild(containerElt);
+                    finalMsg.appendChild(cardElt);
+                    messageNode.outerHTML = finalMsg.outerHTML;
+                }
+            } else {
+              // Try to display images.
+                const linkElt = document.createElement('a');
+                linkElt.href = link;
+                const imageElt = document.createElement('img');
+                // Note, here, we don't check the size of the image.
+                // in the future, we can check the content-type and content-length with a request
+                // and maybe disable svg
+                imageElt.setAttribute("onerror", "this.style.display='none'");
+                imageElt.src = link;
+                linkElt.appendChild(imageElt);
+                cardElt.appendChild(linkElt);
+                finalMsg.appendChild(cardElt);
+                messageNode.outerHTML = finalMsg.outerHTML;
+            }
+        }
+    }
+
+  /**
+   * Returns HTML message from the message text.
+   * Cleaned and linkified.
+   */
+  function getMessageHtml(message_text)
+  {
+    const escaped_message = escapeHtml(message_text),
+      linkified_message = linkifyHtml(escaped_message, {});
+
+    const textPart = document.createElement('pre');
+    textPart.innerHTML = linkified_message;
+
+    return textPart.outerHTML;
+  }
+
     /**
      * Returns the message status, formatted for display
      */
@@ -363,6 +443,8 @@
 
         // Set the variables
         chatview_message_text.innerHTML = getMessageHtml(message_text);
+        if (new_message)
+            displayLinks(chatview_message_text);
         chatview_message_sender.textContent = message_sender + ": ";
         chatview_message_delivery_status.innerHTML = getMessageDeliveryStatusText(message_delivery_status);
         chatview_message_timestamp.textContent = getMessageTimestampText(message_timestamp);