';
@@ -151,7 +156,7 @@ define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader
html += '';
html += '
';
if (enableScrollX()) {
- var scrollXClass = 'scrollX hiddenScrollX';
+ let scrollXClass = 'scrollX hiddenScrollX';
if (layoutManager.tv) {
scrollXClass += 'smoothScrollX padded-top-focusscale padded-bottom-focusscale';
@@ -182,37 +187,37 @@ define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader
});
}
- function fullyReload() {
- self.preRender();
- self.renderTab();
- }
+ const fullyReload = () => {
+ this.preRender();
+ this.renderTab();
+ };
- var self = this;
- var data = {};
+ const data = {};
- self.getViewStyles = function () {
+ this.getViewStyles = function () {
return 'Poster,PosterCard,Thumb,ThumbCard'.split(',');
};
- self.getCurrentViewStyle = function () {
+ this.getCurrentViewStyle = function () {
return getPageData().view;
};
- self.setCurrentViewStyle = function (viewStyle) {
+ this.setCurrentViewStyle = function (viewStyle) {
getPageData().view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
fullyReload();
};
- self.enableViewSelection = true;
- var promise;
+ this.enableViewSelection = true;
+ let promise;
- self.preRender = function () {
+ this.preRender = function () {
promise = getPromise();
};
- self.renderTab = function () {
+ this.renderTab = function () {
reloadItems(tabContent, promise);
};
- };
-});
+ }
+
+/* eslint-enable indent */
diff --git a/src/movies.html b/src/controllers/movies/movies.html
similarity index 100%
rename from src/movies.html
rename to src/controllers/movies/movies.html
diff --git a/src/controllers/movies/movies.js b/src/controllers/movies/movies.js
index ade9dc4b89..91b428ec68 100644
--- a/src/controllers/movies/movies.js
+++ b/src/controllers/movies/movies.js
@@ -1,12 +1,18 @@
-define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser', 'alphaPicker', 'listView', 'cardBuilder', 'globalize', 'emby-itemscontainer'], function (loading, layoutManager, userSettings, events, libraryBrowser, AlphaPicker, listView, cardBuilder, globalize) {
- 'use strict';
+import loading from 'loading';
+import * as userSettings from 'userSettings';
+import events from 'events';
+import libraryBrowser from 'libraryBrowser';
+import AlphaPicker from 'alphaPicker';
+import listView from 'listView';
+import cardBuilder from 'cardBuilder';
+import globalize from 'globalize';
+import 'emby-itemscontainer';
- loading = loading.default || loading;
- libraryBrowser = libraryBrowser.default || libraryBrowser;
+/* eslint-disable indent */
- return function (view, params, tabContent, options) {
- function onViewStyleChange() {
- if (self.getCurrentViewStyle() == 'List') {
+ export default function (view, params, tabContent, options) {
+ const onViewStyleChange = () => {
+ if (this.getCurrentViewStyle() == 'List') {
itemsContainer.classList.add('vertical-list');
itemsContainer.classList.remove('vertical-wrap');
} else {
@@ -15,13 +21,13 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser',
}
itemsContainer.innerHTML = '';
- }
+ };
- function updateFilterControls() {
- if (self.alphaPicker) {
- self.alphaPicker.value(query.NameStartsWithOrGreater);
+ const updateFilterControls = () => {
+ if (this.alphaPicker) {
+ this.alphaPicker.value(query.NameStartsWithOrGreater);
}
- }
+ };
function fetchData() {
isLoading = true;
@@ -54,7 +60,7 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser',
window.scrollTo(0, 0);
updateFilterControls();
- var pagingHtml = libraryBrowser.getQueryPagingHtml({
+ const pagingHtml = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
@@ -64,35 +70,30 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser',
sortButton: false,
filterButton: false
});
- var i;
- var length;
- var elems = tabContent.querySelectorAll('.paging');
- for (i = 0, length = elems.length; i < length; i++) {
- elems[i].innerHTML = pagingHtml;
+ for (const elem of tabContent.querySelectorAll('.paging')) {
+ elem.innerHTML = pagingHtml;
}
- elems = tabContent.querySelectorAll('.btnNextPage');
- for (i = 0, length = elems.length; i < length; i++) {
- elems[i].addEventListener('click', onNextPageClick);
+ for (const elem of tabContent.querySelectorAll('.btnNextPage')) {
+ elem.addEventListener('click', onNextPageClick);
}
- elems = tabContent.querySelectorAll('.btnPreviousPage');
- for (i = 0, length = elems.length; i < length; i++) {
- elems[i].addEventListener('click', onPreviousPageClick);
+ for (const elem of tabContent.querySelectorAll('.btnPreviousPage')) {
+ elem.addEventListener('click', onPreviousPageClick);
}
isLoading = false;
loading.hide();
- require(['autoFocuser'], function (autoFocuser) {
+ import('autoFocuser').then(({default: autoFocuser}) => {
autoFocuser.autoFocus(tabContent);
});
}
- function getItemsHtml(items) {
- var html;
- var viewStyle = self.getCurrentViewStyle();
+ const getItemsHtml = (items) => {
+ let html;
+ const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'Thumb') {
html = cardBuilder.getCardsHtml({
@@ -156,22 +157,22 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser',
}
return html;
- }
+ };
- function initPage(tabContent) {
+ const initPage = (tabContent) => {
itemsContainer.fetchData = fetchData;
itemsContainer.getItemsHtml = getItemsHtml;
itemsContainer.afterRefresh = afterRefresh;
- var alphaPickerElement = tabContent.querySelector('.alphaPicker');
+ let alphaPickerElement = tabContent.querySelector('.alphaPicker');
if (alphaPickerElement) {
alphaPickerElement.addEventListener('alphavaluechanged', function (e) {
- var newValue = e.detail.value;
+ let newValue = e.detail.value;
query.NameStartsWithOrGreater = newValue;
query.StartIndex = 0;
itemsContainer.refreshItems();
});
- self.alphaPicker = new AlphaPicker.default({
+ this.alphaPicker = new AlphaPicker({
element: alphaPickerElement,
valueChangeEvent: 'click'
});
@@ -181,14 +182,14 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser',
itemsContainer.classList.add('padded-right-withalphapicker');
}
- var btnFilter = tabContent.querySelector('.btnFilter');
+ const btnFilter = tabContent.querySelector('.btnFilter');
if (btnFilter) {
- btnFilter.addEventListener('click', function () {
- self.showFilterMenu();
+ btnFilter.addEventListener('click', () => {
+ this.showFilterMenu();
});
}
- var btnSort = tabContent.querySelector('.btnSort');
+ const btnSort = tabContent.querySelector('.btnSort');
if (btnSort) {
btnSort.addEventListener('click', function (e) {
@@ -231,24 +232,23 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser',
});
});
}
- var btnSelectView = tabContent.querySelector('.btnSelectView');
+ const btnSelectView = tabContent.querySelector('.btnSelectView');
btnSelectView.addEventListener('click', function (e) {
- libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), 'Banner,List,Poster,PosterCard,Thumb,ThumbCard'.split(','));
+ libraryBrowser.showLayoutMenu(e.target, this.getCurrentViewStyle, 'Banner,List,Poster,PosterCard,Thumb,ThumbCard'.split(','));
});
btnSelectView.addEventListener('layoutchange', function (e) {
- var viewStyle = e.detail.viewStyle;
+ let viewStyle = e.detail.viewStyle;
userSettings.set(savedViewKey, viewStyle);
query.StartIndex = 0;
onViewStyleChange();
itemsContainer.refreshItems();
});
- }
+ };
- var self = this;
- var itemsContainer = tabContent.querySelector('.itemsContainer');
- var savedQueryKey = params.topParentId + '-' + options.mode;
- var savedViewKey = savedQueryKey + '-view';
- var query = {
+ let itemsContainer = tabContent.querySelector('.itemsContainer');
+ const savedQueryKey = params.topParentId + '-' + options.mode;
+ const savedViewKey = savedQueryKey + '-view';
+ let query = {
SortBy: 'SortName,ProductionYear',
SortOrder: 'Ascending',
IncludeItemTypes: 'Movie',
@@ -264,7 +264,7 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser',
query['Limit'] = userSettings.libraryPageSize();
}
- var isLoading = false;
+ let isLoading = false;
if (options.mode === 'favorites') {
query.IsFavorite = true;
@@ -272,14 +272,14 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser',
query = userSettings.loadQuerySettings(savedQueryKey, query);
- self.showFilterMenu = function () {
- require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) {
- var filterDialog = new filterDialogFactory({
+ this.showFilterMenu = function () {
+ import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => {
+ let filterDialog = new filterDialogFactory({
query: query,
mode: 'movies',
serverId: ApiClient.serverId()
});
- events.on(filterDialog, 'filterchange', function () {
+ events.on(filterDialog, 'filterchange', () => {
query.StartIndex = 0;
itemsContainer.refreshItems();
});
@@ -287,22 +287,23 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser',
});
};
- self.getCurrentViewStyle = function () {
+ this.getCurrentViewStyle = function () {
return userSettings.get(savedViewKey) || 'Poster';
};
- self.initTab = function () {
+ this.initTab = function () {
initPage(tabContent);
onViewStyleChange();
};
- self.renderTab = function () {
+ this.renderTab = function () {
itemsContainer.refreshItems();
updateFilterControls();
};
- self.destroy = function () {
+ this.destroy = function () {
itemsContainer = null;
};
- };
-});
+ }
+
+/* eslint-enable indent */
diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js
index a633d654cd..91163c3412 100644
--- a/src/controllers/movies/moviesrecommended.js
+++ b/src/controllers/movies/moviesrecommended.js
@@ -1,7 +1,20 @@
-define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu', 'mainTabsManager', 'cardBuilder', 'dom', 'imageLoader', 'playbackManager', 'globalize', 'emby-scroller', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager, globalize) {
- 'use strict';
+import events from 'events';
+import layoutManager from 'layoutManager';
+import inputManager from 'inputManager';
+import * as userSettings from 'userSettings';
+import libraryMenu from 'libraryMenu';
+import * as mainTabsManager from 'mainTabsManager';
+import cardBuilder from 'cardBuilder';
+import dom from 'dom';
+import imageLoader from 'imageLoader';
+import playbackManager from 'playbackManager';
+import globalize from 'globalize';
+import 'emby-scroller';
+import 'emby-itemscontainer';
+import 'emby-tabs';
+import 'emby-button';
- playbackManager = playbackManager.default || playbackManager;
+/* eslint-disable indent */
function enableScrollX() {
return !layoutManager.desktop;
@@ -16,7 +29,7 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
}
function loadLatest(page, userId, parentId) {
- var options = {
+ const options = {
IncludeItemTypes: 'Movie',
Limit: 18,
Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo',
@@ -26,8 +39,8 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
EnableTotalRecordCount: false
};
ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)).then(function (items) {
- var allowBottomPadding = !enableScrollX();
- var container = page.querySelector('#recentlyAddedItems');
+ const allowBottomPadding = !enableScrollX();
+ const container = page.querySelector('#recentlyAddedItems');
cardBuilder.buildCards(items, {
itemsContainer: container,
shape: getPortraitShape(),
@@ -45,8 +58,8 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
}
function loadResume(page, userId, parentId) {
- var screenWidth = dom.getWindowSize().innerWidth;
- var options = {
+ let screenWidth = dom.getWindowSize().innerWidth;
+ const options = {
SortBy: 'DatePlayed',
SortOrder: 'Descending',
IncludeItemTypes: 'Movie',
@@ -67,8 +80,8 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
page.querySelector('#resumableSection').classList.add('hide');
}
- var allowBottomPadding = !enableScrollX();
- var container = page.querySelector('#resumableItems');
+ const allowBottomPadding = !enableScrollX();
+ const container = page.querySelector('#resumableItems');
cardBuilder.buildCards(result.Items, {
itemsContainer: container,
preferThumb: true,
@@ -88,8 +101,8 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
}
function getRecommendationHtml(recommendation) {
- var html = '';
- var title = '';
+ let html = '';
+ let title = '';
switch (recommendation.RecommendationType) {
case 'SimilarToRecentlyPlayed':
@@ -113,7 +126,7 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
html += '
';
html += '
' + title + '
';
- var allowBottomPadding = true;
+ const allowBottomPadding = true;
if (enableScrollX()) {
html += '
';
@@ -141,8 +154,8 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
}
function loadSuggestions(page, userId, parentId) {
- var screenWidth = dom.getWindowSize().innerWidth;
- var url = ApiClient.getUrl('Movies/Recommendations', {
+ let screenWidth = dom.getWindowSize().innerWidth;
+ let url = ApiClient.getUrl('Movies/Recommendations', {
userId: userId,
categoryLimit: 6,
ItemLimit: screenWidth >= 1920 ? 8 : screenWidth >= 1600 ? 8 : screenWidth >= 1200 ? 6 : 5,
@@ -157,9 +170,9 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
return;
}
- var html = recommendations.map(getRecommendationHtml).join('');
+ const html = recommendations.map(getRecommendationHtml).join('');
page.querySelector('.noItemsMessage').classList.add('hide');
- var recs = page.querySelector('.recommendations');
+ let recs = page.querySelector('.recommendations');
recs.innerHTML = html;
imageLoader.lazyChildren(recs);
@@ -169,7 +182,7 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
}
function autoFocus(page) {
- require(['autoFocuser'], function (autoFocuser) {
+ import('autoFocuser').then(({default: autoFocuser}) => {
autoFocuser.autoFocus(page);
});
}
@@ -195,17 +208,16 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
}
function initSuggestedTab(page, tabContent) {
- var containers = tabContent.querySelectorAll('.itemsContainer');
+ const containers = tabContent.querySelectorAll('.itemsContainer');
- for (var i = 0, length = containers.length; i < length; i++) {
- setScrollClasses(containers[i], enableScrollX());
+ for (const container of containers) {
+ setScrollClasses(container, enableScrollX());
}
}
function loadSuggestionsTab(view, params, tabContent) {
- var parentId = params.topParentId;
- var userId = ApiClient.getCurrentUserId();
- console.debug('loadSuggestionsTab');
+ const parentId = params.topParentId;
+ const userId = ApiClient.getCurrentUserId();
loadResume(tabContent, userId, parentId);
loadLatest(tabContent, userId, parentId);
loadSuggestions(tabContent, userId, parentId);
@@ -224,9 +236,6 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
name: globalize.translate('TabCollections')
}, {
name: globalize.translate('TabGenres')
- }, {
- name: globalize.translate('ButtonSearch'),
- cssClass: 'searchTabButton'
}];
}
@@ -249,13 +258,13 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
}
}
- return function (view, params) {
+ export default function (view, params) {
function onBeforeTabChange(e) {
preLoadTab(view, parseInt(e.detail.selectedTabIndex));
}
function onTabChange(e) {
- var newIndex = parseInt(e.detail.selectedTabIndex);
+ const newIndex = parseInt(e.detail.selectedTabIndex);
loadTab(view, newIndex);
}
@@ -267,52 +276,50 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange);
}
- function getTabController(page, index, callback) {
- var depends = [];
+ const getTabController = (page, index, callback) => {
+ let depends = '';
switch (index) {
case 0:
- depends.push('controllers/movies/movies');
+ depends = 'controllers/movies/movies';
break;
case 1:
+ depends = 'controllers/movies/moviesrecommended.js';
break;
case 2:
- depends.push('controllers/movies/movietrailers');
+ depends = 'controllers/movies/movietrailers';
break;
case 3:
- depends.push('controllers/movies/movies');
+ depends = 'controllers/movies/movies';
break;
case 4:
- depends.push('controllers/movies/moviecollections');
+ depends = 'controllers/movies/moviecollections';
break;
case 5:
- depends.push('controllers/movies/moviegenres');
+ depends = 'controllers/movies/moviegenres';
break;
-
- case 6:
- depends.push('scripts/searchtab');
}
- require(depends, function (controllerFactory) {
- var tabContent;
+ import(depends).then(({default: controllerFactory}) => {
+ let tabContent;
if (index === suggestionsTabIndex) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
- self.tabContent = tabContent;
+ this.tabContent = tabContent;
}
- var controller = tabControllers[index];
+ let controller = tabControllers[index];
if (!controller) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
if (index === suggestionsTabIndex) {
- controller = self;
+ controller = this;
} else if (index === 6) {
controller = new controllerFactory(view, tabContent, {
collectionType: 'movies',
@@ -335,7 +342,7 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
callback(controller);
});
- }
+ };
function preLoadTab(page, index) {
getTabController(page, index, function (controller) {
@@ -347,12 +354,12 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
function loadTab(page, index) {
currentTabIndex = index;
- getTabController(page, index, function (controller) {
+ getTabController(page, index, ((controller) => {
if (renderedTabs.indexOf(index) == -1) {
renderedTabs.push(index);
controller.renderTab();
}
- });
+ }));
}
function onPlaybackStop(e, state) {
@@ -370,22 +377,21 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
}
}
- var self = this;
- var currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId));
- var suggestionsTabIndex = 1;
+ let currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId));
+ const suggestionsTabIndex = 1;
- self.initTab = function () {
- var tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
+ this.initTab = function () {
+ let tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
initSuggestedTab(view, tabContent);
};
- self.renderTab = function () {
- var tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
+ this.renderTab = function () {
+ let tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
loadSuggestionsTab(view, params, tabContent);
};
- var tabControllers = [];
- var renderedTabs = [];
+ let tabControllers = [];
+ let renderedTabs = [];
view.addEventListener('viewshow', function (e) {
initTabs();
if (!view.getAttribute('data-title')) {
@@ -405,15 +411,14 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu'
events.on(playbackManager, 'playbackstop', onPlaybackStop);
inputManager.on(window, onInputCommand);
});
- view.addEventListener('viewbeforehide', function (e) {
+ view.addEventListener('viewbeforehide', function () {
inputManager.off(window, onInputCommand);
});
- view.addEventListener('viewdestroy', function (e) {
- tabControllers.forEach(function (t) {
- if (t.destroy) {
- t.destroy();
- }
- });
- });
- };
-});
+ for (const tabController of tabControllers) {
+ if (tabController.destroy) {
+ tabController.destroy();
+ }
+ }
+ }
+
+/* eslint-enable indent */
diff --git a/src/controllers/movies/movietrailers.js b/src/controllers/movies/movietrailers.js
index 8d9fe8d090..5f1aa1fe62 100644
--- a/src/controllers/movies/movietrailers.js
+++ b/src/controllers/movies/movietrailers.js
@@ -1,13 +1,20 @@
-define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (layoutManager, loading, events, libraryBrowser, imageLoader, AlphaPicker, listView, cardBuilder, userSettings, globalize) {
- 'use strict';
+import loading from 'loading';
+import events from 'events';
+import libraryBrowser from 'libraryBrowser';
+import imageLoader from 'imageLoader';
+import AlphaPicker from 'alphaPicker';
+import listView from 'listView';
+import cardBuilder from 'cardBuilder';
+import * as userSettings from 'userSettings';
+import globalize from 'globalize';
+import 'emby-itemscontainer';
- loading = loading.default || loading;
- libraryBrowser = libraryBrowser.default || libraryBrowser;
+/* eslint-disable indent */
- return function (view, params, tabContent) {
+ export default function (view, params, tabContent) {
function getPageData(context) {
- var key = getSavedQueryKey(context);
- var pageData = data[key];
+ const key = getSavedQueryKey(context);
+ let pageData = data[key];
if (!pageData) {
pageData = data[key] = {
@@ -46,11 +53,11 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
return context.savedQueryKey;
}
- function reloadItems() {
+ const reloadItems = () => {
loading.show();
isLoading = true;
- var query = getQuery(tabContent);
- ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) {
+ const query = getQuery(tabContent);
+ ApiClient.getItems(ApiClient.getCurrentUserId(), query).then((result) => {
function onNextPageClick() {
if (isLoading) {
return;
@@ -75,7 +82,7 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
window.scrollTo(0, 0);
updateFilterControls(tabContent);
- var pagingHtml = libraryBrowser.getQueryPagingHtml({
+ const pagingHtml = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
@@ -85,8 +92,8 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
sortButton: false,
filterButton: false
});
- var html;
- var viewStyle = self.getCurrentViewStyle();
+ let html;
+ const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'Thumb') {
html = cardBuilder.getCardsHtml({
@@ -142,22 +149,20 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
});
}
- var i;
- var length;
- var elems = tabContent.querySelectorAll('.paging');
+ let elems = tabContent.querySelectorAll('.paging');
- for (i = 0, length = elems.length; i < length; i++) {
- elems[i].innerHTML = pagingHtml;
+ for (const elem of elems) {
+ elem.innerHTML = pagingHtml;
}
elems = tabContent.querySelectorAll('.btnNextPage');
- for (i = 0, length = elems.length; i < length; i++) {
- elems[i].addEventListener('click', onNextPageClick);
+ for (const elem of elems) {
+ elem.addEventListener('click', onNextPageClick);
}
elems = tabContent.querySelectorAll('.btnPreviousPage');
- for (i = 0, length = elems.length; i < length; i++) {
- elems[i].addEventListener('click', onPreviousPageClick);
+ for (const elem of elems) {
+ elem.addEventListener('click', onPreviousPageClick);
}
if (!result.Items.length) {
@@ -169,27 +174,26 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
html += '
';
}
- var itemsContainer = tabContent.querySelector('.itemsContainer');
+ const itemsContainer = tabContent.querySelector('.itemsContainer');
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(tabContent), query);
loading.hide();
isLoading = false;
});
- }
+ };
- function updateFilterControls(tabContent) {
- var query = getQuery(tabContent);
- self.alphaPicker.value(query.NameStartsWithOrGreater);
- }
+ const updateFilterControls = (tabContent) => {
+ const query = getQuery(tabContent);
+ this.alphaPicker.value(query.NameStartsWithOrGreater);
+ };
- var self = this;
- var data = {};
- var isLoading = false;
+ const data = {};
+ let isLoading = false;
- self.showFilterMenu = function () {
- require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) {
- var filterDialog = new filterDialogFactory({
+ this.showFilterMenu = function () {
+ import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => {
+ const filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: 'movies',
serverId: ApiClient.serverId()
@@ -202,21 +206,21 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
});
};
- self.getCurrentViewStyle = function () {
+ this.getCurrentViewStyle = function () {
return getPageData(tabContent).view;
};
- function initPage(tabContent) {
- var alphaPickerElement = tabContent.querySelector('.alphaPicker');
- var itemsContainer = tabContent.querySelector('.itemsContainer');
+ const initPage = (tabContent) => {
+ const alphaPickerElement = tabContent.querySelector('.alphaPicker');
+ const itemsContainer = tabContent.querySelector('.itemsContainer');
alphaPickerElement.addEventListener('alphavaluechanged', function (e) {
- var newValue = e.detail.value;
- var query = getQuery(tabContent);
+ const newValue = e.detail.value;
+ const query = getQuery(tabContent);
query.NameStartsWithOrGreater = newValue;
query.StartIndex = 0;
reloadItems();
});
- self.alphaPicker = new AlphaPicker.default({
+ this.alphaPicker = new AlphaPicker({
element: alphaPickerElement,
valueChangeEvent: 'click'
});
@@ -226,7 +230,7 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
itemsContainer.classList.add('padded-right-withalphapicker');
tabContent.querySelector('.btnFilter').addEventListener('click', function () {
- self.showFilterMenu();
+ this.showFilterMenu();
});
tabContent.querySelector('.btnSort').addEventListener('click', function (e) {
libraryBrowser.showSortMenu({
@@ -260,15 +264,16 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
button: e.target
});
});
- }
+ };
initPage(tabContent);
- self.renderTab = function () {
+ this.renderTab = function () {
reloadItems();
updateFilterControls(tabContent);
};
- self.destroy = function () {};
- };
-});
+ this.destroy = function () {};
+ }
+
+/* eslint-enable indent */
diff --git a/src/music.html b/src/controllers/music/music.html
similarity index 100%
rename from src/music.html
rename to src/controllers/music/music.html
diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js
index db7dac9547..9bc449e2a2 100644
--- a/src/controllers/music/musicrecommended.js
+++ b/src/controllers/music/musicrecommended.js
@@ -191,9 +191,6 @@ import 'flexStyles';
name: globalize.translate('TabSongs')
}, {
name: globalize.translate('TabGenres')
- }, {
- name: globalize.translate('ButtonSearch'),
- cssClass: 'searchTabButton'
}];
}
@@ -295,10 +292,6 @@ import 'flexStyles';
case 6:
depends = 'controllers/music/musicgenres';
break;
-
- case 7:
- depends = 'scripts/searchtab';
- break;
}
import(depends).then(({default: controllerFactory}) => {
diff --git a/src/search.html b/src/controllers/search.html
similarity index 100%
rename from src/search.html
rename to src/controllers/search.html
diff --git a/src/tv.html b/src/controllers/shows/tvrecommended.html
similarity index 100%
rename from src/tv.html
rename to src/controllers/shows/tvrecommended.html
diff --git a/src/controllers/shows/tvrecommended.js b/src/controllers/shows/tvrecommended.js
index 4aab69e978..585449d0c0 100644
--- a/src/controllers/shows/tvrecommended.js
+++ b/src/controllers/shows/tvrecommended.js
@@ -30,9 +30,6 @@ import 'emby-button';
name: globalize.translate('TabNetworks')
}, {
name: globalize.translate('TabEpisodes')
- }, {
- name: globalize.translate('ButtonSearch'),
- cssClass: 'searchTabButton'
}];
}
@@ -217,10 +214,6 @@ import 'emby-button';
case 6:
depends = 'controllers/shows/episodes';
break;
-
- case 7:
- depends = 'scripts/searchtab';
- break;
}
import(depends).then(({default: controllerFactory}) => {
diff --git a/src/wizardlibrary.html b/src/controllers/wizard/library.html
similarity index 100%
rename from src/wizardlibrary.html
rename to src/controllers/wizard/library.html
diff --git a/src/elements/emby-slider/emby-slider.css b/src/elements/emby-slider/emby-slider.css
index 7661895f15..01221b6cae 100644
--- a/src/elements/emby-slider/emby-slider.css
+++ b/src/elements/emby-slider/emby-slider.css
@@ -230,3 +230,18 @@
margin: 0;
padding: 0.5em 0.75em;
}
+
+/* FIXME: 'sliderContainer' is used to wrap slider's pieces */
+.sliderContainer-settings {
+ margin-bottom: 1.8em;
+ position: relative;
+}
+
+.sliderContainer-settings .mdl-slider-container {
+ height: 2.83em; /* similar to emby-input with its 110% font-size */
+}
+
+.sliderLabel {
+ display: block;
+ margin-bottom: 0.25em;
+}
diff --git a/src/elements/emby-slider/emby-slider.js b/src/elements/emby-slider/emby-slider.js
index 2439331144..b39e24f5e4 100644
--- a/src/elements/emby-slider/emby-slider.js
+++ b/src/elements/emby-slider/emby-slider.js
@@ -150,6 +150,16 @@ import 'emby-input';
this.classList.add('show-focus');
}
+ const topContainer = dom.parentWithClass(this, 'sliderContainer-settings');
+
+ if (topContainer && this.getAttribute('label')) {
+ const label = this.ownerDocument.createElement('label');
+ label.innerHTML = this.getAttribute('label');
+ label.classList.add('sliderLabel');
+ label.htmlFor = this.id;
+ topContainer.insertBefore(label, topContainer.firstChild);
+ }
+
const containerElement = this.parentNode;
containerElement.classList.add('mdl-slider-container');
diff --git a/src/index.html b/src/index.html
index 797fce8a94..c689a42f30 100644
--- a/src/index.html
+++ b/src/index.html
@@ -137,8 +137,7 @@
}
@media screen
- and (min-device-width: 992px)
- and (-webkit-min-device-pixel-ratio: 1) {
+ and (min-device-width: 992px) {
.splashLogo {
background-image: url(assets/img/banner-light.png);
}
diff --git a/src/libraries/navdrawer/navdrawer.js b/src/libraries/navdrawer/navdrawer.js
index 4733c617f3..965b68aee4 100644
--- a/src/libraries/navdrawer/navdrawer.js
+++ b/src/libraries/navdrawer/navdrawer.js
@@ -1,354 +1,357 @@
-define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, dom) {
- "use strict";
+/* Cleaning this file properly is not neecessary, since it's an outdated library
+ * and will be replaced soon by a Vue component.
+ */
- browser = browser.default || browser;
+import browser from 'browser';
+import dom from 'dom';
+import 'css!./navdrawer';
+import 'scrollStyles';
- return function (options) {
- function getTouches(e) {
- return e.changedTouches || e.targetTouches || e.touches;
+export default function (options) {
+ function getTouches(e) {
+ return e.changedTouches || e.targetTouches || e.touches;
+ }
+
+ function onMenuTouchStart(e) {
+ options.target.classList.remove('transition');
+ var touches = getTouches(e);
+ var touch = touches[0] || {};
+ menuTouchStartX = touch.clientX;
+ menuTouchStartY = touch.clientY;
+ menuTouchStartTime = new Date().getTime();
+ }
+
+ function setVelocity(deltaX) {
+ var time = new Date().getTime() - (menuTouchStartTime || 0);
+ velocity = Math.abs(deltaX) / time;
+ }
+
+ function onMenuTouchMove(e) {
+ var isOpen = self.visible;
+ var touches = getTouches(e);
+ var touch = touches[0] || {};
+ var endX = touch.clientX || 0;
+ var endY = touch.clientY || 0;
+ var deltaX = endX - (menuTouchStartX || 0);
+ var deltaY = endY - (menuTouchStartY || 0);
+ setVelocity(deltaX);
+
+ if (isOpen && dragMode !== 1 && deltaX > 0) {
+ dragMode = 2;
}
- function onMenuTouchStart(e) {
- options.target.classList.remove("transition");
- var touches = getTouches(e);
- var touch = touches[0] || {};
- menuTouchStartX = touch.clientX;
- menuTouchStartY = touch.clientY;
- menuTouchStartTime = new Date().getTime();
+ if (dragMode === 0 && (!isOpen || Math.abs(deltaX) >= 10) && Math.abs(deltaY) < 5) {
+ dragMode = 1;
+ scrollContainer.addEventListener('scroll', disableEvent);
+ self.showMask();
+ } else if (dragMode === 0 && Math.abs(deltaY) >= 5) {
+ dragMode = 2;
}
- function setVelocity(deltaX) {
- var time = new Date().getTime() - (menuTouchStartTime || 0);
- velocity = Math.abs(deltaX) / time;
+ if (dragMode === 1) {
+ newPos = currentPos + deltaX;
+ self.changeMenuPos();
}
+ }
- function onMenuTouchMove(e) {
- var isOpen = self.visible;
- var touches = getTouches(e);
- var touch = touches[0] || {};
- var endX = touch.clientX || 0;
- var endY = touch.clientY || 0;
- var deltaX = endX - (menuTouchStartX || 0);
- var deltaY = endY - (menuTouchStartY || 0);
- setVelocity(deltaX);
+ function onMenuTouchEnd(e) {
+ options.target.classList.add('transition');
+ scrollContainer.removeEventListener('scroll', disableEvent);
+ dragMode = 0;
+ var touches = getTouches(e);
+ var touch = touches[0] || {};
+ var endX = touch.clientX || 0;
+ var endY = touch.clientY || 0;
+ var deltaX = endX - (menuTouchStartX || 0);
+ var deltaY = endY - (menuTouchStartY || 0);
+ currentPos = deltaX;
+ self.checkMenuState(deltaX, deltaY);
+ }
- if (isOpen && 1 !== dragMode && deltaX > 0) {
- dragMode = 2;
- }
+ function onEdgeTouchStart(e) {
+ if (isPeeking) {
+ onMenuTouchMove(e);
+ } else {
+ if (((getTouches(e)[0] || {}).clientX || 0) <= options.handleSize) {
+ isPeeking = true;
- if (0 === dragMode && (!isOpen || Math.abs(deltaX) >= 10) && Math.abs(deltaY) < 5) {
- dragMode = 1;
- scrollContainer.addEventListener("scroll", disableEvent);
- self.showMask();
- } else if (0 === dragMode && Math.abs(deltaY) >= 5) {
- dragMode = 2;
- }
-
- if (1 === dragMode) {
- newPos = currentPos + deltaX;
- self.changeMenuPos();
- }
- }
-
- function onMenuTouchEnd(e) {
- options.target.classList.add("transition");
- scrollContainer.removeEventListener("scroll", disableEvent);
- dragMode = 0;
- var touches = getTouches(e);
- var touch = touches[0] || {};
- var endX = touch.clientX || 0;
- var endY = touch.clientY || 0;
- var deltaX = endX - (menuTouchStartX || 0);
- var deltaY = endY - (menuTouchStartY || 0);
- currentPos = deltaX;
- self.checkMenuState(deltaX, deltaY);
- }
-
- function onEdgeTouchStart(e) {
- if (isPeeking) {
- onMenuTouchMove(e);
- } else {
- if (((getTouches(e)[0] || {}).clientX || 0) <= options.handleSize) {
- isPeeking = true;
-
- if (e.type === "touchstart") {
- dom.removeEventListener(edgeContainer, "touchmove", onEdgeTouchMove, {});
- dom.addEventListener(edgeContainer, "touchmove", onEdgeTouchMove, {});
- }
-
- onMenuTouchStart(e);
+ if (e.type === 'touchstart') {
+ dom.removeEventListener(edgeContainer, 'touchmove', onEdgeTouchMove, {});
+ dom.addEventListener(edgeContainer, 'touchmove', onEdgeTouchMove, {});
}
+
+ onMenuTouchStart(e);
}
}
+ }
- function onEdgeTouchMove(e) {
- e.preventDefault();
- e.stopPropagation();
- onEdgeTouchStart(e);
+ function onEdgeTouchMove(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ onEdgeTouchStart(e);
+ }
+
+ function onEdgeTouchEnd(e) {
+ if (isPeeking) {
+ isPeeking = false;
+ dom.removeEventListener(edgeContainer, 'touchmove', onEdgeTouchMove, {});
+ onMenuTouchEnd(e);
}
+ }
- function onEdgeTouchEnd(e) {
- if (isPeeking) {
- isPeeking = false;
- dom.removeEventListener(edgeContainer, "touchmove", onEdgeTouchMove, {});
- onMenuTouchEnd(e);
- }
- }
+ function disableEvent(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
- function disableEvent(e) {
- e.preventDefault();
- e.stopPropagation();
- }
+ function onBackgroundTouchStart(e) {
+ var touches = getTouches(e);
+ var touch = touches[0] || {};
+ backgroundTouchStartX = touch.clientX;
+ backgroundTouchStartTime = new Date().getTime();
+ }
- function onBackgroundTouchStart(e) {
- var touches = getTouches(e);
- var touch = touches[0] || {};
- backgroundTouchStartX = touch.clientX;
- backgroundTouchStartTime = new Date().getTime();
- }
+ function onBackgroundTouchMove(e) {
+ var touches = getTouches(e);
+ var touch = touches[0] || {};
+ var endX = touch.clientX || 0;
- function onBackgroundTouchMove(e) {
- var touches = getTouches(e);
- var touch = touches[0] || {};
- var endX = touch.clientX || 0;
-
- if (endX <= options.width && self.isVisible) {
- countStart++;
- var deltaX = endX - (backgroundTouchStartX || 0);
-
- if (countStart == 1) {
- startPoint = deltaX;
- }
- if (deltaX < 0 && dragMode !== 2) {
- dragMode = 1;
- newPos = deltaX - startPoint + options.width;
- self.changeMenuPos();
- var time = new Date().getTime() - (backgroundTouchStartTime || 0);
- velocity = Math.abs(deltaX) / time;
- }
- }
-
- e.preventDefault();
- e.stopPropagation();
- }
-
- function onBackgroundTouchEnd(e) {
- var touches = getTouches(e);
- var touch = touches[0] || {};
- var endX = touch.clientX || 0;
+ if (endX <= options.width && self.isVisible) {
+ countStart++;
var deltaX = endX - (backgroundTouchStartX || 0);
- self.checkMenuState(deltaX);
- countStart = 0;
- }
- function onMaskTransitionEnd() {
- var classList = mask.classList;
-
- if (!classList.contains("backdrop")) {
- classList.add("hide");
+ if (countStart == 1) {
+ startPoint = deltaX;
+ }
+ if (deltaX < 0 && dragMode !== 2) {
+ dragMode = 1;
+ newPos = deltaX - startPoint + options.width;
+ self.changeMenuPos();
+ var time = new Date().getTime() - (backgroundTouchStartTime || 0);
+ velocity = Math.abs(deltaX) / time;
}
}
- var self;
- var defaults;
- var mask;
- var newPos = 0;
- var currentPos = 0;
- var startPoint = 0;
- var countStart = 0;
- var velocity = 0;
- options.target.classList.add("transition");
- var dragMode = 0;
- var scrollContainer = options.target.querySelector(".mainDrawer-scrollContainer");
- scrollContainer.classList.add("scrollY");
+ e.preventDefault();
+ e.stopPropagation();
+ }
- var TouchMenuLA = function () {
- self = this;
- defaults = {
- width: 260,
- handleSize: 10,
- disableMask: false,
- maxMaskOpacity: 0.5
- };
- this.isVisible = false;
- this.initialize();
+ function onBackgroundTouchEnd(e) {
+ var touches = getTouches(e);
+ var touch = touches[0] || {};
+ var endX = touch.clientX || 0;
+ var deltaX = endX - (backgroundTouchStartX || 0);
+ self.checkMenuState(deltaX);
+ countStart = 0;
+ }
+
+ function onMaskTransitionEnd() {
+ var classList = mask.classList;
+
+ if (!classList.contains('backdrop')) {
+ classList.add('hide');
+ }
+ }
+
+ var self;
+ var defaults;
+ var mask;
+ var newPos = 0;
+ var currentPos = 0;
+ var startPoint = 0;
+ var countStart = 0;
+ var velocity = 0;
+ options.target.classList.add('transition');
+ var dragMode = 0;
+ var scrollContainer = options.target.querySelector('.mainDrawer-scrollContainer');
+ scrollContainer.classList.add('scrollY');
+
+ var TouchMenuLA = function () {
+ self = this;
+ defaults = {
+ width: 260,
+ handleSize: 10,
+ disableMask: false,
+ maxMaskOpacity: 0.5
};
+ this.isVisible = false;
+ this.initialize();
+ };
- TouchMenuLA.prototype.initElements = function () {
- options.target.classList.add("touch-menu-la");
- options.target.style.width = options.width + "px";
- options.target.style.left = -options.width + "px";
+ TouchMenuLA.prototype.initElements = function () {
+ options.target.classList.add('touch-menu-la');
+ options.target.style.width = options.width + 'px';
+ options.target.style.left = -options.width + 'px';
- if (!options.disableMask) {
- mask = document.createElement("div");
- mask.className = "tmla-mask hide";
- document.body.appendChild(mask);
- dom.addEventListener(mask, dom.whichTransitionEvent(), onMaskTransitionEnd, {
- passive: true
- });
- }
- };
-
- var menuTouchStartX;
- var menuTouchStartY;
- var menuTouchStartTime;
- var edgeContainer = document.querySelector(".mainDrawerHandle");
- var isPeeking = false;
-
- TouchMenuLA.prototype.animateToPosition = function (pos) {
- requestAnimationFrame(function () {
- options.target.style.transform = pos ? "translateX(" + pos + "px)" : "none";
+ if (!options.disableMask) {
+ mask = document.createElement('div');
+ mask.className = 'tmla-mask hide';
+ document.body.appendChild(mask);
+ dom.addEventListener(mask, dom.whichTransitionEvent(), onMaskTransitionEnd, {
+ passive: true
});
- };
+ }
+ };
- TouchMenuLA.prototype.changeMenuPos = function () {
- if (newPos <= options.width) {
- this.animateToPosition(newPos);
- }
- };
+ var menuTouchStartX;
+ var menuTouchStartY;
+ var menuTouchStartTime;
+ var edgeContainer = document.querySelector('.mainDrawerHandle');
+ var isPeeking = false;
- TouchMenuLA.prototype.clickMaskClose = function () {
- mask.addEventListener("click", function () {
+ TouchMenuLA.prototype.animateToPosition = function (pos) {
+ requestAnimationFrame(function () {
+ options.target.style.transform = pos ? 'translateX(' + pos + 'px)' : 'none';
+ });
+ };
+
+ TouchMenuLA.prototype.changeMenuPos = function () {
+ if (newPos <= options.width) {
+ this.animateToPosition(newPos);
+ }
+ };
+
+ TouchMenuLA.prototype.clickMaskClose = function () {
+ mask.addEventListener('click', function () {
+ self.close();
+ });
+ };
+
+ TouchMenuLA.prototype.checkMenuState = function (deltaX, deltaY) {
+ if (velocity >= 0.4) {
+ if (deltaX >= 0 || Math.abs(deltaY || 0) >= 70) {
+ self.open();
+ } else {
self.close();
- });
- };
-
- TouchMenuLA.prototype.checkMenuState = function (deltaX, deltaY) {
- if (velocity >= 0.4) {
- if (deltaX >= 0 || Math.abs(deltaY || 0) >= 70) {
- self.open();
- } else {
+ }
+ } else {
+ if (newPos >= 100) {
+ self.open();
+ } else {
+ if (newPos) {
self.close();
}
- } else {
- if (newPos >= 100) {
- self.open();
- } else {
- if (newPos) {
- self.close();
- }
- }
}
- };
-
- TouchMenuLA.prototype.open = function () {
- this.animateToPosition(options.width);
- currentPos = options.width;
- this.isVisible = true;
- options.target.classList.add("drawer-open");
- self.showMask();
- self.invoke(options.onChange);
- };
-
- TouchMenuLA.prototype.close = function () {
- this.animateToPosition(0);
- currentPos = 0;
- self.isVisible = false;
- options.target.classList.remove("drawer-open");
- self.hideMask();
- self.invoke(options.onChange);
- };
-
- TouchMenuLA.prototype.toggle = function () {
- if (self.isVisible) {
- self.close();
- } else {
- self.open();
- }
- };
-
- var backgroundTouchStartX;
- var backgroundTouchStartTime;
-
- TouchMenuLA.prototype.showMask = function () {
- mask.classList.remove("hide");
- mask.classList.add("backdrop");
- };
-
- TouchMenuLA.prototype.hideMask = function () {
- mask.classList.add("hide");
- mask.classList.remove("backdrop");
- };
-
- TouchMenuLA.prototype.invoke = function (fn) {
- if (fn) {
- fn.apply(self);
- }
- };
-
- var _edgeSwipeEnabled;
-
- TouchMenuLA.prototype.setEdgeSwipeEnabled = function (enabled) {
- if (!options.disableEdgeSwipe) {
- if (browser.touch) {
- if (enabled) {
- if (!_edgeSwipeEnabled) {
- _edgeSwipeEnabled = true;
- dom.addEventListener(edgeContainer, "touchstart", onEdgeTouchStart, {
- passive: true
- });
- dom.addEventListener(edgeContainer, "touchend", onEdgeTouchEnd, {
- passive: true
- });
- dom.addEventListener(edgeContainer, "touchcancel", onEdgeTouchEnd, {
- passive: true
- });
- }
- } else {
- if (_edgeSwipeEnabled) {
- _edgeSwipeEnabled = false;
- dom.removeEventListener(edgeContainer, "touchstart", onEdgeTouchStart, {
- passive: true
- });
- dom.removeEventListener(edgeContainer, "touchend", onEdgeTouchEnd, {
- passive: true
- });
- dom.removeEventListener(edgeContainer, "touchcancel", onEdgeTouchEnd, {
- passive: true
- });
- }
- }
- }
- }
- };
-
- TouchMenuLA.prototype.initialize = function () {
- options = Object.assign(defaults, options || {});
-
- if (browser.edge) {
- options.disableEdgeSwipe = true;
- }
-
- self.initElements();
-
- if (browser.touch) {
- dom.addEventListener(options.target, "touchstart", onMenuTouchStart, {
- passive: true
- });
- dom.addEventListener(options.target, "touchmove", onMenuTouchMove, {
- passive: true
- });
- dom.addEventListener(options.target, "touchend", onMenuTouchEnd, {
- passive: true
- });
- dom.addEventListener(options.target, "touchcancel", onMenuTouchEnd, {
- passive: true
- });
- dom.addEventListener(mask, "touchstart", onBackgroundTouchStart, {
- passive: true
- });
- dom.addEventListener(mask, "touchmove", onBackgroundTouchMove, {});
- dom.addEventListener(mask, "touchend", onBackgroundTouchEnd, {
- passive: true
- });
- dom.addEventListener(mask, "touchcancel", onBackgroundTouchEnd, {
- passive: true
- });
- }
-
- self.clickMaskClose();
- };
-
- return new TouchMenuLA();
+ }
};
-});
+
+ TouchMenuLA.prototype.open = function () {
+ this.animateToPosition(options.width);
+ currentPos = options.width;
+ this.isVisible = true;
+ options.target.classList.add('drawer-open');
+ self.showMask();
+ self.invoke(options.onChange);
+ };
+
+ TouchMenuLA.prototype.close = function () {
+ this.animateToPosition(0);
+ currentPos = 0;
+ self.isVisible = false;
+ options.target.classList.remove('drawer-open');
+ self.hideMask();
+ self.invoke(options.onChange);
+ };
+
+ TouchMenuLA.prototype.toggle = function () {
+ if (self.isVisible) {
+ self.close();
+ } else {
+ self.open();
+ }
+ };
+
+ var backgroundTouchStartX;
+ var backgroundTouchStartTime;
+
+ TouchMenuLA.prototype.showMask = function () {
+ mask.classList.remove('hide');
+ mask.classList.add('backdrop');
+ };
+
+ TouchMenuLA.prototype.hideMask = function () {
+ mask.classList.add('hide');
+ mask.classList.remove('backdrop');
+ };
+
+ TouchMenuLA.prototype.invoke = function (fn) {
+ if (fn) {
+ fn.apply(self);
+ }
+ };
+
+ var _edgeSwipeEnabled;
+
+ TouchMenuLA.prototype.setEdgeSwipeEnabled = function (enabled) {
+ if (!options.disableEdgeSwipe) {
+ if (browser.touch) {
+ if (enabled) {
+ if (!_edgeSwipeEnabled) {
+ _edgeSwipeEnabled = true;
+ dom.addEventListener(edgeContainer, 'touchstart', onEdgeTouchStart, {
+ passive: true
+ });
+ dom.addEventListener(edgeContainer, 'touchend', onEdgeTouchEnd, {
+ passive: true
+ });
+ dom.addEventListener(edgeContainer, 'touchcancel', onEdgeTouchEnd, {
+ passive: true
+ });
+ }
+ } else {
+ if (_edgeSwipeEnabled) {
+ _edgeSwipeEnabled = false;
+ dom.removeEventListener(edgeContainer, 'touchstart', onEdgeTouchStart, {
+ passive: true
+ });
+ dom.removeEventListener(edgeContainer, 'touchend', onEdgeTouchEnd, {
+ passive: true
+ });
+ dom.removeEventListener(edgeContainer, 'touchcancel', onEdgeTouchEnd, {
+ passive: true
+ });
+ }
+ }
+ }
+ }
+ };
+
+ TouchMenuLA.prototype.initialize = function () {
+ options = Object.assign(defaults, options || {});
+
+ if (browser.edge) {
+ options.disableEdgeSwipe = true;
+ }
+
+ self.initElements();
+
+ if (browser.touch) {
+ dom.addEventListener(options.target, 'touchstart', onMenuTouchStart, {
+ passive: true
+ });
+ dom.addEventListener(options.target, 'touchmove', onMenuTouchMove, {
+ passive: true
+ });
+ dom.addEventListener(options.target, 'touchend', onMenuTouchEnd, {
+ passive: true
+ });
+ dom.addEventListener(options.target, 'touchcancel', onMenuTouchEnd, {
+ passive: true
+ });
+ dom.addEventListener(mask, 'touchstart', onBackgroundTouchStart, {
+ passive: true
+ });
+ dom.addEventListener(mask, 'touchmove', onBackgroundTouchMove, {});
+ dom.addEventListener(mask, 'touchend', onBackgroundTouchEnd, {
+ passive: true
+ });
+ dom.addEventListener(mask, 'touchcancel', onBackgroundTouchEnd, {
+ passive: true
+ });
+ }
+
+ self.clickMaskClose();
+ };
+
+ return new TouchMenuLA();
+}
diff --git a/src/libraries/screensavermanager.js b/src/libraries/screensavermanager.js
index 557b31e0f4..5c24ec63d0 100644
--- a/src/libraries/screensavermanager.js
+++ b/src/libraries/screensavermanager.js
@@ -1,134 +1,128 @@
-define(["events", "playbackManager", "pluginManager", "inputManager", "connectionManager", "userSettings"], function (events, playbackManager, pluginManager, inputManager, connectionManager, userSettings) {
- "use strict";
+import events from 'events';
+import playbackManager from 'playbackManager';
+import pluginManager from 'pluginManager';
+import inputManager from 'inputManager';
+import connectionManager from 'connectionManager';
+import * as userSettings from 'userSettings';
- playbackManager = playbackManager.default || playbackManager;
+function getMinIdleTime() {
+ // Returns the minimum amount of idle time required before the screen saver can be displayed
+ //time units used Millisecond
+ return 180000;
+}
- function getMinIdleTime() {
- // Returns the minimum amount of idle time required before the screen saver can be displayed
- //time units used Millisecond
- return 180000;
+let lastFunctionalEvent = 0;
+
+function getFunctionalEventIdleTime() {
+ return new Date().getTime() - lastFunctionalEvent;
+}
+
+events.on(playbackManager, 'playbackstop', function (e, stopInfo) {
+ const state = stopInfo.state;
+ if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') {
+ lastFunctionalEvent = new Date().getTime();
}
-
- var lastFunctionalEvent = 0;
-
- function getFunctionalEventIdleTime() {
- return new Date().getTime() - lastFunctionalEvent;
- }
-
- events.on(playbackManager, "playbackstop", function (e, stopInfo) {
- var state = stopInfo.state;
- if (state.NowPlayingItem && state.NowPlayingItem.MediaType == "Video") {
- lastFunctionalEvent = new Date().getTime();
- }
- });
-
- function getScreensaverPlugin(isLoggedIn) {
-
- var option;
- try {
- option = userSettings.get("screensaver", false);
- } catch (err) {
- option = isLoggedIn ? "backdropscreensaver" : "logoscreensaver";
- }
-
- var plugins = pluginManager.ofType("screensaver");
-
- for (var i = 0, length = plugins.length; i < length; i++) {
- var plugin = plugins[i];
-
- if (plugin.id === option) {
- return plugin;
- }
- }
-
- return null;
- }
-
- function ScreenSaverManager() {
-
- var self = this;
- var activeScreenSaver;
-
- function showScreenSaver(screensaver) {
-
- if (activeScreenSaver) {
- throw new Error("An existing screensaver is already active.");
- }
-
- console.debug("Showing screensaver " + screensaver.name);
-
- screensaver.show();
- activeScreenSaver = screensaver;
-
- if (screensaver.hideOnClick !== false) {
- window.addEventListener("click", hide, true);
- }
- if (screensaver.hideOnMouse !== false) {
- window.addEventListener("mousemove", hide, true);
- }
- if (screensaver.hideOnKey !== false) {
- window.addEventListener("keydown", hide, true);
- }
- }
-
- function hide() {
- if (activeScreenSaver) {
- console.debug("Hiding screensaver");
- activeScreenSaver.hide();
- activeScreenSaver = null;
- }
-
- window.removeEventListener("click", hide, true);
- window.removeEventListener("mousemove", hide, true);
- window.removeEventListener("keydown", hide, true);
- }
-
- self.isShowing = function () {
- return activeScreenSaver != null;
- };
-
- self.show = function () {
- var isLoggedIn;
- var apiClient = connectionManager.currentApiClient();
-
- if (apiClient && apiClient.isLoggedIn()) {
- isLoggedIn = true;
- }
-
- var screensaver = getScreensaverPlugin(isLoggedIn);
-
- if (screensaver) {
- showScreenSaver(screensaver);
- }
- };
-
- self.hide = function () {
- hide();
- };
-
- function onInterval() {
-
- if (self.isShowing()) {
- return;
- }
-
- if (inputManager.idleTime() < getMinIdleTime()) {
- return;
- }
-
- if (getFunctionalEventIdleTime < getMinIdleTime()) {
- return;
- }
-
- if (playbackManager.isPlayingVideo()) {
- return;
- }
-
- self.show();
- }
-
- setInterval(onInterval, 10000);
- }
-
- return new ScreenSaverManager();
});
+
+function getScreensaverPlugin(isLoggedIn) {
+ let option;
+ try {
+ option = userSettings.get('screensaver', false);
+ } catch (err) {
+ option = isLoggedIn ? 'backdropscreensaver' : 'logoscreensaver';
+ }
+
+ const plugins = pluginManager.ofType('screensaver');
+
+ for (const plugin of plugins) {
+ if (plugin.id === option) {
+ return plugin;
+ }
+ }
+
+ return null;
+}
+
+function ScreenSaverManager() {
+ let activeScreenSaver;
+
+ function showScreenSaver(screensaver) {
+ if (activeScreenSaver) {
+ throw new Error('An existing screensaver is already active.');
+ }
+
+ console.debug('Showing screensaver ' + screensaver.name);
+
+ screensaver.show();
+ activeScreenSaver = screensaver;
+
+ if (screensaver.hideOnClick !== false) {
+ window.addEventListener('click', hide, true);
+ }
+ if (screensaver.hideOnMouse !== false) {
+ window.addEventListener('mousemove', hide, true);
+ }
+ if (screensaver.hideOnKey !== false) {
+ window.addEventListener('keydown', hide, true);
+ }
+ }
+
+ function hide() {
+ if (activeScreenSaver) {
+ console.debug('Hiding screensaver');
+ activeScreenSaver.hide();
+ activeScreenSaver = null;
+ }
+
+ window.removeEventListener('click', hide, true);
+ window.removeEventListener('mousemove', hide, true);
+ window.removeEventListener('keydown', hide, true);
+ }
+
+ this.isShowing = () => {
+ return activeScreenSaver != null;
+ };
+
+ this.show = function () {
+ let isLoggedIn;
+ const apiClient = connectionManager.currentApiClient();
+
+ if (apiClient && apiClient.isLoggedIn()) {
+ isLoggedIn = true;
+ }
+
+ const screensaver = getScreensaverPlugin(isLoggedIn);
+
+ if (screensaver) {
+ showScreenSaver(screensaver);
+ }
+ };
+
+ this.hide = function () {
+ hide();
+ };
+
+ const onInterval = () => {
+ if (this.isShowing()) {
+ return;
+ }
+
+ if (inputManager.idleTime() < getMinIdleTime()) {
+ return;
+ }
+
+ if (getFunctionalEventIdleTime < getMinIdleTime()) {
+ return;
+ }
+
+ if (playbackManager.isPlayingVideo()) {
+ return;
+ }
+
+ this.show();
+ };
+
+ setInterval(onInterval, 10000);
+}
+
+export default new ScreenSaverManager;
diff --git a/src/libraries/scroller.js b/src/libraries/scroller.js
index cc75dcdeef..c460ec5b2c 100644
--- a/src/libraries/scroller.js
+++ b/src/libraries/scroller.js
@@ -1,928 +1,886 @@
-define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'scrollStyles'], function (browser, layoutManager, dom, focusManager, ResizeObserver) {
- 'use strict';
+/* Cleaning this file properly is not neecessary, since it's an outdated library
+ * and will be replaced soon by a Vue component.
+ */
- browser = browser.default || browser;
- focusManager = focusManager.default || focusManager;
+import browser from 'browser';
+import layoutManager from 'layoutManager';
+import dom from 'dom';
+import focusManager from 'focusManager';
+import ResizeObserver from 'ResizeObserver';
+import 'scrollStyles';
- /**
+/**
* Return type of the value.
*
* @param {Mixed} value
*
* @return {String}
*/
- function type(value) {
- if (value == null) {
- return String(value);
- }
-
- if (typeof value === 'object' || typeof value === 'function') {
- return Object.prototype.toString.call(value).match(/\s([a-z]+)/i)[1].toLowerCase() || 'object';
- }
-
- return typeof value;
+function type(value) {
+ if (value == null) {
+ return String(value);
}
- /**
- * Disables an event it was triggered on and unbinds itself.
- *
- * @param {Event} event
- *
- * @return {Void}
- */
- function disableOneEvent(event) {
- /*jshint validthis:true */
- event.preventDefault();
- event.stopPropagation();
- this.removeEventListener(event.type, disableOneEvent);
+ if (typeof value === 'object' || typeof value === 'function') {
+ return Object.prototype.toString.call(value).match(/\s([a-z]+)/i)[1].toLowerCase() || 'object';
}
- /**
- * Make sure that number is within the limits.
- *
- * @param {Number} number
- * @param {Number} min
- * @param {Number} max
- *
- * @return {Number}
- */
- function within(number, min, max) {
- return number < min ? min : number > max ? max : number;
+ return typeof value;
+}
+
+/**
+ * Disables an event it was triggered on and unbinds itself.
+ *
+ * @param {Event} event
+ *
+ * @return {Void}
+ */
+function disableOneEvent(event) {
+ /*jshint validthis:true */
+ event.preventDefault();
+ event.stopPropagation();
+ this.removeEventListener(event.type, disableOneEvent);
+}
+
+/**
+ * Make sure that number is within the limits.
+ *
+ * @param {Number} number
+ * @param {Number} min
+ * @param {Number} max
+ *
+ * @return {Number}
+ */
+function within(number, min, max) {
+ return number < min ? min : number > max ? max : number;
+}
+
+// Other global values
+var dragMouseEvents = ['mousemove', 'mouseup'];
+var dragTouchEvents = ['touchmove', 'touchend'];
+var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel' : 'mousewheel');
+var interactiveElements = ['INPUT', 'SELECT', 'TEXTAREA'];
+
+var scrollerFactory = function (frame, options) {
+ // Extend options
+ var o = Object.assign({}, {
+ slidee: null, // Selector, DOM element, or jQuery object with DOM element representing SLIDEE.
+ horizontal: false, // Switch to horizontal mode.
+
+ // Scrolling
+ mouseWheel: true,
+ scrollBy: 0, // Pixels or items to move per one mouse scroll. 0 to disable scrolling
+
+ // Dragging
+ dragSource: null, // Selector or DOM element for catching dragging events. Default is FRAME.
+ mouseDragging: 1, // Enable navigation by dragging the SLIDEE with mouse cursor.
+ touchDragging: 1, // Enable navigation by dragging the SLIDEE with touch events.
+ dragThreshold: 3, // Distance in pixels before Sly recognizes dragging.
+ intervactive: null, // Selector for special interactive elements.
+
+ // Mixed options
+ speed: 0 // Animations speed in milliseconds. 0 to disable animations.
+
+ }, options);
+
+ var isSmoothScrollSupported = 'scrollBehavior' in document.documentElement.style;
+
+ // native scroll is a must with touch input
+ // also use native scroll when scrolling vertically in desktop mode - excluding horizontal because the mouse wheel support is choppy at the moment
+ // in cases with firefox, if the smooth scroll api is supported then use that because their implementation is very good
+ if (options.allowNativeScroll === false) {
+ options.enableNativeScroll = false;
+ } else if (isSmoothScrollSupported && ((browser.firefox && !layoutManager.tv) || options.allowNativeSmoothScroll)) {
+ // native smooth scroll
+ options.enableNativeScroll = true;
+ } else if (options.requireAnimation && (browser.animate || browser.supportsCssAnimation())) {
+ // transform is the only way to guarantee animation
+ options.enableNativeScroll = false;
+ } else if (!layoutManager.tv || !browser.animate) {
+ options.enableNativeScroll = true;
}
- // Other global values
- var dragMouseEvents = ['mousemove', 'mouseup'];
- var dragTouchEvents = ['touchmove', 'touchend'];
- var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel' : 'mousewheel');
- var interactiveElements = ['INPUT', 'SELECT', 'TEXTAREA'];
- var tmpArray = [];
- var time;
-
- // Math shorthands
- var abs = Math.abs;
- var sqrt = Math.sqrt;
- var pow = Math.pow;
- var round = Math.round;
- var max = Math.max;
- var min = Math.min;
-
- var scrollerFactory = function (frame, options) {
-
- // Extend options
- var o = Object.assign({}, {
- slidee: null, // Selector, DOM element, or jQuery object with DOM element representing SLIDEE.
- horizontal: false, // Switch to horizontal mode.
-
- // Scrolling
- mouseWheel: true,
- scrollBy: 0, // Pixels or items to move per one mouse scroll. 0 to disable scrolling
-
- // Dragging
- dragSource: null, // Selector or DOM element for catching dragging events. Default is FRAME.
- mouseDragging: 1, // Enable navigation by dragging the SLIDEE with mouse cursor.
- touchDragging: 1, // Enable navigation by dragging the SLIDEE with touch events.
- dragThreshold: 3, // Distance in pixels before Sly recognizes dragging.
- intervactive: null, // Selector for special interactive elements.
-
- // Mixed options
- speed: 0 // Animations speed in milliseconds. 0 to disable animations.
-
- }, options);
-
- var isSmoothScrollSupported = 'scrollBehavior' in document.documentElement.style;
-
- // native scroll is a must with touch input
- // also use native scroll when scrolling vertically in desktop mode - excluding horizontal because the mouse wheel support is choppy at the moment
- // in cases with firefox, if the smooth scroll api is supported then use that because their implementation is very good
- if (options.allowNativeScroll === false) {
- options.enableNativeScroll = false;
- } else if (isSmoothScrollSupported && ((browser.firefox && !layoutManager.tv) || options.allowNativeSmoothScroll)) {
- // native smooth scroll
- options.enableNativeScroll = true;
- } else if (options.requireAnimation && (browser.animate || browser.supportsCssAnimation())) {
-
- // transform is the only way to guarantee animation
- options.enableNativeScroll = false;
- } else if (!layoutManager.tv || !browser.animate) {
-
- options.enableNativeScroll = true;
- }
-
- // Need this for the magic wheel. With the animated scroll the magic wheel will run off of the screen
- if (browser.web0s) {
- options.enableNativeScroll = true;
- }
-
- // Private variables
- var self = this;
- self.options = o;
-
- // Frame
- var slideeElement = o.slidee ? o.slidee : sibling(frame.firstChild)[0];
- self._pos = {
- start: 0,
- center: 0,
- end: 0,
- cur: 0,
- dest: 0
- };
-
- var transform = !options.enableNativeScroll;
-
- // Miscellaneous
- var scrollSource = frame;
- var dragSourceElement = o.dragSource ? o.dragSource : frame;
- var dragging = {
- released: 1
- };
- var scrolling = {
- last: 0,
- delta: 0,
- resetTime: 200
- };
-
- // Expose properties
- self.initialized = 0;
- self.slidee = slideeElement;
- self.options = o;
- self.dragging = dragging;
-
- var nativeScrollElement = frame;
-
- function sibling(n, elem) {
- var matched = [];
-
- for (; n; n = n.nextSibling) {
- if (n.nodeType === 1 && n !== elem) {
- matched.push(n);
- }
- }
- return matched;
- }
-
- var requiresReflow = true;
-
- var frameSize = 0;
- var slideeSize = 0;
- function ensureSizeInfo() {
-
- if (requiresReflow) {
-
- requiresReflow = false;
-
- // Reset global variables
- frameSize = o.horizontal ? (frame).offsetWidth : (frame).offsetHeight;
-
- slideeSize = o.scrollWidth || Math.max(slideeElement[o.horizontal ? 'offsetWidth' : 'offsetHeight'], slideeElement[o.horizontal ? 'scrollWidth' : 'scrollHeight']);
-
- // Set position limits & relativess
- self._pos.end = max(slideeSize - frameSize, 0);
- }
- }
-
- /**
- * Loading function.
- *
- * Populate arrays, set sizes, bind events, ...
- *
- * @param {Boolean} [isInit] Whether load is called from within self.init().
- * @return {Void}
- */
- function load(isInit) {
-
- requiresReflow = true;
-
- if (!isInit) {
-
- ensureSizeInfo();
-
- // Fix possible overflowing
- var pos = self._pos;
- self.slideTo(within(pos.dest, pos.start, pos.end));
- }
- }
-
- function initFrameResizeObserver() {
-
- var observerOptions = {};
-
- self.frameResizeObserver = new ResizeObserver(onResize, observerOptions);
-
- self.frameResizeObserver.observe(frame);
- }
-
- self.reload = function () {
- load();
- };
-
- self.getScrollEventName = function () {
- return transform ? 'scrollanimate' : 'scroll';
- };
-
- self.getScrollSlider = function () {
- return slideeElement;
- };
-
- self.getScrollFrame = function () {
- return frame;
- };
-
- function nativeScrollTo(container, pos, immediate) {
-
- if (container.scroll) {
- if (o.horizontal) {
-
- container.scroll({
- left: pos,
- behavior: immediate ? 'instant' : 'smooth'
- });
- } else {
-
- container.scroll({
- top: pos,
- behavior: immediate ? 'instant' : 'smooth'
- });
- }
- } else if (!immediate && container.scrollTo) {
- if (o.horizontal) {
- container.scrollTo(Math.round(pos), 0);
- } else {
- container.scrollTo(0, Math.round(pos));
- }
- } else {
- if (o.horizontal) {
- container.scrollLeft = Math.round(pos);
- } else {
- container.scrollTop = Math.round(pos);
- }
- }
- }
-
- var lastAnimate;
-
- /**
- * Animate to a position.
- *
- * @param {Int} newPos New position.
- * @param {Bool} immediate Reposition immediately without an animation.
- *
- * @return {Void}
- */
- self.slideTo = function (newPos, immediate, fullItemPos) {
-
- ensureSizeInfo();
- var pos = self._pos;
-
- newPos = within(newPos, pos.start, pos.end);
-
- if (!transform) {
-
- nativeScrollTo(nativeScrollElement, newPos, immediate);
- return;
- }
-
- // Update the animation object
- var from = pos.cur;
- immediate = immediate || dragging.init || !o.speed;
-
- var now = new Date().getTime();
-
- if (o.autoImmediate) {
- if (!immediate && (now - (lastAnimate || 0)) <= 50) {
- immediate = true;
- }
- }
-
- if (!immediate && o.skipSlideToWhenVisible && fullItemPos && fullItemPos.isVisible) {
-
- return;
- }
-
- // Start animation rendering
- // NOTE the dependency was modified here to fix a scrollbutton issue
- pos.dest = newPos;
- renderAnimateWithTransform(from, newPos, immediate);
- lastAnimate = now;
- };
-
- function setStyleProperty(elem, name, value, speed, resetTransition) {
-
- var style = elem.style;
-
- if (resetTransition || browser.edge) {
- style.transition = 'none';
- void elem.offsetWidth;
- }
-
- style.transition = 'transform ' + speed + 'ms ease-out';
- style[name] = value;
- }
-
- function dispatchScrollEventIfNeeded() {
- if (o.dispatchScrollEvent) {
- frame.dispatchEvent(new CustomEvent(self.getScrollEventName(), {
- bubbles: true,
- cancelable: false
- }));
- }
- }
-
- function renderAnimateWithTransform(fromPosition, toPosition, immediate) {
-
- var speed = o.speed;
-
- if (immediate) {
- speed = o.immediateSpeed || 50;
- }
-
- if (o.horizontal) {
- setStyleProperty(slideeElement, 'transform', 'translateX(' + (-round(toPosition)) + 'px)', speed);
- } else {
- setStyleProperty(slideeElement, 'transform', 'translateY(' + (-round(toPosition)) + 'px)', speed);
- }
- self._pos.cur = toPosition;
-
- dispatchScrollEventIfNeeded();
- }
-
- function getBoundingClientRect(elem) {
-
- // Support: BlackBerry 5, iOS 3 (original iPhone)
- // If we don't have gBCR, just use 0,0 rather than error
- if (elem.getBoundingClientRect) {
- return elem.getBoundingClientRect();
- } else {
- return { top: 0, left: 0 };
- }
- }
-
- /**
- * Returns the position object.
- *
- * @param {Mixed} item
- *
- * @return {Object}
- */
- self.getPos = function (item) {
-
- var scrollElement = transform ? slideeElement : nativeScrollElement;
- var slideeOffset = getBoundingClientRect(scrollElement);
- var itemOffset = getBoundingClientRect(item);
-
- var slideeStartPos = o.horizontal ? slideeOffset.left : slideeOffset.top;
- var slideeEndPos = o.horizontal ? slideeOffset.right : slideeOffset.bottom;
-
- var offset = o.horizontal ? itemOffset.left - slideeOffset.left : itemOffset.top - slideeOffset.top;
-
- var size = o.horizontal ? itemOffset.width : itemOffset.height;
- if (!size && size !== 0) {
- size = item[o.horizontal ? 'offsetWidth' : 'offsetHeight'];
- }
-
- var centerOffset = o.centerOffset || 0;
-
- if (!transform) {
- centerOffset = 0;
- if (o.horizontal) {
- offset += nativeScrollElement.scrollLeft;
- } else {
- offset += nativeScrollElement.scrollTop;
- }
- }
-
- ensureSizeInfo();
-
- var currentStart = self._pos.cur;
- var currentEnd = currentStart + frameSize;
-
- console.debug('offset:' + offset + ' currentStart:' + currentStart + ' currentEnd:' + currentEnd);
- var isVisible = offset >= currentStart && (offset + size) <= currentEnd;
-
- return {
- start: offset,
- center: offset + centerOffset - (frameSize / 2) + (size / 2),
- end: offset - frameSize + size,
- size: size,
- isVisible: isVisible
- };
- };
-
- self.getCenterPosition = function (item) {
-
- ensureSizeInfo();
-
- var pos = self.getPos(item);
- return within(pos.center, pos.start, pos.end);
- };
-
- function dragInitSlidee(event) {
- var isTouch = event.type === 'touchstart';
-
- // Ignore when already in progress, or interactive element in non-touch navivagion
- if (dragging.init || !isTouch && isInteractive(event.target)) {
- return;
- }
-
- // SLIDEE dragging conditions
- if (!(isTouch ? o.touchDragging : o.mouseDragging && event.which < 2)) {
- return;
- }
-
- if (!isTouch) {
- // prevents native image dragging in Firefox
- event.preventDefault();
- }
-
- // Reset dragging object
- dragging.released = 0;
-
- // Properties used in dragHandler
- dragging.init = 0;
- dragging.source = event.target;
- dragging.touch = isTouch;
- var pointer = isTouch ? event.touches[0] : event;
- dragging.initX = pointer.pageX;
- dragging.initY = pointer.pageY;
- dragging.initPos = self._pos.cur;
- dragging.start = +new Date();
- dragging.time = 0;
- dragging.path = 0;
- dragging.delta = 0;
- dragging.locked = 0;
- dragging.pathToLock = isTouch ? 30 : 10;
-
- // Bind dragging events
- if (transform) {
-
- if (isTouch) {
- dragTouchEvents.forEach(function (eventName) {
- dom.addEventListener(document, eventName, dragHandler, {
- passive: true
- });
- });
- } else {
- dragMouseEvents.forEach(function (eventName) {
- dom.addEventListener(document, eventName, dragHandler, {
- passive: true
- });
- });
- }
- }
- }
-
- /**
- * Handler for dragging scrollbar handle or SLIDEE.
- *
- * @param {Event} event
- *
- * @return {Void}
- */
- function dragHandler(event) {
- dragging.released = event.type === 'mouseup' || event.type === 'touchend';
- var pointer = dragging.touch ? event[dragging.released ? 'changedTouches' : 'touches'][0] : event;
- dragging.pathX = pointer.pageX - dragging.initX;
- dragging.pathY = pointer.pageY - dragging.initY;
- dragging.path = sqrt(pow(dragging.pathX, 2) + pow(dragging.pathY, 2));
- dragging.delta = o.horizontal ? dragging.pathX : dragging.pathY;
-
- if (!dragging.released && dragging.path < 1) {
- return;
- }
-
- // We haven't decided whether this is a drag or not...
- if (!dragging.init) {
- // If the drag path was very short, maybe it's not a drag?
- if (dragging.path < o.dragThreshold) {
- // If the pointer was released, the path will not become longer and it's
- // definitely not a drag. If not released yet, decide on next iteration
- return dragging.released ? dragEnd() : undefined;
- } else {
- // If dragging path is sufficiently long we can confidently start a drag
- // if drag is in different direction than scroll, ignore it
- if (o.horizontal ? abs(dragging.pathX) > abs(dragging.pathY) : abs(dragging.pathX) < abs(dragging.pathY)) {
- dragging.init = 1;
- } else {
- return dragEnd();
- }
- }
- }
-
- //event.preventDefault();
-
- // Disable click on a source element, as it is unwelcome when dragging
- if (!dragging.locked && dragging.path > dragging.pathToLock) {
- dragging.locked = 1;
- dragging.source.addEventListener('click', disableOneEvent);
- }
-
- // Cancel dragging on release
- if (dragging.released) {
- dragEnd();
- }
-
- self.slideTo(round(dragging.initPos - dragging.delta));
- }
-
- /**
- * Stops dragging and cleans up after it.
- *
- * @return {Void}
- */
- function dragEnd() {
- dragging.released = true;
-
- dragTouchEvents.forEach(function (eventName) {
- dom.removeEventListener(document, eventName, dragHandler, {
- passive: true
- });
- });
-
- dragMouseEvents.forEach(function (eventName) {
- dom.removeEventListener(document, eventName, dragHandler, {
- passive: true
- });
- });
-
- // Make sure that disableOneEvent is not active in next tick.
- setTimeout(function () {
- dragging.source.removeEventListener('click', disableOneEvent);
- });
-
- dragging.init = 0;
- }
-
- /**
- * Check whether element is interactive.
- *
- * @return {Boolean}
- */
- function isInteractive(element) {
-
- while (element) {
-
- if (interactiveElements.indexOf(element.tagName) !== -1) {
- return true;
- }
-
- element = element.parentNode;
- }
- return false;
- }
-
- /**
- * Mouse wheel delta normalization.
- *
- * @param {Event} event
- *
- * @return {Int}
- */
- function normalizeWheelDelta(event) {
- // JELLYFIN MOD: Only use deltaX for horizontal scroll and remove IE8 support
- scrolling.curDelta = o.horizontal ? event.deltaX : event.deltaY;
- // END JELLYFIN MOD
-
- if (transform) {
- scrolling.curDelta /= event.deltaMode === 1 ? 3 : 100;
- }
- return scrolling.curDelta;
- }
-
- /**
- * Mouse scrolling handler.
- *
- * @param {Event} event
- *
- * @return {Void}
- */
- function scrollHandler(event) {
-
- ensureSizeInfo();
- var pos = self._pos;
- // Ignore if there is no scrolling to be done
- if (!o.scrollBy || pos.start === pos.end) {
- return;
- }
- var delta = normalizeWheelDelta(event);
-
- if (transform) {
- // Trap scrolling only when necessary and/or requested
- if (delta > 0 && pos.dest < pos.end || delta < 0 && pos.dest > pos.start) {
- //stopDefault(event, 1);
- }
-
- self.slideBy(o.scrollBy * delta);
- } else {
-
- if (isSmoothScrollSupported) {
- delta *= 12;
- }
-
- if (o.horizontal) {
- nativeScrollElement.scrollLeft += delta;
- } else {
- nativeScrollElement.scrollTop += delta;
- }
- }
- }
-
- /**
- * Destroys instance and everything it created.
- *
- * @return {Void}
- */
- self.destroy = function () {
-
- if (self.frameResizeObserver) {
- self.frameResizeObserver.disconnect();
- self.frameResizeObserver = null;
- }
-
- // Reset native FRAME element scroll
- dom.removeEventListener(frame, 'scroll', resetScroll, {
- passive: true
- });
-
- dom.removeEventListener(scrollSource, wheelEvent, scrollHandler, {
- passive: true
- });
-
- dom.removeEventListener(dragSourceElement, 'touchstart', dragInitSlidee, {
- passive: true
- });
-
- dom.removeEventListener(frame, 'click', onFrameClick, {
- passive: true,
- capture: true
- });
-
- dom.removeEventListener(dragSourceElement, 'mousedown', dragInitSlidee, {
- //passive: true
- });
-
- // Reset initialized status and return the instance
- self.initialized = 0;
- return self;
- };
-
- var contentRect = {};
-
- function onResize(entries) {
-
- var entry = entries[0];
-
- if (entry) {
-
- var newRect = entry.contentRect;
-
- // handle element being hidden
- if (newRect.width === 0 || newRect.height === 0) {
- return;
- }
-
- if (newRect.width !== contentRect.width || newRect.height !== contentRect.height) {
-
- contentRect = newRect;
-
- load(false);
- }
- }
- }
-
- function resetScroll() {
- if (o.horizontal) {
- this.scrollLeft = 0;
- } else {
- this.scrollTop = 0;
- }
- }
-
- function onFrameClick(e) {
- if (e.which === 1) {
- var focusableParent = focusManager.focusableParent(e.target);
- if (focusableParent && focusableParent !== document.activeElement) {
- focusableParent.focus();
- }
- }
- }
-
- self.getScrollPosition = function () {
-
- if (transform) {
- return self._pos.cur;
- }
-
- if (o.horizontal) {
- return nativeScrollElement.scrollLeft;
- } else {
- return nativeScrollElement.scrollTop;
- }
- };
-
- self.getScrollSize = function () {
-
- if (transform) {
- return slideeSize;
- }
-
- if (o.horizontal) {
- return nativeScrollElement.scrollWidth;
- } else {
- return nativeScrollElement.scrollHeight;
- }
- };
-
- /**
- * Initialize.
- *
- * @return {Object}
- */
- self.init = function () {
- if (self.initialized) {
- return;
- }
-
- if (!transform) {
- if (o.horizontal) {
- if (layoutManager.desktop && !o.hideScrollbar) {
- nativeScrollElement.classList.add('scrollX');
- } else {
- nativeScrollElement.classList.add('scrollX');
- nativeScrollElement.classList.add('hiddenScrollX');
-
- if (layoutManager.tv && o.allowNativeSmoothScroll !== false) {
- nativeScrollElement.classList.add('smoothScrollX');
- }
- }
-
- if (o.forceHideScrollbars) {
- nativeScrollElement.classList.add('hiddenScrollX-forced');
- }
- } else {
- if (layoutManager.desktop && !o.hideScrollbar) {
- nativeScrollElement.classList.add('scrollY');
- } else {
- nativeScrollElement.classList.add('scrollY');
- nativeScrollElement.classList.add('hiddenScrollY');
-
- if (layoutManager.tv && o.allowNativeSmoothScroll !== false) {
- nativeScrollElement.classList.add('smoothScrollY');
- }
- }
-
- if (o.forceHideScrollbars) {
- nativeScrollElement.classList.add('hiddenScrollY-forced');
- }
- }
- } else {
- frame.style.overflow = 'hidden';
- slideeElement.style['will-change'] = 'transform';
- slideeElement.style.transition = 'transform ' + o.speed + 'ms ease-out';
-
- if (o.horizontal) {
- slideeElement.classList.add('animatedScrollX');
- } else {
- slideeElement.classList.add('animatedScrollY');
- }
- }
-
- if (transform || layoutManager.tv) {
- // This can prevent others from being able to listen to mouse events
- dom.addEventListener(dragSourceElement, 'mousedown', dragInitSlidee, {
- //passive: true
- });
- }
-
- initFrameResizeObserver();
-
- if (transform) {
-
- dom.addEventListener(dragSourceElement, 'touchstart', dragInitSlidee, {
- passive: true
- });
-
- if (!o.horizontal) {
- dom.addEventListener(frame, 'scroll', resetScroll, {
- passive: true
- });
- }
-
- if (o.mouseWheel) {
- // Scrolling navigation
- dom.addEventListener(scrollSource, wheelEvent, scrollHandler, {
- passive: true
- });
- }
-
- } else if (o.horizontal) {
-
- // Don't bind to mouse events with vertical scroll since the mouse wheel can handle this natively
-
- if (o.mouseWheel) {
- // Scrolling navigation
- dom.addEventListener(scrollSource, wheelEvent, scrollHandler, {
- passive: true
- });
- }
- }
-
- dom.addEventListener(frame, 'click', onFrameClick, {
- passive: true,
- capture: true
- });
-
- // Mark instance as initialized
- self.initialized = 1;
-
- // Load
- load(true);
-
- // Return instance
- return self;
- };
+ // Need this for the magic wheel. With the animated scroll the magic wheel will run off of the screen
+ if (browser.web0s) {
+ options.enableNativeScroll = true;
+ }
+
+ // Private variables
+ var self = this;
+ self.options = o;
+
+ // Frame
+ var slideeElement = o.slidee ? o.slidee : sibling(frame.firstChild)[0];
+ self._pos = {
+ start: 0,
+ center: 0,
+ end: 0,
+ cur: 0,
+ dest: 0
};
+ var transform = !options.enableNativeScroll;
+
+ // Miscellaneous
+ var scrollSource = frame;
+ var dragSourceElement = o.dragSource ? o.dragSource : frame;
+ var dragging = {
+ released: 1
+ };
+ var scrolling = {
+ last: 0,
+ delta: 0,
+ resetTime: 200
+ };
+
+ // Expose properties
+ self.initialized = 0;
+ self.slidee = slideeElement;
+ self.options = o;
+ self.dragging = dragging;
+
+ var nativeScrollElement = frame;
+
+ function sibling(n, elem) {
+ var matched = [];
+
+ for (; n; n = n.nextSibling) {
+ if (n.nodeType === 1 && n !== elem) {
+ matched.push(n);
+ }
+ }
+ return matched;
+ }
+
+ var requiresReflow = true;
+
+ var frameSize = 0;
+ var slideeSize = 0;
+ function ensureSizeInfo() {
+ if (requiresReflow) {
+ requiresReflow = false;
+
+ // Reset global variables
+ frameSize = o.horizontal ? (frame).offsetWidth : (frame).offsetHeight;
+
+ slideeSize = o.scrollWidth || Math.max(slideeElement[o.horizontal ? 'offsetWidth' : 'offsetHeight'], slideeElement[o.horizontal ? 'scrollWidth' : 'scrollHeight']);
+
+ // Set position limits & relativess
+ self._pos.end = Math.max(slideeSize - frameSize, 0);
+ }
+ }
+
/**
- * Slide SLIDEE by amount of pixels.
+ * Loading function.
*
- * @param {Int} delta Pixels/Items. Positive means forward, negative means backward.
- * @param {Bool} immediate Reposition immediately without an animation.
+ * Populate arrays, set sizes, bind events, ...
*
+ * @param {Boolean} [isInit] Whether load is called from within self.init().
* @return {Void}
*/
- scrollerFactory.prototype.slideBy = function (delta, immediate) {
- if (!delta) {
+ function load(isInit) {
+ requiresReflow = true;
+
+ if (!isInit) {
+ ensureSizeInfo();
+
+ // Fix possible overflowing
+ var pos = self._pos;
+ self.slideTo(within(pos.dest, pos.start, pos.end));
+ }
+ }
+
+ function initFrameResizeObserver() {
+ var observerOptions = {};
+
+ self.frameResizeObserver = new ResizeObserver(onResize, observerOptions);
+
+ self.frameResizeObserver.observe(frame);
+ }
+
+ self.reload = function () {
+ load();
+ };
+
+ self.getScrollEventName = function () {
+ return transform ? 'scrollanimate' : 'scroll';
+ };
+
+ self.getScrollSlider = function () {
+ return slideeElement;
+ };
+
+ self.getScrollFrame = function () {
+ return frame;
+ };
+
+ function nativeScrollTo(container, pos, immediate) {
+ if (container.scroll) {
+ if (o.horizontal) {
+ container.scroll({
+ left: pos,
+ behavior: immediate ? 'instant' : 'smooth'
+ });
+ } else {
+ container.scroll({
+ top: pos,
+ behavior: immediate ? 'instant' : 'smooth'
+ });
+ }
+ } else if (!immediate && container.scrollTo) {
+ if (o.horizontal) {
+ container.scrollTo(Math.round(pos), 0);
+ } else {
+ container.scrollTo(0, Math.round(pos));
+ }
+ } else {
+ if (o.horizontal) {
+ container.scrollLeft = Math.round(pos);
+ } else {
+ container.scrollTop = Math.round(pos);
+ }
+ }
+ }
+
+ var lastAnimate;
+
+ /**
+ * Animate to a position.
+ *
+ * @param {Int} newPos New position.
+ * @param {Bool} immediate Reposition immediately without an animation.
+ *
+ * @return {Void}
+ */
+ self.slideTo = function (newPos, immediate, fullItemPos) {
+ ensureSizeInfo();
+ var pos = self._pos;
+
+ newPos = within(newPos, pos.start, pos.end);
+
+ if (!transform) {
+ nativeScrollTo(nativeScrollElement, newPos, immediate);
return;
}
- this.slideTo(this._pos.dest + delta, immediate);
- };
- /**
- * Core method for handling `toLocation` methods.
- *
- * @param {String} location
- * @param {Mixed} item
- * @param {Bool} immediate
- *
- * @return {Void}
- */
- scrollerFactory.prototype.to = function (location, item, immediate) {
- // Optional arguments logic
- if (type(item) === 'boolean') {
- immediate = item;
- item = undefined;
- }
+ // Update the animation object
+ var from = pos.cur;
+ immediate = immediate || dragging.init || !o.speed;
- if (item === undefined) {
- this.slideTo(this._pos[location], immediate);
- } else {
- var itemPos = this.getPos(item);
+ var now = new Date().getTime();
- if (itemPos) {
- this.slideTo(itemPos[location], immediate, itemPos);
+ if (o.autoImmediate) {
+ if (!immediate && (now - (lastAnimate || 0)) <= 50) {
+ immediate = true;
}
}
+
+ if (!immediate && o.skipSlideToWhenVisible && fullItemPos && fullItemPos.isVisible) {
+ return;
+ }
+
+ // Start animation rendering
+ // NOTE the dependency was modified here to fix a scrollbutton issue
+ pos.dest = newPos;
+ renderAnimateWithTransform(from, newPos, immediate);
+ lastAnimate = now;
};
+ function setStyleProperty(elem, name, value, speed, resetTransition) {
+ var style = elem.style;
+
+ if (resetTransition || browser.edge) {
+ style.transition = 'none';
+ void elem.offsetWidth;
+ }
+
+ style.transition = 'transform ' + speed + 'ms ease-out';
+ style[name] = value;
+ }
+
+ function dispatchScrollEventIfNeeded() {
+ if (o.dispatchScrollEvent) {
+ frame.dispatchEvent(new CustomEvent(self.getScrollEventName(), {
+ bubbles: true,
+ cancelable: false
+ }));
+ }
+ }
+
+ function renderAnimateWithTransform(fromPosition, toPosition, immediate) {
+ var speed = o.speed;
+
+ if (immediate) {
+ speed = o.immediateSpeed || 50;
+ }
+
+ if (o.horizontal) {
+ setStyleProperty(slideeElement, 'transform', 'translateX(' + (-Math.round(toPosition)) + 'px)', speed);
+ } else {
+ setStyleProperty(slideeElement, 'transform', 'translateY(' + (-Math.round(toPosition)) + 'px)', speed);
+ }
+ self._pos.cur = toPosition;
+
+ dispatchScrollEventIfNeeded();
+ }
+
+ function getBoundingClientRect(elem) {
+ // Support: BlackBerry 5, iOS 3 (original iPhone)
+ // If we don't have gBCR, just use 0,0 rather than error
+ if (elem.getBoundingClientRect) {
+ return elem.getBoundingClientRect();
+ } else {
+ return { top: 0, left: 0 };
+ }
+ }
+
/**
- * Animate element or the whole SLIDEE to the start of the frame.
+ * Returns the position object.
*
- * @param {Mixed} item Item DOM element, or index starting at 0. Omitting will animate SLIDEE.
- * @param {Bool} immediate Reposition immediately without an animation.
+ * @param {Mixed} item
+ *
+ * @return {Object}
+ */
+ self.getPos = function (item) {
+ var scrollElement = transform ? slideeElement : nativeScrollElement;
+ var slideeOffset = getBoundingClientRect(scrollElement);
+ var itemOffset = getBoundingClientRect(item);
+
+ var offset = o.horizontal ? itemOffset.left - slideeOffset.left : itemOffset.top - slideeOffset.top;
+
+ var size = o.horizontal ? itemOffset.width : itemOffset.height;
+ if (!size && size !== 0) {
+ size = item[o.horizontal ? 'offsetWidth' : 'offsetHeight'];
+ }
+
+ var centerOffset = o.centerOffset || 0;
+
+ if (!transform) {
+ centerOffset = 0;
+ if (o.horizontal) {
+ offset += nativeScrollElement.scrollLeft;
+ } else {
+ offset += nativeScrollElement.scrollTop;
+ }
+ }
+
+ ensureSizeInfo();
+
+ var currentStart = self._pos.cur;
+ var currentEnd = currentStart + frameSize;
+
+ console.debug('offset:' + offset + ' currentStart:' + currentStart + ' currentEnd:' + currentEnd);
+ var isVisible = offset >= currentStart && (offset + size) <= currentEnd;
+
+ return {
+ start: offset,
+ center: offset + centerOffset - (frameSize / 2) + (size / 2),
+ end: offset - frameSize + size,
+ size: size,
+ isVisible: isVisible
+ };
+ };
+
+ self.getCenterPosition = function (item) {
+ ensureSizeInfo();
+
+ var pos = self.getPos(item);
+ return within(pos.center, pos.start, pos.end);
+ };
+
+ function dragInitSlidee(event) {
+ var isTouch = event.type === 'touchstart';
+
+ // Ignore when already in progress, or interactive element in non-touch navivagion
+ if (dragging.init || !isTouch && isInteractive(event.target)) {
+ return;
+ }
+
+ // SLIDEE dragging conditions
+ if (!(isTouch ? o.touchDragging : o.mouseDragging && event.which < 2)) {
+ return;
+ }
+
+ if (!isTouch) {
+ // prevents native image dragging in Firefox
+ event.preventDefault();
+ }
+
+ // Reset dragging object
+ dragging.released = 0;
+
+ // Properties used in dragHandler
+ dragging.init = 0;
+ dragging.source = event.target;
+ dragging.touch = isTouch;
+ var pointer = isTouch ? event.touches[0] : event;
+ dragging.initX = pointer.pageX;
+ dragging.initY = pointer.pageY;
+ dragging.initPos = self._pos.cur;
+ dragging.start = +new Date();
+ dragging.time = 0;
+ dragging.path = 0;
+ dragging.delta = 0;
+ dragging.locked = 0;
+ dragging.pathToLock = isTouch ? 30 : 10;
+
+ // Bind dragging events
+ if (transform) {
+ if (isTouch) {
+ dragTouchEvents.forEach(function (eventName) {
+ dom.addEventListener(document, eventName, dragHandler, {
+ passive: true
+ });
+ });
+ } else {
+ dragMouseEvents.forEach(function (eventName) {
+ dom.addEventListener(document, eventName, dragHandler, {
+ passive: true
+ });
+ });
+ }
+ }
+ }
+
+ /**
+ * Handler for dragging scrollbar handle or SLIDEE.
+ *
+ * @param {Event} event
*
* @return {Void}
*/
- scrollerFactory.prototype.toStart = function (item, immediate) {
- this.to('start', item, immediate);
- };
+ function dragHandler(event) {
+ dragging.released = event.type === 'mouseup' || event.type === 'touchend';
+ var pointer = dragging.touch ? event[dragging.released ? 'changedTouches' : 'touches'][0] : event;
+ dragging.pathX = pointer.pageX - dragging.initX;
+ dragging.pathY = pointer.pageY - dragging.initY;
+ dragging.path = Math.sqrt(Math.pow(dragging.pathX, 2) + Math.pow(dragging.pathY, 2));
+ dragging.delta = o.horizontal ? dragging.pathX : dragging.pathY;
+
+ if (!dragging.released && dragging.path < 1) {
+ return;
+ }
+
+ // We haven't decided whether this is a drag or not...
+ if (!dragging.init) {
+ // If the drag path was very short, maybe it's not a drag?
+ if (dragging.path < o.dragThreshold) {
+ // If the pointer was released, the path will not become longer and it's
+ // definitely not a drag. If not released yet, decide on next iteration
+ return dragging.released ? dragEnd() : undefined;
+ } else {
+ // If dragging path is sufficiently long we can confidently start a drag
+ // if drag is in different direction than scroll, ignore it
+ if (o.horizontal ? Math.abs(dragging.pathX) > Math.abs(dragging.pathY) : Math.abs(dragging.pathX) < Math.abs(dragging.pathY)) {
+ dragging.init = 1;
+ } else {
+ return dragEnd();
+ }
+ }
+ }
+
+ //event.preventDefault();
+
+ // Disable click on a source element, as it is unwelcome when dragging
+ if (!dragging.locked && dragging.path > dragging.pathToLock) {
+ dragging.locked = 1;
+ dragging.source.addEventListener('click', disableOneEvent);
+ }
+
+ // Cancel dragging on release
+ if (dragging.released) {
+ dragEnd();
+ }
+
+ self.slideTo(Math.round(dragging.initPos - dragging.delta));
+ }
/**
- * Animate element or the whole SLIDEE to the end of the frame.
- *
- * @param {Mixed} item Item DOM element, or index starting at 0. Omitting will animate SLIDEE.
- * @param {Bool} immediate Reposition immediately without an animation.
+ * Stops dragging and cleans up after it.
*
* @return {Void}
*/
- scrollerFactory.prototype.toEnd = function (item, immediate) {
- this.to('end', item, immediate);
- };
+ function dragEnd() {
+ dragging.released = true;
+
+ dragTouchEvents.forEach(function (eventName) {
+ dom.removeEventListener(document, eventName, dragHandler, {
+ passive: true
+ });
+ });
+
+ dragMouseEvents.forEach(function (eventName) {
+ dom.removeEventListener(document, eventName, dragHandler, {
+ passive: true
+ });
+ });
+
+ // Make sure that disableOneEvent is not active in next tick.
+ setTimeout(function () {
+ dragging.source.removeEventListener('click', disableOneEvent);
+ });
+
+ dragging.init = 0;
+ }
/**
- * Animate element or the whole SLIDEE to the center of the frame.
+ * Check whether element is interactive.
*
- * @param {Mixed} item Item DOM element, or index starting at 0. Omitting will animate SLIDEE.
- * @param {Bool} immediate Reposition immediately without an animation.
+ * @return {Boolean}
+ */
+ function isInteractive(element) {
+ while (element) {
+ if (interactiveElements.indexOf(element.tagName) !== -1) {
+ return true;
+ }
+
+ element = element.parentNode;
+ }
+ return false;
+ }
+
+ /**
+ * Mouse wheel delta normalization.
+ *
+ * @param {Event} event
+ *
+ * @return {Int}
+ */
+ function normalizeWheelDelta(event) {
+ // JELLYFIN MOD: Only use deltaX for horizontal scroll and remove IE8 support
+ scrolling.curDelta = o.horizontal ? event.deltaX : event.deltaY;
+ // END JELLYFIN MOD
+
+ if (transform) {
+ scrolling.curDelta /= event.deltaMode === 1 ? 3 : 100;
+ }
+ return scrolling.curDelta;
+ }
+
+ /**
+ * Mouse scrolling handler.
+ *
+ * @param {Event} event
*
* @return {Void}
*/
- scrollerFactory.prototype.toCenter = function (item, immediate) {
- this.to('center', item, immediate);
+ function scrollHandler(event) {
+ ensureSizeInfo();
+ var pos = self._pos;
+ // Ignore if there is no scrolling to be done
+ if (!o.scrollBy || pos.start === pos.end) {
+ return;
+ }
+ var delta = normalizeWheelDelta(event);
+
+ if (transform) {
+ // Trap scrolling only when necessary and/or requested
+ if (delta > 0 && pos.dest < pos.end || delta < 0 && pos.dest > pos.start) {
+ //stopDefault(event, 1);
+ }
+
+ self.slideBy(o.scrollBy * delta);
+ } else {
+ if (isSmoothScrollSupported) {
+ delta *= 12;
+ }
+
+ if (o.horizontal) {
+ nativeScrollElement.scrollLeft += delta;
+ } else {
+ nativeScrollElement.scrollTop += delta;
+ }
+ }
+ }
+
+ /**
+ * Destroys instance and everything it created.
+ *
+ * @return {Void}
+ */
+ self.destroy = function () {
+ if (self.frameResizeObserver) {
+ self.frameResizeObserver.disconnect();
+ self.frameResizeObserver = null;
+ }
+
+ // Reset native FRAME element scroll
+ dom.removeEventListener(frame, 'scroll', resetScroll, {
+ passive: true
+ });
+
+ dom.removeEventListener(scrollSource, wheelEvent, scrollHandler, {
+ passive: true
+ });
+
+ dom.removeEventListener(dragSourceElement, 'touchstart', dragInitSlidee, {
+ passive: true
+ });
+
+ dom.removeEventListener(frame, 'click', onFrameClick, {
+ passive: true,
+ capture: true
+ });
+
+ dom.removeEventListener(dragSourceElement, 'mousedown', dragInitSlidee, {
+ //passive: true
+ });
+
+ // Reset initialized status and return the instance
+ self.initialized = 0;
+ return self;
};
- scrollerFactory.create = function (frame, options) {
- var instance = new scrollerFactory(frame, options);
- return Promise.resolve(instance);
+ var contentRect = {};
+
+ function onResize(entries) {
+ var entry = entries[0];
+
+ if (entry) {
+ var newRect = entry.contentRect;
+
+ // handle element being hidden
+ if (newRect.width === 0 || newRect.height === 0) {
+ return;
+ }
+
+ if (newRect.width !== contentRect.width || newRect.height !== contentRect.height) {
+ contentRect = newRect;
+
+ load(false);
+ }
+ }
+ }
+
+ function resetScroll() {
+ if (o.horizontal) {
+ this.scrollLeft = 0;
+ } else {
+ this.scrollTop = 0;
+ }
+ }
+
+ function onFrameClick(e) {
+ if (e.which === 1) {
+ var focusableParent = focusManager.focusableParent(e.target);
+ if (focusableParent && focusableParent !== document.activeElement) {
+ focusableParent.focus();
+ }
+ }
+ }
+
+ self.getScrollPosition = function () {
+ if (transform) {
+ return self._pos.cur;
+ }
+
+ if (o.horizontal) {
+ return nativeScrollElement.scrollLeft;
+ } else {
+ return nativeScrollElement.scrollTop;
+ }
};
- return scrollerFactory;
-});
+ self.getScrollSize = function () {
+ if (transform) {
+ return slideeSize;
+ }
+
+ if (o.horizontal) {
+ return nativeScrollElement.scrollWidth;
+ } else {
+ return nativeScrollElement.scrollHeight;
+ }
+ };
+
+ /**
+ * Initialize.
+ *
+ * @return {Object}
+ */
+ self.init = function () {
+ if (self.initialized) {
+ return;
+ }
+
+ if (!transform) {
+ if (o.horizontal) {
+ if (layoutManager.desktop && !o.hideScrollbar) {
+ nativeScrollElement.classList.add('scrollX');
+ } else {
+ nativeScrollElement.classList.add('scrollX');
+ nativeScrollElement.classList.add('hiddenScrollX');
+
+ if (layoutManager.tv && o.allowNativeSmoothScroll !== false) {
+ nativeScrollElement.classList.add('smoothScrollX');
+ }
+ }
+
+ if (o.forceHideScrollbars) {
+ nativeScrollElement.classList.add('hiddenScrollX-forced');
+ }
+ } else {
+ if (layoutManager.desktop && !o.hideScrollbar) {
+ nativeScrollElement.classList.add('scrollY');
+ } else {
+ nativeScrollElement.classList.add('scrollY');
+ nativeScrollElement.classList.add('hiddenScrollY');
+
+ if (layoutManager.tv && o.allowNativeSmoothScroll !== false) {
+ nativeScrollElement.classList.add('smoothScrollY');
+ }
+ }
+
+ if (o.forceHideScrollbars) {
+ nativeScrollElement.classList.add('hiddenScrollY-forced');
+ }
+ }
+ } else {
+ frame.style.overflow = 'hidden';
+ slideeElement.style['will-change'] = 'transform';
+ slideeElement.style.transition = 'transform ' + o.speed + 'ms ease-out';
+
+ if (o.horizontal) {
+ slideeElement.classList.add('animatedScrollX');
+ } else {
+ slideeElement.classList.add('animatedScrollY');
+ }
+ }
+
+ if (transform || layoutManager.tv) {
+ // This can prevent others from being able to listen to mouse events
+ dom.addEventListener(dragSourceElement, 'mousedown', dragInitSlidee, {
+ //passive: true
+ });
+ }
+
+ initFrameResizeObserver();
+
+ if (transform) {
+ dom.addEventListener(dragSourceElement, 'touchstart', dragInitSlidee, {
+ passive: true
+ });
+
+ if (!o.horizontal) {
+ dom.addEventListener(frame, 'scroll', resetScroll, {
+ passive: true
+ });
+ }
+
+ if (o.mouseWheel) {
+ // Scrolling navigation
+ dom.addEventListener(scrollSource, wheelEvent, scrollHandler, {
+ passive: true
+ });
+ }
+ } else if (o.horizontal) {
+ // Don't bind to mouse events with vertical scroll since the mouse wheel can handle this natively
+
+ if (o.mouseWheel) {
+ // Scrolling navigation
+ dom.addEventListener(scrollSource, wheelEvent, scrollHandler, {
+ passive: true
+ });
+ }
+ }
+
+ dom.addEventListener(frame, 'click', onFrameClick, {
+ passive: true,
+ capture: true
+ });
+
+ // Mark instance as initialized
+ self.initialized = 1;
+
+ // Load
+ load(true);
+
+ // Return instance
+ return self;
+ };
+};
+
+/**
+ * Slide SLIDEE by amount of pixels.
+ *
+ * @param {Int} delta Pixels/Items. Positive means forward, negative means backward.
+ * @param {Bool} immediate Reposition immediately without an animation.
+ *
+ * @return {Void}
+ */
+scrollerFactory.prototype.slideBy = function (delta, immediate) {
+ if (!delta) {
+ return;
+ }
+ this.slideTo(this._pos.dest + delta, immediate);
+};
+
+/**
+ * Core method for handling `toLocation` methods.
+ *
+ * @param {String} location
+ * @param {Mixed} item
+ * @param {Bool} immediate
+ *
+ * @return {Void}
+ */
+scrollerFactory.prototype.to = function (location, item, immediate) {
+ // Optional arguments logic
+ if (type(item) === 'boolean') {
+ immediate = item;
+ item = undefined;
+ }
+
+ if (item === undefined) {
+ this.slideTo(this._pos[location], immediate);
+ } else {
+ var itemPos = this.getPos(item);
+
+ if (itemPos) {
+ this.slideTo(itemPos[location], immediate, itemPos);
+ }
+ }
+};
+
+/**
+ * Animate element or the whole SLIDEE to the start of the frame.
+ *
+ * @param {Mixed} item Item DOM element, or index starting at 0. Omitting will animate SLIDEE.
+ * @param {Bool} immediate Reposition immediately without an animation.
+ *
+ * @return {Void}
+ */
+scrollerFactory.prototype.toStart = function (item, immediate) {
+ this.to('start', item, immediate);
+};
+
+/**
+ * Animate element or the whole SLIDEE to the end of the frame.
+ *
+ * @param {Mixed} item Item DOM element, or index starting at 0. Omitting will animate SLIDEE.
+ * @param {Bool} immediate Reposition immediately without an animation.
+ *
+ * @return {Void}
+ */
+scrollerFactory.prototype.toEnd = function (item, immediate) {
+ this.to('end', item, immediate);
+};
+
+/**
+ * Animate element or the whole SLIDEE to the center of the frame.
+ *
+ * @param {Mixed} item Item DOM element, or index starting at 0. Omitting will animate SLIDEE.
+ * @param {Bool} immediate Reposition immediately without an animation.
+ *
+ * @return {Void}
+ */
+scrollerFactory.prototype.toCenter = function (item, immediate) {
+ this.to('center', item, immediate);
+};
+
+scrollerFactory.create = function (frame, options) {
+ var instance = new scrollerFactory(frame, options);
+ return Promise.resolve(instance);
+};
+
+export default scrollerFactory;
diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js
index d52f0eb5b3..525372ac88 100644
--- a/src/plugins/htmlVideoPlayer/plugin.js
+++ b/src/plugins/htmlVideoPlayer/plugin.js
@@ -1132,7 +1132,7 @@ function tryRemoveElement(elem) {
*/
getCueCss(appearance, selector) {
return `${selector}::cue {
- ${appearance.text.map((s) => `${s.name}:${s.value}!important;`).join('')}
+ ${appearance.text.map((s) => s.value !== undefined && s.value !== '' ? `${s.name}:${s.value}!important;` : '').join('')}
}`;
}
@@ -1150,7 +1150,7 @@ function tryRemoveElement(elem) {
document.getElementsByTagName('head')[0].appendChild(styleElem);
}
- styleElem.innerHTML = this.getCueCss(subtitleAppearanceHelper.getStyles(userSettings.getSubtitleAppearanceSettings(), true), '.htmlvideoplayer');
+ styleElem.innerHTML = this.getCueCss(subtitleAppearanceHelper.getStyles(userSettings.getSubtitleAppearanceSettings()), '.htmlvideoplayer');
});
}
@@ -1195,17 +1195,28 @@ function tryRemoveElement(elem) {
// download the track json
this.fetchSubtitles(track, item).then(function (data) {
- // show in ui
- console.debug(`downloaded ${data.TrackEvents.length} track events`);
- // add some cues to show the text
- // in safari, the cues need to be added before setting the track mode to showing
- for (const trackEvent of data.TrackEvents) {
- const trackCueObject = window.VTTCue || window.TextTrackCue;
- const cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text, false));
+ import('userSettings').then((userSettings) => {
+ // show in ui
+ console.debug(`downloaded ${data.TrackEvents.length} track events`);
- trackElement.addCue(cue);
- }
- trackElement.mode = 'showing';
+ const subtitleAppearance = userSettings.getSubtitleAppearanceSettings();
+ const cueLine = parseInt(subtitleAppearance.verticalPosition, 10);
+
+ // add some cues to show the text
+ // in safari, the cues need to be added before setting the track mode to showing
+ for (const trackEvent of data.TrackEvents) {
+ const trackCueObject = window.VTTCue || window.TextTrackCue;
+ const cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text, false));
+
+ if (cue.line === 'auto') {
+ cue.line = cueLine;
+ }
+
+ trackElement.addCue(cue);
+ }
+
+ trackElement.mode = 'showing';
+ });
});
}
diff --git a/src/plugins/htmlVideoPlayer/style.css b/src/plugins/htmlVideoPlayer/style.css
index b83a7816f5..880ea86743 100644
--- a/src/plugins/htmlVideoPlayer/style.css
+++ b/src/plugins/htmlVideoPlayer/style.css
@@ -33,16 +33,22 @@ video::-webkit-media-controls {
text-shadow: 0.14em 0.14em 0.14em rgba(0, 0, 0, 1);
-webkit-font-smoothing: antialiased;
font-family: inherit;
+ line-height: normal; /* Restore value. See -webkit-media-text-track-container 'line-height' */
}
-.htmlvideoplayer-moveupsubtitles::-webkit-media-text-track-display {
- /* style the text itself */
- margin-top: -2em;
+.htmlvideoplayer::-webkit-media-text-track-container {
+ font-size: 170% !important; /* Override element inline style */
+ line-height: 50%; /* Child element cannot set line height smaller than its parent has. This allow smaller values for children */
+}
+
+.htmlvideoplayer::-webkit-media-text-track-display {
+ max-width: 70%;
+ margin-left: 15%;
}
.videoSubtitles {
position: fixed;
- bottom: 10%;
+ bottom: 0;
text-align: center;
left: 0;
right: 0;
@@ -53,7 +59,6 @@ video::-webkit-media-controls {
.videoSubtitlesInner {
max-width: 70%;
background-color: rgba(0, 0, 0, 0.8);
- padding: 0.25em;
margin: auto;
display: inline-block;
}
diff --git a/src/plugins/logoScreensaver/plugin.js b/src/plugins/logoScreensaver/plugin.js
index bdd1d34e79..61b8f8a6d6 100644
--- a/src/plugins/logoScreensaver/plugin.js
+++ b/src/plugins/logoScreensaver/plugin.js
@@ -1,165 +1,165 @@
-define(['pluginManager'], function (pluginManager) {
- return function () {
- var self = this;
+import pluginManager from 'pluginManager';
- self.name = 'Logo ScreenSaver';
- self.type = 'screensaver';
- self.id = 'logoscreensaver';
- self.supportsAnonymous = true;
+export default function () {
+ const self = this;
- var interval;
+ self.name = 'Logo ScreenSaver';
+ self.type = 'screensaver';
+ self.id = 'logoscreensaver';
+ self.supportsAnonymous = true;
- function animate() {
- var animations = [
+ let interval;
- bounceInLeft,
- bounceInRight,
- swing,
- tada,
- wobble,
- rotateIn,
- rotateOut
- ];
+ function animate() {
+ const animations = [
- var elem = document.querySelector('.logoScreenSaverImage');
+ bounceInLeft,
+ bounceInRight,
+ swing,
+ tada,
+ wobble,
+ rotateIn,
+ rotateOut
+ ];
- if (elem && elem.animate) {
- var random = getRandomInt(0, animations.length - 1);
+ const elem = document.querySelector('.logoScreenSaverImage');
- animations[random](elem, 1);
+ if (elem && elem.animate) {
+ const random = getRandomInt(0, animations.length - 1);
+
+ animations[random](elem, 1);
+ }
+ }
+
+ function getRandomInt(min, max) {
+ return Math.floor(Math.random() * (max - min + 1)) + min;
+ }
+
+ function bounceInLeft(elem, iterations) {
+ const keyframes = [
+ { transform: 'translate3d(-3000px, 0, 0)', opacity: '0', offset: 0 },
+ { transform: 'translate3d(25px, 0, 0)', opacity: '1', offset: 0.6 },
+ { transform: 'translate3d(-100px, 0, 0)', offset: 0.75 },
+ { transform: 'translate3d(5px, 0, 0)', offset: 0.9 },
+ { transform: 'none', opacity: '1', offset: 1 }];
+ const timing = { duration: 900, iterations: iterations, easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' };
+ return elem.animate(keyframes, timing);
+ }
+
+ function bounceInRight(elem, iterations) {
+ const keyframes = [
+ { transform: 'translate3d(3000px, 0, 0)', opacity: '0', offset: 0 },
+ { transform: 'translate3d(-25px, 0, 0)', opacity: '1', offset: 0.6 },
+ { transform: 'translate3d(100px, 0, 0)', offset: 0.75 },
+ { transform: 'translate3d(-5px, 0, 0)', offset: 0.9 },
+ { transform: 'none', opacity: '1', offset: 1 }];
+ const timing = { duration: 900, iterations: iterations, easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' };
+ return elem.animate(keyframes, timing);
+ }
+
+ function swing(elem, iterations) {
+ const keyframes = [
+ { transform: 'translate(0%)', offset: 0 },
+ { transform: 'rotate3d(0, 0, 1, 15deg)', offset: 0.2 },
+ { transform: 'rotate3d(0, 0, 1, -10deg)', offset: 0.4 },
+ { transform: 'rotate3d(0, 0, 1, 5deg)', offset: 0.6 },
+ { transform: 'rotate3d(0, 0, 1, -5deg)', offset: 0.8 },
+ { transform: 'rotate3d(0, 0, 1, 0deg)', offset: 1 }];
+ const timing = { duration: 900, iterations: iterations };
+ return elem.animate(keyframes, timing);
+ }
+
+ function tada(elem, iterations) {
+ const keyframes = [
+ { transform: 'scale3d(1, 1, 1)', offset: 0 },
+ { transform: 'scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)', offset: 0.1 },
+ { transform: 'scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)', offset: 0.2 },
+ { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.3 },
+ { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)', offset: 0.4 },
+ { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.5 },
+ { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)', offset: 0.6 },
+ { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.7 },
+ { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)', offset: 0.8 },
+ { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.9 },
+ { transform: 'scale3d(1, 1, 1)', offset: 1 }];
+ const timing = { duration: 900, iterations: iterations };
+ return elem.animate(keyframes, timing);
+ }
+
+ function wobble(elem, iterations) {
+ const keyframes = [
+ { transform: 'translate(0%)', offset: 0 },
+ { transform: 'translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg)', offset: 0.15 },
+ { transform: 'translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg)', offset: 0.45 },
+ { transform: 'translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg)', offset: 0.6 },
+ { transform: 'translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg)', offset: 0.75 },
+ { transform: 'translateX(0%)', offset: 1 }];
+ const timing = { duration: 900, iterations: iterations };
+ return elem.animate(keyframes, timing);
+ }
+
+ function rotateIn(elem, iterations) {
+ const keyframes = [{ transform: 'rotate3d(0, 0, 1, -200deg)', opacity: '0', transformOrigin: 'center', offset: 0 },
+ { transform: 'none', opacity: '1', transformOrigin: 'center', offset: 1 }];
+ const timing = { duration: 900, iterations: iterations };
+ return elem.animate(keyframes, timing);
+ }
+
+ function rotateOut(elem, iterations) {
+ const keyframes = [{ transform: 'none', opacity: '1', transformOrigin: 'center', offset: 0 },
+ { transform: 'rotate3d(0, 0, 1, 200deg)', opacity: '0', transformOrigin: 'center', offset: 1 }];
+ const timing = { duration: 900, iterations: iterations };
+ return elem.animate(keyframes, timing);
+ }
+
+ function fadeOut(elem, iterations) {
+ const keyframes = [
+ { opacity: '1', offset: 0 },
+ { opacity: '0', offset: 1 }];
+ const timing = { duration: 400, iterations: iterations };
+ return elem.animate(keyframes, timing);
+ }
+
+ function stopInterval() {
+ if (interval) {
+ clearInterval(interval);
+ interval = null;
+ }
+ }
+
+ self.show = function () {
+ import('css!' + pluginManager.mapPath(self, 'style.css')).then(() => {
+ let elem = document.querySelector('.logoScreenSaver');
+
+ if (!elem) {
+ elem = document.createElement('div');
+ elem.classList.add('logoScreenSaver');
+ document.body.appendChild(elem);
+
+ elem.innerHTML = '

';
}
- }
- function getRandomInt(min, max) {
- return Math.floor(Math.random() * (max - min + 1)) + min;
- }
-
- function bounceInLeft(elem, iterations) {
- var keyframes = [
- { transform: 'translate3d(-3000px, 0, 0)', opacity: '0', offset: 0 },
- { transform: 'translate3d(25px, 0, 0)', opacity: '1', offset: 0.6 },
- { transform: 'translate3d(-100px, 0, 0)', offset: 0.75 },
- { transform: 'translate3d(5px, 0, 0)', offset: 0.9 },
- { transform: 'none', opacity: '1', offset: 1 }];
- var timing = { duration: 900, iterations: iterations, easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' };
- return elem.animate(keyframes, timing);
- }
-
- function bounceInRight(elem, iterations) {
- var keyframes = [
- { transform: 'translate3d(3000px, 0, 0)', opacity: '0', offset: 0 },
- { transform: 'translate3d(-25px, 0, 0)', opacity: '1', offset: 0.6 },
- { transform: 'translate3d(100px, 0, 0)', offset: 0.75 },
- { transform: 'translate3d(-5px, 0, 0)', offset: 0.9 },
- { transform: 'none', opacity: '1', offset: 1 }];
- var timing = { duration: 900, iterations: iterations, easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' };
- return elem.animate(keyframes, timing);
- }
-
- function swing(elem, iterations) {
- var keyframes = [
- { transform: 'translate(0%)', offset: 0 },
- { transform: 'rotate3d(0, 0, 1, 15deg)', offset: 0.2 },
- { transform: 'rotate3d(0, 0, 1, -10deg)', offset: 0.4 },
- { transform: 'rotate3d(0, 0, 1, 5deg)', offset: 0.6 },
- { transform: 'rotate3d(0, 0, 1, -5deg)', offset: 0.8 },
- { transform: 'rotate3d(0, 0, 1, 0deg)', offset: 1 }];
- var timing = { duration: 900, iterations: iterations };
- return elem.animate(keyframes, timing);
- }
-
- function tada(elem, iterations) {
- var keyframes = [
- { transform: 'scale3d(1, 1, 1)', offset: 0 },
- { transform: 'scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)', offset: 0.1 },
- { transform: 'scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)', offset: 0.2 },
- { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.3 },
- { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)', offset: 0.4 },
- { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.5 },
- { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)', offset: 0.6 },
- { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.7 },
- { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)', offset: 0.8 },
- { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.9 },
- { transform: 'scale3d(1, 1, 1)', offset: 1 }];
- var timing = { duration: 900, iterations: iterations };
- return elem.animate(keyframes, timing);
- }
-
- function wobble(elem, iterations) {
- var keyframes = [
- { transform: 'translate(0%)', offset: 0 },
- { transform: 'translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg)', offset: 0.15 },
- { transform: 'translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg)', offset: 0.45 },
- { transform: 'translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg)', offset: 0.6 },
- { transform: 'translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg)', offset: 0.75 },
- { transform: 'translateX(0%)', offset: 1 }];
- var timing = { duration: 900, iterations: iterations };
- return elem.animate(keyframes, timing);
- }
-
- function rotateIn(elem, iterations) {
- var keyframes = [{ transform: 'rotate3d(0, 0, 1, -200deg)', opacity: '0', transformOrigin: 'center', offset: 0 },
- { transform: 'none', opacity: '1', transformOrigin: 'center', offset: 1 }];
- var timing = { duration: 900, iterations: iterations };
- return elem.animate(keyframes, timing);
- }
-
- function rotateOut(elem, iterations) {
- var keyframes = [{ transform: 'none', opacity: '1', transformOrigin: 'center', offset: 0 },
- { transform: 'rotate3d(0, 0, 1, 200deg)', opacity: '0', transformOrigin: 'center', offset: 1 }];
- var timing = { duration: 900, iterations: iterations };
- return elem.animate(keyframes, timing);
- }
-
- function fadeOut(elem, iterations) {
- var keyframes = [
- { opacity: '1', offset: 0 },
- { opacity: '0', offset: 1 }];
- var timing = { duration: 400, iterations: iterations };
- return elem.animate(keyframes, timing);
- }
-
- function stopInterval() {
- if (interval) {
- clearInterval(interval);
- interval = null;
- }
- }
-
- self.show = function () {
- require(['css!' + pluginManager.mapPath(self, 'style.css')], function () {
- var elem = document.querySelector('.logoScreenSaver');
-
- if (!elem) {
- elem = document.createElement('div');
- elem.classList.add('logoScreenSaver');
- document.body.appendChild(elem);
-
- elem.innerHTML = '

';
- }
-
- stopInterval();
- interval = setInterval(animate, 3000);
- });
- };
-
- self.hide = function () {
stopInterval();
-
- var elem = document.querySelector('.logoScreenSaver');
-
- if (elem) {
- var onAnimationFinish = function () {
- elem.parentNode.removeChild(elem);
- };
-
- if (elem.animate) {
- var animation = fadeOut(elem, 1);
- animation.onfinish = onAnimationFinish;
- } else {
- onAnimationFinish();
- }
- }
- };
+ interval = setInterval(animate, 3000);
+ });
};
-});
+
+ self.hide = function () {
+ stopInterval();
+
+ const elem = document.querySelector('.logoScreenSaver');
+
+ if (elem) {
+ const onAnimationFinish = function () {
+ elem.parentNode.removeChild(elem);
+ };
+
+ if (elem.animate) {
+ const animation = fadeOut(elem, 1);
+ animation.onfinish = onAnimationFinish;
+ } else {
+ onAnimationFinish();
+ }
+ }
+ };
+}
diff --git a/src/plugins/playAccessValidation/plugin.js b/src/plugins/playAccessValidation/plugin.js
index 5148d2b821..a9fbeda9a9 100644
--- a/src/plugins/playAccessValidation/plugin.js
+++ b/src/plugins/playAccessValidation/plugin.js
@@ -1,33 +1,26 @@
-define(['connectionManager', 'globalize'], function (connectionManager, globalize) {
- 'use strict';
+import connectionManager from 'connectionManager';
+import globalize from 'globalize';
- function getRequirePromise(deps) {
- return new Promise(function (resolve, reject) {
- require(deps, resolve);
- });
- }
+function showErrorMessage() {
+ return import('alert').then(({default: alert}) => {
+ return alert(globalize.translate('MessagePlayAccessRestricted'));
+ });
+}
- function showErrorMessage() {
- return getRequirePromise(['alert']).then(function (alert) {
- return alert(globalize.translate('MessagePlayAccessRestricted')).then(function () {
- return Promise.reject();
- });
- });
- }
-
- function PlayAccessValidation() {
+class PlayAccessValidation {
+ constructor() {
this.name = 'Playback validation';
this.type = 'preplayintercept';
this.id = 'playaccessvalidation';
this.order = -2;
}
- PlayAccessValidation.prototype.intercept = function (options) {
- var item = options.item;
+ intercept(options) {
+ const item = options.item;
if (!item) {
return Promise.resolve();
}
- var serverId = item.ServerId;
+ const serverId = item.ServerId;
if (!serverId) {
return Promise.resolve();
}
@@ -44,7 +37,7 @@ define(['connectionManager', 'globalize'], function (connectionManager, globaliz
return showErrorMessage();
});
- };
+ }
+}
- return PlayAccessValidation;
-});
+export default PlayAccessValidation;
diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js
index fb1f745df3..c68e0d7a4a 100644
--- a/src/plugins/sessionPlayer/plugin.js
+++ b/src/plugins/sessionPlayer/plugin.js
@@ -1,6 +1,7 @@
define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'], function (playbackManager, events, serverNotifications, connectionManager) {
'use strict';
+ serverNotifications = serverNotifications.default || serverNotifications;
playbackManager = playbackManager.default || playbackManager;
function getActivePlayerId() {
diff --git a/src/scripts/libraryMenu.js b/src/scripts/libraryMenu.js
index bbe01276ba..0780916a7c 100644
--- a/src/scripts/libraryMenu.js
+++ b/src/scripts/libraryMenu.js
@@ -1,11 +1,26 @@
-define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', 'viewManager', 'libraryBrowser', 'appRouter', 'apphost', 'playbackManager', 'syncPlayManager', 'groupSelectionMenu', 'browser', 'globalize', 'scripts/imagehelper', 'paper-icon-button-light', 'material-icons', 'scrollStyles', 'flexStyles'], function (dom, layoutManager, inputManager, connectionManager, events, viewManager, libraryBrowser, appRouter, appHost, playbackManager, syncPlayManager, groupSelectionMenu, browser, globalize, imageHelper) {
- 'use strict';
+import dom from 'dom';
+import layoutManager from 'layoutManager';
+import inputManager from 'inputManager';
+import connectionManager from 'connectionManager';
+import events from 'events';
+import viewManager from 'viewManager';
+import appRouter from 'appRouter';
+import appHost from 'apphost';
+import playbackManager from 'playbackManager';
+import syncPlayManager from 'syncPlayManager';
+import groupSelectionMenu from 'groupSelectionMenu';
+import browser from 'browser';
+import globalize from 'globalize';
+import imageHelper from 'scripts/imagehelper';
+import 'paper-icon-button-light';
+import 'material-icons';
+import 'scrollStyles';
+import 'flexStyles';
- playbackManager = playbackManager.default || playbackManager;
- browser = browser.default || browser;
+/* eslint-disable indent */
function renderHeader() {
- var html = '';
+ let html = '';
html += '