mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
restored chapter flyout
This commit is contained in:
parent
3fc8466680
commit
cd0260b41e
4 changed files with 153 additions and 23 deletions
BIN
dashboard-ui/css/images/media/chapterflyout.png
Normal file
BIN
dashboard-ui/css/images/media/chapterflyout.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 990 B |
|
@ -885,6 +885,58 @@ input[type="range"]::-ms-fill-upper {
|
||||||
z-index: 99999;
|
z-index: 99999;
|
||||||
bottom: 55px;
|
bottom: 55px;
|
||||||
margin-left: -50px;
|
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 {
|
.installedPluginTitle {
|
||||||
|
|
|
@ -115,19 +115,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPositionSliderChange() {
|
function seek(ticks) {
|
||||||
|
|
||||||
isPositionSliderActive = false;
|
|
||||||
|
|
||||||
var element = currentMediaElement;
|
var element = currentMediaElement;
|
||||||
|
|
||||||
var newPercent = parseInt(this.value);
|
|
||||||
|
|
||||||
var newPositionTicks = (newPercent / 100) * currentItem.RunTimeTicks;
|
|
||||||
|
|
||||||
if (isStaticStream) {
|
if (isStaticStream) {
|
||||||
|
|
||||||
element.currentTime = newPositionTicks / (1000 * 10000);
|
element.currentTime = ticks / (1000 * 10000);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -135,10 +129,10 @@
|
||||||
|
|
||||||
if (currentSrc.toLowerCase().indexOf('starttimeticks') == -1) {
|
if (currentSrc.toLowerCase().indexOf('starttimeticks') == -1) {
|
||||||
|
|
||||||
currentSrc += "&starttimeticks=" + newPositionTicks;
|
currentSrc += "&starttimeticks=" + ticks;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
currentSrc = replaceQueryString(currentSrc, 'starttimeticks', newPositionTicks);
|
currentSrc = replaceQueryString(currentSrc, 'starttimeticks', ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearProgressInterval();
|
clearProgressInterval();
|
||||||
|
@ -150,12 +144,23 @@
|
||||||
sendProgressUpdate(currentItem.Id);
|
sendProgressUpdate(currentItem.Id);
|
||||||
|
|
||||||
});
|
});
|
||||||
startTimeTicksOffset = newPositionTicks;
|
startTimeTicksOffset = ticks;
|
||||||
|
|
||||||
element.src = currentSrc;
|
element.src = currentSrc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onPositionSliderChange() {
|
||||||
|
|
||||||
|
isPositionSliderActive = false;
|
||||||
|
|
||||||
|
var newPercent = parseInt(this.value);
|
||||||
|
|
||||||
|
var newPositionTicks = (newPercent / 100) * currentItem.RunTimeTicks;
|
||||||
|
|
||||||
|
seek(newPositionTicks);
|
||||||
|
}
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
muteButton = $('#muteButton');
|
muteButton = $('#muteButton');
|
||||||
|
@ -203,6 +208,15 @@
|
||||||
timer = setTimeout(trig, timeout);
|
timer = setTimeout(trig, timeout);
|
||||||
});
|
});
|
||||||
})(positionSlider, 500);
|
})(positionSlider, 500);
|
||||||
|
|
||||||
|
$('#chaptersFlyout').on('click', '.mediaFlyoutOption', function () {
|
||||||
|
|
||||||
|
var ticks = parseInt(this.getAttribute('data-positionticks'));
|
||||||
|
|
||||||
|
seek(ticks);
|
||||||
|
|
||||||
|
hideFlyout($('#chaptersFlyout'));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function endsWith(text, pattern) {
|
function endsWith(text, pattern) {
|
||||||
|
@ -740,27 +754,29 @@
|
||||||
|
|
||||||
var url = "";
|
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, {
|
url = ApiClient.getImageUrl(item.Id, {
|
||||||
type: "Backdrop",
|
type: "Backdrop",
|
||||||
height: 36,
|
height: 80,
|
||||||
tag: item.BackdropImageTags[0]
|
tag: item.BackdropImageTags[0]
|
||||||
});
|
});
|
||||||
} else if (imageTags.Thumb) {
|
} else if (imageTags.Thumb) {
|
||||||
|
|
||||||
url = ApiClient.getImageUrl(item.Id, {
|
url = ApiClient.getImageUrl(item.Id, {
|
||||||
type: "Thumb",
|
type: "Thumb",
|
||||||
height: 36,
|
height: 80,
|
||||||
tag: item.ImageTags.Thumb
|
tag: item.ImageTags.Thumb
|
||||||
});
|
});
|
||||||
} else if (imageTags.Primary) {
|
|
||||||
|
|
||||||
url = ApiClient.getImageUrl(item.Id, {
|
|
||||||
type: "Primary",
|
|
||||||
height: 36,
|
|
||||||
tag: item.ImageTags.Primary
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
url = "css/images/items/detail/video.png";
|
url = "css/images/items/detail/video.png";
|
||||||
}
|
}
|
||||||
|
@ -908,6 +924,11 @@
|
||||||
return currentMediaElement;
|
return currentMediaElement;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function hideFlyout(flyout) {
|
||||||
|
flyout.hide().empty();
|
||||||
|
$(document.body).off("mousedown.hidesearchhints");
|
||||||
|
}
|
||||||
|
|
||||||
function showFlyout(flyout, button) {
|
function showFlyout(flyout, button) {
|
||||||
|
|
||||||
$(document.body).off("mousedown.mediaflyout").on("mousedown.mediaflyout", function (e) {
|
$(document.body).off("mousedown.mediaflyout").on("mousedown.mediaflyout", function (e) {
|
||||||
|
@ -918,8 +939,7 @@
|
||||||
var safeItems = button + ',#' + flyoutId;
|
var safeItems = button + ',#' + flyoutId;
|
||||||
|
|
||||||
if (!elem.is(safeItems) && !elem.parents(safeItems).length) {
|
if (!elem.is(safeItems) && !elem.parents(safeItems).length) {
|
||||||
flyout.hide();
|
hideFlyout(flyout);
|
||||||
$(document.body).off("mousedown.hidesearchhints");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -927,6 +947,63 @@
|
||||||
flyout.show();
|
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 += '<div data-positionticks="' + chapter.StartPositionTicks + '" class="mediaFlyoutOption selectedMediaFlyoutOption">';
|
||||||
|
} else {
|
||||||
|
html += '<div data-positionticks="' + chapter.StartPositionTicks + '" class="mediaFlyoutOption">';
|
||||||
|
}
|
||||||
|
|
||||||
|
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 += '<img class="mediaFlyoutOptionImage" src="' + imgUrl + '" />';
|
||||||
|
|
||||||
|
html += '<div class="mediaFlyoutOptionContent">';
|
||||||
|
|
||||||
|
var name = chapter.Name || "Chapter " + (i + 1);
|
||||||
|
|
||||||
|
html += '<div class="mediaFlyoutOptionName">' + name + '</div>';
|
||||||
|
html += '<div class="mediaFlyoutOptionSecondaryText">' + DashboardPage.getDisplayText(chapter.StartPositionTicks) + '</div>';
|
||||||
|
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
html += "</div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
self.showAudioTracksFlyout = function () {
|
self.showAudioTracksFlyout = function () {
|
||||||
|
|
||||||
var flyout = $('#audioTracksFlyout');
|
var flyout = $('#audioTracksFlyout');
|
||||||
|
@ -946,6 +1023,7 @@
|
||||||
|
|
||||||
showFlyout(flyout, '#chaptersButton');
|
showFlyout(flyout, '#chaptersButton');
|
||||||
|
|
||||||
|
flyout.html(getChaptersFlyoutHtml(currentItem));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1130,7 +1130,7 @@ $(function () {
|
||||||
footerHtml += '<div class="mediaFlyoutContainer"><div id="subtitleFlyout" style="display:none;" class="mediaPlayerFlyout">Coming soon</div></div>';
|
footerHtml += '<div class="mediaFlyoutContainer"><div id="subtitleFlyout" style="display:none;" class="mediaPlayerFlyout">Coming soon</div></div>';
|
||||||
|
|
||||||
footerHtml += '<button onclick="MediaPlayer.showChaptersFlyout();" id="chaptersButton" class="imageButton mediaButton chaptersButton" title="Scenes" type="button"><img src="css/images/media/chapters.png" /></button>';
|
footerHtml += '<button onclick="MediaPlayer.showChaptersFlyout();" id="chaptersButton" class="imageButton mediaButton chaptersButton" title="Scenes" type="button"><img src="css/images/media/chapters.png" /></button>';
|
||||||
footerHtml += '<div class="mediaFlyoutContainer"><div id="chaptersFlyout" style="display:none;" class="mediaPlayerFlyout">Coming soon</div></div>';
|
footerHtml += '<div class="mediaFlyoutContainer"><div id="chaptersFlyout" style="display:none;" class="mediaPlayerFlyout chaptersFlyout">Coming soon</div></div>';
|
||||||
|
|
||||||
footerHtml += '</div>';
|
footerHtml += '</div>';
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue