diff --git a/dashboard-ui/css/images/media/chapterflyout.png b/dashboard-ui/css/images/media/chapterflyout.png new file mode 100644 index 0000000000..3e71abe95c Binary files /dev/null and b/dashboard-ui/css/images/media/chapterflyout.png differ diff --git a/dashboard-ui/css/site.css b/dashboard-ui/css/site.css index efce771085..509f2aabdf 100644 --- a/dashboard-ui/css/site.css +++ b/dashboard-ui/css/site.css @@ -885,6 +885,58 @@ input[type="range"]::-ms-fill-upper { z-index: 99999; bottom: 55px; margin-left: -50px; + max-height: 300px; + overflow-y: auto; + font-size: 13px; +} + +.chaptersFlyout { + width: 250px; +} + +.mediaFlyoutOption { + display: block; + text-decoration: none; + color: #000; + border-bottom: 1px solid #eee; + cursor: pointer; +} + + .mediaFlyoutOption:hover, .mediaFlyoutOption:focus { + background-color: #eee; + } + +.selectedMediaFlyoutOption { + background-color: #e4F4FF; +} + +.mediaFlyoutOptionImage { + display: inline-block; + width: 40%; + vertical-align: middle; +} + + .mediaFlyoutOptionImage + .mediaFlyoutOptionContent { + vertical-align: top; + display: inline-block; + width: 60%; + } + +.mediaFlyoutOptionName { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + padding-left: 5px; +} + +.mediaFlyoutOptionSecondaryText { + font-size: 11px; + color: #999; + margin-top: 3px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + padding-left: 5px; } .installedPluginTitle { diff --git a/dashboard-ui/scripts/mediaplayer.js b/dashboard-ui/scripts/mediaplayer.js index 67fa06a81b..fcea5e514e 100644 --- a/dashboard-ui/scripts/mediaplayer.js +++ b/dashboard-ui/scripts/mediaplayer.js @@ -115,19 +115,13 @@ } } - function onPositionSliderChange() { - - isPositionSliderActive = false; + function seek(ticks) { var element = currentMediaElement; - var newPercent = parseInt(this.value); - - var newPositionTicks = (newPercent / 100) * currentItem.RunTimeTicks; - if (isStaticStream) { - element.currentTime = newPositionTicks / (1000 * 10000); + element.currentTime = ticks / (1000 * 10000); } else { @@ -135,10 +129,10 @@ if (currentSrc.toLowerCase().indexOf('starttimeticks') == -1) { - currentSrc += "&starttimeticks=" + newPositionTicks; + currentSrc += "&starttimeticks=" + ticks; } else { - currentSrc = replaceQueryString(currentSrc, 'starttimeticks', newPositionTicks); + currentSrc = replaceQueryString(currentSrc, 'starttimeticks', ticks); } clearProgressInterval(); @@ -150,12 +144,23 @@ sendProgressUpdate(currentItem.Id); }); - startTimeTicksOffset = newPositionTicks; + startTimeTicksOffset = ticks; element.src = currentSrc; } } + function onPositionSliderChange() { + + isPositionSliderActive = false; + + var newPercent = parseInt(this.value); + + var newPositionTicks = (newPercent / 100) * currentItem.RunTimeTicks; + + seek(newPositionTicks); + } + $(function () { muteButton = $('#muteButton'); @@ -203,6 +208,15 @@ timer = setTimeout(trig, timeout); }); })(positionSlider, 500); + + $('#chaptersFlyout').on('click', '.mediaFlyoutOption', function () { + + var ticks = parseInt(this.getAttribute('data-positionticks')); + + seek(ticks); + + hideFlyout($('#chaptersFlyout')); + }); }); function endsWith(text, pattern) { @@ -740,27 +754,29 @@ var url = ""; - if (item.BackdropImageTags && item.BackdropImageTags.length) { + if (imageTags.Primary) { + + url = ApiClient.getImageUrl(item.Id, { + type: "Primary", + height: 80, + tag: item.ImageTags.Primary + }); + } + else if (item.BackdropImageTags && item.BackdropImageTags.length) { url = ApiClient.getImageUrl(item.Id, { type: "Backdrop", - height: 36, + height: 80, tag: item.BackdropImageTags[0] }); } else if (imageTags.Thumb) { url = ApiClient.getImageUrl(item.Id, { type: "Thumb", - height: 36, + height: 80, tag: item.ImageTags.Thumb }); - } else if (imageTags.Primary) { - url = ApiClient.getImageUrl(item.Id, { - type: "Primary", - height: 36, - tag: item.ImageTags.Primary - }); } else { url = "css/images/items/detail/video.png"; } @@ -908,6 +924,11 @@ return currentMediaElement; }; + function hideFlyout(flyout) { + flyout.hide().empty(); + $(document.body).off("mousedown.hidesearchhints"); + } + function showFlyout(flyout, button) { $(document.body).off("mousedown.mediaflyout").on("mousedown.mediaflyout", function (e) { @@ -918,8 +939,7 @@ var safeItems = button + ',#' + flyoutId; if (!elem.is(safeItems) && !elem.parents(safeItems).length) { - flyout.hide(); - $(document.body).off("mousedown.hidesearchhints"); + hideFlyout(flyout); } }); @@ -927,6 +947,63 @@ flyout.show(); } + function getChaptersFlyoutHtml(item) { + + var html = ''; + + var currentTicks = Math.floor(10000000 * currentMediaElement.currentTime) + startTimeTicksOffset; + + for (var i = 0, length = item.Chapters.length; i < length; i++) { + + var chapter = item.Chapters[i]; + + var isSelected = false; + + if (currentTicks >= chapter.StartPositionTicks) { + + var nextChapter = item.Chapters[i + 1]; + + isSelected = !nextChapter || currentTicks < nextChapter.StartPositionTicks; + } + + if (isSelected) { + html += '
'; + } else { + html += '
'; + } + + var imgUrl; + + if (chapter.ImageTag) { + + imgUrl = ApiClient.getImageUrl(item.Id, { + maxwidth: 200, + tag: chapter.ImageTag, + type: "Chapter", + index: i + }); + + } else { + imgUrl = "css/images/media/chapterflyout.png"; + } + + html += ''; + + html += '
'; + + var name = chapter.Name || "Chapter " + (i + 1); + + html += '
' + name + '
'; + html += '
' + DashboardPage.getDisplayText(chapter.StartPositionTicks) + '
'; + + html += '
'; + + html += "
"; + } + + return html; + } + self.showAudioTracksFlyout = function () { var flyout = $('#audioTracksFlyout'); @@ -946,6 +1023,7 @@ showFlyout(flyout, '#chaptersButton'); + flyout.html(getChaptersFlyoutHtml(currentItem)); } }; diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 02003eaff0..94c61592ac 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -1130,7 +1130,7 @@ $(function () { footerHtml += '
'; footerHtml += ''; - footerHtml += '
'; + footerHtml += '
'; footerHtml += '
';