mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-18 03:18:19 -07:00
908 lines
34 KiB
JavaScript
908 lines
34 KiB
JavaScript
define(['viewManager', 'appSettings', 'appStorage', 'apphost', 'datetime', 'itemHelper', 'mediaInfo', 'scroller', 'indicators', 'dom', 'browser', 'imageLoader', 'scrollStyles'], function (viewManager, appSettings, appStorage, appHost, datetime, itemHelper, mediaInfo, scroller, indicators, dom, browser) {
|
|
|
|
function fadeInRight(elem) {
|
|
|
|
var pct = browser.mobile ? '4%' : '0.5%';
|
|
|
|
var keyframes = [
|
|
{ opacity: '0', transform: 'translate3d(' + pct + ', 0, 0)', offset: 0 },
|
|
{ opacity: '1', transform: 'none', offset: 1 }];
|
|
|
|
elem.animate(keyframes, {
|
|
duration: 160,
|
|
iterations: 1,
|
|
easing: 'ease-out'
|
|
});
|
|
}
|
|
|
|
var libraryBrowser = (function (window, document, screen) {
|
|
|
|
var pageSizeKey = 'pagesize_v4';
|
|
|
|
var libraryBrowser = {
|
|
getDefaultPageSize: function (key, defaultValue) {
|
|
|
|
return 100;
|
|
},
|
|
|
|
getSavedQueryKey: function (modifier) {
|
|
|
|
return window.location.href.split('#')[0] + (modifier || '');
|
|
},
|
|
|
|
loadSavedQueryValues: function (key, query) {
|
|
|
|
var values = appStorage.getItem(key + '_' + Dashboard.getCurrentUserId());
|
|
|
|
if (values) {
|
|
|
|
values = JSON.parse(values);
|
|
|
|
return Object.assign(query, values);
|
|
}
|
|
|
|
return query;
|
|
},
|
|
|
|
saveQueryValues: function (key, query) {
|
|
|
|
var values = {};
|
|
|
|
if (query.SortBy) {
|
|
values.SortBy = query.SortBy;
|
|
}
|
|
if (query.SortOrder) {
|
|
values.SortOrder = query.SortOrder;
|
|
}
|
|
|
|
try {
|
|
appStorage.setItem(key + '_' + Dashboard.getCurrentUserId(), JSON.stringify(values));
|
|
} catch (e) {
|
|
|
|
}
|
|
},
|
|
|
|
saveViewSetting: function (key, value) {
|
|
|
|
try {
|
|
appStorage.setItem(key + '_' + Dashboard.getCurrentUserId() + '_view', value);
|
|
} catch (e) {
|
|
|
|
}
|
|
},
|
|
|
|
getSavedView: function (key) {
|
|
|
|
var val = appStorage.getItem(key + '_' + Dashboard.getCurrentUserId() + '_view');
|
|
|
|
return val;
|
|
},
|
|
|
|
getSavedViewSetting: function (key) {
|
|
|
|
return new Promise(function (resolve, reject) {
|
|
|
|
var val = LibraryBrowser.getSavedView(key);
|
|
resolve(val);
|
|
});
|
|
},
|
|
|
|
allowSwipe: function (target) {
|
|
|
|
function allowSwipeOn(elem) {
|
|
|
|
if (dom.parentWithTag(elem, 'input')) {
|
|
return false;
|
|
}
|
|
|
|
if (elem.classList) {
|
|
return !elem.classList.contains('hiddenScrollX') && !elem.classList.contains('smoothScrollX') && !elem.classList.contains('libraryViewNav');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
var parent = target;
|
|
while (parent != null) {
|
|
if (!allowSwipeOn(parent)) {
|
|
return false;
|
|
}
|
|
parent = parent.parentNode;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
configureSwipeTabs: function (ownerpage, tabs) {
|
|
|
|
if (!browser.touch) {
|
|
return;
|
|
}
|
|
|
|
var pageCount = ownerpage.querySelectorAll('.pageTabContent').length;
|
|
var onSwipeLeft = function (e) {
|
|
if (LibraryBrowser.allowSwipe(e.target) && ownerpage.contains(e.target)) {
|
|
var selected = parseInt(tabs.selectedIndex() || '0');
|
|
if (selected < (pageCount - 1)) {
|
|
tabs.selectedIndex(selected + 1);
|
|
}
|
|
}
|
|
};
|
|
|
|
var onSwipeRight = function (e) {
|
|
if (LibraryBrowser.allowSwipe(e.target) && ownerpage.contains(e.target)) {
|
|
var selected = parseInt(tabs.selectedIndex() || '0');
|
|
if (selected > 0) {
|
|
tabs.selectedIndex(selected - 1);
|
|
}
|
|
}
|
|
};
|
|
|
|
require(['hammer-main'], function (hammertime) {
|
|
|
|
hammertime.on('swipeleft', onSwipeLeft);
|
|
hammertime.on('swiperight', onSwipeRight);
|
|
|
|
ownerpage.addEventListener('viewdestroy', function () {
|
|
hammertime.off('swipeleft', onSwipeLeft);
|
|
hammertime.off('swiperight', onSwipeRight);
|
|
});
|
|
});
|
|
},
|
|
|
|
configurePaperLibraryTabs: function (ownerpage, tabs, panels, animateTabs, enableSwipe) {
|
|
|
|
if (!browser.safari && enableSwipe !== false) {
|
|
LibraryBrowser.configureSwipeTabs(ownerpage, tabs);
|
|
}
|
|
|
|
ownerpage.addEventListener('viewbeforeshow', function () {
|
|
if (tabs.triggerBeforeTabChange && this.firstTabIndex == null) {
|
|
tabs.triggerBeforeTabChange();
|
|
}
|
|
});
|
|
|
|
ownerpage.addEventListener('viewshow', function () {
|
|
if (this.firstTabIndex) {
|
|
tabs.selectedIndex(this.firstTabIndex);
|
|
this.firstTabIndex = null;
|
|
} else {
|
|
tabs.triggerTabChange();
|
|
}
|
|
});
|
|
|
|
tabs.addEventListener('beforetabchange', function (e) {
|
|
|
|
if (e.detail.previousIndex != null) {
|
|
panels[e.detail.previousIndex].classList.remove('is-active');
|
|
}
|
|
|
|
var newPanel = panels[e.detail.selectedTabIndex];
|
|
|
|
if (e.detail.previousIndex != null && e.detail.previousIndex != e.detail.selectedTabIndex) {
|
|
if (newPanel.animate && (animateTabs || []).indexOf(e.detail.selectedTabIndex) != -1) {
|
|
fadeInRight(newPanel);
|
|
}
|
|
}
|
|
|
|
newPanel.classList.add('is-active');
|
|
});
|
|
},
|
|
|
|
showTab: function (url, index) {
|
|
|
|
var afterNavigate = function () {
|
|
|
|
document.removeEventListener('pageinit', afterNavigate);
|
|
if (window.location.href.toLowerCase().indexOf(url.toLowerCase()) != -1) {
|
|
this.firstTabIndex = index;
|
|
}
|
|
};
|
|
|
|
if (window.location.href.toLowerCase().indexOf(url.toLowerCase()) != -1) {
|
|
|
|
afterNavigate.call(viewManager.currentView());
|
|
} else {
|
|
|
|
pageClassOn('pageinit', 'page', afterNavigate);
|
|
Dashboard.navigate(url);
|
|
}
|
|
},
|
|
|
|
getArtistLinksHtml: function (artists, cssClass) {
|
|
|
|
var html = [];
|
|
|
|
for (var i = 0, length = artists.length; i < length; i++) {
|
|
|
|
var artist = artists[i];
|
|
|
|
var css = cssClass ? (' class="' + cssClass + '"') : '';
|
|
html.push('<a' + css + ' href="itemdetails.html?id=' + artist.Id + '">' + artist.Name + '</a>');
|
|
|
|
}
|
|
|
|
html = html.join(' / ');
|
|
|
|
return html;
|
|
},
|
|
|
|
playInExternalPlayer: function (id) {
|
|
|
|
Dashboard.loadExternalPlayer().then(function () {
|
|
ExternalPlayer.showMenu(id);
|
|
});
|
|
},
|
|
|
|
getHref: function (item, context, topParentId) {
|
|
|
|
var href = LibraryBrowser.getHrefInternal(item, context);
|
|
|
|
if (context == 'tv') {
|
|
if (!topParentId) {
|
|
topParentId = LibraryMenu.getTopParentId();
|
|
}
|
|
|
|
if (topParentId) {
|
|
href += href.indexOf('?') == -1 ? "?topParentId=" : "&topParentId=";
|
|
href += topParentId;
|
|
}
|
|
}
|
|
|
|
return href;
|
|
},
|
|
|
|
getHrefInternal: function (item, context) {
|
|
|
|
if (!item) {
|
|
throw new Error('item cannot be null');
|
|
}
|
|
|
|
if (item.url) {
|
|
return item.url;
|
|
}
|
|
|
|
// Handle search hints
|
|
var id = item.Id || item.ItemId;
|
|
|
|
if (item.CollectionType == 'livetv') {
|
|
return 'livetv.html';
|
|
}
|
|
|
|
if (item.CollectionType == 'channels') {
|
|
|
|
return 'channels.html';
|
|
}
|
|
|
|
if (context != 'folders') {
|
|
if (item.CollectionType == 'movies') {
|
|
return 'movies.html?topParentId=' + item.Id;
|
|
}
|
|
|
|
if (item.CollectionType == 'boxsets') {
|
|
return 'itemlist.html?topParentId=' + item.Id + '&parentId=' + item.Id;
|
|
}
|
|
|
|
if (item.CollectionType == 'tvshows') {
|
|
return 'tv.html?topParentId=' + item.Id;
|
|
}
|
|
|
|
if (item.CollectionType == 'music') {
|
|
return 'music.html?topParentId=' + item.Id;
|
|
}
|
|
|
|
if (item.CollectionType == 'games') {
|
|
return id ? "itemlist.html?parentId=" + id : "#";
|
|
//return 'gamesrecommended.html?topParentId=' + item.Id;
|
|
}
|
|
if (item.CollectionType == 'playlists') {
|
|
return 'playlists.html?topParentId=' + item.Id;
|
|
}
|
|
if (item.CollectionType == 'photos') {
|
|
return 'photos.html?topParentId=' + item.Id;
|
|
}
|
|
}
|
|
else if (item.IsFolder) {
|
|
if (item.Type != "BoxSet" && item.Type != "Series") {
|
|
return id ? "itemlist.html?parentId=" + id : "#";
|
|
}
|
|
}
|
|
|
|
if (item.Type == 'CollectionFolder') {
|
|
return 'itemlist.html?topParentId=' + item.Id + '&parentId=' + item.Id;
|
|
}
|
|
|
|
if (item.Type == "PhotoAlbum") {
|
|
return "itemlist.html?context=photos&parentId=" + id;
|
|
}
|
|
if (item.Type == "Playlist") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
if (item.Type == "TvChannel") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
if (item.Type == "Channel") {
|
|
return "channelitems.html?id=" + id;
|
|
}
|
|
if ((item.IsFolder && item.SourceType == 'Channel') || item.Type == 'ChannelFolderItem') {
|
|
return "channelitems.html?id=" + item.ChannelId + '&folderId=' + item.Id;
|
|
}
|
|
if (item.Type == "Program") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
|
|
if (item.Type == "BoxSet") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
if (item.Type == "MusicAlbum") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
if (item.Type == "GameSystem") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
if (item.Type == "Genre") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
if (item.Type == "MusicGenre") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
if (item.Type == "GameGenre") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
if (item.Type == "Studio") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
if (item.Type == "Person") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
if (item.Type == "Recording") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
|
|
if (item.Type == "MusicArtist") {
|
|
return "itemdetails.html?id=" + id;
|
|
}
|
|
|
|
var contextSuffix = context ? ('&context=' + context) : '';
|
|
|
|
if (item.Type == "Series" || item.Type == "Season" || item.Type == "Episode") {
|
|
return "itemdetails.html?id=" + id + contextSuffix;
|
|
}
|
|
|
|
if (item.IsFolder) {
|
|
return id ? "itemlist.html?parentId=" + id : "#";
|
|
}
|
|
|
|
return "itemdetails.html?id=" + id;
|
|
},
|
|
|
|
getListItemInfo: function (elem) {
|
|
|
|
var elemWithAttributes = elem;
|
|
|
|
while (!elemWithAttributes.getAttribute('data-id')) {
|
|
elemWithAttributes = elemWithAttributes.parentNode;
|
|
}
|
|
|
|
var itemId = elemWithAttributes.getAttribute('data-id');
|
|
var index = elemWithAttributes.getAttribute('data-index');
|
|
var mediaType = elemWithAttributes.getAttribute('data-mediatype');
|
|
|
|
return {
|
|
id: itemId,
|
|
index: index,
|
|
mediaType: mediaType,
|
|
context: elemWithAttributes.getAttribute('data-context')
|
|
};
|
|
},
|
|
|
|
getFutureDateText: function (date) {
|
|
|
|
var weekday = [];
|
|
weekday[0] = Globalize.translate('OptionSunday');
|
|
weekday[1] = Globalize.translate('OptionMonday');
|
|
weekday[2] = Globalize.translate('OptionTuesday');
|
|
weekday[3] = Globalize.translate('OptionWednesday');
|
|
weekday[4] = Globalize.translate('OptionThursday');
|
|
weekday[5] = Globalize.translate('OptionFriday');
|
|
weekday[6] = Globalize.translate('OptionSaturday');
|
|
|
|
var day = weekday[date.getDay()];
|
|
date = date.toLocaleDateString();
|
|
|
|
if (date.toLowerCase().indexOf(day.toLowerCase()) == -1) {
|
|
return day + " " + date;
|
|
}
|
|
|
|
return date;
|
|
},
|
|
|
|
renderName: function (item, nameElem, linkToElement, context) {
|
|
|
|
var name = itemHelper.getDisplayName(item, {
|
|
includeParentInfo: false
|
|
});
|
|
|
|
LibraryMenu.setTitle(name);
|
|
|
|
if (linkToElement) {
|
|
nameElem.innerHTML = '<a class="detailPageParentLink" href="' + LibraryBrowser.getHref(item, context) + '">' + name + '</a>';
|
|
} else {
|
|
nameElem.innerHTML = name;
|
|
}
|
|
},
|
|
|
|
renderParentName: function (item, parentNameElem, context) {
|
|
|
|
var html = [];
|
|
|
|
var contextParam = context ? ('&context=' + context) : '';
|
|
|
|
if (item.AlbumArtists) {
|
|
html.push(LibraryBrowser.getArtistLinksHtml(item.AlbumArtists, "detailPageParentLink"));
|
|
} else if (item.ArtistItems && item.ArtistItems.length && item.Type == "MusicVideo") {
|
|
html.push(LibraryBrowser.getArtistLinksHtml(item.ArtistItems, "detailPageParentLink"));
|
|
} else if (item.SeriesName && item.Type == "Episode") {
|
|
|
|
html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + item.SeriesId + contextParam + '">' + item.SeriesName + '</a>');
|
|
}
|
|
|
|
if (item.SeriesName && item.Type == "Season") {
|
|
|
|
html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + item.SeriesId + contextParam + '">' + item.SeriesName + '</a>');
|
|
|
|
} else if (item.ParentIndexNumber != null && item.Type == "Episode") {
|
|
|
|
html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + item.SeasonId + contextParam + '">' + item.SeasonName + '</a>');
|
|
|
|
} else if (item.Album && item.Type == "Audio" && (item.AlbumId || item.ParentId)) {
|
|
html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + (item.AlbumId || item.ParentId) + contextParam + '">' + item.Album + '</a>');
|
|
|
|
} else if (item.Album && item.Type == "MusicVideo" && item.AlbumId) {
|
|
html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + item.AlbumId + contextParam + '">' + item.Album + '</a>');
|
|
|
|
} else if (item.Album) {
|
|
html.push(item.Album);
|
|
} else if (item.Type == 'Program' && item.EpisodeTitle) {
|
|
html.push(item.Name);
|
|
}
|
|
|
|
if (html.length) {
|
|
parentNameElem.classList.remove('hide');
|
|
parentNameElem.innerHTML = html.join(' - ');
|
|
} else {
|
|
parentNameElem.classList.add('hide');
|
|
}
|
|
},
|
|
|
|
showLayoutMenu: function (button, currentLayout, views) {
|
|
|
|
var dispatchEvent = true;
|
|
|
|
if (!views) {
|
|
|
|
dispatchEvent = false;
|
|
// Add banner and list once all screens support them
|
|
views = button.getAttribute('data-layouts');
|
|
|
|
views = views ? views.split(',') : ['List', 'Poster', 'PosterCard', 'Thumb', 'ThumbCard'];
|
|
}
|
|
|
|
var menuItems = views.map(function (v) {
|
|
return {
|
|
name: Globalize.translate('Option' + v),
|
|
id: v,
|
|
selected: currentLayout == v
|
|
};
|
|
});
|
|
|
|
require(['actionsheet'], function (actionsheet) {
|
|
|
|
actionsheet.show({
|
|
items: menuItems,
|
|
positionTo: button,
|
|
callback: function (id) {
|
|
|
|
button.dispatchEvent(new CustomEvent('layoutchange', {
|
|
detail: {
|
|
viewStyle: id
|
|
},
|
|
bubbles: true,
|
|
cancelable: false
|
|
}));
|
|
|
|
if (!dispatchEvent) {
|
|
if (window.$) {
|
|
$(button).trigger('layoutchange', [id]);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
getQueryPagingHtml: function (options) {
|
|
|
|
var startIndex = options.startIndex;
|
|
var limit = options.limit;
|
|
var totalRecordCount = options.totalRecordCount;
|
|
|
|
if (limit && options.updatePageSizeSetting !== false) {
|
|
try {
|
|
appStorage.setItem(options.pageSizeKey || pageSizeKey, limit);
|
|
} catch (e) {
|
|
|
|
}
|
|
}
|
|
|
|
var html = '';
|
|
|
|
var recordsEnd = Math.min(startIndex + limit, totalRecordCount);
|
|
|
|
// 20 is the minimum page size
|
|
var showControls = totalRecordCount > 20 || limit < totalRecordCount;
|
|
|
|
html += '<div class="listPaging">';
|
|
|
|
if (showControls) {
|
|
html += '<span style="vertical-align:middle;">';
|
|
|
|
var startAtDisplay = totalRecordCount ? startIndex + 1 : 0;
|
|
html += startAtDisplay + '-' + recordsEnd + ' of ' + totalRecordCount;
|
|
|
|
html += '</span>';
|
|
}
|
|
|
|
if (showControls || options.viewButton || options.filterButton || options.sortButton || options.addLayoutButton) {
|
|
|
|
html += '<div style="display:inline-block;">';
|
|
|
|
if (showControls) {
|
|
|
|
html += '<button is="paper-icon-button-light" class="btnPreviousPage autoSize" ' + (startIndex ? '' : 'disabled') + '><i class="md-icon"></i></button>';
|
|
html += '<button is="paper-icon-button-light" class="btnNextPage autoSize" ' + (startIndex + limit >= totalRecordCount ? 'disabled' : '') + '><i class="md-icon">arrow_forward</i></button>';
|
|
}
|
|
|
|
if (options.addLayoutButton) {
|
|
|
|
html += '<button is="paper-icon-button-light" title="' + Globalize.translate('ButtonSelectView') + '" class="btnChangeLayout autoSize" data-layouts="' + (options.layouts || '') + '" onclick="LibraryBrowser.showLayoutMenu(this, \'' + (options.currentLayout || '') + '\');"><i class="md-icon">view_comfy</i></button>';
|
|
}
|
|
|
|
if (options.sortButton) {
|
|
|
|
html += '<button is="paper-icon-button-light" class="btnSort autoSize" title="' + Globalize.translate('ButtonSort') + '"><i class="md-icon">sort_by_alpha</i></button>';
|
|
}
|
|
|
|
if (options.filterButton) {
|
|
|
|
html += '<button is="paper-icon-button-light" class="btnFilter autoSize" title="' + Globalize.translate('ButtonFilter') + '"><i class="md-icon">filter_list</i></button>';
|
|
}
|
|
|
|
html += '</div>';
|
|
|
|
if (showControls && options.showLimit) {
|
|
|
|
var id = "selectPageSize";
|
|
|
|
var pageSizes = options.pageSizes || [20, 50, 100, 200, 300, 400, 500];
|
|
|
|
var optionsHtml = pageSizes.map(function (val) {
|
|
|
|
if (limit == val) {
|
|
|
|
return '<option value="' + val + '" selected="selected">' + val + '</option>';
|
|
|
|
} else {
|
|
return '<option value="' + val + '">' + val + '</option>';
|
|
}
|
|
}).join('');
|
|
|
|
// Add styles to defeat jquery mobile
|
|
html += '<div class="pageSizeContainer"><label class="labelPageSize" for="' + id + '">' + Globalize.translate('LabelLimit') + '</label><select style="width:auto;" class="selectPageSize" id="' + id + '" data-inline="true" data-mini="true">' + optionsHtml + '</select></div>';
|
|
}
|
|
}
|
|
|
|
html += '</div>';
|
|
|
|
return html;
|
|
},
|
|
|
|
showSortMenu: function (options) {
|
|
|
|
require(['dialogHelper', 'emby-radio'], function (dialogHelper) {
|
|
|
|
var dlg = dialogHelper.createDialog({
|
|
removeOnClose: true,
|
|
modal: false,
|
|
entryAnimationDuration: 160,
|
|
exitAnimationDuration: 200
|
|
});
|
|
|
|
dlg.classList.add('ui-body-a');
|
|
dlg.classList.add('background-theme-a');
|
|
dlg.classList.add('formDialog');
|
|
|
|
var html = '';
|
|
|
|
html += '<div style="margin:0;padding:1.25em 1.5em 1.5em;">';
|
|
|
|
html += '<h2 style="margin:0 0 .5em;">';
|
|
html += Globalize.translate('HeaderSortBy');
|
|
html += '</h2>';
|
|
|
|
var i, length;
|
|
var isChecked;
|
|
|
|
html += '<div>';
|
|
for (i = 0, length = options.items.length; i < length; i++) {
|
|
|
|
var option = options.items[i];
|
|
|
|
var radioValue = option.id.replace(',', '_');
|
|
isChecked = (options.query.SortBy || '').replace(',', '_') == radioValue ? ' checked' : '';
|
|
html += '<label class="radio-label-block"><input type="radio" is="emby-radio" name="SortBy" data-id="' + option.id + '" value="' + radioValue + '" class="menuSortBy" ' + isChecked + ' /><span>' + option.name + '</span></label>';
|
|
}
|
|
html += '</div>';
|
|
|
|
html += '<h2 style="margin: 1em 0 .5em;">';
|
|
html += Globalize.translate('HeaderSortOrder');
|
|
html += '</h2>';
|
|
html += '<div>';
|
|
isChecked = options.query.SortOrder == 'Ascending' ? ' checked' : '';
|
|
html += '<label class="radio-label-block"><input type="radio" is="emby-radio" name="SortOrder" value="Ascending" class="menuSortOrder" ' + isChecked + ' /><span>' + Globalize.translate('OptionAscending') + '</span></label>';
|
|
isChecked = options.query.SortOrder == 'Descending' ? ' checked' : '';
|
|
html += '<label class="radio-label-block"><input type="radio" is="emby-radio" name="SortOrder" value="Descending" class="menuSortOrder" ' + isChecked + ' /><span>' + Globalize.translate('OptionDescending') + '</span></label>';
|
|
html += '</div>';
|
|
html += '</div>';
|
|
|
|
dlg.innerHTML = html;
|
|
|
|
dialogHelper.open(dlg);
|
|
|
|
function onSortByChange() {
|
|
var newValue = this.value;
|
|
if (this.checked) {
|
|
var changed = options.query.SortBy != newValue;
|
|
|
|
options.query.SortBy = newValue.replace('_', ',');
|
|
options.query.StartIndex = 0;
|
|
|
|
if (options.callback && changed) {
|
|
options.callback();
|
|
}
|
|
}
|
|
}
|
|
|
|
var sortBys = dlg.querySelectorAll('.menuSortBy');
|
|
for (i = 0, length = sortBys.length; i < length; i++) {
|
|
sortBys[i].addEventListener('change', onSortByChange);
|
|
}
|
|
|
|
function onSortOrderChange() {
|
|
var newValue = this.value;
|
|
if (this.checked) {
|
|
var changed = options.query.SortOrder != newValue;
|
|
|
|
options.query.SortOrder = newValue;
|
|
options.query.StartIndex = 0;
|
|
|
|
if (options.callback && changed) {
|
|
options.callback();
|
|
}
|
|
}
|
|
}
|
|
|
|
var sortOrders = dlg.querySelectorAll('.menuSortOrder');
|
|
for (i = 0, length = sortOrders.length; i < length; i++) {
|
|
sortOrders[i].addEventListener('change', onSortOrderChange);
|
|
}
|
|
});
|
|
},
|
|
|
|
renderDetailImage: function (elem, item, editable, preferThumb) {
|
|
|
|
var imageTags = item.ImageTags || {};
|
|
|
|
if (item.PrimaryImageTag) {
|
|
imageTags.Primary = item.PrimaryImageTag;
|
|
}
|
|
|
|
var html = '';
|
|
|
|
var url;
|
|
var shape = 'portrait';
|
|
|
|
var imageHeight = 360;
|
|
var detectRatio = false;
|
|
|
|
if (preferThumb && imageTags.Thumb) {
|
|
|
|
url = ApiClient.getScaledImageUrl(item.Id, {
|
|
type: "Thumb",
|
|
maxHeight: imageHeight,
|
|
tag: item.ImageTags.Thumb
|
|
});
|
|
shape = 'thumb';
|
|
}
|
|
else if (imageTags.Primary) {
|
|
|
|
url = ApiClient.getScaledImageUrl(item.Id, {
|
|
type: "Primary",
|
|
maxHeight: imageHeight,
|
|
tag: item.ImageTags.Primary
|
|
});
|
|
detectRatio = true;
|
|
}
|
|
else if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
|
|
|
url = ApiClient.getScaledImageUrl(item.Id, {
|
|
type: "Backdrop",
|
|
maxHeight: imageHeight,
|
|
tag: item.BackdropImageTags[0]
|
|
});
|
|
shape = 'thumb';
|
|
}
|
|
else if (imageTags.Thumb) {
|
|
|
|
url = ApiClient.getScaledImageUrl(item.Id, {
|
|
type: "Thumb",
|
|
maxHeight: imageHeight,
|
|
tag: item.ImageTags.Thumb
|
|
});
|
|
shape = 'thumb';
|
|
}
|
|
else if (imageTags.Disc) {
|
|
|
|
url = ApiClient.getScaledImageUrl(item.Id, {
|
|
type: "Disc",
|
|
maxHeight: imageHeight,
|
|
tag: item.ImageTags.Disc
|
|
});
|
|
shape = 'square';
|
|
}
|
|
else if (item.AlbumId && item.AlbumPrimaryImageTag) {
|
|
|
|
url = ApiClient.getScaledImageUrl(item.AlbumId, {
|
|
type: "Primary",
|
|
maxHeight: imageHeight,
|
|
tag: item.AlbumPrimaryImageTag
|
|
});
|
|
shape = 'square';
|
|
}
|
|
else if (item.MediaType == "Audio" || item.Type == "MusicAlbum" || item.Type == "MusicGenre") {
|
|
url = "css/images/items/detail/audio.png";
|
|
shape = 'square';
|
|
}
|
|
else if (item.MediaType == "Game" || item.Type == "GameGenre") {
|
|
url = "css/images/items/detail/game.png";
|
|
shape = 'square';
|
|
}
|
|
else if (item.Type == "Person") {
|
|
url = "css/images/items/detail/person.png";
|
|
shape = 'square';
|
|
}
|
|
else if (item.Type == "Genre" || item.Type == "Studio") {
|
|
url = "css/images/items/detail/video.png";
|
|
shape = 'square';
|
|
}
|
|
else if (item.Type == "TvChannel") {
|
|
url = "css/images/items/detail/tv.png";
|
|
shape = 'square';
|
|
}
|
|
else {
|
|
url = "css/images/items/detail/video.png";
|
|
shape = 'square';
|
|
}
|
|
|
|
html += '<div style="position:relative;">';
|
|
|
|
if (editable) {
|
|
html += "<a class='itemDetailGalleryLink' href='#'>";
|
|
}
|
|
|
|
if (detectRatio && item.PrimaryImageAspectRatio) {
|
|
|
|
if (item.PrimaryImageAspectRatio >= 1.48) {
|
|
shape = 'thumb';
|
|
} else if (item.PrimaryImageAspectRatio >= .85 && item.PrimaryImageAspectRatio <= 1.34) {
|
|
shape = 'square';
|
|
}
|
|
}
|
|
|
|
html += "<img class='itemDetailImage lazy' src='css/images/empty.png' />";
|
|
|
|
if (editable) {
|
|
html += "</a>";
|
|
}
|
|
|
|
var progressHtml = item.IsFolder || !item.UserData ? '' : indicators.getProgressBarHtml(item);
|
|
|
|
html += '<div class="detailImageProgressContainer">';
|
|
if (progressHtml) {
|
|
html += progressHtml;
|
|
}
|
|
html += "</div>";
|
|
|
|
html += "</div>";
|
|
|
|
elem.innerHTML = html;
|
|
|
|
if (shape == 'thumb') {
|
|
elem.classList.add('thumbDetailImageContainer');
|
|
elem.classList.remove('portraitDetailImageContainer');
|
|
elem.classList.remove('squareDetailImageContainer');
|
|
}
|
|
else if (shape == 'square') {
|
|
elem.classList.remove('thumbDetailImageContainer');
|
|
elem.classList.remove('portraitDetailImageContainer');
|
|
elem.classList.add('squareDetailImageContainer');
|
|
} else {
|
|
elem.classList.remove('thumbDetailImageContainer');
|
|
elem.classList.add('portraitDetailImageContainer');
|
|
elem.classList.remove('squareDetailImageContainer');
|
|
}
|
|
|
|
var img = elem.querySelector('img');
|
|
img.onload = function () {
|
|
if (img.src.indexOf('empty.png') == -1) {
|
|
img.classList.add('loaded');
|
|
}
|
|
};
|
|
ImageLoader.lazyImage(img, url);
|
|
},
|
|
|
|
renderDetailPageBackdrop: function (page, item) {
|
|
|
|
var screenWidth = screen.availWidth;
|
|
|
|
var imgUrl;
|
|
var hasbackdrop = false;
|
|
|
|
var itemBackdropElement = page.querySelector('#itemBackdrop');
|
|
|
|
if (item.BackdropImageTags && item.BackdropImageTags.length) {
|
|
|
|
imgUrl = ApiClient.getScaledImageUrl(item.Id, {
|
|
type: "Backdrop",
|
|
index: 0,
|
|
maxWidth: screenWidth,
|
|
tag: item.BackdropImageTags[0]
|
|
});
|
|
|
|
itemBackdropElement.classList.remove('noBackdrop');
|
|
ImageLoader.lazyImage(itemBackdropElement, imgUrl, false);
|
|
hasbackdrop = true;
|
|
}
|
|
else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
|
|
|
|
imgUrl = ApiClient.getScaledImageUrl(item.ParentBackdropItemId, {
|
|
type: 'Backdrop',
|
|
index: 0,
|
|
tag: item.ParentBackdropImageTags[0],
|
|
maxWidth: screenWidth
|
|
});
|
|
|
|
itemBackdropElement.classList.remove('noBackdrop');
|
|
ImageLoader.lazyImage(itemBackdropElement, imgUrl, false);
|
|
hasbackdrop = true;
|
|
}
|
|
else {
|
|
|
|
itemBackdropElement.classList.add('noBackdrop');
|
|
itemBackdropElement.style.backgroundImage = '';
|
|
}
|
|
|
|
return hasbackdrop;
|
|
}
|
|
};
|
|
|
|
return libraryBrowser;
|
|
|
|
})(window, document, screen);
|
|
|
|
window.LibraryBrowser = libraryBrowser;
|
|
|
|
return libraryBrowser;
|
|
}); |