1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

infinite scroll proof of concept on tv series

This commit is contained in:
Luke Pulverenti 2016-04-24 00:24:16 -04:00
parent 826a115d81
commit b9f3bc6cf1
9 changed files with 1000 additions and 359 deletions

View file

@ -1,21 +1,24 @@
define(['iron-list', 'lazyload-image'], function () { define(['layoutManager', 'iron-list', 'lazyload-image'], function (layoutManager) {
function getTemplate(scrollTarget) { function getTemplate(scrollTarget) {
var html = ''; var html = '';
var maxPhysical = 60;
html += '<template is="dom-bind">\ html += '<template is="dom-bind">\
<iron-list as="item" id="ironList" scroll-target="' + scrollTarget + '" max-physical-count="60" style="width:96%;" grid>\ <iron-list as="item" id="ironList" scroll-target="' + scrollTarget + '" max-physical-count="' + maxPhysical + '" style="width:96%;" grid>\
<template>\ <template>\
<div class$="{{item.elemClass}}" data-action$="{{item.defaultAction}}">\ <div class$="{{item.elemClass}}" data-action$="{{item.defaultAction}}" data-itemid$="{{item.data-itemid}}" data-commands$="{{item.data-commands}}" data-context$="{{item.data-context}}" data-isfolder$="{{item.data-isfolder}}" data-itemtype$="{{item.data-itemtype}}" data-mediatype$="{{item.data-mediatype}}" data-positionticks$="{{item.data-positionticks}}" data-playaccess$="{{item.data-playaccess}}" data-locationtype$="{{item.data-locationtype}}" data-index$="{{item.data-index}}" data-albumid$="{{item.data-albumid}}" data-channelid$="{{item.data-channelid}}" data-artistid$="{{item.data-artistid}}">\
<div class$="{{item.cardBoxClass}}">\ <div class$="{{item.cardBoxClass}}">\
<div class="cardScalable">\ <div class="cardScalable">\
<div class="cardPadder"></div>\ <div class="cardPadder"></div>\
<a onclick$="{{item.onclick}}" class$="{{item.anchorClass}}" href$="{{item.href}}">\ <a onclick$="{{item.onclick}}" data-action$="{{item.defaultAction}}" class$="{{item.anchorClass}}" href$="{{item.href}}">\
<img class$="{{item.imageClass}}" is="lazyload-image" src$="{{item.imgUrl}}" />\ <img class$="{{item.imageClass}}" is="lazyload-image" src$="{{item.imgUrl}}" />\
<div inner-h-t-m-l="{{item.overlayHtml}}"></div>\
</a>\ </a>\
</div>\ </div>\
<!--cardFooter will be here-->\ <div inner-h-t-m-l="{{item.footerHtml}}"></div>\
</div>\ </div>\
</div>\ </div>\
</template>\ </template>\

View file

@ -62,10 +62,18 @@
padding-bottom: 0; padding-bottom: 0;
} }
.pageWithAbsoluteTabs .pageTabContent, .libraryPage > .ui-content { .pageWithAbsoluteTabs .pageTabsContainer, .libraryPage > .ui-content {
padding-top: 10px; padding-top: 10px;
} }
.absolutePageTabContent {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
/*.pageWithAbsoluteTabs .pageTabContent { /*.pageWithAbsoluteTabs .pageTabContent {
padding-left: .5em !important; padding-left: .5em !important;
padding-right: .5em !important; padding-right: .5em !important;
@ -1174,7 +1182,7 @@ span.itemCommunityRating:not(:empty) + .userDataIcons {
.alphabetPicker { .alphabetPicker {
position: fixed; position: fixed;
right: 0; right: 5px;
bottom: 0; bottom: 0;
z-index: 999; z-index: 999;
text-align: center; text-align: center;
@ -1183,16 +1191,20 @@ span.itemCommunityRating:not(:empty) + .userDataIcons {
line-height: 1; line-height: 1;
} }
.alphabetPicker a { .layout-desktop .absolutePageTabContent .alphabetPicker {
display: block; right: 15px;
text-decoration: none; }
padding: 1px 5px 1px 10px;
font-weight: 500;
}
.alphabetPicker a:not(.selectedCharacter) { .alphabetPicker a {
color: #bbb !important; display: block;
} text-decoration: none;
padding: 1px 2px 1px 5px;
font-weight: 500;
}
.alphabetPicker a:not(.selectedCharacter) {
color: #bbb !important;
}
.selectedCharacter { .selectedCharacter {
@ -1256,6 +1268,17 @@ span.itemCommunityRating:not(:empty) + .userDataIcons {
.itemsContainerWithAlphaPicker { .itemsContainerWithAlphaPicker {
margin-right: 20px; margin-right: 20px;
} }
.absolutePageTabContent .itemsContainerWithAlphaPicker {
margin-right: 30px;
}
}
@media all and (min-height: 480px) and (max-width: 800px) {
.absolutePageTabContent .itemsContainerWithAlphaPicker iron-list {
width: 99.5% !important;
}
} }
@media all and (min-height: 500px) { @media all and (min-height: 500px) {
@ -1267,7 +1290,7 @@ span.itemCommunityRating:not(:empty) + .userDataIcons {
@media all and (min-width: 1200px) { @media all and (min-width: 1200px) {
.itemsContainerWithAlphaPicker { .itemsContainerWithAlphaPicker, .absolutePageTabContent .itemsContainerWithAlphaPicker {
margin-right: 0; margin-right: 0;
} }
} }

View file

@ -10,6 +10,12 @@
padding-top: 98px !important; padding-top: 98px !important;
} }
.absolutePageTabContent {
margin: 0 !important;
width: 100% !important;
top: 98px !important;
}
.sidebarDivider { .sidebarDivider {
height: 1px; height: 1px;
background: #eaeaea; background: #eaeaea;

View file

@ -870,7 +870,7 @@ paper-input + .fieldDescription {
padding: 1em; padding: 1em;
} }
.page > .ui-content, .pageWithAbsoluteTabs .pageTabContent { .page > .ui-content, .pageWithAbsoluteTabs .pageTabContent, .absolutePageTabContent .itemsContainer {
/* Need this so that the audio player doesn't cover content, but also for unveil lazy loading. */ /* Need this so that the audio player doesn't cover content, but also for unveil lazy loading. */
padding-bottom: 160px; padding-bottom: 160px;
} }

View file

@ -1,8 +1,9 @@
define(['jQuery'], function ($) { define(['ironCardList', 'scrollThreshold', 'events', 'libraryBrowser', 'jQuery'], function (ironCardList, scrollThreshold, events, libraryBrowser, $) {
return function (view, params, tabContent) { return function (view, params, tabContent) {
var self = this; var self = this;
var pageSize = libraryBrowser.getDefaultPageSize();
var data = {}; var data = {};
@ -23,13 +24,13 @@
ImageTypeLimit: 1, ImageTypeLimit: 1,
EnableImageTypes: "Primary,Backdrop,Banner,Thumb", EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
StartIndex: 0, StartIndex: 0,
Limit: LibraryBrowser.getDefaultPageSize() Limit: pageSize
}, },
view: LibraryBrowser.getSavedView(key) || LibraryBrowser.getDefaultItemsView('Poster', 'Poster') view: libraryBrowser.getSavedView(key) || libraryBrowser.getDefaultItemsView('Poster', 'Poster')
}; };
pageData.query.ParentId = params.topParentId; pageData.query.ParentId = params.topParentId;
LibraryBrowser.loadSavedQueryValues(key, pageData.query); libraryBrowser.loadSavedQueryValues(key, pageData.query);
} }
return pageData; return pageData;
} }
@ -42,164 +43,111 @@
function getSavedQueryKey(context) { function getSavedQueryKey(context) {
if (!context.savedQueryKey) { if (!context.savedQueryKey) {
context.savedQueryKey = LibraryBrowser.getSavedQueryKey('episodes'); context.savedQueryKey = libraryBrowser.getSavedQueryKey('episodes');
} }
return context.savedQueryKey; return context.savedQueryKey;
} }
function setCardOptions(result) {
var cardOptions;
var view = self.getCurrentViewStyle();
if (view == "List") {
html = libraryBrowser.getListViewHtml({
items: result.Items,
sortBy: query.SortBy
});
}
else if (view == "PosterCard") {
cardOptions = {
items: result.Items,
shape: "backdrop",
showTitle: true,
showParentTitle: true,
lazy: true,
cardLayout: true,
showDetailsMenu: true
};
}
else {
// poster
cardOptions = {
items: result.Items,
shape: "backdrop",
showTitle: true,
showParentTitle: true,
overlayText: true,
lazy: true,
showDetailsMenu: true,
overlayPlayButton: true
};
}
self.cardOptions = cardOptions;
}
function reloadItems(page) { function reloadItems(page) {
self.isLoading = true;
Dashboard.showLoadingMsg(); Dashboard.showLoadingMsg();
var query = getQuery(page); var query = getQuery(page);
var startIndex = query.StartIndex;
var reloadList = !self.cardOptions || startIndex == 0;
ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) { ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) {
// Scroll back up so they can see the results from the beginning
window.scrollTo(0, 0);
var view = getPageData(page).view;
var html = '';
var pagingHtml = LibraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
showLimit: false,
updatePageSizeSetting: false,
addLayoutButton: true,
sortButton: true,
currentLayout: view,
layouts: 'Poster,PosterCard',
filterButton: true
});
page.querySelector('.listTopPaging').innerHTML = pagingHtml;
updateFilterControls(page); updateFilterControls(page);
if (view == "List") { var pushItems = true;
if (reloadList) {
setCardOptions(result);
pushItems = false;
}
libraryBrowser.setPosterViewData(self.cardOptions);
libraryBrowser.setPosterViewDataOnItems(self.cardOptions, result.Items);
html = LibraryBrowser.getListViewHtml({ var ironList = page.querySelector('#ironList');
items: result.Items, if (pushItems) {
sortBy: query.SortBy for (var i = 0, length = result.Items.length; i < length; i++) {
}); ironList.push('items', result.Items[i]);
} }
else if (view == "Poster") { } else {
html += LibraryBrowser.getPosterViewHtml({ ironList.items = result.Items;
items: result.Items,
shape: "backdrop",
showTitle: true,
showParentTitle: true,
overlayText: true,
lazy: true,
showDetailsMenu: true,
overlayPlayButton: true
});
}
else if (view == "PosterCard") {
html += LibraryBrowser.getPosterViewHtml({
items: result.Items,
shape: "backdrop",
showTitle: true,
showParentTitle: true,
lazy: true,
cardLayout: true,
showDetailsMenu: true
});
} }
var elem = page.querySelector('.itemsContainer'); // Hack: notifyResize needs to be done after the items have been rendered
elem.innerHTML = html + pagingHtml; setTimeout(function () {
ImageLoader.lazyChildren(elem); ironList.notifyResize();
self.scrollThreshold.resetSize();
}, 300);
$('.btnNextPage', page).on('click', function () { libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
query.StartIndex += query.Limit;
reloadItems(page);
});
$('.btnPreviousPage', page).on('click', function () {
query.StartIndex -= query.Limit;
reloadItems(page);
});
$('.btnChangeLayout', page).on('layoutchange', function (e, layout) {
getPageData(page).view = layout;
LibraryBrowser.saveViewSetting(getSavedQueryKey(page), layout);
reloadItems(page);
});
$('.btnFilter', page).on('click', function () {
showFilterMenu(page);
});
// On callback make sure to set StartIndex = 0
$('.btnSort', page).on('click', function () {
LibraryBrowser.showSortMenu({
items: [{
name: Globalize.translate('OptionNameSort'),
id: 'SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionTvdbRating'),
id: 'CommunityRating,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionDateAdded'),
id: 'DateCreated,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionPremiereDate'),
id: 'PremiereDate,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionDatePlayed'),
id: 'DatePlayed,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionParentalRating'),
id: 'OfficialRating,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionPlayCount'),
id: 'PlayCount,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionRuntime'),
id: 'Runtime,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionVideoBitrate'),
id: 'VideoBitRate,SeriesSortName,SortName'
}],
callback: function () {
reloadItems(page);
},
query: query
});
});
LibraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
Dashboard.hideLoadingMsg(); Dashboard.hideLoadingMsg();
self.hasMoreItems = result.TotalRecordCount > (startIndex + result.Items.length);
self.isLoading = false;
}); });
} }
function showFilterMenu(page) { self.showFilterMenu = function () {
require(['components/filterdialog/filterdialog'], function (filterDialogFactory) { require(['components/filterdialog/filterdialog'], function (filterDialogFactory) {
var filterDialog = new filterDialogFactory({ var filterDialog = new filterDialogFactory({
query: getQuery(page), query: getQuery(tabContent),
mode: 'episodes' mode: 'episodes'
}); });
Events.on(filterDialog, 'filterchange', function () { Events.on(filterDialog, 'filterchange', function () {
reloadItems(page); reloadItems(tabContent);
}); });
filterDialog.show(); filterDialog.show();
}); });
} };
function updateFilterControls(tabContent) { function updateFilterControls(tabContent) {
@ -230,13 +178,113 @@
reloadItems(tabContent); reloadItems(tabContent);
}); });
tabContent.querySelector('.btnFilter').addEventListener('click', function () {
self.showFilterMenu();
});
tabContent.querySelector('.btnSort').addEventListener('click', function () {
libraryBrowser.showSortMenu({
items: [{
name: Globalize.translate('OptionNameSort'),
id: 'SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionTvdbRating'),
id: 'CommunityRating,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionDateAdded'),
id: 'DateCreated,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionPremiereDate'),
id: 'PremiereDate,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionDatePlayed'),
id: 'DatePlayed,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionParentalRating'),
id: 'OfficialRating,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionPlayCount'),
id: 'PlayCount,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionRuntime'),
id: 'Runtime,SeriesSortName,SortName'
},
{
name: Globalize.translate('OptionVideoBitrate'),
id: 'VideoBitRate,SeriesSortName,SortName'
}],
callback: function () {
reloadItems(tabContent);
},
query: getQuery(tabContent)
});
});
tabContent.querySelector('.btnSelectView').addEventListener('click', function (e) {
libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(','));
});
tabContent.querySelector('.btnSelectView').addEventListener('layoutchange', function (e) {
var viewStyle = e.detail.viewStyle;
getPageData(tabContent).view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
reloadItems(tabContent);
});
} }
initPage(tabContent); self.getCurrentViewStyle = function () {
self.renderTab = function () { return getPageData(tabContent).view;
};
reloadItems(tabContent); initPage(tabContent);
updateFilterControls(tabContent); function createList() {
if (self.listCreated) {
return Promise.resolve();
}
return ironCardList.getTemplate('episodesTab').then(function (html) {
tabContent.querySelector('.itemsContainer').innerHTML = html;
self.listCreated = true;
});
}
function loadMoreItems() {
if (!self.isLoading && self.hasMoreItems) {
getQuery(tabContent).StartIndex += pageSize;
reloadItems(tabContent);
}
}
self.scrollThreshold = new scrollThreshold(tabContent, false);
events.on(self.scrollThreshold, 'lower-threshold', loadMoreItems);
self.renderTab = function () {
createList().then(function () {
reloadItems(tabContent);
updateFilterControls(tabContent);
});
};
self.destroy = function () {
events.off(self.scrollThreshold, 'lower-threshold', loadMoreItems);
if (self.scrollThreshold) {
self.scrollThreshold.destroy();
}
}; };
}; };
}); });

View file

@ -173,6 +173,7 @@
enableFullPaperTabs: function () { enableFullPaperTabs: function () {
return true;
if (browserInfo.animate && !browserInfo.mobile) { if (browserInfo.animate && !browserInfo.mobile) {
//return true; //return true;
} }
@ -1489,49 +1490,94 @@
return outerHtml; return outerHtml;
}, },
getItemDataAttributes: function (item, options, index) { getItemDataAttributesList: function (item, options, index) {
var atts = []; var atts = [];
var itemCommands = LibraryBrowser.getItemCommands(item, options); var itemCommands = LibraryBrowser.getItemCommands(item, options);
atts.push('data-itemid="' + item.Id + '"'); atts.push({
atts.push('data-commands="' + itemCommands.join(',') + '"'); name: 'itemid',
value: item.Id
});
atts.push({
name: 'commands',
value: itemCommands.join(',')
});
if (options.context) { if (options.context) {
atts.push('data-context="' + (options.context || '') + '"'); atts.push({
name: 'context',
value: options.context || ''
});
} }
if (item.IsFolder) { if (item.IsFolder) {
atts.push('data-isfolder="' + item.IsFolder + '"'); atts.push({
name: 'isfolder',
value: item.IsFolder
});
} }
atts.push('data-itemtype="' + item.Type + '"'); atts.push({
name: 'itemtype',
value: item.Type
});
if (item.MediaType) { if (item.MediaType) {
atts.push('data-mediatype="' + (item.MediaType || '') + '"'); atts.push({
name: 'mediatype',
value: item.MediaType || ''
});
} }
if (item.UserData.PlaybackPositionTicks) { if (item.UserData.PlaybackPositionTicks) {
atts.push('data-positionticks="' + (item.UserData.PlaybackPositionTicks || 0) + '"'); atts.push({
name: 'positionticks',
value: (item.UserData.PlaybackPositionTicks || 0)
});
} }
atts.push('data-playaccess="' + (item.PlayAccess || '') + '"'); atts.push({
atts.push('data-locationtype="' + (item.LocationType || '') + '"'); name: 'playaccess',
atts.push('data-index="' + index + '"'); value: item.PlayAccess || ''
});
atts.push({
name: 'locationtype',
value: item.LocationType || ''
});
if (item.AlbumId) { if (item.AlbumId) {
atts.push('data-albumid="' + item.AlbumId + '"'); atts.push({
name: 'albumid',
value: item.AlbumId
});
} }
if (item.ChannelId) { if (item.ChannelId) {
atts.push('data-channelid="' + item.ChannelId + '"'); atts.push({
name: 'channelid',
value: item.ChannelId
});
} }
if (item.ArtistItems && item.ArtistItems.length) { if (item.ArtistItems && item.ArtistItems.length) {
atts.push('data-artistid="' + item.ArtistItems[0].Id + '"'); atts.push({
name: 'artistid',
value: item.ArtistItems[0].Id
});
} }
return atts;
},
getItemDataAttributes: function (item, options, index) {
var atts = LibraryBrowser.getItemDataAttributesList(item, options, index).map(function (i) {
return 'data-' + i.name + '="' + i.value + '"';
});
var html = atts.join(' '); var html = atts.join(' ');
if (html) { if (html) {
@ -1754,15 +1800,12 @@
return result; return result;
}, },
getPosterViewHtml: function (options) { setPosterViewData: function (options) {
var items = options.items; var items = options.items;
var currentIndexValue;
options.shape = options.shape || "portrait"; options.shape = options.shape || "portrait";
var html = "";
var primaryImageAspectRatio = LibraryBrowser.getAveragePrimaryImageAspectRatio(items); var primaryImageAspectRatio = LibraryBrowser.getAveragePrimaryImageAspectRatio(items);
var isThumbAspectRatio = primaryImageAspectRatio && Math.abs(primaryImageAspectRatio - 1.777777778) < .3; var isThumbAspectRatio = primaryImageAspectRatio && Math.abs(primaryImageAspectRatio - 1.777777778) < .3;
var isSquareAspectRatio = primaryImageAspectRatio && Math.abs(primaryImageAspectRatio - 1) < .33 || var isSquareAspectRatio = primaryImageAspectRatio && Math.abs(primaryImageAspectRatio - 1) < .33 ||
@ -1827,8 +1870,446 @@
thumbWidth = 320; thumbWidth = 320;
} }
options.uiAspect = getDesiredAspect(options.shape);
options.primaryImageAspectRatio = primaryImageAspectRatio;
options.posterWidth = posterWidth;
options.thumbWidth = thumbWidth;
options.bannerWidth = bannerWidth;
options.squareSize = squareSize;
},
setPosterViewDataOnItems: function (options, items) {
LibraryBrowser.setPosterViewData(options);
options.shape = options.shape || "portrait";
var html = "";
var primaryImageAspectRatio;
var thumbWidth = options.thumbWidth;
var posterWidth = options.posterWidth;
var squareSize = options.squareSize;
var bannerWidth = options.bannerWidth;
var uiAspect = options.uiAspect;
for (var i = 0, length = items.length; i < length; i++) {
var item = items[i];
primaryImageAspectRatio = LibraryBrowser.getAveragePrimaryImageAspectRatio([item]);
LibraryBrowser.setPosterViewDataOnItem(item, i, options, primaryImageAspectRatio, thumbWidth, posterWidth, squareSize, bannerWidth, uiAspect);
}
return html;
},
setPosterViewDataOnItem: function (item, index, options, primaryImageAspectRatio, thumbWidth, posterWidth, squareSize, bannerWidth, uiAspect) {
var imgUrl = null;
var icon;
var width = null;
var height = null;
var forceName = false;
var enableImageEnhancers = options.enableImageEnhancers !== false;
var cssClass = "card";
if (options.fullWidthOnMobile) {
cssClass += " fullWidthCardOnMobile";
}
var showTitle = options.showTitle == 'auto' ? true : options.showTitle;
var coverImage = options.coverImage;
if (options.autoThumb && item.ImageTags && item.ImageTags.Primary && item.PrimaryImageAspectRatio && item.PrimaryImageAspectRatio >= 1.34) {
width = posterWidth;
height = primaryImageAspectRatio ? Math.round(posterWidth / primaryImageAspectRatio) : null;
imgUrl = ApiClient.getImageUrl(item.Id, {
type: "Primary",
maxHeight: height,
maxWidth: width,
tag: item.ImageTags.Primary,
enableImageEnhancers: enableImageEnhancers
});
if (primaryImageAspectRatio) {
if (uiAspect) {
if (Math.abs(primaryImageAspectRatio - uiAspect) <= .2) {
coverImage = true;
}
}
}
} else if (options.autoThumb && item.ImageTags && item.ImageTags.Thumb) {
imgUrl = ApiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxWidth: thumbWidth,
tag: item.ImageTags.Thumb,
enableImageEnhancers: enableImageEnhancers
});
} else if (options.preferBackdrop && item.BackdropImageTags && item.BackdropImageTags.length) {
imgUrl = ApiClient.getScaledImageUrl(item.Id, {
type: "Backdrop",
maxWidth: thumbWidth,
tag: item.BackdropImageTags[0],
enableImageEnhancers: enableImageEnhancers
});
} else if (options.preferThumb && item.ImageTags && item.ImageTags.Thumb) {
imgUrl = ApiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxWidth: thumbWidth,
tag: item.ImageTags.Thumb,
enableImageEnhancers: enableImageEnhancers
});
} else if (options.preferBanner && item.ImageTags && item.ImageTags.Banner) {
imgUrl = ApiClient.getScaledImageUrl(item.Id, {
type: "Banner",
maxWidth: bannerWidth,
tag: item.ImageTags.Banner,
enableImageEnhancers: enableImageEnhancers
});
} else if (options.preferThumb && item.SeriesThumbImageTag && options.inheritThumb !== false) {
imgUrl = ApiClient.getScaledImageUrl(item.SeriesId, {
type: "Thumb",
maxWidth: thumbWidth,
tag: item.SeriesThumbImageTag,
enableImageEnhancers: enableImageEnhancers
});
} else if (options.preferThumb && item.ParentThumbItemId && options.inheritThumb !== false) {
imgUrl = ApiClient.getThumbImageUrl(item.ParentThumbItemId, {
type: "Thumb",
maxWidth: thumbWidth,
enableImageEnhancers: enableImageEnhancers
});
} else if (options.preferThumb && item.BackdropImageTags && item.BackdropImageTags.length) {
imgUrl = ApiClient.getScaledImageUrl(item.Id, {
type: "Backdrop",
maxWidth: thumbWidth,
tag: item.BackdropImageTags[0],
enableImageEnhancers: enableImageEnhancers
});
forceName = true;
} else if (item.ImageTags && item.ImageTags.Primary) {
width = posterWidth;
height = primaryImageAspectRatio ? Math.round(posterWidth / primaryImageAspectRatio) : null;
imgUrl = ApiClient.getImageUrl(item.Id, {
type: "Primary",
maxHeight: height,
maxWidth: width,
tag: item.ImageTags.Primary,
enableImageEnhancers: enableImageEnhancers
});
if (primaryImageAspectRatio) {
if (uiAspect) {
if (Math.abs(primaryImageAspectRatio - uiAspect) <= .2) {
coverImage = true;
}
}
}
}
else if (item.ParentPrimaryImageTag) {
imgUrl = ApiClient.getImageUrl(item.ParentPrimaryImageItemId, {
type: "Primary",
maxWidth: posterWidth,
tag: item.ParentPrimaryImageTag,
enableImageEnhancers: enableImageEnhancers
});
}
else if (item.AlbumId && item.AlbumPrimaryImageTag) {
height = squareSize;
width = primaryImageAspectRatio ? Math.round(height * primaryImageAspectRatio) : null;
imgUrl = ApiClient.getScaledImageUrl(item.AlbumId, {
type: "Primary",
maxHeight: height,
maxWidth: width,
tag: item.AlbumPrimaryImageTag,
enableImageEnhancers: enableImageEnhancers
});
if (primaryImageAspectRatio) {
if (uiAspect) {
if (Math.abs(primaryImageAspectRatio - uiAspect) <= .2) {
coverImage = true;
}
}
}
}
else if (item.Type == 'Season' && item.ImageTags && item.ImageTags.Thumb) {
imgUrl = ApiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxWidth: thumbWidth,
tag: item.ImageTags.Thumb,
enableImageEnhancers: enableImageEnhancers
});
}
else if (item.BackdropImageTags && item.BackdropImageTags.length) {
imgUrl = ApiClient.getScaledImageUrl(item.Id, {
type: "Backdrop",
maxWidth: thumbWidth,
tag: item.BackdropImageTags[0],
enableImageEnhancers: enableImageEnhancers
});
} else if (item.ImageTags && item.ImageTags.Thumb) {
imgUrl = ApiClient.getScaledImageUrl(item.Id, {
type: "Thumb",
maxWidth: thumbWidth,
tag: item.ImageTags.Thumb,
enableImageEnhancers: enableImageEnhancers
});
} else if (item.SeriesThumbImageTag) {
imgUrl = ApiClient.getScaledImageUrl(item.SeriesId, {
type: "Thumb",
maxWidth: thumbWidth,
tag: item.SeriesThumbImageTag,
enableImageEnhancers: enableImageEnhancers
});
} else if (item.ParentThumbItemId) {
imgUrl = ApiClient.getThumbImageUrl(item, {
type: "Thumb",
maxWidth: thumbWidth,
enableImageEnhancers: enableImageEnhancers
});
} else if (item.MediaType == "Audio" || item.Type == "MusicAlbum" || item.Type == "MusicArtist") {
if (item.Name && showTitle) {
icon = 'library-music';
}
cssClass += " defaultBackground";
} else if (item.Type == "Recording" || item.Type == "Program" || item.Type == "TvChannel") {
if (item.Name && showTitle) {
icon = 'folder-open';
}
cssClass += " defaultBackground";
} else if (item.MediaType == "Video" || item.Type == "Season" || item.Type == "Series") {
if (item.Name && showTitle) {
icon = 'videocam';
}
cssClass += " defaultBackground";
} else if (item.Type == "Person") {
if (item.Name && showTitle) {
icon = 'person';
}
cssClass += " defaultBackground";
} else {
if (item.Name && showTitle) {
icon = 'folder-open';
}
cssClass += " defaultBackground";
}
icon = item.icon || icon;
cssClass += ' ' + options.shape + 'Card';
var mediaSourceCount = item.MediaSourceCount || 1;
var href = options.linkItem === false ? '#' : LibraryBrowser.getHref(item, options.context);
if (options.showChildCountIndicator && item.ChildCount && options.showLatestItemsPopup !== false) {
cssClass += ' groupedCard';
}
if ((showTitle || options.showItemCounts) && !options.overlayText) {
cssClass += ' bottomPaddedCard';
}
var dataAttributes = LibraryBrowser.getItemDataAttributesList(item, options, index);
for (var i = 0, length = dataAttributes.length; i < length; i++) {
var att = dataAttributes[i];
if (att.value) {
item['data-' + att.name] = att.value;
}
}
console.log(item['data-commands']);
var defaultAction = options.defaultAction;
if (defaultAction == 'play' || defaultAction == 'playallfromhere') {
if (item.PlayAccess != 'Full') {
defaultAction = null;
}
}
// card
//html += '<div' + dataAttributes + ' class="' + cssClass + '">';
item.elemClass = cssClass;
item.defaultAction = defaultAction;
var style = "";
if (imgUrl && !options.lazy) {
style += 'background-image:url(\'' + imgUrl + '\');';
}
var imageCssClass = 'cardImage';
if (icon) {
imageCssClass += " iconCardImage";
}
if (coverImage) {
imageCssClass += " coveredCardImage";
if (item.MediaType == 'Photo' || item.Type == 'PhotoAlbum' || item.Type == 'Folder' || item.Type == 'Program' || item.Type == 'Recording') {
imageCssClass += " noScale";
}
}
if (options.centerImage) {
imageCssClass += " centeredCardImage";
}
var dataSrc = "";
if (options.lazy && imgUrl) {
imageCssClass += " lazy";
dataSrc = ' data-src="' + imgUrl + '"';
}
var cardboxCssClass = 'cardBox';
if (options.cardLayout) {
cardboxCssClass += ' visualCardBox';
}
item.cardBoxClass = cardboxCssClass;
var anchorCssClass = "cardContent";
anchorCssClass += ' mediaItem';
if (defaultAction) {
anchorCssClass += ' itemWithAction';
}
item.anchorClass = anchorCssClass;
item.href = href;
item.imgUrl = imgUrl;
item.imageClass = imageCssClass;
if (imgUrl) {
item.imageStyle = 'background-image:url("' + imgUrl + '");';
} else {
item.imageStyle = null;
}
var overlayHtml = '';
if (item.LocationType == "Virtual" || item.LocationType == "Offline") {
if (options.showLocationTypeIndicator !== false) {
overlayHtml += LibraryBrowser.getOfflineIndicatorHtml(item);
}
} else if (options.showUnplayedIndicator !== false) {
overlayHtml += LibraryBrowser.getPlayedIndicatorHtml(item);
} else if (options.showChildCountIndicator) {
overlayHtml += LibraryBrowser.getGroupCountIndicator(item);
}
overlayHtml += LibraryBrowser.getSyncIndicator(item);
if (mediaSourceCount > 1) {
overlayHtml += '<div class="mediaSourceIndicator">' + mediaSourceCount + '</div>';
}
var progressHtml = options.showProgress === false || item.IsFolder ? '' : LibraryBrowser.getItemProgressBarHtml((item.Type == 'Recording' ? item : item.UserData));
var footerOverlayed = false;
if (options.overlayText || (forceName && !showTitle)) {
var footerCssClass = progressHtml ? 'cardFooter fullCardFooter' : 'cardFooter';
overlayHtml += LibraryBrowser.getCardFooterText(item, options, showTitle, imgUrl, forceName, footerCssClass, progressHtml);
footerOverlayed = true;
}
else if (progressHtml) {
overlayHtml += '<div class="cardFooter fullCardFooter lightCardFooter">';
overlayHtml += "<div class='cardProgress cardText'>";
overlayHtml += progressHtml;
overlayHtml += "</div>";
//cardFooter
overlayHtml += "</div>";
progressHtml = '';
}
if (options.overlayPlayButton && !item.IsPlaceHolder && (item.LocationType != 'Virtual' || !item.MediaType || item.Type == 'Program') && item.Type != 'Person') {
overlayHtml += '<div class="cardOverlayButtonContainer"><paper-icon-button icon="play-arrow" class="cardOverlayPlayButton" onclick="return false;"></paper-icon-button></div>';
}
if (options.overlayMoreButton) {
overlayHtml += '<div class="cardOverlayButtonContainer"><paper-icon-button icon="' + AppInfo.moreIcon + '" class="cardOverlayMoreButton" onclick="return false;"></paper-icon-button></div>';
}
//// cardScalable
if (!options.overlayText && !footerOverlayed) {
item.footerHtml = LibraryBrowser.getCardFooterText(item, options, showTitle, imgUrl, forceName, 'cardFooter outerCardFooter', progressHtml);
} else {
item.footerHtml = '';
}
item.overlayHtml = overlayHtml;
},
getPosterViewHtml: function (options) {
LibraryBrowser.setPosterViewData(options);
var items = options.items;
var currentIndexValue;
options.shape = options.shape || "portrait";
var html = "";
var primaryImageAspectRatio;
var thumbWidth = options.thumbWidth;
var posterWidth = options.posterWidth;
var squareSize = options.squareSize;
var bannerWidth = options.bannerWidth;
var dateText; var dateText;
var uiAspect = getDesiredAspect(options.shape); var uiAspect = options.uiAspect;
for (var i = 0, length = items.length; i < length; i++) { for (var i = 0, length = items.length; i < length; i++) {
@ -2765,23 +3246,24 @@
} }
}, },
getDefaultPageSizeSelections: function () { showLayoutMenu: function (button, currentLayout, views) {
return [20, 50, 100, 200, 300, 400, 500]; var dispatchEvent = true;
},
showLayoutMenu: function (button, currentLayout) { if (!views) {
// Add banner and list once all screens support them dispatchEvent = false;
var views = button.getAttribute('data-layouts'); // Add banner and list once all screens support them
views = button.getAttribute('data-layouts');
views = views ? views.split(',') : ['List', 'Poster', 'PosterCard', 'Thumb', 'ThumbCard']; views = views ? views.split(',') : ['List', 'Poster', 'PosterCard', 'Thumb', 'ThumbCard'];
}
var menuItems = views.map(function (v) { var menuItems = views.map(function (v) {
return { return {
name: Globalize.translate('Option' + v), name: Globalize.translate('Option' + v),
id: v, id: v,
ironIcon: currentLayout == v ? 'check' : null selected: currentLayout == v
}; };
}); });
@ -2792,10 +3274,20 @@
positionTo: button, positionTo: button,
callback: function (id) { callback: function (id) {
// TODO: remove jQuery if (dispatchEvent) {
require(['jQuery'], function ($) { button.dispatchEvent(new CustomEvent('layoutchange', {
$(button).trigger('layoutchange', [id]); detail: {
}); viewStyle: id
},
bubbles: true,
cancelable: false
}));
} else {
// TODO: remove jQuery
require(['jQuery'], function ($) {
$(button).trigger('layoutchange', [id]);
});
}
} }
}); });
@ -2866,7 +3358,7 @@
var id = "selectPageSize"; var id = "selectPageSize";
var pageSizes = options.pageSizes || LibraryBrowser.getDefaultPageSizeSelections(); var pageSizes = options.pageSizes || [20, 50, 100, 200, 300, 400, 500];
var optionsHtml = pageSizes.map(function (val) { var optionsHtml = pageSizes.map(function (val) {

View file

@ -294,5 +294,14 @@
Events.off(MediaController, 'playbackstop', onPlaybackStop); Events.off(MediaController, 'playbackstop', onPlaybackStop);
}); });
view.addEventListener('viewdestroy', function (e) {
tabControllers.forEach(function (t) {
if (t.destroy) {
t.destroy();
}
});
});
}; };
}); });

View file

@ -1,8 +1,9 @@
define(['jQuery'], function ($) { define(['ironCardList', 'scrollThreshold', 'events', 'libraryBrowser', 'jQuery'], function (ironCardList, scrollThreshold, events, libraryBrowser, $) {
return function (view, params, tabContent) { return function (view, params, tabContent) {
var self = this; var self = this;
var pageSize = libraryBrowser.getDefaultPageSize();
var data = {}; var data = {};
@ -21,13 +22,13 @@
ImageTypeLimit: 1, ImageTypeLimit: 1,
EnableImageTypes: "Primary,Backdrop,Banner,Thumb", EnableImageTypes: "Primary,Backdrop,Banner,Thumb",
StartIndex: 0, StartIndex: 0,
Limit: LibraryBrowser.getDefaultPageSize() Limit: pageSize
}, },
view: LibraryBrowser.getSavedView(key) || LibraryBrowser.getDefaultItemsView('Poster', 'Thumb') view: libraryBrowser.getSavedView(key) || libraryBrowser.getDefaultItemsView('Poster', 'Thumb')
}; };
pageData.query.ParentId = params.topParentId; pageData.query.ParentId = params.topParentId;
LibraryBrowser.loadSavedQueryValues(key, pageData.query); libraryBrowser.loadSavedQueryValues(key, pageData.query);
} }
return pageData; return pageData;
} }
@ -40,192 +41,143 @@
function getSavedQueryKey(context) { function getSavedQueryKey(context) {
if (!context.savedQueryKey) { if (!context.savedQueryKey) {
context.savedQueryKey = LibraryBrowser.getSavedQueryKey('series'); context.savedQueryKey = libraryBrowser.getSavedQueryKey('series');
} }
return context.savedQueryKey; return context.savedQueryKey;
} }
function setCardOptions(result) {
var cardOptions;
var view = self.getCurrentViewStyle();
if (view == "Thumb") {
cardOptions = {
items: result.Items,
shape: "backdrop",
preferThumb: true,
context: 'tv',
lazy: true,
overlayPlayButton: true
};
}
else if (view == "ThumbCard") {
cardOptions = {
items: result.Items,
shape: "backdrop",
preferThumb: true,
context: 'tv',
lazy: true,
cardLayout: true,
showTitle: true,
showSeriesYear: true
};
}
else if (view == "Banner") {
cardOptions = {
items: result.Items,
shape: "banner",
preferBanner: true,
context: 'tv',
lazy: true
};
}
else if (view == "List") {
html = libraryBrowser.getListViewHtml({
items: result.Items,
context: 'tv',
sortBy: query.SortBy
});
}
else if (view == "PosterCard") {
cardOptions = {
items: result.Items,
shape: "portrait",
context: 'tv',
showTitle: true,
showYear: true,
lazy: true,
cardLayout: true
};
}
else {
// Poster
cardOptions = {
items: result.Items,
shape: "portrait",
context: 'tv',
centerText: true,
lazy: true,
overlayPlayButton: true
};
}
self.cardOptions = cardOptions;
}
function reloadItems(page) { function reloadItems(page) {
self.isLoading = true;
Dashboard.showLoadingMsg(); Dashboard.showLoadingMsg();
var query = getQuery(page); var query = getQuery(page);
var startIndex = query.StartIndex;
var reloadList = !self.cardOptions || startIndex == 0;
ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) { ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) {
// Scroll back up so they can see the results from the beginning
window.scrollTo(0, 0);
var view = getPageData(page).view;
var html = '';
var pagingHtml = LibraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
showLimit: false,
updatePageSizeSetting: false,
addLayoutButton: true,
sortButton: true,
currentLayout: view,
layouts: 'Banner,List,Poster,PosterCard,Thumb,ThumbCard',
filterButton: true
});
page.querySelector('.listTopPaging').innerHTML = pagingHtml;
updateFilterControls(page); updateFilterControls(page);
if (view == "Thumb") { var pushItems = true;
if (reloadList) {
html = LibraryBrowser.getPosterViewHtml({ setCardOptions(result);
items: result.Items, pushItems = false;
shape: "backdrop",
preferThumb: true,
context: 'tv',
lazy: true,
overlayPlayButton: true
});
} }
else if (view == "ThumbCard") { libraryBrowser.setPosterViewData(self.cardOptions);
libraryBrowser.setPosterViewDataOnItems(self.cardOptions, result.Items);
html = LibraryBrowser.getPosterViewHtml({ var ironList = page.querySelector('#ironList');
items: result.Items, if (pushItems) {
shape: "backdrop", for (var i = 0, length = result.Items.length; i < length; i++) {
preferThumb: true, ironList.push('items', result.Items[i]);
context: 'tv', }
lazy: true, } else {
cardLayout: true, ironList.items = result.Items;
showTitle: true,
showSeriesYear: true
});
}
else if (view == "Banner") {
html = LibraryBrowser.getPosterViewHtml({
items: result.Items,
shape: "banner",
preferBanner: true,
context: 'tv',
lazy: true
});
}
else if (view == "List") {
html = LibraryBrowser.getListViewHtml({
items: result.Items,
context: 'tv',
sortBy: query.SortBy
});
}
else if (view == "PosterCard") {
html = LibraryBrowser.getPosterViewHtml({
items: result.Items,
shape: "portrait",
context: 'tv',
showTitle: true,
showYear: true,
lazy: true,
cardLayout: true
});
}
else {
// Poster
html = LibraryBrowser.getPosterViewHtml({
items: result.Items,
shape: "portrait",
context: 'tv',
centerText: true,
lazy: true,
overlayPlayButton: true
});
} }
var elem = page.querySelector('#items'); // Hack: notifyResize needs to be done after the items have been rendered
elem.innerHTML = html + pagingHtml; setTimeout(function () {
ImageLoader.lazyChildren(elem);
$('.btnNextPage', page).on('click', function () { ironList.notifyResize();
query.StartIndex += query.Limit; self.scrollThreshold.resetSize();
reloadItems(page); }, 300);
});
$('.btnPreviousPage', page).on('click', function () { libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
query.StartIndex -= query.Limit;
reloadItems(page);
});
$('.btnChangeLayout', page).on('layoutchange', function (e, layout) {
getPageData(page).view = layout;
LibraryBrowser.saveViewSetting(getSavedQueryKey(page), layout);
reloadItems(page);
});
$('.btnFilter', page).on('click', function () {
showFilterMenu(page);
});
// On callback make sure to set StartIndex = 0
$('.btnSort', page).on('click', function () {
LibraryBrowser.showSortMenu({
items: [{
name: Globalize.translate('OptionNameSort'),
id: 'SortName'
},
{
name: Globalize.translate('OptionImdbRating'),
id: 'CommunityRating,SortName'
},
{
name: Globalize.translate('OptionDateAdded'),
id: 'DateCreated,SortName'
},
{
name: Globalize.translate('OptionDatePlayed'),
id: 'DatePlayed,SortName'
},
{
name: Globalize.translate('OptionMetascore'),
id: 'Metascore,SortName'
},
{
name: Globalize.translate('OptionParentalRating'),
id: 'OfficialRating,SortName'
},
{
name: Globalize.translate('OptionPlayCount'),
id: 'PlayCount,SortName'
},
{
name: Globalize.translate('OptionReleaseDate'),
id: 'PremiereDate,SortName'
}],
callback: function () {
reloadItems(page);
},
query: query
});
});
LibraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
Dashboard.hideLoadingMsg(); Dashboard.hideLoadingMsg();
self.hasMoreItems = result.TotalRecordCount > (startIndex + result.Items.length);
self.isLoading = false;
}); });
} }
function showFilterMenu(page) { self.showFilterMenu = function () {
require(['components/filterdialog/filterdialog'], function (filterDialogFactory) { require(['components/filterdialog/filterdialog'], function (filterDialogFactory) {
var filterDialog = new filterDialogFactory({ var filterDialog = new filterDialogFactory({
query: getQuery(page), query: getQuery(tabContent),
mode: 'series' mode: 'series'
}); });
Events.on(filterDialog, 'filterchange', function () { Events.on(filterDialog, 'filterchange', function () {
reloadItems(page); getQuery(tabContent).StartIndex = 0;
reloadItems(tabContent);
}); });
filterDialog.show(); filterDialog.show();
@ -252,16 +204,117 @@
var query = getQuery(tabContent); var query = getQuery(tabContent);
query.NameStartsWithOrGreater = ''; query.NameStartsWithOrGreater = '';
getQuery(tabContent).StartIndex = 0;
reloadItems(tabContent); reloadItems(tabContent);
}); });
tabContent.querySelector('.btnFilter').addEventListener('click', function () {
self.showFilterMenu();
});
tabContent.querySelector('.btnSort').addEventListener('click', function () {
libraryBrowser.showSortMenu({
items: [{
name: Globalize.translate('OptionNameSort'),
id: 'SortName'
},
{
name: Globalize.translate('OptionImdbRating'),
id: 'CommunityRating,SortName'
},
{
name: Globalize.translate('OptionDateAdded'),
id: 'DateCreated,SortName'
},
{
name: Globalize.translate('OptionDatePlayed'),
id: 'DatePlayed,SortName'
},
{
name: Globalize.translate('OptionMetascore'),
id: 'Metascore,SortName'
},
{
name: Globalize.translate('OptionParentalRating'),
id: 'OfficialRating,SortName'
},
{
name: Globalize.translate('OptionPlayCount'),
id: 'PlayCount,SortName'
},
{
name: Globalize.translate('OptionReleaseDate'),
id: 'PremiereDate,SortName'
}],
callback: function () {
getQuery(tabContent).StartIndex = 0;
reloadItems(tabContent);
},
query: getQuery(tabContent)
});
});
tabContent.querySelector('.btnSelectView').addEventListener('click', function (e) {
libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), 'Banner,List,Poster,PosterCard,Thumb,ThumbCard'.split(','));
});
tabContent.querySelector('.btnSelectView').addEventListener('layoutchange', function (e) {
var viewStyle = e.detail.viewStyle;
getPageData(tabContent).view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle);
getQuery(tabContent).StartIndex = 0;
reloadItems(tabContent);
});
} }
initPage(tabContent); self.getCurrentViewStyle = function () {
self.renderTab = function () { return getPageData(tabContent).view;
};
reloadItems(tabContent); initPage(tabContent);
updateFilterControls(tabContent);
function createList() {
if (self.listCreated) {
return Promise.resolve();
}
return ironCardList.getTemplate('seriesTab').then(function (html) {
tabContent.querySelector('.itemsContainer').innerHTML = html;
self.listCreated = true;
});
}
function loadMoreItems() {
if (!self.isLoading && self.hasMoreItems) {
getQuery(tabContent).StartIndex += pageSize;
reloadItems(tabContent);
}
}
self.scrollThreshold = new scrollThreshold(tabContent, false);
events.on(self.scrollThreshold, 'lower-threshold', loadMoreItems);
self.renderTab = function () {
createList().then(function () {
reloadItems(tabContent);
updateFilterControls(tabContent);
});
};
self.destroy = function () {
events.off(self.scrollThreshold, 'lower-threshold', loadMoreItems);
if (self.scrollThreshold) {
self.scrollThreshold.destroy();
}
}; };
}; };
}); });

View file

@ -22,6 +22,7 @@
</div> </div>
<div class="ehsContent fullWidth pageTabsContainer"> <div class="ehsContent fullWidth pageTabsContainer">
<div class="pageTabContent hide" data-index="0"> <div class="pageTabContent hide" data-index="0">
<div id="resumableSection" class="homePageSection"> <div id="resumableSection" class="homePageSection">
<div> <div>
@ -63,26 +64,32 @@
</p> </p>
</div> </div>
</div> </div>
<div class="pageTabContent hide" data-index="3"> <div id="seriesTab" class="pageTabContent absolutePageTabContent hide smoothScrollY" data-index="3">
<div style="text-align: center;padding:.7em 0;">
<paper-icon-button class="btnSelectView" icon="view-comfy" title="${ButtonSelectView}"></paper-icon-button>
<paper-icon-button class="btnSort" title="${ButtonSort}" icon="sort-by-alpha"></paper-icon-button>
<paper-icon-button class="btnFilter" title="${ButtonFilter}" icon="filter-list"></paper-icon-button>
</div>
<div class="alphabetPicker"> <div class="alphabetPicker">
</div> </div>
<div class="viewSettings">
<div class="listTopPaging"> <div class="itemsContainer" style="margin-left:-10px;">
</div>
</div> </div>
<div id="items" class="itemsContainer paddedItemsContainer" style="text-align: center;"></div>
</div> </div>
<div class="pageTabContent hide" data-index="4"> <div id="episodesTab" class="pageTabContent absolutePageTabContent hide smoothScrollY" data-index="4">
<div class="viewSettings"> <div style="text-align: center;padding:.7em 0;">
<div class="listTopPaging"> <paper-icon-button class="btnSelectView" icon="view-comfy" title="${ButtonSelectView}"></paper-icon-button>
</div> <paper-icon-button class="btnSort" title="${ButtonSort}" icon="sort-by-alpha"></paper-icon-button>
<paper-icon-button class="btnFilter" title="${ButtonFilter}" icon="filter-list"></paper-icon-button>
</div>
<div class="itemsContainer">
</div> </div>
<div id="items" class="itemsContainer paddedItemsContainer"></div>
</div> </div>
<div class="pageTabContent hide" data-index="5"> <div class="pageTabContent hide" data-index="5">
<div class="viewSettings"> <div style="text-align: center;">
<div class="listTopPaging"> <paper-icon-button class="btnSelectView" icon="view-comfy" title="${ButtonSelectView}"></paper-icon-button>
</div>
</div> </div>
<div id="items" class="itemsContainer paddedItemsContainer"></div> <div id="items" class="itemsContainer paddedItemsContainer"></div>
</div> </div>