1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00
This commit is contained in:
Tavares André 2015-04-30 18:20:10 +02:00
commit bb77192e8c
21 changed files with 404 additions and 151 deletions

View file

@ -275,10 +275,6 @@
@media all and (min-width: 540px) { @media all and (min-width: 540px) {
.portraitCard {
width: 25%;
}
.smallBackdropCard { .smallBackdropCard {
width: 33.3%; width: 33.3%;
} }
@ -287,6 +283,12 @@
@media all and (min-width: 640px) { @media all and (min-width: 640px) {
.portraitCard {
width: 25%;
}
}
@media all and (min-width: 700px) {
.backdropCard { .backdropCard {
width: 33.3%; width: 33.3%;
} }
@ -296,7 +298,6 @@
} }
} }
@media all and (min-width: 800px) { @media all and (min-width: 800px) {
.squareCard { .squareCard {
@ -319,10 +320,6 @@
width: 20%; width: 20%;
} }
.backdropCard {
width: 25%;
}
.smallBackdropCard { .smallBackdropCard {
width: 20%; width: 20%;
} }
@ -331,6 +328,10 @@
@media all and (min-width: 1200px) { @media all and (min-width: 1200px) {
.backdropCard {
width: 25%;
}
.squareCard { .squareCard {
width: 16.666666666666666666666666666667%; width: 16.666666666666666666666666666667%;
} }
@ -483,15 +484,6 @@
} }
} }
@media all and (min-width: 600px) {
.detailPageSquareCard {
width: 20%;
}
}
/** homePageSmallBackdropCard */ /** homePageSmallBackdropCard */
.homePageSmallBackdropCard .cardPadder { .homePageSmallBackdropCard .cardPadder {
padding-bottom: 56.25%; padding-bottom: 56.25%;

View file

@ -384,7 +384,7 @@ span.itemCommunityRating:not(:empty) + .userDataIcons {
.noBackdrop { .noBackdrop {
height: auto; height: auto;
margin: 2.5em 0 0; margin: 3em 0 0;
} }
.noBackdrop .itemBackdropContent { .noBackdrop .itemBackdropContent {
@ -633,7 +633,7 @@ span.itemCommunityRating:not(:empty) + .userDataIcons {
.detailSection { .detailSection {
vertical-align: top; vertical-align: top;
margin-bottom: 2em; margin-bottom: 2.5em;
} }
.detailCollapsibleSection:not(.hide) + .detailCollapsibleSection { .detailCollapsibleSection:not(.hide) + .detailCollapsibleSection {
@ -664,7 +664,7 @@ span.itemCommunityRating:not(:empty) + .userDataIcons {
} }
.detailSectionHeader, .detailSectionHeader h3 { .detailSectionHeader, .detailSectionHeader h3 {
font-size: 16px; font-size: 17px;
font-weight: 400; font-weight: 400;
} }
@ -754,13 +754,37 @@ span.itemCommunityRating:not(:empty) + .userDataIcons {
@media all and (max-width: 800px) { @media all and (max-width: 800px) {
.editorMenuLink { .itemBackdrop:not(.noBackdrop) {
display: none; height: 500px;
} }
}
@media all and (max-height: 800px), (max-width: 700px) {
.itemBackdrop:not(.noBackdrop) {
height: 400px;
}
}
@media all and (max-height: 700px) {
.itemBackdrop:not(.noBackdrop) {
height: 340px;
}
}
@media all and (max-height: 600px), (max-width: 600px) {
.itemBackdrop:not(.noBackdrop) { .itemBackdrop:not(.noBackdrop) {
height: 280px; height: 280px;
} }
}
@media all and (max-width: 800px) {
.editorMenuLink {
display: none;
}
.itemDetailImage { .itemDetailImage {
max-height: 240px; max-height: 240px;

View file

@ -8,10 +8,14 @@
.libraryMenuDivider { .libraryMenuDivider {
height: 1px; height: 1px;
background: #333; background: #282828;
margin: .5em 0; margin: .5em 0;
} }
.headerBackButton {
padding-right: 0 !important;
}
.viewMenuBar, .barsMenuButton, .libraryMenuButtonText, .btnCast { .viewMenuBar, .barsMenuButton, .libraryMenuButtonText, .btnCast {
height: 50px; height: 50px;
} }
@ -50,7 +54,6 @@
} }
.headerButtonLeft { .headerButtonLeft {
float: left;
padding: 0 15px; padding: 0 15px;
} }
@ -176,23 +179,23 @@
vertical-align: top; vertical-align: top;
} }
.librarySidebarLinks a { .librarySidebarLinks {
font-weight: 300 !important; margin-left: -1em;
margin-right: -1em;
margin-top: -1em;
padding-top: 0;
} }
.librarySidebarLinks a {
font-weight: 300 !important;
padding: .7em 20px .7em 0;
}
.librarySidebarLinks a:hover { .librarySidebarLinks a:hover {
background-color: #38c !important; background-color: #38c !important;
color: #fff !important; color: #fff !important;
} }
.homeViewMenu {
background-image: url(images/mblogoicon.png) !important;
background-size: 39px 26px !important;
background-position: 13px center !important;
padding-left: 66px !important;
background-repeat: no-repeat !important;
}
.viewMenuSecondary { .viewMenuSecondary {
position: absolute; position: absolute;
top: 0; top: 0;
@ -210,7 +213,7 @@
} }
.ui-panel.ui-body-b { .ui-panel.ui-body-b {
background-color: #222; background-color: #161616;
} }
.libraryViewNav .ui-btn-active { .libraryViewNav .ui-btn-active {

View file

@ -130,8 +130,8 @@
} }
/* Hack for safari because it doesn't allow clickable content over the video surface. */ /* Hack for safari because it doesn't allow clickable content over the video surface. */
.itemVideo { (;top: 9%!important;height: 91% !important;); } /*.itemVideo { (;top: 9%!important;height: 91% !important;); }
.itemVideo { [;top: 9%!important;height: 91% !important;]; } .itemVideo { [;top: 9%!important;height: 91% !important;]; }*/
#mediaPlayer .ui-slider-track, .nowPlayingBar .ui-slider-track, .nowPlayingPage .ui-slider-track { #mediaPlayer .ui-slider-track, .nowPlayingBar .ui-slider-track, .nowPlayingPage .ui-slider-track {
border-color: #2ad !important; border-color: #2ad !important;

View file

@ -156,6 +156,12 @@ h1 a:hover {
display: none; display: none;
} }
.ui-slider-track.ui-mini .ui-slider-handle {
height: 18px;
width: 18px;
margin: -10px 0 0 -10px;
}
.largePanel { .largePanel {
width: 270px; width: 270px;
} }
@ -382,6 +388,7 @@ h1 .imageLink {
font-size: 17px; font-size: 17px;
width: 66px; width: 66px;
text-align: center; text-align: center;
vertical-align: middle;
} }
.ui-page-theme-a .sidebarLinkIcon { .ui-page-theme-a .sidebarLinkIcon {

View file

@ -110,6 +110,12 @@
<a href="gamestudios.html">${TabStudios}</a> <a href="gamestudios.html">${TabStudios}</a>
</div> </div>
</div> </div>
<div class="itemTabs channelTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav">
<a href="channelslatest.html">${TabLatest}</a>
<a href="channels.html" class="ui-btn-active">${TabChannels}</a>
</div>
</div>
<div class="channelHeader" style="display: none;"></div> <div class="channelHeader" style="display: none;"></div>

View file

@ -121,6 +121,35 @@
</select> </select>
</div> </div>
<br /> <br />
<div>
<label for="selectMaxChromecastBitrate">${LabelMaxChromecastBitrate}</label>
<select id="selectMaxChromecastBitrate" data-mini="true">
<option value="30000000">30Mbps</option>
<option value="25000000">25Mbps</option>
<option value="20000000">20Mbps</option>
<option value="15000000">15Mbps</option>
<option value="12000000">12Mbps</option>
<option value="11000000">11Mbps</option>
<option value="10000000">10Mbps</option>
<option value="9000000">9Mbps</option>
<option value="8000000">8Mbps</option>
<option value="7000000">7Mbps</option>
<option value="6000000">6Mbps</option>
<option value="5000000">5Mbps</option>
<option value="4000000">4Mbps</option>
<option value="3000000">3Mbps</option>
<option value="2500000">2.5Mbps</option>
<option value="2000000">2Mbps</option>
<option value="1500000">1.5Mbps</option>
<option value="1000000">1Mbps</option>
<option value="720000">720kbps</option>
<option value="420000">420kbps</option>
<option value="400000">400kbps</option>
<option value="320000">320kbps</option>
<option value="192000">192kbps</option>
</select>
</div>
<br />
<div> <div>
<label for="selectThemeSong">${LabelEnableThemeSongs}</label> <label for="selectThemeSong">${LabelEnableThemeSongs}</label>
<select id="selectThemeSong" data-mini="true"> <select id="selectThemeSong" data-mini="true">

View file

@ -336,8 +336,7 @@
var player = this; var player = this;
var bitrateSetting = AppSettings.maxStreamingBitrate(); var bitrateSetting = AppSettings.maxChromecastBitrate();
bitrateSetting = Math.min(bitrateSetting, 10000000);
var receiverName = null; var receiverName = null;

View file

@ -155,49 +155,49 @@
if (item.MovieCount) { if (item.MovieCount) {
html += '<input type="radio" name="ibnItems" id="radioMovies" class="context-movies" value="on">'; html += '<input type="radio" name="ibnItems" id="radioMovies" class="context-movies" value="on">';
html += '<label for="radioMovies">'+Globalize.translate('TabMovies')+'</label>'; html += '<label for="radioMovies">' + Globalize.translate('TabMovies') + '</label>';
} }
if (item.SeriesCount) { if (item.SeriesCount) {
html += '<input type="radio" name="ibnItems" id="radioShows" class="context-tv" value="on">'; html += '<input type="radio" name="ibnItems" id="radioShows" class="context-tv" value="on">';
html += '<label for="radioShows">'+Globalize.translate('TabSeries')+'</label>'; html += '<label for="radioShows">' + Globalize.translate('TabSeries') + '</label>';
} }
if (item.EpisodeCount) { if (item.EpisodeCount) {
html += '<input type="radio" name="ibnItems" id="radioEpisodes" class="context-tv" value="on">'; html += '<input type="radio" name="ibnItems" id="radioEpisodes" class="context-tv" value="on">';
html += '<label for="radioEpisodes">'+Globalize.translate('TabEpisodes')+'</label>'; html += '<label for="radioEpisodes">' + Globalize.translate('TabEpisodes') + '</label>';
} }
if (item.TrailerCount) { if (item.TrailerCount) {
html += '<input type="radio" name="ibnItems" id="radioTrailers" class="context-movies" value="on">'; html += '<input type="radio" name="ibnItems" id="radioTrailers" class="context-movies" value="on">';
html += '<label for="radioTrailers">'+Globalize.translate('TabTrailers')+'</label>'; html += '<label for="radioTrailers">' + Globalize.translate('TabTrailers') + '</label>';
} }
if (item.GameCount) { if (item.GameCount) {
html += '<input type="radio" name="ibnItems" id="radioGames" class="context-games" value="on">'; html += '<input type="radio" name="ibnItems" id="radioGames" class="context-games" value="on">';
html += '<label for="radioGames">'+Globalize.translate('TabGames')+'</label>'; html += '<label for="radioGames">' + Globalize.translate('TabGames') + '</label>';
} }
if (item.AlbumCount) { if (item.AlbumCount) {
html += '<input type="radio" name="ibnItems" id="radioAlbums" class="context-music" value="on">'; html += '<input type="radio" name="ibnItems" id="radioAlbums" class="context-music" value="on">';
html += '<label for="radioAlbums">'+Globalize.translate('TabAlbums')+'</label>'; html += '<label for="radioAlbums">' + Globalize.translate('TabAlbums') + '</label>';
} }
if (item.SongCount) { if (item.SongCount) {
html += '<input type="radio" name="ibnItems" id="radioSongs" class="context-music" value="on">'; html += '<input type="radio" name="ibnItems" id="radioSongs" class="context-music" value="on">';
html += '<label for="radioSongs">'+Globalize.translate('TabSongs')+'</label>'; html += '<label for="radioSongs">' + Globalize.translate('TabSongs') + '</label>';
} }
if (item.MusicVideoCount) { if (item.MusicVideoCount) {
html += '<input type="radio" name="ibnItems" id="radioMusicVideos" class="context-music" value="on">'; html += '<input type="radio" name="ibnItems" id="radioMusicVideos" class="context-music" value="on">';
html += '<label for="radioMusicVideos">'+Globalize.translate('TabMusicVideos')+'</label>'; html += '<label for="radioMusicVideos">' + Globalize.translate('TabMusicVideos') + '</label>';
} }
html += '</fieldset>'; html += '</fieldset>';
@ -385,7 +385,7 @@
} }
} }
function getItemsFunction(options) { function getQuery(options) {
var query = { var query = {
@ -407,6 +407,13 @@
addCurrentItemToQuery(query); addCurrentItemToQuery(query);
return query;
}
function getItemsFunction(options) {
var query = getQuery(options);
return function (index, limit, fields) { return function (index, limit, fields) {
query.StartIndex = index; query.StartIndex = index;
@ -424,27 +431,10 @@
Dashboard.showLoadingMsg(); Dashboard.showLoadingMsg();
_childrenItemsFunction = getItemsFunction(options); _childrenItemsFunction = getItemsFunction(options);
var query = {
SortBy: "SortName", var query = getQuery(options);
SortOrder: "Ascending",
IncludeItemTypes: "",
Recursive: true,
Fields: "AudioInfo,SeriesInfo,ParentId,PrimaryImageAspectRatio,SyncInfo",
Limit: LibraryBrowser.getDefaultPageSize(),
StartIndex: 0,
CollapseBoxSetItems: false
};
query = $.extend(query, options || {}); getItemsFunction(options)(options.StartIndex, options.Limit, options.Fields).done(function (result) {
if (query.IncludeItemTypes == "Audio") {
query.SortBy = "AlbumArtist,Album,SortName";
}
addCurrentItemToQuery(query);
ApiClient.getItems(Dashboard.getCurrentUserId(), query).done(function (result) {
var html = ''; var html = '';

View file

@ -282,6 +282,9 @@
$('.lnkMovies', page).addClass('ui-btn-active'); $('.lnkMovies', page).addClass('ui-btn-active');
} }
} }
else if (context == 'channels') {
elem = $('.channelTabs', page).show();
}
else if (item.Type == "MusicAlbum") { else if (item.Type == "MusicAlbum") {
$('#albumTabs', page).show(); $('#albumTabs', page).show();
} }
@ -627,6 +630,7 @@
promise = ApiClient.getSimilarTrailers(item.Id, options); promise = ApiClient.getSimilarTrailers(item.Id, options);
} }
else if (item.Type == "MusicAlbum") { else if (item.Type == "MusicAlbum") {
options.limit = 4;
promise = ApiClient.getSimilarAlbums(item.Id, options); promise = ApiClient.getSimilarAlbums(item.Id, options);
} }
else if (item.Type == "Series") { else if (item.Type == "Series") {
@ -1314,7 +1318,7 @@
if (stream.ChannelLayout) { if (stream.ChannelLayout) {
attributes.push(createAttribute(Globalize.translate('MediaInfoLayout'), stream.ChannelLayout)); attributes.push(createAttribute(Globalize.translate('MediaInfoLayout'), stream.ChannelLayout));
} }
else if (stream.Channels) { if (stream.Channels) {
attributes.push(createAttribute(Globalize.translate('MediaInfoChannels'), stream.Channels + ' ch')); attributes.push(createAttribute(Globalize.translate('MediaInfoChannels'), stream.Channels + ' ch'));
} }

View file

@ -4,6 +4,10 @@
var html = '<div class="viewMenuBar ui-bar-b">'; var html = '<div class="viewMenuBar ui-bar-b">';
if ($.browser.safari && $.browser.mobile && window.navigator.standalone) {
html += '<a data-rel="back" data-role="none" href="#" class="headerButton headerButtonLeft headerBackButton"><div class="fa fa-arrow-circle-o-left"></div></a>';
}
html += '<button type="button" data-role="none" title="Menu" class="headerButton dashboardMenuButton barsMenuButton headerButtonLeft">'; html += '<button type="button" data-role="none" title="Menu" class="headerButton dashboardMenuButton barsMenuButton headerButtonLeft">';
html += '<div class="barMenuInner fa fa-bars">'; html += '<div class="barMenuInner fa fa-bars">';
html += '</div>'; html += '</div>';
@ -46,7 +50,7 @@
var url = user.imageUrl; var url = user.imageUrl;
if (user.supportsImageParams) { if (user.supportsImageParams) {
url += "&height=" + userButtonHeight; url += "&height=" + (userButtonHeight * Math.max(devicePixelRatio || 1, 2));
} }
html += '<img src="' + url + '" style="border-radius: 1000px; height:' + userButtonHeight + 'px;" />'; html += '<img src="' + url + '" style="border-radius: 1000px; height:' + userButtonHeight + 'px;" />';
@ -68,10 +72,25 @@
$('.viewMenuBar').trigger('create'); $('.viewMenuBar').trigger('create');
$(document).trigger('headercreated'); $(document).trigger('headercreated');
bindMenuEvents();
}
function bindMenuEvents() {
if ($.browser.mobile) {
$('.libraryMenuButton').on('mousedown', function () {
showLibraryMenu(false);
});
$('.dashboardMenuButton').on('mousedown', function () {
showDashboardMenu(false);
});
} else {
$('.libraryMenuButton').createHoverTouch().on('hovertouch', showLibraryMenu); $('.libraryMenuButton').createHoverTouch().on('hovertouch', showLibraryMenu);
$('.dashboardMenuButton').createHoverTouch().on('hovertouch', showDashboardMenu); $('.dashboardMenuButton').createHoverTouch().on('hovertouch', showDashboardMenu);
} }
}
function getItemHref(item, context) { function getItemHref(item, context) {
@ -102,7 +121,9 @@
var page = $.mobile.activePage; var page = $.mobile.activePage;
var panel; var panel;
panel = getLibraryMenu(); ConnectionManager.user().done(function (user) {
panel = getLibraryMenu(user);
updateLibraryNavLinks(page); updateLibraryNavLinks(page);
$(panel).panel('toggle').off('mouseleave.librarymenu').on('mouseleave.librarymenu', function () { $(panel).panel('toggle').off('mouseleave.librarymenu').on('mouseleave.librarymenu', function () {
@ -110,6 +131,7 @@
$(this).panel("close"); $(this).panel("close");
}); });
});
} }
function showDashboardMenu() { function showDashboardMenu() {
@ -229,13 +251,42 @@
html += '<div data-role="panel" id="libraryPanel" class="libraryPanel" data-position="left" data-display="overlay" data-position-fixed="true" data-theme="b">'; html += '<div data-role="panel" id="libraryPanel" class="libraryPanel" data-position="left" data-display="overlay" data-position-fixed="true" data-theme="b">';
html += '<div class="sidebarLinks librarySidebarLinks" style="margin-top: 0;margin-left: -1em;margin-right: -1em;">'; html += '<div class="sidebarLinks librarySidebarLinks">';
//var userHref = user.localUser && user.localUser.Policy.EnableUserPreferenceAccess ?
// 'mypreferencesdisplay.html?userId=' + user.localUser.Id :
// (user.localUser ? 'index.html' : '#');
//var paddingLeft = user.imageUrl ? 'padding-left:.7em;' : '';
//html += '<a style="margin-top:0;' + paddingLeft + 'display:block;color:#fff;text-decoration:none;font-size:16px;font-weight:400!important;background: #000;" href="' + userHref + '">';
//var imgWidth = 44;
//if (user.imageUrl) {
// var url = user.imageUrl;
// if (user.supportsImageParams) {
// url += "&width=" + (imgWidth * Math.max(devicePixelRatio || 1, 2));
// }
// html += '<img style="max-width:' + imgWidth + 'px;vertical-align:middle;margin-right:.8em;border-radius: 50px;" src="' + url + '" />';
//} else {
// html += '<span class="fa fa-user sidebarLinkIcon"></span>';
//}
//html += user.name;
//html += '</a>';
var homeHref = ConnectionManager.currentApiClient() ? 'index.html' : 'selectserver.html'; var homeHref = ConnectionManager.currentApiClient() ? 'index.html' : 'selectserver.html';
html += '<a class="lnkMediaFolder sidebarLink homeViewMenu" href="' + homeHref + '">' + Globalize.translate('ButtonHome') + '</a>'; html += '<a class="lnkMediaFolder sidebarLink" style="margin-top:.5em;padding-left:1em;display:block;color:#fff;text-decoration:none;" href="' + homeHref + '">';
html += '<div class="libraryMenuDivider"></div>'; html += '<img style="max-width:36px;vertical-align:middle;margin-right:1em;" src="css/images/mblogoicon.png" />';
html += Globalize.translate('ButtonHome');
html += '</a>';
html += '<div class="libraryMenuDivider" style="margin-top:0;"></div>';
html += getViewsHtml(); html += getViewsHtml();
html += '</div>'; html += '</div>';

View file

@ -69,9 +69,6 @@
ApiClient.reportPlaybackStopped(stopInfo); ApiClient.reportPlaybackStopped(stopInfo);
}).on('positionchange.mediacontroller', function (e, state) {
}); });
} }

View file

@ -931,6 +931,31 @@
var streamInfo = self.createStreamInfo('Video', item, mediaSource, startPosition); var streamInfo = self.createStreamInfo('Video', item, mediaSource, startPosition);
// Huge hack alert. Safari doesn't seem to like if the segments aren't available right away when playback starts
// This will start the transcoding process before actually feeding the video url into the player
if ($.browser.safari && !mediaSource.RunTimeTicks) {
Dashboard.showLoadingMsg();
ApiClient.ajax({
type: 'GET',
url: streamInfo.url.replace('master.m3u8', 'live.m3u8')
}).always(function () {
Dashboard.hideLoadingMsg();
}).done(function () {
self.playVideoInternal(item, mediaSource, startPosition, streamInfo);
});
} else {
self.playVideoInternal(item, mediaSource, startPosition, streamInfo);
}
};
self.playVideoInternal = function (item, mediaSource, startPosition, streamInfo) {
var videoUrl = streamInfo.url; var videoUrl = streamInfo.url;
var contentType = streamInfo.contentType; var contentType = streamInfo.contentType;
var startPositionInSeekParam = streamInfo.startPositionInSeekParam; var startPositionInSeekParam = streamInfo.startPositionInSeekParam;
@ -941,6 +966,31 @@
return s.Type == 'Subtitle'; return s.Type == 'Subtitle';
}); });
// Get Video Poster (Code from librarybrowser.js)
var screenWidth = Math.max(screen.height, screen.width);
var posterCode = '';
if (item.BackdropImageTags && item.BackdropImageTags.length) {
posterCode = ' poster="' + ApiClient.getScaledImageUrl(item.Id, {
type: "Backdrop",
index: 0,
maxWidth: screenWidth,
tag: item.BackdropImageTags[0]
}) + '"';
}
else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
posterCode = ' poster="' + ApiClient.getScaledImageUrl(item.ParentBackdropItemId, {
type: 'Backdrop',
index: 0,
maxWidth: screenWidth,
tag: item.ParentBackdropImageTags[0]
}) + '"';
}
//======================================================================================> //======================================================================================>
// Create video player // Create video player
@ -950,11 +1000,12 @@
// Can't autoplay in these browsers so we need to use the full controls // Can't autoplay in these browsers so we need to use the full controls
if (requiresNativeControls) { if (requiresNativeControls) {
html += '<video class="itemVideo" id="itemVideo" preload="none" autoplay="autoplay" crossorigin="anonymous" controls="controls">'; html += '<video class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous" controls="controls"' + posterCode + '>';
} else { }
else {
// Chrome 35 won't play with preload none // Chrome 35 won't play with preload none
html += '<video class="itemVideo" id="itemVideo" preload="metadata" crossorigin="anonymous" autoplay>'; html += '<video class="itemVideo" id="itemVideo" preload="metadata" crossorigin="anonymous" autoplay' + posterCode + '>';
} }
html += '<source type="' + contentType + '" src="' + videoUrl + '" />'; html += '<source type="' + contentType + '" src="' + videoUrl + '" />';
@ -1142,7 +1193,10 @@
$('body').addClass('bodyWithPopupOpen'); $('body').addClass('bodyWithPopupOpen');
return video[0]; self.currentMediaElement = video[0];
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
self.updateNowPlayingInfo(item);
}; };
self.updatePlaylistUi = function () { self.updatePlaylistUi = function () {

View file

@ -208,13 +208,22 @@
profile.ContainerProfiles = []; profile.ContainerProfiles = [];
var audioConditions = []; var audioConditions = [];
if ($.browser.msie) { var videoAudioAacConditions = [];
audioConditions.push({ var videoAudioMp3Conditions = [];
var maxAudioChannels = $.browser.msie || $.browser.safari ?
'2' :
'6';
var channelCondition = {
Condition: 'LessThanEqual', Condition: 'LessThanEqual',
Property: 'AudioChannels', Property: 'AudioChannels',
Value: '2' Value: maxAudioChannels
}); };
}
audioConditions.push(channelCondition);
videoAudioAacConditions.push(channelCondition);
videoAudioMp3Conditions.push(channelCondition);
profile.CodecProfiles = []; profile.CodecProfiles = [];
profile.CodecProfiles.push({ profile.CodecProfiles.push({
@ -222,21 +231,36 @@
Conditions: audioConditions Conditions: audioConditions
}); });
if (videoAudioMp3Conditions.length) {
profile.CodecProfiles.push({ profile.CodecProfiles.push({
Type: 'VideoAudio', Type: 'VideoAudio',
Conditions: audioConditions Codec: 'mp3',
Conditions: videoAudioMp3Conditions
});
}
videoAudioAacConditions.push({
Condition: 'NotEquals',
Property: 'AudioProfile',
Value: 'LC'
});
videoAudioAacConditions.push({
Condition: 'NotEquals',
Property: 'AudioProfile',
Value: 'HE-AAC'
});
profile.CodecProfiles.push({
Type: 'VideoAudio',
Codec: 'aac',
Conditions: videoAudioAacConditions
}); });
profile.CodecProfiles.push({ profile.CodecProfiles.push({
Type: 'Video', Type: 'Video',
Codec: 'h264', Codec: 'h264',
Conditions: [ Conditions: [
{
Condition: 'Equals',
Property: 'IsCabac',
Value: 'true',
IsRequired: false
},
{ {
Condition: 'NotEquals', Condition: 'NotEquals',
Property: 'IsAnamorphic', Property: 'IsAnamorphic',
@ -355,36 +379,6 @@
return false; return false;
}; };
self.getVideoTranscodingExtension = function (currentSrc) {
if (currentSrc) {
return self.getCurrentMediaExtension(currentSrc);
}
// safari
if (self.canPlayHls()) {
return '.m3u8';
}
// Chrome, Firefox or IE with plugin installed
// For some reason in chrome pausing mp4 is causing the video to fail.
// So for now it will have to prioritize webm
if (self.canPlayWebm()) {
if ($.browser.msie) {
return '.webm';
}
if ($.browser.chrome) {
return '.webm';
}
// Firefox suddenly having trouble with our webm
return '.webm';
}
return '.mp4';
};
self.changeStream = function (ticks, params) { self.changeStream = function (ticks, params) {
var element = self.currentMediaElement; var element = self.currentMediaElement;
@ -871,10 +865,7 @@
if (item.MediaType === "Video") { if (item.MediaType === "Video") {
self.currentMediaElement = self.playVideo(item, self.currentMediaSource, startPosition); self.playVideo(item, self.currentMediaSource, startPosition);
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
self.updateNowPlayingInfo(item);
} else if (item.MediaType === "Audio") { } else if (item.MediaType === "Audio") {

View file

@ -400,7 +400,7 @@
// The button is created dynamically // The button is created dynamically
$(page).on('click', '.btnNewCollection', function () { $(page).on('click', '.btnNewCollection', function () {
showCollectionPanel(page, []); showCollectionPanel([]);
}); });
}); });

View file

@ -4,7 +4,7 @@
var screenWidth = $(window).width(); var screenWidth = $(window).width();
return screenWidth >= 1920 ? 9 : 8; return screenWidth >= 1920 ? 9 : (screenWidth >= 1200 ? 12 : (screenWidth >= 1000 ? 10 : 8));
} }
function loadLatest(page, parentId) { function loadLatest(page, parentId) {

View file

@ -5,6 +5,7 @@
var externalPlayers = JSON.parse(store.getItem('externalplayers') || '[]'); var externalPlayers = JSON.parse(store.getItem('externalplayers') || '[]');
$('#selectMaxBitrate', page).val(AppSettings.maxStreamingBitrate()).selectmenu("refresh"); $('#selectMaxBitrate', page).val(AppSettings.maxStreamingBitrate()).selectmenu("refresh");
$('#selectMaxChromecastBitrate', page).val(AppSettings.maxChromecastBitrate()).selectmenu("refresh");
$('.chkExternalPlayer', page).each(function () { $('.chkExternalPlayer', page).each(function () {
@ -66,6 +67,7 @@
store.setItem('externalplayers', JSON.stringify(externalPlayers)); store.setItem('externalplayers', JSON.stringify(externalPlayers));
AppSettings.maxStreamingBitrate($('#selectMaxBitrate', page).val()); AppSettings.maxStreamingBitrate($('#selectMaxBitrate', page).val());
AppSettings.maxChromecastBitrate($('#selectMaxChromecastBitrate', page).val());
var userId = getParameterByName('userId') || Dashboard.getCurrentUserId(); var userId = getParameterByName('userId') || Dashboard.getCurrentUserId();
@ -122,6 +124,14 @@
} }
return parseInt(store.getItem('preferredVideoBitrate') || '') || 1500000; return parseInt(store.getItem('preferredVideoBitrate') || '') || 1500000;
},
maxChromecastBitrate: function (val) {
if (val != null) {
store.setItem('chromecastBitrate', val);
}
return parseInt(store.getItem('chromecastBitrate') || '') || 3000000;
} }
}; };

View file

@ -40,6 +40,8 @@
updateFilterControls(page); updateFilterControls(page);
var defaultAction = query.MediaTypes == 'Photo' ? 'photoslideshow' : null;
// Poster // Poster
html = LibraryBrowser.getPosterViewHtml({ html = LibraryBrowser.getPosterViewHtml({
items: result.Items, items: result.Items,
@ -47,7 +49,8 @@
context: getParameterByName('context') || 'photos', context: getParameterByName('context') || 'photos',
showTitle: false, showTitle: false,
centerText: true, centerText: true,
lazy: true lazy: true,
defaultAction: defaultAction
}); });
var elem = $('#items', page).html(html).lazyChildren(); var elem = $('#items', page).html(html).lazyChildren();
@ -134,6 +137,50 @@
query.ParentId = getParameterByName('parentId') || LibraryMenu.getTopParentId(); query.ParentId = getParameterByName('parentId') || LibraryMenu.getTopParentId();
} }
function startSlideshow(page, index) {
index += (query.StartIndex || 0);
var userId = Dashboard.getCurrentUserId();
var localQuery = $.extend({}, query);
localQuery.StartIndex = 0;
localQuery.Limit = null;
localQuery.MediaTypes = "Photo";
localQuery.Recursive = true;
localQuery.Filters = "IsNotFolder";
ApiClient.getItems(userId, localQuery).done(function (result) {
showSlideshow(page, result.Items, index);
});
}
function showSlideshow(page, items, index) {
var slideshowItems = items.map(function (item) {
var imgUrl = ApiClient.getScaledImageUrl(item.Id, {
tag: item.ImageTags.Primary,
type: 'Primary'
});
return {
title: item.Name,
href: imgUrl
};
});
index = Math.max(index || 0, 0);
$.swipebox(slideshowItems, {
initialIndexOnArray: index,
hideBarsDelay: 30000
});
}
$(document).on('pageinit', "#photosPage", function () { $(document).on('pageinit', "#photosPage", function () {
var page = this; var page = this;
@ -197,6 +244,10 @@
reloadItems(page); reloadItems(page);
}); });
$('.itemsContainer', page).on('photoslideshow', function (e, index) {
startSlideshow(page, index);
});
}).on('pagebeforeshow', "#photosPage", function () { }).on('pagebeforeshow', "#photosPage", function () {
var page = this; var page = this;

View file

@ -577,14 +577,16 @@ var Dashboard = {
html += '<h3>'; html += '<h3>';
var imgWidth = 48;
if (user.imageUrl) { if (user.imageUrl) {
var url = user.imageUrl; var url = user.imageUrl;
if (user.supportsImageParams) { if (user.supportsImageParams) {
url += "&width=" + 28; url += "&width=" + (imgWidth * Math.max(devicePixelRatio || 1, 2));
} }
html += '<img style="max-width:28px;vertical-align:middle;margin-right:5px;" src="' + url + '" />'; html += '<img style="max-width:' + imgWidth + 'px;vertical-align:middle;margin-right:.5em;border-radius: 50px;" src="' + url + '" />';
} }
html += user.name; html += user.name;
html += '</h3>'; html += '</h3>';
@ -1385,6 +1387,27 @@ var Dashboard = {
if (window.ApiClient) { if (window.ApiClient) {
Dashboard.importCss(ApiClient.getUrl('Branding/Css')); Dashboard.importCss(ApiClient.getUrl('Branding/Css'));
ApiClient.getDefaultImageQuality = function (imageType) {
var quality = 90;
var isBackdrop = imageType.toLowerCase() == 'backdrop';
if (isBackdrop) {
quality -= 10;
}
if ($.browser.safari && $.browser.mobile) {
quality -= 10;
if (isBackdrop) {
quality -= 10;
}
}
return quality;
};
} }
})(); })();

View file

@ -54,6 +54,25 @@
return serverInfo; return serverInfo;
}; };
var currentUser;
/**
* Gets or sets the current user id.
*/
self.getCurrentUser = function () {
if (currentUser != null) {
var deferred = DeferredBuilder.Deferred();
deferred.resolveWith(null, [currentUser]);
return deferred.promise();
}
return self.getUser(self.getCurrentUserId()).done(function (user) {
currentUser = user;
});
};
/** /**
* Gets or sets the current user id. * Gets or sets the current user id.
*/ */
@ -69,6 +88,7 @@
self.setCurrentUserId = function (userId, token) { self.setCurrentUserId = function (userId, token) {
currentUserId = userId; currentUserId = userId;
currentUser = null;
accessToken = token; accessToken = token;
}; };
@ -2305,6 +2325,10 @@
}); });
}; };
self.getDefaultImageQuality = function (imageType) {
return imageType.toLowerCase() == 'backdrop' ? 80 : 90;
};
function normalizeImageOptions(options) { function normalizeImageOptions(options) {
var ratio = devicePixelRatio || 1; var ratio = devicePixelRatio || 1;
@ -2329,7 +2353,7 @@
} }
} }
options.quality = options.quality || (options.type.toLowerCase() == 'backdrop' ? 80 : 90); options.quality = options.quality || self.getDefaultImageQuality(options.type);
} }
/** /**
@ -2350,9 +2374,7 @@
throw new Error("null userId"); throw new Error("null userId");
} }
options = options || { options = options || {};
};
var url = "Users/" + userId + "/Images/" + options.type; var url = "Users/" + userId + "/Images/" + options.type;

View file

@ -433,7 +433,7 @@
var apiClient = self.currentApiClient(); var apiClient = self.currentApiClient();
if (apiClient && apiClient.getCurrentUserId()) { if (apiClient && apiClient.getCurrentUserId()) {
apiClient.getUser(apiClient.getCurrentUserId()).done(function (u) { apiClient.getCurrentUser().done(function (u) {
localUser = u; localUser = u;
}).always(onLocalUserDone); }).always(onLocalUserDone);
} else { } else {