jellyfin-web/dashboard-ui/scripts/librarybrowser.js

913 lines
35 KiB
JavaScript
Raw Normal View History

2016-08-14 12:58:13 -07:00
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) {
2016-05-09 12:27:38 -07:00
2016-05-16 10:11:49 -07:00
function fadeInRight(elem) {
2016-08-14 12:58:13 -07:00
var pct = browser.mobile ? '4%' : '0.5%';
2016-05-16 10:11:49 -07:00
var keyframes = [
{ opacity: '0', transform: 'translate3d(' + pct + ', 0, 0)', offset: 0 },
{ opacity: '1', transform: 'none', offset: 1 }];
elem.animate(keyframes, {
2016-05-16 22:45:06 -07:00
duration: 160,
2016-05-16 10:11:49 -07:00
iterations: 1,
easing: 'ease-out'
});
}
2016-02-17 19:55:15 -07:00
var libraryBrowser = (function (window, document, screen) {
var pageSizeKey = 'pagesize_v4';
2016-02-17 19:55:15 -07:00
var libraryBrowser = {
getDefaultPageSize: function (key, defaultValue) {
2016-02-17 19:55:15 -07:00
return 100;
},
2015-10-14 21:32:10 -07:00
2016-02-17 19:55:15 -07:00
getSavedQueryKey: function (modifier) {
2013-10-12 09:55:58 -07:00
2016-02-17 19:55:15 -07:00
return window.location.href.split('#')[0] + (modifier || '');
},
2013-10-12 09:55:58 -07:00
2016-02-17 19:55:15 -07:00
loadSavedQueryValues: function (key, query) {
2013-10-12 09:55:58 -07:00
2016-02-17 19:55:15 -07:00
var values = appStorage.getItem(key + '_' + Dashboard.getCurrentUserId());
2013-10-12 09:55:58 -07:00
2016-02-17 19:55:15 -07:00
if (values) {
2013-10-12 09:55:58 -07:00
2016-02-17 19:55:15 -07:00
values = JSON.parse(values);
2013-10-12 09:55:58 -07:00
2016-03-16 14:30:49 -07:00
return Object.assign(query, values);
2016-02-17 19:55:15 -07:00
}
2016-02-17 19:55:15 -07:00
return query;
},
2014-01-14 08:50:39 -07:00
2016-02-17 19:55:15 -07:00
saveQueryValues: function (key, query) {
2014-01-14 08:50:39 -07:00
2016-02-17 19:55:15 -07:00
var values = {};
2014-07-02 11:34:08 -07:00
2016-02-17 19:55:15 -07:00
if (query.SortBy) {
values.SortBy = query.SortBy;
}
if (query.SortOrder) {
values.SortOrder = query.SortOrder;
}
2014-01-13 09:25:18 -07:00
2016-02-17 19:55:15 -07:00
try {
appStorage.setItem(key + '_' + Dashboard.getCurrentUserId(), JSON.stringify(values));
} catch (e) {
2015-08-15 11:46:57 -07:00
2016-02-17 19:55:15 -07:00
}
},
2015-08-15 11:46:57 -07:00
2016-02-17 19:55:15 -07:00
saveViewSetting: function (key, value) {
2015-08-15 11:46:57 -07:00
2016-02-17 19:55:15 -07:00
try {
appStorage.setItem(key + '_' + Dashboard.getCurrentUserId() + '_view', value);
} catch (e) {
2014-01-13 09:25:18 -07:00
2016-02-17 19:55:15 -07:00
}
},
2014-01-13 09:25:18 -07:00
2016-02-17 19:55:15 -07:00
getSavedView: function (key) {
2013-10-12 09:55:58 -07:00
2016-02-17 19:55:15 -07:00
var val = appStorage.getItem(key + '_' + Dashboard.getCurrentUserId() + '_view');
2015-06-29 22:45:20 -07:00
2016-02-17 19:55:15 -07:00
return val;
},
2015-06-30 10:21:20 -07:00
2016-02-17 19:55:15 -07:00
getSavedViewSetting: function (key) {
2015-06-29 22:45:20 -07:00
2016-02-17 19:55:15 -07:00
return new Promise(function (resolve, reject) {
2015-06-29 22:45:20 -07:00
2016-02-17 19:55:15 -07:00
var val = LibraryBrowser.getSavedView(key);
resolve(val);
});
},
2015-07-01 22:08:05 -07:00
2016-02-17 19:55:15 -07:00
allowSwipe: function (target) {
2015-07-01 08:47:41 -07:00
2016-02-17 19:55:15 -07:00
function allowSwipeOn(elem) {
2015-07-01 08:47:41 -07:00
2016-08-01 11:16:07 -07:00
if (dom.parentWithTag(elem, 'input')) {
return false;
}
2016-02-17 19:55:15 -07:00
if (elem.classList) {
2016-05-09 12:27:38 -07:00
return !elem.classList.contains('hiddenScrollX') && !elem.classList.contains('smoothScrollX') && !elem.classList.contains('libraryViewNav');
2016-02-17 19:55:15 -07:00
}
2015-12-14 08:43:03 -07:00
2016-02-17 19:55:15 -07:00
return true;
}
2015-12-14 08:43:03 -07:00
2016-02-17 19:55:15 -07:00
var parent = target;
while (parent != null) {
if (!allowSwipeOn(parent)) {
return false;
}
parent = parent.parentNode;
2015-12-14 08:43:03 -07:00
}
2016-02-17 19:55:15 -07:00
return true;
},
2015-12-14 08:43:03 -07:00
2016-05-09 12:27:38 -07:00
configureSwipeTabs: function (ownerpage, tabs) {
2016-03-24 11:11:03 -07:00
2016-08-14 12:58:13 -07:00
if (!browser.touch) {
return;
2016-08-08 19:09:56 -07:00
}
2016-08-15 21:12:12 -07:00
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);
2015-09-01 12:18:25 -07:00
}
2016-08-15 21:12:12 -07:00
}
};
2015-09-01 12:18:25 -07:00
2016-08-15 21:12:12 -07:00
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);
2015-09-01 12:18:25 -07:00
}
2016-08-15 21:12:12 -07:00
}
};
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);
2016-02-17 19:55:15 -07:00
});
2015-09-01 12:18:25 -07:00
});
2016-02-17 19:55:15 -07:00
},
2015-07-01 08:47:41 -07:00
2016-09-01 13:21:55 -07:00
configurePaperLibraryTabs: function (ownerpage, tabs, panels, animateTabs, enableSwipe) {
2015-09-01 08:31:50 -07:00
2016-09-01 13:21:55 -07:00
if (!browser.safari && enableSwipe !== false) {
2016-05-09 12:27:38 -07:00
LibraryBrowser.configureSwipeTabs(ownerpage, tabs);
2016-02-17 19:55:15 -07:00
}
2015-07-01 08:47:41 -07:00
2016-08-14 14:29:35 -07:00
ownerpage.addEventListener('viewbeforeshow', function () {
2016-08-17 13:10:24 -07:00
if (tabs.triggerBeforeTabChange && this.firstTabIndex == null) {
2016-08-14 14:29:35 -07:00
tabs.triggerBeforeTabChange();
2016-08-14 12:58:13 -07:00
}
});
2016-07-07 08:56:49 -07:00
2016-08-14 14:29:35 -07:00
ownerpage.addEventListener('viewshow', function () {
2016-08-17 13:10:24 -07:00
if (this.firstTabIndex) {
tabs.selectedIndex(this.firstTabIndex);
this.firstTabIndex = null;
} else {
tabs.triggerTabChange();
}
2016-08-14 14:29:35 -07:00
});
2016-08-14 12:58:13 -07:00
tabs.addEventListener('beforetabchange', function (e) {
2016-05-16 10:11:49 -07:00
2016-08-14 14:29:35 -07:00
if (e.detail.previousIndex != null) {
panels[e.detail.previousIndex].classList.remove('is-active');
}
2016-08-14 12:58:13 -07:00
var newPanel = panels[e.detail.selectedTabIndex];
2016-07-07 08:56:49 -07:00
2016-08-14 12:58:13 -07:00
if (e.detail.previousIndex != null && e.detail.previousIndex != e.detail.selectedTabIndex) {
if (newPanel.animate && (animateTabs || []).indexOf(e.detail.selectedTabIndex) != -1) {
fadeInRight(newPanel);
2016-07-07 08:56:49 -07:00
}
2016-03-16 22:04:32 -07:00
}
2015-07-01 22:08:05 -07:00
2016-08-14 12:58:13 -07:00
newPanel.classList.add('is-active');
});
2016-02-17 19:55:15 -07:00
},
2015-07-01 22:08:05 -07:00
2016-02-17 19:55:15 -07:00
showTab: function (url, index) {
2015-08-28 08:02:22 -07:00
2016-02-17 19:55:15 -07:00
var afterNavigate = function () {
2016-03-16 22:04:32 -07:00
2016-08-17 13:10:24 -07:00
document.removeEventListener('pageinit', afterNavigate);
2016-05-09 12:27:38 -07:00
if (window.location.href.toLowerCase().indexOf(url.toLowerCase()) != -1) {
this.firstTabIndex = index;
2015-08-28 08:02:22 -07:00
}
2016-02-17 19:55:15 -07:00
};
2015-08-28 10:39:52 -07:00
2016-02-17 19:55:15 -07:00
if (window.location.href.toLowerCase().indexOf(url.toLowerCase()) != -1) {
2015-08-28 08:02:22 -07:00
2016-06-11 10:10:06 -07:00
afterNavigate.call(viewManager.currentView());
2016-02-17 19:55:15 -07:00
} else {
2016-05-09 12:27:38 -07:00
2016-08-17 13:10:24 -07:00
pageClassOn('pageinit', 'page', afterNavigate);
2016-02-17 19:55:15 -07:00
Dashboard.navigate(url);
}
},
2015-08-28 08:02:22 -07:00
2016-02-17 19:55:15 -07:00
getArtistLinksHtml: function (artists, cssClass) {
2015-03-13 08:54:20 -07:00
2016-02-17 19:55:15 -07:00
var html = [];
2015-03-13 08:54:20 -07:00
2016-02-17 19:55:15 -07:00
for (var i = 0, length = artists.length; i < length; i++) {
2015-03-13 08:54:20 -07:00
2016-02-17 19:55:15 -07:00
var artist = artists[i];
2015-03-13 08:54:20 -07:00
2016-02-17 19:55:15 -07:00
var css = cssClass ? (' class="' + cssClass + '"') : '';
html.push('<a' + css + ' href="itemdetails.html?id=' + artist.Id + '">' + artist.Name + '</a>');
2015-03-13 08:54:20 -07:00
2016-02-17 19:55:15 -07:00
}
2015-03-13 08:54:20 -07:00
2016-02-17 19:55:15 -07:00
html = html.join(' / ');
2015-03-13 08:54:20 -07:00
2016-02-17 19:55:15 -07:00
return html;
},
2015-03-13 08:54:20 -07:00
2016-02-17 19:55:15 -07:00
playInExternalPlayer: function (id) {
2015-06-02 10:46:44 -07:00
2016-02-17 19:55:15 -07:00
Dashboard.loadExternalPlayer().then(function () {
ExternalPlayer.showMenu(id);
});
},
2015-05-25 10:32:22 -07:00
2016-02-17 19:55:15 -07:00
getHref: function (item, context, topParentId) {
2015-10-04 09:15:08 -07:00
2016-02-17 19:55:15 -07:00
var href = LibraryBrowser.getHrefInternal(item, context);
2013-04-30 10:21:21 -07:00
2016-02-17 19:55:15 -07:00
if (context == 'tv') {
if (!topParentId) {
topParentId = LibraryMenu.getTopParentId();
}
2014-05-29 12:34:20 -07:00
2016-02-17 19:55:15 -07:00
if (topParentId) {
href += href.indexOf('?') == -1 ? "?topParentId=" : "&topParentId=";
href += topParentId;
}
2015-09-21 18:05:33 -07:00
}
2014-07-16 20:17:14 -07:00
2016-02-17 19:55:15 -07:00
return href;
},
getHrefInternal: function (item, context) {
if (!item) {
throw new Error('item cannot be null');
2015-09-21 18:05:33 -07:00
}
2014-07-16 20:17:14 -07:00
2016-02-17 19:55:15 -07:00
if (item.url) {
return item.url;
}
2014-05-29 12:34:20 -07:00
2016-02-17 19:55:15 -07:00
// Handle search hints
var id = item.Id || item.ItemId;
2013-04-10 22:27:27 -07:00
2016-02-17 19:55:15 -07:00
if (item.CollectionType == 'livetv') {
return 'livetv.html';
}
2014-05-04 17:46:52 -07:00
2016-02-17 19:55:15 -07:00
if (item.CollectionType == 'channels') {
2013-04-10 22:27:27 -07:00
2016-02-17 19:55:15 -07:00
return 'channels.html';
}
2013-04-27 06:05:33 -07:00
2016-02-17 19:55:15 -07:00
if (context != 'folders') {
if (item.CollectionType == 'movies') {
return 'movies.html?topParentId=' + item.Id;
}
2014-06-07 12:46:24 -07:00
2016-02-17 19:55:15 -07:00
if (item.CollectionType == 'boxsets') {
2016-06-18 12:21:28 -07:00
return 'itemlist.html?topParentId=' + item.Id + '&parentId=' + item.Id;
2016-02-17 19:55:15 -07:00
}
2015-05-07 07:04:10 -07:00
2016-02-17 19:55:15 -07:00
if (item.CollectionType == 'tvshows') {
return 'tv.html?topParentId=' + item.Id;
}
2014-06-07 12:46:24 -07:00
2016-02-17 19:55:15 -07:00
if (item.CollectionType == 'music') {
return 'music.html?topParentId=' + item.Id;
}
2014-06-07 12:46:24 -07:00
2016-02-17 19:55:15 -07:00
if (item.CollectionType == 'games') {
2016-05-18 14:46:56 -07:00
return id ? "itemlist.html?parentId=" + id : "#";
//return 'gamesrecommended.html?topParentId=' + item.Id;
2016-02-17 19:55:15 -07:00
}
if (item.CollectionType == 'playlists') {
return 'playlists.html?topParentId=' + item.Id;
}
if (item.CollectionType == 'photos') {
return 'photos.html?topParentId=' + item.Id;
}
2014-08-14 06:24:30 -07:00
}
2016-04-15 12:20:04 -07:00
else if (item.IsFolder) {
2016-08-29 11:42:53 -07:00
if (item.Type != "BoxSet" && item.Type != "Series") {
2016-08-29 00:12:24 -07:00
return id ? "itemlist.html?parentId=" + id : "#";
}
2016-04-15 12:20:04 -07:00
}
2016-02-17 19:55:15 -07:00
if (item.Type == 'CollectionFolder') {
2016-03-18 12:43:17 -07:00
return 'itemlist.html?topParentId=' + item.Id + '&parentId=' + item.Id;
2014-08-14 06:24:30 -07:00
}
2014-05-06 19:28:19 -07:00
2016-02-17 19:55:15 -07:00
if (item.Type == "PhotoAlbum") {
return "itemlist.html?context=photos&parentId=" + id;
2014-08-14 06:24:30 -07:00
}
2016-02-17 19:55:15 -07:00
if (item.Type == "Playlist") {
return "itemdetails.html?id=" + id;
2014-08-14 06:24:30 -07:00
}
2016-02-17 19:55:15 -07:00
if (item.Type == "TvChannel") {
return "itemdetails.html?id=" + id;
2014-08-14 06:24:30 -07:00
}
2016-02-17 19:55:15 -07:00
if (item.Type == "Channel") {
return "channelitems.html?id=" + id;
}
2016-03-19 08:38:05 -07:00
if ((item.IsFolder && item.SourceType == 'Channel') || item.Type == 'ChannelFolderItem') {
2016-02-17 19:55:15 -07:00
return "channelitems.html?id=" + item.ChannelId + '&folderId=' + item.Id;
}
if (item.Type == "Program") {
return "itemdetails.html?id=" + id;
2015-04-19 08:54:20 -07:00
}
2014-05-06 19:28:19 -07:00
2016-02-17 19:55:15 -07:00
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;
}
2015-08-20 20:21:27 -07:00
2016-02-17 19:55:15 -07:00
if (item.Type == "MusicArtist") {
return "itemdetails.html?id=" + id;
}
2013-11-26 09:22:11 -07:00
2016-02-17 19:55:15 -07:00
var contextSuffix = context ? ('&context=' + context) : '';
2015-08-20 20:21:27 -07:00
2016-02-17 19:55:15 -07:00
if (item.Type == "Series" || item.Type == "Season" || item.Type == "Episode") {
return "itemdetails.html?id=" + id + contextSuffix;
}
2015-08-20 20:21:27 -07:00
2016-02-17 19:55:15 -07:00
if (item.IsFolder) {
return id ? "itemlist.html?parentId=" + id : "#";
}
2013-04-10 22:27:27 -07:00
2016-02-17 19:55:15 -07:00
return "itemdetails.html?id=" + id;
},
2013-04-10 22:27:27 -07:00
2016-02-17 19:55:15 -07:00
getListItemInfo: function (elem) {
2014-08-01 19:34:45 -07:00
2016-02-17 19:55:15 -07:00
var elemWithAttributes = elem;
2014-08-01 19:34:45 -07:00
while (!elemWithAttributes.getAttribute('data-id')) {
2016-02-17 19:55:15 -07:00
elemWithAttributes = elemWithAttributes.parentNode;
2014-08-01 19:34:45 -07:00
}
var itemId = elemWithAttributes.getAttribute('data-id');
2016-02-17 19:55:15 -07:00
var index = elemWithAttributes.getAttribute('data-index');
var mediaType = elemWithAttributes.getAttribute('data-mediatype');
2015-12-14 08:43:03 -07:00
2016-02-17 19:55:15 -07:00
return {
id: itemId,
index: index,
mediaType: mediaType,
context: elemWithAttributes.getAttribute('data-context')
};
},
2016-02-17 19:55:15 -07:00
getFutureDateText: function (date) {
2014-05-10 10:28:03 -07:00
2016-02-17 19:55:15 -07:00
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');
2014-05-10 10:28:03 -07:00
2016-02-17 19:55:15 -07:00
var day = weekday[date.getDay()];
date = date.toLocaleDateString();
2014-05-10 10:28:03 -07:00
2016-02-17 19:55:15 -07:00
if (date.toLowerCase().indexOf(day.toLowerCase()) == -1) {
return day + " " + date;
2014-05-10 10:28:03 -07:00
}
2016-02-17 19:55:15 -07:00
return date;
},
2014-05-10 10:28:03 -07:00
2016-02-17 19:55:15 -07:00
renderName: function (item, nameElem, linkToElement, context) {
2013-05-04 21:49:49 -07:00
2016-05-11 10:46:44 -07:00
var name = itemHelper.getDisplayName(item, {
includeParentInfo: false
});
2016-02-17 19:55:15 -07:00
Dashboard.setPageTitle(name);
2016-02-17 19:55:15 -07:00
if (linkToElement) {
2016-06-24 09:51:13 -07:00
nameElem.innerHTML = '<a class="detailPageParentLink" href="' + LibraryBrowser.getHref(item, context) + '">' + name + '</a>';
2016-02-17 19:55:15 -07:00
} else {
2016-06-24 09:51:13 -07:00
nameElem.innerHTML = name;
2016-02-17 19:55:15 -07:00
}
},
2016-02-17 19:55:15 -07:00
renderParentName: function (item, parentNameElem, context) {
2016-02-17 19:55:15 -07:00
var html = [];
2016-02-17 19:55:15 -07:00
var contextParam = context ? ('&context=' + context) : '';
2014-09-29 21:47:30 -07:00
2016-02-17 19:55:15 -07:00
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") {
2016-02-17 19:55:15 -07:00
html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + item.SeriesId + contextParam + '">' + item.SeriesName + '</a>');
}
2016-02-17 19:55:15 -07:00
if (item.SeriesName && item.Type == "Season") {
2016-02-17 19:55:15 -07:00
html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + item.SeriesId + contextParam + '">' + item.SeriesName + '</a>');
2014-09-16 18:38:50 -07:00
2016-02-17 19:55:15 -07:00
} else if (item.ParentIndexNumber != null && item.Type == "Episode") {
2016-02-17 19:55:15 -07:00
html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + item.SeasonId + contextParam + '">' + item.SeasonName + '</a>');
2014-09-16 18:38:50 -07:00
2016-02-17 19:55:15 -07:00
} 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>');
2013-07-22 16:59:28 -07:00
2016-02-17 19:55:15 -07:00
} else if (item.Album && item.Type == "MusicVideo" && item.AlbumId) {
html.push('<a class="detailPageParentLink" href="itemdetails.html?id=' + item.AlbumId + contextParam + '">' + item.Album + '</a>');
2016-02-17 19:55:15 -07:00
} else if (item.Album) {
html.push(item.Album);
} else if (item.Type == 'Program' && item.EpisodeTitle) {
html.push(item.Name);
}
2016-02-17 19:55:15 -07:00
if (html.length) {
2016-06-24 09:51:13 -07:00
parentNameElem.classList.remove('hide');
parentNameElem.innerHTML = html.join(' - ');
2016-02-17 19:55:15 -07:00
} else {
2016-06-24 09:51:13 -07:00
parentNameElem.classList.add('hide');
2016-02-17 19:55:15 -07:00
}
},
showLayoutMenu: function (button, currentLayout, views) {
2014-07-19 21:46:29 -07:00
var dispatchEvent = true;
2014-07-19 21:46:29 -07:00
if (!views) {
2015-08-15 16:10:50 -07:00
dispatchEvent = false;
// Add banner and list once all screens support them
views = button.getAttribute('data-layouts');
2015-09-01 15:04:54 -07:00
views = views ? views.split(',') : ['List', 'Poster', 'PosterCard', 'Thumb', 'ThumbCard'];
}
2015-08-15 16:10:50 -07:00
2016-02-17 19:55:15 -07:00
var menuItems = views.map(function (v) {
return {
name: Globalize.translate('Option' + v),
id: v,
selected: currentLayout == v
2016-02-17 19:55:15 -07:00
};
});
2015-08-15 16:10:50 -07:00
2016-02-17 19:55:15 -07:00
require(['actionsheet'], function (actionsheet) {
2015-08-15 16:10:50 -07:00
2016-02-17 19:55:15 -07:00
actionsheet.show({
items: menuItems,
positionTo: button,
callback: function (id) {
2015-08-15 16:10:50 -07:00
2016-05-27 10:18:22 -07:00
button.dispatchEvent(new CustomEvent('layoutchange', {
detail: {
viewStyle: id
},
bubbles: true,
cancelable: false
}));
if (!dispatchEvent) {
2016-05-28 23:04:11 -07:00
if (window.$) {
$(button).trigger('layoutchange', [id]);
2016-05-28 23:04:11 -07:00
}
}
2016-02-17 19:55:15 -07:00
}
});
2015-08-15 16:10:50 -07:00
2016-02-17 19:55:15 -07:00
});
2015-08-15 16:10:50 -07:00
2016-02-17 19:55:15 -07:00
},
2015-08-15 16:10:50 -07:00
2016-02-17 19:55:15 -07:00
getQueryPagingHtml: function (options) {
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
var startIndex = options.startIndex;
var limit = options.limit;
var totalRecordCount = options.totalRecordCount;
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
if (limit && options.updatePageSizeSetting !== false) {
try {
appStorage.setItem(options.pageSizeKey || pageSizeKey, limit);
} catch (e) {
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
}
2014-07-19 21:46:29 -07:00
}
2016-02-17 19:55:15 -07:00
var html = '';
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
var recordsEnd = Math.min(startIndex + limit, totalRecordCount);
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
// 20 is the minimum page size
var showControls = totalRecordCount > 20 || limit < totalRecordCount;
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
html += '<div class="listPaging">';
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
if (showControls) {
html += '<span style="vertical-align:middle;">';
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
var startAtDisplay = totalRecordCount ? startIndex + 1 : 0;
html += startAtDisplay + '-' + recordsEnd + ' of ' + totalRecordCount;
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
html += '</span>';
}
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
if (showControls || options.viewButton || options.filterButton || options.sortButton || options.addLayoutButton) {
2014-07-19 21:46:29 -07:00
2016-06-14 20:12:32 -07:00
html += '<div style="display:inline-block;">';
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
if (showControls) {
2014-07-19 21:46:29 -07:00
2016-07-07 20:24:22 -07:00
html += '<button is="paper-icon-button-light" class="btnPreviousPage autoSize" ' + (startIndex ? '' : 'disabled') + '><i class="md-icon">&#xE5C4;</i></button>';
2016-06-14 12:21:26 -07:00
html += '<button is="paper-icon-button-light" class="btnNextPage autoSize" ' + (startIndex + limit >= totalRecordCount ? 'disabled' : '') + '><i class="md-icon">arrow_forward</i></button>';
2016-02-17 19:55:15 -07:00
}
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
if (options.addLayoutButton) {
2015-08-15 16:10:50 -07:00
2016-06-14 12:21:26 -07:00
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>';
2016-02-17 19:55:15 -07:00
}
2015-08-15 16:10:50 -07:00
2016-02-17 19:55:15 -07:00
if (options.sortButton) {
2015-08-25 19:13:28 -07:00
2016-06-14 12:21:26 -07:00
html += '<button is="paper-icon-button-light" class="btnSort autoSize" title="' + Globalize.translate('ButtonSort') + '"><i class="md-icon">sort_by_alpha</i></button>';
2016-02-17 19:55:15 -07:00
}
2015-08-25 19:13:28 -07:00
2016-02-17 19:55:15 -07:00
if (options.filterButton) {
2016-02-14 13:34:54 -07:00
2016-06-14 12:21:26 -07:00
html += '<button is="paper-icon-button-light" class="btnFilter autoSize" title="' + Globalize.translate('ButtonFilter') + '"><i class="md-icon">filter_list</i></button>';
2016-02-17 19:55:15 -07:00
}
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
html += '</div>';
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
if (showControls && options.showLimit) {
2015-06-18 21:23:55 -07:00
2016-02-17 19:55:15 -07:00
var id = "selectPageSize";
2014-07-19 21:46:29 -07:00
var pageSizes = options.pageSizes || [20, 50, 100, 200, 300, 400, 500];
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
var optionsHtml = pageSizes.map(function (val) {
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
if (limit == val) {
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
return '<option value="' + val + '" selected="selected">' + val + '</option>';
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
} else {
return '<option value="' + val + '">' + val + '</option>';
}
}).join('');
2014-07-19 21:46:29 -07:00
2016-02-17 19:55:15 -07:00
// 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>';
}
2014-07-19 21:46:29 -07:00
}
2016-02-17 19:55:15 -07:00
html += '</div>';
2013-04-10 06:53:44 -07:00
2016-02-17 19:55:15 -07:00
return html;
},
2015-08-25 19:13:28 -07:00
2016-02-17 19:55:15 -07:00
showSortMenu: function (options) {
2015-09-17 20:43:30 -07:00
2016-07-10 00:01:25 -07:00
require(['dialogHelper', 'emby-radio'], function (dialogHelper) {
2015-09-17 20:43:30 -07:00
2016-03-23 12:03:17 -07:00
var dlg = dialogHelper.createDialog({
2016-02-17 19:55:15 -07:00
removeOnClose: true,
modal: false,
entryAnimationDuration: 160,
exitAnimationDuration: 200
});
2016-01-30 13:59:09 -07:00
2016-02-17 19:55:15 -07:00
dlg.classList.add('ui-body-a');
dlg.classList.add('background-theme-a');
2016-05-31 10:04:49 -07:00
dlg.classList.add('formDialog');
2015-08-25 19:13:28 -07:00
2016-02-17 19:55:15 -07:00
var html = '';
2015-08-25 19:13:28 -07:00
2016-03-31 11:46:03 -07:00
html += '<div style="margin:0;padding:1.25em 1.5em 1.5em;">';
2015-08-25 19:13:28 -07:00
2016-02-17 19:55:15 -07:00
html += '<h2 style="margin:0 0 .5em;">';
html += Globalize.translate('HeaderSortBy');
html += '</h2>';
2015-08-25 19:13:28 -07:00
2016-07-10 00:01:25 -07:00
var i, length;
var isChecked;
html += '<div>';
for (i = 0, length = options.items.length; i < length; i++) {
2015-08-25 19:13:28 -07:00
2016-02-17 19:55:15 -07:00
var option = options.items[i];
2015-08-25 19:13:28 -07:00
2016-07-10 00:01:25 -07:00
var radioValue = option.id.replace(',', '_');
isChecked = (options.query.SortBy || '').replace(',', '_') == radioValue ? ' checked' : '';
2016-08-04 12:05:52 -07:00
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>';
2016-02-17 19:55:15 -07:00
}
2016-07-10 00:01:25 -07:00
html += '</div>';
2016-02-17 19:55:15 -07:00
html += '<h2 style="margin: 1em 0 .5em;">';
html += Globalize.translate('HeaderSortOrder');
html += '</h2>';
2016-07-10 00:01:25 -07:00
html += '<div>';
isChecked = options.query.SortOrder == 'Ascending' ? ' checked' : '';
2016-08-04 12:05:52 -07:00
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>';
2016-07-10 00:01:25 -07:00
isChecked = options.query.SortOrder == 'Descending' ? ' checked' : '';
2016-08-04 12:05:52 -07:00
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>';
2016-07-10 00:01:25 -07:00
html += '</div>';
2016-02-17 19:55:15 -07:00
html += '</div>';
2015-08-25 19:13:28 -07:00
2016-02-17 19:55:15 -07:00
dlg.innerHTML = html;
document.body.appendChild(dlg);
2015-08-25 19:13:28 -07:00
2016-02-26 21:39:11 -07:00
// Seeing an issue in Firefox and IE where it's initially visible in the bottom right, then moves to the center
2016-08-14 12:58:13 -07:00
var delay = browser.animate ? 0 : 100;
2016-03-16 14:30:49 -07:00
setTimeout(function () {
2016-03-23 12:03:17 -07:00
dialogHelper.open(dlg);
2016-02-26 21:39:11 -07:00
}, delay);
2015-08-25 19:13:28 -07:00
2016-07-10 00:01:25 -07:00
function onSortByChange() {
var newValue = this.value;
if (this.checked) {
var changed = options.query.SortBy != newValue;
2015-12-14 08:43:03 -07:00
2016-07-10 00:01:25 -07:00
options.query.SortBy = newValue.replace('_', ',');
options.query.StartIndex = 0;
2015-08-25 19:13:28 -07:00
2016-07-10 00:01:25 -07:00
if (options.callback && changed) {
options.callback();
}
2016-02-17 19:55:15 -07:00
}
2016-07-10 00:01:25 -07:00
}
2015-08-25 19:13:28 -07:00
2016-07-10 00:01:25 -07:00
var sortBys = dlg.querySelectorAll('.menuSortBy');
for (i = 0, length = sortBys.length; i < length; i++) {
sortBys[i].addEventListener('change', onSortByChange);
}
2015-08-25 19:13:28 -07:00
2016-07-10 00:01:25 -07:00
function onSortOrderChange() {
var newValue = this.value;
if (this.checked) {
var changed = options.query.SortOrder != newValue;
2015-12-14 08:43:03 -07:00
2016-07-10 00:01:25 -07:00
options.query.SortOrder = newValue;
options.query.StartIndex = 0;
2015-08-25 19:13:28 -07:00
2016-07-10 00:01:25 -07:00
if (options.callback && changed) {
options.callback();
}
2016-02-17 19:55:15 -07:00
}
2016-07-10 00:01:25 -07:00
}
var sortOrders = dlg.querySelectorAll('.menuSortOrder');
for (i = 0, length = sortOrders.length; i < length; i++) {
sortOrders[i].addEventListener('change', onSortOrderChange);
}
});
2016-02-17 19:55:15 -07:00
},
2015-08-25 19:13:28 -07:00
2016-02-17 19:55:15 -07:00
renderDetailImage: function (elem, item, editable, preferThumb) {
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
var imageTags = item.ImageTags || {};
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
if (item.PrimaryImageTag) {
imageTags.Primary = item.PrimaryImageTag;
}
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
var html = '';
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
var url;
var shape = 'portrait';
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
var imageHeight = 360;
var detectRatio = false;
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
if (preferThumb && imageTags.Thumb) {
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
url = ApiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxHeight: imageHeight,
tag: item.ImageTags.Thumb
});
shape = 'thumb';
}
else if (imageTags.Primary) {
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
url = ApiClient.getScaledImageUrl(item.Id, {
type: "Primary",
maxHeight: imageHeight,
tag: item.ImageTags.Primary
});
detectRatio = true;
}
else if (item.BackdropImageTags && item.BackdropImageTags.length) {
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
url = ApiClient.getScaledImageUrl(item.Id, {
type: "Backdrop",
maxHeight: imageHeight,
tag: item.BackdropImageTags[0]
});
shape = 'thumb';
}
else if (imageTags.Thumb) {
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
url = ApiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxHeight: imageHeight,
tag: item.ImageTags.Thumb
});
shape = 'thumb';
}
else if (imageTags.Disc) {
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
url = ApiClient.getScaledImageUrl(item.Id, {
type: "Disc",
maxHeight: imageHeight,
tag: item.ImageTags.Disc
});
shape = 'square';
}
else if (item.AlbumId && item.AlbumPrimaryImageTag) {
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
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';
}
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
html += '<div style="position:relative;">';
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
if (editable) {
html += "<a class='itemDetailGalleryLink' href='#'>";
2016-02-17 19:55:15 -07:00
}
2015-02-05 22:59:55 -07:00
2016-02-17 19:55:15 -07:00
if (detectRatio && item.PrimaryImageAspectRatio) {
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
if (item.PrimaryImageAspectRatio >= 1.48) {
shape = 'thumb';
} else if (item.PrimaryImageAspectRatio >= .85 && item.PrimaryImageAspectRatio <= 1.34) {
shape = 'square';
}
2015-02-02 21:54:52 -07:00
}
2016-02-17 19:55:15 -07:00
html += "<img class='itemDetailImage lazy' src='css/images/empty.png' />";
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
if (editable) {
html += "</a>";
}
2015-02-02 21:54:52 -07:00
2016-07-30 16:23:57 -07:00
var progressHtml = item.IsFolder || !item.UserData ? '' : indicators.getProgressBarHtml(item);
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
html += '<div class="detailImageProgressContainer">';
if (progressHtml) {
html += progressHtml;
}
html += "</div>";
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
html += "</div>";
2015-06-28 08:43:49 -07:00
2016-02-17 19:55:15 -07:00
elem.innerHTML = html;
2015-09-24 22:15:29 -07:00
2016-02-17 19:55:15 -07:00
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');
2015-12-14 08:43:03 -07:00
}
2015-02-02 21:54:52 -07:00
2016-02-17 19:55:15 -07:00
var img = elem.querySelector('img');
img.onload = function () {
if (img.src.indexOf('empty.png') == -1) {
img.classList.add('loaded');
}
};
ImageLoader.lazyImage(img, url);
},
2015-08-23 19:08:20 -07:00
2016-02-17 19:55:15 -07:00
renderDetailPageBackdrop: function (page, item) {
2016-02-17 19:55:15 -07:00
var screenWidth = screen.availWidth;
2016-02-17 19:55:15 -07:00
var imgUrl;
var hasbackdrop = false;
2016-03-16 22:04:32 -07:00
var itemBackdropElement = page.querySelector('#itemBackdrop');
2016-02-17 19:55:15 -07:00
if (item.BackdropImageTags && item.BackdropImageTags.length) {
2016-02-17 19:55:15 -07:00
imgUrl = ApiClient.getScaledImageUrl(item.Id, {
type: "Backdrop",
index: 0,
maxWidth: screenWidth,
tag: item.BackdropImageTags[0]
});
2016-03-16 22:04:32 -07:00
itemBackdropElement.classList.remove('noBackdrop');
2016-05-15 18:22:22 -07:00
ImageLoader.lazyImage(itemBackdropElement, imgUrl, false);
2016-02-17 19:55:15 -07:00
hasbackdrop = true;
}
else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) {
2016-02-17 19:55:15 -07:00
imgUrl = ApiClient.getScaledImageUrl(item.ParentBackdropItemId, {
type: 'Backdrop',
index: 0,
tag: item.ParentBackdropImageTags[0],
maxWidth: screenWidth
});
2016-03-16 22:04:32 -07:00
itemBackdropElement.classList.remove('noBackdrop');
2016-05-15 18:22:22 -07:00
ImageLoader.lazyImage(itemBackdropElement, imgUrl, false);
2016-02-17 19:55:15 -07:00
hasbackdrop = true;
}
else {
2016-03-16 22:04:32 -07:00
itemBackdropElement.classList.add('noBackdrop');
itemBackdropElement.style.backgroundImage = '';
2016-02-17 19:55:15 -07:00
}
2016-02-17 19:55:15 -07:00
return hasbackdrop;
}
2016-02-17 19:55:15 -07:00
};
2015-08-18 10:54:29 -07:00
2016-02-17 19:55:15 -07:00
return libraryBrowser;
2015-08-24 20:13:04 -07:00
2016-02-17 19:55:15 -07:00
})(window, document, screen);
2015-08-24 20:13:04 -07:00
2016-02-17 19:55:15 -07:00
window.LibraryBrowser = libraryBrowser;
return libraryBrowser;
});