mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
add basic dlna server browsing
This commit is contained in:
parent
af093d1752
commit
aa5f5fd65a
7 changed files with 175 additions and 36 deletions
|
@ -357,10 +357,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cursor-active {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cursor-inactive {
|
.cursor-inactive {
|
||||||
cursor: none;
|
cursor: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -870,7 +870,7 @@ progress {
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
border-radius: 3px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sessionNowPlayingInnerContent {
|
.sessionNowPlayingInnerContent {
|
||||||
|
@ -882,7 +882,7 @@ progress {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
border-radius: 3px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sessionAppInfo {
|
.sessionAppInfo {
|
||||||
|
@ -931,6 +931,7 @@ progress {
|
||||||
height: 7px;
|
height: 7px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
opacity: .95;
|
opacity: .95;
|
||||||
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notPlayingSession .sessionNowPlayingContent {
|
.notPlayingSession .sessionNowPlayingContent {
|
||||||
|
|
|
@ -211,7 +211,7 @@
|
||||||
|
|
||||||
var className = nowPlayingItem ? 'activeSession' : 'notPlayingSession activeSession';
|
var className = nowPlayingItem ? 'activeSession' : 'notPlayingSession activeSession';
|
||||||
|
|
||||||
html += '<a class="' + className + '" id="' + rowId + '" href="nowplaying.html?id=' + connection.Id + '">';
|
html += '<div class="' + className + '" id="' + rowId + '">';
|
||||||
|
|
||||||
html += '<div class="sessionNowPlayingContent"';
|
html += '<div class="sessionNowPlayingContent"';
|
||||||
|
|
||||||
|
@ -233,8 +233,9 @@
|
||||||
html += clientImage;
|
html += clientImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '<div class="sessionAppName" style="display:inline-block;">' + connection.DeviceName;
|
html += '<div class="sessionAppName" style="display:inline-block;">';
|
||||||
html += '<br/>' + connection.ApplicationVersion;
|
html += '<div class="sessionDeviceName">' + connection.DeviceName + '</div>';
|
||||||
|
html += '<div class="sessionAppSecondaryText">' + DashboardPage.getAppSecondaryText(connection) + '</div>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
@ -256,9 +257,14 @@
|
||||||
|
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
html += '<div class="sessionNowPlayingInfo">';
|
|
||||||
if (nowPlayingItem) {
|
if (nowPlayingItem) {
|
||||||
html += DashboardPage.getNowPlayingName(connection);
|
|
||||||
|
var nowPlayingName = DashboardPage.getNowPlayingName(connection);
|
||||||
|
|
||||||
|
html += '<div class="sessionNowPlayingInfo" data-imgsrc="' + nowPlayingName.image + '">';
|
||||||
|
html += nowPlayingName.html;
|
||||||
|
} else {
|
||||||
|
html += '<div class="sessionNowPlayingInfo">';
|
||||||
}
|
}
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
|
@ -273,35 +279,39 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
html += '</a>';
|
|
||||||
|
html += '<div class="posterItemOverlayTarget"></div>';
|
||||||
|
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parentElement.append(html).trigger('create');
|
parentElement.append(html).createSessionItemMenus().trigger('create');
|
||||||
|
|
||||||
$('.deadSession', parentElement).remove();
|
$('.deadSession', parentElement).remove();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getAppSecondaryText: function (session) {
|
||||||
|
|
||||||
|
return session.ApplicationVersion;
|
||||||
|
},
|
||||||
|
|
||||||
getNowPlayingName: function (session) {
|
getNowPlayingName: function (session) {
|
||||||
|
|
||||||
|
var imgUrl = '';
|
||||||
|
|
||||||
var nowPlayingItem = session.NowPlayingItem;
|
var nowPlayingItem = session.NowPlayingItem;
|
||||||
|
|
||||||
if (!nowPlayingItem) {
|
if (!nowPlayingItem) {
|
||||||
|
|
||||||
return 'Last seen ' + humane_date(session.LastActivityDate);
|
return {
|
||||||
|
html: 'Last seen ' + humane_date(session.LastActivityDate),
|
||||||
|
image: imgUrl
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var topText = nowPlayingItem.Name;
|
var topText = nowPlayingItem.Name;
|
||||||
|
|
||||||
if (nowPlayingItem.MediaType == 'Video') {
|
|
||||||
if (nowPlayingItem.IndexNumber != null) {
|
|
||||||
topText = nowPlayingItem.IndexNumber + " - " + topText;
|
|
||||||
}
|
|
||||||
if (nowPlayingItem.ParentIndexNumber != null) {
|
|
||||||
topText = nowPlayingItem.ParentIndexNumber + "." + topText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var bottomText = '';
|
var bottomText = '';
|
||||||
|
|
||||||
if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) {
|
if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) {
|
||||||
|
@ -316,8 +326,40 @@
|
||||||
bottomText = nowPlayingItem.ProductionYear;
|
bottomText = nowPlayingItem.ProductionYear;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bottomText ? topText + '<br/>' + bottomText : topText;
|
if (nowPlayingItem.LogoItemId) {
|
||||||
|
|
||||||
|
imgUrl = ApiClient.getImageUrl(nowPlayingItem.LogoItemId, {
|
||||||
|
|
||||||
|
tag: session.LogoImageTag,
|
||||||
|
height: 48,
|
||||||
|
type: 'Logo'
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
topText = '<img src="' + imgUrl + '" style="max-height:24px;max-width:130px;" />';
|
||||||
|
}
|
||||||
|
|
||||||
|
var text = bottomText ? topText + '<br/>' + bottomText : topText;
|
||||||
|
|
||||||
|
return {
|
||||||
|
html: text,
|
||||||
|
image: imgUrl
|
||||||
|
};
|
||||||
|
|
||||||
|
//var playstate = session.PlayState;
|
||||||
|
|
||||||
|
//if (playstate) {
|
||||||
|
|
||||||
|
// if (playstate.PlayMethod == 'DirectPlay') {
|
||||||
|
// return 'Direct playing';
|
||||||
|
// }
|
||||||
|
// if (playstate.PlayMethod == 'DirectStream') {
|
||||||
|
// return 'Direct streaming';
|
||||||
|
// }
|
||||||
|
// if (playstate.PlayMethod == 'Transcode') {
|
||||||
|
// text = text + '<div class="sessionPlayMethod">Transcoding</div>';
|
||||||
|
// }
|
||||||
|
//}
|
||||||
},
|
},
|
||||||
|
|
||||||
getUsersHtml: function (session) {
|
getUsersHtml: function (session) {
|
||||||
|
@ -365,7 +407,15 @@
|
||||||
|
|
||||||
$('.sessionUserName', row).html(DashboardPage.getUsersHtml(session));
|
$('.sessionUserName', row).html(DashboardPage.getUsersHtml(session));
|
||||||
|
|
||||||
$('.sessionNowPlayingInfo', row).html(DashboardPage.getNowPlayingName(session));
|
$('.sessionAppSecondaryText', row).html(DashboardPage.getAppSecondaryText(session));
|
||||||
|
|
||||||
|
var nowPlayingName = DashboardPage.getNowPlayingName(session);
|
||||||
|
var nowPlayingInfoElem = $('.sessionNowPlayingInfo', row);
|
||||||
|
|
||||||
|
if (!nowPlayingName.image || nowPlayingName.image != nowPlayingInfoElem.attr('data-imgsrc')) {
|
||||||
|
nowPlayingInfoElem.html(nowPlayingName.html);
|
||||||
|
nowPlayingInfoElem.attr('data-imgsrc', nowPlayingName.image || '');
|
||||||
|
}
|
||||||
|
|
||||||
if (nowPlayingItem && nowPlayingItem.RunTimeTicks) {
|
if (nowPlayingItem && nowPlayingItem.RunTimeTicks) {
|
||||||
|
|
||||||
|
@ -755,3 +805,80 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).on('pageshow', "#dashboardPage", DashboardPage.onPageShow).on('pagehide', "#dashboardPage", DashboardPage.onPageHide);
|
$(document).on('pageshow', "#dashboardPage", DashboardPage.onPageShow).on('pagehide', "#dashboardPage", DashboardPage.onPageHide);
|
||||||
|
|
||||||
|
(function ($, document, window) {
|
||||||
|
|
||||||
|
var showOverlayTimeout;
|
||||||
|
|
||||||
|
function onHoverOut() {
|
||||||
|
|
||||||
|
if (showOverlayTimeout) {
|
||||||
|
clearTimeout(showOverlayTimeout);
|
||||||
|
showOverlayTimeout = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.posterItemOverlayTarget:visible', this).each(function () {
|
||||||
|
|
||||||
|
var elem = this;
|
||||||
|
|
||||||
|
$(this).animate({ "height": "0" }, "fast", function () {
|
||||||
|
|
||||||
|
$(elem).hide();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.posterItemOverlayTarget:visible', this).stop().animate({ "height": "0" }, function () {
|
||||||
|
|
||||||
|
$(this).hide();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn.createSessionItemMenus = function () {
|
||||||
|
|
||||||
|
function onShowTimerExpired(elem) {
|
||||||
|
|
||||||
|
if ($('.itemSelectionPanel:visible', elem).length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var innerElem = $('.posterItemOverlayTarget', elem);
|
||||||
|
|
||||||
|
innerElem.show().each(function () {
|
||||||
|
|
||||||
|
this.style.height = 0;
|
||||||
|
|
||||||
|
}).animate({ "height": "100%" }, "fast");
|
||||||
|
}
|
||||||
|
|
||||||
|
function onHoverIn() {
|
||||||
|
|
||||||
|
if (showOverlayTimeout) {
|
||||||
|
clearTimeout(showOverlayTimeout);
|
||||||
|
showOverlayTimeout = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var elem = this;
|
||||||
|
|
||||||
|
showOverlayTimeout = setTimeout(function () {
|
||||||
|
|
||||||
|
onShowTimerExpired(elem);
|
||||||
|
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how/
|
||||||
|
|
||||||
|
if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) {
|
||||||
|
/* browser with either Touch Events of Pointer Events
|
||||||
|
running on touch-capable device */
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.off('.sessionItemMenu').on('mouseenter.sessionItemMenu', '.activeSession', onHoverIn)
|
||||||
|
.on('mouseleave.sessionItemMenu', '.activeSession', onHoverOut);
|
||||||
|
};
|
||||||
|
|
||||||
|
})(jQuery, document, window);
|
|
@ -1062,7 +1062,7 @@
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
if (version.Name && item.MediaSources.length > 1) {
|
if (version.Name && item.MediaSources.length > 1) {
|
||||||
html += '<span class="mediaInfoAttribute">' + version.Name + '</span><br/>';
|
html += '<div><span class="mediaInfoAttribute">' + version.Name + '</span></div><br/>';
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0, length = version.MediaStreams.length; i < length; i++) {
|
for (var i = 0, length = version.MediaStreams.length; i < length; i++) {
|
||||||
|
@ -1150,8 +1150,23 @@
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version.Container) {
|
||||||
|
html += '<div><span class="mediaInfoLabel">Container</span><span class="mediaInfoAttribute">' + version.Container + '</span></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version.Formats && version.Formats.length) {
|
||||||
|
html += '<div><span class="mediaInfoLabel">Format</span><span class="mediaInfoAttribute">' + version.Formats.join(',') + '</span></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version.Size) {
|
||||||
|
|
||||||
|
var size = (version.Size / (1024 * 1024)).toFixed(0);
|
||||||
|
|
||||||
|
html += '<div><span class="mediaInfoLabel">Size</span><span class="mediaInfoAttribute">' + size + ' MB</span></div>';
|
||||||
|
}
|
||||||
|
|
||||||
if (version.Path) {
|
if (version.Path) {
|
||||||
html += '<br/><span class="mediaInfoLabel">Path</span><span class="mediaInfoAttribute">' + version.Path + '</span>';
|
html += '<div><span class="mediaInfoLabel">Path</span><span class="mediaInfoAttribute">' + version.Path + '</span></div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
|
|
|
@ -279,8 +279,8 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.on('mouseenter', '.backdropPosterItem,.smallBackdropPosterItem,.portraitPosterItem,.squarePosterItem', onHoverIn)
|
return this.off('.posterItemHoverMenu').on('mouseenter.posterItemHoverMenu', '.backdropPosterItem,.smallBackdropPosterItem,.portraitPosterItem,.squarePosterItem', onHoverIn)
|
||||||
.on('mouseleave', '.backdropPosterItem,.smallBackdropPosterItem,.portraitPosterItem,.squarePosterItem', onHoverOut);
|
.on('mouseleave.posterItemHoverMenu', '.backdropPosterItem,.smallBackdropPosterItem,.portraitPosterItem,.squarePosterItem', onHoverOut);
|
||||||
};
|
};
|
||||||
|
|
||||||
function toggleSelections(page) {
|
function toggleSelections(page) {
|
||||||
|
|
|
@ -290,7 +290,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idleState == true) {
|
if (idleState == true) {
|
||||||
video.removeClass("cursor-inactive").addClass("cursor-active");
|
video.removeClass("cursor-inactive");
|
||||||
videoControls.removeClass("inactive").addClass("active");
|
videoControls.removeClass("inactive").addClass("active");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@
|
||||||
|
|
||||||
timeout = window.setTimeout(function () {
|
timeout = window.setTimeout(function () {
|
||||||
idleState = true;
|
idleState = true;
|
||||||
video.removeClass("cursor-active").addClass("cursor-inactive");
|
video.addClass("cursor-inactive");
|
||||||
videoControls.removeClass("active").addClass("inactive");
|
videoControls.removeClass("active").addClass("inactive");
|
||||||
}, 4000);
|
}, 4000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1202,7 +1202,7 @@
|
||||||
if (stream.Type == "Audio") {
|
if (stream.Type == "Audio") {
|
||||||
|
|
||||||
// Stream statically when possible
|
// Stream statically when possible
|
||||||
if (stream.BitRate <= 256000) {
|
if (stream.BitRate <= 320000) {
|
||||||
isStatic = true;
|
isStatic = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue