';
}
var shape = item.Type == "MusicAlbum" || item.Type == "MusicArtist" ? getSquareShape() : getPortraitShape();
var supportsImageAnalysis = appHost.supports('imageanalysis');
html += cardBuilder.getCardsHtml({
items: result.Items,
shape: shape,
showParentTitle: item.Type == "MusicAlbum",
centerText: !supportsImageAnalysis,
showTitle: item.Type == "MusicAlbum" || item.Type == "Game" || item.Type == "MusicArtist",
coverImage: item.Type == "MusicAlbum" || item.Type == "MusicArtist",
overlayPlayButton: true,
cardLayout: supportsImageAnalysis,
vibrant: supportsImageAnalysis
});
html += '
';
var similarContent = page.querySelector('#moreFromItems');
similarContent.innerHTML = html;
imageLoader.lazyChildren(similarContent);
});
}
function renderSimilarItems(page, item, context) {
var similarCollapsible = page.querySelector('#similarCollapsible');
if (!similarCollapsible) {
return;
}
if (item.Type == "Movie" || item.Type == "Trailer" || item.Type == "Series" || item.Type == "Program" || item.Type == "Recording" || item.Type == "Game" || item.Type == "MusicAlbum" || item.Type == "MusicArtist" || item.Type == "ChannelVideoItem") {
similarCollapsible.classList.remove('hide');
}
else {
similarCollapsible.classList.add('hide');
return;
}
var shape = item.Type == "MusicAlbum" || item.Type == "MusicArtist" ? getSquareShape() : getPortraitShape();
var options = {
userId: Dashboard.getCurrentUserId(),
limit: item.Type == "MusicAlbum" || item.Type == "MusicArtist" ? 8 : 10,
fields: "PrimaryImageAspectRatio,UserData,CanDelete"
};
if (item.Type == 'MusicAlbum' && item.AlbumArtists && item.AlbumArtists.length) {
options.ExcludeArtistIds = item.AlbumArtists[0].Id;
}
if (enableScrollX()) {
options.limit = 12;
}
ApiClient.getSimilarItems(item.Id, options).then(function (result) {
if (!result.Items.length) {
similarCollapsible.classList.add('hide');
return;
}
similarCollapsible.classList.remove('hide');
var html = '';
if (enableScrollX()) {
html += '
';
} else {
html += '
';
}
var supportsImageAnalysis = appHost.supports('imageanalysis');
var cardLayout = supportsImageAnalysis && (item.Type == "MusicAlbum" || item.Type == "Game" || item.Type == "MusicArtist");
html += cardBuilder.getCardsHtml({
items: result.Items,
shape: shape,
showParentTitle: item.Type == "MusicAlbum",
centerText: !cardLayout,
showTitle: item.Type == "MusicAlbum" || item.Type == "Game" || item.Type == "MusicArtist",
context: context,
lazy: true,
showDetailsMenu: true,
coverImage: item.Type == "MusicAlbum" || item.Type == "MusicArtist",
overlayPlayButton: true,
cardLayout: cardLayout,
vibrant: cardLayout && supportsImageAnalysis
});
html += '
';
var similarContent = similarCollapsible.querySelector('.similarContent');
similarContent.innerHTML = html;
imageLoader.lazyChildren(similarContent);
});
}
function renderSeriesAirTime(page, item, isStatic) {
var seriesAirTime = page.querySelector('#seriesAirTime');
if (item.Type != "Series") {
seriesAirTime.classList.add('hide');
return;
}
var html = '';
if (item.AirDays && item.AirDays.length) {
html += item.AirDays.length == 7 ? 'daily' : item.AirDays.map(function (a) {
return a + "s";
}).join(',');
}
if (item.AirTime) {
html += ' at ' + item.AirTime;
}
if (item.Studios.length) {
if (isStatic) {
html += ' on ' + item.Studios[0].Name;
} else {
var context = inferContext(item);
var href = LibraryBrowser.getHref(item.Studios[0], context);
html += ' on
' + item.Studios[0].Name + ' ';
}
}
if (html) {
html = (item.Status == 'Ended' ? 'Aired ' : 'Airs ') + html;
seriesAirTime.innerHTML = html;
seriesAirTime.classList.remove('hide');
} else {
seriesAirTime.classList.add('hide');
}
}
function renderTags(page, item) {
var itemTags = page.querySelector('.itemTags');
if (item.Tags && item.Tags.length) {
var html = '';
for (var i = 0, length = item.Tags.length; i < length; i++) {
html += '
' + item.Tags[i] + '
';
}
itemTags.innerHTML = html;
itemTags.classList.remove('hide');
} else {
itemTags.classList.add('hide');
}
}
function getEpisodesFunction(seriesId, query) {
query = Object.assign({}, query);
return function (index, limit, fields) {
query.StartIndex = index;
query.Limit = limit;
query.Fields = fields;
return ApiClient.getEpisodes(seriesId, query);
};
}
function getAlbumSongsFunction(query) {
query = Object.assign({}, query);
return function (index, limit, fields) {
query.StartIndex = index;
query.Limit = limit;
query.Fields = fields;
return ApiClient.getItems(Dashboard.getCurrentUserId(), query);
};
}
var _childrenItemsFunction = null;
function renderChildren(page, item) {
_childrenItemsFunction = null;
var fields = "ItemCounts,AudioInfo,PrimaryImageAspectRatio,BasicSyncInfo,CanDelete";
var query = {
ParentId: item.Id,
Fields: fields
};
// Let the server pre-sort boxsets
if (item.Type !== "BoxSet") {
query.SortBy = "SortName";
}
var userId = Dashboard.getCurrentUserId();
var promise;
if (item.Type == "Series") {
promise = ApiClient.getSeasons(item.Id, {
userId: userId,
Fields: fields
});
}
else if (item.Type == "Season") {
// Use dedicated episodes endpoint
promise = ApiClient.getEpisodes(item.SeriesId, {
seasonId: item.Id,
userId: userId,
Fields: fields
});
_childrenItemsFunction = getEpisodesFunction(item.SeriesId, {
seasonId: item.Id,
userId: userId,
Fields: fields
});
}
else if (item.Type == "Episode" && item.SeriesId && item.SeasonId) {
// Use dedicated episodes endpoint
promise = ApiClient.getEpisodes(item.SeriesId, {
seasonId: item.SeasonId,
userId: userId,
Fields: fields
});
_childrenItemsFunction = getEpisodesFunction(item.SeriesId, {
seasonId: item.SeasonId,
userId: userId,
Fields: fields
});
}
else if (item.Type == "MusicAlbum") {
_childrenItemsFunction = getAlbumSongsFunction(query);
}
promise = promise || ApiClient.getItems(Dashboard.getCurrentUserId(), query);
promise.then(function (result) {
var html = '';
var scrollX = false;
var isList = false;
var scrollClass = 'hiddenScrollX';
var childrenItemsContainer = page.querySelector('.childrenItemsContainer');
if (item.Type == "MusicAlbum") {
html = listView.getListViewHtml({
items: result.Items,
smallIcon: true,
showIndex: true,
index: 'disc',
showIndexNumber: true,
playFromHere: true,
action: 'playallfromhere',
image: false,
artist: 'auto',
containerAlbumArtist: item.AlbumArtist
});
isList = true;
}
else if (item.Type == "Series") {
scrollX = enableScrollX();
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: getPortraitShape(),
showTitle: true,
centerText: true,
lazy: true,
overlayPlayButton: true,
allowBottomPadding: !scrollX
});
}
else if (item.Type == "Season" || item.Type == "Episode") {
if (item.Type === 'Episode') {
childrenItemsContainer.classList.add('darkScroller');
}
scrollX = item.Type == "Episode";
if (!browser.touch) {
scrollClass = 'smoothScrollX';
}
if (result.Items.length == 1 && item.Type === 'Episode') {
return;
} else {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: getThumbShape(scrollX),
showTitle: true,
displayAsSpecial: item.Type == "Season" && item.IndexNumber,
playFromHere: true,
overlayText: true,
lazy: true,
showDetailsMenu: true,
overlayPlayButton: true,
allowBottomPadding: !scrollX,
includeParentInfoInTitle: false
});
}
}
else if (item.Type == "GameSystem") {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: "auto",
showTitle: true,
centerText: true,
lazy: true,
showDetailsMenu: true
});
}
page.querySelector('#childrenCollapsible').classList.remove('hide');
if (scrollX) {
childrenItemsContainer.classList.add(scrollClass);
childrenItemsContainer.classList.remove('vertical-wrap');
childrenItemsContainer.classList.remove('vertical-list');
} else {
childrenItemsContainer.classList.remove('hiddenScrollX');
childrenItemsContainer.classList.remove('smoothScrollX');
if (isList) {
childrenItemsContainer.classList.add('vertical-list');
childrenItemsContainer.classList.remove('vertical-wrap');
} else {
childrenItemsContainer.classList.add('vertical-wrap');
childrenItemsContainer.classList.remove('vertical-list');
}
}
childrenItemsContainer.innerHTML = html;
imageLoader.lazyChildren(childrenItemsContainer);
if (item.Type == "BoxSet") {
var collectionItemTypes = [
{ name: globalize.translate('HeaderMovies'), type: 'Movie' },
{ name: globalize.translate('HeaderSeries'), type: 'Series' },
{ name: globalize.translate('HeaderAlbums'), type: 'MusicAlbum' },
{ name: globalize.translate('HeaderGames'), type: 'Game' },
{ name: globalize.translate('HeaderBooks'), type: 'Book' }
];
renderCollectionItems(page, item, collectionItemTypes, result.Items);
}
else if (item.Type === 'Episode') {
var card = childrenItemsContainer.querySelector('.card[data-id="' + item.Id + '"]');
if (card) {
scrollHelper.toStart(childrenItemsContainer, card.previousSibling || card, true);
}
}
});
if (item.Type == "Season") {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderEpisodes');
}
else if (item.Type == "Episode") {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('MoreFromValue', item.SeasonName);
}
else if (item.Type == "Series") {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderSeasons');
}
else if (item.Type == "MusicAlbum") {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderTracks');
}
else if (item.Type == "GameSystem") {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderGames');
}
else {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderItems');
}
if (item.Type == "MusicAlbum") {
page.querySelector('.childrenSectionHeader', page).classList.add('hide');
} else {
page.querySelector('.childrenSectionHeader', page).classList.remove('hide');
}
}
function renderItemsByName(page, item, user) {
require('scripts/itembynamedetailpage'.split(','), function () {
window.ItemsByName.renderItems(page, item);
});
}
function renderPlaylistItems(page, item, user) {
require('scripts/playlistedit'.split(','), function () {
PlaylistViewer.render(page, item);
});
}
function renderChannelGuide(page, item, user) {
require('scripts/livetvchannel,scripts/livetvcomponents,livetvcss'.split(','), function (liveTvChannelPage) {
liveTvChannelPage.renderPrograms(page, item.Id);
});
}
function renderSeriesSchedule(page, item, user) {
return;
ApiClient.getLiveTvPrograms({
UserId: Dashboard.getCurrentUserId(),
HasAired: false,
SortBy: "StartDate",
EnableTotalRecordCount: false,
EnableImages: false,
ImageTypeLimit: 0,
Limit: 50,
EnableUserData: false,
LibrarySeriesId: item.Id
}).then(function (result) {
if (result.Items.length) {
page.querySelector('#seriesScheduleSection').classList.remove('hide');
} else {
page.querySelector('#seriesScheduleSection').classList.add('hide');
}
page.querySelector('#seriesScheduleList').innerHTML = listView.getListViewHtml({
items: result.Items,
enableUserDataButtons: false,
showParentTitle: false,
image: false,
showProgramDateTime: true,
mediaInfo: false,
showTitle: true,
moreButton: false,
action: 'programdialog'
});
Dashboard.hideLoadingMsg();
});
}
function inferContext(item) {
if (item.Type == 'Movie' || item.Type == 'BoxSet') {
return 'movies';
}
if (item.Type == 'Series' || item.Type == 'Season' || item.Type == 'Episode') {
return 'tvshows';
}
if (item.Type == 'Game' || item.Type == 'GameSystem') {
return 'games';
}
if (item.Type == 'Game' || item.Type == 'GameSystem') {
return 'games';
}
if (item.Type == 'MusicArtist' || item.Type == 'MusicAlbum') {
return 'music';
}
return null;
}
function renderStudios(elem, item, isStatic) {
var context = inferContext(item);
if (item.Studios && item.Studios.length && item.Type != "Series" && false) {
var html = '';
for (var i = 0, length = item.Studios.length; i < length; i++) {
if (i > 0) {
html += ' / ';
}
if (isStatic) {
html += item.Studios[i].Name;
} else {
item.Studios[i].Type = 'Studio';
var href = LibraryBrowser.getHref(item.Studios[i], context);
html += '
' + item.Studios[i].Name + ' ';
}
}
var translationKey = item.Studios.length > 1 ? "ValueStudios" : "ValueStudio";
html = globalize.translate(translationKey, html);
elem.innerHTML = html;
elem.classList.remove('hide');
} else {
elem.classList.add('hide');
}
}
function renderGenres(elem, item, limit, isStatic) {
var context = inferContext(item);
var html = '';
var genres = item.Genres || [];
for (var i = 0, length = genres.length; i < length; i++) {
if (limit && i >= limit) {
break;
}
if (i > 0) {
html += '
• ';
}
var param = item.Type == "Audio" || item.Type == "MusicArtist" || item.Type == "MusicAlbum" ? "musicgenre" : "genre";
if (item.MediaType == "Game") {
param = "gamegenre";
}
if (isStatic) {
html += genres[i];
} else {
var type;
switch (context) {
case 'tvshows':
type = 'Series';
break;
case 'games':
type = 'Game';
break;
default:
type = 'Movie';
break;
}
var url = "secondaryitems.html?type=" + type + "&" + param + "=" + ApiClient.encodeName(genres[i]);
html += '
' + genres[i] + ' ';
}
}
elem.innerHTML = html;
}
function renderAwardSummary(elem, item) {
if (item.AwardSummary) {
elem.classList.remove('hide');
elem.innerHTML = globalize.translate('ValueAwards', item.AwardSummary);
} else {
elem.classList.add('hide');
}
}
function renderCollectionItems(page, parentItem, types, items) {
// First empty out existing content
page.querySelector('.collectionItems').innerHTML = '';
var i, length;
for (i = 0, length = types.length; i < length; i++) {
var type = types[i];
var typeItems = items.filter(function (curr) {
return curr.Type == type.type;
});
if (typeItems.length) {
renderCollectionItemType(page, parentItem, type, typeItems);
}
}
var otherType = { name: globalize.translate('HeaderOtherItems') };
var otherTypeItems = items.filter(function (curr) {
return !types.filter(function (t) {
return t.type == curr.Type;
}).length;
});
if (otherTypeItems.length) {
renderCollectionItemType(page, parentItem, otherType, otherTypeItems);
}
if (!items.length) {
renderCollectionItemType(page, parentItem, { name: globalize.translate('HeaderItems') }, items);
}
}
function renderCollectionItemType(page, parentItem, type, items) {
var html = '';
html += '
';
html += '
';
html += '
';
html += '' + type.name + ' ';
html += ' ';
html += 'add ';
html += '';
html += '
';
var shape = type.type == 'MusicAlbum' ? getSquareShape(false) : getPortraitShape(false);
html += cardBuilder.getCardsHtml({
items: items,
shape: shape,
showTitle: true,
centerText: true,
lazy: true,
showDetailsMenu: true,
overlayMoreButton: true,
showAddToCollection: false,
showRemoveFromCollection: true,
collectionId: parentItem.Id
});
html += '
';
html += '
';
var collectionItems = page.querySelector('.collectionItems');
collectionItems.insertAdjacentHTML('beforeend', html);
imageLoader.lazyChildren(collectionItems);
collectionItems.querySelector('.btnAddToCollection').addEventListener('click', function () {
require(['alert'], function (alert) {
alert({
text: globalize.translate('AddItemToCollectionHelp'),
html: globalize.translate('AddItemToCollectionHelp') + '
' + globalize.translate('ButtonLearnMore') + ' '
});
});
});
}
function renderUserDataIcons(page, item) {
var userDataIcons = page.querySelectorAll('.userDataIcons');
for (var i = 0, length = userDataIcons.length; i < length; i++) {
if (item.Type == 'Program' || item.Type == 'SeriesTimer') {
userDataIcons[i].classList.add('hide');
} else {
userDataIcons[i].classList.remove('hide');
}
userdataButtons.fill({
item: item,
style: 'fab-mini',
element: userDataIcons[i]
});
}
}
function renderCriticReviews(page, item, limit) {
if (item.Type != "Movie" && item.Type != "Trailer" && item.Type != "MusicVideo") {
page.querySelector('#criticReviewsCollapsible').classList.add('hide');
return;
}
var options = {};
if (limit) {
options.limit = limit;
}
ApiClient.getCriticReviews(item.Id, options).then(function (result) {
if (result.TotalRecordCount || item.CriticRatingSummary || item.AwardSummary) {
page.querySelector('#criticReviewsCollapsible').classList.remove('hide');
renderCriticReviewsContent(page, result, limit);
} else {
page.querySelector('#criticReviewsCollapsible').classList.add('hide');
}
});
}
function renderCriticReviewsContent(page, result, limit) {
var html = '';
var reviews = result.Items;
for (var i = 0, length = reviews.length; i < length; i++) {
var review = reviews[i];
html += '
';
html += '
';
if (review.Score != null) {
//html += review.Score;
}
else if (review.Likes != null) {
if (review.Likes) {
html += '
';
} else {
html += '
';
}
}
html += '
';
html += '
' + review.Caption + ' ';
var vals = [];
if (review.ReviewerName) {
vals.push(review.ReviewerName);
}
if (review.Publisher) {
vals.push(review.Publisher);
}
html += '
' + vals.join(', ') + '.';
if (review.Date) {
try {
var date = datetime.toLocaleDateString(datetime.parseISO8601Date(review.Date, true));
html += '' + date + ' ';
}
catch (error) {
}
}
html += '
';
if (review.Url) {
html += '
';
}
html += '
';
html += '
';
html += '
';
}
if (limit && result.TotalRecordCount > limit) {
html += '
' + globalize.translate('ButtonMore') + '
';
}
var criticReviewsContent = page.querySelector('#criticReviewsContent');
criticReviewsContent.innerHTML = html;
if (enableScrollX()) {
criticReviewsContent.classList.add('hiddenScrollX');
} else {
criticReviewsContent.classList.remove('hiddenScrollX');
}
}
function renderThemeMedia(page, item) {
if (item.Type === 'SeriesTimer' || item.Type === 'Timer' || item.Type === 'Genre' || item.Type === 'MusicGenre' || item.Type === 'GameGenre' || item.Type === 'Studio' || item.Type === 'Person') {
return;
}
ApiClient.getThemeMedia(Dashboard.getCurrentUserId(), item.Id, true).then(function (result) {
var themeSongs = result.ThemeSongsResult.OwnerId == item.Id ?
result.ThemeSongsResult.Items :
[];
var themeVideos = result.ThemeVideosResult.OwnerId == item.Id ?
result.ThemeVideosResult.Items :
[];
renderThemeSongs(page, themeSongs);
renderThemeVideos(page, themeVideos);
});
}
function renderThemeSongs(page, items) {
if (items.length) {
page.querySelector('#themeSongsCollapsible').classList.remove('hide');
var html = listView.getListViewHtml({
items: items
});
page.querySelector('#themeSongsContent').innerHTML = html;
} else {
page.querySelector('#themeSongsCollapsible').classList.add('hide');
}
}
function renderThemeVideos(page, items, user) {
if (items.length) {
page.querySelector('#themeVideosCollapsible').classList.remove('hide');
var themeVideosContent = page.querySelector('#themeVideosContent');
themeVideosContent.innerHTML = getVideosHtml(items, user);
imageLoader.lazyChildren(themeVideosContent);
} else {
page.querySelector('#themeVideosCollapsible').classList.add('hide');
}
}
function renderMusicVideos(page, item, user) {
ApiClient.getItems(user.Id, {
SortBy: "SortName",
SortOrder: "Ascending",
IncludeItemTypes: "MusicVideo",
Recursive: true,
Fields: "DateCreated,CanDelete",
Albums: item.Name
}).then(function (result) {
if (result.Items.length) {
page.querySelector('#musicVideosCollapsible').classList.remove('hide');
var musicVideosContent = page.querySelector('.musicVideosContent');
musicVideosContent.innerHTML = getVideosHtml(result.Items, user);
imageLoader.lazyChildren(musicVideosContent);
} else {
page.querySelector('#musicVideosCollapsible').classList.add('hide');
}
});
}
function renderAdditionalParts(page, item, user) {
ApiClient.getAdditionalVideoParts(user.Id, item.Id).then(function (result) {
if (result.Items.length) {
page.querySelector('#additionalPartsCollapsible').classList.remove('hide');
var additionalPartsContent = page.querySelector('#additionalPartsContent');
additionalPartsContent.innerHTML = getVideosHtml(result.Items, user);
imageLoader.lazyChildren(additionalPartsContent);
} else {
page.querySelector('#additionalPartsCollapsible').classList.add('hide');
}
});
}
function renderScenes(page, item) {
var chapters = item.Chapters || [];
// If there are no chapter images, don't show a bunch of empty tiles
if (chapters.length && !chapters[0].ImageTag) {
chapters = [];
}
if (!chapters.length) {
page.querySelector('#scenesCollapsible').classList.add('hide');
} else {
page.querySelector('#scenesCollapsible').classList.remove('hide');
var scenesContent = page.querySelector('#scenesContent');
if (enableScrollX()) {
scenesContent.classList.add('smoothScrollX');
} else {
scenesContent.classList.add('vertical-wrap');
}
require(['chaptercardbuilder'], function (chaptercardbuilder) {
chaptercardbuilder.buildChapterCards(item, chapters, {
itemsContainer: scenesContent,
coverImage: true,
width: 400,
backdropShape: getThumbShape(),
squareShape: getSquareShape()
});
});
}
}
function renderMediaSources(page, user, item) {
var html = item.MediaSources.map(function (v) {
return getMediaSourceHtml(user, item, v);
}).join('
');
if (item.MediaSources.length > 1) {
html = '
' + html;
}
var mediaInfoContent = page.querySelector('#mediaInfoContent');
mediaInfoContent.innerHTML = html;
}
function getMediaSourceHtml(user, item, version) {
var html = '';
if (version.Name && item.MediaSources.length > 1) {
html += '
' + version.Name + '
';
}
for (var i = 0, length = version.MediaStreams.length; i < length; i++) {
var stream = version.MediaStreams[i];
if (stream.Type == "Data") {
continue;
}
html += '
';
var displayType = globalize.translate('MediaInfoStreamType' + stream.Type);
html += '';
var attributes = [];
if (stream.Language && stream.Type != "Video") {
attributes.push(createAttribute(globalize.translate('MediaInfoLanguage'), stream.Language));
}
if (stream.Codec) {
attributes.push(createAttribute(globalize.translate('MediaInfoCodec'), stream.Codec.toUpperCase()));
}
if (stream.CodecTag) {
attributes.push(createAttribute(globalize.translate('MediaInfoCodecTag'), stream.CodecTag));
}
if (stream.IsAVC != null) {
attributes.push(createAttribute('AVC', (stream.IsAVC ? 'Yes' : 'No')));
}
if (stream.Profile) {
attributes.push(createAttribute(globalize.translate('MediaInfoProfile'), stream.Profile));
}
if (stream.Level) {
attributes.push(createAttribute(globalize.translate('MediaInfoLevel'), stream.Level));
}
if (stream.Width || stream.Height) {
attributes.push(createAttribute(globalize.translate('MediaInfoResolution'), stream.Width + 'x' + stream.Height));
}
if (stream.AspectRatio && stream.Codec != "mjpeg") {
attributes.push(createAttribute(globalize.translate('MediaInfoAspectRatio'), stream.AspectRatio));
}
if (stream.Type == "Video") {
if (stream.IsAnamorphic != null) {
attributes.push(createAttribute(globalize.translate('MediaInfoAnamorphic'), (stream.IsAnamorphic ? 'Yes' : 'No')));
}
attributes.push(createAttribute(globalize.translate('MediaInfoInterlaced'), (stream.IsInterlaced ? 'Yes' : 'No')));
}
if (stream.AverageFrameRate || stream.RealFrameRate) {
attributes.push(createAttribute(globalize.translate('MediaInfoFramerate'), (stream.AverageFrameRate || stream.RealFrameRate)));
}
if (stream.ChannelLayout) {
attributes.push(createAttribute(globalize.translate('MediaInfoLayout'), stream.ChannelLayout));
}
if (stream.Channels) {
attributes.push(createAttribute(globalize.translate('MediaInfoChannels'), stream.Channels + ' ch'));
}
if (stream.BitRate && stream.Codec != "mjpeg") {
attributes.push(createAttribute(globalize.translate('MediaInfoBitrate'), (parseInt(stream.BitRate / 1000)) + ' kbps'));
}
if (stream.SampleRate) {
attributes.push(createAttribute(globalize.translate('MediaInfoSampleRate'), stream.SampleRate + ' Hz'));
}
if (stream.BitDepth) {
attributes.push(createAttribute(globalize.translate('MediaInfoBitDepth'), stream.BitDepth + ' bit'));
}
if (stream.PixelFormat) {
attributes.push(createAttribute(globalize.translate('MediaInfoPixelFormat'), stream.PixelFormat));
}
if (stream.RefFrames) {
attributes.push(createAttribute(globalize.translate('MediaInfoRefFrames'), stream.RefFrames));
}
if (stream.NalLengthSize) {
attributes.push(createAttribute('NAL', stream.NalLengthSize));
}
if (stream.Type != "Video") {
attributes.push(createAttribute(globalize.translate('MediaInfoDefault'), (stream.IsDefault ? 'Yes' : 'No')));
}
if (stream.Type == "Subtitle") {
attributes.push(createAttribute(globalize.translate('MediaInfoForced'), (stream.IsForced ? 'Yes' : 'No')));
attributes.push(createAttribute(globalize.translate('MediaInfoExternal'), (stream.IsExternal ? 'Yes' : 'No')));
}
if (stream.Type == "Video" && version.Timestamp) {
attributes.push(createAttribute(globalize.translate('MediaInfoTimestamp'), version.Timestamp));
}
if (stream.DisplayTitle) {
attributes.push(createAttribute('Title', stream.DisplayTitle));
}
html += attributes.join(' ');
html += '
';
}
if (version.Container) {
html += '
' + globalize.translate('MediaInfoContainer') + ' ' + version.Container + '
';
}
if (version.Formats && version.Formats.length) {
//html += '
'+Globalize.translate('MediaInfoFormat')+' ' + version.Formats.join(',') + '
';
}
if (version.Path && version.Protocol != 'Http' && user && user.Policy.IsAdministrator) {
html += '
' + globalize.translate('MediaInfoPath') + ' ' + version.Path + '
';
}
if (version.Size) {
var size = (version.Size / (1024 * 1024)).toFixed(0);
html += '
' + globalize.translate('MediaInfoSize') + ' ' + size + ' MB
';
}
return html;
}
function createAttribute(label, value) {
return '
' + label + ' ' + value + ' '
}
function getVideosHtml(items, user, limit, moreButtonClass) {
var html = cardBuilder.getCardsHtml({
items: items,
shape: "auto",
showTitle: true,
action: 'play',
overlayText: true,
showRuntime: true
});
if (limit && items.length > limit) {
html += '
' + globalize.translate('ButtonMore') + '
';
}
return html;
}
function renderSpecials(page, item, user, limit) {
ApiClient.getSpecialFeatures(user.Id, item.Id).then(function (specials) {
var specialsContent = page.querySelector('#specialsContent');
specialsContent.innerHTML = getVideosHtml(specials, user, limit, "moreSpecials");
imageLoader.lazyChildren(specialsContent);
});
}
function renderCast(page, item, context, limit, isStatic) {
var people = item.People || [];
var castContent = page.querySelector('#castContent');
if (enableScrollX()) {
castContent.classList.add('smoothScrollX');
limit = 32;
} else {
castContent.classList.add('vertical-wrap');
}
var limitExceeded = limit && people.length > limit;
if (limitExceeded) {
people = people.slice(0);
people.length = Math.min(limit, people.length);
}
require(['peoplecardbuilder'], function (peoplecardbuilder) {
peoplecardbuilder.buildPeopleCards(people, {
itemsContainer: castContent,
coverImage: true,
serverId: item.ServerId,
width: 160,
shape: getPortraitShape()
});
});
var morePeopleButton = page.querySelector('.morePeople');
if (morePeopleButton) {
if (limitExceeded && !enableScrollX()) {
morePeopleButton.classList.remove('hide');
} else {
morePeopleButton.classList.add('hide');
}
}
}
function play(startPosition) {
playbackManager.play({
items: [currentItem],
startPositionTicks: startPosition
});
}
function splitVersions(page, params) {
require(['confirm'], function (confirm) {
confirm("Are you sure you wish to split the media sources into separate items?", "Split Media Apart").then(function () {
Dashboard.showLoadingMsg();
ApiClient.ajax({
type: "DELETE",
url: ApiClient.getUrl("Videos/" + params.id + "/AlternateSources")
}).then(function () {
Dashboard.hideLoadingMsg();
reload(page, params);
});
});
});
}
function playTrailer(page) {
playbackManager.playTrailers(currentItem);
}
function showPlayMenu(item, target) {
require(['playMenu'], function (playMenu) {
playMenu.show({
item: item,
positionTo: target
});
});
}
function playCurrentItem(button) {
if (currentItem.Type == 'Program') {
ApiClient.getLiveTvChannel(currentItem.ChannelId, Dashboard.getCurrentUserId()).then(function (channel) {
showPlayMenu(channel, button);
});
return;
}
showPlayMenu(currentItem, button);
}
function deleteTimer(page, params, id) {
require(['confirm'], function (confirm) {
confirm(globalize.translate('MessageConfirmRecordingCancellation'), globalize.translate('HeaderConfirmRecordingCancellation')).then(function () {
Dashboard.showLoadingMsg();
ApiClient.cancelLiveTvTimer(id).then(function () {
require(['toast'], function (toast) {
toast(globalize.translate('MessageRecordingCancelled'));
});
reload(page, params);
});
});
});
}
function itemDetailPage() {
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();
function onPlayClick() {
playCurrentItem(this);
}
function onDeleteClick() {
require(['deleteHelper'], function (deleteHelper) {
deleteHelper.deleteItem({
item: currentItem,
navigate: true
});
});
}
function onCancelSeriesTimerClick() {
require(['recordingHelper'], function (recordingHelper) {
recordingHelper.cancelSeriesTimerWithConfirmation(currentItem.Id, currentItem.ServerId).then(function () {
Dashboard.navigate('livetv.html');
});
});
}
return function (view, params) {
function onPlayTrailerClick() {
playTrailer(view);
}
function onMoreCommandsClick() {
var button = this;
itemContextMenu.show(getContextMenuOptions(currentItem, button)).then(function (result) {
if (result.deleted) {
Emby.Page.goHome();
} else if (result.updated) {
reload(view, params);
}
});
}
var elems = view.querySelectorAll('.btnPlay');
var i, length;
for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onPlayClick);
}
elems = view.querySelectorAll('.btnPlayTrailer');
for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onPlayTrailerClick);
}
elems = view.querySelectorAll('.btnCancelSeriesTimer');
for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onCancelSeriesTimerClick);
}
elems = view.querySelectorAll('.btnDeleteItem');
for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onDeleteClick);
}
view.querySelector('.btnSplitVersions').addEventListener('click', function () {
splitVersions(view, params);
});
elems = view.querySelectorAll('.btnMoreCommands');
for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onMoreCommandsClick);
}
view.addEventListener('click', function (e) {
if (dom.parentWithClass(e.target, 'moreScenes')) {
Dashboard.getCurrentUser().then(function (user) {
renderScenes(view, currentItem, user);
});
}
else if (dom.parentWithClass(e.target, 'morePeople')) {
renderCast(view, currentItem, params.context);
}
else if (dom.parentWithClass(e.target, 'moreSpecials')) {
Dashboard.getCurrentUser().then(function (user) {
renderSpecials(view, currentItem, user);
});
}
else if (dom.parentWithClass(e.target, 'moreCriticReviews')) {
renderCriticReviews(view, currentItem);
}
});
view.querySelector('.collectionItems').addEventListener('needsrefresh', function (e) {
renderChildren(view, currentItem);
});
function editImages() {
return new Promise(function (resolve, reject) {
require(['imageEditor'], function (imageEditor) {
imageEditor.show({
itemId: currentItem.Id,
serverId: currentItem.ServerId
}).then(resolve, reject);
});
});
}
view.querySelector('.detailImageContainer').addEventListener('click', function (e) {
var itemDetailGalleryLink = dom.parentWithClass(e.target, 'itemDetailGalleryLink');
if (itemDetailGalleryLink) {
editImages().then(function () {
reload(view, params);
});
}
});
function onWebSocketMessage(e, data) {
var msg = data;
if (msg.MessageType === "UserDataChanged") {
if (currentItem && msg.Data.UserId == Dashboard.getCurrentUserId()) {
var key = currentItem.UserData.Key;
var userData = msg.Data.UserDataList.filter(function (u) {
return u.Key == key;
})[0];
if (userData) {
currentItem.UserData = userData;
Dashboard.getCurrentUser().then(function (user) {
refreshImage(view, currentItem, user);
});
}
}
}
}
view.addEventListener('viewbeforeshow', function () {
var page = this;
reload(page, params);
events.on(ApiClient, 'websocketmessage', onWebSocketMessage);
});
view.addEventListener('viewbeforehide', function () {
currentItem = null;
currentRecordingFields = null;
events.off(ApiClient, 'websocketmessage', onWebSocketMessage);
libraryMenu.setTransparentMenu(false);
});
view.addEventListener('viewdestroy', function () {
if (view.syncToggleInstance) {
view.syncToggleInstance.destroy();
view.syncToggleInstance = null;
}
});
};
});