mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
update shared item page
This commit is contained in:
parent
eb3e3bfaed
commit
a54146dd0c
16 changed files with 470 additions and 161 deletions
|
@ -211,6 +211,9 @@
|
|||
|
||||
function tryReconnectInternal(deferred, connectionMode, currentRetryCount) {
|
||||
|
||||
var previousConnectionMode = self.serverInfo().LastConnectionMode;
|
||||
var previousServerAddress = MediaBrowser.ServerInfo.getServerAddress(self.serverInfo(), previousConnectionMode);
|
||||
|
||||
connectionMode = switchConnectionMode(connectionMode);
|
||||
var url = MediaBrowser.ServerInfo.getServerAddress(self.serverInfo(), connectionMode);
|
||||
|
||||
|
@ -228,7 +231,7 @@
|
|||
|
||||
}).done(function () {
|
||||
|
||||
logger.log("Reconnect succeeeded to " + url);
|
||||
logger.log("Reconnect succeeded to " + url);
|
||||
|
||||
self.serverInfo().LastConnectionMode = connectionMode;
|
||||
self.serverAddress(url);
|
||||
|
@ -262,25 +265,11 @@
|
|||
return deferred.promise();
|
||||
}
|
||||
|
||||
function replaceServerAddress(url, oldBaseUrl, newBaseUrl) {
|
||||
|
||||
return url.replace(oldBaseUrl, newBaseUrl);
|
||||
}
|
||||
|
||||
self.ajaxWithFailover = function (request, deferred, enableReconnection, replaceUrl) {
|
||||
|
||||
if (replaceUrl) {
|
||||
|
||||
var currentServerInfo = self.serverInfo();
|
||||
|
||||
var baseUrl = MediaBrowser.ServerInfo.getServerAddress(currentServerInfo, currentServerInfo.LastConnectionMode);
|
||||
|
||||
request.url = replaceServerAddress(request.url, baseUrl);
|
||||
}
|
||||
|
||||
logger.log("Requesting " + request.url);
|
||||
|
||||
request.timeout = 15000;
|
||||
request.timeout = 30000;
|
||||
|
||||
HttpClient.send(request).done(function (response) {
|
||||
|
||||
|
@ -301,6 +290,8 @@
|
|||
tryReconnect().done(function () {
|
||||
|
||||
logger.log("Reconnect succeesed");
|
||||
request.url = request.url.replace("dddd", MediaBrowser.ServerInfo.getServerAddress(self.serverInfo(), self.serverInfo().LastConnectionMode));
|
||||
|
||||
self.ajaxWithFailover(request, deferred, false, true);
|
||||
|
||||
}).fail(function () {
|
||||
|
|
19
dashboard-ui/cordova/chromecast.js
vendored
19
dashboard-ui/cordova/chromecast.js
vendored
|
@ -25,13 +25,6 @@
|
|||
|
||||
var castPlayer = {};
|
||||
|
||||
$(castPlayer).on("connect", function (e) {
|
||||
|
||||
Logger.log('cc: connect');
|
||||
// Reset this so the next query doesn't make it appear like content is playing.
|
||||
self.lastPlayerData = {};
|
||||
});
|
||||
|
||||
$(castPlayer).on("playbackstart", function (e, data) {
|
||||
|
||||
Logger.log('cc: playbackstart');
|
||||
|
@ -461,10 +454,12 @@
|
|||
}
|
||||
|
||||
function handleSessionDisconnect() {
|
||||
|
||||
Logger.log("session disconnected");
|
||||
|
||||
cleanupSession();
|
||||
MediaController.removeActivePlayer(PlayerName);
|
||||
// We can't trust this because we might receive events of other devices disconnecting
|
||||
//cleanupSession();
|
||||
//MediaController.removeActivePlayer(PlayerName);
|
||||
}
|
||||
|
||||
function onWebAppSessionConnect(webAppSession, device) {
|
||||
|
@ -476,10 +471,9 @@
|
|||
|
||||
currentDevice = device;
|
||||
currentDeviceId = device.getId();
|
||||
self.lastPlayerData = {};
|
||||
MediaController.setActivePlayer(PlayerName, convertDeviceToTarget(device));
|
||||
|
||||
$(castPlayer).trigger('connect');
|
||||
|
||||
sendIdentifyMessage();
|
||||
}
|
||||
|
||||
|
@ -528,6 +522,7 @@
|
|||
session.release();
|
||||
}
|
||||
|
||||
self.lastPlayerData = {};
|
||||
currentWebAppSession = null;
|
||||
}
|
||||
|
||||
|
@ -592,6 +587,7 @@
|
|||
device.off("ready");
|
||||
|
||||
Logger.log('creating webAppSession');
|
||||
self.lastPlayerData = {};
|
||||
|
||||
launchWebApp(device);
|
||||
}
|
||||
|
@ -653,6 +649,7 @@
|
|||
cleanupSession();
|
||||
currentDevice = null;
|
||||
currentDeviceId = null;
|
||||
self.lastPlayerData = {};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #222;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.itemVideo {
|
||||
|
@ -69,7 +70,7 @@
|
|||
|
||||
.nowPlayingInfo {
|
||||
text-align: center;
|
||||
padding: 1em 1em 2em 1em;
|
||||
padding: 1.5em 1em 2em 1em;
|
||||
}
|
||||
|
||||
#videoPlayer .nowPlayingImage img {
|
||||
|
|
|
@ -311,7 +311,7 @@ html {
|
|||
}
|
||||
|
||||
body {
|
||||
overflow-y: scroll !important;
|
||||
overflow-y: auto !important;
|
||||
/* This is needed to prevent a horizontal scrollbar while neon-animated-pages are animating. */
|
||||
overflow-x: hidden;
|
||||
font-size: 13px;
|
||||
|
|
|
@ -61,15 +61,15 @@
|
|||
|
||||
function onOneVideoPlaying() {
|
||||
|
||||
var requiresNativeControls = !MediaPlayer.enableCustomVideoControls();
|
||||
var requiresNativeControls = !self.enableCustomVideoControls();
|
||||
|
||||
if (requiresNativeControls) {
|
||||
$(this).attr('controls', 'controls');
|
||||
}
|
||||
|
||||
var currentSrc = (this.currentSrc || '').toLowerCase();
|
||||
var src = (self.currentSrc() || '').toLowerCase();
|
||||
|
||||
var parts = currentSrc.split('#');
|
||||
var parts = src.split('#');
|
||||
|
||||
if (parts.length > 1) {
|
||||
|
||||
|
@ -80,7 +80,7 @@
|
|||
var startPositionInSeekParam = parseFloat(parts[1]);
|
||||
|
||||
// Appending #t=xxx to the query string doesn't seem to work with HLS
|
||||
if (startPositionInSeekParam && currentSrc.indexOf('.m3u8') != -1) {
|
||||
if (startPositionInSeekParam && src.indexOf('.m3u8') != -1) {
|
||||
var element = this;
|
||||
setTimeout(function () {
|
||||
element.currentTime = startPositionInSeekParam;
|
||||
|
@ -124,11 +124,35 @@
|
|||
.on('error', onError)[0];
|
||||
}
|
||||
|
||||
function enableViblast() {
|
||||
|
||||
return MediaPlayer.canPlayHls() && !MediaPlayer.canPlayNativeHls();
|
||||
}
|
||||
|
||||
function createVideoElement() {
|
||||
|
||||
var elem = $('.itemVideo');
|
||||
var html = '';
|
||||
|
||||
return elem
|
||||
var requiresNativeControls = !self.enableCustomVideoControls();
|
||||
|
||||
// Can't autoplay in these browsers so we need to use the full controls
|
||||
if (requiresNativeControls && AppInfo.isNativeApp && $.browser.android) {
|
||||
html += '<video class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous" webkit-playsinline>';
|
||||
}
|
||||
else if (requiresNativeControls) {
|
||||
html += '<video class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous" controls="controls" webkit-playsinline>';
|
||||
}
|
||||
else {
|
||||
|
||||
// Chrome 35 won't play with preload none
|
||||
html += '<video class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous" webkit-playsinline>';
|
||||
}
|
||||
|
||||
html += '</video>';
|
||||
|
||||
var elem = $('#videoElement', '#mediaPlayer').prepend(html);
|
||||
|
||||
return $('.itemVideo', elem)
|
||||
.one('.loadedmetadata', onLoadedMetadata)
|
||||
.one('playing', onOneVideoPlaying)
|
||||
.on('timeupdate', onTimeUpdate)
|
||||
|
@ -166,6 +190,10 @@
|
|||
self.stop = function () {
|
||||
if (mediaElement) {
|
||||
mediaElement.pause();
|
||||
|
||||
if (mediaElement.tagName == 'VIDEO' && enableViblast()) {
|
||||
viblast(mediaElement).stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -192,15 +220,18 @@
|
|||
}
|
||||
};
|
||||
|
||||
var currentSrc;
|
||||
self.setCurrentSrc = function (val) {
|
||||
|
||||
var elem = mediaElement;
|
||||
|
||||
if (!elem) {
|
||||
currentSrc = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!val) {
|
||||
currentSrc = null;
|
||||
elem.src = null;
|
||||
elem.src = "";
|
||||
|
||||
|
@ -213,20 +244,50 @@
|
|||
return;
|
||||
}
|
||||
|
||||
elem.src = val;
|
||||
|
||||
if (elem.tagName.toLowerCase() == 'audio') {
|
||||
|
||||
elem.src = val;
|
||||
elem.play();
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
if (enableViblast()) {
|
||||
|
||||
viblast(elem).setup({
|
||||
key: 'N8FjNTQ3NDdhZqZhNGI5NWU5ZTI=',
|
||||
stream: val
|
||||
});
|
||||
|
||||
} else {
|
||||
elem.src = val;
|
||||
$(elem).one("loadedmetadata", onLoadedMetadata);
|
||||
}
|
||||
}
|
||||
alert(val);
|
||||
currentSrc = val;
|
||||
};
|
||||
|
||||
self.setTracks = function (tracks) {
|
||||
|
||||
var html = tracks.map(function (t) {
|
||||
|
||||
var defaultAttribute = t.isDefault ? ' default' : '';
|
||||
|
||||
return '<track kind="subtitles" src="' + t.url + '" srclang="' + t.language + '"' + defaultAttribute + '></track>';
|
||||
|
||||
}).join('');
|
||||
|
||||
if (html) {
|
||||
mediaElement.innerHTML = html;
|
||||
}
|
||||
};
|
||||
|
||||
self.currentSrc = function () {
|
||||
if (mediaElement) {
|
||||
return mediaElement.currentSrc;
|
||||
// We have to use this cached value because viblast will muck with the url
|
||||
return currentSrc;
|
||||
//return mediaElement.currentSrc;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -358,15 +419,47 @@
|
|||
|
||||
$('track', mediaElement).each(function () {
|
||||
|
||||
var currentSrc = this.src;
|
||||
|
||||
currentSrc = replaceQueryString(currentSrc, 'startPositionTicks', startPositionTicks);
|
||||
|
||||
this.src = currentSrc;
|
||||
this.src = replaceQueryString(this.src, 'startPositionTicks', startPositionTicks);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
self.enableCustomVideoControls = function () {
|
||||
|
||||
return self.canAutoPlayVideo() && !$.browser.mobile;
|
||||
};
|
||||
|
||||
self.canAutoPlayVideo = function () {
|
||||
|
||||
if (AppInfo.isNativeApp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($.browser.mobile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
self.init = function () {
|
||||
|
||||
var deferred = DeferredBuilder.Deferred();
|
||||
|
||||
if (type == 'video' && enableViblast()) {
|
||||
|
||||
requirejs(['https://viblast.com/player/free-version/sdqsdx86/viblast.js'], function () {
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
|
||||
return deferred.promise();
|
||||
};
|
||||
|
||||
if (type == 'audio') {
|
||||
mediaElement = createAudioElement();
|
||||
}
|
||||
|
|
|
@ -357,7 +357,7 @@
|
|||
renderCriticReviews(page, item, 1);
|
||||
}
|
||||
|
||||
function renderDetails(page, item, context) {
|
||||
function renderDetails(page, item, context, isStatic) {
|
||||
|
||||
renderSimilarItems(page, item, context);
|
||||
renderSiblingLinks(page, item, context);
|
||||
|
@ -378,8 +378,8 @@
|
|||
|
||||
$('.itemMiscInfo', page).html(LibraryBrowser.getMiscInfoHtml(item));
|
||||
|
||||
LibraryBrowser.renderGenres($('.itemGenres', page), item, context);
|
||||
LibraryBrowser.renderStudios($('.itemStudios', page), item, context);
|
||||
LibraryBrowser.renderGenres($('.itemGenres', page), item, context, null, isStatic);
|
||||
LibraryBrowser.renderStudios($('.itemStudios', page), item, context, isStatic);
|
||||
renderUserDataIcons(page, item);
|
||||
LibraryBrowser.renderLinks(page.querySelector('.itemExternalLinks'), item);
|
||||
|
||||
|
@ -1164,7 +1164,7 @@
|
|||
});
|
||||
}
|
||||
|
||||
function renderScenes(page, item, user, limit) {
|
||||
function renderScenes(page, item, user, limit, isStatic) {
|
||||
var html = '';
|
||||
|
||||
var chapters = item.Chapters || [];
|
||||
|
@ -1180,7 +1180,7 @@
|
|||
var chapter = chapters[i];
|
||||
var chapterName = chapter.Name || "Chapter " + i;
|
||||
|
||||
var onclick = item.PlayAccess == 'Full' ? ' onclick="ItemDetailPage.play(' + chapter.StartPositionTicks + ');"' : '';
|
||||
var onclick = item.PlayAccess == 'Full' && !isStatic ? ' onclick="ItemDetailPage.play(' + chapter.StartPositionTicks + ');"' : '';
|
||||
|
||||
html += '<a class="card detailPage169Card" href="#play-Chapter-' + i + '"' + onclick + '>';
|
||||
|
||||
|
@ -1480,7 +1480,7 @@
|
|||
});
|
||||
}
|
||||
|
||||
function renderCast(page, item, context, limit) {
|
||||
function renderCast(page, item, context, limit, isStatic) {
|
||||
|
||||
var html = '';
|
||||
|
||||
|
@ -1493,8 +1493,8 @@
|
|||
}
|
||||
|
||||
var cast = casts[i];
|
||||
|
||||
html += '<a class="tileItem smallPosterTileItem" href="itembynamedetails.html?context=' + context + '&id=' + cast.Id + '">';
|
||||
var href = isStatic ? '#' : 'itembynamedetails.html?context=' + context + '&id=' + cast.Id + '';
|
||||
html += '<a class="tileItem smallPosterTileItem" href="' + href + '">';
|
||||
|
||||
var imgUrl;
|
||||
|
||||
|
@ -1704,6 +1704,12 @@
|
|||
var self = this;
|
||||
|
||||
self.play = play;
|
||||
self.setInitialCollapsibleState = setInitialCollapsibleState;
|
||||
self.renderDetails = renderDetails;
|
||||
self.renderCriticReviews = renderCriticReviews;
|
||||
self.renderCast = renderCast;
|
||||
self.renderScenes = renderScenes;
|
||||
self.renderMediaSources = renderMediaSources;
|
||||
}
|
||||
|
||||
window.ItemDetailPage = new itemDetailPage();
|
||||
|
|
|
@ -2815,7 +2815,7 @@
|
|||
html += "</a>";
|
||||
}
|
||||
|
||||
var progressHtml = item.IsFolder ? '' : LibraryBrowser.getItemProgressBarHtml((item.Type == 'Recording' ? item : item.UserData));
|
||||
var progressHtml = item.IsFolder || !item.UserData ? '' : LibraryBrowser.getItemProgressBarHtml((item.Type == 'Recording' ? item : item.UserData));
|
||||
|
||||
if (progressHtml) {
|
||||
html += '<div class="detailImageProgressContainer">';
|
||||
|
@ -3059,7 +3059,7 @@
|
|||
|
||||
},
|
||||
|
||||
renderStudios: function (elem, item, context) {
|
||||
renderStudios: function (elem, item, context, isStatic) {
|
||||
|
||||
if (item.Studios && item.Studios.length && item.Type != "Series") {
|
||||
|
||||
|
@ -3071,8 +3071,12 @@
|
|||
html += ' / ';
|
||||
}
|
||||
|
||||
if (isStatic) {
|
||||
html += item.Studios[i].Name;
|
||||
} else {
|
||||
html += '<a class="textlink" href="itembynamedetails.html?context=' + context + '&id=' + item.Studios[i].Id + '">' + item.Studios[i].Name + '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
var translationKey = item.Studios.length > 1 ? "ValueStudios" : "ValueStudio";
|
||||
|
||||
|
@ -3086,7 +3090,7 @@
|
|||
}
|
||||
},
|
||||
|
||||
renderGenres: function (elem, item, context, limit) {
|
||||
renderGenres: function (elem, item, context, limit, isStatic) {
|
||||
|
||||
var html = '';
|
||||
|
||||
|
@ -3108,8 +3112,12 @@
|
|||
param = "gamegenre";
|
||||
}
|
||||
|
||||
if (isStatic) {
|
||||
html += genres[i];
|
||||
} else {
|
||||
html += '<a class="textlink" href="itembynamedetails.html?context=' + context + '&' + param + '=' + ApiClient.encodeName(genres[i]) + '">' + genres[i] + '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
elem.html(html).trigger('create');
|
||||
},
|
||||
|
|
|
@ -70,12 +70,9 @@
|
|||
}
|
||||
|
||||
ApiClient.reportPlaybackStopped(stopInfo);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getTargetsHtml(targets) {
|
||||
|
||||
var playerInfo = MediaController.getPlayerInfo();
|
||||
|
|
|
@ -518,7 +518,7 @@
|
|||
var personHtml = '<div class="tileItem smallPosterTileItem" style="width:300px;">';
|
||||
|
||||
var imgUrl;
|
||||
var height = 160;
|
||||
var height = 150;
|
||||
|
||||
if (cast.PrimaryImageTag) {
|
||||
|
||||
|
@ -612,7 +612,7 @@
|
|||
|
||||
function ensureVideoPlayerElements() {
|
||||
|
||||
var html = '<div id="mediaPlayer" data-theme="b" class="ui-bar-b" style="display: none;">';
|
||||
var html = '<div id="mediaPlayer" style="display: none;">';
|
||||
|
||||
html += '<div class="videoBackdrop">';
|
||||
html += '<div id="videoPlayer">';
|
||||
|
@ -631,10 +631,8 @@
|
|||
|
||||
// Embedding onclicks due to issues not firing in cordova safari
|
||||
html += '<paper-icon-button icon="audiotrack" class="mediaButton videoAudioButton" onclick="MediaPlayer.showAudioTracksFlyout();"></paper-icon-button>';
|
||||
html += '<div data-role="popup" class="videoAudioPopup videoPlayerPopup" data-history="false" data-theme="b"></div>';
|
||||
|
||||
html += '<paper-icon-button icon="subtitles" class="mediaButton videoSubtitleButton" onclick="MediaPlayer.showSubtitleMenu();"></paper-icon-button>';
|
||||
html += '<div data-role="popup" class="videoSubtitlePopup videoPlayerPopup" data-history="false" data-theme="b"></div>';
|
||||
|
||||
html += '<paper-icon-button icon="videocam" class="mediaButton videoChaptersButton" onclick="MediaPlayer.showChaptersFlyout();"></paper-icon-button>';
|
||||
html += '<div data-role="popup" class="videoChaptersPopup videoPlayerPopup" data-history="false" data-theme="b"></div>';
|
||||
|
@ -681,6 +679,7 @@
|
|||
var div = document.createElement('div');
|
||||
div.innerHTML = html;
|
||||
document.body.appendChild(div);
|
||||
$(div).trigger('create');
|
||||
}
|
||||
|
||||
Dashboard.ready(function () {
|
||||
|
@ -926,24 +925,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
self.canAutoPlayVideo = function () {
|
||||
|
||||
if (AppInfo.isNativeApp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($.browser.mobile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
self.enableCustomVideoControls = function () {
|
||||
|
||||
return self.canAutoPlayVideo() && !$.browser.mobile;
|
||||
};
|
||||
|
||||
// Replace audio version
|
||||
self.cleanup = function (mediaRenderer) {
|
||||
|
||||
|
@ -1002,45 +983,7 @@
|
|||
videoUrl += '&EnableAutoStreamCopy=false';
|
||||
}
|
||||
|
||||
var posterCode = self.getPosterUrl(item);
|
||||
posterCode = posterCode ? (' poster="' + posterCode + '"') : '';
|
||||
//======================================================================================>
|
||||
|
||||
// Create video player
|
||||
var html = '';
|
||||
|
||||
var requiresNativeControls = !self.enableCustomVideoControls();
|
||||
|
||||
// Can't autoplay in these browsers so we need to use the full controls
|
||||
if (requiresNativeControls && AppInfo.isNativeApp && $.browser.android) {
|
||||
html += '<video data-viblast-key="N8FjNTQ3NDdhZqZhNGI5NWU5ZTI=" class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous" ' + posterCode + ' webkit-playsinline>';
|
||||
}
|
||||
else if (requiresNativeControls) {
|
||||
html += '<video data-viblast-key="N8FjNTQ3NDdhZqZhNGI5NWU5ZTI=" class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous" controls="controls"' + posterCode + ' webkit-playsinline>';
|
||||
}
|
||||
else {
|
||||
|
||||
// Chrome 35 won't play with preload none
|
||||
html += '<video data-viblast-key="N8FjNTQ3NDdhZqZhNGI5NWU5ZTI=" class="itemVideo" id="itemVideo" preload="metadata" crossorigin="anonymous" autoplay' + posterCode + '>';
|
||||
}
|
||||
|
||||
html += '<source type="' + contentType + '" src="' + videoUrl + '" />';
|
||||
|
||||
var textStreams = subtitleStreams.filter(function (s) {
|
||||
return s.DeliveryMethod == 'External';
|
||||
});
|
||||
|
||||
for (var i = 0, length = textStreams.length; i < length; i++) {
|
||||
|
||||
var textStream = textStreams[i];
|
||||
var textStreamUrl = !textStream.IsExternalUrl ? ApiClient.getUrl(textStream.DeliveryUrl) : textStream.DeliveryUrl;
|
||||
var defaultAttribute = textStream.Index == mediaSource.DefaultSubtitleStreamIndex ? ' default' : '';
|
||||
|
||||
html += '<track kind="subtitles" src="' + textStreamUrl + '" srclang="' + (textStream.Language || 'und') + '"' + defaultAttribute + '></track>';
|
||||
}
|
||||
|
||||
html += '</video>';
|
||||
|
||||
var mediaPlayerContainer = $("#mediaPlayer").show();
|
||||
var videoControls = $('.videoControls', mediaPlayerContainer);
|
||||
|
||||
|
@ -1049,7 +992,7 @@
|
|||
$('#video-pauseButton', videoControls).show();
|
||||
$('.videoTrackControl').hide();
|
||||
|
||||
var videoElement = $('#videoElement', mediaPlayerContainer).prepend(html);
|
||||
var videoElement = $('#videoElement', mediaPlayerContainer);
|
||||
|
||||
$('.videoQualityButton', videoControls).show();
|
||||
|
||||
|
@ -1073,6 +1016,11 @@
|
|||
$('.videoChaptersButton').hide();
|
||||
}
|
||||
|
||||
var mediaRenderer = new VideoRenderer('video');
|
||||
mediaRenderer.setPoster(self.getPosterUrl(item));
|
||||
|
||||
var requiresNativeControls = !mediaRenderer.enableCustomVideoControls();
|
||||
|
||||
if (requiresNativeControls) {
|
||||
$('#video-fullscreenButton', videoControls).hide();
|
||||
} else {
|
||||
|
@ -1095,8 +1043,6 @@
|
|||
videoControls.removeClass('hide');
|
||||
}
|
||||
|
||||
var mediaRenderer = new VideoRenderer('video');
|
||||
|
||||
initialVolume = self.getSavedVolume();
|
||||
|
||||
mediaRenderer.volume(initialVolume);
|
||||
|
@ -1184,8 +1130,6 @@
|
|||
|
||||
bindEventsForPlayback(mediaRenderer);
|
||||
|
||||
mediaPlayerContainer.trigger('create');
|
||||
|
||||
self.currentSubtitleStreamIndex = mediaSource.DefaultSubtitleStreamIndex;
|
||||
|
||||
$(document.body).addClass('bodyWithPopupOpen');
|
||||
|
@ -1194,12 +1138,47 @@
|
|||
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
|
||||
|
||||
self.updateNowPlayingInfo(item);
|
||||
|
||||
mediaRenderer.init().done(function() {
|
||||
|
||||
mediaRenderer.setCurrentSrc(videoUrl, item, mediaSource);
|
||||
|
||||
var textStreams = subtitleStreams.filter(function (s) {
|
||||
return s.DeliveryMethod == 'External';
|
||||
});
|
||||
|
||||
var tracks = [];
|
||||
|
||||
for (var i = 0, length = textStreams.length; i < length; i++) {
|
||||
|
||||
var textStream = textStreams[i];
|
||||
var textStreamUrl = !textStream.IsExternalUrl ? ApiClient.getUrl(textStream.DeliveryUrl) : textStream.DeliveryUrl;
|
||||
|
||||
tracks.push({
|
||||
url: textStreamUrl,
|
||||
language: (textStream.Language || 'und'),
|
||||
isDefault: textStream.Index == mediaSource.DefaultSubtitleStreamIndex
|
||||
});
|
||||
}
|
||||
|
||||
mediaRenderer.setTracks(tracks);
|
||||
|
||||
// IE wont autoplay without this
|
||||
if (videoUrl.indexOf('.m3u8') == -1) {
|
||||
mediaRenderer.unpause();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
self.updatePlaylistUi = function () {
|
||||
var index = self.currentPlaylistIndex(null);
|
||||
var length = self.playlist.length;
|
||||
var requiresNativeControls = !self.enableCustomVideoControls();
|
||||
|
||||
var requiresNativeControls = false;
|
||||
|
||||
if (self.currentMediaRenderer && !self.currentMediaRenderer.enableCustomVideoControls) {
|
||||
requiresNativeControls = self.currentMediaRenderer.enableCustomVideoControls();
|
||||
}
|
||||
|
||||
if (length < 2) {
|
||||
$('.videoTrackControl').hide();
|
||||
|
|
|
@ -500,7 +500,20 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
//return $.browser.chrome || $.browser.msie;
|
||||
if ($.browser.chrome) {
|
||||
|
||||
// viblast can help us here
|
||||
//return true;
|
||||
return window.MediaSource != null;
|
||||
}
|
||||
|
||||
if ($.browser.msie) {
|
||||
|
||||
// viblast can help us here
|
||||
//return true;
|
||||
return window.MediaSource != null;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -721,7 +734,7 @@
|
|||
|
||||
var firstItem = items[0];
|
||||
|
||||
if (options.startPositionTicks || firstItem.MediaType !== 'Video' || !self.canAutoPlayVideo()) {
|
||||
if (options.startPositionTicks || firstItem.MediaType !== 'Video') {
|
||||
|
||||
self.playInternal(firstItem, options.startPositionTicks, function () {
|
||||
self.setPlaylistState(0, items);
|
||||
|
@ -795,7 +808,6 @@
|
|||
playMethod = 'DirectStream';
|
||||
} else {
|
||||
|
||||
startTimeTicksOffset = startPosition || 0;
|
||||
mediaUrl = ApiClient.getUrl(mediaSource.TranscodingUrl);
|
||||
|
||||
if (mediaSource.TranscodingSubProtocol == 'hls') {
|
||||
|
@ -804,6 +816,7 @@
|
|||
contentType = 'application/x-mpegURL';
|
||||
} else {
|
||||
|
||||
startTimeTicksOffset = startPosition || 0;
|
||||
contentType = 'video/' + mediaSource.TranscodingContainer;
|
||||
}
|
||||
}
|
||||
|
@ -836,12 +849,18 @@
|
|||
playMethod = 'DirectStream';
|
||||
} else {
|
||||
|
||||
contentType = 'audio/' + mediaSource.TranscodingContainer;
|
||||
|
||||
mediaUrl = ApiClient.getUrl(mediaSource.TranscodingUrl);
|
||||
}
|
||||
|
||||
if (mediaSource.TranscodingSubProtocol == 'hls') {
|
||||
|
||||
mediaUrl += seekParam;
|
||||
contentType = 'application/x-mpegURL';
|
||||
} else {
|
||||
|
||||
startTimeTicksOffset = startPosition || 0;
|
||||
contentType = 'audio/' + mediaSource.TranscodingContainer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1570,13 +1589,15 @@
|
|||
|
||||
Events.off(mediaRenderer, 'ended', self.onPlaybackStopped);
|
||||
|
||||
var item = self.currentItem;
|
||||
var mediaSource = self.currentMediaSource;
|
||||
|
||||
var state = self.getPlayerStateInternal(mediaRenderer, item, mediaSource);
|
||||
|
||||
self.cleanup(mediaRenderer);
|
||||
|
||||
clearProgressInterval();
|
||||
|
||||
var item = self.currentItem;
|
||||
var mediaSource = self.currentMediaSource;
|
||||
|
||||
if (item.MediaType == "Video") {
|
||||
|
||||
if (self.isFullScreen()) {
|
||||
|
@ -1585,8 +1606,6 @@
|
|||
self.resetEnhancements();
|
||||
}
|
||||
|
||||
var state = self.getPlayerStateInternal(mediaRenderer, item, mediaSource);
|
||||
|
||||
Events.trigger(self, 'playbackstop', [state]);
|
||||
};
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
html += '<paper-icon-button icon="play-arrow" class="mediaButton unpauseButton"></paper-icon-button>';
|
||||
html += '<paper-icon-button icon="pause" class="mediaButton pauseButton"></paper-icon-button>';
|
||||
html += '<paper-icon-button icon="tablet-android" onclick="Dashboard.navigate(\'nowplaying.html\', false);" class="mediaButton remoteControlButton"></paper-icon-button>';
|
||||
html += '<paper-icon-button icon="queue-music" onclick="Dashboard.navigate(\'nowplaying.html?tab=Playlist\', false);" class="mediaButton playlistButton"></paper-icon-button>';
|
||||
html += '<paper-icon-button icon="queue-music" class="mediaButton playlistButton"></paper-icon-button>';
|
||||
|
||||
html += '</div>';
|
||||
|
||||
|
@ -128,6 +128,13 @@
|
|||
}
|
||||
});
|
||||
|
||||
$('.playlistButton', elem).on('click', function () {
|
||||
|
||||
$.mobile.changePage('nowplaying.html', {
|
||||
dataUrl: 'nowplaying.html#playlist'
|
||||
});
|
||||
});
|
||||
|
||||
volumeSlider = $('.nowPlayingBarVolumeSlider', elem).on('change', function () {
|
||||
|
||||
if (currentPlayer) {
|
||||
|
|
|
@ -726,8 +726,8 @@
|
|||
|
||||
loadPlaylist(page);
|
||||
|
||||
var tab = getParameterByName('tab');
|
||||
var selected = tab == 'Playlist' ? 2 : 0;;
|
||||
var tab = window.location.hash;
|
||||
var selected = tab == '#playlist' ? 2 : 0;;
|
||||
this.querySelectorAll('paper-tabs')[0].selected = selected;
|
||||
|
||||
updateCastIcon(page);
|
||||
|
|
99
dashboard-ui/scripts/shared.js
Normal file
99
dashboard-ui/scripts/shared.js
Normal file
|
@ -0,0 +1,99 @@
|
|||
(function ($, document, LibraryBrowser, window) {
|
||||
|
||||
var currentItem;
|
||||
|
||||
function reload(page) {
|
||||
|
||||
var id = getParameterByName('id');
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.getJSON(ApiClient.getUrl('Social/Shares/Public/' + id + '/Item')).done(function (item) {
|
||||
|
||||
reloadFromItem(page, item);
|
||||
});
|
||||
}
|
||||
|
||||
function reloadFromItem(page, item) {
|
||||
|
||||
currentItem = item;
|
||||
|
||||
LibraryBrowser.renderName(item, $('.itemName', page), false);
|
||||
LibraryBrowser.renderParentName(item, $('.parentName', page));
|
||||
LibraryBrowser.renderDetailPageBackdrop(page, item);
|
||||
|
||||
renderImage(page, item);
|
||||
|
||||
setInitialCollapsibleState(page, item);
|
||||
ItemDetailPage.renderDetails(page, item, null, true);
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
}
|
||||
|
||||
function setInitialCollapsibleState(page, item) {
|
||||
|
||||
$('.collectionItems', page).empty();
|
||||
|
||||
if (item.MediaSources && item.MediaSources.length) {
|
||||
ItemDetailPage.renderMediaSources(page, item);
|
||||
}
|
||||
|
||||
var chapters = item.Chapters || [];
|
||||
|
||||
if (!chapters.length || !AppInfo.enableDetailPageChapters) {
|
||||
$('#scenesCollapsible', page).hide();
|
||||
} else {
|
||||
$('#scenesCollapsible', page).show();
|
||||
ItemDetailPage.renderScenes(page, item, null, 3, true);
|
||||
}
|
||||
|
||||
if (!item.People || !item.People.length) {
|
||||
$('#castCollapsible', page).hide();
|
||||
} else {
|
||||
$('#castCollapsible', page).show();
|
||||
ItemDetailPage.renderCast(page, item, null, 6, true);
|
||||
}
|
||||
|
||||
ItemDetailPage.renderCriticReviews(page, item, 1);
|
||||
}
|
||||
|
||||
function renderImage(page, item) {
|
||||
LibraryBrowser.renderDetailImage(page.querySelector('.detailImageContainer'), item, '#');
|
||||
}
|
||||
|
||||
$(document).on('pageinitdepends', "#publicSharedItemPage", function () {
|
||||
|
||||
var page = this;
|
||||
|
||||
$(page).on("click", ".moreScenes", function () {
|
||||
|
||||
ItemDetailPage.renderScenes(page, currentItem, null, null, true);
|
||||
|
||||
}).on("click", ".morePeople", function () {
|
||||
|
||||
ItemDetailPage.renderCast(page, currentItem, null, null, true);
|
||||
|
||||
}).on("click", ".moreCriticReviews", function () {
|
||||
|
||||
ItemDetailPage.renderCriticReviews(page, currentItem);
|
||||
|
||||
});
|
||||
|
||||
}).on('pageshowready', "#publicSharedItemPage", function () {
|
||||
|
||||
var page = this;
|
||||
|
||||
reload(page);
|
||||
|
||||
});
|
||||
|
||||
function itemDetailPage() {
|
||||
|
||||
var self = this;
|
||||
|
||||
self.play = play;
|
||||
}
|
||||
|
||||
window.ItemDetailPage = new itemDetailPage();
|
||||
|
||||
})(jQuery, document, LibraryBrowser, window);
|
|
@ -240,7 +240,11 @@ var Dashboard = {
|
|||
document.createStyleSheet(url);
|
||||
}
|
||||
else {
|
||||
$('<link rel="stylesheet" type="text/css" href="' + url + '" />').appendTo('head');
|
||||
var link = document.createElement('link');
|
||||
link.setAttribute('rel', 'stylesheet');
|
||||
link.setAttribute('type', 'text/css');
|
||||
link.setAttribute('href', url);
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -637,7 +641,10 @@ var Dashboard = {
|
|||
var confirmed = this.closingReason.confirmed;
|
||||
this.parentNode.removeChild(this);
|
||||
document.body.classList.remove('bodyWithPopupOpen');
|
||||
|
||||
if (callback) {
|
||||
callback(confirmed);
|
||||
}
|
||||
});
|
||||
|
||||
dlg.open();
|
||||
|
@ -2007,8 +2014,6 @@ var AppInfo = {};
|
|||
define("sharingwidget", ["scripts/sharingwidget"]);
|
||||
}
|
||||
|
||||
//requirejs(['http://viblast.com/player/free-version/qy2fdwajo1/viblast.js']);
|
||||
|
||||
$.extend(AppInfo, Dashboard.getAppInfo(appName, deviceId, deviceName));
|
||||
|
||||
$(document).on('WebComponentsReady', function () {
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Emby</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="publicSharedItemPage" data-role="page" class="page standalonePage noSecondaryNavPage" data-theme="b" data-require="paperbuttonstyle">
|
||||
|
||||
<div data-role="content">
|
||||
|
||||
Coming soon.
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
122
dashboard-ui/shared.html
Normal file
122
dashboard-ui/shared.html
Normal file
|
@ -0,0 +1,122 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Emby</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="publicSharedItemPage" data-role="page" class="page standalonePage noSecondaryNavPage" data-theme="b" data-require="scripts/shared,scripts/itemdetailpage,paperbuttonstyle,tileitemcss">
|
||||
|
||||
<style>
|
||||
#publicSharedItemPage .header {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 1.5em 1em 1.5em 1em;
|
||||
z-index: 1;
|
||||
background: rgba(0, 0, 0, .6);
|
||||
border-bottom-right-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
<div class="header"><a class="logo" href="http://emby.media" style="text-decoration:none;font-size: 22px;" target="_blank"><img class="imgLogoIcon" src="css/images/mblogoicon.png"><span class="logoLibraryMenuButtonText">EMBY</span></a></div>
|
||||
|
||||
<div id="itemBackdrop" class="itemBackdrop noBackdrop">
|
||||
<div class="itemBackdropContent">
|
||||
|
||||
<div class="detailPageContent primaryDetailPageContent backdropDetailPageContent">
|
||||
|
||||
<div class="detailImageContainer">
|
||||
</div>
|
||||
|
||||
<div class="detailContentEffectedByImage">
|
||||
<p><span class="parentName"></span><span class="itemName inlineItemName"></span><span class="itemMiscInfo" style="display: inline;"></span></p>
|
||||
<p style="margin:1.1em 0">
|
||||
<span class="itemCommunityRating"></span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-role="content">
|
||||
<div class="detailPageContent">
|
||||
|
||||
<div class="detailSection" style="margin-bottom:1.5em;">
|
||||
<div class="detailSectionContent detailContentEffectedByImage lastDetailContentEffectedByImage">
|
||||
|
||||
<p id="artist"></p>
|
||||
<p class="itemGenres"></p>
|
||||
<p class="itemOverview smoothScrollY"></p>
|
||||
<p id="seriesAirTime"></p>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div id="castCollapsible" style="display: none;" class="detailSection">
|
||||
<div id="peopleHeader" class="detailSectionHeader">
|
||||
${HeaderCastCrew}
|
||||
</div>
|
||||
<div id="castContent" class="detailSectionContent"></div>
|
||||
</div>
|
||||
|
||||
<div class="detailSection photoInfo hide">
|
||||
<div class="detailSectionHeader">
|
||||
${HeaderPhotoInfo}
|
||||
</div>
|
||||
<div class="detailSectionContent" style="padding:1em;">
|
||||
<div class="photoInfoContent"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="criticReviewsCollapsible" style="display: none;" class="detailSection">
|
||||
<div class="detailSectionHeader">
|
||||
${HeaderAwardsAndReviews}
|
||||
</div>
|
||||
<div style="padding: 0 .5em;">
|
||||
<p id="awardSummary"></p>
|
||||
<div id="criticRatingSummary" class="criticReview criticRatingSummary" style="display: none;">
|
||||
<p style="margin: 0 0 .5em -40px; font-weight: bold;">TOMATOMETER®</p>
|
||||
<div class="reviewScore">
|
||||
<img src="css/images/fresh.png">
|
||||
</div>
|
||||
<div class="criticRatingScore"></div>
|
||||
<div class="criticRatingSummaryText"></div>
|
||||
</div>
|
||||
<div id="criticReviewsContent" class="detailSectionContent"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detailSection detailsSection">
|
||||
<div class="detailSectionHeader">
|
||||
${HeaderDetails}
|
||||
</div>
|
||||
<div class="detailSectionContent" style="padding:0 1em;">
|
||||
<div class="tabDetails">
|
||||
<p id="players"></p>
|
||||
<p id="itemBudget"></p>
|
||||
<p id="itemRevenue"></p>
|
||||
<p class="itemExternalLinks"></p>
|
||||
<p class="itemStudios"></p>
|
||||
<p class="itemKeywords"></p>
|
||||
<p class="itemTags"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="scenesCollapsible" style="display: none;" class="detailSection">
|
||||
<div class="detailSectionHeader">
|
||||
${HeaderScenes}
|
||||
</div>
|
||||
<div id="scenesContent" class="detailSectionContent smallItemsContainer"></div>
|
||||
</div>
|
||||
|
||||
<div class="detailSection audioVideoMediaInfo hide">
|
||||
<h2 class="detailSectionHeader">${HeaderMediaInfo}</h2>
|
||||
<div class="detailSectionContent" style="padding: 0 .7em;">
|
||||
<div id="mediaInfoContent" class="mediaInfoContent"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue