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

Merge pull request #315 from dkanada/scroller

Move buttons to top right for custom scroll element
This commit is contained in:
Anthony Lavado 2019-07-04 12:44:28 -04:00 committed by GitHub
commit accaac3405
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 206 additions and 503 deletions

View file

@ -36,6 +36,16 @@ button {
margin-right: -0.6em; margin-right: -0.6em;
} }
/* TODO replace this with a proper fix */
/* doesnt work on mobile devices */
/* negative margin fixes annoying misalignment with cards and title */
@media all and (max-width:50em) {
.itemsContainer {
margin-left: 0;
margin-right: 0;
}
}
.vertical-list { .vertical-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View file

@ -1,13 +1,11 @@
define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager', 'imageLoader', 'layoutManager', 'browser', 'dom', 'loading', 'focusManager', 'serverNotifications', 'events', 'registerElement'], function (itemShortcuts, inputManager, connectionManager, playbackManager, imageLoader, layoutManager, browser, dom, loading, focusManager, serverNotifications, events) { define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager', 'imageLoader', 'layoutManager', 'browser', 'dom', 'loading', 'focusManager', 'serverNotifications', 'events', 'registerElement'], function (itemShortcuts, inputManager, connectionManager, playbackManager, imageLoader, layoutManager, browser, dom, loading, focusManager, serverNotifications, events) {
'use strict'; 'use strict';
var ItemsContainerProtoType = Object.create(HTMLDivElement.prototype); var ItemsContainerPrototype = Object.create(HTMLDivElement.prototype);
function onClick(e) { function onClick(e) {
var itemsContainer = this; var itemsContainer = this;
var target = e.target; var target = e.target;
var multiSelect = itemsContainer.multiSelect; var multiSelect = itemsContainer.multiSelect;
if (multiSelect) { if (multiSelect) {
@ -20,22 +18,18 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
} }
function disableEvent(e) { function disableEvent(e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
return false; return false;
} }
function onContextMenu(e) { function onContextMenu(e) {
var itemsContainer = this; var itemsContainer = this;
var target = e.target; var target = e.target;
var card = dom.parentWithAttribute(target, 'data-id'); var card = dom.parentWithAttribute(target, 'data-id');
// check for serverId, it won't be present on selectserver // check for serverId, it won't be present on selectserver
if (card && card.getAttribute('data-serverid')) { if (card && card.getAttribute('data-serverid')) {
inputManager.trigger('menu', { inputManager.trigger('menu', {
sourceElement: card sourceElement: card
}); });
@ -52,8 +46,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
}; };
} }
ItemsContainerProtoType.enableMultiSelect = function (enabled) { ItemsContainerPrototype.enableMultiSelect = function (enabled) {
var current = this.multiSelect; var current = this.multiSelect;
if (!enabled) { if (!enabled) {
@ -78,7 +71,6 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
}; };
function onDrop(evt, itemsContainer) { function onDrop(evt, itemsContainer) {
var el = evt.item; var el = evt.item;
var newIndex = evt.newIndex; var newIndex = evt.newIndex;
@ -86,9 +78,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
var playlistId = el.getAttribute('data-playlistid'); var playlistId = el.getAttribute('data-playlistid');
if (!playlistId) { if (!playlistId) {
var oldIndex = evt.oldIndex; var oldIndex = evt.oldIndex;
el.dispatchEvent(new CustomEvent('itemdrop', { el.dispatchEvent(new CustomEvent('itemdrop', {
detail: { detail: {
oldIndex: oldIndex, oldIndex: oldIndex,
@ -107,27 +97,18 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
loading.show(); loading.show();
apiClient.ajax({ apiClient.ajax({
url: apiClient.getUrl('Playlists/' + playlistId + '/Items/' + itemId + '/Move/' + newIndex), url: apiClient.getUrl('Playlists/' + playlistId + '/Items/' + itemId + '/Move/' + newIndex),
type: 'POST' type: 'POST'
}).then(function () { }).then(function () {
loading.hide(); loading.hide();
}, function () { }, function () {
loading.hide(); loading.hide();
itemsContainer.refreshItems(); itemsContainer.refreshItems();
}); });
} }
ItemsContainerProtoType.enableDragReordering = function (enabled) { ItemsContainerPrototype.enableDragReordering = function (enabled) {
var current = this.sortable; var current = this.sortable;
if (!enabled) { if (!enabled) {
if (current) { if (current) {
current.destroy(); current.destroy();
@ -142,15 +123,12 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
var self = this; var self = this;
require(['sortable'], function (Sortable) { require(['sortable'], function (Sortable) {
self.sortable = new Sortable(self, { self.sortable = new Sortable(self, {
draggable: ".listItem", draggable: ".listItem",
handle: '.listViewDragHandle', handle: '.listViewDragHandle',
// dragging ended // dragging ended
onEnd: function (/**Event*/evt) { onEnd: function (evt) {
return onDrop(evt, self); return onDrop(evt, self);
} }
}); });
@ -169,17 +147,13 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
// TODO: Check user data change reason? // TODO: Check user data change reason?
if (eventsToMonitor.indexOf('markfavorite') !== -1) { if (eventsToMonitor.indexOf('markfavorite') !== -1) {
itemsContainer.notifyRefreshNeeded(); itemsContainer.notifyRefreshNeeded();
} } else if (eventsToMonitor.indexOf('markplayed') !== -1) {
else if (eventsToMonitor.indexOf('markplayed') !== -1) {
itemsContainer.notifyRefreshNeeded(); itemsContainer.notifyRefreshNeeded();
} }
} }
function getEventsToMonitor(itemsContainer) { function getEventsToMonitor(itemsContainer) {
var monitor = itemsContainer.getAttribute('data-monitor'); var monitor = itemsContainer.getAttribute('data-monitor');
if (monitor) { if (monitor) {
return monitor.split(','); return monitor.split(',');
@ -193,7 +167,6 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
var itemsContainer = this; var itemsContainer = this;
if (getEventsToMonitor(itemsContainer).indexOf('timers') !== -1) { if (getEventsToMonitor(itemsContainer).indexOf('timers') !== -1) {
itemsContainer.notifyRefreshNeeded(); itemsContainer.notifyRefreshNeeded();
return; return;
} }
@ -208,10 +181,8 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
} }
function onSeriesTimerCreated(e, apiClient, data) { function onSeriesTimerCreated(e, apiClient, data) {
var itemsContainer = this; var itemsContainer = this;
if (getEventsToMonitor(itemsContainer).indexOf('seriestimers') !== -1) { if (getEventsToMonitor(itemsContainer).indexOf('seriestimers') !== -1) {
itemsContainer.notifyRefreshNeeded(); itemsContainer.notifyRefreshNeeded();
return; return;
} }
@ -219,42 +190,33 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
function onTimerCancelled(e, apiClient, data) { function onTimerCancelled(e, apiClient, data) {
var itemsContainer = this; var itemsContainer = this;
if (getEventsToMonitor(itemsContainer).indexOf('timers') !== -1) { if (getEventsToMonitor(itemsContainer).indexOf('timers') !== -1) {
itemsContainer.notifyRefreshNeeded(); itemsContainer.notifyRefreshNeeded();
return; return;
} }
var id = data.Id;
require(['cardBuilder'], function (cardBuilder) { require(['cardBuilder'], function (cardBuilder) {
cardBuilder.onTimerCancelled(id, itemsContainer); cardBuilder.onTimerCancelled(data.Id, itemsContainer);
}); });
} }
function onSeriesTimerCancelled(e, apiClient, data) { function onSeriesTimerCancelled(e, apiClient, data) {
var itemsContainer = this; var itemsContainer = this;
if (getEventsToMonitor(itemsContainer).indexOf('seriestimers') !== -1) { if (getEventsToMonitor(itemsContainer).indexOf('seriestimers') !== -1) {
itemsContainer.notifyRefreshNeeded(); itemsContainer.notifyRefreshNeeded();
return; return;
} }
var id = data.Id;
require(['cardBuilder'], function (cardBuilder) { require(['cardBuilder'], function (cardBuilder) {
cardBuilder.onSeriesTimerCancelled(id, itemsContainer); cardBuilder.onSeriesTimerCancelled(data.Id, itemsContainer);
}); });
} }
function onLibraryChanged(e, apiClient, data) { function onLibraryChanged(e, apiClient, data) {
var itemsContainer = this; var itemsContainer = this;
var eventsToMonitor = getEventsToMonitor(itemsContainer); var eventsToMonitor = getEventsToMonitor(itemsContainer);
if (eventsToMonitor.indexOf('seriestimers') !== -1 || eventsToMonitor.indexOf('timers') !== -1) { if (eventsToMonitor.indexOf('seriestimers') !== -1 || eventsToMonitor.indexOf('timers') !== -1) {
// yes this is an assumption // yes this is an assumption
return; return;
} }
@ -280,25 +242,17 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
} }
function onPlaybackStopped(e, stopInfo) { function onPlaybackStopped(e, stopInfo) {
var itemsContainer = this; var itemsContainer = this;
var state = stopInfo.state; var state = stopInfo.state;
var eventsToMonitor = getEventsToMonitor(itemsContainer); var eventsToMonitor = getEventsToMonitor(itemsContainer);
if (state.NowPlayingItem && state.NowPlayingItem.MediaType === 'Video') { if (state.NowPlayingItem && state.NowPlayingItem.MediaType === 'Video') {
if (eventsToMonitor.indexOf('videoplayback') !== -1) { if (eventsToMonitor.indexOf('videoplayback') !== -1) {
itemsContainer.notifyRefreshNeeded(true); itemsContainer.notifyRefreshNeeded(true);
return; return;
} }
} } else if (state.NowPlayingItem && state.NowPlayingItem.MediaType === 'Audio') {
else if (state.NowPlayingItem && state.NowPlayingItem.MediaType === 'Audio') {
if (eventsToMonitor.indexOf('audioplayback') !== -1) { if (eventsToMonitor.indexOf('audioplayback') !== -1) {
itemsContainer.notifyRefreshNeeded(true); itemsContainer.notifyRefreshNeeded(true);
return; return;
} }
@ -306,7 +260,6 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
} }
function addNotificationEvent(instance, name, handler, owner) { function addNotificationEvent(instance, name, handler, owner) {
var localHandler = handler.bind(instance); var localHandler = handler.bind(instance);
owner = owner || serverNotifications; owner = owner || serverNotifications;
events.on(owner, name, localHandler); events.on(owner, name, localHandler);
@ -314,7 +267,6 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
} }
function removeNotificationEvent(instance, name, owner) { function removeNotificationEvent(instance, name, owner) {
var handler = instance['event_' + name]; var handler = instance['event_' + name];
if (handler) { if (handler) {
owner = owner || serverNotifications; owner = owner || serverNotifications;
@ -323,13 +275,11 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
} }
} }
ItemsContainerProtoType.createdCallback = function () { ItemsContainerPrototype.createdCallback = function () {
this.classList.add('itemsContainer'); this.classList.add('itemsContainer');
}; };
ItemsContainerProtoType.attachedCallback = function () { ItemsContainerPrototype.attachedCallback = function () {
this.addEventListener('click', onClick); this.addEventListener('click', onClick);
if (browser.touch) { if (browser.touch) {
@ -365,8 +315,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
} }
}; };
ItemsContainerProtoType.detachedCallback = function () { ItemsContainerPrototype.detachedCallback = function () {
clearRefreshInterval(this); clearRefreshInterval(this);
this.enableMultiSelect(false); this.enableMultiSelect(false);
@ -374,6 +323,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
this.removeEventListener('click', onClick); this.removeEventListener('click', onClick);
this.removeEventListener('contextmenu', onContextMenu); this.removeEventListener('contextmenu', onContextMenu);
this.removeEventListener('contextmenu', disableEvent); this.removeEventListener('contextmenu', disableEvent);
itemShortcuts.off(this, getShortcutOptions()); itemShortcuts.off(this, getShortcutOptions());
removeNotificationEvent(this, 'UserDataChanged'); removeNotificationEvent(this, 'UserDataChanged');
@ -389,15 +339,12 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
this.parentContainer = null; this.parentContainer = null;
}; };
ItemsContainerProtoType.pause = function () { ItemsContainerPrototype.pause = function () {
clearRefreshInterval(this, true); clearRefreshInterval(this, true);
this.paused = true; this.paused = true;
}; };
ItemsContainerProtoType.resume = function (options) { ItemsContainerPrototype.resume = function (options) {
this.paused = false; this.paused = false;
var refreshIntervalEndTime = this.refreshIntervalEndTime; var refreshIntervalEndTime = this.refreshIntervalEndTime;
@ -405,9 +352,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
var remainingMs = refreshIntervalEndTime - new Date().getTime(); var remainingMs = refreshIntervalEndTime - new Date().getTime();
if (remainingMs > 0 && !this.needsRefresh) { if (remainingMs > 0 && !this.needsRefresh) {
resetRefreshInterval(this, remainingMs); resetRefreshInterval(this, remainingMs);
} else { } else {
this.needsRefresh = true; this.needsRefresh = true;
this.refreshIntervalEndTime = null; this.refreshIntervalEndTime = null;
@ -421,8 +366,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
return Promise.resolve(); return Promise.resolve();
}; };
ItemsContainerProtoType.refreshItems = function () { ItemsContainerPrototype.refreshItems = function () {
if (!this.fetchData) { if (!this.fetchData) {
return Promise.resolve(); return Promise.resolve();
} }
@ -437,8 +381,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
return this.fetchData().then(onDataFetched.bind(this)); return this.fetchData().then(onDataFetched.bind(this));
}; };
ItemsContainerProtoType.notifyRefreshNeeded = function (isInForeground) { ItemsContainerPrototype.notifyRefreshNeeded = function (isInForeground) {
if (this.paused) { if (this.paused) {
this.needsRefresh = true; this.needsRefresh = true;
return; return;
@ -457,9 +400,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
}; };
function clearRefreshInterval(itemsContainer, isPausing) { function clearRefreshInterval(itemsContainer, isPausing) {
if (itemsContainer.refreshInterval) { if (itemsContainer.refreshInterval) {
clearInterval(itemsContainer.refreshInterval); clearInterval(itemsContainer.refreshInterval);
itemsContainer.refreshInterval = null; itemsContainer.refreshInterval = null;
@ -470,7 +411,6 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
} }
function resetRefreshInterval(itemsContainer, intervalMs) { function resetRefreshInterval(itemsContainer, intervalMs) {
clearRefreshInterval(itemsContainer); clearRefreshInterval(itemsContainer);
if (!intervalMs) { if (!intervalMs) {
@ -484,7 +424,6 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
} }
function onDataFetched(result) { function onDataFetched(result) {
var items = result.Items || result; var items = result.Items || result;
var parentContainer = this.parentContainer; var parentContainer = this.parentContainer;
@ -496,10 +435,6 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
} }
} }
// Scroll back up so they can see the results from the beginning
// TODO: Find scroller
//window.scrollTo(0, 0);
var activeElement = document.activeElement; var activeElement = document.activeElement;
var focusId; var focusId;
var hasActiveElement; var hasActiveElement;
@ -528,12 +463,11 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
if (focusId) { if (focusId) {
var newElement = itemsContainer.querySelector('[data-id="' + focusId + '"]'); var newElement = itemsContainer.querySelector('[data-id="' + focusId + '"]');
if (newElement) { if (newElement) {
try { try {
focusManager.focus(newElement); focusManager.focus(newElement);
return; return;
} } catch (err) {
catch (err) { console.log(err);
} }
} }
} }
@ -542,7 +476,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager',
} }
document.registerElement('emby-itemscontainer', { document.registerElement('emby-itemscontainer', {
prototype: ItemsContainerProtoType, prototype: ItemsContainerPrototype,
extends: 'div' extends: 'div'
}); });
}); });

View file

@ -1,60 +1,11 @@
.emby-scrollbuttons-scroller { .emby-scrollbuttons {
position: relative;
}
.scrollbuttoncontainer {
position: absolute; position: absolute;
top: 10%; top: 0;
bottom: 35%; right: 0;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 1; z-index: 1;
font-size: 3em; color: #ffffff;
color: #fff; display: flex;
display: none;
overflow: hidden; overflow: hidden;
} }
.scrollbuttoncontainer-left {
background: rgba(20, 20, 20, .5);
background: -moz-linear-gradient(left,#000 0,rgba(0,0,0,0) 100%);
background: -webkit-linear-gradient(left,#000 0,rgba(0,0,0,0) 100%);
background: linear-gradient(to right,#000,rgba(0,0,0,0));
}
.scrollbuttoncontainer-right {
background: rgba(20, 20, 20, .5);
background: -moz-linear-gradient(right,#000 0,rgba(0,0,0,0) 100%);
background: -webkit-linear-gradient(right,#000 0,rgba(0,0,0,0) 100%);
background: linear-gradient(to left,#000,rgba(0,0,0,0));
}
.emby-scrollbuttons-scroller:hover .scrollbuttoncontainer {
display: flex;
}
.scrollbuttoncontainer-left {
left: 0;
}
.scrollbuttoncontainer-right {
right: 0;
}
.emby-scrollbuttons-scrollbutton {
margin: 0 -.2em;
transition: transform 160ms ease-out;
}
.scrollbuttoncontainer:hover > .emby-scrollbuttons-scrollbutton {
transform: scale(1.3, 1.3);
}
.emby-scrollbuttons-scrollbutton:after {
content: '';
display: none !important;
}
.emby-scrollbuttons-scrollbutton:focus {
color: inherit !important;
}

View file

@ -3,30 +3,20 @@ define(['layoutManager', 'dom', 'css!./emby-scrollbuttons', 'registerElement', '
var EmbyScrollButtonsPrototype = Object.create(HTMLDivElement.prototype); var EmbyScrollButtonsPrototype = Object.create(HTMLDivElement.prototype);
EmbyScrollButtonsPrototype.createdCallback = function () { EmbyScrollButtonsPrototype.createdCallback = function () {};
};
function getScrollButtonContainerHtml(direction) {
function getScrollButtonHtml(direction) {
var html = ''; var html = '';
var hide = direction === 'left' ? ' hide' : '';
html += '<div class="scrollbuttoncontainer scrollbuttoncontainer-' + direction + hide + '">';
var icon = direction === 'left' ? '&#xE5CB;' : '&#xE5CC;'; var icon = direction === 'left' ? '&#xE5CB;' : '&#xE5CC;';
html += '<button type="button" is="paper-icon-button-light" data-ripple="false" data-direction="' + direction + '" class="emby-scrollbuttons-scrollbutton">'; html += '<button type="button" is="paper-icon-button-light" data-ripple="false" data-direction="' + direction + '" class="emby-scrollbuttons-button">';
html += '<i class="md-icon">' + icon + '</i>'; html += '<i class="md-icon">' + icon + '</i>';
html += '</button>'; html += '</button>';
html += '</div>';
return html; return html;
} }
function getScrollPosition(parent) { function getScrollPosition(parent) {
if (parent.getScrollPosition) { if (parent.getScrollPosition) {
return parent.getScrollPosition(); return parent.getScrollPosition();
} }
@ -35,7 +25,6 @@ define(['layoutManager', 'dom', 'css!./emby-scrollbuttons', 'registerElement', '
} }
function getScrollWidth(parent) { function getScrollWidth(parent) {
if (parent.getScrollSize) { if (parent.getScrollSize) {
return parent.getScrollSize(); return parent.getScrollSize();
} }
@ -43,46 +32,45 @@ define(['layoutManager', 'dom', 'css!./emby-scrollbuttons', 'registerElement', '
return 0; return 0;
} }
function onScrolledToPosition(scrollButtons, pos, scrollWidth) { function updateScrollButtons(scrollButtons, scrollSize, scrollPos, scrollWidth) {
// hack alert add twenty for rounding errors
if (pos > 0) { if (scrollWidth <= scrollSize + 20) {
scrollButtons.scrollButtonsLeft.classList.remove('hide');
} else {
scrollButtons.scrollButtonsLeft.classList.add('hide'); scrollButtons.scrollButtonsLeft.classList.add('hide');
}
if (scrollWidth > 0) {
pos += scrollButtons.offsetWidth;
if (pos >= scrollWidth) {
scrollButtons.scrollButtonsRight.classList.add('hide'); scrollButtons.scrollButtonsRight.classList.add('hide');
} else {
scrollButtons.scrollButtonsRight.classList.remove('hide');
} }
if (scrollPos > 0) {
scrollButtons.scrollButtonsLeft.disabled = false;
} else {
scrollButtons.scrollButtonsLeft.disabled = true;
}
var scrollPosEnd = scrollPos + scrollSize;
if (scrollWidth > 0 && scrollPosEnd >= scrollWidth) {
scrollButtons.scrollButtonsRight.disabled = true;
} else {
scrollButtons.scrollButtonsRight.disabled = false;
} }
} }
function onScroll(e) { function onScroll(e) {
var scrollButtons = this; var scrollButtons = this;
var scroller = this.scroller; var scroller = this.scroller;
var pos = getScrollPosition(scroller);
var scrollSize = getScrollSize(scroller);
var scrollPos = getScrollPosition(scroller);
var scrollWidth = getScrollWidth(scroller); var scrollWidth = getScrollWidth(scroller);
onScrolledToPosition(scrollButtons, pos, scrollWidth); updateScrollButtons(scrollButtons, scrollSize, scrollPos, scrollWidth);
} }
function getStyleValue(style, name) { function getStyleValue(style, name) {
var value = style.getPropertyValue(name); var value = style.getPropertyValue(name);
if (!value) { if (!value) {
return 0; return 0;
} }
value = value.replace('px', ''); value = value.replace('px', '');
if (!value) { if (!value) {
return 0; return 0;
} }
@ -96,18 +84,15 @@ define(['layoutManager', 'dom', 'css!./emby-scrollbuttons', 'registerElement', '
} }
function getScrollSize(elem) { function getScrollSize(elem) {
var scrollSize = elem.offsetWidth; var scrollSize = elem.offsetWidth;
var style = window.getComputedStyle(elem, null); var style = window.getComputedStyle(elem, null);
var paddingLeft = getStyleValue(style, 'padding-left'); var paddingLeft = getStyleValue(style, 'padding-left');
if (paddingLeft) { if (paddingLeft) {
scrollSize -= paddingLeft; scrollSize -= paddingLeft;
} }
var paddingRight = getStyleValue(style, 'padding-right');
var paddingRight = getStyleValue(style, 'padding-right');
if (paddingRight) { if (paddingRight) {
scrollSize -= paddingRight; scrollSize -= paddingRight;
} }
@ -116,12 +101,11 @@ define(['layoutManager', 'dom', 'css!./emby-scrollbuttons', 'registerElement', '
style = window.getComputedStyle(slider, null); style = window.getComputedStyle(slider, null);
paddingLeft = getStyleValue(style, 'padding-left'); paddingLeft = getStyleValue(style, 'padding-left');
if (paddingLeft) { if (paddingLeft) {
scrollSize -= paddingLeft; scrollSize -= paddingLeft;
} }
paddingRight = getStyleValue(style, 'padding-right');
paddingRight = getStyleValue(style, 'padding-right');
if (paddingRight) { if (paddingRight) {
scrollSize -= paddingRight; scrollSize -= paddingRight;
} }
@ -130,58 +114,52 @@ define(['layoutManager', 'dom', 'css!./emby-scrollbuttons', 'registerElement', '
} }
function onScrollButtonClick(e) { function onScrollButtonClick(e) {
var scroller = this.parentNode.nextSibling;
var parent = dom.parentWithAttribute(this, 'is', 'emby-scroller');
var direction = this.getAttribute('data-direction'); var direction = this.getAttribute('data-direction');
var scrollSize = getScrollSize(scroller);
var scrollPos = getScrollPosition(scroller);
var scrollWidth = getScrollWidth(scroller);
var scrollSize = getScrollSize(parent);
var pos = getScrollPosition(parent);
var newPos; var newPos;
if (direction === 'left') { if (direction === 'left') {
newPos = Math.max(0, pos - scrollSize); newPos = Math.max(0, scrollPos - scrollSize);
} else { } else {
newPos = pos + scrollSize; newPos = scrollPos + scrollSize;
} }
parent.scrollToPosition(newPos, false); scroller.scrollToPosition(newPos, false);
} }
EmbyScrollButtonsPrototype.attachedCallback = function () { EmbyScrollButtonsPrototype.attachedCallback = function () {
var scroller = this.nextSibling;
var parent = this.parentNode;
this.scroller = scroller;
var parent = dom.parentWithAttribute(this, 'is', 'emby-scroller'); parent.classList.add('emby-scroller-container');
this.scroller = parent;
parent.classList.add('emby-scrollbuttons-scroller'); this.innerHTML = getScrollButtonHtml('left') + getScrollButtonHtml('right');
this.innerHTML = getScrollButtonContainerHtml('left') + getScrollButtonContainerHtml('right');
var scrollHandler = onScroll.bind(this); var scrollHandler = onScroll.bind(this);
this.scrollHandler = scrollHandler; this.scrollHandler = scrollHandler;
var buttons = this.querySelectorAll('.emby-scrollbuttons-scrollbutton'); var buttons = this.querySelectorAll('.emby-scrollbuttons-button');
buttons[0].addEventListener('click', onScrollButtonClick); buttons[0].addEventListener('click', onScrollButtonClick);
buttons[1].addEventListener('click', onScrollButtonClick); buttons[1].addEventListener('click', onScrollButtonClick);
buttons = this.querySelectorAll('.scrollbuttoncontainer');
this.scrollButtonsLeft = buttons[0]; this.scrollButtonsLeft = buttons[0];
this.scrollButtonsRight = buttons[1]; this.scrollButtonsRight = buttons[1];
parent.addScrollEventListener(scrollHandler, { scroller.addScrollEventListener(scrollHandler, {
capture: false, capture: false,
passive: true passive: true
}); });
}; };
EmbyScrollButtonsPrototype.detachedCallback = function () { EmbyScrollButtonsPrototype.detachedCallback = function () {
var parent = this.scroller; var parent = this.scroller;
this.scroller = null; this.scroller = null;
var scrollHandler = this.scrollHandler; var scrollHandler = this.scrollHandler;
if (parent && scrollHandler) { if (parent && scrollHandler) {
parent.removeScrollEventListener(scrollHandler, { parent.removeScrollEventListener(scrollHandler, {
capture: false, capture: false,

View file

@ -0,0 +1,17 @@
.emby-scroller-container {
position: relative;
}
.emby-scroller {
margin-left: 3.3%;
margin-right: 3.3%;
}
@media all and (max-width:50em) {
.emby-scroller {
padding-left: 3.3%;
padding-right: 3.3%;
margin-left: 0;
margin-right: 0;
}
}

View file

@ -1,101 +1,95 @@
define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'browser', 'registerElement'], function (scroller, dom, layoutManager, inputManager, focusManager, browser) { define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'browser', 'registerElement', 'css!./emby-scroller'], function (scroller, dom, layoutManager, inputManager, focusManager, browser) {
'use strict'; 'use strict';
var ScrollerProtoType = Object.create(HTMLDivElement.prototype); var ScrollerPrototype = Object.create(HTMLDivElement.prototype);
ScrollerProtoType.createdCallback = function () { ScrollerPrototype.createdCallback = function () {
this.classList.add('emby-scroller'); this.classList.add('emby-scroller');
}; };
function initCenterFocus(elem, scrollerInstance) { function initCenterFocus(elem, scrollerInstance) {
dom.addEventListener(elem, 'focus', function (e) { dom.addEventListener(elem, 'focus', function (e) {
var focused = focusManager.focusableParent(e.target); var focused = focusManager.focusableParent(e.target);
if (focused) { if (focused) {
scrollerInstance.toCenter(focused); scrollerInstance.toCenter(focused);
} }
}, { }, {
capture: true, capture: true,
passive: true passive: true
}); });
} }
ScrollerProtoType.scrollToBeginning = function () { ScrollerPrototype.scrollToBeginning = function () {
if (this.scroller) { if (this.scroller) {
this.scroller.slideTo(0, true); this.scroller.slideTo(0, true);
} }
}; };
ScrollerProtoType.toStart = function (elem, immediate) {
ScrollerPrototype.toStart = function (elem, immediate) {
if (this.scroller) { if (this.scroller) {
this.scroller.toStart(elem, immediate); this.scroller.toStart(elem, immediate);
} }
}; };
ScrollerProtoType.toCenter = function (elem, immediate) {
ScrollerPrototype.toCenter = function (elem, immediate) {
if (this.scroller) { if (this.scroller) {
this.scroller.toCenter(elem, immediate); this.scroller.toCenter(elem, immediate);
} }
}; };
ScrollerProtoType.scrollToPosition = function (pos, immediate) { ScrollerPrototype.scrollToPosition = function (pos, immediate) {
if (this.scroller) { if (this.scroller) {
this.scroller.slideTo(pos, immediate); this.scroller.slideTo(pos, immediate);
} }
}; };
ScrollerProtoType.getScrollPosition = function () { ScrollerPrototype.getScrollPosition = function () {
if (this.scroller) { if (this.scroller) {
return this.scroller.getScrollPosition(); return this.scroller.getScrollPosition();
} }
}; };
ScrollerProtoType.getScrollSize = function () { ScrollerPrototype.getScrollSize = function () {
if (this.scroller) { if (this.scroller) {
return this.scroller.getScrollSize(); return this.scroller.getScrollSize();
} }
}; };
ScrollerProtoType.getScrollEventName = function () { ScrollerPrototype.getScrollEventName = function () {
if (this.scroller) { if (this.scroller) {
return this.scroller.getScrollEventName(); return this.scroller.getScrollEventName();
} }
}; };
ScrollerProtoType.getScrollSlider = function () { ScrollerPrototype.getScrollSlider = function () {
if (this.scroller) { if (this.scroller) {
return this.scroller.getScrollSlider(); return this.scroller.getScrollSlider();
} }
}; };
ScrollerProtoType.addScrollEventListener = function (fn, options) { ScrollerPrototype.addScrollEventListener = function (fn, options) {
if (this.scroller) { if (this.scroller) {
dom.addEventListener(this.scroller.getScrollFrame(), this.scroller.getScrollEventName(), fn, options); dom.addEventListener(this.scroller.getScrollFrame(), this.scroller.getScrollEventName(), fn, options);
} }
}; };
ScrollerProtoType.removeScrollEventListener = function (fn, options) { ScrollerPrototype.removeScrollEventListener = function (fn, options) {
if (this.scroller) { if (this.scroller) {
dom.removeEventListener(this.scroller.getScrollFrame(), this.scroller.getScrollEventName(), fn, options); dom.removeEventListener(this.scroller.getScrollFrame(), this.scroller.getScrollEventName(), fn, options);
} }
}; };
function onInputCommand(e) { function onInputCommand(e) {
var cmd = e.detail.command; var cmd = e.detail.command;
if (cmd === 'end') { if (cmd === 'end') {
focusManager.focusLast(this, '.' + this.getAttribute('data-navcommands')); focusManager.focusLast(this, '.' + this.getAttribute('data-navcommands'));
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
} } else if (cmd === 'pageup') {
else if (cmd === 'pageup') {
focusManager.moveFocus(e.target, this, '.' + this.getAttribute('data-navcommands'), -12); focusManager.moveFocus(e.target, this, '.' + this.getAttribute('data-navcommands'), -12);
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
} } else if (cmd === 'pagedown') {
else if (cmd === 'pagedown') {
focusManager.moveFocus(e.target, this, '.' + this.getAttribute('data-navcommands'), 12); focusManager.moveFocus(e.target, this, '.' + this.getAttribute('data-navcommands'), 12);
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@ -104,7 +98,6 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro
function initHeadroom(elem) { function initHeadroom(elem) {
require(['headroom'], function (Headroom) { require(['headroom'], function (Headroom) {
var headroom = new Headroom([], { var headroom = new Headroom([], {
scroller: elem scroller: elem
}); });
@ -114,8 +107,7 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro
}); });
} }
ScrollerProtoType.attachedCallback = function () { ScrollerPrototype.attachedCallback = function () {
if (this.getAttribute('data-navcommands')) { if (this.getAttribute('data-navcommands')) {
inputManager.on(this, onInputCommand); inputManager.on(this, onInputCommand);
} }
@ -141,10 +133,8 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro
slidee: slider, slidee: slider,
scrollBy: 200, scrollBy: 200,
speed: horizontal ? 270 : 240, speed: horizontal ? 270 : 240,
//immediateSpeed: pageOptions.immediateSpeed,
elasticBounds: 1, elasticBounds: 1,
dragHandle: 1, dragHandle: 1,
scrollWidth: this.getAttribute('data-scrollsize') === 'auto' ? null : 5000000,
autoImmediate: true, autoImmediate: true,
skipSlideToWhenVisible: this.getAttribute('data-skipfocuswhenvisible') === 'true', skipSlideToWhenVisible: this.getAttribute('data-skipfocuswhenvisible') === 'true',
dispatchScrollEvent: enableScrollButtons || bindHeader || this.getAttribute('data-scrollevent') === 'true', dispatchScrollEvent: enableScrollButtons || bindHeader || this.getAttribute('data-scrollevent') === 'true',
@ -152,7 +142,6 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro
allowNativeSmoothScroll: this.getAttribute('data-allownativesmoothscroll') === 'true' && !enableScrollButtons, allowNativeSmoothScroll: this.getAttribute('data-allownativesmoothscroll') === 'true' && !enableScrollButtons,
allowNativeScroll: !enableScrollButtons, allowNativeScroll: !enableScrollButtons,
forceHideScrollbars: enableScrollButtons, forceHideScrollbars: enableScrollButtons,
// In edge, with the native scroll, the content jumps around when hovering over the buttons // In edge, with the native scroll, the content jumps around when hovering over the buttons
requireAnimation: enableScrollButtons && browser.edge requireAnimation: enableScrollButtons && browser.edge
}; };
@ -160,6 +149,7 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro
// If just inserted it might not have any height yet - yes this is a hack // If just inserted it might not have any height yet - yes this is a hack
this.scroller = new scroller(scrollFrame, options); this.scroller = new scroller(scrollFrame, options);
this.scroller.init(); this.scroller.init();
this.scroller.reload();
if (layoutManager.tv && this.getAttribute('data-centerfocus')) { if (layoutManager.tv && this.getAttribute('data-centerfocus')) {
initCenterFocus(this, this.scroller); initCenterFocus(this, this.scroller);
@ -175,30 +165,26 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro
}; };
function loadScrollButtons(scroller) { function loadScrollButtons(scroller) {
require(['emby-scrollbuttons'], function () { require(['emby-scrollbuttons'], function () {
scroller.insertAdjacentHTML('beforeend', '<div is="emby-scrollbuttons"></div>'); scroller.insertAdjacentHTML('beforebegin', '<div is="emby-scrollbuttons" class="emby-scrollbuttons padded-right"></div>');
}); });
} }
ScrollerProtoType.pause = function () { ScrollerPrototype.pause = function () {
var headroom = this.headroom; var headroom = this.headroom;
if (headroom) { if (headroom) {
headroom.pause(); headroom.pause();
} }
}; };
ScrollerProtoType.resume = function () { ScrollerPrototype.resume = function () {
var headroom = this.headroom; var headroom = this.headroom;
if (headroom) { if (headroom) {
headroom.resume(); headroom.resume();
} }
}; };
ScrollerProtoType.detachedCallback = function () { ScrollerPrototype.detachedCallback = function () {
if (this.getAttribute('data-navcommands')) { if (this.getAttribute('data-navcommands')) {
inputManager.off(this, onInputCommand); inputManager.off(this, onInputCommand);
} }
@ -217,7 +203,7 @@ define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'bro
}; };
document.registerElement('emby-scroller', { document.registerElement('emby-scroller', {
prototype: ScrollerProtoType, prototype: ScrollerPrototype,
extends: 'div' extends: 'div'
}); });
}); });

View file

@ -27,10 +27,6 @@ _:-ms-input-placeholder {
/* Disable webkit tap highlighting */ /* Disable webkit tap highlighting */
-webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: rgba(0,0,0,0);
display: block; display: block;
/**************************** Tracks ****************************/
/**************************** Thumbs ****************************/
/**************************** 0-value ****************************/
/**************************** Disabled ****************************/
} }
.mdl-slider::-moz-focus-outer { .mdl-slider::-moz-focus-outer {

View file

@ -18,7 +18,6 @@
</div> </div>
<div is="emby-scroller" class="guideVerticalScroller flex flex-grow programContainer guideScroller" data-skipfocuswhenvisible="true" data-horizontal="false"> <div is="emby-scroller" class="guideVerticalScroller flex flex-grow programContainer guideScroller" data-skipfocuswhenvisible="true" data-horizontal="false">
<div class="scrollSlider flex flex-grow flex-direction-row" style="overflow:hidden;contain: layout style paint;"> <div class="scrollSlider flex flex-grow flex-direction-row" style="overflow:hidden;contain: layout style paint;">
<div class="channelsContainer"> <div class="channelsContainer">
<div class="channelList"></div> <div class="channelList"></div>

View file

@ -2,9 +2,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
'use strict'; 'use strict';
function getDefaultSection(index) { function getDefaultSection(index) {
switch (index) { switch (index) {
case 0: case 0:
return 'smalllibrarytiles'; return 'smalllibrarytiles';
case 1: case 1:
@ -25,13 +23,9 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function getAllSectionsToShow(userSettings, sectionCount) { function getAllSectionsToShow(userSettings, sectionCount) {
var sections = []; var sections = [];
for (var i = 0, length = sectionCount; i < length; i++) { for (var i = 0, length = sectionCount; i < length; i++) {
var section = userSettings.get('homesection' + i) || getDefaultSection(i); var section = userSettings.get('homesection' + i) || getDefaultSection(i);
if (section === 'folders') { if (section === 'folders') {
section = getDefaultSection(0); section = getDefaultSection(0);
} }
@ -43,15 +37,11 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function loadSections(elem, apiClient, user, userSettings) { function loadSections(elem, apiClient, user, userSettings) {
return getUserViews(apiClient, user.Id).then(function (userViews) { return getUserViews(apiClient, user.Id).then(function (userViews) {
var i, length;
var sectionCount = 7;
var html = ''; var html = '';
for (i = 0, length = sectionCount; i < length; i++) {
var sectionCount = 7;
for (var i = 0; i < sectionCount; i++) {
html += '<div class="verticalSection section' + i + '"></div>'; html += '<div class="verticalSection section' + i + '"></div>';
} }
@ -60,14 +50,11 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
var promises = []; var promises = [];
var sections = getAllSectionsToShow(userSettings, sectionCount); var sections = getAllSectionsToShow(userSettings, sectionCount);
for (var i = 0; i < sections.length; i++) {
for (i = 0, length = sections.length; i < length; i++) {
promises.push(loadSection(elem, apiClient, user, userSettings, userViews, sections, i)); promises.push(loadSection(elem, apiClient, user, userSettings, userViews, sections, i));
} }
return Promise.all(promises).then(function () { return Promise.all(promises).then(function () {
return resume(elem, { return resume(elem, {
refresh: true, refresh: true,
returnPromise: false returnPromise: false
@ -77,12 +64,8 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function destroySections(elem) { function destroySections(elem) {
var elems = elem.querySelectorAll('.itemsContainer'); var elems = elem.querySelectorAll('.itemsContainer');
var i, length; for (var i = 0; i < elems.length; i++) {
for (i = 0, length = elems.length; i < length; i++) {
elems[i].fetchData = null; elems[i].fetchData = null;
elems[i].parentContainer = null; elems[i].parentContainer = null;
elems[i].getItemsHtml = null; elems[i].getItemsHtml = null;
@ -92,17 +75,13 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function pause(elem) { function pause(elem) {
var elems = elem.querySelectorAll('.itemsContainer'); var elems = elem.querySelectorAll('.itemsContainer');
var i, length; for (var i = 0; i < elems.length; i++) {
for (i = 0, length = elems.length; i < length; i++) {
elems[i].pause(); elems[i].pause();
} }
} }
function resume(elem, options) { function resume(elem, options) {
var elems = elem.querySelectorAll('.itemsContainer'); var elems = elem.querySelectorAll('.itemsContainer');
var i, length; var i, length;
var promises = []; var promises = [];
@ -112,7 +91,6 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
var promise = Promise.all(promises); var promise = Promise.all(promises);
if (!options || options.returnPromise !== false) { if (!options || options.returnPromise !== false) {
return promise; return promise;
} }
@ -127,41 +105,29 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
if (section === 'latestmedia') { if (section === 'latestmedia') {
loadRecentlyAdded(elem, apiClient, user, userViews); loadRecentlyAdded(elem, apiClient, user, userViews);
} } else if (section === 'librarytiles' || section === 'smalllibrarytiles' || section === 'smalllibrarytiles-automobile' || section === 'librarytiles-automobile') {
else if (section === 'librarytiles' || section === 'smalllibrarytiles' || section === 'smalllibrarytiles-automobile' || section === 'librarytiles-automobile') {
loadLibraryTiles(elem, apiClient, user, userSettings, 'smallBackdrop', userViews, allSections); loadLibraryTiles(elem, apiClient, user, userSettings, 'smallBackdrop', userViews, allSections);
} } else if (section === 'librarybuttons') {
else if (section === 'librarybuttons') {
loadlibraryButtons(elem, apiClient, user, userSettings, userViews, allSections); loadlibraryButtons(elem, apiClient, user, userSettings, userViews, allSections);
} } else if (section === 'resume') {
else if (section === 'resume') {
loadResumeVideo(elem, apiClient, userId); loadResumeVideo(elem, apiClient, userId);
} } else if (section === 'resumeaudio') {
else if (section === 'resumeaudio') {
loadResumeAudio(elem, apiClient, userId); loadResumeAudio(elem, apiClient, userId);
} } else if (section === 'activerecordings') {
else if (section === 'activerecordings') {
loadLatestLiveTvRecordings(elem, true, apiClient, userId); loadLatestLiveTvRecordings(elem, true, apiClient, userId);
} } else if (section === 'nextup') {
else if (section === 'nextup') {
loadNextUp(elem, apiClient, userId); loadNextUp(elem, apiClient, userId);
} } else if (section === 'onnow' || section === 'livetv') {
else if (section === 'onnow' || section === 'livetv') {
return loadOnNow(elem, apiClient, user); return loadOnNow(elem, apiClient, user);
} } else {
else {
elem.innerHTML = ''; elem.innerHTML = '';
return Promise.resolve(); return Promise.resolve();
} }
return Promise.resolve(); return Promise.resolve();
} }
function getUserViews(apiClient, userId) { function getUserViews(apiClient, userId) {
return apiClient.getUserViews({}, userId || apiClient.getCurrentUserId()).then(function (result) { return apiClient.getUserViews({}, userId || apiClient.getCurrentUserId()).then(function (result) {
return result.Items; return result.Items;
}); });
} }
@ -186,9 +152,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
var html = ""; var html = "";
html += '<div class="verticalSection verticalSection-extrabottompadding">'; html += '<div class="verticalSection verticalSection-extrabottompadding">';
html += '<div class="sectionTitleContainer sectionTitleContainer-cards">';
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderMyMedia') + '</h2>'; html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderMyMedia') + '</h2>';
html += '</div>';
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-multiselect="false">'; html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-multiselect="false">';
@ -261,21 +225,15 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function getFetchLatestItemsFn(serverId, parentId, collectionType) { function getFetchLatestItemsFn(serverId, parentId, collectionType) {
return function () { return function () {
var apiClient = connectionManager.getApiClient(serverId); var apiClient = connectionManager.getApiClient(serverId);
var limit = 16; var limit = 16;
if (enableScrollX()) { if (enableScrollX()) {
if (collectionType === 'music') { if (collectionType === 'music') {
limit = 30; limit = 30;
} }
} } else {
else {
if (collectionType === 'tvshows') { if (collectionType === 'tvshows') {
limit = 5; limit = 5;
} else if (collectionType === 'music') { } else if (collectionType === 'music') {
@ -286,7 +244,6 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
var options = { var options = {
Limit: limit, Limit: limit,
Fields: "PrimaryImageAspectRatio,BasicSyncInfo", Fields: "PrimaryImageAspectRatio,BasicSyncInfo",
ImageTypeLimit: 1, ImageTypeLimit: 1,
@ -299,9 +256,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function getLatestItemsHtmlFn(itemType, viewType) { function getLatestItemsHtmlFn(itemType, viewType) {
return function (items) { return function (items) {
var shape = itemType === 'Channel' || viewType === 'movies' ? var shape = itemType === 'Channel' || viewType === 'movies' ?
getPortraitShape() : getPortraitShape() :
viewType === 'music' ? viewType === 'music' ?
@ -331,31 +286,28 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function renderLatestSection(elem, apiClient, user, parent) { function renderLatestSection(elem, apiClient, user, parent) {
var html = ''; var html = '';
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">'; html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
if (!layoutManager.tv) { if (!layoutManager.tv) {
html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl(parent, { html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl(parent, {
section: 'latest' section: 'latest'
}) + '" class="more button-flat button-flat-mini sectionTitleTextButton">'; }) + '" class="more button-flat button-flat-mini sectionTitleTextButton">';
html += '<h2 class="sectionTitle sectionTitle-cards">'; html += '<h2 class="sectionTitle sectionTitle-cards">';
html += globalize.translate('LatestFromLibrary', parent.Name); html += globalize.translate('LatestFromLibrary', parent.Name);
html += '</h2>'; html += '</h2>';
html += '<i class="md-icon">&#xE5CC;</i>'; html += '<i class="md-icon">&#xE5CC;</i>';
html += '</a>'; html += '</a>';
} else { } else {
html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate('LatestFromLibrary', parent.Name) + '</h2>'; html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate('LatestFromLibrary', parent.Name) + '</h2>';
} }
html += '</div>'; html += '</div>';
if (enableScrollX()) { if (enableScrollX()) {
html += '<div is="emby-scroller" data-mousewheel="false" data-centerfocus="true" class="padded-top-focusscale padded-bottom-focusscale"><div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x padded-left padded-right">'; html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">';
} else { } else {
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">'; html += '<div is="emby-itemscontainer" class="itemsContainer focuscontainer-x padded-left padded-right vertical-wrap">';
} }
if (enableScrollX()) { if (enableScrollX()) {
@ -369,19 +321,14 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
itemsContainer.fetchData = getFetchLatestItemsFn(apiClient.serverId(), parent.Id, parent.CollectionType); itemsContainer.fetchData = getFetchLatestItemsFn(apiClient.serverId(), parent.Id, parent.CollectionType);
itemsContainer.getItemsHtml = getLatestItemsHtmlFn(parent.Type, parent.CollectionType); itemsContainer.getItemsHtml = getLatestItemsHtmlFn(parent.Type, parent.CollectionType);
itemsContainer.parentContainer = elem; itemsContainer.parentContainer = elem;
} }
function loadRecentlyAdded(elem, apiClient, user, userViews) { function loadRecentlyAdded(elem, apiClient, user, userViews) {
elem.classList.remove('verticalSection'); elem.classList.remove('verticalSection');
var excludeViewTypes = ['playlists', 'livetv', 'boxsets', 'channels']; var excludeViewTypes = ['playlists', 'livetv', 'boxsets', 'channels'];
for (var i = 0, length = userViews.length; i < length; i++) { for (var i = 0, length = userViews.length; i < length; i++) {
var item = userViews[i]; var item = userViews[i];
if (user.Configuration.LatestItemsExcludes.indexOf(item.Id) !== -1) { if (user.Configuration.LatestItemsExcludes.indexOf(item.Id) !== -1) {
continue; continue;
} }
@ -406,39 +353,31 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function loadLibraryTiles(elem, apiClient, user, userSettings, shape, userViews, allSections) { function loadLibraryTiles(elem, apiClient, user, userSettings, shape, userViews, allSections) {
elem.classList.remove('verticalSection');
var html = ''; var html = '';
var scrollX = !layoutManager.desktop;
if (userViews.length) { if (userViews.length) {
html += '<div class="verticalSection">';
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderMyMedia') + '</h2>'; html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderMyMedia') + '</h2>';
if (enableScrollX()) {
if (scrollX) { html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true"><div is="emby-itemscontainer" class="scrollSlider focuscontainer-x padded-left padded-right">'; html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">';
} else { } else {
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">'; html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right focuscontainer-x vertical-wrap">';
} }
html += cardBuilder.getCardsHtml({ html += cardBuilder.getCardsHtml({
items: userViews, items: userViews,
shape: scrollX ? 'overflowSmallBackdrop' : shape, shape: enableScrollX() ? 'overflowSmallBackdrop' : shape,
showTitle: true, showTitle: true,
centerText: true, centerText: true,
overlayText: false, overlayText: false,
lazy: true, lazy: true,
transition: false, transition: false,
allowBottomPadding: !scrollX allowBottomPadding: !enableScrollX()
}); });
if (scrollX) { if (enableScrollX()) {
html += '</div>'; html += '</div>';
} }
html += '</div>'; html += '</div>';
html += '</div>';
} }
elem.innerHTML = html; elem.innerHTML = html;
@ -446,27 +385,19 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function getContinueWatchingFetchFn(serverId) { function getContinueWatchingFetchFn(serverId) {
return function () { return function () {
var apiClient = connectionManager.getApiClient(serverId); var apiClient = connectionManager.getApiClient(serverId);
var screenWidth = dom.getWindowSize().innerWidth; var screenWidth = dom.getWindowSize().innerWidth;
var limit; var limit;
if (enableScrollX()) { if (enableScrollX()) {
limit = 12; limit = 12;
} else { } else {
limit = screenWidth >= 1920 ? 8 : (screenWidth >= 1600 ? 8 : (screenWidth >= 1200 ? 9 : 6)); limit = screenWidth >= 1920 ? 8 : (screenWidth >= 1600 ? 8 : (screenWidth >= 1200 ? 9 : 6));
limit = Math.min(limit, 5); limit = Math.min(limit, 5);
} }
var options = { var options = {
Limit: limit, Limit: limit,
Recursive: true, Recursive: true,
Fields: "PrimaryImageAspectRatio,BasicSyncInfo", Fields: "PrimaryImageAspectRatio,BasicSyncInfo",
@ -481,9 +412,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function getContinueWatchingItemsHtml(items) { function getContinueWatchingItemsHtml(items) {
var cardLayout = false; var cardLayout = false;
return cardBuilder.getCardsHtml({ return cardBuilder.getCardsHtml({
items: items, items: items,
preferThumb: true, preferThumb: true,
@ -504,12 +433,12 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function loadResumeVideo(elem, apiClient, userId) { function loadResumeVideo(elem, apiClient, userId) {
var html = ''; var html = '';
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderContinueWatching') + '</h2>';
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderContinueWatching') + '</h2>';
if (enableScrollX()) { if (enableScrollX()) {
html += '<div is="emby-scroller" data-mousewheel="false" data-centerfocus="true" class="padded-top-focusscale padded-bottom-focusscale"><div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x padded-left padded-right" data-monitor="videoplayback,markplayed">'; html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="videoplayback,markplayed">';
} else { } else {
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="videoplayback,markplayed">'; html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="videoplayback,markplayed">';
} }
@ -529,27 +458,19 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function getContinueListeningFetchFn(serverId) { function getContinueListeningFetchFn(serverId) {
return function () { return function () {
var apiClient = connectionManager.getApiClient(serverId); var apiClient = connectionManager.getApiClient(serverId);
var screenWidth = dom.getWindowSize().innerWidth; var screenWidth = dom.getWindowSize().innerWidth;
var limit; var limit;
if (enableScrollX()) { if (enableScrollX()) {
limit = 12; limit = 12;
} else { } else {
limit = screenWidth >= 1920 ? 8 : (screenWidth >= 1600 ? 8 : (screenWidth >= 1200 ? 9 : 6)); limit = screenWidth >= 1920 ? 8 : (screenWidth >= 1600 ? 8 : (screenWidth >= 1200 ? 9 : 6));
limit = Math.min(limit, 5); limit = Math.min(limit, 5);
} }
var options = { var options = {
Limit: limit, Limit: limit,
Recursive: true, Recursive: true,
Fields: "PrimaryImageAspectRatio,BasicSyncInfo", Fields: "PrimaryImageAspectRatio,BasicSyncInfo",
@ -564,9 +485,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function getContinueListeningItemsHtml(items) { function getContinueListeningItemsHtml(items) {
var cardLayout = false; var cardLayout = false;
return cardBuilder.getCardsHtml({ return cardBuilder.getCardsHtml({
items: items, items: items,
preferThumb: true, preferThumb: true,
@ -587,12 +506,12 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function loadResumeAudio(elem, apiClient, userId) { function loadResumeAudio(elem, apiClient, userId) {
var html = ''; var html = '';
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderContinueWatching') + '</h2>';
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + globalize.translate('HeaderContinueWatching') + '</h2>';
if (enableScrollX()) { if (enableScrollX()) {
html += '<div is="emby-scroller" data-mousewheel="false" data-centerfocus="true" class="padded-top-focusscale padded-bottom-focusscale"><div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x padded-left padded-right" data-monitor="audioplayback,markplayed">'; html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="audioplayback,markplayed">';
} else { } else {
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="audioplayback,markplayed">'; html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="audioplayback,markplayed">';
} }
@ -678,9 +597,9 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
if (enableScrollX()) { if (enableScrollX()) {
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true" data-scrollbuttons="false">'; html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true" data-scrollbuttons="false">';
html += '<div class="scrollSlider padded-left padded-right padded-top padded-bottom focuscontainer-x">'; html += '<div class="padded-left padded-right padded-top padded-bottom scrollSlider focuscontainer-x">';
} else { } else {
html += '<div class="padded-left padded-right padded-top focuscontainer-x">'; html += '<div class="padded-left padded-right padded-top padded-bottom focuscontainer-x">';
} }
html += '<a style="margin-left:.8em;margin-right:0;" is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', { html += '<a style="margin-left:.8em;margin-right:0;" is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', {
@ -733,9 +652,10 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
html += '</div>'; html += '</div>';
if (enableScrollX()) { if (enableScrollX()) {
html += '<div is="emby-scroller" data-mousewheel="false" data-centerfocus="true" class="padded-top-focusscale padded-bottom-focusscale"><div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x padded-left padded-right" data-refreshinterval="300000">'; html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">'
} else { } else {
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-refreshinterval="300000">'; html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">';
} }
if (enableScrollX()) { if (enableScrollX()) {
@ -756,13 +676,9 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function getNextUpFetchFn(serverId) { function getNextUpFetchFn(serverId) {
return function () { return function () {
var apiClient = connectionManager.getApiClient(serverId); var apiClient = connectionManager.getApiClient(serverId);
return apiClient.getNextUpEpisodes({ return apiClient.getNextUpEpisodes({
Limit: enableScrollX() ? 24 : 15, Limit: enableScrollX() ? 24 : 15,
Fields: "PrimaryImageAspectRatio,SeriesInfo,DateCreated,BasicSyncInfo", Fields: "PrimaryImageAspectRatio,SeriesInfo,DateCreated,BasicSyncInfo",
UserId: apiClient.getCurrentUserId(), UserId: apiClient.getCurrentUserId(),
@ -774,9 +690,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function getNextUpItemsHtml(items) { function getNextUpItemsHtml(items) {
var cardLayout = false; var cardLayout = false;
return cardBuilder.getCardsHtml({ return cardBuilder.getCardsHtml({
items: items, items: items,
preferThumb: true, preferThumb: true,
@ -794,29 +708,26 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function loadNextUp(elem, apiClient, userId) { function loadNextUp(elem, apiClient, userId) {
var html = ''; var html = '';
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">'; html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
if (!layoutManager.tv) { if (!layoutManager.tv) {
html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl('nextup', { html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl('nextup', {
serverId: apiClient.serverId() serverId: apiClient.serverId()
}) + '" class="button-flat button-flat-mini sectionTitleTextButton">'; }) + '" class="button-flat button-flat-mini sectionTitleTextButton">';
html += '<h2 class="sectionTitle sectionTitle-cards">'; html += '<h2 class="sectionTitle sectionTitle-cards">';
html += globalize.translate('HeaderNextUp'); html += globalize.translate('HeaderNextUp');
html += '</h2>'; html += '</h2>';
html += '<i class="md-icon">&#xE5CC;</i>'; html += '<i class="md-icon">&#xE5CC;</i>';
html += '</a>'; html += '</a>';
} else { } else {
html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate('HeaderNextUp') + '</h2>'; html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate('HeaderNextUp') + '</h2>';
} }
html += '</div>'; html += '</div>';
if (enableScrollX()) { if (enableScrollX()) {
html += '<div is="emby-scroller" data-mousewheel="false" data-centerfocus="true" class="padded-top-focusscale padded-bottom-focusscale"><div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x padded-left padded-right" data-monitor="videoplayback,markplayed">'; html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="videoplayback,markplayed">'
} else { } else {
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="videoplayback,markplayed">'; html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="videoplayback,markplayed">';
} }
@ -824,7 +735,6 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
if (enableScrollX()) { if (enableScrollX()) {
html += '</div>'; html += '</div>';
} }
html += '</div>'; html += '</div>';
elem.classList.add('hide'); elem.classList.add('hide');
@ -837,29 +747,22 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function getLatestRecordingsFetchFn(serverId, activeRecordingsOnly) { function getLatestRecordingsFetchFn(serverId, activeRecordingsOnly) {
return function () { return function () {
var apiClient = connectionManager.getApiClient(serverId); var apiClient = connectionManager.getApiClient(serverId);
return apiClient.getLiveTvRecordings({ return apiClient.getLiveTvRecordings({
userId: apiClient.getCurrentUserId(), userId: apiClient.getCurrentUserId(),
Limit: enableScrollX() ? 12 : 5, Limit: enableScrollX() ? 12 : 5,
Fields: "PrimaryImageAspectRatio,BasicSyncInfo", Fields: "PrimaryImageAspectRatio,BasicSyncInfo",
EnableTotalRecordCount: false, EnableTotalRecordCount: false,
IsLibraryItem: activeRecordingsOnly ? null : false, IsLibraryItem: activeRecordingsOnly ? null : false,
IsInProgress: activeRecordingsOnly ? true : null IsInProgress: activeRecordingsOnly ? true : null
}); });
}; };
} }
function getLatestRecordingItemsHtml(activeRecordingsOnly) { function getLatestRecordingItemsHtml(activeRecordingsOnly) {
return function (items) { return function (items) {
var cardLayout = false; var cardLayout = false;
return cardBuilder.getCardsHtml({ return cardBuilder.getCardsHtml({
items: items, items: items,
shape: enableScrollX() ? 'autooverflow' : 'auto', shape: enableScrollX() ? 'autooverflow' : 'auto',
@ -884,7 +787,6 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} }
function loadLatestLiveTvRecordings(elem, activeRecordingsOnly, apiClient, userId) { function loadLatestLiveTvRecordings(elem, activeRecordingsOnly, apiClient, userId) {
var title = activeRecordingsOnly ? var title = activeRecordingsOnly ?
globalize.translate('HeaderActiveRecordings') : globalize.translate('HeaderActiveRecordings') :
globalize.translate('HeaderLatestRecordings'); globalize.translate('HeaderLatestRecordings');
@ -893,16 +795,11 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
html += '<div class="sectionTitleContainer sectionTitleContainer-cards">'; html += '<div class="sectionTitleContainer sectionTitleContainer-cards">';
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + title + '</h2>'; html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + title + '</h2>';
if (!layoutManager.tv) {
//html += '<a href="livetv.html?tab=3" class="clearLink" style="margin-left:2em;"><button is="emby-button" type="button" class="raised more mini"><span>' + globalize.translate('More') + '</span></button></a>';
//html += '<button data-href="" type="button" is="emby-button" class="raised raised-mini sectionTitleButton btnMore">';
//html += '<span>' + globalize.translate('More') + '</span>';
//html += '</button>';
}
html += '</div>'; html += '</div>';
if (enableScrollX()) { if (enableScrollX()) {
html += '<div is="emby-scroller" data-mousewheel="false" data-centerfocus="true" class="padded-top-focusscale padded-bottom-focusscale"><div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x padded-left padded-right">'; html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true">';
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">'
} else { } else {
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">'; html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">';
} }
@ -910,7 +807,6 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
if (enableScrollX()) { if (enableScrollX()) {
html += '</div>'; html += '</div>';
} }
html += '</div>'; html += '</div>';
elem.classList.add('hide'); elem.classList.add('hide');

View file

@ -299,13 +299,10 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc
} }
// Start animation rendering // Start animation rendering
if (newPos !== pos.dest) { // NOTE the dependency was modified here to fix a scrollbutton issue
pos.dest = newPos; pos.dest = newPos;
renderAnimateWithTransform(from, newPos, immediate); renderAnimateWithTransform(from, newPos, immediate);
lastAnimate = now; lastAnimate = now;
}
}; };
function setStyleProperty(elem, name, value, speed, resetTransition) { function setStyleProperty(elem, name, value, speed, resetTransition) {

View file

@ -5,7 +5,6 @@
</div> </div>
<div class="searchSuggestionsList padded-left padded-right"> <div class="searchSuggestionsList padded-left padded-right">
</div> </div>
</div> </div>
@ -13,7 +12,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Movies}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Movies}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -21,7 +20,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Shows}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Shows}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -29,7 +28,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Episodes}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Episodes}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -37,7 +36,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Sports}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Sports}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -45,7 +44,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Kids}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Kids}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -53,7 +52,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${News}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${News}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -61,7 +60,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Programs}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Programs}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -69,7 +68,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Videos}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Videos}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -77,7 +76,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Playlists}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Playlists}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -85,7 +84,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Artists}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Artists}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -93,7 +92,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Albums}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Albums}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -101,7 +100,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Songs}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Songs}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -109,7 +108,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${HeaderPhotoAlbums}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${HeaderPhotoAlbums}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -117,7 +116,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Photos}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Photos}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -125,7 +124,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${HeaderAudioBooks}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${HeaderAudioBooks}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -133,7 +132,7 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Books}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Books}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>
@ -141,6 +140,6 @@
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${People}</h2> <h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${People}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale"> <div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div> <div is="emby-itemscontainer" class="focuscontainer-x itemsContainer scrollSlider"></div>
</div> </div>
</div> </div>

View file

@ -22,7 +22,7 @@ html {
.skinHeader.semiTransparent { .skinHeader.semiTransparent {
-webkit-backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
backdrop-filter: none !important; backdrop-filter: none !important;
background-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.4);
} }
.pageTitleWithDefaultLogo { .pageTitleWithDefaultLogo {

View file

@ -22,7 +22,7 @@ html {
.skinHeader.semiTransparent { .skinHeader.semiTransparent {
-webkit-backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
backdrop-filter: none !important; backdrop-filter: none !important;
background-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.4);
} }
.pageTitleWithDefaultLogo { .pageTitleWithDefaultLogo {

View file

@ -35,7 +35,7 @@ html {
.skinHeader.semiTransparent { .skinHeader.semiTransparent {
-webkit-backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
backdrop-filter: none !important; backdrop-filter: none !important;
background-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.4);
} }
.pageTitleWithDefaultLogo { .pageTitleWithDefaultLogo {

View file

@ -2,19 +2,19 @@ define(["appRouter", "cardBuilder", "dom", "globalize", "connectionManager", "ap
"use strict"; "use strict";
function enableScrollX() { function enableScrollX() {
return !0 return true;
} }
function getThumbShape() { function getThumbShape() {
return enableScrollX() ? "overflowBackdrop" : "backdrop" return enableScrollX() ? "overflowBackdrop" : "backdrop";
} }
function getPosterShape() { function getPosterShape() {
return enableScrollX() ? "overflowPortrait" : "portrait" return enableScrollX() ? "overflowPortrait" : "portrait";
} }
function getSquareShape() { function getSquareShape() {
return enableScrollX() ? "overflowSquare" : "square" return enableScrollX() ? "overflowSquare" : "square";
} }
function getSections() { function getSections() {

View file

@ -960,97 +960,47 @@
} }
.padded-left { .padded-left {
padding-left: 2% padding-left: 3.3%;
} }
.padded-right { .padded-right {
padding-right: 2% padding-right: 3.3%;
} }
.padded-top { .padded-top {
padding-top: 1em padding-top: 1em;
} }
.padded-bottom { .padded-bottom {
padding-bottom: 1em padding-bottom: 1em;
} }
.layout-tv .padded-top-focusscale { .layout-tv .padded-top-focusscale {
padding-top: 1em; padding-top: 1em;
margin-top: -1em margin-top: -1em;
} }
.layout-tv .padded-bottom-focusscale { .layout-tv .padded-bottom-focusscale {
padding-bottom: 1em; padding-bottom: 1em;
margin-bottom: -1em margin-bottom: -1em;
} }
@media all and (min-height:31.25em) { @media all and (min-height:31.25em) {
.padded-left-withalphapicker { .padded-left-withalphapicker {
padding-left: 7.5% padding-left: 7.5%;
} }
.padded-right-withalphapicker { .padded-right-withalphapicker {
padding-right: 7.5% padding-right: 7.5%;
}
}
@media all and (min-width:31.25em) {
.padded-left {
padding-left: 6%
}
.padded-right {
padding-right: 6%
}
}
@media all and (min-width:37.5em) {
.padded-left {
padding-left: 4%
}
.padded-right {
padding-right: 4%
}
}
@media all and (min-width:50em) {
.padded-left {
padding-left: 3.2%
}
.padded-right {
padding-right: 3.2%
}
}
@media all and (min-width:64em) {
.padded-left {
padding-left: 3.3%
}
.padded-right {
padding-right: 3.3%
}
}
@media all and (min-width:50em) {
.layout-tv .padded-left-withalphapicker {
padding-left: 4.5%
}
.layout-tv .padded-right-withalphapicker {
padding-right: 4.5%
} }
} }
.searchfields-icon { .searchfields-icon {
color: #aaa color: #aaaaaa;
} }
.button-accent-flat { .button-accent-flat {
color: #00a4dc !important color: #00a4dc !important;
} }
.clearLink { .clearLink {

View file

@ -207,9 +207,7 @@
</div> </div>
<div class="collectionItems"></div> <div class="collectionItems"></div>
<div class="nextUpSection verticalSection detailVerticalSection hide"> <div class="nextUpSection verticalSection detailVerticalSection hide">
<h2 class="sectionTitle sectionTitle-cards padded-left"> <h2 class="sectionTitle sectionTitle-cards padded-left">${HeaderNextUp}</h2>
${HeaderNextUp}
</h2>
<div is="emby-itemscontainer" class="nextUpItems vertical-wrap padded-left padded-right"></div> <div is="emby-itemscontainer" class="nextUpItems vertical-wrap padded-left padded-right"></div>
</div> </div>
<div class="programGuideSection hide verticalSection detailVerticalSection"> <div class="programGuideSection hide verticalSection detailVerticalSection">
@ -224,18 +222,15 @@
</div> </div>
</div> </div>
<div id="additionalPartsCollapsible" class="verticalSection detailVerticalSection hide"> <div id="additionalPartsCollapsible" class="verticalSection detailVerticalSection hide">
<h2 class="sectionTitle sectionTitle-cards padded-left"> <h2 class="sectionTitle sectionTitle-cards padded-left">${HeaderAdditionalParts}</h2>
${HeaderAdditionalParts}
</h2>
<div id="additionalPartsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"></div> <div id="additionalPartsContent" is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"></div>
</div> </div>
<div class="verticalSection itemVerticalSection moreFromSeasonSection hide"> <div class="verticalSection itemVerticalSection moreFromSeasonSection hide">
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right"></h2> <h2 class="sectionTitle sectionTitle-cards padded-left padded-right"></h2>
<div is="emby-scroller" class="emby-scroller" data-mousewheel="false" data-centerfocus="true" data-horizontal="true"> <div is="emby-scroller" class="emby-scroller" data-mousewheel="false" data-centerfocus="true" data-horizontal="true">
<div class="scrollerframe padded-top-focusscale padded-bottom-focusscale"> <div class="scrollerframe padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer padded-left padded-right"></div> <div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
</div> </div>
</div> </div>
</div> </div>
@ -243,20 +238,17 @@
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right"></h2> <h2 class="sectionTitle sectionTitle-cards padded-left padded-right"></h2>
<div is="emby-scroller" class="emby-scroller" data-mousewheel="false" data-centerfocus="true" data-horizontal="true"> <div is="emby-scroller" class="emby-scroller" data-mousewheel="false" data-centerfocus="true" data-horizontal="true">
<div class="scrollerframe padded-top-focusscale padded-bottom-focusscale"> <div class="scrollerframe padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer padded-left padded-right"></div> <div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
</div> </div>
</div> </div>
</div> </div>
<div id="castCollapsible" class="verticalSection detailVerticalSection hide"> <div id="castCollapsible" class="verticalSection detailVerticalSection hide">
<h2 id="peopleHeader" class="sectionTitle sectionTitle-cards padded-left padded-right"> <h2 id="peopleHeader" class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderCastCrew}</h2>
${HeaderCastCrew}
</h2>
<div is="emby-scroller" class="emby-scroller" data-mousewheel="false" data-centerfocus="true" data-horizontal="true"> <div is="emby-scroller" class="emby-scroller" data-mousewheel="false" data-centerfocus="true" data-horizontal="true">
<div class="scrollerframe padded-top-focusscale padded-bottom-focusscale"> <div class="scrollerframe padded-top-focusscale padded-bottom-focusscale">
<div id="castContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer padded-left padded-right"></div> <div id="castContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
</div> </div>
</div> </div>
</div> </div>
@ -285,9 +277,8 @@
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderScenes}</h2> <h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderScenes}</h2>
<div is="emby-scroller" class="emby-scroller" data-mousewheel="false" data-centerfocus="true" data-horizontal="true"> <div is="emby-scroller" class="emby-scroller" data-mousewheel="false" data-centerfocus="true" data-horizontal="true">
<div class="scrollerframe padded-top-focusscale padded-bottom-focusscale"> <div class="scrollerframe padded-top-focusscale padded-bottom-focusscale">
<div id="scenesContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer padded-left padded-right"></div> <div id="scenesContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
</div> </div>
</div> </div>
</div> </div>
@ -296,9 +287,8 @@
<h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderMoreLikeThis}</h2> <h2 class="sectionTitle sectionTitle-cards padded-left padded-right">${HeaderMoreLikeThis}</h2>
<div is="emby-scroller" class="emby-scroller" data-mousewheel="false" data-centerfocus="true" data-horizontal="true"> <div is="emby-scroller" class="emby-scroller" data-mousewheel="false" data-centerfocus="true" data-horizontal="true">
<div class="scrollerframe padded-top-focusscale padded-bottom-focusscale"> <div class="scrollerframe padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer padded-left padded-right similarContent"></div> <div is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer similarContent"></div>
</div> </div>
</div> </div>
</div> </div>