]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
ui: Add fanart background to dvr details dialog.
authorE.Smith <31170571+azlm8t@users.noreply.github.com>
Wed, 26 Sep 2018 22:35:26 +0000 (23:35 +0100)
committerperexg <perex@perex.cz>
Tue, 2 Oct 2018 14:04:48 +0000 (16:04 +0200)
We now display fanart (if available) on the background of the dvr
dialog. This fanart image is also displayed every ten seconds where
the existing image is displayed.

We have to put the image inside a fixed width container, otherwise if
you alternate between a long thin image and a wide image then the text
reflows.

src/webui/static/app/dvr.js
src/webui/static/app/epg.js
src/webui/static/app/ext.css

index fa6391f2c433d9d772bbf0a7c4eb1787ecbe0944..950fbe10b8ba90e22d449a52435f8eee45f130f7 100644 (file)
@@ -24,6 +24,7 @@ tvheadend.labelFormattingParser = function(description) {
 tvheadend.dvrDetails = function(grid, index) {
     var current_index = index;
     var win;
+    var updateTimer;
     // We need a unique DOM id in case user opens two dialogs.
     var nextButtonId = Ext.id();
     var previousButtonId = Ext.id();
@@ -70,7 +71,12 @@ tvheadend.dvrDetails = function(grid, index) {
         var category = params[19].value;
         var first_aired = params[20].value;
         var genre = params[21].value;
-        var content = '';
+        /* channelname is unused param 22 */
+        var fanart_image = params[23].value;
+        var content = '<div class="dvr-details-dialog">' +
+        '<div class="dvr-details-dialog-background-image"></div>' +
+        '<div class="dvr-details-dialog-content">';
+
         var but;
 
         if (chicon != null && chicon.length > 0) {
@@ -110,9 +116,14 @@ tvheadend.dvrDetails = function(grid, index) {
             content += '</div>'; /* x-epg-left */
             content += '<div class="x-epg-bottom">';
         }
+        // If we have no image then use fanart image instead.
+        content += '<div class="x-epg-image-container">';
         if (image != null && image.length > 0) {
           content += '<img class="x-epg-image" src="' + image + '">';
+        } else if (fanart_image != null && fanart_image.length > 0) {
+          content += '<img class="x-epg-image" src="' + fanart_image + '">';
         }
+        content += '</div>';
 
         content += '<hr class="x-epg-hr"/>';
         if (summary && (!subtitle || subtitle != summary))
@@ -138,6 +149,7 @@ tvheadend.dvrDetails = function(grid, index) {
             content += '<div class="x-epg-meta"><span class="x-epg-prefix">' + _('Time Scheduler') + ':</span><span class="x-epg-body">' + timerec_caption + '</span></div>';
         if (chicon)
             content += '</div>'; /* x-epg-bottom */
+      content += '</div>';        //dialog content
       return content
     }
 
@@ -191,6 +203,55 @@ tvheadend.dvrDetails = function(grid, index) {
     return buttons;
   }                             // getDialogButtons
 
+  function updateDialogFanart(d) {
+      var params = d[0].params;
+      var image=params[15].value;
+      var fanart = params[23].value;
+
+      if (updateTimer)
+          clearInterval(updateTimer);
+
+      fanart_div = win.el.child(".dvr-details-dialog-background-image");
+      if (fanart != null && fanart.length > 0 && fanart_div) {
+          // Set the fanart image. The rest of the css _should_ by in the tv.css,
+          // but it seemed to ignore it when we applyStyles.
+          // We have to explicitly set width/height otherwise the box was 0px tall.
+          fanart_div.applyStyles({
+              'background' : 'url(' + fanart + ') center center no-repeat',
+              'opacity': 0.15,
+              'position': 'relative',
+              'width' : '100%',
+              'height': '100%',
+          });
+      }                        // Have fanart div
+
+      if (image != null && image.length > 0 &&
+          fanart != null && fanart.length > 0) {
+          // We have image and fanart, so alternate the images every x milliseconds.
+          var index = 0;
+          updateTimer = setInterval(function() {
+              if (win.isDestroyed) {
+                  clearInterval(updateTimer);
+                  return;
+              }
+              var img_div = win.el.child(".x-epg-image");
+              if (img_div && img_div.dom) {
+                  var img= img_div.dom;
+                  // The img.src can be changed by browser so it does
+                  // not match either fanart or image! So we use a
+                  // counter to determine which image should be displayed.
+                  if (++index % 2) {
+                      img.src = fanart;
+                  } else {
+                      img.src = image;
+                  }
+              } else {
+                  clearInterval(updateTimer);
+              }
+          }, 10 * 1000);
+      }
+  }                             //updateDialogFanart
+
   function showit(d) {
        var dialogTitle = getDialogTitle(d);
        var content = getDialogContent(d);
@@ -209,6 +270,7 @@ tvheadend.dvrDetails = function(grid, index) {
             html: content
         });
        win.show();
+       updateDialogFanart(d);
        checkButtonAvailability(win.fbar)
   }
 
@@ -222,7 +284,7 @@ tvheadend.dvrDetails = function(grid, index) {
             list: 'channel_icon,disp_title,disp_subtitle,disp_summary,episode_disp,start_real,stop_real,' +
                   'duration,disp_description,status,filesize,comment,duplicate,' +
                   'autorec_caption,timerec_caption,image,copyright_year,credits,keyword,category,' +
-                  'first_aired,genre,channelname',
+                  'first_aired,genre,channelname,fanart_image',
         },
         success: function(d) {
             d = json_decode(d);
@@ -267,6 +329,7 @@ tvheadend.dvrDetails = function(grid, index) {
         Ext.each(buttons, function(btn) {
             tbar.addButton(btn);
         });
+        updateDialogFanart(d);
         checkButtonAvailability(tbar);
         // Finally, relayout.
         win.doLayout();
index 7b16ff4389a1376a18560bbf59f319ae87d8aeff..51cc3a975aa0909a4e3073051b8fc3950a3e22c0 100644 (file)
@@ -166,7 +166,9 @@ tvheadend.epgDetails = function(grid, index) {
         content += '<div class="x-epg-bottom">';
       }
       if (event.image != null && event.image.length > 0) {
+        content += '<div class="x-epg-image-container">';
         content += '<img class="x-epg-image" src="' + event.image + '">';
+        content += '</div>';
       }
       content += '<hr class="x-epg-hr"/>';
       if (event.summary)
index 239706510150d9cb782ba2561732e83864e4fabe..d1f4f4bde42c6fac0fe143f741799aac91f268ed 100644 (file)
     margin: 5px 5px 5px 10px;
 }
 
-.x-epg-image{
+/* Our image has to be inside an image container
+ * since when the image changes we don't want text
+ * to reflow. This image is not scaled to this size,
+ * it is simply the size of the container to avoid text
+ * flowing around it.
+ */
+.x-epg-image-container {
     float: right;
     margin-left: 5px;
     margin-right: 5px;
     margin-bottom: 5px;
     width: 20%;
+    height: 200px;
+    position: relative;
+}
+
+.x-epg-image{
+    width: 100%;                /*100% of the container*/
+    max-height: 100%;
+    z-index: 10;                /*Need higher z-index since we are inside a div*/
+    position: relative;         /*z-index only works with position of non-static (the default)*/
 }
 
 .x-epg-image:hover{
     text-decoration: line-through;
 }
 
+.dvr-details-dialog {
+    postition: relative;
+}
+.dvr-details-dialog-background-image {
+    /* Details in here are overridden by  code */
+}
+.dvr-details-dialog-content {
+    position: absolute;
+    top: 0;
+    left: 0;
+}
+
 .tv-video-player {
     margin-right: auto;
     margin-left : auto;