From 7e7613d5de732bc5b59164613252b680895fba77 Mon Sep 17 00:00:00 2001 From: Guilherme Danno Date: Fri, 8 May 2020 19:06:44 -0300 Subject: [PATCH 001/155] Update CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 2eae7e6933..65bb24e9fc 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -35,6 +35,7 @@ - [Thibault Nocchi](https://github.com/ThibaultNocchi) - [MrTimscampi](https://github.com/MrTimscampi) - [Sarab Singh](https://github.com/sarab97) + - [GuilhermeHideki](https://github.com/GuilhermeHideki) # Emby Contributors From 934797e07409e7e56cbed10f67504eaf4f0c9d41 Mon Sep 17 00:00:00 2001 From: Guilherme Danno Date: Sun, 3 May 2020 20:45:14 -0300 Subject: [PATCH 002/155] feat: add mixins file --- src/styles/_mixins.scss | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/styles/_mixins.scss diff --git a/src/styles/_mixins.scss b/src/styles/_mixins.scss new file mode 100644 index 0000000000..ed23ab0833 --- /dev/null +++ b/src/styles/_mixins.scss @@ -0,0 +1,23 @@ +@mixin background-cover($position) { + background-position: $position; + background-repeat: no-repeat; + background-size: cover; +} + +@mixin circle($size) { + @include square($size); + border-radius: 100%; +} + +@mixin position($position, $top: null, $right: null, $bottom: null, $left: null) { + position: $position; + top: $top; + right: $right; + bottom: $bottom; + left: $left; +} + +@mixin square($size) { + height: $size; + width: $size; +} From 9e92bfaae78b3bd1f1dfdc9ba02ced18729bef95 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Sun, 14 Jun 2020 23:37:48 +0300 Subject: [PATCH 003/155] Fix subtitle line spacing --- .../subtitleappearancehelper.js | 71 ++++++------------- src/plugins/htmlVideoPlayer/plugin.js | 2 +- src/plugins/htmlVideoPlayer/style.css | 6 ++ 3 files changed, 30 insertions(+), 49 deletions(-) diff --git a/src/components/subtitlesettings/subtitleappearancehelper.js b/src/components/subtitlesettings/subtitleappearancehelper.js index bec8156aca..503c81472f 100644 --- a/src/components/subtitlesettings/subtitleappearancehelper.js +++ b/src/components/subtitlesettings/subtitleappearancehelper.js @@ -1,55 +1,30 @@ define([], function () { 'use strict'; - function getTextStyles(settings, isCue) { + function getTextStyles(settings) { var list = []; - if (isCue) { - switch (settings.textSize || '') { - - case 'smaller': - list.push({ name: 'font-size', value: '.5em' }); - break; - case 'small': - list.push({ name: 'font-size', value: '.7em' }); - break; - case 'large': - list.push({ name: 'font-size', value: '1.3em' }); - break; - case 'larger': - list.push({ name: 'font-size', value: '1.72em' }); - break; - case 'extralarge': - list.push({ name: 'font-size', value: '2em' }); - break; - default: - case 'medium': - break; - } - } else { - switch (settings.textSize || '') { - - case 'smaller': - list.push({ name: 'font-size', value: '.8em' }); - break; - case 'small': - list.push({ name: 'font-size', value: 'inherit' }); - break; - case 'larger': - list.push({ name: 'font-size', value: '2em' }); - break; - case 'extralarge': - list.push({ name: 'font-size', value: '2.2em' }); - break; - case 'large': - list.push({ name: 'font-size', value: '1.72em' }); - break; - default: - case 'medium': - list.push({ name: 'font-size', value: '1.36em' }); - break; - } + switch (settings.textSize || '') { + case 'smaller': + list.push({ name: 'font-size', value: '.8em' }); + break; + case 'small': + list.push({ name: 'font-size', value: 'inherit' }); + break; + case 'larger': + list.push({ name: 'font-size', value: '2em' }); + break; + case 'extralarge': + list.push({ name: 'font-size', value: '2.2em' }); + break; + case 'large': + list.push({ name: 'font-size', value: '1.72em' }); + break; + default: + case 'medium': + list.push({ name: 'font-size', value: '1.36em' }); + break; } switch (settings.dropShadow || '') { @@ -122,10 +97,10 @@ define([], function () { return []; } - function getStyles(settings, isCue) { + function getStyles(settings) { return { - text: getTextStyles(settings, isCue), + text: getTextStyles(settings), window: getWindowStyles(settings) }; } diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index cc312bb956..9302612539 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -1178,7 +1178,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa document.getElementsByTagName('head')[0].appendChild(styleElem); } - styleElem.innerHTML = getCueCss(subtitleAppearanceHelper.getStyles(userSettings.getSubtitleAppearanceSettings(), true), '.htmlvideoplayer'); + styleElem.innerHTML = getCueCss(subtitleAppearanceHelper.getStyles(userSettings.getSubtitleAppearanceSettings()), '.htmlvideoplayer'); }); } diff --git a/src/plugins/htmlVideoPlayer/style.css b/src/plugins/htmlVideoPlayer/style.css index b83a7816f5..0f63e72d7e 100644 --- a/src/plugins/htmlVideoPlayer/style.css +++ b/src/plugins/htmlVideoPlayer/style.css @@ -33,6 +33,12 @@ 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::-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-moveupsubtitles::-webkit-media-text-track-display { From 597b4258d9eba3a663082632149511d4500264ce Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Tue, 7 Jul 2020 01:06:47 +0300 Subject: [PATCH 004/155] Add subtitle position --- .../subtitleappearancehelper.js | 39 ++++++++-- .../subtitlesettings/subtitlesettings.js | 71 ++++++++++++++++++- .../subtitlesettings.template.html | 53 ++++++++++++++ src/elements/emby-slider/emby-slider.css | 15 ++++ src/elements/emby-slider/emby-slider.js | 10 +++ src/plugins/htmlVideoPlayer/plugin.js | 39 +++++----- src/plugins/htmlVideoPlayer/style.css | 9 ++- src/scripts/settings/userSettings.js | 6 +- src/strings/en-us.json | 5 +- src/strings/ru.json | 5 +- 10 files changed, 219 insertions(+), 33 deletions(-) diff --git a/src/components/subtitlesettings/subtitleappearancehelper.js b/src/components/subtitlesettings/subtitleappearancehelper.js index 503c81472f..e611228d9a 100644 --- a/src/components/subtitlesettings/subtitleappearancehelper.js +++ b/src/components/subtitlesettings/subtitleappearancehelper.js @@ -1,7 +1,7 @@ define([], function () { 'use strict'; - function getTextStyles(settings) { + function getTextStyles(settings, preview) { var list = []; @@ -89,19 +89,44 @@ define([], function () { break; } + if (!preview) { + const pos = parseInt(settings.verticalPosition); + const lineHeight = 1.35; // FIXME: It is better to read this value from element + const line = Math.abs(pos * lineHeight); + if (pos < 0) { + list.push({ name: 'min-height', value: `${line}em` }); + list.push({ name: 'margin-top', value: '' }); + } else { + list.push({ name: 'min-height', value: '' }); + list.push({ name: 'margin-top', value: `${line}em` }); + } + } + return list; } - function getWindowStyles(settings) { + function getWindowStyles(settings, preview) { + const list = []; - return []; + if (!preview) { + const pos = parseInt(settings.verticalPosition); + if (pos < 0) { + list.push({ name: 'top', value: '' }); + list.push({ name: 'bottom', value: '0' }); + } else { + list.push({ name: 'top', value: '0' }); + list.push({ name: 'bottom', value: '' }); + } + } + + return list; } - function getStyles(settings) { + function getStyles(settings, preview) { return { - text: getTextStyles(settings), - window: getWindowStyles(settings) + text: getTextStyles(settings, preview), + window: getWindowStyles(settings, preview) }; } @@ -117,7 +142,7 @@ define([], function () { function applyStyles(elements, appearanceSettings) { - var styles = getStyles(appearanceSettings); + var styles = getStyles(appearanceSettings, !!elements.preview); if (elements.text) { applyStyleList(styles.text, elements.text); diff --git a/src/components/subtitlesettings/subtitlesettings.js b/src/components/subtitlesettings/subtitlesettings.js index d728360d05..819631184c 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -1,4 +1,4 @@ -define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loading', 'connectionManager', 'subtitleAppearanceHelper', 'dom', 'events', 'listViewStyle', 'emby-select', 'emby-input', 'emby-checkbox', 'flexStyles'], function (require, globalize, appSettings, appHost, focusManager, loading, connectionManager, subtitleAppearanceHelper, dom, events) { +define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loading', 'connectionManager', 'subtitleAppearanceHelper', 'dom', 'events', 'layoutManager', 'listViewStyle', 'emby-select', 'emby-input', 'emby-checkbox', 'emby-slider', 'flexStyles'], function (require, globalize, appSettings, appHost, focusManager, loading, connectionManager, subtitleAppearanceHelper, dom, events, layoutManager) { 'use strict'; function populateLanguages(select, languages) { @@ -21,6 +21,7 @@ define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loadi appearanceSettings.font = context.querySelector('#selectFont').value; appearanceSettings.textBackground = context.querySelector('#inputTextBackground').value; appearanceSettings.textColor = context.querySelector('#inputTextColor').value; + appearanceSettings.verticalPosition = context.querySelector('#sliderVerticalPosition').value; return appearanceSettings; } @@ -47,6 +48,7 @@ define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loadi context.querySelector('#inputTextBackground').value = appearanceSettings.textBackground || 'transparent'; context.querySelector('#inputTextColor').value = appearanceSettings.textColor || '#ffffff'; context.querySelector('#selectFont').value = appearanceSettings.font || ''; + context.querySelector('#sliderVerticalPosition').value = appearanceSettings.verticalPosition; context.querySelector('#selectSubtitleBurnIn').value = appSettings.get('subtitleburnin') || ''; @@ -134,10 +136,45 @@ define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loadi var elements = { window: view.querySelector('.subtitleappearance-preview-window'), - text: view.querySelector('.subtitleappearance-preview-text') + text: view.querySelector('.subtitleappearance-preview-text'), + preview: true }; subtitleAppearanceHelper.applyStyles(elements, appearanceSettings); + + subtitleAppearanceHelper.applyStyles({ + window: view.querySelector('.subtitleappearance-fullpreview-window'), + text: view.querySelector('.subtitleappearance-fullpreview-text') + }, appearanceSettings); + } + + const subtitlePreviewDelay = 1000; + let subtitlePreviewTimer; + + function showSubtitlePreview(persistent) { + clearTimeout(subtitlePreviewTimer); + + this._fullPreview.classList.remove('subtitleappearance-fullpreview-hide'); + + if (persistent) { + this._refFullPreview++; + } + + if (this._refFullPreview === 0) { + subtitlePreviewTimer = setTimeout(hideSubtitlePreview.bind(this), subtitlePreviewDelay); + } + } + + function hideSubtitlePreview(persistent) { + clearTimeout(subtitlePreviewTimer); + + if (persistent) { + this._refFullPreview--; + } + + if (this._refFullPreview === 0) { + this._fullPreview.classList.add('subtitleappearance-fullpreview-hide'); + } } function embed(options, self) { @@ -162,6 +199,36 @@ define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loadi if (appHost.supports('subtitleappearancesettings')) { options.element.querySelector('.subtitleAppearanceSection').classList.remove('hide'); + + self._fullPreview = options.element.querySelector('.subtitleappearance-fullpreview'); + self._refFullPreview = 0; + + const sliderVerticalPosition = options.element.querySelector('#sliderVerticalPosition'); + sliderVerticalPosition.addEventListener('input', onAppearanceFieldChange); + sliderVerticalPosition.addEventListener('input', () => showSubtitlePreview.call(self)); + + const eventPrefix = window.PointerEvent ? 'pointer' : 'mouse'; + sliderVerticalPosition.addEventListener(`${eventPrefix}enter`, () => showSubtitlePreview.call(self, true)); + sliderVerticalPosition.addEventListener(`${eventPrefix}leave`, () => hideSubtitlePreview.call(self, true)); + + if (layoutManager.tv) { + sliderVerticalPosition.addEventListener('focus', () => showSubtitlePreview.call(self, true)); + sliderVerticalPosition.addEventListener('blur', () => hideSubtitlePreview.call(self, true)); + + // Give CustomElements time to attach + setTimeout(() => { + sliderVerticalPosition.classList.add('focusable'); + sliderVerticalPosition.enableKeyboardDragging(); + }, 0); + } + + options.element.querySelector('.chkPreview').addEventListener('change', (e) => { + if (e.target.checked) { + showSubtitlePreview.call(self, true); + } else { + hideSubtitlePreview.call(self, true); + } + }); } self.loadData(); diff --git a/src/components/subtitlesettings/subtitlesettings.template.html b/src/components/subtitlesettings/subtitlesettings.template.html index 716296a257..2f49fa4c3e 100644 --- a/src/components/subtitlesettings/subtitlesettings.template.html +++ b/src/components/subtitlesettings/subtitlesettings.template.html @@ -38,6 +38,45 @@ ${HeaderSubtitleAppearance} + + +
+
+
+ ${HeaderSubtitleAppearance} +
+ ${TheseSettingsAffectSubtitlesOnThisDevice} +
+
+
+
@@ -89,6 +128,20 @@
+ +
+
+ +
+
${SubtitleVerticalPositionHelp}
+
+ +
+ +
'; - itemHtml += ''; - } - itemHtml += '
'; - itemHtml += '
'; - itemHtml += '

'; - itemHtml += notification.Category; - itemHtml += '

'; - if (showHelp) { - showHelp = false; - itemHtml += ''; - itemHtml += globalize.translate('Help'); - itemHtml += ''; - } +function reload(page) { + loading.show(); + ApiClient.getJSON(ApiClient.getUrl('Notifications/Types')).then(function (list) { + let html = ''; + let lastCategory = ''; + let showHelp = true; + html += list.map(function (notification) { + let itemHtml = ''; + if (notification.Category !== lastCategory) { + lastCategory = notification.Category; + if (lastCategory) { + itemHtml += '
'; itemHtml += '
'; - itemHtml += '
'; } - itemHtml += ''; - if (notification.Enabled) { - itemHtml += ''; - } else { - itemHtml += ''; + itemHtml += '
'; + itemHtml += '
'; + itemHtml += '

'; + itemHtml += notification.Category; + itemHtml += '

'; + if (showHelp) { + showHelp = false; + itemHtml += '
'; + itemHtml += globalize.translate('Help'); + itemHtml += ''; } - itemHtml += '
'; - itemHtml += '
' + notification.Name + '
'; itemHtml += '
'; - itemHtml += ''; - itemHtml += ''; - return itemHtml; - }).join(''); - - if (list.length) { - html += '
'; - html += '
'; + itemHtml += '
'; } - page.querySelector('.notificationList').innerHTML = html; - loading.hide(); - }); - } + itemHtml += ''; + if (notification.Enabled) { + itemHtml += ''; + } else { + itemHtml += ''; + } + itemHtml += '
'; + itemHtml += '
' + notification.Name + '
'; + itemHtml += '
'; + itemHtml += ''; + itemHtml += '
'; + return itemHtml; + }).join(''); - return function(view, params) { - view.addEventListener('viewshow', function() { - reload(view); - }); - }; -}); + if (list.length) { + html += '
'; + html += '
'; + } + page.querySelector('.notificationList').innerHTML = html; + loading.hide(); + }); +} + +export default function (view, params) { + view.addEventListener('viewshow', function () { + reload(view); + }); +} From 287cc06963b5935e1a7979c763d26a1cc7d3d17f Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 26 Jul 2020 11:29:02 +0100 Subject: [PATCH 006/155] Migration of edititemmetadata to ES6 module --- package.json | 1 + src/controllers/edititemmetadata.js | 51 ++++++++++++++--------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index dbedd2922e..ecb33b77c8 100644 --- a/package.json +++ b/package.json @@ -189,6 +189,7 @@ "src/controllers/dashboard/users/userparentalcontrol.js", "src/controllers/dashboard/users/userpasswordpage.js", "src/controllers/dashboard/users/userprofilespage.js", + "src/controllers/edititemmetadata.js", "src/controllers/playback/nowplaying.js", "src/controllers/playback/videoosd.js", "src/controllers/searchpage.js", diff --git a/src/controllers/edititemmetadata.js b/src/controllers/edititemmetadata.js index 1a3647a758..57c72dda28 100644 --- a/src/controllers/edititemmetadata.js +++ b/src/controllers/edititemmetadata.js @@ -1,31 +1,30 @@ -define(['loading', 'scripts/editorsidebar'], function (loading) { - 'use strict'; +import loading from 'loading'; +import 'scripts/editorsidebar'; - function reload(context, itemId) { - loading.show(); +function reload(context, itemId) { + loading.show(); - if (itemId) { - require(['metadataEditor'], function ({default: metadataEditor}) { - metadataEditor.embed(context.querySelector('.editPageInnerContent'), itemId, ApiClient.serverInfo().Id); - }); - } else { - context.querySelector('.editPageInnerContent').innerHTML = ''; - loading.hide(); - } + if (itemId) { + import('metadataEditor').then(({ default: metadataEditor }) => { + metadataEditor.embed(context.querySelector('.editPageInnerContent'), itemId, ApiClient.serverInfo().Id); + }); + } else { + context.querySelector('.editPageInnerContent').innerHTML = ''; + loading.hide(); } +} - return function (view, params) { - view.addEventListener('viewshow', function () { - reload(this, MetadataEditor.getCurrentItemId()); - }); - MetadataEditor.setCurrentItemId(null); - view.querySelector('.libraryTree').addEventListener('itemclicked', function (event) { - var data = event.detail; +export default function (view, params) { + view.addEventListener('viewshow', function () { + reload(this, MetadataEditor.getCurrentItemId()); + }); + MetadataEditor.setCurrentItemId(null); + view.querySelector('.libraryTree').addEventListener('itemclicked', function (event) { + var data = event.detail; - if (data.id != MetadataEditor.getCurrentItemId()) { - MetadataEditor.setCurrentItemId(data.id); - reload(view, data.id); - } - }); - }; -}); + if (data.id != MetadataEditor.getCurrentItemId()) { + MetadataEditor.setCurrentItemId(data.id); + reload(view, data.id); + } + }); +} From 3658b4471a1314d32bb84eb0cb83f6149fc5da1a Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 26 Jul 2020 11:29:26 +0100 Subject: [PATCH 007/155] Migration of Favorites and Hometab to ES6 modules --- package.json | 2 + src/controllers/favorites.js | 108 +++++++++++++++++++---------------- src/controllers/home.js | 2 +- src/controllers/hometab.js | 67 +++++++++++----------- 4 files changed, 97 insertions(+), 82 deletions(-) diff --git a/package.json b/package.json index ecb33b77c8..de3fe62adc 100644 --- a/package.json +++ b/package.json @@ -190,6 +190,8 @@ "src/controllers/dashboard/users/userpasswordpage.js", "src/controllers/dashboard/users/userprofilespage.js", "src/controllers/edititemmetadata.js", + "src/controllers/favorites.js", + "src/controllers/hometab.js", "src/controllers/playback/nowplaying.js", "src/controllers/playback/videoosd.js", "src/controllers/searchpage.js", diff --git a/src/controllers/favorites.js b/src/controllers/favorites.js index b4c7936239..532801bfaf 100644 --- a/src/controllers/favorites.js +++ b/src/controllers/favorites.js @@ -1,5 +1,15 @@ -define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'apphost', 'layoutManager', 'focusManager', 'emby-itemscontainer', 'emby-scroller'], function (appRouter, cardBuilder, dom, globalize, connectionManager, appHost, layoutManager, focusManager) { - 'use strict'; +import appRouter from 'appRouter'; +import cardBuilder from 'cardBuilder'; +import dom from 'dom'; +import globalize from 'globalize'; +import connectionManager from 'connectionManager'; +import appHost from 'apphost'; +import layoutManager from 'layoutManager'; +import focusManager from 'focusManager'; +import 'emby-itemscontainer'; +import 'emby-scroller'; + +/* eslint-disable indent */ function enableScrollX() { return true; @@ -133,8 +143,8 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap function getFetchDataFn(section) { return function () { - var apiClient = this.apiClient; - var options = { + const apiClient = this.apiClient; + const options = { SortBy: (section.types, 'SeriesName,SortName'), SortOrder: 'Ascending', Filters: 'IsFavorite', @@ -145,7 +155,7 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap EnableTotalRecordCount: false }; options.Limit = 20; - var userId = apiClient.getCurrentUserId(); + const userId = apiClient.getCurrentUserId(); if ('MusicArtist' === section.types) { return apiClient.getArtists(userId, options); @@ -170,17 +180,17 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap function getItemsHtmlFn(section) { return function (items) { - var supportsImageAnalysis = appHost.supports('imageanalysis'); - var cardLayout = (appHost.preferVisualCards || supportsImageAnalysis) && section.autoCardLayout && section.showTitle; + const supportsImageAnalysis = appHost.supports('imageanalysis'); + let cardLayout = (appHost.preferVisualCards || supportsImageAnalysis) && section.autoCardLayout && section.showTitle; cardLayout = false; - var serverId = this.apiClient.serverId(); - var leadingButtons = layoutManager.tv ? [{ + const serverId = this.apiClient.serverId(); + const leadingButtons = layoutManager.tv ? [{ name: globalize.translate('All'), id: 'more', icon: 'favorite', routeUrl: getRouteUrl(section, serverId) }] : null; - var lines = 0; + let lines = 0; if (section.showTitle) { lines++; @@ -216,23 +226,12 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap }; } - function FavoritesTab(view, params) { - this.view = view; - this.params = params; - this.apiClient = connectionManager.currentApiClient(); - this.sectionsContainer = view.querySelector('.sections'); - createSections(this, this.sectionsContainer, this.apiClient); - } - function createSections(instance, elem, apiClient) { - var i; - var length; - var sections = getSections(); - var html = ''; + const sections = getSections(); + let html = ''; - for (i = 0, length = sections.length; i < length; i++) { - var section = sections[i]; - var sectionClass = 'verticalSection'; + for (const section of sections) { + let sectionClass = 'verticalSection'; if (!section.showTitle) { sectionClass += ' verticalSection-extrabottompadding'; @@ -258,23 +257,32 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap } elem.innerHTML = html; - var elems = elem.querySelectorAll('.itemsContainer'); + const elems = elem.querySelectorAll('.itemsContainer'); - for (i = 0, length = elems.length; i < length; i++) { - var itemsContainer = elems[i]; + for (let i = 0, length = elems.length; i < length; i++) { + const itemsContainer = elems[i]; itemsContainer.fetchData = getFetchDataFn(sections[i]).bind(instance); itemsContainer.getItemsHtml = getItemsHtmlFn(sections[i]).bind(instance); itemsContainer.parentContainer = dom.parentWithClass(itemsContainer, 'verticalSection'); } } - FavoritesTab.prototype.onResume = function (options) { - var promises = (this.apiClient, []); - var view = this.view; - var elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); +class FavoritesTab { + constructor(view, params) { + this.view = view; + this.params = params; + this.apiClient = connectionManager.currentApiClient(); + this.sectionsContainer = view.querySelector('.sections'); + createSections(this, this.sectionsContainer, this.apiClient); + } - for (var i = 0, length = elems.length; i < length; i++) { - promises.push(elems[i].resume(options)); + onResume(options) { + const promises = (this.apiClient, []); + const view = this.view; + const elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); + + for (const elem of elems) { + promises.push(elem.resume(options)); } Promise.all(promises).then(function () { @@ -282,30 +290,32 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap focusManager.autoFocus(view); } }); - }; + } - FavoritesTab.prototype.onPause = function () { - var elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); + onPause() { + const elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); - for (var i = 0, length = elems.length; i < length; i++) { - elems[i].pause(); + for (const elem of elems) { + elem.pause(); } - }; + } - FavoritesTab.prototype.destroy = function () { + destroy() { this.view = null; this.params = null; this.apiClient = null; - var elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); + const elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); - for (var i = 0, length = elems.length; i < length; i++) { - elems[i].fetchData = null; - elems[i].getItemsHtml = null; - elems[i].parentContainer = null; + for (const elem of elems) { + elem.fetchData = null; + elem.getItemsHtml = null; + elem.parentContainer = null; } this.sectionsContainer = null; - }; + } +} - return FavoritesTab; -}); +export default FavoritesTab; + +/* eslint-enable indent */ diff --git a/src/controllers/home.js b/src/controllers/home.js index 9a4cea2227..ea3fef3ce2 100644 --- a/src/controllers/home.js +++ b/src/controllers/home.js @@ -40,7 +40,7 @@ define(['tabbedView', 'globalize', 'require', 'emby-tabs', 'emby-button', 'emby- var controller = instance.tabControllers[index]; if (!controller) { - controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params); + controller = new controllerFactory.default(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params); instance.tabControllers[index] = controller; } diff --git a/src/controllers/hometab.js b/src/controllers/hometab.js index 8e2a1f92e7..4b7ddee057 100644 --- a/src/controllers/hometab.js +++ b/src/controllers/hometab.js @@ -1,27 +1,23 @@ -define(['userSettings', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'focusManager', 'homeSections', 'emby-itemscontainer'], function (userSettings, loading, connectionManager, appHost, layoutManager, focusManager, homeSections) { - 'use strict'; +import * as userSettings from 'userSettings'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; +import appHost from 'apphost'; +import layoutManager from 'layoutManager'; +import focusManager from 'focusManager'; +import homeSections from 'homeSections'; +import 'emby-itemscontainer'; - function HomeTab(view, params) { +class HomeTab { + constructor(view, params) { this.view = view; this.params = params; this.apiClient = connectionManager.currentApiClient(); this.sectionsContainer = view.querySelector('.sections'); view.querySelector('.sections').addEventListener('settingschange', onHomeScreenSettingsChanged.bind(this)); } - - function onHomeScreenSettingsChanged() { - this.sectionsRendered = false; - - if (!this.paused) { - this.onResume({ - refresh: true - }); - } - } - - HomeTab.prototype.onResume = function (options) { + onResume(options) { if (this.sectionsRendered) { - var sectionsContainer = this.sectionsContainer; + const sectionsContainer = this.sectionsContainer; if (sectionsContainer) { return homeSections.resume(sectionsContainer, options); @@ -31,8 +27,8 @@ define(['userSettings', 'loading', 'connectionManager', 'apphost', 'layoutManage } loading.show(); - var view = this.view; - var apiClient = this.apiClient; + const view = this.view; + const apiClient = this.apiClient; this.destroyHomeSections(); this.sectionsRendered = true; return apiClient.getCurrentUser().then(function (user) { @@ -44,31 +40,38 @@ define(['userSettings', 'loading', 'connectionManager', 'apphost', 'layoutManage loading.hide(); }); }); - }; - - HomeTab.prototype.onPause = function () { - var sectionsContainer = this.sectionsContainer; + } + onPause() { + const sectionsContainer = this.sectionsContainer; if (sectionsContainer) { homeSections.pause(sectionsContainer); } - }; - - HomeTab.prototype.destroy = function () { + } + destroy() { this.view = null; this.params = null; this.apiClient = null; this.destroyHomeSections(); this.sectionsContainer = null; - }; - - HomeTab.prototype.destroyHomeSections = function () { - var sectionsContainer = this.sectionsContainer; + } + destroyHomeSections() { + const sectionsContainer = this.sectionsContainer; if (sectionsContainer) { homeSections.destroySections(sectionsContainer); } - }; + } +} - return HomeTab; -}); +function onHomeScreenSettingsChanged() { + this.sectionsRendered = false; + + if (!this.paused) { + this.onResume({ + refresh: true + }); + } +} + +export default HomeTab; From 0bf23576ee9b95176390ea1b3ba3f6d4c36715c7 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Sun, 26 Jul 2020 15:00:09 +0300 Subject: [PATCH 008/155] Extract styles --- .../subtitlesettings/subtitlesettings.css | 26 +++++++++++++++++ .../subtitlesettings/subtitlesettings.js | 1 + .../subtitlesettings.template.html | 29 ------------------- 3 files changed, 27 insertions(+), 29 deletions(-) create mode 100644 src/components/subtitlesettings/subtitlesettings.css diff --git a/src/components/subtitlesettings/subtitlesettings.css b/src/components/subtitlesettings/subtitlesettings.css new file mode 100644 index 0000000000..e8cb9a50b5 --- /dev/null +++ b/src/components/subtitlesettings/subtitlesettings.css @@ -0,0 +1,26 @@ +.subtitleappearance-fullpreview { + position: fixed; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 1000; + pointer-events: none; + transition: 0.2s +} + +.subtitleappearance-fullpreview-hide { + opacity: 0; +} + +.subtitleappearance-fullpreview-window { + position: absolute; + width: 100%; + font-size: 170%; + text-align: center; +} + +.subtitleappearance-fullpreview-text { + display: inline-block; + max-width: 70%; +} diff --git a/src/components/subtitlesettings/subtitlesettings.js b/src/components/subtitlesettings/subtitlesettings.js index 07d83d86ea..f7e37c8212 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -16,6 +16,7 @@ import 'emby-slider'; import 'emby-input'; import 'emby-checkbox'; import 'flexStyles'; +import 'css!./subtitlesettings' /** * Subtitle settings. diff --git a/src/components/subtitlesettings/subtitlesettings.template.html b/src/components/subtitlesettings/subtitlesettings.template.html index 2f49fa4c3e..af9139188c 100644 --- a/src/components/subtitlesettings/subtitlesettings.template.html +++ b/src/components/subtitlesettings/subtitlesettings.template.html @@ -38,35 +38,6 @@ ${HeaderSubtitleAppearance} - -
From 3339315b9cbdca0cd19a37c345d4e5de6f9a84e0 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Sun, 26 Jul 2020 18:12:10 +0300 Subject: [PATCH 009/155] Add missing semicolon (Lint) --- src/components/subtitlesettings/subtitlesettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/subtitlesettings/subtitlesettings.js b/src/components/subtitlesettings/subtitlesettings.js index f7e37c8212..68defc656a 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -16,7 +16,7 @@ import 'emby-slider'; import 'emby-input'; import 'emby-checkbox'; import 'flexStyles'; -import 'css!./subtitlesettings' +import 'css!./subtitlesettings'; /** * Subtitle settings. From 270b717cd032e0d6ca4700d45813cba7479841d0 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Sun, 26 Jul 2020 19:25:58 +0300 Subject: [PATCH 010/155] Add missing semicolon (Lint) --- src/components/subtitlesettings/subtitlesettings.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/subtitlesettings/subtitlesettings.css b/src/components/subtitlesettings/subtitlesettings.css index e8cb9a50b5..204757f10f 100644 --- a/src/components/subtitlesettings/subtitlesettings.css +++ b/src/components/subtitlesettings/subtitlesettings.css @@ -6,7 +6,7 @@ left: 0; z-index: 1000; pointer-events: none; - transition: 0.2s + transition: 0.2s; } .subtitleappearance-fullpreview-hide { From 8fb8dacdf1bca533c4021dc9adff35cfd98b9aea Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 26 Jul 2020 22:45:00 +0200 Subject: [PATCH 011/155] Migrate shell, serverNotifications to ES6 + remove searchtab --- package.json | 2 + src/assets/css/librarybrowser.css | 6 - src/components/guide/guide.js | 2 + src/components/itemsrefresher.js | 2 + src/components/notifications/notifications.js | 2 + src/components/playback/playbackmanager.js | 1 + .../recordingcreator/recordingfields.js | 2 + src/controllers/livetv/livetvsuggested.js | 6 - src/controllers/movies/moviesrecommended.js | 6 - src/controllers/music/musicrecommended.js | 6 - src/controllers/shows/tvrecommended.js | 7 - src/plugins/sessionPlayer/plugin.js | 2 + src/scripts/searchtab.js | 57 --- src/scripts/serverNotifications.js | 407 +++++++++--------- src/scripts/shell.js | 43 +- 15 files changed, 239 insertions(+), 312 deletions(-) delete mode 100644 src/scripts/searchtab.js diff --git a/package.json b/package.json index d1831b13ee..12ed63929a 100644 --- a/package.json +++ b/package.json @@ -250,9 +250,11 @@ "src/scripts/inputManager.js", "src/scripts/keyboardNavigation.js", "src/scripts/playlists.js", + "src/scripts/serverNotifications.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", "src/scripts/settings/webSettings.js", + "src/scripts/shell.js", "src/scripts/taskbutton.js", "src/scripts/themeLoader.js", "src/scripts/touchHelper.js" diff --git a/src/assets/css/librarybrowser.css b/src/assets/css/librarybrowser.css index 61815a590f..644dba9371 100644 --- a/src/assets/css/librarybrowser.css +++ b/src/assets/css/librarybrowser.css @@ -236,12 +236,6 @@ text-align: center; } -.layout-desktop .searchTabButton, -.layout-mobile .searchTabButton, -.layout-tv .headerSearchButton { - display: none !important; -} - .mainDrawer-scrollContainer { padding-bottom: 10vh; } diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index bb4a36497c..e18f053a5a 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -1,6 +1,8 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'webcomponents'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) { 'use strict'; + serverNotifications = serverNotifications.default || serverNotifications; + function showViewSettings(instance) { require(['guide-settings-dialog'], function (guideSettingsDialog) { diff --git a/src/components/itemsrefresher.js b/src/components/itemsrefresher.js index 6da74eef80..f50813a7e0 100644 --- a/src/components/itemsrefresher.js +++ b/src/components/itemsrefresher.js @@ -1,6 +1,8 @@ define(['playbackManager', 'serverNotifications', 'events'], function (playbackManager, serverNotifications, events) { 'use strict'; + serverNotifications = serverNotifications.default || serverNotifications; + function onUserDataChanged(e, apiClient, userData) { var instance = this; diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index c8480e4f15..d12b14cc01 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -1,6 +1,8 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'require'], function (serverNotifications, playbackManager, events, globalize, require) { 'use strict'; + serverNotifications = serverNotifications.default || serverNotifications; + function onOneDocumentClick() { document.removeEventListener('click', onOneDocumentClick); document.removeEventListener('keydown', onOneDocumentClick); diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index fe3ff11250..a6fc3942be 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3455,6 +3455,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (apphost.supports('remotecontrol')) { require(['serverNotifications'], function (serverNotifications) { + serverNotifications = serverNotifications.default || serverNotifications; events.on(serverNotifications, 'ServerShuttingDown', self.setDefaultPlayerActive.bind(self)); events.on(serverNotifications, 'ServerRestarting', self.setDefaultPlayerActive.bind(self)); }); diff --git a/src/components/recordingcreator/recordingfields.js b/src/components/recordingcreator/recordingfields.js index 84348fcfbc..5fc0f24af4 100644 --- a/src/components/recordingcreator/recordingfields.js +++ b/src/components/recordingcreator/recordingfields.js @@ -1,6 +1,8 @@ define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loading', 'apphost', 'dom', 'recordingHelper', 'events', 'paper-icon-button-light', 'emby-button', 'css!./recordingfields', 'flexStyles'], function (globalize, connectionManager, serverNotifications, require, loading, appHost, dom, recordingHelper, events) { 'use strict'; + serverNotifications = serverNotifications.default || serverNotifications; + function loadData(parent, program, apiClient) { if (program.IsSeries) { parent.querySelector('.recordSeriesContainer').classList.remove('hide'); diff --git a/src/controllers/livetv/livetvsuggested.js b/src/controllers/livetv/livetvsuggested.js index 036eee9fc6..16cee8a496 100644 --- a/src/controllers/livetv/livetvsuggested.js +++ b/src/controllers/livetv/livetvsuggested.js @@ -167,9 +167,6 @@ define(['layoutManager', 'userSettings', 'inputManager', 'loading', 'globalize', name: globalize.translate('HeaderSchedule') }, { name: globalize.translate('TabSeries') - }, { - name: globalize.translate('ButtonSearch'), - cssClass: 'searchTabButton' }]; } @@ -253,9 +250,6 @@ define(['layoutManager', 'userSettings', 'inputManager', 'loading', 'globalize', case 5: depends.push('controllers/livetv/livetvseriestimers'); break; - - case 6: - depends.push('scripts/searchtab'); } require(depends, function (controllerFactory) { diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js index d948c1cef7..11aa6e3fec 100644 --- a/src/controllers/movies/moviesrecommended.js +++ b/src/controllers/movies/moviesrecommended.js @@ -222,9 +222,6 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu' name: globalize.translate('TabCollections') }, { name: globalize.translate('TabGenres') - }, { - name: globalize.translate('ButtonSearch'), - cssClass: 'searchTabButton' }]; } @@ -291,9 +288,6 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu' case 5: depends.push('controllers/movies/moviegenres'); break; - - case 6: - depends.push('scripts/searchtab'); } require(depends, function (controllerFactory) { diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js index 3f025799f6..1409d6de3f 100644 --- a/src/controllers/music/musicrecommended.js +++ b/src/controllers/music/musicrecommended.js @@ -180,9 +180,6 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' name: globalize.translate('TabSongs') }, { name: globalize.translate('TabGenres') - }, { - name: globalize.translate('ButtonSearch'), - cssClass: 'searchTabButton' }]; } @@ -283,9 +280,6 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' case 6: depends.push('controllers/music/musicgenres'); break; - - case 7: - depends.push('scripts/searchtab'); } require(depends, function (controllerFactory) { diff --git a/src/controllers/shows/tvrecommended.js b/src/controllers/shows/tvrecommended.js index 7edd2ab501..25459b7b6a 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/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index 084aa027cf..a8cb1e3579 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -1,6 +1,8 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'], function (playbackManager, events, serverNotifications, connectionManager) { 'use strict'; + serverNotifications = serverNotifications.default || serverNotifications; + function getActivePlayerId() { var info = playbackManager.getPlayerInfo(); return info ? info.id : null; diff --git a/src/scripts/searchtab.js b/src/scripts/searchtab.js deleted file mode 100644 index e012b8a4b2..0000000000 --- a/src/scripts/searchtab.js +++ /dev/null @@ -1,57 +0,0 @@ -define(['searchFields', 'searchResults', 'events'], function (SearchFields, SearchResults, events) { - 'use strict'; - - SearchFields = SearchFields.default || SearchFields; - SearchResults = SearchResults.default || SearchResults; - - function init(instance, tabContent, options) { - tabContent.innerHTML = '
'; - instance.searchFields = new SearchFields({ - element: tabContent.querySelector('.searchFields') - }); - instance.searchResults = new SearchResults({ - element: tabContent.querySelector('.searchResults'), - serverId: ApiClient.serverId(), - parentId: options.parentId, - collectionType: options.collectionType - }); - events.on(instance.searchFields, 'search', function (e, value) { - instance.searchResults.search(value); - }); - } - - function SearchTab(view, tabContent, options) { - var self = this; - options = options || {}; - init(this, tabContent, options); - - self.preRender = function () {}; - - self.renderTab = function () { - var searchFields = this.searchFields; - - if (searchFields) { - searchFields.focus(); - } - }; - } - - SearchTab.prototype.destroy = function () { - var searchFields = this.searchFields; - - if (searchFields) { - searchFields.destroy(); - } - - this.searchFields = null; - var searchResults = this.searchResults; - - if (searchResults) { - searchResults.destroy(); - } - - this.searchResults = null; - }; - - return SearchTab; -}); diff --git a/src/scripts/serverNotifications.js b/src/scripts/serverNotifications.js index 331a75329c..83af40c4e6 100644 --- a/src/scripts/serverNotifications.js +++ b/src/scripts/serverNotifications.js @@ -1,211 +1,216 @@ -define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'inputManager', 'focusManager', 'appRouter'], function (connectionManager, playbackManager, syncPlayManager, events, inputManager, focusManager, appRouter) { - 'use strict'; +import connectionManager from 'connectionManager'; +import playbackManager from 'playbackManager'; +import syncPlayManager from 'syncPlayManager'; +import events from 'events'; +import inputManager from 'inputManager'; +import focusManager from 'focusManager'; +import appRouter from 'appRouter'; - var serverNotifications = {}; +const serverNotifications = {}; - function notifyApp() { - inputManager.notify(); - } +function notifyApp() { + inputManager.notify(); +} - function displayMessage(cmd) { - var args = cmd.Arguments; - if (args.TimeoutMs) { - require(['toast'], function (toast) { - toast({ title: args.Header, text: args.Text }); - }); - } else { - require(['alert'], function (alert) { - alert.default({ title: args.Header, text: args.Text }); - }); - } - } - - function displayContent(cmd, apiClient) { - if (!playbackManager.isPlayingLocally(['Video', 'Book'])) { - appRouter.showItem(cmd.Arguments.ItemId, apiClient.serverId()); - } - } - - function playTrailers(apiClient, itemId) { - apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) { - playbackManager.playTrailers(item); +function displayMessage(cmd) { + const args = cmd.Arguments; + if (args.TimeoutMs) { + require(['toast'], function (toast) { + toast({ title: args.Header, text: args.Text }); + }); + } else { + require(['alert'], function (alert) { + alert.default({ title: args.Header, text: args.Text }); }); } +} - function processGeneralCommand(cmd, apiClient) { - console.debug('Received command: ' + cmd.Name); - switch (cmd.Name) { - case 'Select': - inputManager.handleCommand('select'); - return; - case 'Back': - inputManager.handleCommand('back'); - return; - case 'MoveUp': - inputManager.handleCommand('up'); - return; - case 'MoveDown': - inputManager.handleCommand('down'); - return; - case 'MoveLeft': - inputManager.handleCommand('left'); - return; - case 'MoveRight': - inputManager.handleCommand('right'); - return; - case 'PageUp': - inputManager.handleCommand('pageup'); - return; - case 'PageDown': - inputManager.handleCommand('pagedown'); - return; - case 'PlayTrailers': - playTrailers(apiClient, cmd.Arguments.ItemId); - break; - case 'SetRepeatMode': - playbackManager.setRepeatMode(cmd.Arguments.RepeatMode); - break; - case 'SetShuffleQueue': - playbackManager.setQueueShuffleMode(cmd.Arguments.ShuffleMode); - break; - case 'VolumeUp': - inputManager.handleCommand('volumeup'); - return; - case 'VolumeDown': - inputManager.handleCommand('volumedown'); - return; - case 'ChannelUp': - inputManager.handleCommand('channelup'); - return; - case 'ChannelDown': - inputManager.handleCommand('channeldown'); - return; - case 'Mute': - inputManager.handleCommand('mute'); - return; - case 'Unmute': - inputManager.handleCommand('unmute'); - return; - case 'ToggleMute': - inputManager.handleCommand('togglemute'); - return; - case 'SetVolume': - notifyApp(); - playbackManager.setVolume(cmd.Arguments.Volume); - break; - case 'SetAudioStreamIndex': - notifyApp(); - playbackManager.setAudioStreamIndex(parseInt(cmd.Arguments.Index)); - break; - case 'SetSubtitleStreamIndex': - notifyApp(); - playbackManager.setSubtitleStreamIndex(parseInt(cmd.Arguments.Index)); - break; - case 'ToggleFullscreen': - inputManager.handleCommand('togglefullscreen'); - return; - case 'GoHome': - inputManager.handleCommand('home'); - return; - case 'GoToSettings': - inputManager.handleCommand('settings'); - return; - case 'DisplayContent': - displayContent(cmd, apiClient); - break; - case 'GoToSearch': - inputManager.handleCommand('search'); - return; - case 'DisplayMessage': - displayMessage(cmd); - break; - case 'ToggleOsd': - // todo - break; - case 'ToggleContextMenu': - // todo - break; - case 'TakeScreenShot': - // todo - break; - case 'SendKey': - // todo - break; - case 'SendString': - // todo - focusManager.sendText(cmd.Arguments.String); - break; - default: - console.debug('processGeneralCommand does not recognize: ' + cmd.Name); - break; - } - - notifyApp(); +function displayContent(cmd, apiClient) { + if (!playbackManager.isPlayingLocally(['Video', 'Book'])) { + appRouter.showItem(cmd.Arguments.ItemId, apiClient.serverId()); } +} - function onMessageReceived(e, msg) { - var apiClient = this; - if (msg.MessageType === 'Play') { - notifyApp(); - var serverId = apiClient.serverInfo().Id; - if (msg.Data.PlayCommand === 'PlayNext') { - playbackManager.queueNext({ ids: msg.Data.ItemIds, serverId: serverId }); - } else if (msg.Data.PlayCommand === 'PlayLast') { - playbackManager.queue({ ids: msg.Data.ItemIds, serverId: serverId }); - } else { - playbackManager.play({ - ids: msg.Data.ItemIds, - startPositionTicks: msg.Data.StartPositionTicks, - mediaSourceId: msg.Data.MediaSourceId, - audioStreamIndex: msg.Data.AudioStreamIndex, - subtitleStreamIndex: msg.Data.SubtitleStreamIndex, - startIndex: msg.Data.StartIndex, - serverId: serverId - }); - } - } else if (msg.MessageType === 'Playstate') { - if (msg.Data.Command === 'Stop') { - inputManager.handleCommand('stop'); - } else if (msg.Data.Command === 'Pause') { - inputManager.handleCommand('pause'); - } else if (msg.Data.Command === 'Unpause') { - inputManager.handleCommand('play'); - } else if (msg.Data.Command === 'PlayPause') { - inputManager.handleCommand('playpause'); - } else if (msg.Data.Command === 'Seek') { - playbackManager.seek(msg.Data.SeekPositionTicks); - } else if (msg.Data.Command === 'NextTrack') { - inputManager.handleCommand('next'); - } else if (msg.Data.Command === 'PreviousTrack') { - inputManager.handleCommand('previous'); - } else { - notifyApp(); - } - } else if (msg.MessageType === 'GeneralCommand') { - var cmd = msg.Data; - processGeneralCommand(cmd, apiClient); - } else if (msg.MessageType === 'UserDataChanged') { - if (msg.Data.UserId === apiClient.getCurrentUserId()) { - for (var i = 0, length = msg.Data.UserDataList.length; i < length; i++) { - events.trigger(serverNotifications, 'UserDataChanged', [apiClient, msg.Data.UserDataList[i]]); - } - } - } else if (msg.MessageType === 'SyncPlayCommand') { - syncPlayManager.processCommand(msg.Data, apiClient); - } else if (msg.MessageType === 'SyncPlayGroupUpdate') { - syncPlayManager.processGroupUpdate(msg.Data, apiClient); - } else { - events.trigger(serverNotifications, msg.MessageType, [apiClient, msg.Data]); - } - } - function bindEvents(apiClient) { - events.off(apiClient, 'message', onMessageReceived); - events.on(apiClient, 'message', onMessageReceived); - } - - connectionManager.getApiClients().forEach(bindEvents); - events.on(connectionManager, 'apiclientcreated', function (e, newApiClient) { - bindEvents(newApiClient); +function playTrailers(apiClient, itemId) { + apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) { + playbackManager.playTrailers(item); }); - return serverNotifications; +} + +function processGeneralCommand(cmd, apiClient) { + console.debug('Received command: ' + cmd.Name); + switch (cmd.Name) { + case 'Select': + inputManager.handleCommand('select'); + return; + case 'Back': + inputManager.handleCommand('back'); + return; + case 'MoveUp': + inputManager.handleCommand('up'); + return; + case 'MoveDown': + inputManager.handleCommand('down'); + return; + case 'MoveLeft': + inputManager.handleCommand('left'); + return; + case 'MoveRight': + inputManager.handleCommand('right'); + return; + case 'PageUp': + inputManager.handleCommand('pageup'); + return; + case 'PageDown': + inputManager.handleCommand('pagedown'); + return; + case 'PlayTrailers': + playTrailers(apiClient, cmd.Arguments.ItemId); + break; + case 'SetRepeatMode': + playbackManager.setRepeatMode(cmd.Arguments.RepeatMode); + break; + case 'SetShuffleQueue': + playbackManager.setQueueShuffleMode(cmd.Arguments.ShuffleMode); + break; + case 'VolumeUp': + inputManager.handleCommand('volumeup'); + return; + case 'VolumeDown': + inputManager.handleCommand('volumedown'); + return; + case 'ChannelUp': + inputManager.handleCommand('channelup'); + return; + case 'ChannelDown': + inputManager.handleCommand('channeldown'); + return; + case 'Mute': + inputManager.handleCommand('mute'); + return; + case 'Unmute': + inputManager.handleCommand('unmute'); + return; + case 'ToggleMute': + inputManager.handleCommand('togglemute'); + return; + case 'SetVolume': + notifyApp(); + playbackManager.setVolume(cmd.Arguments.Volume); + break; + case 'SetAudioStreamIndex': + notifyApp(); + playbackManager.setAudioStreamIndex(parseInt(cmd.Arguments.Index)); + break; + case 'SetSubtitleStreamIndex': + notifyApp(); + playbackManager.setSubtitleStreamIndex(parseInt(cmd.Arguments.Index)); + break; + case 'ToggleFullscreen': + inputManager.handleCommand('togglefullscreen'); + return; + case 'GoHome': + inputManager.handleCommand('home'); + return; + case 'GoToSettings': + inputManager.handleCommand('settings'); + return; + case 'DisplayContent': + displayContent(cmd, apiClient); + break; + case 'GoToSearch': + inputManager.handleCommand('search'); + return; + case 'DisplayMessage': + displayMessage(cmd); + break; + case 'ToggleOsd': + // todo + break; + case 'ToggleContextMenu': + // todo + break; + case 'TakeScreenShot': + // todo + break; + case 'SendKey': + // todo + break; + case 'SendString': + // todo + focusManager.sendText(cmd.Arguments.String); + break; + default: + console.debug('processGeneralCommand does not recognize: ' + cmd.Name); + break; + } + + notifyApp(); +} + +function onMessageReceived(e, msg) { + const apiClient = this; + if (msg.MessageType === 'Play') { + notifyApp(); + const serverId = apiClient.serverInfo().Id; + if (msg.Data.PlayCommand === 'PlayNext') { + playbackManager.queueNext({ ids: msg.Data.ItemIds, serverId: serverId }); + } else if (msg.Data.PlayCommand === 'PlayLast') { + playbackManager.queue({ ids: msg.Data.ItemIds, serverId: serverId }); + } else { + playbackManager.play({ + ids: msg.Data.ItemIds, + startPositionTicks: msg.Data.StartPositionTicks, + mediaSourceId: msg.Data.MediaSourceId, + audioStreamIndex: msg.Data.AudioStreamIndex, + subtitleStreamIndex: msg.Data.SubtitleStreamIndex, + startIndex: msg.Data.StartIndex, + serverId: serverId + }); + } + } else if (msg.MessageType === 'Playstate') { + if (msg.Data.Command === 'Stop') { + inputManager.handleCommand('stop'); + } else if (msg.Data.Command === 'Pause') { + inputManager.handleCommand('pause'); + } else if (msg.Data.Command === 'Unpause') { + inputManager.handleCommand('play'); + } else if (msg.Data.Command === 'PlayPause') { + inputManager.handleCommand('playpause'); + } else if (msg.Data.Command === 'Seek') { + playbackManager.seek(msg.Data.SeekPositionTicks); + } else if (msg.Data.Command === 'NextTrack') { + inputManager.handleCommand('next'); + } else if (msg.Data.Command === 'PreviousTrack') { + inputManager.handleCommand('previous'); + } else { + notifyApp(); + } + } else if (msg.MessageType === 'GeneralCommand') { + const cmd = msg.Data; + processGeneralCommand(cmd, apiClient); + } else if (msg.MessageType === 'UserDataChanged') { + if (msg.Data.UserId === apiClient.getCurrentUserId()) { + for (let i = 0, length = msg.Data.UserDataList.length; i < length; i++) { + events.trigger(serverNotifications, 'UserDataChanged', [apiClient, msg.Data.UserDataList[i]]); + } + } + } else if (msg.MessageType === 'SyncPlayCommand') { + syncPlayManager.processCommand(msg.Data, apiClient); + } else if (msg.MessageType === 'SyncPlayGroupUpdate') { + syncPlayManager.processGroupUpdate(msg.Data, apiClient); + } else { + events.trigger(serverNotifications, msg.MessageType, [apiClient, msg.Data]); + } +} +function bindEvents(apiClient) { + events.off(apiClient, 'message', onMessageReceived); + events.on(apiClient, 'message', onMessageReceived); +} + +connectionManager.getApiClients().forEach(bindEvents); +events.on(connectionManager, 'apiclientcreated', function (e, newApiClient) { + bindEvents(newApiClient); }); + +export default serverNotifications; diff --git a/src/scripts/shell.js b/src/scripts/shell.js index 4f1aa0c8de..390ddae82c 100644 --- a/src/scripts/shell.js +++ b/src/scripts/shell.js @@ -1,24 +1,21 @@ -define([], function () { - 'use strict'; - - return { - openUrl: function (url, target) { - if (window.NativeShell) { - window.NativeShell.openUrl(url, target); - } else { - window.open(url, target || '_blank'); - } - - }, - enableFullscreen: function () { - if (window.NativeShell) { - window.NativeShell.enableFullscreen(); - } - }, - disableFullscreen: function () { - if (window.NativeShell) { - window.NativeShell.disableFullscreen(); - } +// TODO: This seems like a good candidate for deprecation +export default { + openUrl: function (url, target) { + if (window.NativeShell) { + window.NativeShell.openUrl(url, target); + } else { + window.open(url, target || '_blank'); } - }; -}); + + }, + enableFullscreen: function () { + if (window.NativeShell) { + window.NativeShell.enableFullscreen(); + } + }, + disableFullscreen: function () { + if (window.NativeShell) { + window.NativeShell.disableFullscreen(); + } + } +}; From 4fce7f8be5076cb8cc05546c6ef0b33ebee6f14e Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 26 Jul 2020 22:52:55 +0200 Subject: [PATCH 012/155] Migrate scrollHelper to ES6 --- package.json | 1 + .../collectionEditor/collectionEditor.js | 2 +- src/components/dialogHelper/dialogHelper.js | 2 +- src/components/filtermenu/filtermenu.js | 1 + src/components/guide/guide-settings.js | 2 + src/components/guide/guide.js | 2 + .../imageDownloader/imageDownloader.js | 2 + src/components/imageeditor/imageeditor.js | 2 + .../playlisteditor/playlisteditor.js | 2 +- .../recordingcreator/recordingcreator.js | 2 + .../recordingcreator/recordingeditor.js | 2 + .../recordingcreator/seriesrecordingeditor.js | 2 + src/components/refreshdialog/refreshdialog.js | 1 + src/components/sortmenu/sortmenu.js | 1 + .../subtitleeditor/subtitleeditor.js | 1 + src/components/tunerPicker.js | 2 + src/components/viewSettings/viewSettings.js | 1 + src/scripts/scrollHelper.js | 250 +++++++++--------- 18 files changed, 150 insertions(+), 128 deletions(-) diff --git a/package.json b/package.json index 12ed63929a..7a80b89140 100644 --- a/package.json +++ b/package.json @@ -250,6 +250,7 @@ "src/scripts/inputManager.js", "src/scripts/keyboardNavigation.js", "src/scripts/playlists.js", + "src/scripts/scrollHelper.js", "src/scripts/serverNotifications.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", diff --git a/src/components/collectionEditor/collectionEditor.js b/src/components/collectionEditor/collectionEditor.js index 18cc0d311f..67daad9f2e 100644 --- a/src/components/collectionEditor/collectionEditor.js +++ b/src/components/collectionEditor/collectionEditor.js @@ -212,7 +212,7 @@ import 'flexStyles'; } function centerFocus(elem, horiz, on) { - import('scrollHelper').then(scrollHelper => { + import('scrollHelper').then((scrollHelper) => { const fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/dialogHelper/dialogHelper.js b/src/components/dialogHelper/dialogHelper.js index ca7c94a416..af1a278cb4 100644 --- a/src/components/dialogHelper/dialogHelper.js +++ b/src/components/dialogHelper/dialogHelper.js @@ -376,7 +376,7 @@ import 'scrollStyles'; } function centerFocus(elem, horiz, on) { - import('scrollHelper').then(scrollHelper => { + import('scrollHelper').then((scrollHelper) => { const fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/filtermenu/filtermenu.js b/src/components/filtermenu/filtermenu.js index 936e2b0407..075af143d2 100644 --- a/src/components/filtermenu/filtermenu.js +++ b/src/components/filtermenu/filtermenu.js @@ -194,6 +194,7 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', function centerFocus(elem, horiz, on) { require(['scrollHelper'], function (scrollHelper) { + scrollHelper = scrollHelper.default || scrollHelper; var fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/guide/guide-settings.js b/src/components/guide/guide-settings.js index 77a3637251..aded7ac5dd 100644 --- a/src/components/guide/guide-settings.js +++ b/src/components/guide/guide-settings.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectionManager', 'require', 'loading', 'scrollHelper', 'emby-checkbox', 'emby-radio', 'css!./../formdialog', 'material-icons'], function (dialogHelper, globalize, userSettings, layoutManager, connectionManager, require, loading, scrollHelper) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + function saveCategories(context, options) { var categories = []; diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index e18f053a5a..0d3c721e2d 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -1,6 +1,8 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'webcomponents'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + serverNotifications = serverNotifications.default || serverNotifications; function showViewSettings(instance) { diff --git a/src/components/imageDownloader/imageDownloader.js b/src/components/imageDownloader/imageDownloader.js index fbe98c532f..9ad65dd157 100644 --- a/src/components/imageDownloader/imageDownloader.js +++ b/src/components/imageDownloader/imageDownloader.js @@ -1,6 +1,8 @@ define(['dom', 'loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader', 'browser', 'layoutManager', 'scrollHelper', 'globalize', 'require', 'emby-checkbox', 'paper-icon-button-light', 'emby-button', 'formDialogStyle', 'cardStyle'], function (dom, loading, appHost, dialogHelper, connectionManager, imageLoader, browser, layoutManager, scrollHelper, globalize, require) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var enableFocusTransform = !browser.slow && !browser.edge; var currentItemId; diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index 0a873fa4c7..766304f9aa 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', 'focusManager', 'globalize', 'scrollHelper', 'imageLoader', 'require', 'browser', 'apphost', 'cardStyle', 'formDialogStyle', 'emby-button', 'paper-icon-button-light', 'css!./imageeditor'], function (dialogHelper, connectionManager, loading, dom, layoutManager, focusManager, globalize, scrollHelper, imageLoader, require, browser, appHost) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var enableFocusTransform = !browser.slow && !browser.edge; var currentItem; diff --git a/src/components/playlisteditor/playlisteditor.js b/src/components/playlisteditor/playlisteditor.js index 7b1e915e1f..78f0cf3dec 100644 --- a/src/components/playlisteditor/playlisteditor.js +++ b/src/components/playlisteditor/playlisteditor.js @@ -210,7 +210,7 @@ import 'emby-button'; } function centerFocus(elem, horiz, on) { - import('scrollHelper').then(scrollHelper => { + import('scrollHelper').then((scrollHelper) => { const fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/recordingcreator/recordingcreator.js b/src/components/recordingcreator/recordingcreator.js index d18d5fcb6c..3b7cbe49aa 100644 --- a/src/components/recordingcreator/recordingcreator.js +++ b/src/components/recordingcreator/recordingcreator.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'datetime', 'imageLoader', 'recordingFields', 'events', 'emby-checkbox', 'emby-button', 'emby-collapse', 'emby-input', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper, datetime, imageLoader, recordingFields, events) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var currentDialog; var closeAction; var currentRecordingFields; diff --git a/src/components/recordingcreator/recordingeditor.js b/src/components/recordingcreator/recordingeditor.js index c3f40fcddb..2fde735404 100644 --- a/src/components/recordingcreator/recordingeditor.js +++ b/src/components/recordingcreator/recordingeditor.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'imageLoader', 'scrollStyles', 'emby-button', 'emby-collapse', 'emby-input', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons', 'flexStyles'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper, imageLoader) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var currentDialog; var recordingDeleted = false; var currentItemId; diff --git a/src/components/recordingcreator/seriesrecordingeditor.js b/src/components/recordingcreator/seriesrecordingeditor.js index a101ce53ec..053dd1a12c 100644 --- a/src/components/recordingcreator/seriesrecordingeditor.js +++ b/src/components/recordingcreator/seriesrecordingeditor.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'imageLoader', 'datetime', 'scrollStyles', 'emby-button', 'emby-checkbox', 'emby-input', 'emby-select', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons', 'flexStyles'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper, imageLoader, datetime) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var currentDialog; var recordingUpdated = false; var recordingDeleted = false; diff --git a/src/components/refreshdialog/refreshdialog.js b/src/components/refreshdialog/refreshdialog.js index 3edb725c4a..593cc0dc2d 100644 --- a/src/components/refreshdialog/refreshdialog.js +++ b/src/components/refreshdialog/refreshdialog.js @@ -42,6 +42,7 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionM function centerFocus(elem, horiz, on) { require(['scrollHelper'], function (scrollHelper) { + scrollHelper = scrollHelper.default || scrollHelper; var fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/sortmenu/sortmenu.js b/src/components/sortmenu/sortmenu.js index dbf7ef1a7f..abe55a6092 100644 --- a/src/components/sortmenu/sortmenu.js +++ b/src/components/sortmenu/sortmenu.js @@ -17,6 +17,7 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana function centerFocus(elem, horiz, on) { require(['scrollHelper'], function (scrollHelper) { + scrollHelper = scrollHelper.default || scrollHelper; var fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js index 9c0992c53c..4c33252574 100644 --- a/src/components/subtitleeditor/subtitleeditor.js +++ b/src/components/subtitleeditor/subtitleeditor.js @@ -420,6 +420,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', function centerFocus(elem, horiz, on) { require(['scrollHelper'], function (scrollHelper) { + scrollHelper = scrollHelper.default || scrollHelper; var fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/tunerPicker.js b/src/components/tunerPicker.js index e7c92851a4..f064f95152 100644 --- a/src/components/tunerPicker.js +++ b/src/components/tunerPicker.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'dom', 'layoutManager', 'connectionManager', 'globalize', 'loading', 'browser', 'focusManager', 'scrollHelper', 'material-icons', 'formDialogStyle', 'emby-button', 'emby-itemscontainer', 'cardStyle'], function (dialogHelper, dom, layoutManager, connectionManager, globalize, loading, browser, focusManager, scrollHelper) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var enableFocusTransform = !browser.slow && !browser.edge; function getEditorHtml() { diff --git a/src/components/viewSettings/viewSettings.js b/src/components/viewSettings/viewSettings.js index 28a9854c34..198c0a541c 100644 --- a/src/components/viewSettings/viewSettings.js +++ b/src/components/viewSettings/viewSettings.js @@ -33,6 +33,7 @@ define(['require', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'conne function centerFocus(elem, horiz, on) { require(['scrollHelper'], function (scrollHelper) { + scrollHelper = scrollHelper.default || scrollHelper; var fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/scripts/scrollHelper.js b/src/scripts/scrollHelper.js index 1a36594026..020888a2e3 100644 --- a/src/scripts/scrollHelper.js +++ b/src/scripts/scrollHelper.js @@ -1,137 +1,137 @@ -define(['focusManager', 'dom', 'scrollStyles'], function (focusManager, dom) { - 'use strict'; +import focusManager from 'focusManager'; +import dom from 'dom'; +import 'scrollStyles'; - function getBoundingClientRect(elem) { +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 }; - } + // 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 }; + } +} + +export function getPosition(scrollContainer, item, horizontal) { + + const slideeOffset = getBoundingClientRect(scrollContainer); + const itemOffset = getBoundingClientRect(item); + + let offset = horizontal ? itemOffset.left - slideeOffset.left : itemOffset.top - slideeOffset.top; + let size = horizontal ? itemOffset.width : itemOffset.height; + if (!size && size !== 0) { + size = item[horizontal ? 'offsetWidth' : 'offsetHeight']; } - function getPosition(scrollContainer, item, horizontal) { + const currentStart = horizontal ? scrollContainer.scrollLeft : scrollContainer.scrollTop; - var slideeOffset = getBoundingClientRect(scrollContainer); - var itemOffset = getBoundingClientRect(item); + offset += currentStart; - var offset = horizontal ? itemOffset.left - slideeOffset.left : itemOffset.top - slideeOffset.top; - var size = horizontal ? itemOffset.width : itemOffset.height; - if (!size && size !== 0) { - size = item[horizontal ? 'offsetWidth' : 'offsetHeight']; - } + const frameSize = horizontal ? scrollContainer.offsetWidth : scrollContainer.offsetHeight; - var currentStart = horizontal ? scrollContainer.scrollLeft : scrollContainer.scrollTop; + const currentEnd = currentStart + frameSize; - offset += currentStart; - - var frameSize = horizontal ? scrollContainer.offsetWidth : scrollContainer.offsetHeight; - - var currentEnd = currentStart + frameSize; - - var isVisible = offset >= currentStart && (offset + size) <= currentEnd; - - return { - start: offset, - center: (offset - (frameSize / 2) + (size / 2)), - end: offset - frameSize + size, - size: size, - isVisible: isVisible - }; - } - - function toCenter(container, elem, horizontal, skipWhenVisible) { - var pos = getPosition(container, elem, horizontal); - - if (skipWhenVisible && pos.isVisible) { - return; - } - - if (container.scrollTo) { - if (horizontal) { - container.scrollTo(pos.center, 0); - } else { - container.scrollTo(0, pos.center); - } - } else { - if (horizontal) { - container.scrollLeft = Math.round(pos.center); - } else { - container.scrollTop = Math.round(pos.center); - } - } - } - - function toStart(container, elem, horizontal, skipWhenVisible) { - var pos = getPosition(container, elem, horizontal); - - if (skipWhenVisible && pos.isVisible) { - return; - } - - if (container.scrollTo) { - if (horizontal) { - container.scrollTo(pos.start, 0); - } else { - container.scrollTo(0, pos.start); - } - } else { - if (horizontal) { - container.scrollLeft = Math.round(pos.start); - } else { - container.scrollTop = Math.round(pos.start); - } - } - } - - function centerOnFocus(e, scrollSlider, horizontal) { - var focused = focusManager.focusableParent(e.target); - - if (focused) { - toCenter(scrollSlider, focused, horizontal); - } - } - - function centerOnFocusHorizontal(e) { - centerOnFocus(e, this, true); - } - function centerOnFocusVertical(e) { - centerOnFocus(e, this, false); - } + const isVisible = offset >= currentStart && (offset + size) <= currentEnd; return { - getPosition: getPosition, - centerFocus: { - on: function (element, horizontal) { - if (horizontal) { - dom.addEventListener(element, 'focus', centerOnFocusHorizontal, { - capture: true, - passive: true - }); - } else { - dom.addEventListener(element, 'focus', centerOnFocusVertical, { - capture: true, - passive: true - }); - } - }, - off: function (element, horizontal) { - if (horizontal) { - dom.removeEventListener(element, 'focus', centerOnFocusHorizontal, { - capture: true, - passive: true - }); - } else { - dom.removeEventListener(element, 'focus', centerOnFocusVertical, { - capture: true, - passive: true - }); - } + start: offset, + center: (offset - (frameSize / 2) + (size / 2)), + end: offset - frameSize + size, + size: size, + isVisible: isVisible + }; +} + +export function toCenter(container, elem, horizontal, skipWhenVisible) { + const pos = getPosition(container, elem, horizontal); + + if (skipWhenVisible && pos.isVisible) { + return; + } + + if (container.scrollTo) { + if (horizontal) { + container.scrollTo(pos.center, 0); + } else { + container.scrollTo(0, pos.center); + } + } else { + if (horizontal) { + container.scrollLeft = Math.round(pos.center); + } else { + container.scrollTop = Math.round(pos.center); + } + } +} + +export function toStart(container, elem, horizontal, skipWhenVisible) { + const pos = getPosition(container, elem, horizontal); + + if (skipWhenVisible && pos.isVisible) { + return; + } + + if (container.scrollTo) { + if (horizontal) { + container.scrollTo(pos.start, 0); + } else { + container.scrollTo(0, pos.start); + } + } else { + if (horizontal) { + container.scrollLeft = Math.round(pos.start); + } else { + container.scrollTop = Math.round(pos.start); + } + } +} + +function centerOnFocus(e, scrollSlider, horizontal) { + const focused = focusManager.focusableParent(e.target); + + if (focused) { + toCenter(scrollSlider, focused, horizontal); + } +} + +function centerOnFocusHorizontal(e) { + centerOnFocus(e, this, true); +} +function centerOnFocusVertical(e) { + centerOnFocus(e, this, false); +} + +export default { + getPosition: getPosition, + centerFocus: { + on: function (element, horizontal) { + if (horizontal) { + dom.addEventListener(element, 'focus', centerOnFocusHorizontal, { + capture: true, + passive: true + }); + } else { + dom.addEventListener(element, 'focus', centerOnFocusVertical, { + capture: true, + passive: true + }); } }, - toCenter: toCenter, - toStart: toStart - }; -}); + off: function (element, horizontal) { + if (horizontal) { + dom.removeEventListener(element, 'focus', centerOnFocusHorizontal, { + capture: true, + passive: true + }); + } else { + dom.removeEventListener(element, 'focus', centerOnFocusVertical, { + capture: true, + passive: true + }); + } + } + }, + toCenter: toCenter, + toStart: toStart +}; From b6dfeb59fca3dffae15eaa0bdfcedbff94f6e7bb Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 27 Jul 2020 10:26:09 +0100 Subject: [PATCH 013/155] Migration of toast and upnextdialog to ES6 modules --- package.json | 2 + src/components/toast/toast.js | 66 ++++++++++----------- src/components/upnextdialog/upnextdialog.js | 40 ++++++++----- 3 files changed, 60 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index da8c87aedd..e88a68efbd 100644 --- a/package.json +++ b/package.json @@ -156,6 +156,8 @@ "src/components/syncPlay/playbackPermissionManager.js", "src/components/syncPlay/syncPlayManager.js", "src/components/syncPlay/timeSyncManager.js", + "src/components/toast/toast.js", + "src/components/upnextdialog/upnextdialog.js", "src/controllers/session/addServer/index.js", "src/controllers/session/forgotPassword/index.js", "src/controllers/session/redeemPassword/index.js", diff --git a/src/components/toast/toast.js b/src/components/toast/toast.js index 7b8e49e4d2..36226ab8e3 100644 --- a/src/components/toast/toast.js +++ b/src/components/toast/toast.js @@ -1,42 +1,40 @@ -define(['css!./toast'], function () { - 'use strict'; +import 'css!./toast'; - function remove(elem) { +function remove(elem) { - setTimeout(function () { - elem.parentNode.removeChild(elem); - }, 300); + setTimeout(function () { + elem.parentNode.removeChild(elem); + }, 300); +} + +function animateRemove(elem) { + + setTimeout(function () { + + elem.classList.remove('toastVisible'); + remove(elem); + + }, 3300); +} + +export default function (options) { + + if (typeof options === 'string') { + options = { + text: options + }; } - function animateRemove(elem) { + var elem = document.createElement('div'); + elem.classList.add('toast'); + elem.innerHTML = options.text; - setTimeout(function () { + document.body.appendChild(elem); - elem.classList.remove('toastVisible'); - remove(elem); + setTimeout(function () { + elem.classList.add('toastVisible'); - }, 3300); - } + animateRemove(elem); - return function (options) { - - if (typeof options === 'string') { - options = { - text: options - }; - } - - var elem = document.createElement('div'); - elem.classList.add('toast'); - elem.innerHTML = options.text; - - document.body.appendChild(elem); - - setTimeout(function () { - elem.classList.add('toastVisible'); - - animateRemove(elem); - - }, 300); - }; -}); + }, 300); +} diff --git a/src/components/upnextdialog/upnextdialog.js b/src/components/upnextdialog/upnextdialog.js index 3e9c9f9c5e..e45b3d5951 100644 --- a/src/components/upnextdialog/upnextdialog.js +++ b/src/components/upnextdialog/upnextdialog.js @@ -1,5 +1,17 @@ -define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'layoutManager', 'focusManager', 'globalize', 'itemHelper', 'css!./upnextdialog', 'emby-button', 'flexStyles'], function (dom, playbackManager, connectionManager, events, mediaInfo, layoutManager, focusManager, globalize, itemHelper) { - 'use strict'; +import dom from 'dom'; +import playbackManager from 'playbackManager'; +import connectionManager from 'connectionManager'; +import events from 'events'; +import mediaInfo from 'mediaInfo'; +import layoutManager from 'layoutManager'; +import focusManager from 'focusManager'; +import globalize from 'globalize'; +import itemHelper from 'itemHelper'; +import 'css!./upnextdialog'; +import 'emby-button'; +import 'flexStyles'; + +/* eslint-disable indent */ var transitionEndEventName = dom.whichTransitionEvent(); @@ -289,14 +301,14 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l instance._countdownTextTimeout = setInterval(setNextVideoText.bind(instance), 400); } - function UpNextDialog(options) { +class UpNextDialog { + constructor(options) { this.options = options; init(this, options); } - - UpNextDialog.prototype.show = function () { + show() { var elem = this.options.parent; @@ -316,20 +328,20 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } startComingUpNextHideTimer(this); - }; - - UpNextDialog.prototype.hide = function () { + } + hide() { hideComingUpNext.call(this); - }; - - UpNextDialog.prototype.destroy = function () { + } + destroy() { hideComingUpNext.call(this); this.options = null; this.itemType = null; - }; + } +} - return UpNextDialog; -}); +export default UpNextDialog; + +/* eslint-enable indent */ From 1d74c5c85a57263a051c5bcc6e63dd609f0fa525 Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 27 Jul 2020 10:30:24 +0100 Subject: [PATCH 014/155] Update variables --- src/components/toast/toast.js | 2 +- src/components/upnextdialog/upnextdialog.js | 48 ++++++++++----------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/components/toast/toast.js b/src/components/toast/toast.js index 36226ab8e3..5eacc2787b 100644 --- a/src/components/toast/toast.js +++ b/src/components/toast/toast.js @@ -25,7 +25,7 @@ export default function (options) { }; } - var elem = document.createElement('div'); + const elem = document.createElement('div'); elem.classList.add('toast'); elem.innerHTML = options.text; diff --git a/src/components/upnextdialog/upnextdialog.js b/src/components/upnextdialog/upnextdialog.js index e45b3d5951..9879f0ed47 100644 --- a/src/components/upnextdialog/upnextdialog.js +++ b/src/components/upnextdialog/upnextdialog.js @@ -13,7 +13,7 @@ import 'flexStyles'; /* eslint-disable indent */ - var transitionEndEventName = dom.whichTransitionEvent(); + const transitionEndEventName = dom.whichTransitionEvent(); function seriesImageUrl(item, options) { @@ -79,7 +79,7 @@ import 'flexStyles'; if (item) { - var imgUrl = seriesImageUrl(item, { type: 'Primary' }) || + let imgUrl = seriesImageUrl(item, { type: 'Primary' }) || seriesImageUrl(item, { type: 'Thumb' }) || imageUrl(item, { type: 'Primary' }); @@ -100,7 +100,7 @@ import 'flexStyles'; function getHtml() { - var html = ''; + let html = ''; html += '
'; html += '
'; @@ -137,17 +137,17 @@ import 'flexStyles'; function setNextVideoText() { - var instance = this; + const instance = this; - var elem = instance.options.parent; + const elem = instance.options.parent; - var secondsRemaining = Math.max(Math.round(getTimeRemainingMs(instance) / 1000), 0); + const secondsRemaining = Math.max(Math.round(getTimeRemainingMs(instance) / 1000), 0); console.debug('up next seconds remaining: ' + secondsRemaining); - var timeText = '' + globalize.translate('HeaderSecondsValue', secondsRemaining) + ''; + const timeText = '' + globalize.translate('HeaderSecondsValue', secondsRemaining) + ''; - var nextVideoText = instance.itemType === 'Episode' ? + const nextVideoText = instance.itemType === 'Episode' ? globalize.translate('HeaderNextEpisodePlayingInValue', timeText) : globalize.translate('HeaderNextVideoPlayingInValue', timeText); @@ -156,9 +156,9 @@ import 'flexStyles'; function fillItem(item) { - var instance = this; + const instance = this; - var elem = instance.options.parent; + const elem = instance.options.parent; setPoster(elem.querySelector('.upNextDialog-poster'), item); @@ -167,7 +167,7 @@ import 'flexStyles'; elem.querySelector('.upNextDialog-mediainfo').innerHTML = mediaInfo.getPrimaryMediaInfoHtml(item, { }); - var title = itemHelper.getDisplayName(item); + let title = itemHelper.getDisplayName(item); if (item.SeriesName) { title = item.SeriesName + ' - ' + title; } @@ -188,11 +188,11 @@ import 'flexStyles'; function onStartNowClick() { - var options = this.options; + const options = this.options; if (options) { - var player = options.player; + const player = options.player; this.hide(); @@ -216,7 +216,7 @@ import 'flexStyles'; function clearHideAnimationEventListeners(instance, elem) { - var fn = instance._onHideAnimationComplete; + const fn = instance._onHideAnimationComplete; if (fn) { dom.removeEventListener(elem, transitionEndEventName, fn, { @@ -227,8 +227,8 @@ import 'flexStyles'; function onHideAnimationComplete(e) { - var instance = this; - var elem = e.target; + const instance = this; + const elem = e.target; elem.classList.add('hide'); @@ -238,14 +238,14 @@ import 'flexStyles'; function hideComingUpNext() { - var instance = this; + const instance = this; clearCountdownTextTimeout(this); if (!instance.options) { return; } - var elem = instance.options.parent; + const elem = instance.options.parent; if (!elem) { return; @@ -262,7 +262,7 @@ import 'flexStyles'; elem.classList.add('upNextDialog-hidden'); - var fn = onHideAnimationComplete.bind(instance); + const fn = onHideAnimationComplete.bind(instance); instance._onHideAnimationComplete = fn; dom.addEventListener(elem, transitionEndEventName, fn, { @@ -272,13 +272,13 @@ import 'flexStyles'; function getTimeRemainingMs(instance) { - var options = instance.options; + const options = instance.options; if (options) { - var runtimeTicks = playbackManager.duration(options.player); + const runtimeTicks = playbackManager.duration(options.player); if (runtimeTicks) { - var timeRemainingTicks = runtimeTicks - playbackManager.currentTime(options.player); + const timeRemainingTicks = runtimeTicks - playbackManager.currentTime(options.player); return Math.round(timeRemainingTicks / 10000); } @@ -289,7 +289,7 @@ import 'flexStyles'; function startComingUpNextHideTimer(instance) { - var timeRemainingMs = getTimeRemainingMs(instance); + const timeRemainingMs = getTimeRemainingMs(instance); if (timeRemainingMs <= 0) { return; @@ -310,7 +310,7 @@ class UpNextDialog { } show() { - var elem = this.options.parent; + const elem = this.options.parent; clearHideAnimationEventListeners(this, elem); From 951d3ffc498f1f22735a04b5cdde643fb8f92313 Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 27 Jul 2020 10:32:48 +0100 Subject: [PATCH 015/155] Update site.js --- src/scripts/site.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index cddf2506a0..85e8c427d0 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -152,13 +152,13 @@ var Dashboard = { processPluginConfigurationUpdateResult: function () { require(['loading', 'toast'], function (loading, toast) { loading.hide(); - toast(Globalize.translate('MessageSettingsSaved')); + toast.default(Globalize.translate('MessageSettingsSaved')); }); }, processServerConfigurationUpdateResult: function (result) { require(['loading', 'toast'], function (loading, toast) { loading.hide(); - toast(Globalize.translate('MessageSettingsSaved')); + toast.default(Globalize.translate('MessageSettingsSaved')); }); }, processErrorResponse: function (response) { @@ -180,7 +180,7 @@ var Dashboard = { alert: function (options) { if ('string' == typeof options) { return void require(['toast'], function (toast) { - toast({ + toast.default({ text: options }); }); From e2b7daf4b70e982a49cd672d9ff0788e419d4368 Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 27 Jul 2020 13:08:16 +0100 Subject: [PATCH 016/155] fix lint --- src/components/imageeditor/imageeditor.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index 0a873fa4c7..96c179404a 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -51,7 +51,6 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', var btnBrowseAllImages = page.querySelectorAll('.btnBrowseAllImages'); for (var i = 0, length = btnBrowseAllImages.length; i < length; i++) { - if (providers.length) { btnBrowseAllImages[i].classList.remove('hide'); } else { @@ -60,7 +59,6 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', } apiClient.getItemImageInfos(currentItem.Id).then(function (imageInfos) { - renderStandardImages(page, apiClient, item, imageInfos, providers); renderBackdrops(page, apiClient, item, imageInfos, providers); renderScreenshots(page, apiClient, item, imageInfos, providers); From f9e79c0a4eda2b6aca51244eb59d7541c47a7fdb Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 28 Jul 2020 21:28:16 +0100 Subject: [PATCH 017/155] Migration of list.js and screensavermanager to ES6 modules --- .eslintignore | 1 - package.json | 2 + src/controllers/list.js | 270 ++++++++++++++-------------- src/libraries/screensavermanager.js | 256 +++++++++++++------------- 4 files changed, 264 insertions(+), 265 deletions(-) diff --git a/.eslintignore b/.eslintignore index 8e3aee83fb..74b18ddcf6 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,4 +2,3 @@ node_modules dist .idea .vscode -src/libraries diff --git a/package.json b/package.json index 30c0c481e6..f412c0671a 100644 --- a/package.json +++ b/package.json @@ -188,6 +188,7 @@ "src/controllers/dashboard/users/userparentalcontrol.js", "src/controllers/dashboard/users/userpasswordpage.js", "src/controllers/dashboard/users/userprofilespage.js", + "src/controllers/list.js", "src/controllers/playback/queue/index.js", "src/controllers/playback/video/index.js", "src/controllers/searchpage.js", @@ -230,6 +231,7 @@ "src/elements/emby-tabs/emby-tabs.js", "src/elements/emby-textarea/emby-textarea.js", "src/elements/emby-toggle/emby-toggle.js", + "src/libraries/screensavermanager.js", "src/plugins/backdropScreensaver/plugin.js", "src/plugins/bookPlayer/plugin.js", "src/plugins/bookPlayer/tableOfContents.js", diff --git a/src/controllers/list.js b/src/controllers/list.js index e550b535f4..c7c4b2a31d 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -1,8 +1,21 @@ -define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager', 'cardBuilder', 'loading', 'connectionManager', 'alphaNumericShortcuts', 'scroller', 'playbackManager', 'alphaPicker', 'emby-itemscontainer', 'emby-scroller'], function (globalize, listView, layoutManager, userSettings, focusManager, cardBuilder, loading, connectionManager, AlphaNumericShortcuts, scroller, playbackManager, AlphaPicker) { - 'use strict'; +import globalize from 'globalize'; +import listView from 'listView'; +import layoutManager from 'layoutManager'; +import * as userSettings from 'userSettings'; +import focusManager from 'focusManager'; +import cardBuilder from 'cardBuilder'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; +import AlphaNumericShortcuts from 'alphaNumericShortcuts'; +import playbackManager from 'playbackManager'; +import AlphaPicker from 'alphaPicker'; +import 'emby-itemscontainer'; +import 'emby-scroller'; + +/* eslint-disable indent */ function getInitialLiveTvQuery(instance, params) { - var query = { + const query = { UserId: connectionManager.getApiClient(params.serverId).getCurrentUserId(), StartIndex: 0, Fields: 'ChannelInfo,PrimaryImageAspectRatio', @@ -59,7 +72,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function modifyQueryWithFilters(instance, query) { - var sortValues = instance.getSortValues(); + const sortValues = instance.getSortValues(); if (!query.SortBy) { query.SortBy = sortValues.sortBy; @@ -68,9 +81,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' query.Fields = query.Fields ? query.Fields + ',PrimaryImageAspectRatio' : 'PrimaryImageAspectRatio'; query.ImageTypeLimit = 1; - var hasFilters; - var queryFilters = []; - var filters = instance.getFilters(); + let hasFilters; + const queryFilters = []; + const filters = instance.getFilters(); if (filters.IsPlayed) { queryFilters.push('IsPlayed'); @@ -164,21 +177,21 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function updateSortText(instance) { - var btnSortText = instance.btnSortText; + const btnSortText = instance.btnSortText; if (btnSortText) { - var options = instance.getSortMenuOptions(); - var values = instance.getSortValues(); - var sortBy = values.sortBy; + const options = instance.getSortMenuOptions(); + const values = instance.getSortValues(); + const sortBy = values.sortBy; - for (var i = 0, length = options.length; i < length; i++) { + for (let i = 0, length = options.length; i < length; i++) { if (sortBy === options[i].value) { btnSortText.innerHTML = globalize.translate('SortByValue', options[i].name); break; } } - var btnSortIcon = instance.btnSortIcon; + const btnSortIcon = instance.btnSortIcon; if (btnSortIcon) { setSortButtonIcon(btnSortIcon, 'Descending' === values.sortOrder ? 'arrow_downward' : 'arrow_upward'); @@ -198,10 +211,10 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' function updateAlphaPickerState(instance, numItems) { if (instance.alphaPicker) { - var alphaPicker = instance.alphaPickerElement; + const alphaPicker = instance.alphaPickerElement; if (alphaPicker) { - var values = instance.getSortValues(); + const values = instance.getSortValues(); if (null == numItems) { numItems = 100; @@ -219,7 +232,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function getItems(instance, params, item, sortBy, startIndex, limit) { - var apiClient = connectionManager.getApiClient(params.serverId); + const apiClient = connectionManager.getApiClient(params.serverId); instance.queryRecursive = false; if ('Recordings' === params.type) { @@ -248,7 +261,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' if (!item) { instance.queryRecursive = true; - var method = 'getItems'; + let method = 'getItems'; if ('MusicArtist' === params.type) { method = 'getArtists'; @@ -271,7 +284,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' if ('Genre' === item.Type || 'MusicGenre' === item.Type || 'Studio' === item.Type || 'Person' === item.Type) { instance.queryRecursive = true; - var query = { + const query = { StartIndex: startIndex, Limit: limit, Fields: 'PrimaryImageAspectRatio,SortName', @@ -320,8 +333,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' return Promise.resolve(null); } - var apiClient = connectionManager.getApiClient(params.serverId); - var itemId = params.genreId || params.musicGenreId || params.studioId || params.personId || params.parentId; + const apiClient = connectionManager.getApiClient(params.serverId); + const itemId = params.genreId || params.musicGenreId || params.studioId || params.personId || params.parentId; if (itemId) { return apiClient.getItem(apiClient.getCurrentUserId(), itemId); @@ -331,9 +344,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function showViewSettingsMenu() { - var instance = this; + const instance = this; - require(['viewSettings'], function (ViewSettings) { + import('viewSettings').then(({default: ViewSettings}) => { new ViewSettings().show({ settingsKey: instance.getSettingsKey(), settings: instance.getViewSettings(), @@ -346,9 +359,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function showFilterMenu() { - var instance = this; + const instance = this; - require(['filterMenu'], function (FilterMenu) { + import('filterMenu').then(({default: FilterMenu}) => { new FilterMenu().show({ settingsKey: instance.getSettingsKey(), settings: instance.getFilters(), @@ -365,9 +378,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function showSortMenu() { - var instance = this; + const instance = this; - require(['sortMenu'], function (SortMenu) { + import('sortMenu').then(({default: SortMenu}) => { new SortMenu().show({ settingsKey: instance.getSettingsKey(), settings: instance.getSortValues(), @@ -383,9 +396,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function onNewItemClick() { - var instance = this; + const instance = this; - require(['playlistEditor'], function (playlistEditor) { + import('playlistEditor').then(({default: playlistEditor}) => { new playlistEditor.showEditor({ items: [], serverId: instance.params.serverId @@ -394,7 +407,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function hideOrShowAll(elems, hide) { - for (var i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { if (hide) { elems[i].classList.add('hide'); } else { @@ -404,12 +417,13 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function bindAll(elems, eventName, fn) { - for (var i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener(eventName, fn); } } - function ItemsView(view, params) { +class ItemsView { + constructor(view, params) { function fetchData() { return getItems(self, params, self.currentItem).then(function (result) { if (null == self.totalItemCount) { @@ -422,7 +436,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function getItemsHtml(items) { - var settings = self.getViewSettings(); + const settings = self.getViewSettings(); if ('list' === settings.imageType) { return listView.getListViewHtml({ @@ -430,13 +444,13 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' }); } - var shape; - var preferThumb; - var preferDisc; - var preferLogo; - var defaultShape; - var item = self.currentItem; - var lines = settings.showTitle ? 2 : 0; + let shape; + let preferThumb; + let preferDisc; + let preferLogo; + let defaultShape; + const item = self.currentItem; + let lines = settings.showTitle ? 2 : 0; if ('banner' === settings.imageType) { shape = 'banner'; @@ -460,7 +474,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' shape = 'autoVertical'; } - var posterOptions = { + let posterOptions = { shape: shape, showTitle: settings.showTitle, showYear: settings.showTitle, @@ -493,19 +507,19 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' lines = 1; } else if ('Programs' === params.type) { lines = settings.showTitle ? 1 : 0; - var showParentTitle = settings.showTitle && 'true' !== params.IsMovie; + const showParentTitle = settings.showTitle && 'true' !== params.IsMovie; if (showParentTitle) { lines++; } - var showAirTime = settings.showTitle && 'Recordings' !== params.type; + const showAirTime = settings.showTitle && 'Recordings' !== params.type; if (showAirTime) { lines++; } - var showYear = settings.showTitle && 'true' === params.IsMovie && 'Recordings' === params.type; + const showYear = settings.showTitle && 'true' === params.IsMovie && 'Recordings' === params.type; if (showYear) { lines++; @@ -538,7 +552,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' function initAlphaPicker() { self.scroller = view.querySelector('.scrollFrameY'); - var alphaPickerElement = self.alphaPickerElement; + const alphaPickerElement = self.alphaPickerElement; alphaPickerElement.classList.add('alphaPicker-fixed-right'); alphaPickerElement.classList.add('focuscontainer-right'); @@ -649,7 +663,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function play() { - var currentItem = self.currentItem; + const currentItem = self.currentItem; if (currentItem && !self.hasFilters) { playbackManager.play({ @@ -665,7 +679,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function queue() { - var currentItem = self.currentItem; + const currentItem = self.currentItem; if (currentItem && !self.hasFilters) { playbackManager.queue({ @@ -681,7 +695,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function shuffle() { - var currentItem = self.currentItem; + const currentItem = self.currentItem; if (currentItem && !self.hasFilters) { playbackManager.shuffle(currentItem); @@ -694,7 +708,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } } - var self = this; + const self = this; self.params = params; this.itemsContainer = view.querySelector('.itemsContainer'); @@ -708,20 +722,20 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' this.itemsContainer.setAttribute('data-refreshinterval', '300000'); } - var i; - var length; - var btnViewSettings = view.querySelectorAll('.btnViewSettings'); + let i; + let length; + const btnViewSettings = view.querySelectorAll('.btnViewSettings'); for (i = 0, length = btnViewSettings.length; i < length; i++) { btnViewSettings[i].addEventListener('click', showViewSettingsMenu.bind(this)); } - var filterButtons = view.querySelectorAll('.btnFilter'); + const filterButtons = view.querySelectorAll('.btnFilter'); this.filterButtons = filterButtons; - var hasVisibleFilters = this.getVisibleFilters().length; + const hasVisibleFilters = this.getVisibleFilters().length; for (i = 0, length = filterButtons.length; i < length; i++) { - var btnFilter = filterButtons[i]; + const btnFilter = filterButtons[i]; btnFilter.addEventListener('click', showFilterMenu.bind(this)); if (hasVisibleFilters) { @@ -731,10 +745,10 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } } - var sortButtons = view.querySelectorAll('.btnSort'); + const sortButtons = view.querySelectorAll('.btnSort'); for (this.sortButtons = sortButtons, i = 0, length = sortButtons.length; i < length; i++) { - var sortButton = sortButtons[i]; + const sortButton = sortButtons[i]; sortButton.addEventListener('click', showSortMenu.bind(this)); if ('nextup' !== params.type) { @@ -749,7 +763,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' self.itemsContainer.fetchData = fetchData; self.itemsContainer.getItemsHtml = getItemsHtml; view.addEventListener('viewshow', function (e) { - var isRestored = e.detail.isRestored; + const isRestored = e.detail.isRestored; if (!isRestored) { loading.show(); @@ -761,7 +775,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' getItem(params).then(function (item) { setTitle(item); self.currentItem = item; - var refresh = !isRestored; + const refresh = !isRestored; self.itemsContainer.resume({ refresh: refresh }).then(function () { @@ -776,7 +790,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' initAlphaPicker(); } - var itemType = item ? item.Type : null; + const itemType = item ? item.Type : null; if ('MusicGenre' === itemType || 'Programs' !== params.type && 'Channel' !== itemType) { hideOrShowAll(view.querySelectorAll('.btnPlay'), false); @@ -808,13 +822,13 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' }); }); view.addEventListener('viewhide', function (e) { - var itemsContainer = self.itemsContainer; + const itemsContainer = self.itemsContainer; if (itemsContainer) { itemsContainer.pause(); } - var alphaNumericShortcuts = self.alphaNumericShortcuts; + const alphaNumericShortcuts = self.alphaNumericShortcuts; if (alphaNumericShortcuts) { alphaNumericShortcuts.destroy(); @@ -841,9 +855,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' self.alphaPickerElement = null; }); } - - ItemsView.prototype.getFilters = function () { - var basekey = this.getSettingsKey(); + getFilters() { + const basekey = this.getSettingsKey(); return { IsPlayed: 'true' === userSettings.getFilter(basekey + '-filter-IsPlayed'), IsUnplayed: 'true' === userSettings.getFilter(basekey + '-filter-IsUnplayed'), @@ -862,30 +875,27 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' HasThemeVideo: userSettings.getFilter(basekey + '-filter-HasThemeVideo'), GenreIds: userSettings.getFilter(basekey + '-filter-GenreIds') }; - }; - - ItemsView.prototype.getSortValues = function () { - var basekey = this.getSettingsKey(); + } + getSortValues() { + const basekey = this.getSettingsKey(); return { sortBy: userSettings.getFilter(basekey + '-sortby') || this.getDefaultSortBy(), sortOrder: 'Descending' === userSettings.getFilter(basekey + '-sortorder') ? 'Descending' : 'Ascending' }; - }; - - ItemsView.prototype.getDefaultSortBy = function () { - var params = this.params; - var sortNameOption = this.getNameSortOption(params); + } + getDefaultSortBy() { + const params = this.params; + const sortNameOption = this.getNameSortOption(params); if (params.type) { return sortNameOption.value; } return 'IsFolder,' + sortNameOption.value; - }; - - ItemsView.prototype.getSortMenuOptions = function () { - var sortBy = []; - var params = this.params; + } + getSortMenuOptions() { + const sortBy = []; + const params = this.params; if ('Programs' === params.type) { sortBy.push({ @@ -894,7 +904,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' }); } - var option = this.getNameSortOption(params); + let option = this.getNameSortOption(params); if (option) { sortBy.push(option); @@ -952,9 +962,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' value: 'Runtime,SortName' }); return sortBy; - }; - - ItemsView.prototype.getNameSortOption = function (params) { + } + getNameSortOption(params) { if ('Episode' === params.type) { return { name: globalize.translate('Name'), @@ -966,9 +975,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' name: globalize.translate('Name'), value: 'SortName' }; - }; - - ItemsView.prototype.getPlayCountSortOption = function () { + } + getPlayCountSortOption() { if ('Programs' === this.params.type) { return null; } @@ -977,9 +985,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' name: globalize.translate('PlayCount'), value: 'PlayCount,SortName' }; - }; - - ItemsView.prototype.getDatePlayedSortOption = function () { + } + getDatePlayedSortOption() { if ('Programs' === this.params.type) { return null; } @@ -988,9 +995,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' name: globalize.translate('DatePlayed'), value: 'DatePlayed,SortName' }; - }; - - ItemsView.prototype.getCriticRatingSortOption = function () { + } + getCriticRatingSortOption() { if ('Programs' === this.params.type) { return null; } @@ -999,18 +1005,16 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' name: globalize.translate('CriticRating'), value: 'CriticRating,SortName' }; - }; - - ItemsView.prototype.getCommunityRatingSortOption = function () { + } + getCommunityRatingSortOption() { return { name: globalize.translate('CommunityRating'), value: 'CommunityRating,SortName' }; - }; - - ItemsView.prototype.getVisibleFilters = function () { - var filters = []; - var params = this.params; + } + getVisibleFilters() { + const filters = []; + const params = this.params; if (!('nextup' === params.type)) { if ('Programs' === params.type) { @@ -1034,16 +1038,15 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } return filters; - }; - - ItemsView.prototype.setFilterStatus = function (hasFilters) { + } + setFilterStatus(hasFilters) { this.hasFilters = hasFilters; - var filterButtons = this.filterButtons; + const filterButtons = this.filterButtons; if (filterButtons.length) { - for (var i = 0, length = filterButtons.length; i < length; i++) { - var btnFilter = filterButtons[i]; - var bubble = btnFilter.querySelector('.filterButtonBubble'); + for (let i = 0, length = filterButtons.length; i < length; i++) { + const btnFilter = filterButtons[i]; + let bubble = btnFilter.querySelector('.filterButtonBubble'); if (!bubble) { if (!hasFilters) { @@ -1062,10 +1065,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } } } - }; - - ItemsView.prototype.getFilterMenuOptions = function () { - var params = this.params; + } + getFilterMenuOptions() { + const params = this.params; return { IsAiring: params.IsAiring, IsMovie: params.IsMovie, @@ -1075,11 +1077,10 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' IsSeries: params.IsSeries, Recursive: this.queryRecursive }; - }; - - ItemsView.prototype.getVisibleViewSettings = function () { - var item = (this.params, this.currentItem); - var fields = ['showTitle']; + } + getVisibleViewSettings() { + const item = (this.params, this.currentItem); + const fields = ['showTitle']; if (!item || 'PhotoAlbum' !== item.Type && 'ChannelFolderItem' !== item.Type) { fields.push('imageType'); @@ -1087,13 +1088,12 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' fields.push('viewType'); return fields; - }; - - ItemsView.prototype.getViewSettings = function () { - var basekey = this.getSettingsKey(); - var params = this.params; - var item = this.currentItem; - var showTitle = userSettings.get(basekey + '-showTitle'); + } + getViewSettings() { + const basekey = this.getSettingsKey(); + const params = this.params; + const item = this.currentItem; + let showTitle = userSettings.get(basekey + '-showTitle'); if ('true' === showTitle) { showTitle = true; @@ -1105,7 +1105,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' showTitle = true; } - var imageType = userSettings.get(basekey + '-imageType'); + let imageType = userSettings.get(basekey + '-imageType'); if (!imageType && 'nextup' === params.type) { imageType = 'thumb'; @@ -1117,10 +1117,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' imageType: imageType || 'primary', viewType: userSettings.get(basekey + '-viewType') || 'images' }; - }; - - ItemsView.prototype.getItemTypes = function () { - var params = this.params; + } + getItemTypes() { + const params = this.params; if ('nextup' === params.type) { return ['Episode']; @@ -1131,12 +1130,11 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } return []; - }; - - ItemsView.prototype.getSettingsKey = function () { - var values = []; + } + getSettingsKey() { + const values = []; values.push('items'); - var params = this.params; + const params = this.params; if (params.type) { values.push(params.type); @@ -1193,7 +1191,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } return values.join('-'); - }; + } +} - return ItemsView; -}); +export default ItemsView; + +/* eslint-enable indent */ diff --git a/src/libraries/screensavermanager.js b/src/libraries/screensavermanager.js index b9d7082850..61d128ff14 100644 --- a/src/libraries/screensavermanager.js +++ b/src/libraries/screensavermanager.js @@ -1,132 +1,130 @@ -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'; - 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 (let i = 0, length = plugins.length; i < length; i++) { + const plugin = plugins[i]; + + 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; From d63a229e0ef0573af125e29d8981faf2a89a040f Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 28 Jul 2020 21:43:46 +0100 Subject: [PATCH 018/155] fix lint --- src/libraries/navdrawer/navdrawer.js | 86 ++++++++++++++-------------- src/libraries/scroller.js | 39 ------------- 2 files changed, 43 insertions(+), 82 deletions(-) diff --git a/src/libraries/navdrawer/navdrawer.js b/src/libraries/navdrawer/navdrawer.js index d9c246b406..750dd510b8 100644 --- a/src/libraries/navdrawer/navdrawer.js +++ b/src/libraries/navdrawer/navdrawer.js @@ -1,5 +1,5 @@ -define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, dom) { - "use strict"; +define(['browser', 'dom', 'css!./navdrawer', 'scrollStyles'], function (browser, dom) { + 'use strict'; return function (options) { function getTouches(e) { @@ -7,7 +7,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, } function onMenuTouchStart(e) { - options.target.classList.remove("transition"); + options.target.classList.remove('transition'); var touches = getTouches(e); var touch = touches[0] || {}; menuTouchStartX = touch.clientX; @@ -36,7 +36,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, if (0 === dragMode && (!isOpen || Math.abs(deltaX) >= 10) && Math.abs(deltaY) < 5) { dragMode = 1; - scrollContainer.addEventListener("scroll", disableEvent); + scrollContainer.addEventListener('scroll', disableEvent); self.showMask(); } else if (0 === dragMode && Math.abs(deltaY) >= 5) { dragMode = 2; @@ -49,8 +49,8 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, } function onMenuTouchEnd(e) { - options.target.classList.add("transition"); - scrollContainer.removeEventListener("scroll", disableEvent); + options.target.classList.add('transition'); + scrollContainer.removeEventListener('scroll', disableEvent); dragMode = 0; var touches = getTouches(e); var touch = touches[0] || {}; @@ -69,9 +69,9 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, if (((getTouches(e)[0] || {}).clientX || 0) <= options.handleSize) { isPeeking = true; - if (e.type === "touchstart") { - dom.removeEventListener(edgeContainer, "touchmove", onEdgeTouchMove, {}); - dom.addEventListener(edgeContainer, "touchmove", onEdgeTouchMove, {}); + if (e.type === 'touchstart') { + dom.removeEventListener(edgeContainer, 'touchmove', onEdgeTouchMove, {}); + dom.addEventListener(edgeContainer, 'touchmove', onEdgeTouchMove, {}); } onMenuTouchStart(e); @@ -88,7 +88,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, function onEdgeTouchEnd(e) { if (isPeeking) { isPeeking = false; - dom.removeEventListener(edgeContainer, "touchmove", onEdgeTouchMove, {}); + dom.removeEventListener(edgeContainer, 'touchmove', onEdgeTouchMove, {}); onMenuTouchEnd(e); } } @@ -142,8 +142,8 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, function onMaskTransitionEnd() { var classList = mask.classList; - if (!classList.contains("backdrop")) { - classList.add("hide"); + if (!classList.contains('backdrop')) { + classList.add('hide'); } } @@ -155,10 +155,10 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, var startPoint = 0; var countStart = 0; var velocity = 0; - options.target.classList.add("transition"); + options.target.classList.add('transition'); var dragMode = 0; - var scrollContainer = options.target.querySelector(".mainDrawer-scrollContainer"); - scrollContainer.classList.add("scrollY"); + var scrollContainer = options.target.querySelector('.mainDrawer-scrollContainer'); + scrollContainer.classList.add('scrollY'); var TouchMenuLA = function () { self = this; @@ -173,13 +173,13 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, }; 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"; + 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"; + mask = document.createElement('div'); + mask.className = 'tmla-mask hide'; document.body.appendChild(mask); dom.addEventListener(mask, dom.whichTransitionEvent(), onMaskTransitionEnd, { passive: true @@ -190,12 +190,12 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, var menuTouchStartX; var menuTouchStartY; var menuTouchStartTime; - var edgeContainer = document.querySelector(".mainDrawerHandle"); + var edgeContainer = document.querySelector('.mainDrawerHandle'); var isPeeking = false; TouchMenuLA.prototype.animateToPosition = function (pos) { requestAnimationFrame(function () { - options.target.style.transform = pos ? "translateX(" + pos + "px)" : "none"; + options.target.style.transform = pos ? 'translateX(' + pos + 'px)' : 'none'; }); }; @@ -206,7 +206,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, }; TouchMenuLA.prototype.clickMaskClose = function () { - mask.addEventListener("click", function () { + mask.addEventListener('click', function () { self.close(); }); }; @@ -233,7 +233,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, this.animateToPosition(options.width); currentPos = options.width; this.isVisible = true; - options.target.classList.add("drawer-open"); + options.target.classList.add('drawer-open'); self.showMask(); self.invoke(options.onChange); }; @@ -242,7 +242,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, this.animateToPosition(0); currentPos = 0; self.isVisible = false; - options.target.classList.remove("drawer-open"); + options.target.classList.remove('drawer-open'); self.hideMask(); self.invoke(options.onChange); }; @@ -259,13 +259,13 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, var backgroundTouchStartTime; TouchMenuLA.prototype.showMask = function () { - mask.classList.remove("hide"); - mask.classList.add("backdrop"); + mask.classList.remove('hide'); + mask.classList.add('backdrop'); }; TouchMenuLA.prototype.hideMask = function () { - mask.classList.add("hide"); - mask.classList.remove("backdrop"); + mask.classList.add('hide'); + mask.classList.remove('backdrop'); }; TouchMenuLA.prototype.invoke = function (fn) { @@ -282,26 +282,26 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, if (enabled) { if (!_edgeSwipeEnabled) { _edgeSwipeEnabled = true; - dom.addEventListener(edgeContainer, "touchstart", onEdgeTouchStart, { + dom.addEventListener(edgeContainer, 'touchstart', onEdgeTouchStart, { passive: true }); - dom.addEventListener(edgeContainer, "touchend", onEdgeTouchEnd, { + dom.addEventListener(edgeContainer, 'touchend', onEdgeTouchEnd, { passive: true }); - dom.addEventListener(edgeContainer, "touchcancel", onEdgeTouchEnd, { + dom.addEventListener(edgeContainer, 'touchcancel', onEdgeTouchEnd, { passive: true }); } } else { if (_edgeSwipeEnabled) { _edgeSwipeEnabled = false; - dom.removeEventListener(edgeContainer, "touchstart", onEdgeTouchStart, { + dom.removeEventListener(edgeContainer, 'touchstart', onEdgeTouchStart, { passive: true }); - dom.removeEventListener(edgeContainer, "touchend", onEdgeTouchEnd, { + dom.removeEventListener(edgeContainer, 'touchend', onEdgeTouchEnd, { passive: true }); - dom.removeEventListener(edgeContainer, "touchcancel", onEdgeTouchEnd, { + dom.removeEventListener(edgeContainer, 'touchcancel', onEdgeTouchEnd, { passive: true }); } @@ -320,26 +320,26 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, self.initElements(); if (browser.touch) { - dom.addEventListener(options.target, "touchstart", onMenuTouchStart, { + dom.addEventListener(options.target, 'touchstart', onMenuTouchStart, { passive: true }); - dom.addEventListener(options.target, "touchmove", onMenuTouchMove, { + dom.addEventListener(options.target, 'touchmove', onMenuTouchMove, { passive: true }); - dom.addEventListener(options.target, "touchend", onMenuTouchEnd, { + dom.addEventListener(options.target, 'touchend', onMenuTouchEnd, { passive: true }); - dom.addEventListener(options.target, "touchcancel", onMenuTouchEnd, { + dom.addEventListener(options.target, 'touchcancel', onMenuTouchEnd, { passive: true }); - dom.addEventListener(mask, "touchstart", onBackgroundTouchStart, { + dom.addEventListener(mask, 'touchstart', onBackgroundTouchStart, { passive: true }); - dom.addEventListener(mask, "touchmove", onBackgroundTouchMove, {}); - dom.addEventListener(mask, "touchend", onBackgroundTouchEnd, { + dom.addEventListener(mask, 'touchmove', onBackgroundTouchMove, {}); + dom.addEventListener(mask, 'touchend', onBackgroundTouchEnd, { passive: true }); - dom.addEventListener(mask, "touchcancel", onBackgroundTouchEnd, { + dom.addEventListener(mask, 'touchcancel', onBackgroundTouchEnd, { passive: true }); } diff --git a/src/libraries/scroller.js b/src/libraries/scroller.js index 645a8ea85c..464b31059d 100644 --- a/src/libraries/scroller.js +++ b/src/libraries/scroller.js @@ -52,8 +52,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc 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; @@ -61,10 +59,8 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc 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. @@ -97,11 +93,9 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc // 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; } @@ -162,9 +156,7 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc var frameSize = 0; var slideeSize = 0; function ensureSizeInfo() { - if (requiresReflow) { - requiresReflow = false; // Reset global variables @@ -186,11 +178,9 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @return {Void} */ function load(isInit) { - requiresReflow = true; if (!isInit) { - ensureSizeInfo(); // Fix possible overflowing @@ -200,7 +190,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } function initFrameResizeObserver() { - var observerOptions = {}; self.frameResizeObserver = new ResizeObserver(onResize, observerOptions); @@ -225,16 +214,13 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc }; 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' @@ -266,14 +252,12 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @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; } @@ -291,7 +275,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } if (!immediate && o.skipSlideToWhenVisible && fullItemPos && fullItemPos.isVisible) { - return; } @@ -303,7 +286,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc }; function setStyleProperty(elem, name, value, speed, resetTransition) { - var style = elem.style; if (resetTransition || browser.edge) { @@ -325,7 +307,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } function renderAnimateWithTransform(fromPosition, toPosition, immediate) { - var speed = o.speed; if (immediate) { @@ -343,7 +324,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } 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) { @@ -361,14 +341,10 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @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; @@ -405,7 +381,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc }; self.getCenterPosition = function (item) { - ensureSizeInfo(); var pos = self.getPos(item); @@ -450,7 +425,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc // Bind dragging events if (transform) { - if (isTouch) { dragTouchEvents.forEach(function (eventName) { dom.addEventListener(document, eventName, dragHandler, { @@ -554,9 +528,7 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @return {Boolean} */ function isInteractive(element) { - while (element) { - if (interactiveElements.indexOf(element.tagName) !== -1) { return true; } @@ -592,7 +564,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @return {Void} */ function scrollHandler(event) { - ensureSizeInfo(); var pos = self._pos; // Ignore if there is no scrolling to be done @@ -609,7 +580,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc self.slideBy(o.scrollBy * delta); } else { - if (isSmoothScrollSupported) { delta *= 12; } @@ -628,7 +598,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @return {Void} */ self.destroy = function () { - if (self.frameResizeObserver) { self.frameResizeObserver.disconnect(); self.frameResizeObserver = null; @@ -664,11 +633,9 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc var contentRect = {}; function onResize(entries) { - var entry = entries[0]; if (entry) { - var newRect = entry.contentRect; // handle element being hidden @@ -677,7 +644,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } if (newRect.width !== contentRect.width || newRect.height !== contentRect.height) { - contentRect = newRect; load(false); @@ -703,7 +669,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } self.getScrollPosition = function () { - if (transform) { return self._pos.cur; } @@ -716,7 +681,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc }; self.getScrollSize = function () { - if (transform) { return slideeSize; } @@ -792,7 +756,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc initFrameResizeObserver(); if (transform) { - dom.addEventListener(dragSourceElement, 'touchstart', dragInitSlidee, { passive: true }); @@ -809,9 +772,7 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc 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) { From 6ef3be136a1e2f98e0d292cfdc108b94eb3eb470 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Thu, 30 Jul 2020 23:36:52 +0300 Subject: [PATCH 019/155] Add parseInt radix --- src/components/subtitlesettings/subtitleappearancehelper.js | 4 ++-- src/plugins/htmlVideoPlayer/plugin.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/subtitlesettings/subtitleappearancehelper.js b/src/components/subtitlesettings/subtitleappearancehelper.js index 4b8b7aed2a..904c018bfc 100644 --- a/src/components/subtitlesettings/subtitleappearancehelper.js +++ b/src/components/subtitlesettings/subtitleappearancehelper.js @@ -89,7 +89,7 @@ function getTextStyles(settings, preview) { } if (!preview) { - const pos = parseInt(settings.verticalPosition); + const pos = parseInt(settings.verticalPosition, 10); const lineHeight = 1.35; // FIXME: It is better to read this value from element const line = Math.abs(pos * lineHeight); if (pos < 0) { @@ -108,7 +108,7 @@ function getWindowStyles(settings, preview) { const list = []; if (!preview) { - const pos = parseInt(settings.verticalPosition); + const pos = parseInt(settings.verticalPosition, 10); if (pos < 0) { list.push({ name: 'top', value: '' }); list.push({ name: 'bottom', value: '0' }); diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 77e3253641..7ef35adf41 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -1200,7 +1200,7 @@ function tryRemoveElement(elem) { console.debug(`downloaded ${data.TrackEvents.length} track events`); const subtitleAppearance = userSettings.getSubtitleAppearanceSettings(); - const cueLine = parseInt(subtitleAppearance.verticalPosition); + 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 From 116e73e5606a47da15c2cacb74f829f02c24924d Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 11:30:02 +0100 Subject: [PATCH 020/155] Remove unused vars --- src/controllers/hometab.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/controllers/hometab.js b/src/controllers/hometab.js index 4b7ddee057..d834e3e233 100644 --- a/src/controllers/hometab.js +++ b/src/controllers/hometab.js @@ -1,8 +1,6 @@ import * as userSettings from 'userSettings'; import loading from 'loading'; import connectionManager from 'connectionManager'; -import appHost from 'apphost'; -import layoutManager from 'layoutManager'; import focusManager from 'focusManager'; import homeSections from 'homeSections'; import 'emby-itemscontainer'; From af93c4a798376f89bb089bcf1226420767e31408 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 1 Aug 2020 05:36:36 +0200 Subject: [PATCH 021/155] Migrate routes.js to ES6 --- package.json | 2 + src/components/viewContainer.js | 104 +++++++++++++------------- src/scripts/routes.js | 126 ++++++++++++++++++++++---------- 3 files changed, 142 insertions(+), 90 deletions(-) diff --git a/package.json b/package.json index a9e269f5ef..74cf0ad5e9 100644 --- a/package.json +++ b/package.json @@ -163,6 +163,7 @@ "src/components/syncPlay/playbackPermissionManager.js", "src/components/syncPlay/syncPlayManager.js", "src/components/syncPlay/timeSyncManager.js", + "src/components/viewContainer.js", "src/controllers/session/addServer/index.js", "src/controllers/session/forgotPassword/index.js", "src/controllers/session/redeemPassword/index.js", @@ -267,6 +268,7 @@ "src/scripts/libraryBrowser.js", "src/scripts/multiDownload.js", "src/scripts/playlists.js", + "src/scripts/routes.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", "src/scripts/settings/webSettings.js", diff --git a/src/components/viewContainer.js b/src/components/viewContainer.js index d1b0df6fbb..766a12b9ce 100644 --- a/src/components/viewContainer.js +++ b/src/components/viewContainer.js @@ -1,12 +1,11 @@ -define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewContainer'], function (browser, dom, layoutManager) { - 'use strict'; +/* eslint-disable indent */ function setControllerClass(view, options) { if (options.controllerFactory) { return Promise.resolve(); } - var controllerUrl = view.getAttribute('data-controller'); + let controllerUrl = view.getAttribute('data-controller'); if (controllerUrl) { if (controllerUrl.indexOf('__plugin/') === 0) { @@ -14,7 +13,7 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta } controllerUrl = Dashboard.getConfigurationResourceUrl(controllerUrl); - return getRequirePromise([controllerUrl]).then(function (ControllerFactory) { + return getRequirePromise([controllerUrl]).then((ControllerFactory) => { options.controllerFactory = ControllerFactory; }); } @@ -23,35 +22,35 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta } function getRequirePromise(deps) { - return new Promise(function (resolve, reject) { + return new Promise((resolve, reject) => { require(deps, resolve); }); } - function loadView(options) { + export function loadView(options) { if (!options.cancel) { - var selected = selectedPageIndex; - var previousAnimatable = selected === -1 ? null : allPages[selected]; - var pageIndex = selected + 1; + const selected = selectedPageIndex; + const previousAnimatable = selected === -1 ? null : allPages[selected]; + let pageIndex = selected + 1; if (pageIndex >= pageContainerCount) { pageIndex = 0; } - var isPluginpage = options.url.toLowerCase().indexOf('/configurationpage') !== -1; - var newViewInfo = normalizeNewView(options, isPluginpage); - var newView = newViewInfo.elem; - var modulesToLoad = []; + const isPluginpage = options.url.toLowerCase().indexOf('/configurationpage') !== -1; + const newViewInfo = normalizeNewView(options, isPluginpage); + const newView = newViewInfo.elem; + const modulesToLoad = []; - return new Promise(function (resolve) { - require(modulesToLoad, function () { - var currentPage = allPages[pageIndex]; + return new Promise((resolve) => { + require(modulesToLoad, () => { + const currentPage = allPages[pageIndex]; if (currentPage) { triggerDestroy(currentPage); } - var view = newView; + let view = newView; if (typeof view == 'string') { view = document.createElement('div'); @@ -79,7 +78,7 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta view.setAttribute('data-type', options.type); } - var properties = []; + const properties = []; if (options.fullscreen) { properties.push('fullscreen'); @@ -90,7 +89,7 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta } allPages[pageIndex] = view; - setControllerClass(view, options).then(function () { + setControllerClass(view, options).then(() => { if (onBeforeChange) { onBeforeChange(view, false, options); } @@ -125,28 +124,28 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta html = replaceAll(html, '<\/script>--\x3e', '<\/script>'); } - var wrapper = document.createElement('div'); + const wrapper = document.createElement('div'); wrapper.innerHTML = html; return wrapper.querySelector('div[data-role="page"]'); } function normalizeNewView(options, isPluginpage) { - var viewHtml = options.view; + const viewHtml = options.view; if (viewHtml.indexOf('data-role="page"') === -1) { return viewHtml; } - var hasScript = viewHtml.indexOf(' { if (onBeforeChange) { onBeforeChange(view, true, options); } @@ -228,25 +227,28 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta view.dispatchEvent(new CustomEvent('viewdestroy', {})); } - function reset() { + export function reset() { allPages = []; currentUrls = []; mainAnimatedPages.innerHTML = ''; selectedPageIndex = -1; } - var onBeforeChange; - var mainAnimatedPages = document.querySelector('.mainAnimatedPages'); - var allPages = []; - var currentUrls = []; - var pageContainerCount = 3; - var selectedPageIndex = -1; + let onBeforeChange; + const mainAnimatedPages = document.querySelector('.mainAnimatedPages'); + let allPages = []; + let currentUrls = []; + const pageContainerCount = 3; + let selectedPageIndex = -1; reset(); mainAnimatedPages.classList.remove('hide'); - return { - loadView: loadView, - tryRestoreView: tryRestoreView, - reset: reset, - setOnBeforeChange: setOnBeforeChange - }; -}); + +/* eslint-enable indent */ + +export default { + loadView: loadView, + tryRestoreView: tryRestoreView, + reset: reset, + setOnBeforeChange: setOnBeforeChange +}; + diff --git a/src/scripts/routes.js b/src/scripts/routes.js index 1d735e3018..4094a2552f 100644 --- a/src/scripts/routes.js +++ b/src/scripts/routes.js @@ -1,18 +1,21 @@ -define([ - 'jQuery', - 'emby-button', - 'emby-input', - 'scripts/livetvcomponents', - 'paper-icon-button-light', - 'emby-itemscontainer', - 'emby-collapse', - 'emby-select', - 'livetvcss', - 'emby-checkbox', - 'emby-slider', - 'listViewStyle', - 'dashboardcss', - 'detailtablecss'], function () { +import 'emby-button'; +import 'emby-input'; +import 'scripts/livetvcomponents'; +import 'paper-icon-button-light'; +import 'emby-itemscontainer'; +import 'emby-collapse'; +import 'emby-select'; +import 'livetvcss'; +import 'emby-checkbox'; +import 'emby-slider'; +import 'listViewStyle'; +import 'dashboardcss'; +import 'detailtablecss'; + +/* eslint-disable indent */ + + console.groupCollapsed('defining core routes'); + function defineRoute(newRoute) { var path = newRoute.alias ? newRoute.alias : newRoute.path; console.debug('defining route: ' + path); @@ -20,8 +23,6 @@ define([ Emby.Page.addRoute(path, newRoute); } - console.debug('defining core routes'); - defineRoute({ alias: '/addserver.html', path: '/controllers/session/addServer/index.html', @@ -30,6 +31,7 @@ define([ startup: true, controller: 'session/addServer/index' }); + defineRoute({ alias: '/selectserver.html', path: '/controllers/session/selectServer/index.html', @@ -39,6 +41,7 @@ define([ controller: 'session/selectServer/index', type: 'selectserver' }); + defineRoute({ alias: '/login.html', path: '/controllers/session/login/index.html', @@ -48,6 +51,7 @@ define([ controller: 'session/login/index', type: 'login' }); + defineRoute({ alias: '/forgotpassword.html', path: '/controllers/session/forgotPassword/index.html', @@ -55,6 +59,7 @@ define([ startup: true, controller: 'session/forgotPassword/index' }); + defineRoute({ alias: '/forgotpasswordpin.html', path: '/controllers/session/redeemPassword/index.html', @@ -68,42 +73,41 @@ define([ alias: '/mypreferencesmenu.html', path: '/controllers/user/menu/index.html', autoFocus: false, - transition: 'fade', controller: 'user/menu/index' }); + defineRoute({ alias: '/myprofile.html', path: '/controllers/user/profile/index.html', autoFocus: false, - transition: 'fade', controller: 'user/profile/index' }); + defineRoute({ alias: '/mypreferencesdisplay.html', path: '/controllers/user/display/index.html', autoFocus: false, - transition: 'fade', controller: 'user/display/index' }); + defineRoute({ alias: '/mypreferenceshome.html', path: '/controllers/user/home/index.html', autoFocus: false, - transition: 'fade', controller: 'user/home/index' }); + defineRoute({ alias: '/mypreferencesplayback.html', path: '/controllers/user/playback/index.html', autoFocus: false, - transition: 'fade', controller: 'user/playback/index' }); + defineRoute({ alias: '/mypreferencessubtitles.html', path: '/controllers/user/subtitles/index.html', autoFocus: false, - transition: 'fade', controller: 'user/subtitles/index' }); @@ -113,42 +117,49 @@ define([ roles: 'admin', controller: 'dashboard/dashboard' }); + defineRoute({ path: '/dashboardgeneral.html', controller: 'dashboard/general', autoFocus: false, roles: 'admin' }); + defineRoute({ path: '/networking.html', autoFocus: false, roles: 'admin', controller: 'dashboard/networking' }); + defineRoute({ path: '/devices.html', autoFocus: false, roles: 'admin', controller: 'dashboard/devices/devices' }); + defineRoute({ path: '/device.html', autoFocus: false, roles: 'admin', controller: 'dashboard/devices/device' }); + defineRoute({ path: '/dlnaprofile.html', autoFocus: false, roles: 'admin', controller: 'dashboard/dlna/profile' }); + defineRoute({ path: '/dlnaprofiles.html', autoFocus: false, roles: 'admin', controller: 'dashboard/dlna/profiles' }); + defineRoute({ alias: '/addplugin.html', path: '/controllers/dashboard/plugins/add/index.html', @@ -156,52 +167,61 @@ define([ roles: 'admin', controller: 'dashboard/plugins/add/index' }); + defineRoute({ path: '/library.html', autoFocus: false, roles: 'admin', controller: 'dashboard/mediaLibrary' }); + defineRoute({ path: '/librarydisplay.html', autoFocus: false, roles: 'admin', controller: 'dashboard/librarydisplay' }); + defineRoute({ path: '/dlnasettings.html', autoFocus: false, roles: 'admin', controller: 'dashboard/dlna/settings' }); + defineRoute({ path: '/edititemmetadata.html', controller: 'edititemmetadata', autoFocus: false }); + defineRoute({ path: '/encodingsettings.html', autoFocus: false, roles: 'admin', controller: 'dashboard/encodingsettings' }); + defineRoute({ path: '/log.html', roles: 'admin', controller: 'dashboard/logs' }); + defineRoute({ path: '/metadataimages.html', autoFocus: false, roles: 'admin', controller: 'dashboard/metadataImages' }); + defineRoute({ path: '/metadatanfo.html', autoFocus: false, roles: 'admin', controller: 'dashboard/metadatanfo' }); + defineRoute({ alias: '/notificationsetting.html', path: '/controllers/dashboard/notifications/notification/index.html', @@ -209,6 +229,7 @@ define([ roles: 'admin', controller: 'dashboard/notifications/notification/index' }); + defineRoute({ alias: '/notificationsettings.html', path: '/controllers/dashboard/notifications/notifications/index.html', @@ -216,12 +237,14 @@ define([ autoFocus: false, roles: 'admin' }); + defineRoute({ path: '/playbackconfiguration.html', autoFocus: false, roles: 'admin', controller: 'dashboard/playback' }); + defineRoute({ alias: '/availableplugins.html', path: '/controllers/dashboard/plugins/available/index.html', @@ -229,6 +252,7 @@ define([ roles: 'admin', controller: 'dashboard/plugins/available/index' }); + defineRoute({ alias: '/repositories.html', path: '/controllers/dashboard/plugins/repositories/index.html', @@ -241,67 +265,72 @@ define([ path: '/home.html', autoFocus: false, controller: 'home', - transition: 'fade', type: 'home' }); + defineRoute({ path: '/search.html', controller: 'searchpage' }); + defineRoute({ path: '/list.html', autoFocus: false, - controller: 'list', - transition: 'fade' + controller: 'list' }); + defineRoute({ alias: '/details', path: '/controllers/itemDetails/index.html', controller: 'itemDetails/index', - autoFocus: false, - transition: 'fade' + autoFocus: false }); + defineRoute({ path: '/livetv.html', controller: 'livetv/livetvsuggested', - autoFocus: false, - transition: 'fade' + autoFocus: false }); + defineRoute({ path: '/livetvguideprovider.html', autoFocus: false, roles: 'admin', controller: 'livetvguideprovider' }); + defineRoute({ path: '/livetvsettings.html', autoFocus: false, controller: 'livetvsettings' }); + defineRoute({ path: '/livetvstatus.html', autoFocus: false, roles: 'admin', controller: 'livetvstatus' }); + defineRoute({ path: '/livetvtuner.html', autoFocus: false, roles: 'admin', controller: 'livetvtuner' }); + defineRoute({ path: '/movies.html', autoFocus: false, - controller: 'movies/moviesrecommended', - transition: 'fade' + controller: 'movies/moviesrecommended' }); + defineRoute({ path: '/music.html', controller: 'music/musicrecommended', - autoFocus: false, - transition: 'fade' + autoFocus: false }); + defineRoute({ alias: '/installedplugins.html', path: '/controllers/dashboard/plugins/installed/index.html', @@ -309,41 +338,46 @@ define([ roles: 'admin', controller: 'dashboard/plugins/installed/index' }); + defineRoute({ path: '/scheduledtask.html', autoFocus: false, roles: 'admin', controller: 'dashboard/scheduledtasks/scheduledtask' }); + defineRoute({ path: '/scheduledtasks.html', autoFocus: false, roles: 'admin', controller: 'dashboard/scheduledtasks/scheduledtasks' }); + defineRoute({ path: '/serveractivity.html', autoFocus: false, roles: 'admin', controller: 'dashboard/serveractivity' }); + defineRoute({ path: '/apikeys.html', autoFocus: false, roles: 'admin', controller: 'dashboard/apikeys' }); + defineRoute({ path: '/streamingsettings.html', autoFocus: false, roles: 'admin', controller: 'dashboard/streaming' }); + defineRoute({ path: '/tv.html', autoFocus: false, - controller: 'shows/tvrecommended', - transition: 'fade' + controller: 'shows/tvrecommended' }); defineRoute({ @@ -352,29 +386,34 @@ define([ roles: 'admin', controller: 'dashboard/users/useredit' }); + defineRoute({ path: '/userlibraryaccess.html', autoFocus: false, roles: 'admin', controller: 'dashboard/users/userlibraryaccess' }); + defineRoute({ path: '/usernew.html', autoFocus: false, roles: 'admin', controller: 'dashboard/users/usernew' }); + defineRoute({ path: '/userparentalcontrol.html', autoFocus: false, roles: 'admin', controller: 'dashboard/users/userparentalcontrol' }); + defineRoute({ path: '/userpassword.html', autoFocus: false, controller: 'dashboard/users/userpasswordpage' }); + defineRoute({ path: '/userprofiles.html', autoFocus: false, @@ -389,6 +428,7 @@ define([ anonymous: true, controller: 'wizard/remote/index' }); + defineRoute({ alias: '/wizardfinish.html', path: '/controllers/wizard/finish/index.html', @@ -396,12 +436,14 @@ define([ anonymous: true, controller: 'wizard/finish/index' }); + defineRoute({ path: '/wizardlibrary.html', autoFocus: false, anonymous: true, controller: 'dashboard/mediaLibrary' }); + defineRoute({ alias: '/wizardsettings.html', path: '/controllers/wizard/settings/index.html', @@ -409,6 +451,7 @@ define([ anonymous: true, controller: 'wizard/settings/index' }); + defineRoute({ alias: '/wizardstart.html', path: '/controllers/wizard/start/index.html', @@ -416,6 +459,7 @@ define([ anonymous: true, controller: 'wizard/start/index' }); + defineRoute({ alias: '/wizarduser.html', path: '/controllers/wizard/user/index.html', @@ -427,7 +471,6 @@ define([ defineRoute({ alias: '/video', path: '/controllers/playback/video/index.html', - transition: 'fade', controller: 'playback/video/index', autoFocus: false, type: 'video-osd', @@ -435,16 +478,17 @@ define([ fullscreen: true, enableMediaControl: false }); + defineRoute({ alias: '/queue', path: '/controllers/playback/queue/index.html', controller: 'playback/queue/index', autoFocus: false, - transition: 'fade', fullscreen: true, supportsThemeMedia: true, enableMediaControl: false }); + defineRoute({ path: '/configurationpage', autoFocus: false, @@ -458,9 +502,13 @@ define([ isDefaultRoute: true, autoFocus: false }); + defineRoute({ path: '/index.html', autoFocus: false, isDefaultRoute: true }); -}); + + console.groupEnd('defining core routes'); + +/* eslint-enable indent */ From 5d2d8d2855d2b8173f9eb04c86a1f81724cc2b13 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 1 Aug 2020 05:37:07 +0200 Subject: [PATCH 022/155] Fix typo in imageLoader --- src/components/images/imageLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index c9d3e6fdb2..0effcc7a57 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -205,7 +205,7 @@ import 'css!./style'; /* eslint-enable indent */ export default { - serLazyImage: setLazyImage, + setLazyImage: setLazyImage, fillImages: fillImages, fillImage: fillImage, lazyImage: lazyImage, From 1f3bc8a4272df1d03af6dd4f3dee5aab1ed65df5 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 1 Aug 2020 05:46:31 +0200 Subject: [PATCH 023/155] Migrate mouseManager to es6 --- package.json | 1 + src/scripts/mouseManager.js | 49 +++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 74cf0ad5e9..4695eb155a 100644 --- a/package.json +++ b/package.json @@ -266,6 +266,7 @@ "src/scripts/inputManager.js", "src/scripts/keyboardNavigation.js", "src/scripts/libraryBrowser.js", + "src/scripts/mouseManager.js", "src/scripts/multiDownload.js", "src/scripts/playlists.js", "src/scripts/routes.js", diff --git a/src/scripts/mouseManager.js b/src/scripts/mouseManager.js index d801d82393..40253fb91c 100644 --- a/src/scripts/mouseManager.js +++ b/src/scripts/mouseManager.js @@ -1,10 +1,15 @@ -define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'dom'], function (inputManager, focusManager, browser, layoutManager, events, dom) { - 'use strict'; +import inputManager from 'inputManager'; +import focusManager from 'focusManager'; +import browser from 'browser'; +import layoutManager from 'layoutManager'; +import events from 'events'; +import dom from 'dom'; +/* eslint-disable indent */ - var self = {}; + const self = {}; - var lastMouseInputTime = new Date().getTime(); - var isMouseIdle; + let lastMouseInputTime = new Date().getTime(); + let isMouseIdle; function mouseIdleTime() { return new Date().getTime() - lastMouseInputTime; @@ -15,14 +20,14 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } function removeIdleClasses() { - var classList = document.body.classList; + const classList = document.body.classList; classList.remove('mouseIdle'); classList.remove('mouseIdle-tv'); } function addIdleClasses() { - var classList = document.body.classList; + const classList = document.body.classList; classList.add('mouseIdle'); @@ -31,7 +36,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } } - function showCursor() { + export function showCursor() { if (isMouseIdle) { isMouseIdle = false; removeIdleClasses(); @@ -39,7 +44,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } } - function hideCursor() { + export function hideCursor() { if (!isMouseIdle) { isMouseIdle = true; addIdleClasses(); @@ -47,17 +52,17 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } } - var lastPointerMoveData; + let lastPointerMoveData; function onPointerMove(e) { - var eventX = e.screenX; - var eventY = e.screenY; + const eventX = e.screenX; + const eventY = e.screenY; // if coord don't exist how could it move if (typeof eventX === 'undefined' && typeof eventY === 'undefined') { return; } - var obj = lastPointerMoveData; + const obj = lastPointerMoveData; if (!obj) { lastPointerMoveData = { x: eventX, @@ -81,11 +86,11 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } function onPointerEnter(e) { - var pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'); + const pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'); if (pointerType === 'mouse') { if (!isMouseIdle) { - var parent = focusManager.focusableParent(e.target); + const parent = focusManager.focusableParent(e.target); if (parent) { focusManager.focus(parent); } @@ -115,7 +120,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } } - var mouseInterval; + let mouseInterval; function startMouseInterval() { if (!mouseInterval) { mouseInterval = setInterval(onMouseInterval, 5000); @@ -123,7 +128,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } function stopMouseInterval() { - var interval = mouseInterval; + const interval = mouseInterval; if (interval) { clearInterval(interval); @@ -167,8 +172,10 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd events.on(layoutManager, 'modechange', initMouse); - self.hideCursor = hideCursor; - self.showCursor = showCursor; +/* eslint-enable indent */ + +export default { + hideCursor, + showCursor +}; - return self; -}); From 39a1d94c500134b45591a6d48fca02013cf8e159 Mon Sep 17 00:00:00 2001 From: matjaz321 Date: Sat, 1 Aug 2020 14:52:15 +0200 Subject: [PATCH 024/155] Migrated to es6 module --- package.json | 1 + src/controllers/livetvguideprovider.js | 50 +++++++++++++------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 17d175b7e7..efe1fcc2fa 100644 --- a/package.json +++ b/package.json @@ -207,6 +207,7 @@ "src/controllers/searchpage.js", "src/controllers/livetvtuner.js", "src/controllers/livetvstatus.js", + "src/controllers/livetvguideprovider.js", "src/controllers/shows/episodes.js", "src/controllers/shows/tvgenres.js", "src/controllers/shows/tvlatest.js", diff --git a/src/controllers/livetvguideprovider.js b/src/controllers/livetvguideprovider.js index 8f8b9f91c7..6ab195a088 100644 --- a/src/controllers/livetvguideprovider.js +++ b/src/controllers/livetvguideprovider.js @@ -1,30 +1,30 @@ -define(['events', 'loading', 'globalize'], function (events, loading, globalize) { - 'use strict'; +import events from 'events'; +import loading from 'loading'; +import globalize from 'globalize'; - function onListingsSubmitted() { - Dashboard.navigate('livetvstatus.html'); - } +function onListingsSubmitted() { + Dashboard.navigate('livetvstatus.html'); +} - function init(page, type, providerId) { - var url = 'components/tvproviders/' + type + '.js'; +function init(page, type, providerId) { + const url = 'components/tvproviders/' + type + '.js'; - require([url], function (factory) { - var instance = new factory(page, providerId, {}); - events.on(instance, 'submitted', onListingsSubmitted); - instance.init(); - }); - } - - function loadTemplate(page, type, providerId) { - require(['text!./components/tvproviders/' + type + '.template.html'], function (html) { - page.querySelector('.providerTemplate').innerHTML = globalize.translateHtml(html); - init(page, type, providerId); - }); - } - - pageIdOn('pageshow', 'liveTvGuideProviderPage', function () { - loading.show(); - var providerId = getParameterByName('id'); - loadTemplate(this, getParameterByName('type'), providerId); + import(url).then(({default: factory}) => { + const instance = new factory(page, providerId, {}); + events.on(instance, 'submitted', onListingsSubmitted); + instance.init(); }); +} + +function loadTemplate(page, type, providerId) { + import('text!./../components/tvproviders/' + type + '.template.html').then(({default: html}) => { + page.querySelector('.providerTemplate').innerHTML = globalize.translateHtml(html); + init(page, type, providerId); + }); +} + +pageIdOn('pageshow', 'liveTvGuideProviderPage', function () { + loading.show(); + const providerId = getParameterByName('id'); + loadTemplate(this, getParameterByName('type'), providerId); }); From ab52727254019450db9a9fab25bc5eb4cddc504a Mon Sep 17 00:00:00 2001 From: matjaz321 Date: Sat, 1 Aug 2020 15:32:57 +0200 Subject: [PATCH 025/155] Migrated livetvseriestimer to es6 module --- src/controllers/livetv/livetvseriestimers.js | 90 ++++++++++---------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/controllers/livetv/livetvseriestimers.js b/src/controllers/livetv/livetvseriestimers.js index c5d0da60d7..d645a66370 100644 --- a/src/controllers/livetv/livetvseriestimers.js +++ b/src/controllers/livetv/livetvseriestimers.js @@ -1,50 +1,52 @@ -define(['datetime', 'cardBuilder', 'imageLoader', 'apphost', 'loading', 'paper-icon-button-light', 'emby-button'], function (datetime, cardBuilder, imageLoader, appHost, loading) { - 'use strict'; +import cardBuilder from 'cardBuilder'; +import imageLoader from 'imageLoader'; +import loading from 'loading'; +import 'paper-icon-button-light'; +import 'emby-button'; - function renderTimers(context, timers) { - var html = ''; - html += cardBuilder.getCardsHtml({ - items: timers, - shape: 'auto', - defaultShape: 'portrait', - showTitle: true, - cardLayout: false, - preferThumb: 'auto', - coverImage: true, - overlayText: false, - showSeriesTimerTime: true, - showSeriesTimerChannel: true, - centerText: true, - overlayMoreButton: true, - lines: 3 - }); - var elem = context.querySelector('#items'); - elem.innerHTML = html; - imageLoader.lazyChildren(elem); - loading.hide(); - } +function renderTimers(context, timers) { + const html = cardBuilder.getCardsHtml({ + items: timers, + shape: 'auto', + defaultShape: 'portrait', + showTitle: true, + cardLayout: false, + preferThumb: 'auto', + coverImage: true, + overlayText: false, + showSeriesTimerTime: true, + showSeriesTimerChannel: true, + centerText: true, + overlayMoreButton: true, + lines: 3 + }); + const elem = context.querySelector('#items'); + elem.innerHTML = html; + imageLoader.lazyChildren(elem); + loading.hide(); +} - function reload(context, promise) { - loading.show(); - promise.then(function (result) { - renderTimers(context, result.Items); - }); - } +function reload(context, promise) { + loading.show(); + promise.then(function (result) { + renderTimers(context, result.Items); + }); +} - var query = { - SortBy: 'SortName', - SortOrder: 'Ascending' +const query = { + SortBy: 'SortName', + SortOrder: 'Ascending' +}; + +export default function (view, params, tabContent) { + let timersPromise; + const self = this; + + self.preRender = function () { + timersPromise = ApiClient.getLiveTvSeriesTimers(query); }; - return function (view, params, tabContent) { - var timersPromise; - var self = this; - self.preRender = function () { - timersPromise = ApiClient.getLiveTvSeriesTimers(query); - }; - - self.renderTab = function () { - reload(tabContent, timersPromise); - }; + self.renderTab = function () { + reload(tabContent, timersPromise); }; -}); +}; From 0c8e1994b79eebee5056c03bc1056b3d658c94ca Mon Sep 17 00:00:00 2001 From: matjaz321 Date: Sat, 1 Aug 2020 15:36:16 +0200 Subject: [PATCH 026/155] fixed linting errors --- src/controllers/livetv/livetvseriestimers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/livetv/livetvseriestimers.js b/src/controllers/livetv/livetvseriestimers.js index d645a66370..4f6bfaaa6a 100644 --- a/src/controllers/livetv/livetvseriestimers.js +++ b/src/controllers/livetv/livetvseriestimers.js @@ -49,4 +49,4 @@ export default function (view, params, tabContent) { self.renderTab = function () { reload(tabContent, timersPromise); }; -}; +} From 01fd2e056dfb116263c36d1bc0daecaf405d5f43 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 1 Aug 2020 19:18:03 +0200 Subject: [PATCH 027/155] Fix suggestions --- src/components/viewContainer.js | 116 +++++++++++++++----------------- 1 file changed, 54 insertions(+), 62 deletions(-) diff --git a/src/components/viewContainer.js b/src/components/viewContainer.js index 766a12b9ce..4e11ebc7ba 100644 --- a/src/components/viewContainer.js +++ b/src/components/viewContainer.js @@ -1,3 +1,4 @@ +import 'css!components/viewManager/viewContainer'; /* eslint-disable indent */ function setControllerClass(view, options) { @@ -13,7 +14,7 @@ } controllerUrl = Dashboard.getConfigurationResourceUrl(controllerUrl); - return getRequirePromise([controllerUrl]).then((ControllerFactory) => { + return import(controllerUrl).then((ControllerFactory) => { options.controllerFactory = ControllerFactory; }); } @@ -21,12 +22,6 @@ return Promise.resolve(); } - function getRequirePromise(deps) { - return new Promise((resolve, reject) => { - require(deps, resolve); - }); - } - export function loadView(options) { if (!options.cancel) { const selected = selectedPageIndex; @@ -40,75 +35,72 @@ const isPluginpage = options.url.toLowerCase().indexOf('/configurationpage') !== -1; const newViewInfo = normalizeNewView(options, isPluginpage); const newView = newViewInfo.elem; - const modulesToLoad = []; return new Promise((resolve) => { - require(modulesToLoad, () => { - const currentPage = allPages[pageIndex]; + const currentPage = allPages[pageIndex]; - if (currentPage) { - triggerDestroy(currentPage); - } + if (currentPage) { + triggerDestroy(currentPage); + } - let view = newView; + let view = newView; - if (typeof view == 'string') { - view = document.createElement('div'); - view.innerHTML = newView; - } + if (typeof view == 'string') { + view = document.createElement('div'); + view.innerHTML = newView; + } - view.classList.add('mainAnimatedPage'); + view.classList.add('mainAnimatedPage'); - if (currentPage) { - if (newViewInfo.hasScript && window.$) { - view = $(view).appendTo(mainAnimatedPages)[0]; - mainAnimatedPages.removeChild(currentPage); - } else { - mainAnimatedPages.replaceChild(view, currentPage); - } + if (currentPage) { + if (newViewInfo.hasScript && window.$) { + view = $(view).appendTo(mainAnimatedPages)[0]; + mainAnimatedPages.removeChild(currentPage); } else { - if (newViewInfo.hasScript && window.$) { - view = $(view).appendTo(mainAnimatedPages)[0]; - } else { - mainAnimatedPages.appendChild(view); - } + mainAnimatedPages.replaceChild(view, currentPage); + } + } else { + if (newViewInfo.hasScript && window.$) { + view = $(view).appendTo(mainAnimatedPages)[0]; + } else { + mainAnimatedPages.appendChild(view); + } + } + + if (options.type) { + view.setAttribute('data-type', options.type); + } + + const properties = []; + + if (options.fullscreen) { + properties.push('fullscreen'); + } + + if (properties.length) { + view.setAttribute('data-properties', properties.join(',')); + } + + allPages[pageIndex] = view; + setControllerClass(view, options).then(() => { + if (onBeforeChange) { + onBeforeChange(view, false, options); } - if (options.type) { - view.setAttribute('data-type', options.type); + beforeAnimate(allPages, pageIndex, selected); + selectedPageIndex = pageIndex; + currentUrls[pageIndex] = options.url; + + if (!options.cancel && previousAnimatable) { + afterAnimate(allPages, pageIndex); } - const properties = []; - - if (options.fullscreen) { - properties.push('fullscreen'); + if (window.$) { + $.mobile = $.mobile || {}; + $.mobile.activePage = view; } - if (properties.length) { - view.setAttribute('data-properties', properties.join(',')); - } - - allPages[pageIndex] = view; - setControllerClass(view, options).then(() => { - if (onBeforeChange) { - onBeforeChange(view, false, options); - } - - beforeAnimate(allPages, pageIndex, selected); - selectedPageIndex = pageIndex; - currentUrls[pageIndex] = options.url; - - if (!options.cancel && previousAnimatable) { - afterAnimate(allPages, pageIndex); - } - - if (window.$) { - $.mobile = $.mobile || {}; - $.mobile.activePage = view; - } - - resolve(view); - }); + resolve(view); }); }); } From a72c843b13453a4c9020d18adc46c9337cdcaf75 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 09:12:30 +0100 Subject: [PATCH 028/155] Migration of playbackmanager to ES6 module --- package.json | 1 + src/components/playback/playbackmanager.js | 2080 ++++++++++---------- 2 files changed, 1036 insertions(+), 1045 deletions(-) diff --git a/package.json b/package.json index a18eb8e0fb..e785ae2ebd 100644 --- a/package.json +++ b/package.json @@ -138,6 +138,7 @@ "src/components/playback/mediasession.js", "src/components/playback/nowplayinghelper.js", "src/components/playback/playbackorientation.js", + "src/components/playback/playbackmanager.js", "src/components/playback/playerSelectionMenu.js", "src/components/playback/playersettingsmenu.js", "src/components/playback/playmethodhelper.js", diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 1d74cd69f5..99a21dd3e2 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -1,729 +1,738 @@ -define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'playQueueManager', 'userSettings', 'globalize', 'connectionManager', 'loading', 'apphost', 'screenfull'], function (events, datetime, appSettings, itemHelper, pluginManager, PlayQueueManager, userSettings, globalize, connectionManager, loading, apphost, screenfull) { - 'use strict'; - - PlayQueueManager = PlayQueueManager.default || PlayQueueManager; - - function enableLocalPlaylistManagement(player) { - if (player.getPlaylist) { - return false; - } - - if (player.isLocalPlayer) { - return true; - } +import events from 'events'; +import datetime from 'datetime'; +import appSettings from 'appSettings'; +import itemHelper from 'itemHelper'; +import pluginManager from 'pluginManager'; +import PlayQueueManager from 'playQueueManager'; +import * as userSettings from 'userSettings'; +import globalize from 'globalize'; +import connectionManager from 'connectionManager'; +import loading from 'loading'; +import apphost from 'apphost'; +import screenfull from 'screenfull'; +function enableLocalPlaylistManagement(player) { + if (player.getPlaylist) { return false; } - function bindToFullscreenChange(player) { - if (screenfull.isEnabled) { - screenfull.on('change', function () { - events.trigger(player, 'fullscreenchange'); - }); - } else { - // iOS Safari - document.addEventListener('webkitfullscreenchange', function () { - events.trigger(player, 'fullscreenchange'); - }, false); - } - } - - function triggerPlayerChange(playbackManagerInstance, newPlayer, newTarget, previousPlayer, previousTargetInfo) { - if (!newPlayer && !previousPlayer) { - return; - } - - if (newTarget && previousTargetInfo) { - if (newTarget.id === previousTargetInfo.id) { - return; - } - } - - events.trigger(playbackManagerInstance, 'playerchange', [newPlayer, newTarget, previousPlayer]); - } - - function reportPlayback(playbackManagerInstance, state, player, reportPlaylist, serverId, method, progressEventName) { - if (!serverId) { - // Not a server item - // We can expand on this later and possibly report them - events.trigger(playbackManagerInstance, 'reportplayback', [false]); - return; - } - - var info = Object.assign({}, state.PlayState); - info.ItemId = state.NowPlayingItem.Id; - - if (progressEventName) { - info.EventName = progressEventName; - } - - if (reportPlaylist) { - addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId); - } - - var apiClient = connectionManager.getApiClient(serverId); - var reportPlaybackPromise = apiClient[method](info); - // Notify that report has been sent - reportPlaybackPromise.then(() => { - events.trigger(playbackManagerInstance, 'reportplayback', [true]); - }); - } - - function getPlaylistSync(playbackManagerInstance, player) { - player = player || playbackManagerInstance._currentPlayer; - if (player && !enableLocalPlaylistManagement(player)) { - return player.getPlaylistSync(); - } - - return playbackManagerInstance._playQueueManager.getPlaylist(); - } - - function addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId) { - info.NowPlayingQueue = getPlaylistSync(playbackManagerInstance, player).map(function (i) { - var itemInfo = { - Id: i.Id, - PlaylistItemId: i.PlaylistItemId - }; - - if (i.ServerId !== serverId) { - itemInfo.ServerId = i.ServerId; - } - - return itemInfo; - }); - } - - function normalizeName(t) { - return t.toLowerCase().replace(' ', ''); - } - - function getItemsForPlayback(serverId, query) { - var apiClient = connectionManager.getApiClient(serverId); - - if (query.Ids && query.Ids.split(',').length === 1) { - var itemId = query.Ids.split(','); - - return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) { - return { - Items: [item], - TotalRecordCount: 1 - }; - }); - } else { - query.Limit = query.Limit || 300; - query.Fields = 'Chapters'; - query.ExcludeLocationTypes = 'Virtual'; - query.EnableTotalRecordCount = false; - query.CollapseBoxSetItems = false; - - return apiClient.getItems(apiClient.getCurrentUserId(), query); - } - } - - function createStreamInfoFromUrlItem(item) { - // Check item.Path for games - return { - url: item.Url || item.Path, - playMethod: 'DirectPlay', - item: item, - textTracks: [], - mediaType: item.MediaType - }; - } - - function mergePlaybackQueries(obj1, obj2) { - var query = Object.assign(obj1, obj2); - - var filters = query.Filters ? query.Filters.split(',') : []; - if (filters.indexOf('IsNotFolder') === -1) { - filters.push('IsNotFolder'); - } - query.Filters = filters.join(','); - return query; - } - - function backdropImageUrl(apiClient, item, options) { - options = options || {}; - options.type = options.type || 'Backdrop'; - - // If not resizing, get the original image - if (!options.maxWidth && !options.width && !options.maxHeight && !options.height) { - options.quality = 100; - } - - if (item.BackdropImageTags && item.BackdropImageTags.length) { - options.tag = item.BackdropImageTags[0]; - return apiClient.getScaledImageUrl(item.Id, options); - } - - if (item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) { - options.tag = item.ParentBackdropImageTags[0]; - return apiClient.getScaledImageUrl(item.ParentBackdropItemId, options); - } - - return null; - } - - function getMimeType(type, container) { - container = (container || '').toLowerCase(); - - if (type === 'audio') { - if (container === 'opus') { - return 'audio/ogg'; - } - if (container === 'webma') { - return 'audio/webm'; - } - if (container === 'm4a') { - return 'audio/mp4'; - } - } else if (type === 'video') { - if (container === 'mkv') { - return 'video/x-matroska'; - } - if (container === 'm4v') { - return 'video/mp4'; - } - if (container === 'mov') { - return 'video/quicktime'; - } - if (container === 'mpg') { - return 'video/mpeg'; - } - if (container === 'flv') { - return 'video/x-flv'; - } - } - - return type + '/' + container; - } - - function getParam(name, url) { - name = name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]'); - var regexS = '[\\?&]' + name + '=([^&#]*)'; - var regex = new RegExp(regexS, 'i'); - - var results = regex.exec(url); - if (results == null) { - return ''; - } else { - return decodeURIComponent(results[1].replace(/\+/g, ' ')); - } - } - - function isAutomaticPlayer(player) { - if (player.isLocalPlayer) { - return true; - } - - return false; - } - - function getAutomaticPlayers(instance, forceLocalPlayer) { - if (!forceLocalPlayer) { - var player = instance._currentPlayer; - if (player && !isAutomaticPlayer(player)) { - return [player]; - } - } - - return instance.getPlayers().filter(isAutomaticPlayer); - } - - function isServerItem(item) { - if (!item.Id) { - return false; - } + if (player.isLocalPlayer) { return true; } - function enableIntros(item) { - if (item.MediaType !== 'Video') { - return false; - } - if (item.Type === 'TvChannel') { - return false; - } - // disable for in-progress recordings - if (item.Status === 'InProgress') { - return false; - } + return false; +} - return isServerItem(item); +function bindToFullscreenChange(player) { + if (screenfull.isEnabled) { + screenfull.on('change', function () { + events.trigger(player, 'fullscreenchange'); + }); + } else { + // iOS Safari + document.addEventListener('webkitfullscreenchange', function () { + events.trigger(player, 'fullscreenchange'); + }, false); + } +} + +function triggerPlayerChange(playbackManagerInstance, newPlayer, newTarget, previousPlayer, previousTargetInfo) { + if (!newPlayer && !previousPlayer) { + return; } - function getIntros(firstItem, apiClient, options) { - if (options.startPositionTicks || options.startIndex || options.fullscreen === false || !enableIntros(firstItem) || !userSettings.enableCinemaMode()) { - return Promise.resolve({ - Items: [] - }); + if (newTarget && previousTargetInfo) { + if (newTarget.id === previousTargetInfo.id) { + return; } - - return apiClient.getIntros(firstItem.Id).then(function (result) { - return result; - }, function (err) { - return Promise.resolve({ - Items: [] - }); - }); } - function getAudioMaxValues(deviceProfile) { - // TODO - this could vary per codec and should be done on the server using the entire profile - var maxAudioSampleRate = null; - var maxAudioBitDepth = null; - var maxAudioBitrate = null; + events.trigger(playbackManagerInstance, 'playerchange', [newPlayer, newTarget, previousPlayer]); +} - deviceProfile.CodecProfiles.map(function (codecProfile) { - if (codecProfile.Type === 'Audio') { - (codecProfile.Conditions || []).map(function (condition) { - if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioBitDepth') { - return maxAudioBitDepth = condition.Value; - } else if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioSampleRate') { - return maxAudioSampleRate = condition.Value; - } else if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioBitrate') { - return maxAudioBitrate = condition.Value; - } - }); - } - }); +function reportPlayback(playbackManagerInstance, state, player, reportPlaylist, serverId, method, progressEventName) { + if (!serverId) { + // Not a server item + // We can expand on this later and possibly report them + events.trigger(playbackManagerInstance, 'reportplayback', [false]); + return; + } - return { - maxAudioSampleRate: maxAudioSampleRate, - maxAudioBitDepth: maxAudioBitDepth, - maxAudioBitrate: maxAudioBitrate + const info = Object.assign({}, state.PlayState); + info.ItemId = state.NowPlayingItem.Id; + + if (progressEventName) { + info.EventName = progressEventName; + } + + if (reportPlaylist) { + addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId); + } + + const apiClient = connectionManager.getApiClient(serverId); + const reportPlaybackPromise = apiClient[method](info); + // Notify that report has been sent + reportPlaybackPromise.then(() => { + events.trigger(playbackManagerInstance, 'reportplayback', [true]); + }); +} + +function getPlaylistSync(playbackManagerInstance, player) { + player = player || playbackManagerInstance._currentPlayer; + if (player && !enableLocalPlaylistManagement(player)) { + return player.getPlaylistSync(); + } + + return playbackManagerInstance._playQueueManager.getPlaylist(); +} + +function addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId) { + info.NowPlayingQueue = getPlaylistSync(playbackManagerInstance, player).map(function (i) { + const itemInfo = { + Id: i.Id, + PlaylistItemId: i.PlaylistItemId }; + + if (i.ServerId !== serverId) { + itemInfo.ServerId = i.ServerId; + } + + return itemInfo; + }); +} + +function normalizeName(t) { + return t.toLowerCase().replace(' ', ''); +} + +function getItemsForPlayback(serverId, query) { + const apiClient = connectionManager.getApiClient(serverId); + + if (query.Ids && query.Ids.split(',').length === 1) { + const itemId = query.Ids.split(','); + + return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) { + return { + Items: [item], + TotalRecordCount: 1 + }; + }); + } else { + query.Limit = query.Limit || 300; + query.Fields = 'Chapters'; + query.ExcludeLocationTypes = 'Virtual'; + query.EnableTotalRecordCount = false; + query.CollapseBoxSetItems = false; + + return apiClient.getItems(apiClient.getCurrentUserId(), query); + } +} + +function createStreamInfoFromUrlItem(item) { + // Check item.Path for games + return { + url: item.Url || item.Path, + playMethod: 'DirectPlay', + item: item, + textTracks: [], + mediaType: item.MediaType + }; +} + +function mergePlaybackQueries(obj1, obj2) { + const query = Object.assign(obj1, obj2); + + const filters = query.Filters ? query.Filters.split(',') : []; + if (filters.indexOf('IsNotFolder') === -1) { + filters.push('IsNotFolder'); + } + query.Filters = filters.join(','); + return query; +} + +function backdropImageUrl(apiClient, item, options) { + options = options || {}; + options.type = options.type || 'Backdrop'; + + // If not resizing, get the original image + if (!options.maxWidth && !options.width && !options.maxHeight && !options.height) { + options.quality = 100; } - var startingPlaySession = new Date().getTime(); - function getAudioStreamUrl(item, transcodingProfile, directPlayContainers, maxBitrate, apiClient, maxAudioSampleRate, maxAudioBitDepth, maxAudioBitrate, startPosition) { - var url = 'Audio/' + item.Id + '/universal'; + if (item.BackdropImageTags && item.BackdropImageTags.length) { + options.tag = item.BackdropImageTags[0]; + return apiClient.getScaledImageUrl(item.Id, options); + } - startingPlaySession++; - return apiClient.getUrl(url, { - UserId: apiClient.getCurrentUserId(), - DeviceId: apiClient.deviceId(), - MaxStreamingBitrate: maxAudioBitrate || maxBitrate, - Container: directPlayContainers, - TranscodingContainer: transcodingProfile.Container || null, - TranscodingProtocol: transcodingProfile.Protocol || null, - AudioCodec: transcodingProfile.AudioCodec, - MaxAudioSampleRate: maxAudioSampleRate, - MaxAudioBitDepth: maxAudioBitDepth, - api_key: apiClient.accessToken(), - PlaySessionId: startingPlaySession, - StartTimeTicks: startPosition || 0, - EnableRedirection: true, - EnableRemoteMedia: apphost.supports('remoteaudio') + if (item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) { + options.tag = item.ParentBackdropImageTags[0]; + return apiClient.getScaledImageUrl(item.ParentBackdropItemId, options); + } + + return null; +} + +function getMimeType(type, container) { + container = (container || '').toLowerCase(); + + if (type === 'audio') { + if (container === 'opus') { + return 'audio/ogg'; + } + if (container === 'webma') { + return 'audio/webm'; + } + if (container === 'm4a') { + return 'audio/mp4'; + } + } else if (type === 'video') { + if (container === 'mkv') { + return 'video/x-matroska'; + } + if (container === 'm4v') { + return 'video/mp4'; + } + if (container === 'mov') { + return 'video/quicktime'; + } + if (container === 'mpg') { + return 'video/mpeg'; + } + if (container === 'flv') { + return 'video/x-flv'; + } + } + + return type + '/' + container; +} + +function getParam(name, url) { + name = name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]'); + const regexS = '[\\?&]' + name + '=([^&#]*)'; + const regex = new RegExp(regexS, 'i'); + + const results = regex.exec(url); + if (results == null) { + return ''; + } else { + return decodeURIComponent(results[1].replace(/\+/g, ' ')); + } +} + +function isAutomaticPlayer(player) { + if (player.isLocalPlayer) { + return true; + } + + return false; +} + +function getAutomaticPlayers(instance, forceLocalPlayer) { + if (!forceLocalPlayer) { + const player = instance._currentPlayer; + if (player && !isAutomaticPlayer(player)) { + return [player]; + } + } + + return instance.getPlayers().filter(isAutomaticPlayer); +} + +function isServerItem(item) { + if (!item.Id) { + return false; + } + return true; +} + +function enableIntros(item) { + if (item.MediaType !== 'Video') { + return false; + } + if (item.Type === 'TvChannel') { + return false; + } + // disable for in-progress recordings + if (item.Status === 'InProgress') { + return false; + } + + return isServerItem(item); +} + +function getIntros(firstItem, apiClient, options) { + if (options.startPositionTicks || options.startIndex || options.fullscreen === false || !enableIntros(firstItem) || !userSettings.enableCinemaMode()) { + return Promise.resolve({ + Items: [] }); } - function getAudioStreamUrlFromDeviceProfile(item, deviceProfile, maxBitrate, apiClient, startPosition) { - var transcodingProfile = deviceProfile.TranscodingProfiles.filter(function (p) { - return p.Type === 'Audio' && p.Context === 'Streaming'; + return apiClient.getIntros(firstItem.Id).then(function (result) { + return result; + }, function (err) { + return Promise.resolve({ + Items: [] + }); + }); +} + +function getAudioMaxValues(deviceProfile) { + // TODO - this could vary per codec and should be done on the server using the entire profile + let maxAudioSampleRate = null; + let maxAudioBitDepth = null; + let maxAudioBitrate = null; + + deviceProfile.CodecProfiles.map(function (codecProfile) { + if (codecProfile.Type === 'Audio') { + (codecProfile.Conditions || []).map(function (condition) { + if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioBitDepth') { + return maxAudioBitDepth = condition.Value; + } else if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioSampleRate') { + return maxAudioSampleRate = condition.Value; + } else if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioBitrate') { + return maxAudioBitrate = condition.Value; + } + }); + } + }); + + return { + maxAudioSampleRate: maxAudioSampleRate, + maxAudioBitDepth: maxAudioBitDepth, + maxAudioBitrate: maxAudioBitrate + }; +} + +let startingPlaySession = new Date().getTime(); +function getAudioStreamUrl(item, transcodingProfile, directPlayContainers, maxBitrate, apiClient, maxAudioSampleRate, maxAudioBitDepth, maxAudioBitrate, startPosition) { + const url = 'Audio/' + item.Id + '/universal'; + + startingPlaySession++; + return apiClient.getUrl(url, { + UserId: apiClient.getCurrentUserId(), + DeviceId: apiClient.deviceId(), + MaxStreamingBitrate: maxAudioBitrate || maxBitrate, + Container: directPlayContainers, + TranscodingContainer: transcodingProfile.Container || null, + TranscodingProtocol: transcodingProfile.Protocol || null, + AudioCodec: transcodingProfile.AudioCodec, + MaxAudioSampleRate: maxAudioSampleRate, + MaxAudioBitDepth: maxAudioBitDepth, + api_key: apiClient.accessToken(), + PlaySessionId: startingPlaySession, + StartTimeTicks: startPosition || 0, + EnableRedirection: true, + EnableRemoteMedia: apphost.supports('remoteaudio') + }); +} + +function getAudioStreamUrlFromDeviceProfile(item, deviceProfile, maxBitrate, apiClient, startPosition) { + const transcodingProfile = deviceProfile.TranscodingProfiles.filter(function (p) { + return p.Type === 'Audio' && p.Context === 'Streaming'; + })[0]; + + let directPlayContainers = ''; + + deviceProfile.DirectPlayProfiles.map(function (p) { + if (p.Type === 'Audio') { + if (directPlayContainers) { + directPlayContainers += ',' + p.Container; + } else { + directPlayContainers = p.Container; + } + + if (p.AudioCodec) { + directPlayContainers += '|' + p.AudioCodec; + } + } + }); + + const maxValues = getAudioMaxValues(deviceProfile); + + return getAudioStreamUrl(item, transcodingProfile, directPlayContainers, maxBitrate, apiClient, maxValues.maxAudioSampleRate, maxValues.maxAudioBitDepth, maxValues.maxAudioBitrate, startPosition); +} + +function getStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition) { + const audioTranscodingProfile = deviceProfile.TranscodingProfiles.filter(function (p) { + return p.Type === 'Audio' && p.Context === 'Streaming'; + })[0]; + + let audioDirectPlayContainers = ''; + + deviceProfile.DirectPlayProfiles.map(function (p) { + if (p.Type === 'Audio') { + if (audioDirectPlayContainers) { + audioDirectPlayContainers += ',' + p.Container; + } else { + audioDirectPlayContainers = p.Container; + } + + if (p.AudioCodec) { + audioDirectPlayContainers += '|' + p.AudioCodec; + } + } + }); + + const maxValues = getAudioMaxValues(deviceProfile); + + const streamUrls = []; + + for (let i = 0, length = items.length; i < length; i++) { + const item = items[i]; + let streamUrl; + + if (item.MediaType === 'Audio' && !itemHelper.isLocalItem(item)) { + streamUrl = getAudioStreamUrl(item, audioTranscodingProfile, audioDirectPlayContainers, maxBitrate, apiClient, maxValues.maxAudioSampleRate, maxValues.maxAudioBitDepth, maxValues.maxAudioBitrate, startPosition); + } + + streamUrls.push(streamUrl || ''); + + if (i === 0) { + startPosition = 0; + } + } + + return Promise.resolve(streamUrls); +} + +function setStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition) { + return getStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition).then(function (streamUrls) { + for (let i = 0, length = items.length; i < length; i++) { + const item = items[i]; + const streamUrl = streamUrls[i]; + + if (streamUrl) { + item.PresetMediaSource = { + StreamUrl: streamUrl, + Id: item.Id, + MediaStreams: [], + RunTimeTicks: item.RunTimeTicks + }; + } + } + }); +} + +function getPlaybackInfo(player, + apiClient, + item, + deviceProfile, + maxBitrate, + startPosition, + isPlayback, + mediaSourceId, + audioStreamIndex, + subtitleStreamIndex, + liveStreamId, + enableDirectPlay, + enableDirectStream, + allowVideoStreamCopy, + allowAudioStreamCopy) { + if (!itemHelper.isLocalItem(item) && item.MediaType === 'Audio') { + return Promise.resolve({ + MediaSources: [ + { + StreamUrl: getAudioStreamUrlFromDeviceProfile(item, deviceProfile, maxBitrate, apiClient, startPosition), + Id: item.Id, + MediaStreams: [], + RunTimeTicks: item.RunTimeTicks + }] + }); + } + + if (item.PresetMediaSource) { + return Promise.resolve({ + MediaSources: [item.PresetMediaSource] + }); + } + + const itemId = item.Id; + + const query = { + UserId: apiClient.getCurrentUserId(), + StartTimeTicks: startPosition || 0 + }; + + if (isPlayback) { + query.IsPlayback = true; + query.AutoOpenLiveStream = true; + } else { + query.IsPlayback = false; + query.AutoOpenLiveStream = false; + } + + if (audioStreamIndex != null) { + query.AudioStreamIndex = audioStreamIndex; + } + if (subtitleStreamIndex != null) { + query.SubtitleStreamIndex = subtitleStreamIndex; + } + if (enableDirectPlay != null) { + query.EnableDirectPlay = enableDirectPlay; + } + + if (enableDirectStream != null) { + query.EnableDirectStream = enableDirectStream; + } + if (allowVideoStreamCopy != null) { + query.AllowVideoStreamCopy = allowVideoStreamCopy; + } + if (allowAudioStreamCopy != null) { + query.AllowAudioStreamCopy = allowAudioStreamCopy; + } + if (mediaSourceId) { + query.MediaSourceId = mediaSourceId; + } + if (liveStreamId) { + query.LiveStreamId = liveStreamId; + } + if (maxBitrate) { + query.MaxStreamingBitrate = maxBitrate; + } + if (player.enableMediaProbe && !player.enableMediaProbe(item)) { + query.EnableMediaProbe = false; + } + + // lastly, enforce player overrides for special situations + if (query.EnableDirectStream !== false) { + if (player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)) { + query.EnableDirectStream = false; + } + } + + if (player.getDirectPlayProtocols) { + query.DirectPlayProtocols = player.getDirectPlayProtocols(); + } + + return apiClient.getPlaybackInfo(itemId, query, deviceProfile); +} + +function getOptimalMediaSource(apiClient, item, versions) { + const promises = versions.map(function (v) { + return supportsDirectPlay(apiClient, item, v); + }); + + if (!promises.length) { + return Promise.reject(); + } + + return Promise.all(promises).then(function (results) { + for (let i = 0, length = versions.length; i < length; i++) { + versions[i].enableDirectPlay = results[i] || false; + } + let optimalVersion = versions.filter(function (v) { + return v.enableDirectPlay; })[0]; - var directPlayContainers = ''; + if (!optimalVersion) { + optimalVersion = versions.filter(function (v) { + return v.SupportsDirectStream; + })[0]; + } - deviceProfile.DirectPlayProfiles.map(function (p) { - if (p.Type === 'Audio') { - if (directPlayContainers) { - directPlayContainers += ',' + p.Container; - } else { - directPlayContainers = p.Container; - } - - if (p.AudioCodec) { - directPlayContainers += '|' + p.AudioCodec; - } - } - }); - - var maxValues = getAudioMaxValues(deviceProfile); - - return getAudioStreamUrl(item, transcodingProfile, directPlayContainers, maxBitrate, apiClient, maxValues.maxAudioSampleRate, maxValues.maxAudioBitDepth, maxValues.maxAudioBitrate, startPosition); - } - - function getStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition) { - var audioTranscodingProfile = deviceProfile.TranscodingProfiles.filter(function (p) { - return p.Type === 'Audio' && p.Context === 'Streaming'; + optimalVersion = optimalVersion || versions.filter(function (s) { + return s.SupportsTranscoding; })[0]; - var audioDirectPlayContainers = ''; + return optimalVersion || versions[0]; + }); +} - deviceProfile.DirectPlayProfiles.map(function (p) { - if (p.Type === 'Audio') { - if (audioDirectPlayContainers) { - audioDirectPlayContainers += ',' + p.Container; - } else { - audioDirectPlayContainers = p.Container; - } +function getLiveStream(player, apiClient, item, playSessionId, deviceProfile, maxBitrate, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex) { + const postData = { + DeviceProfile: deviceProfile, + OpenToken: mediaSource.OpenToken + }; - if (p.AudioCodec) { - audioDirectPlayContainers += '|' + p.AudioCodec; + const query = { + UserId: apiClient.getCurrentUserId(), + StartTimeTicks: startPosition || 0, + ItemId: item.Id, + PlaySessionId: playSessionId + }; + + if (maxBitrate) { + query.MaxStreamingBitrate = maxBitrate; + } + if (audioStreamIndex != null) { + query.AudioStreamIndex = audioStreamIndex; + } + if (subtitleStreamIndex != null) { + query.SubtitleStreamIndex = subtitleStreamIndex; + } + + // lastly, enforce player overrides for special situations + if (query.EnableDirectStream !== false) { + if (player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)) { + query.EnableDirectStream = false; + } + } + + return apiClient.ajax({ + url: apiClient.getUrl('LiveStreams/Open', query), + type: 'POST', + data: JSON.stringify(postData), + contentType: 'application/json', + dataType: 'json' + + }); +} + +function isHostReachable(mediaSource, apiClient) { + if (mediaSource.IsRemote) { + return Promise.resolve(true); + } + + return apiClient.getEndpointInfo().then(function (endpointInfo) { + if (endpointInfo.IsInNetwork) { + if (!endpointInfo.IsLocal) { + const path = (mediaSource.Path || '').toLowerCase(); + if (path.indexOf('localhost') !== -1 || path.indexOf('127.0.0.1') !== -1) { + // This will only work if the app is on the same machine as the server + return Promise.resolve(false); } } - }); - var maxValues = getAudioMaxValues(deviceProfile); - - var streamUrls = []; - - for (var i = 0, length = items.length; i < length; i++) { - var item = items[i]; - var streamUrl; - - if (item.MediaType === 'Audio' && !itemHelper.isLocalItem(item)) { - streamUrl = getAudioStreamUrl(item, audioTranscodingProfile, audioDirectPlayContainers, maxBitrate, apiClient, maxValues.maxAudioSampleRate, maxValues.maxAudioBitDepth, maxValues.maxAudioBitrate, startPosition); - } - - streamUrls.push(streamUrl || ''); - - if (i === 0) { - startPosition = 0; - } - } - - return Promise.resolve(streamUrls); - } - - function setStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition) { - return getStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition).then(function (streamUrls) { - for (var i = 0, length = items.length; i < length; i++) { - var item = items[i]; - var streamUrl = streamUrls[i]; - - if (streamUrl) { - item.PresetMediaSource = { - StreamUrl: streamUrl, - Id: item.Id, - MediaStreams: [], - RunTimeTicks: item.RunTimeTicks - }; - } - } - }); - } - - function getPlaybackInfo(player, - apiClient, - item, - deviceProfile, - maxBitrate, - startPosition, - isPlayback, - mediaSourceId, - audioStreamIndex, - subtitleStreamIndex, - liveStreamId, - enableDirectPlay, - enableDirectStream, - allowVideoStreamCopy, - allowAudioStreamCopy) { - if (!itemHelper.isLocalItem(item) && item.MediaType === 'Audio') { - return Promise.resolve({ - MediaSources: [ - { - StreamUrl: getAudioStreamUrlFromDeviceProfile(item, deviceProfile, maxBitrate, apiClient, startPosition), - Id: item.Id, - MediaStreams: [], - RunTimeTicks: item.RunTimeTicks - }] - }); - } - - if (item.PresetMediaSource) { - return Promise.resolve({ - MediaSources: [item.PresetMediaSource] - }); - } - - var itemId = item.Id; - - var query = { - UserId: apiClient.getCurrentUserId(), - StartTimeTicks: startPosition || 0 - }; - - if (isPlayback) { - query.IsPlayback = true; - query.AutoOpenLiveStream = true; - } else { - query.IsPlayback = false; - query.AutoOpenLiveStream = false; - } - - if (audioStreamIndex != null) { - query.AudioStreamIndex = audioStreamIndex; - } - if (subtitleStreamIndex != null) { - query.SubtitleStreamIndex = subtitleStreamIndex; - } - if (enableDirectPlay != null) { - query.EnableDirectPlay = enableDirectPlay; - } - - if (enableDirectStream != null) { - query.EnableDirectStream = enableDirectStream; - } - if (allowVideoStreamCopy != null) { - query.AllowVideoStreamCopy = allowVideoStreamCopy; - } - if (allowAudioStreamCopy != null) { - query.AllowAudioStreamCopy = allowAudioStreamCopy; - } - if (mediaSourceId) { - query.MediaSourceId = mediaSourceId; - } - if (liveStreamId) { - query.LiveStreamId = liveStreamId; - } - if (maxBitrate) { - query.MaxStreamingBitrate = maxBitrate; - } - if (player.enableMediaProbe && !player.enableMediaProbe(item)) { - query.EnableMediaProbe = false; - } - - // lastly, enforce player overrides for special situations - if (query.EnableDirectStream !== false) { - if (player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)) { - query.EnableDirectStream = false; - } - } - - if (player.getDirectPlayProtocols) { - query.DirectPlayProtocols = player.getDirectPlayProtocols(); - } - - return apiClient.getPlaybackInfo(itemId, query, deviceProfile); - } - - function getOptimalMediaSource(apiClient, item, versions) { - var promises = versions.map(function (v) { - return supportsDirectPlay(apiClient, item, v); - }); - - if (!promises.length) { - return Promise.reject(); - } - - return Promise.all(promises).then(function (results) { - for (var i = 0, length = versions.length; i < length; i++) { - versions[i].enableDirectPlay = results[i] || false; - } - var optimalVersion = versions.filter(function (v) { - return v.enableDirectPlay; - })[0]; - - if (!optimalVersion) { - optimalVersion = versions.filter(function (v) { - return v.SupportsDirectStream; - })[0]; - } - - optimalVersion = optimalVersion || versions.filter(function (s) { - return s.SupportsTranscoding; - })[0]; - - return optimalVersion || versions[0]; - }); - } - - function getLiveStream(player, apiClient, item, playSessionId, deviceProfile, maxBitrate, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex) { - var postData = { - DeviceProfile: deviceProfile, - OpenToken: mediaSource.OpenToken - }; - - var query = { - UserId: apiClient.getCurrentUserId(), - StartTimeTicks: startPosition || 0, - ItemId: item.Id, - PlaySessionId: playSessionId - }; - - if (maxBitrate) { - query.MaxStreamingBitrate = maxBitrate; - } - if (audioStreamIndex != null) { - query.AudioStreamIndex = audioStreamIndex; - } - if (subtitleStreamIndex != null) { - query.SubtitleStreamIndex = subtitleStreamIndex; - } - - // lastly, enforce player overrides for special situations - if (query.EnableDirectStream !== false) { - if (player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)) { - query.EnableDirectStream = false; - } - } - - return apiClient.ajax({ - url: apiClient.getUrl('LiveStreams/Open', query), - type: 'POST', - data: JSON.stringify(postData), - contentType: 'application/json', - dataType: 'json' - - }); - } - - function isHostReachable(mediaSource, apiClient) { - if (mediaSource.IsRemote) { return Promise.resolve(true); } - return apiClient.getEndpointInfo().then(function (endpointInfo) { - if (endpointInfo.IsInNetwork) { - if (!endpointInfo.IsLocal) { - var path = (mediaSource.Path || '').toLowerCase(); - if (path.indexOf('localhost') !== -1 || path.indexOf('127.0.0.1') !== -1) { - // This will only work if the app is on the same machine as the server - return Promise.resolve(false); - } - } + // media source is in network, but connection is out of network + return Promise.resolve(false); + }); +} - return Promise.resolve(true); - } +function supportsDirectPlay(apiClient, item, mediaSource) { + // folder rip hacks due to not yet being supported by the stream building engine + const isFolderRip = mediaSource.VideoType === 'BluRay' || mediaSource.VideoType === 'Dvd' || mediaSource.VideoType === 'HdDvd'; - // media source is in network, but connection is out of network + if (mediaSource.SupportsDirectPlay || isFolderRip) { + if (mediaSource.IsRemote && !apphost.supports('remotevideo')) { return Promise.resolve(false); - }); - } + } - function supportsDirectPlay(apiClient, item, mediaSource) { - // folder rip hacks due to not yet being supported by the stream building engine - var isFolderRip = mediaSource.VideoType === 'BluRay' || mediaSource.VideoType === 'Dvd' || mediaSource.VideoType === 'HdDvd'; - - if (mediaSource.SupportsDirectPlay || isFolderRip) { - if (mediaSource.IsRemote && !apphost.supports('remotevideo')) { - return Promise.resolve(false); + if (mediaSource.Protocol === 'Http' && !mediaSource.RequiredHttpHeaders.length) { + // If this is the only way it can be played, then allow it + if (!mediaSource.SupportsDirectStream && !mediaSource.SupportsTranscoding) { + return Promise.resolve(true); + } else { + return isHostReachable(mediaSource, apiClient); } + } else if (mediaSource.Protocol === 'File') { + return new Promise(function (resolve, reject) { + // Determine if the file can be accessed directly + import('filesystem').then(({ default: filesystem }) => { + const method = isFolderRip ? + 'directoryExists' : + 'fileExists'; - if (mediaSource.Protocol === 'Http' && !mediaSource.RequiredHttpHeaders.length) { - // If this is the only way it can be played, then allow it - if (!mediaSource.SupportsDirectStream && !mediaSource.SupportsTranscoding) { - return Promise.resolve(true); - } else { - return isHostReachable(mediaSource, apiClient); - } - } else if (mediaSource.Protocol === 'File') { - return new Promise(function (resolve, reject) { - // Determine if the file can be accessed directly - require(['filesystem'], function (filesystem) { - var method = isFolderRip ? - 'directoryExists' : - 'fileExists'; - - filesystem[method](mediaSource.Path).then(function () { - resolve(true); - }, function () { - resolve(false); - }); + filesystem[method](mediaSource.Path).then(function () { + resolve(true); + }, function () { + resolve(false); }); }); - } - } - - return Promise.resolve(false); - } - - function validatePlaybackInfoResult(instance, result) { - if (result.ErrorCode) { - showPlaybackInfoErrorMessage(instance, result.ErrorCode); - return false; - } - - return true; - } - - function showPlaybackInfoErrorMessage(instance, errorCode, playNextTrack) { - require(['alert'], function (alert) { - alert.default({ - text: globalize.translate('PlaybackError' + errorCode), - title: globalize.translate('HeaderPlaybackError') - }).then(function () { - if (playNextTrack) { - instance.nextTrack(); - } }); + } + } + + return Promise.resolve(false); +} + +function validatePlaybackInfoResult(instance, result) { + if (result.ErrorCode) { + showPlaybackInfoErrorMessage(instance, result.ErrorCode); + return false; + } + + return true; +} + +function showPlaybackInfoErrorMessage(instance, errorCode, playNextTrack) { + import('alert').then(({ default: alert }) => { + alert({ + text: globalize.translate('PlaybackError' + errorCode), + title: globalize.translate('HeaderPlaybackError') + }).then(function () { + if (playNextTrack) { + instance.nextTrack(); + } }); + }); +} + +function normalizePlayOptions(playOptions) { + playOptions.fullscreen = playOptions.fullscreen !== false; +} + +function truncatePlayOptions(playOptions) { + return { + fullscreen: playOptions.fullscreen, + mediaSourceId: playOptions.mediaSourceId, + audioStreamIndex: playOptions.audioStreamIndex, + subtitleStreamIndex: playOptions.subtitleStreamIndex, + startPositionTicks: playOptions.startPositionTicks + }; +} + +function getNowPlayingItemForReporting(player, item, mediaSource) { + const nowPlayingItem = Object.assign({}, item); + + if (mediaSource) { + nowPlayingItem.RunTimeTicks = mediaSource.RunTimeTicks; + nowPlayingItem.MediaStreams = mediaSource.MediaStreams; + + // not needed + nowPlayingItem.MediaSources = null; } - function normalizePlayOptions(playOptions) { - playOptions.fullscreen = playOptions.fullscreen !== false; + nowPlayingItem.RunTimeTicks = nowPlayingItem.RunTimeTicks || player.duration() * 10000; + + return nowPlayingItem; +} + +function displayPlayerIndividually(player) { + return !player.isLocalPlayer; +} + +function createTarget(instance, player) { + return { + name: player.name, + id: player.id, + playerName: player.name, + playableMediaTypes: ['Audio', 'Video', 'Photo', 'Book'].map(player.canPlayMediaType), + isLocalPlayer: player.isLocalPlayer, + supportedCommands: instance.getSupportedCommands(player) + }; +} + +function getPlayerTargets(player) { + if (player.getTargets) { + return player.getTargets(); } - function truncatePlayOptions(playOptions) { - return { - fullscreen: playOptions.fullscreen, - mediaSourceId: playOptions.mediaSourceId, - audioStreamIndex: playOptions.audioStreamIndex, - subtitleStreamIndex: playOptions.subtitleStreamIndex, - startPositionTicks: playOptions.startPositionTicks - }; - } + return Promise.resolve([createTarget(player)]); +} - function getNowPlayingItemForReporting(player, item, mediaSource) { - var nowPlayingItem = Object.assign({}, item); +function sortPlayerTargets(a, b) { + let aVal = a.isLocalPlayer ? 0 : 1; + let bVal = b.isLocalPlayer ? 0 : 1; - if (mediaSource) { - nowPlayingItem.RunTimeTicks = mediaSource.RunTimeTicks; - nowPlayingItem.MediaStreams = mediaSource.MediaStreams; + aVal = aVal.toString() + a.name; + bVal = bVal.toString() + b.name; - // not needed - nowPlayingItem.MediaSources = null; - } + return aVal.localeCompare(bVal); +} - nowPlayingItem.RunTimeTicks = nowPlayingItem.RunTimeTicks || player.duration() * 10000; +class PlaybackManager { + constructor() { + const self = this; - return nowPlayingItem; - } - - function displayPlayerIndividually(player) { - return !player.isLocalPlayer; - } - - function createTarget(instance, player) { - return { - name: player.name, - id: player.id, - playerName: player.name, - playableMediaTypes: ['Audio', 'Video', 'Photo', 'Book'].map(player.canPlayMediaType), - isLocalPlayer: player.isLocalPlayer, - supportedCommands: instance.getSupportedCommands(player) - }; - } - - function getPlayerTargets(player) { - if (player.getTargets) { - return player.getTargets(); - } - - return Promise.resolve([createTarget(player)]); - } - - function sortPlayerTargets(a, b) { - var aVal = a.isLocalPlayer ? 0 : 1; - var bVal = b.isLocalPlayer ? 0 : 1; - - aVal = aVal.toString() + a.name; - bVal = bVal.toString() + b.name; - - return aVal.localeCompare(bVal); - } - - function PlaybackManager() { - var self = this; - - var players = []; - var currentTargetInfo; - var currentPairingId = null; + const players = []; + let currentTargetInfo; + let currentPairingId = null; this._playNextAfterEnded = true; - var playerStates = {}; + const playerStates = {}; this._playQueueManager = new PlayQueueManager(); @@ -736,7 +745,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.currentItem(); } - var data = getPlayerData(player); + const data = getPlayerData(player); return data.streamInfo ? data.streamInfo.item : null; }; @@ -749,7 +758,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.currentMediaSource(); } - var data = getPlayerData(player); + const data = getPlayerData(player); return data.streamInfo ? data.streamInfo.mediaSource : null; }; @@ -762,7 +771,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.playMethod(); } - var data = getPlayerData(player); + const data = getPlayerData(player); return data.streamInfo ? data.streamInfo.playMethod : null; }; @@ -775,21 +784,20 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.playSessionId(); } - var data = getPlayerData(player); + const data = getPlayerData(player); return data.streamInfo ? data.streamInfo.playSessionId : null; }; self.getPlayerInfo = function () { - var player = self._currentPlayer; + const player = self._currentPlayer; if (!player) { return null; } - var target = currentTargetInfo || {}; + const target = currentTargetInfo || {}; return { - name: player.name, isLocalPlayer: player.isLocalPlayer, id: target.id, @@ -845,7 +853,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla currentPairingId = targetInfo.id; - var promise = player.tryPair ? + const promise = player.tryPair ? player.tryPair(targetInfo) : Promise.resolve(); @@ -863,11 +871,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }; self.getTargets = function () { - var promises = players.filter(displayPlayerIndividually).map(getPlayerTargets); + const promises = players.filter(displayPlayerIndividually).map(getPlayerTargets); return Promise.all(promises).then(function (responses) { return connectionManager.currentApiClient().getCurrentUser().then(function (user) { - var targets = []; + const targets = []; targets.push({ name: globalize.translate('HeaderMyDevice'), @@ -881,10 +889,10 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla user: user }); - for (var i = 0; i < responses.length; i++) { - var subTargets = responses[i]; + for (let i = 0; i < responses.length; i++) { + const subTargets = responses[i]; - for (var j = 0; j < subTargets.length; j++) { + for (let j = 0; j < subTargets.length; j++) { targets.push(subTargets[j]); } } @@ -899,7 +907,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla throw new Error('player cannot be null'); } - var index = getPlayerData(player).subtitleStreamIndex; + const index = getPlayerData(player).subtitleStreamIndex; if (index == null || index === -1) { return null; @@ -928,7 +936,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }; function removeCurrentPlayer(player) { - var previousPlayer = self._currentPlayer; + const previousPlayer = self._currentPlayer; if (!previousPlayer || player.id === previousPlayer.id) { setCurrentPlayerInternal(null); @@ -936,8 +944,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function setCurrentPlayerInternal(player, targetInfo) { - var previousPlayer = self._currentPlayer; - var previousTargetInfo = currentTargetInfo; + const previousPlayer = self._currentPlayer; + const previousTargetInfo = currentTargetInfo; if (player && !targetInfo && player.isLocalPlayer) { targetInfo = createTarget(self, player); @@ -988,7 +996,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } if (self.isPlaying(player)) { - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); return playerData.streamInfo.mediaType === mediaType; } @@ -1027,7 +1035,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } self.canPlay = function (item) { - var itemType = item.Type; + const itemType = item.Type; if (itemType === 'PhotoAlbum' || itemType === 'MusicGenre' || itemType === 'Season' || itemType === 'Series' || itemType === 'BoxSet' || itemType === 'MusicAlbum' || itemType === 'MusicArtist' || itemType === 'Playlist') { return true; @@ -1057,12 +1065,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla player = player || self._currentPlayer; if (player) { - var current = self.getAspectRatio(player); + const current = self.getAspectRatio(player); - var supported = self.getSupportedAspectRatios(player); + const supported = self.getSupportedAspectRatios(player); - var index = -1; - for (var i = 0, length = supported.length; i < length; i++) { + let index = -1; + for (let i = 0, length = supported.length; i < length; i++) { if (supported[i].id === current) { index = i; break; @@ -1104,7 +1112,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } }; - var brightnessOsdLoaded; + let brightnessOsdLoaded; self.setBrightness = function (val, player) { player = player || self._currentPlayer; @@ -1112,7 +1120,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (!brightnessOsdLoaded) { brightnessOsdLoaded = true; // TODO: Have this trigger an event instead to get the osd out of here - require(['brightnessOsd']); + import('brightnessOsd').then(); } player.setBrightness(val); } @@ -1168,11 +1176,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var currentMediaSource = self.currentMediaSource(player); - var mediaStreams = []; - var i; - var length; - for (i = 0, length = currentMediaSource.MediaStreams.length; i < length; i++) { + const currentMediaSource = self.currentMediaSource(player); + const mediaStreams = []; + for (let i = 0, length = currentMediaSource.MediaStreams.length; i < length; i++) { if (currentMediaSource.MediaStreams[i].Type === 'Audio') { mediaStreams.push(currentMediaSource.MediaStreams[i]); } @@ -1183,16 +1189,16 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var currentStreamIndex = self.getAudioStreamIndex(player); - var indexInList = -1; - for (i = 0, length = mediaStreams.length; i < length; i++) { + const currentStreamIndex = self.getAudioStreamIndex(player); + let indexInList = -1; + for (let i = 0, length = mediaStreams.length; i < length; i++) { if (mediaStreams[i].Index === currentStreamIndex) { indexInList = i; break; } } - var nextIndex = indexInList + 1; + let nextIndex = indexInList + 1; if (nextIndex >= mediaStreams.length) { nextIndex = 0; } @@ -1212,11 +1218,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var currentMediaSource = self.currentMediaSource(player); - var mediaStreams = []; - var i; - var length; - for (i = 0, length = currentMediaSource.MediaStreams.length; i < length; i++) { + const currentMediaSource = self.currentMediaSource(player); + const mediaStreams = []; + for (let i = 0, length = currentMediaSource.MediaStreams.length; i < length; i++) { if (currentMediaSource.MediaStreams[i].Type === 'Subtitle') { mediaStreams.push(currentMediaSource.MediaStreams[i]); } @@ -1227,16 +1231,16 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var currentStreamIndex = self.getSubtitleStreamIndex(player); - var indexInList = -1; - for (i = 0, length = mediaStreams.length; i < length; i++) { + const currentStreamIndex = self.getSubtitleStreamIndex(player); + let indexInList = -1; + for (let i = 0, length = mediaStreams.length; i < length; i++) { if (mediaStreams[i].Index === currentStreamIndex) { indexInList = i; break; } } - var nextIndex = indexInList + 1; + let nextIndex = indexInList + 1; if (nextIndex >= mediaStreams.length) { nextIndex = -1; } @@ -1256,12 +1260,10 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }; function isAudioStreamSupported(mediaSource, index, deviceProfile) { - var mediaStream; - var i; - var length; - var mediaStreams = mediaSource.MediaStreams; + let mediaStream; + const mediaStreams = mediaSource.MediaStreams; - for (i = 0, length = mediaStreams.length; i < length; i++) { + for (let i = 0, length = mediaStreams.length; i < length; i++) { if (mediaStreams[i].Type === 'Audio' && mediaStreams[i].Index === index) { mediaStream = mediaStreams[i]; break; @@ -1272,13 +1274,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return false; } - var codec = (mediaStream.Codec || '').toLowerCase(); + const codec = (mediaStream.Codec || '').toLowerCase(); if (!codec) { return false; } - var profiles = deviceProfile.DirectPlayProfiles || []; + const profiles = deviceProfile.DirectPlayProfiles || []; return profiles.filter(function (p) { if (p.Type === 'Video') { @@ -1327,7 +1329,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla apiClient = connectionManager.currentApiClient(); } - var endpointInfo = apiClient.getSavedEndpointInfo() || {}; + const endpointInfo = apiClient.getSavedEndpointInfo() || {}; return appSettings.maxStreamingBitrate(endpointInfo.IsInNetwork, mediaType); } @@ -1338,16 +1340,16 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.getMaxStreamingBitrate(); } - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); if (playerData.maxStreamingBitrate) { return playerData.maxStreamingBitrate; } - var mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; - var currentItem = self.currentItem(player); + const mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; + const currentItem = self.currentItem(player); - var apiClient = currentItem ? connectionManager.getApiClient(currentItem.ServerId) : connectionManager.currentApiClient(); + const apiClient = currentItem ? connectionManager.getApiClient(currentItem.ServerId) : connectionManager.currentApiClient(); return getSavedMaxStreamingBitrate(apiClient, mediaType); }; @@ -1357,12 +1359,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.enableAutomaticBitrateDetection(); } - var playerData = getPlayerData(player); - var mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; - var currentItem = self.currentItem(player); + const playerData = getPlayerData(player); + const mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; + const currentItem = self.currentItem(player); - var apiClient = currentItem ? connectionManager.getApiClient(currentItem.ServerId) : connectionManager.currentApiClient(); - var endpointInfo = apiClient.getSavedEndpointInfo() || {}; + const apiClient = currentItem ? connectionManager.getApiClient(currentItem.ServerId) : connectionManager.currentApiClient(); + const endpointInfo = apiClient.getSavedEndpointInfo() || {}; return appSettings.enableAutomaticBitrateDetection(endpointInfo.IsInNetwork, mediaType); }; @@ -1373,13 +1375,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.setMaxStreamingBitrate(options); } - var apiClient = connectionManager.getApiClient(self.currentItem(player).ServerId); + const apiClient = connectionManager.getApiClient(self.currentItem(player).ServerId); apiClient.getEndpointInfo().then(function (endpointInfo) { - var playerData = getPlayerData(player); - var mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; + const playerData = getPlayerData(player); + const mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; - var promise; + let promise; if (options.enableAutomaticBitrateDetection) { appSettings.enableAutomaticBitrateDetection(endpointInfo.IsInNetwork, mediaType, true); promise = apiClient.detectBitrate(true); @@ -1472,17 +1474,17 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.setSubtitleStreamIndex(index); } - var currentStream = getCurrentSubtitleStream(player); + const currentStream = getCurrentSubtitleStream(player); - var newStream = getSubtitleStream(player, index); + const newStream = getSubtitleStream(player, index); if (!currentStream && !newStream) { return; } - var selectedTrackElementIndex = -1; + let selectedTrackElementIndex = -1; - var currentPlayMethod = self.playMethod(player); + const currentPlayMethod = self.playMethod(player); if (currentStream && !newStream) { if (getDeliveryMethod(currentStream) === 'Encode' || (getDeliveryMethod(currentStream) === 'Embed' && currentPlayMethod === 'Transcode')) { @@ -1519,30 +1521,30 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla getPlayerData(player).subtitleStreamIndex = index; }; - self.supportSubtitleOffset = function(player) { + self.supportSubtitleOffset = function (player) { player = player || self._currentPlayer; return player && 'setSubtitleOffset' in player; }; - self.enableShowingSubtitleOffset = function(player) { + self.enableShowingSubtitleOffset = function (player) { player = player || self._currentPlayer; player.enableShowingSubtitleOffset(); }; - self.disableShowingSubtitleOffset = function(player) { + self.disableShowingSubtitleOffset = function (player) { player = player || self._currentPlayer; if (player.disableShowingSubtitleOffset) { player.disableShowingSubtitleOffset(); } }; - self.isShowingSubtitleOffsetEnabled = function(player) { + self.isShowingSubtitleOffsetEnabled = function (player) { player = player || self._currentPlayer; return player.isShowingSubtitleOffsetEnabled(); }; - self.isSubtitleStreamExternal = function(index, player) { - var stream = getSubtitleStream(player, index); + self.isSubtitleStreamExternal = function (index, player) { + const stream = getSubtitleStream(player, index); return stream ? getDeliveryMethod(stream) === 'External' : false; }; @@ -1553,15 +1555,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } }; - self.getPlayerSubtitleOffset = function(player) { + self.getPlayerSubtitleOffset = function (player) { player = player || self._currentPlayer; if (player.getSubtitleOffset) { return player.getSubtitleOffset(); } }; - self.canHandleOffsetOnCurrentSubtitle = function(player) { - var index = self.getSubtitleStreamIndex(player); + self.canHandleOffsetOnCurrentSubtitle = function (player) { + const index = self.getSubtitleStreamIndex(player); return index !== -1 && self.isSubtitleStreamExternal(index, player); }; @@ -1590,7 +1592,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } } - var ticks = getCurrentTicks(player) + offsetTicks; + const ticks = getCurrentTicks(player) + offsetTicks; return this.seek(ticks, player); }; @@ -1600,9 +1602,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla throw new Error('player cannot be null'); } - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); - var currentSrc = (playerData.streamInfo.url || '').toLowerCase(); + const currentSrc = (playerData.streamInfo.url || '').toLowerCase(); if (currentSrc.indexOf('.m3u8') !== -1) { return true; @@ -1612,7 +1614,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.seekable(); } - var isPlayMethodTranscode = self.playMethod(player) === 'Transcode'; + const isPlayMethodTranscode = self.playMethod(player) === 'Transcode'; if (isPlayMethodTranscode) { return false; @@ -1629,37 +1631,35 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla params = params || {}; - var liveStreamId = getPlayerData(player).streamInfo.liveStreamId; - var lastMediaInfoQuery = getPlayerData(player).streamInfo.lastMediaInfoQuery; + const liveStreamId = getPlayerData(player).streamInfo.liveStreamId; + const lastMediaInfoQuery = getPlayerData(player).streamInfo.lastMediaInfoQuery; - var playSessionId = self.playSessionId(player); + const playSessionId = self.playSessionId(player); - var currentItem = self.currentItem(player); + const currentItem = self.currentItem(player); player.getDeviceProfile(currentItem, { - isRetry: params.EnableDirectPlay === false - }).then(function (deviceProfile) { - var audioStreamIndex = params.AudioStreamIndex == null ? getPlayerData(player).audioStreamIndex : params.AudioStreamIndex; - var subtitleStreamIndex = params.SubtitleStreamIndex == null ? getPlayerData(player).subtitleStreamIndex : params.SubtitleStreamIndex; + const audioStreamIndex = params.AudioStreamIndex == null ? getPlayerData(player).audioStreamIndex : params.AudioStreamIndex; + const subtitleStreamIndex = params.SubtitleStreamIndex == null ? getPlayerData(player).subtitleStreamIndex : params.SubtitleStreamIndex; - var currentMediaSource = self.currentMediaSource(player); - var apiClient = connectionManager.getApiClient(currentItem.ServerId); + let currentMediaSource = self.currentMediaSource(player); + const apiClient = connectionManager.getApiClient(currentItem.ServerId); if (ticks) { ticks = parseInt(ticks); } - var maxBitrate = params.MaxStreamingBitrate || self.getMaxStreamingBitrate(player); + const maxBitrate = params.MaxStreamingBitrate || self.getMaxStreamingBitrate(player); - var currentPlayOptions = currentItem.playOptions || getDefaultPlayOptions(); + const currentPlayOptions = currentItem.playOptions || getDefaultPlayOptions(); getPlaybackInfo(player, apiClient, currentItem, deviceProfile, maxBitrate, ticks, true, currentMediaSource.Id, audioStreamIndex, subtitleStreamIndex, liveStreamId, params.EnableDirectPlay, params.EnableDirectStream, params.AllowVideoStreamCopy, params.AllowAudioStreamCopy).then(function (result) { if (validatePlaybackInfoResult(self, result)) { currentMediaSource = result.MediaSources[0]; - var streamInfo = createStreamInfo(apiClient, currentItem.MediaType, currentItem, currentMediaSource, ticks); + const streamInfo = createStreamInfo(apiClient, currentItem.MediaType, currentItem, currentMediaSource, ticks); streamInfo.fullscreen = currentPlayOptions.fullscreen; streamInfo.lastMediaInfoQuery = lastMediaInfoQuery; @@ -1679,14 +1679,14 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function changeStreamToUrl(apiClient, player, playSessionId, streamInfo, newPositionTicks) { - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); playerData.isChangingStream = true; if (playerData.streamInfo && playSessionId) { apiClient.stopActiveEncodings(playSessionId).then(function () { // Stop the first transcoding afterwards because the player may still send requests to the original url - var afterSetSrc = function () { + const afterSetSrc = function () { apiClient.stopActiveEncodings(playSessionId); }; setSrcIntoPlayer(apiClient, player, streamInfo).then(afterSetSrc, afterSetSrc); @@ -1698,7 +1698,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla function setSrcIntoPlayer(apiClient, player, streamInfo) { return player.play(streamInfo).then(function () { - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); playerData.isChangingStream = false; playerData.streamInfo = streamInfo; @@ -1707,7 +1707,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla sendProgressUpdate(player, 'timeupdate'); }, function (e) { - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); playerData.isChangingStream = false; onPlaybackError.call(player, e, { @@ -1725,12 +1725,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }); } - var firstItem = items[0]; - var promise; + const firstItem = items[0]; + let promise; - var serverId = firstItem.ServerId; + const serverId = firstItem.ServerId; - var queryOptions = options.queryOptions || {}; + const queryOptions = options.queryOptions || {}; if (firstItem.Type === 'Program') { promise = getItemsForPlayback(serverId, { @@ -1758,9 +1758,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla SortBy: options.shuffle ? 'Random' : 'SortName', MediaTypes: 'Photo,Video' }).then(function (result) { - var items = result.Items; + const items = result.Items; - var index = items.map(function (i) { + let index = items.map(function (i) { return i.Id; }).indexOf(firstItem.Id); @@ -1781,7 +1781,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla SortBy: options.shuffle ? 'Random' : 'SortName', MediaTypes: 'Photo,Video', Limit: 1000 - }); } else if (firstItem.Type === 'MusicGenre') { promise = getItemsForPlayback(serverId, { @@ -1793,18 +1792,16 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }); } else if (firstItem.IsFolder) { promise = getItemsForPlayback(serverId, mergePlaybackQueries({ - ParentId: firstItem.Id, Filters: 'IsNotFolder', Recursive: true, // These are pre-sorted SortBy: options.shuffle ? 'Random' : (['BoxSet'].indexOf(firstItem.Type) === -1 ? 'SortName' : null), MediaTypes: 'Audio,Video' - }, queryOptions)); } else if (firstItem.Type === 'Episode' && items.length === 1 && getPlayer(firstItem, options).supportsProgress !== false) { promise = new Promise(function (resolve, reject) { - var apiClient = connectionManager.getApiClient(firstItem.ServerId); + const apiClient = connectionManager.getApiClient(firstItem.ServerId); apiClient.getCurrentUser().then(function (user) { if (!user.Configuration.EnableNextEpisodeAutoPlay || !firstItem.SeriesId) { @@ -1817,9 +1814,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla IsMissing: false, UserId: apiClient.getCurrentUserId(), Fields: 'Chapters' - }).then(function (episodesResult) { - var foundItem = false; + let foundItem = false; episodesResult.Items = episodesResult.Items.filter(function (e) { if (foundItem) { return true; @@ -1874,9 +1870,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return getItemsForPlayback(options.serverId, { - Ids: options.ids.join(',') - }).then(function (result) { return translateItemsForPlayback(result.Items, options).then(function (items) { return playWithIntros(items, options); @@ -1892,7 +1886,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (!player.name) { throw new Error('player name cannot be null'); } - var state = playerStates[player.name]; + let state = playerStates[player.name]; if (!state) { playerStates[player.name] = {}; @@ -1916,7 +1910,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla item = item || self.currentItem(player); mediaSource = mediaSource || self.currentMediaSource(player); - var state = { + const state = { PlayState: {} }; @@ -1974,13 +1968,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla throw new Error('player cannot be null'); } - var mediaSource = self.currentMediaSource(player); + const mediaSource = self.currentMediaSource(player); if (mediaSource && mediaSource.RunTimeTicks) { return mediaSource.RunTimeTicks; } - var playerDuration = player.duration(); + let playerDuration = player.duration(); if (playerDuration) { playerDuration *= 10000; @@ -1994,9 +1988,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla throw new Error('player cannot be null'); } - var playerTime = Math.floor(10000 * (player || self._currentPlayer).currentTime()); + let playerTime = Math.floor(10000 * (player || self._currentPlayer).currentTime()); - var streamInfo = getPlayerData(player).streamInfo; + const streamInfo = getPlayerData(player).streamInfo; if (streamInfo) { playerTime += getPlayerData(player).streamInfo.transcodingOffsetTicks || 0; } @@ -2008,8 +2002,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla self.getCurrentTicks = getCurrentTicks; function playOther(items, options, user) { - var playStartIndex = options.startIndex || 0; - var player = getPlayer(items[playStartIndex], options); + const playStartIndex = options.startIndex || 0; + const player = getPlayer(items[playStartIndex], options); loading.hide(); @@ -2019,8 +2013,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function playWithIntros(items, options, user) { - var playStartIndex = options.startIndex || 0; - var firstItem = items[playStartIndex]; + let playStartIndex = options.startIndex || 0; + let firstItem = items[playStartIndex]; // If index was bad, reset it if (!firstItem) { @@ -2038,11 +2032,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return playOther(items, options, user); } - var apiClient = connectionManager.getApiClient(firstItem.ServerId); + const apiClient = connectionManager.getApiClient(firstItem.ServerId); return getIntros(firstItem, apiClient, options).then(function (introsResult) { - var introItems = introsResult.Items; - var introPlayOptions; + const introItems = introsResult.Items; + let introPlayOptions; firstItem.playOptions = truncatePlayOptions(options); @@ -2098,9 +2092,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } // TODO: This should be the media type requested, not the original media type - var mediaType = item.MediaType; + const mediaType = item.MediaType; - var onBitrateDetectionFailure = function () { + const onBitrateDetectionFailure = function () { return playAfterBitrateDetect(getSavedMaxStreamingBitrate(connectionManager.getApiClient(item.ServerId), mediaType), item, playOptions, onPlaybackStartedFn); }; @@ -2108,7 +2102,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return onBitrateDetectionFailure(); } - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); apiClient.getEndpointInfo().then(function (endpointInfo) { if ((mediaType === 'Video' || mediaType === 'Audio') && appSettings.enableAutomaticBitrateDetection(endpointInfo.IsInNetwork, mediaType)) { return apiClient.detectBitrate().then(function (bitrate) { @@ -2124,7 +2118,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onInterceptorRejection() { - var player = self._currentPlayer; + const player = self._currentPlayer; if (player) { destroyPlayer(player); @@ -2142,7 +2136,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla function runInterceptors(item, playOptions) { return new Promise(function (resolve, reject) { - var interceptors = pluginManager.ofType('preplayintercept'); + const interceptors = pluginManager.ofType('preplayintercept'); interceptors.sort(function (a, b) { return (a.order || 0) - (b.order || 0); @@ -2155,7 +2149,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla loading.hide(); - var options = Object.assign({}, playOptions); + const options = Object.assign({}, playOptions); options.mediaType = item.MediaType; options.item = item; @@ -2170,7 +2164,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var interceptor = interceptors[index]; + const interceptor = interceptors[index]; interceptor.intercept(options).then(function () { runNextPrePlay(interceptors, index + 1, options, resolve, reject); @@ -2193,12 +2187,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function playAfterBitrateDetect(maxBitrate, item, playOptions, onPlaybackStartedFn) { - var startPosition = playOptions.startPositionTicks; + const startPosition = playOptions.startPositionTicks; - var player = getPlayer(item, playOptions); - var activePlayer = self._currentPlayer; + const player = getPlayer(item, playOptions); + const activePlayer = self._currentPlayer; - var promise; + let promise; if (activePlayer) { // TODO: if changing players within the same playlist, this will cause nextItem to be null @@ -2210,7 +2204,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (!isServerItem(item) || item.MediaType === 'Book') { return promise.then(function () { - var streamInfo = createStreamInfoFromUrlItem(item); + const streamInfo = createStreamInfoFromUrlItem(item); streamInfo.fullscreen = playOptions.fullscreen; getPlayerData(player).isChangingStream = false; return player.play(streamInfo).then(function () { @@ -2225,13 +2219,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return Promise.all([promise, player.getDeviceProfile(item)]).then(function (responses) { - var deviceProfile = responses[1]; + const deviceProfile = responses[1]; - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); - var mediaSourceId = playOptions.mediaSourceId; - var audioStreamIndex = playOptions.audioStreamIndex; - var subtitleStreamIndex = playOptions.subtitleStreamIndex; + const mediaSourceId = playOptions.mediaSourceId; + const audioStreamIndex = playOptions.audioStreamIndex; + const subtitleStreamIndex = playOptions.subtitleStreamIndex; if (player && !enableLocalPlaylistManagement(player)) { return sendPlaybackListToPlayer(player, playOptions.items, deviceProfile, maxBitrate, apiClient, startPosition, mediaSourceId, audioStreamIndex, subtitleStreamIndex, playOptions.startIndex); @@ -2241,7 +2235,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla playOptions.items = null; return getPlaybackMediaSource(player, apiClient, deviceProfile, maxBitrate, item, startPosition, mediaSourceId, audioStreamIndex, subtitleStreamIndex).then(function (mediaSource) { - var streamInfo = createStreamInfo(apiClient, item.MediaType, item, mediaSource, startPosition); + const streamInfo = createStreamInfo(apiClient, item.MediaType, item, mediaSource, startPosition); streamInfo.fullscreen = playOptions.fullscreen; @@ -2269,14 +2263,14 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla self.getPlaybackInfo = function (item, options) { options = options || {}; - var startPosition = options.startPositionTicks || 0; - var mediaType = options.mediaType || item.MediaType; - var player = getPlayer(item, options); - var apiClient = connectionManager.getApiClient(item.ServerId); + const startPosition = options.startPositionTicks || 0; + const mediaType = options.mediaType || item.MediaType; + const player = getPlayer(item, options); + const apiClient = connectionManager.getApiClient(item.ServerId); // Call this just to ensure the value is recorded, it is needed with getSavedMaxStreamingBitrate return apiClient.getEndpointInfo().then(function () { - var maxBitrate = getSavedMaxStreamingBitrate(connectionManager.getApiClient(item.ServerId), mediaType); + const maxBitrate = getSavedMaxStreamingBitrate(connectionManager.getApiClient(item.ServerId), mediaType); return player.getDeviceProfile(item).then(function (deviceProfile) { return getPlaybackMediaSource(player, apiClient, deviceProfile, maxBitrate, item, startPosition, options.mediaSourceId, options.audioStreamIndex, options.subtitleStreamIndex).then(function (mediaSource) { @@ -2288,15 +2282,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla self.getPlaybackMediaSources = function (item, options) { options = options || {}; - var startPosition = options.startPositionTicks || 0; - var mediaType = options.mediaType || item.MediaType; + const startPosition = options.startPositionTicks || 0; + const mediaType = options.mediaType || item.MediaType; // TODO: Remove the true forceLocalPlayer hack - var player = getPlayer(item, options, true); - var apiClient = connectionManager.getApiClient(item.ServerId); + const player = getPlayer(item, options, true); + const apiClient = connectionManager.getApiClient(item.ServerId); // Call this just to ensure the value is recorded, it is needed with getSavedMaxStreamingBitrate return apiClient.getEndpointInfo().then(function () { - var maxBitrate = getSavedMaxStreamingBitrate(connectionManager.getApiClient(item.ServerId), mediaType); + const maxBitrate = getSavedMaxStreamingBitrate(connectionManager.getApiClient(item.ServerId), mediaType); return player.getDeviceProfile(item).then(function (deviceProfile) { return getPlaybackInfo(player, apiClient, item, deviceProfile, maxBitrate, startPosition, false, null, null, null, null).then(function (playbackInfoResult) { @@ -2307,16 +2301,16 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }; function createStreamInfo(apiClient, type, item, mediaSource, startPosition) { - var mediaUrl; - var contentType; - var transcodingOffsetTicks = 0; - var playerStartPositionTicks = startPosition; - var liveStreamId = mediaSource.LiveStreamId; + let mediaUrl; + let contentType; + let transcodingOffsetTicks = 0; + const playerStartPositionTicks = startPosition; + const liveStreamId = mediaSource.LiveStreamId; - var playMethod = 'Transcode'; + let playMethod = 'Transcode'; - var mediaSourceContainer = (mediaSource.Container || '').toLowerCase(); - var directOptions; + const mediaSourceContainer = (mediaSource.Container || '').toLowerCase(); + let directOptions; if (type === 'Video' || type === 'Audio') { contentType = getMimeType(type.toLowerCase(), mediaSourceContainer); @@ -2345,7 +2339,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla directOptions.LiveStreamId = mediaSource.LiveStreamId; } - var prefix = type === 'Video' ? 'Videos' : 'Audio'; + const prefix = type === 'Video' ? 'Videos' : 'Audio'; mediaUrl = apiClient.getUrl(prefix + '/' + item.Id + '/stream.' + mediaSourceContainer, directOptions); playMethod = 'DirectStream'; @@ -2374,7 +2368,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla playMethod = 'DirectPlay'; } - var resultInfo = { + const resultInfo = { url: mediaUrl, mimeType: contentType, transcodingOffsetTicks: transcodingOffsetTicks, @@ -2391,7 +2385,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla title: item.Name }; - var backdropUrl = backdropImageUrl(apiClient, item, {}); + const backdropUrl = backdropImageUrl(apiClient, item, {}); if (backdropUrl) { resultInfo.backdropUrl = backdropUrl; } @@ -2400,19 +2394,19 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function getTextTracks(apiClient, item, mediaSource) { - var subtitleStreams = mediaSource.MediaStreams.filter(function (s) { + const subtitleStreams = mediaSource.MediaStreams.filter(function (s) { return s.Type === 'Subtitle'; }); - var textStreams = subtitleStreams.filter(function (s) { + const textStreams = subtitleStreams.filter(function (s) { return s.DeliveryMethod === 'External'; }); - var tracks = []; + const tracks = []; - for (var i = 0, length = textStreams.length; i < length; i++) { - var textStream = textStreams[i]; - var textStreamUrl; + for (let i = 0, length = textStreams.length; i < length; i++) { + const textStream = textStreams[i]; + let textStreamUrl; if (itemHelper.isLocalItem(item)) { textStreamUrl = textStream.Path; @@ -2459,7 +2453,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function getPlayer(item, playOptions, forceLocalPlayers) { - var serverItem = isServerItem(item); + const serverItem = isServerItem(item); return getAutomaticPlayers(self, forceLocalPlayers).filter(function (p) { if (p.canPlayMediaType(item.MediaType)) { if (serverItem) { @@ -2482,11 +2476,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.setCurrentPlaylistItem(playlistItemId); } - var newItem; - var newItemIndex; - var playlist = self._playQueueManager.getPlaylist(); + let newItem; + let newItemIndex; + const playlist = self._playQueueManager.getPlaylist(); - for (var i = 0, length = playlist.length; i < length; i++) { + for (let i = 0, length = playlist.length; i < length; i++) { if (playlist[i].PlaylistItemId === playlistItemId) { newItem = playlist[i]; newItemIndex = i; @@ -2495,7 +2489,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } if (newItem) { - var newItemPlayOptions = newItem.playOptions || getDefaultPlayOptions(); + const newItemPlayOptions = newItem.playOptions || getDefaultPlayOptions(); playInternal(newItem, newItemPlayOptions, function () { setPlaylistState(newItem.PlaylistItemId, newItemIndex); @@ -2513,18 +2507,19 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.removeFromPlaylist(playlistItemIds); } - var removeResult = self._playQueueManager.removeFromPlaylist(playlistItemIds); + const removeResult = self._playQueueManager.removeFromPlaylist(playlistItemIds); if (removeResult.result === 'empty') { return self.stop(player); } - var isCurrentIndex = removeResult.isCurrentIndex; + const isCurrentIndex = removeResult.isCurrentIndex; events.trigger(player, 'playlistitemremove', [ { playlistItemIds: playlistItemIds - }]); + } + ]); if (isCurrentIndex) { return self.setCurrentPlaylistItem(self._playQueueManager.getPlaylist()[0].PlaylistItemId, player); @@ -2539,7 +2534,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.movePlaylistItem(playlistItemId, newIndex); } - var moveResult = self._playQueueManager.movePlaylistItem(playlistItemId, newIndex); + const moveResult = self._playQueueManager.movePlaylistItem(playlistItemId, newIndex); if (moveResult.result === 'noop') { return; @@ -2549,7 +2544,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla { playlistItemId: moveResult.playlistItemId, newIndex: moveResult.newIndex - }]); + } + ]); }; self.getCurrentPlaylistIndex = function (player) { @@ -2586,12 +2582,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.nextTrack(); } - var newItemInfo = self._playQueueManager.getNextItemInfo(); + const newItemInfo = self._playQueueManager.getNextItemInfo(); if (newItemInfo) { console.debug('playing next track'); - var newItemPlayOptions = newItemInfo.item.playOptions || getDefaultPlayOptions(); + const newItemPlayOptions = newItemInfo.item.playOptions || getDefaultPlayOptions(); playInternal(newItemInfo.item, newItemPlayOptions, function () { setPlaylistState(newItemInfo.item.PlaylistItemId, newItemInfo.index); @@ -2605,13 +2601,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.previousTrack(); } - var newIndex = self.getCurrentPlaylistIndex(player) - 1; + const newIndex = self.getCurrentPlaylistIndex(player) - 1; if (newIndex >= 0) { - var playlist = self._playQueueManager.getPlaylist(); - var newItem = playlist[newIndex]; + const playlist = self._playQueueManager.getPlaylist(); + const newItem = playlist[newIndex]; if (newItem) { - var newItemPlayOptions = newItem.playOptions || getDefaultPlayOptions(); + const newItemPlayOptions = newItem.playOptions || getDefaultPlayOptions(); newItemPlayOptions.startPositionTicks = 0; playInternal(newItem, newItemPlayOptions, function () { @@ -2647,9 +2643,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return getItemsForPlayback(options.serverId, { - Ids: options.ids.join(',') - }).then(function (result) { return translateItemsForPlayback(result.Items, options).then(function (items) { // TODO: Handle options.startIndex for photos @@ -2677,10 +2671,10 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var queueDirectToPlayer = player && !enableLocalPlaylistManagement(player); + const queueDirectToPlayer = player && !enableLocalPlaylistManagement(player); if (queueDirectToPlayer) { - var apiClient = connectionManager.getApiClient(items[0].ServerId); + const apiClient = connectionManager.getApiClient(items[0].ServerId); player.getDeviceProfile(items[0]).then(function (profile) { setStreamUrls(items, profile, self.getMaxStreamingBitrate(player), apiClient, 0).then(function () { @@ -2704,7 +2698,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlayerProgressInterval() { - var player = this; + const player = this; sendProgressUpdate(player, 'timeupdate'); } @@ -2728,7 +2722,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla setCurrentPlayerInternal(player); - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); playerData.streamInfo = streamInfo; @@ -2743,10 +2737,10 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } self._playNextAfterEnded = true; - var isFirstItem = playOptions.isFirstItem; - var fullscreen = playOptions.fullscreen; + const isFirstItem = playOptions.isFirstItem; + const fullscreen = playOptions.fullscreen; - var state = self.getPlayerState(player, streamInfo.item, streamInfo.mediaSource); + const state = self.getPlayerState(player, streamInfo.item, streamInfo.mediaSource); reportPlayback(self, state, player, true, state.NowPlayingItem.ServerId, 'reportPlaybackStart'); @@ -2762,22 +2756,22 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlaybackStartedFromSelfManagingPlayer(e, item, mediaSource) { - var player = this; + const player = this; setCurrentPlayerInternal(player); - var playOptions = item.playOptions || getDefaultPlayOptions(); - var isFirstItem = playOptions.isFirstItem; - var fullscreen = playOptions.fullscreen; + const playOptions = item.playOptions || getDefaultPlayOptions(); + const isFirstItem = playOptions.isFirstItem; + const fullscreen = playOptions.fullscreen; playOptions.isFirstItem = false; - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); playerData.streamInfo = {}; - var streamInfo = playerData.streamInfo; + const streamInfo = playerData.streamInfo; streamInfo.playbackStartTimeTicks = new Date().getTime() * 10000; - var state = self.getPlayerState(player, item, mediaSource); + const state = self.getPlayerState(player, item, mediaSource); reportPlayback(self, state, player, true, state.NowPlayingItem.ServerId, 'reportPlaybackStart'); @@ -2793,15 +2787,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlaybackStoppedFromSelfManagingPlayer(e, playerStopInfo) { - var player = this; + const player = this; stopPlaybackProgressTimer(player); - var state = self.getPlayerState(player, playerStopInfo.item, playerStopInfo.mediaSource); + const state = self.getPlayerState(player, playerStopInfo.item, playerStopInfo.mediaSource); - var nextItem = playerStopInfo.nextItem; - var nextMediaType = playerStopInfo.nextMediaType; + const nextItem = playerStopInfo.nextItem; + const nextMediaType = playerStopInfo.nextMediaType; - var playbackStopInfo = { + const playbackStopInfo = { player: player, state: state, nextItem: (nextItem ? nextItem.item : null), @@ -2810,7 +2804,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla state.NextMediaType = nextMediaType; - var streamInfo = getPlayerData(player).streamInfo; + const streamInfo = getPlayerData(player).streamInfo; // only used internally as a safeguard to avoid reporting other events to the server after playback stopped streamInfo.ended = true; @@ -2826,8 +2820,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.trigger(player, 'playbackstop', [state]); events.trigger(self, 'playbackstop', [playbackStopInfo]); - var nextItemPlayOptions = nextItem ? (nextItem.item.playOptions || getDefaultPlayOptions()) : getDefaultPlayOptions(); - var newPlayer = nextItem ? getPlayer(nextItem.item, nextItemPlayOptions) : null; + const nextItemPlayOptions = nextItem ? (nextItem.item.playOptions || getDefaultPlayOptions()) : getDefaultPlayOptions(); + const newPlayer = nextItem ? getPlayer(nextItem.item, nextItemPlayOptions) : null; if (newPlayer !== player) { destroyPlayer(player); @@ -2837,7 +2831,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla function enablePlaybackRetryWithTranscoding(streamInfo, errorType, currentlyPreventsVideoStreamCopy, currentlyPreventsAudioStreamCopy) { // mediadecodeerror, medianotsupported, network, servererror - if (streamInfo.mediaSource.SupportsTranscoding && (!currentlyPreventsVideoStreamCopy || !currentlyPreventsAudioStreamCopy)) { return true; } @@ -2846,46 +2839,44 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlaybackError(e, error) { - var player = this; + const player = this; error = error || {}; // network // mediadecodeerror // medianotsupported - var errorType = error.type; + const errorType = error.type; console.debug('playbackmanager playback error type: ' + (errorType || '')); - var streamInfo = error.streamInfo || getPlayerData(player).streamInfo; + const streamInfo = error.streamInfo || getPlayerData(player).streamInfo; if (streamInfo) { - var currentlyPreventsVideoStreamCopy = streamInfo.url.toLowerCase().indexOf('allowvideostreamcopy=false') !== -1; - var currentlyPreventsAudioStreamCopy = streamInfo.url.toLowerCase().indexOf('allowaudiostreamcopy=false') !== -1; + const currentlyPreventsVideoStreamCopy = streamInfo.url.toLowerCase().indexOf('allowvideostreamcopy=false') !== -1; + const currentlyPreventsAudioStreamCopy = streamInfo.url.toLowerCase().indexOf('allowaudiostreamcopy=false') !== -1; // Auto switch to transcoding if (enablePlaybackRetryWithTranscoding(streamInfo, errorType, currentlyPreventsVideoStreamCopy, currentlyPreventsAudioStreamCopy)) { - var startTime = getCurrentTicks(player) || streamInfo.playerStartPositionTicks; + const startTime = getCurrentTicks(player) || streamInfo.playerStartPositionTicks; changeStream(player, startTime, { - // force transcoding EnableDirectPlay: false, EnableDirectStream: false, AllowVideoStreamCopy: false, AllowAudioStreamCopy: currentlyPreventsAudioStreamCopy || currentlyPreventsVideoStreamCopy ? false : null - }); return; } } - var displayErrorCode = 'NoCompatibleStream'; + const displayErrorCode = 'NoCompatibleStream'; onPlaybackStopped.call(player, e, displayErrorCode); } function onPlaybackStopped(e, displayErrorCode) { - var player = this; + const player = this; if (getPlayerData(player).isChangingStream) { return; @@ -2894,15 +2885,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla stopPlaybackProgressTimer(player); // User clicked stop or content ended - var state = self.getPlayerState(player); - var data = getPlayerData(player); - var streamInfo = data.streamInfo; + const state = self.getPlayerState(player); + const data = getPlayerData(player); + const streamInfo = data.streamInfo; - var nextItem = self._playNextAfterEnded ? self._playQueueManager.getNextItemInfo() : null; + const nextItem = self._playNextAfterEnded ? self._playQueueManager.getNextItemInfo() : null; - var nextMediaType = (nextItem ? nextItem.item.MediaType : null); + const nextMediaType = (nextItem ? nextItem.item.MediaType : null); - var playbackStopInfo = { + const playbackStopInfo = { player: player, state: state, nextItem: (nextItem ? nextItem.item : null), @@ -2931,8 +2922,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.trigger(player, 'playbackstop', [state]); events.trigger(self, 'playbackstop', [playbackStopInfo]); - var nextItemPlayOptions = nextItem ? (nextItem.item.playOptions || getDefaultPlayOptions()) : getDefaultPlayOptions(); - var newPlayer = nextItem ? getPlayer(nextItem.item, nextItemPlayOptions) : null; + const nextItemPlayOptions = nextItem ? (nextItem.item.playOptions || getDefaultPlayOptions()) : getDefaultPlayOptions(); + const newPlayer = nextItem ? getPlayer(nextItem.item, nextItemPlayOptions) : null; if (newPlayer !== player) { destroyPlayer(player); @@ -2950,12 +2941,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlaybackChanging(activePlayer, newPlayer, newItem) { - var state = self.getPlayerState(activePlayer); + const state = self.getPlayerState(activePlayer); - var serverId = self.currentItem(activePlayer).ServerId; + const serverId = self.currentItem(activePlayer).ServerId; // User started playing something new while existing content is playing - var promise; + let promise; stopPlaybackProgressTimer(activePlayer); unbindStopped(activePlayer); @@ -2992,47 +2983,47 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlaybackTimeUpdate(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'timeupdate'); } function onPlaybackPause(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'pause'); } function onPlaybackUnpause(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'unpause'); } function onPlaybackVolumeChange(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'volumechange'); } function onRepeatModeChange(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'repeatmodechange'); } function onShuffleQueueModeChange() { - var player = this; + const player = this; sendProgressUpdate(player, 'shufflequeuemodechange'); } function onPlaylistItemMove(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'playlistitemmove', true); } function onPlaylistItemRemove(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'playlistitemremove', true); } function onPlaylistItemAdd(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'playlistitemadd', true); } @@ -3109,12 +3100,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla throw new Error('player cannot be null'); } - var state = self.getPlayerState(player); + const state = self.getPlayerState(player); if (state.NowPlayingItem) { - var serverId = state.NowPlayingItem.ServerId; + const serverId = state.NowPlayingItem.ServerId; - var streamInfo = getPlayerData(player).streamInfo; + const streamInfo = getPlayerData(player).streamInfo; if (streamInfo && streamInfo.started && !streamInfo.ended) { reportPlayback(self, state, player, reportPlaylist, serverId, 'reportPlaybackProgress', progressEventName); @@ -3133,7 +3124,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla streamInfo.lastMediaInfoQuery = new Date().getTime(); - var apiClient = connectionManager.getApiClient(serverId); + const apiClient = connectionManager.getApiClient(serverId); if (!apiClient.isMinServerVersion('3.2.70.7')) { return; @@ -3143,12 +3134,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla mediaSource.MediaStreams = info.MediaStreams; events.trigger(player, 'mediastreamschange'); }, function () { - }); } self.onAppClose = function () { - var player = this._currentPlayer; + const player = this._currentPlayer; // Try to report playback stopped before the app closes if (player && this.isPlaying(player)) { @@ -3163,64 +3153,64 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.playbackStartTime(); } - var streamInfo = getPlayerData(player).streamInfo; + const streamInfo = getPlayerData(player).streamInfo; return streamInfo ? streamInfo.playbackStartTimeTicks : null; }; if (apphost.supports('remotecontrol')) { - require(['serverNotifications'], function (serverNotifications) { + import('serverNotifications').then(({ default: serverNotifications }) => { events.on(serverNotifications, 'ServerShuttingDown', self.setDefaultPlayerActive.bind(self)); events.on(serverNotifications, 'ServerRestarting', self.setDefaultPlayerActive.bind(self)); }); } } - PlaybackManager.prototype.getCurrentPlayer = function () { + getCurrentPlayer() { return this._currentPlayer; - }; + } - PlaybackManager.prototype.currentTime = function (player) { + currentTime(player) { player = player || this._currentPlayer; if (player && !enableLocalPlaylistManagement(player) && !player.isLocalPlayer) { return player.currentTime(); } return this.getCurrentTicks(player); - }; + } - PlaybackManager.prototype.nextItem = function (player) { + nextItem(player) { player = player || this._currentPlayer; if (player && !enableLocalPlaylistManagement(player)) { return player.nextItem(); } - var nextItem = this._playQueueManager.getNextItemInfo(); + const nextItem = this._playQueueManager.getNextItemInfo(); if (!nextItem || !nextItem.item) { return Promise.reject(); } - var apiClient = connectionManager.getApiClient(nextItem.item.ServerId); + const apiClient = connectionManager.getApiClient(nextItem.item.ServerId); return apiClient.getItem(apiClient.getCurrentUserId(), nextItem.item.Id); - }; + } - PlaybackManager.prototype.canQueue = function (item) { + canQueue(item) { if (item.Type === 'MusicAlbum' || item.Type === 'MusicArtist' || item.Type === 'MusicGenre') { return this.canQueueMediaType('Audio'); } return this.canQueueMediaType(item.MediaType); - }; + } - PlaybackManager.prototype.canQueueMediaType = function (mediaType) { + canQueueMediaType(mediaType) { if (this._currentPlayer) { return this._currentPlayer.canPlayMediaType(mediaType); } return false; - }; + } - PlaybackManager.prototype.isMuted = function (player) { + isMuted(player) { player = player || this._currentPlayer; if (player) { @@ -3228,17 +3218,17 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return false; - }; + } - PlaybackManager.prototype.setMute = function (mute, player) { + setMute(mute, player) { player = player || this._currentPlayer; if (player) { player.setMute(mute); } - }; + } - PlaybackManager.prototype.toggleMute = function (mute, player) { + toggleMute(mute, player) { player = player || this._currentPlayer; if (player) { if (player.toggleMute) { @@ -3247,29 +3237,29 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla player.setMute(!player.isMuted()); } } - }; + } - PlaybackManager.prototype.toggleDisplayMirroring = function () { + toggleDisplayMirroring() { this.enableDisplayMirroring(!this.enableDisplayMirroring()); - }; + } - PlaybackManager.prototype.enableDisplayMirroring = function (enabled) { + enableDisplayMirroring(enabled) { if (enabled != null) { - var val = enabled ? '1' : '0'; + const val = enabled ? '1' : '0'; appSettings.set('displaymirror', val); return; } return (appSettings.get('displaymirror') || '') !== '0'; - }; + } - PlaybackManager.prototype.nextChapter = function (player) { + nextChapter(player) { player = player || this._currentPlayer; - var item = this.currentItem(player); + const item = this.currentItem(player); - var ticks = this.getCurrentTicks(player); + const ticks = this.getCurrentTicks(player); - var nextChapter = (item.Chapters || []).filter(function (i) { + const nextChapter = (item.Chapters || []).filter(function (i) { return i.StartPositionTicks > ticks; })[0]; @@ -3278,13 +3268,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } else { this.nextTrack(player); } - }; + } - PlaybackManager.prototype.previousChapter = function (player) { + previousChapter(player) { player = player || this._currentPlayer; - var item = this.currentItem(player); + const item = this.currentItem(player); - var ticks = this.getCurrentTicks(player); + let ticks = this.getCurrentTicks(player); // Go back 10 seconds ticks -= 100000000; @@ -3294,7 +3284,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla ticks = Math.max(ticks, 0); } - var previousChapters = (item.Chapters || []).filter(function (i) { + const previousChapters = (item.Chapters || []).filter(function (i) { return i.StartPositionTicks <= ticks; }); @@ -3303,9 +3293,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } else { this.previousTrack(player); } - }; + } - PlaybackManager.prototype.fastForward = function (player) { + fastForward(player) { player = player || this._currentPlayer; if (player.fastForward != null) { @@ -3314,12 +3304,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } // Go back 15 seconds - var offsetTicks = userSettings.skipForwardLength() * 10000; + const offsetTicks = userSettings.skipForwardLength() * 10000; this.seekRelative(offsetTicks, player); - }; + } - PlaybackManager.prototype.rewind = function (player) { + rewind(player) { player = player || this._currentPlayer; if (player.rewind != null) { @@ -3328,38 +3318,38 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } // Go back 15 seconds - var offsetTicks = 0 - (userSettings.skipBackLength() * 10000); + const offsetTicks = 0 - (userSettings.skipBackLength() * 10000); this.seekRelative(offsetTicks, player); - }; + } - PlaybackManager.prototype.seekPercent = function (percent, player) { + seekPercent(percent, player) { player = player || this._currentPlayer; - var ticks = this.duration(player) || 0; + let ticks = this.duration(player) || 0; percent /= 100; ticks *= percent; this.seek(parseInt(ticks), player); - }; + } - PlaybackManager.prototype.seekMs = function (ms, player) { + seekMs(ms, player) { player = player || this._currentPlayer; - var ticks = ms * 10000; + const ticks = ms * 10000; this.seek(ticks, player); - }; + } - PlaybackManager.prototype.playTrailers = function (item) { - var player = this._currentPlayer; + playTrailers(item) { + const player = this._currentPlayer; if (player && player.playTrailers) { return player.playTrailers(item); } - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); - var instance = this; + const instance = this; if (item.LocalTrailerCount) { return apiClient.getLocalTrailers(apiClient.getCurrentUserId(), item.Id).then(function (result) { @@ -3368,7 +3358,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }); }); } else { - var remoteTrailers = item.RemoteTrailers || []; + const remoteTrailers = item.RemoteTrailers || []; if (!remoteTrailers.length) { return Promise.reject(); @@ -3386,15 +3376,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }) }); } - }; + } - PlaybackManager.prototype.getSubtitleUrl = function (textStream, serverId) { - var apiClient = connectionManager.getApiClient(serverId); + getSubtitleUrl(textStream, serverId) { + const apiClient = connectionManager.getApiClient(serverId); return !textStream.IsExternalUrl ? apiClient.getUrl(textStream.DeliveryUrl) : textStream.DeliveryUrl; - }; + } - PlaybackManager.prototype.stop = function (player) { + stop(player) { player = player || this._currentPlayer; if (player) { @@ -3407,9 +3397,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return Promise.resolve(); - }; + } - PlaybackManager.prototype.getBufferedRanges = function (player) { + getBufferedRanges(player) { player = player || this._currentPlayer; if (player) { @@ -3419,9 +3409,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return []; - }; + } - PlaybackManager.prototype.playPause = function (player) { + playPause(player) { player = player || this._currentPlayer; if (player) { @@ -3435,115 +3425,115 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return this.pause(player); } } - }; + } - PlaybackManager.prototype.paused = function (player) { + paused(player) { player = player || this._currentPlayer; if (player) { return player.paused(); } - }; + } - PlaybackManager.prototype.pause = function (player) { + pause(player) { player = player || this._currentPlayer; if (player) { player.pause(); } - }; + } - PlaybackManager.prototype.unpause = function (player) { + unpause(player) { player = player || this._currentPlayer; if (player) { player.unpause(); } - }; + } - PlaybackManager.prototype.setPlaybackRate = function (value, player = this._currentPlayer) { + setPlaybackRate(value, player = this._currentPlayer) { if (player && player.setPlaybackRate) { player.setPlaybackRate(value); } - }; + } - PlaybackManager.prototype.getPlaybackRate = function (player = this._currentPlayer) { + getPlaybackRate(player = this._currentPlayer) { if (player && player.getPlaybackRate) { return player.getPlaybackRate(); } return null; - }; + } - PlaybackManager.prototype.instantMix = function (item, player) { + instantMix(item, player) { player = player || this._currentPlayer; if (player && player.instantMix) { return player.instantMix(item); } - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); - var options = {}; + const options = {}; options.UserId = apiClient.getCurrentUserId(); options.Limit = 200; - var instance = this; + const instance = this; apiClient.getInstantMixFromItem(item.Id, options).then(function (result) { instance.play({ items: result.Items }); }); - }; + } - PlaybackManager.prototype.shuffle = function (shuffleItem, player) { + shuffle(shuffleItem, player) { player = player || this._currentPlayer; if (player && player.shuffle) { return player.shuffle(shuffleItem); } return this.play({ items: [shuffleItem], shuffle: true }); - }; + } - PlaybackManager.prototype.audioTracks = function (player) { + audioTracks(player) { player = player || this._currentPlayer; if (player.audioTracks) { - var result = player.audioTracks(); + const result = player.audioTracks(); if (result) { return result; } } - var mediaSource = this.currentMediaSource(player); + const mediaSource = this.currentMediaSource(player); - var mediaStreams = (mediaSource || {}).MediaStreams || []; + const mediaStreams = (mediaSource || {}).MediaStreams || []; return mediaStreams.filter(function (s) { return s.Type === 'Audio'; }); - }; + } - PlaybackManager.prototype.subtitleTracks = function (player) { + subtitleTracks(player) { player = player || this._currentPlayer; if (player.subtitleTracks) { - var result = player.subtitleTracks(); + const result = player.subtitleTracks(); if (result) { return result; } } - var mediaSource = this.currentMediaSource(player); + const mediaSource = this.currentMediaSource(player); - var mediaStreams = (mediaSource || {}).MediaStreams || []; + const mediaStreams = (mediaSource || {}).MediaStreams || []; return mediaStreams.filter(function (s) { return s.Type === 'Subtitle'; }); - }; + } - PlaybackManager.prototype.getSupportedCommands = function (player) { + getSupportedCommands(player) { player = player || this._currentPlayer || { isLocalPlayer: true }; if (player.isLocalPlayer) { - var list = [ + const list = [ 'GoHome', 'GoToSettings', 'VolumeUp', @@ -3589,45 +3579,45 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return list; } - var info = this.getPlayerInfo(); + const info = this.getPlayerInfo(); return info ? info.supportedCommands : []; - }; + } - PlaybackManager.prototype.setRepeatMode = function (value, player = this._currentPlayer) { + setRepeatMode(value, player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.setRepeatMode(value); } this._playQueueManager.setRepeatMode(value); events.trigger(player, 'repeatmodechange'); - }; + } - PlaybackManager.prototype.getRepeatMode = function (player = this._currentPlayer) { + getRepeatMode(player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.getRepeatMode(); } return this._playQueueManager.getRepeatMode(); - }; + } - PlaybackManager.prototype.setQueueShuffleMode = function (value, player = this._currentPlayer) { + setQueueShuffleMode(value, player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.setQueueShuffleMode(value); } this._playQueueManager.setShuffleMode(value); events.trigger(player, 'shufflequeuemodechange'); - }; + } - PlaybackManager.prototype.getQueueShuffleMode = function (player = this._currentPlayer) { + getQueueShuffleMode(player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.getQueueShuffleMode(); } return this._playQueueManager.getShuffleMode(); - }; + } - PlaybackManager.prototype.toggleQueueShuffleMode = function (player = this._currentPlayer) { + toggleQueueShuffleMode(player = this._currentPlayer) { let currentvalue; if (player && !enableLocalPlaylistManagement(player)) { currentvalue = player.getQueueShuffleMode(); @@ -3645,23 +3635,23 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla this._playQueueManager.toggleShuffleMode(); } events.trigger(player, 'shufflequeuemodechange'); - }; + } - PlaybackManager.prototype.clearQueue = function (clearCurrentItem = false, player = this._currentPlayer) { + clearQueue(clearCurrentItem = false, player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.clearQueue(clearCurrentItem); } this._playQueueManager.clearPlaylist(clearCurrentItem); events.trigger(player, 'playlistitemremove'); - }; + } - PlaybackManager.prototype.trySetActiveDeviceName = function (name) { + trySetActiveDeviceName(name) { name = normalizeName(name); - var instance = this; + const instance = this; instance.getTargets().then(function (result) { - var target = result.filter(function (p) { + const target = result.filter(function (p) { return normalizeName(p.name) === name; })[0]; @@ -3669,50 +3659,50 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla instance.trySetActivePlayer(target.playerName, target); } }); - }; + } - PlaybackManager.prototype.displayContent = function (options, player) { + displayContent(options, player) { player = player || this._currentPlayer; if (player && player.displayContent) { player.displayContent(options); } - }; + } - PlaybackManager.prototype.beginPlayerUpdates = function (player) { + beginPlayerUpdates(player) { if (player.beginPlayerUpdates) { player.beginPlayerUpdates(); } - }; + } - PlaybackManager.prototype.endPlayerUpdates = function (player) { + endPlayerUpdates(player) { if (player.endPlayerUpdates) { player.endPlayerUpdates(); } - }; + } - PlaybackManager.prototype.setDefaultPlayerActive = function () { + setDefaultPlayerActive() { this.setActivePlayer('localplayer'); - }; + } - PlaybackManager.prototype.removeActivePlayer = function (name) { - var playerInfo = this.getPlayerInfo(); + removeActivePlayer(name) { + const playerInfo = this.getPlayerInfo(); if (playerInfo) { if (playerInfo.name === name) { this.setDefaultPlayerActive(); } } - }; + } - PlaybackManager.prototype.removeActiveTarget = function (id) { - var playerInfo = this.getPlayerInfo(); + removeActiveTarget(id) { + const playerInfo = this.getPlayerInfo(); if (playerInfo) { if (playerInfo.id === id) { this.setDefaultPlayerActive(); } } - }; + } - PlaybackManager.prototype.sendCommand = function (cmd, player) { + sendCommand(cmd, player) { console.debug('MediaController received command: ' + cmd.Name); switch (cmd.Name) { case 'SetRepeatMode': @@ -3763,7 +3753,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } break; } - }; + } +} - return new PlaybackManager(); -}); +export default new PlaybackManager(); From 49c1b3e159042695b2befc8cc8aa7d5ea8ba88f2 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 09:12:44 +0100 Subject: [PATCH 029/155] Addition of defaults --- src/components/guide/guide.js | 2 ++ src/components/itemsrefresher.js | 2 ++ src/components/notifications/notifications.js | 2 ++ src/components/recordingcreator/recordingcreator.js | 2 +- src/components/remotecontrol/remotecontrol.js | 3 +++ src/components/subtitlesync/subtitlesync.js | 2 ++ src/components/themeMediaPlayer.js | 2 ++ src/components/upnextdialog/upnextdialog.js | 2 ++ src/controllers/itemDetails/index.js | 2 ++ src/controllers/list.js | 2 ++ src/controllers/movies/moviesrecommended.js | 2 ++ src/plugins/chromecastPlayer/plugin.js | 2 ++ src/plugins/sessionPlayer/plugin.js | 2 ++ src/scripts/libraryMenu.js | 2 ++ src/scripts/serverNotifications.js | 2 ++ 15 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index bd3ad89aaa..6601a0508d 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -1,6 +1,8 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'webcomponents'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function showViewSettings(instance) { require(['guide-settings-dialog'], function (guideSettingsDialog) { guideSettingsDialog.show(instance.categoryOptions).then(function () { diff --git a/src/components/itemsrefresher.js b/src/components/itemsrefresher.js index a210af31af..74b08db07f 100644 --- a/src/components/itemsrefresher.js +++ b/src/components/itemsrefresher.js @@ -1,6 +1,8 @@ define(['playbackManager', 'serverNotifications', 'events'], function (playbackManager, serverNotifications, events) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function onUserDataChanged(e, apiClient, userData) { var instance = this; diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index b4647bbf25..0bf270f2a1 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -1,6 +1,8 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'require'], function (serverNotifications, playbackManager, events, globalize, require) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function onOneDocumentClick() { document.removeEventListener('click', onOneDocumentClick); document.removeEventListener('keydown', onOneDocumentClick); diff --git a/src/components/recordingcreator/recordingcreator.js b/src/components/recordingcreator/recordingcreator.js index f330e54156..ca5c475829 100644 --- a/src/components/recordingcreator/recordingcreator.js +++ b/src/components/recordingcreator/recordingcreator.js @@ -104,7 +104,7 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c var apiClient = connectionManager.getApiClient(serverId); apiClient.getLiveTvProgram(programId, apiClient.getCurrentUserId()).then(function (item) { - playbackManager.play({ + playbackManager.default.play({ ids: [item.ChannelId], serverId: serverId }); diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 29e77debd1..b5ac4c9a8b 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -1,5 +1,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageLoader', 'playbackManager', 'nowPlayingHelper', 'events', 'connectionManager', 'apphost', 'globalize', 'layoutManager', 'userSettings', 'cardBuilder', 'itemContextMenu', 'cardStyle', 'emby-itemscontainer', 'css!./remotecontrol.css', 'emby-ratingbutton'], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize, layoutManager, userSettings, cardBuilder, itemContextMenu) { 'use strict'; + + playbackManager = playbackManager.default || playbackManager; + var showMuteButton = true; var showVolumeSlider = true; diff --git a/src/components/subtitlesync/subtitlesync.js b/src/components/subtitlesync/subtitlesync.js index e825e8e0a2..203d88535f 100644 --- a/src/components/subtitlesync/subtitlesync.js +++ b/src/components/subtitlesync/subtitlesync.js @@ -1,6 +1,8 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html', 'css!./subtitlesync'], function (playbackManager, layoutManager, template, css) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + var player; var subtitleSyncSlider; var subtitleSyncTextField; diff --git a/src/components/themeMediaPlayer.js b/src/components/themeMediaPlayer.js index dd04f384aa..60f0986884 100644 --- a/src/components/themeMediaPlayer.js +++ b/src/components/themeMediaPlayer.js @@ -1,6 +1,8 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playbackManager, userSettings, connectionManager) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + var currentOwnerId; var currentThemeIds = []; diff --git a/src/components/upnextdialog/upnextdialog.js b/src/components/upnextdialog/upnextdialog.js index 1dbe71c632..5eb2a2ffcc 100644 --- a/src/components/upnextdialog/upnextdialog.js +++ b/src/components/upnextdialog/upnextdialog.js @@ -1,6 +1,8 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'layoutManager', 'focusManager', 'globalize', 'itemHelper', 'css!./upnextdialog', 'emby-button', 'flexStyles'], function (dom, playbackManager, connectionManager, events, mediaInfo, layoutManager, focusManager, globalize, itemHelper) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + var transitionEndEventName = dom.whichTransitionEvent(); function seriesImageUrl(item, options) { diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index df2855d69a..3fe24b5594 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -29,6 +29,8 @@ import 'emby-select'; /* eslint-disable indent */ + playbackManager = playbackManager.default || playbackManager; + function getPromise(apiClient, params) { const id = params.id; diff --git a/src/controllers/list.js b/src/controllers/list.js index 01ef35a26a..025a56ca9a 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -1,6 +1,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager', 'cardBuilder', 'loading', 'connectionManager', 'alphaNumericShortcuts', 'scroller', 'playbackManager', 'alphaPicker', 'emby-itemscontainer', 'emby-scroller'], function (globalize, listView, layoutManager, userSettings, focusManager, cardBuilder, loading, connectionManager, AlphaNumericShortcuts, scroller, playbackManager, AlphaPicker) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function getInitialLiveTvQuery(instance, params) { var query = { UserId: connectionManager.getApiClient(params.serverId).getCurrentUserId(), diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js index 4ffe7888cf..a633d654cd 100644 --- a/src/controllers/movies/moviesrecommended.js +++ b/src/controllers/movies/moviesrecommended.js @@ -1,6 +1,8 @@ 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'; + playbackManager = playbackManager.default || playbackManager; + function enableScrollX() { return !layoutManager.desktop; } diff --git a/src/plugins/chromecastPlayer/plugin.js b/src/plugins/chromecastPlayer/plugin.js index f4acc6d8b3..e39e30d8cf 100644 --- a/src/plugins/chromecastPlayer/plugin.js +++ b/src/plugins/chromecastPlayer/plugin.js @@ -1,6 +1,8 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', 'globalize', 'events', 'require', 'castSenderApiLoader'], function (appSettings, userSettings, playbackManager, connectionManager, globalize, events, require, castSenderApiLoader) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + // Based on https://github.com/googlecast/CastVideos-chrome/blob/master/CastVideos.js var currentResolve; var currentReject; diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index 89a18a96cc..fb1f745df3 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -1,6 +1,8 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'], function (playbackManager, events, serverNotifications, connectionManager) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function getActivePlayerId() { var info = playbackManager.getPlayerInfo(); return info ? info.id : null; diff --git a/src/scripts/libraryMenu.js b/src/scripts/libraryMenu.js index d2a68cd6e3..5c0ab467ff 100644 --- a/src/scripts/libraryMenu.js +++ b/src/scripts/libraryMenu.js @@ -1,6 +1,8 @@ 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'; + playbackManager = playbackManager.default || playbackManager; + function renderHeader() { var html = ''; html += '
'; diff --git a/src/scripts/serverNotifications.js b/src/scripts/serverNotifications.js index 331a75329c..e5fb0bcd61 100644 --- a/src/scripts/serverNotifications.js +++ b/src/scripts/serverNotifications.js @@ -1,6 +1,8 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'inputManager', 'focusManager', 'appRouter'], function (connectionManager, playbackManager, syncPlayManager, events, inputManager, focusManager, appRouter) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + var serverNotifications = {}; function notifyApp() { From 7ffb7ab0fc07ea8e80d381a971541f0b1c5b1e04 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 10:36:08 +0100 Subject: [PATCH 030/155] fix lint and bug --- src/components/playback/playbackmanager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 99a21dd3e2..dbab7e0f8f 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -1988,7 +1988,7 @@ class PlaybackManager { throw new Error('player cannot be null'); } - let playerTime = Math.floor(10000 * (player || self._currentPlayer).currentTime()); + let playerTime = Math.floor(10000 * (player).currentTime()); const streamInfo = getPlayerData(player).streamInfo; if (streamInfo) { From 91cd1a75d7970316e793bccb5daf470c1297d5eb Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 1 Aug 2020 21:03:27 +0100 Subject: [PATCH 031/155] Apply Suggestions --- src/components/playback/playbackmanager.js | 81 ++++++---------------- src/libraries/screensavermanager.js | 2 + 2 files changed, 25 insertions(+), 58 deletions(-) diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index dbab7e0f8f..1c181c0025 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3147,8 +3147,7 @@ class PlaybackManager { } }; - self.playbackStartTime = function (player) { - player = player || this._currentPlayer; + self.playbackStartTime = function (player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player) && !player.isLocalPlayer) { return player.playbackStartTime(); } @@ -3169,8 +3168,7 @@ class PlaybackManager { return this._currentPlayer; } - currentTime(player) { - player = player || this._currentPlayer; + currentTime(player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player) && !player.isLocalPlayer) { return player.currentTime(); } @@ -3178,9 +3176,7 @@ class PlaybackManager { return this.getCurrentTicks(player); } - nextItem(player) { - player = player || this._currentPlayer; - + nextItem(player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.nextItem(); } @@ -3210,9 +3206,7 @@ class PlaybackManager { return false; } - isMuted(player) { - player = player || this._currentPlayer; - + isMuted(player = this._currentPlayer) { if (player) { return player.isMuted(); } @@ -3220,16 +3214,13 @@ class PlaybackManager { return false; } - setMute(mute, player) { - player = player || this._currentPlayer; - + setMute(mute, player = this._currentPlayer) { if (player) { player.setMute(mute); } } - toggleMute(mute, player) { - player = player || this._currentPlayer; + toggleMute(mute, player = this._currentPlayer) { if (player) { if (player.toggleMute) { player.toggleMute(); @@ -3253,8 +3244,7 @@ class PlaybackManager { return (appSettings.get('displaymirror') || '') !== '0'; } - nextChapter(player) { - player = player || this._currentPlayer; + nextChapter(player = this._currentPlayer) { const item = this.currentItem(player); const ticks = this.getCurrentTicks(player); @@ -3270,8 +3260,7 @@ class PlaybackManager { } } - previousChapter(player) { - player = player || this._currentPlayer; + previousChapter(player = this._currentPlayer) { const item = this.currentItem(player); let ticks = this.getCurrentTicks(player); @@ -3295,9 +3284,7 @@ class PlaybackManager { } } - fastForward(player) { - player = player || this._currentPlayer; - + fastForward(player = this._currentPlayer) { if (player.fastForward != null) { player.fastForward(userSettings.skipForwardLength()); return; @@ -3309,9 +3296,7 @@ class PlaybackManager { this.seekRelative(offsetTicks, player); } - rewind(player) { - player = player || this._currentPlayer; - + rewind(player = this._currentPlayer) { if (player.rewind != null) { player.rewind(userSettings.skipBackLength()); return; @@ -3323,9 +3308,7 @@ class PlaybackManager { this.seekRelative(offsetTicks, player); } - seekPercent(percent, player) { - player = player || this._currentPlayer; - + seekPercent(percent, player = this._currentPlayer) { let ticks = this.duration(player) || 0; percent /= 100; @@ -3333,9 +3316,7 @@ class PlaybackManager { this.seek(parseInt(ticks), player); } - seekMs(ms, player) { - player = player || this._currentPlayer; - + seekMs(ms, player = this._currentPlayer) { const ticks = ms * 10000; this.seek(ticks, player); } @@ -3384,9 +3365,8 @@ class PlaybackManager { return !textStream.IsExternalUrl ? apiClient.getUrl(textStream.DeliveryUrl) : textStream.DeliveryUrl; } - stop(player) { + stop(player ) { player = player || this._currentPlayer; - if (player) { if (enableLocalPlaylistManagement(player)) { this._playNextAfterEnded = false; @@ -3399,9 +3379,7 @@ class PlaybackManager { return Promise.resolve(); } - getBufferedRanges(player) { - player = player || this._currentPlayer; - + getBufferedRanges(player = this._currentPlayer) { if (player) { if (player.getBufferedRanges) { return player.getBufferedRanges(); @@ -3411,9 +3389,7 @@ class PlaybackManager { return []; } - playPause(player) { - player = player || this._currentPlayer; - + playPause(player = this._currentPlayer) { if (player) { if (player.playPause) { return player.playPause(); @@ -3427,25 +3403,19 @@ class PlaybackManager { } } - paused(player) { - player = player || this._currentPlayer; - + paused(player = this._currentPlayer) { if (player) { return player.paused(); } } - pause(player) { - player = player || this._currentPlayer; - + pause(player = this._currentPlayer) { if (player) { player.pause(); } } - unpause(player) { - player = player || this._currentPlayer; - + unpause(player = this._currentPlayer) { if (player) { player.unpause(); } @@ -3465,8 +3435,7 @@ class PlaybackManager { return null; } - instantMix(item, player) { - player = player || this._currentPlayer; + instantMix(item, player = this._currentPlayer) { if (player && player.instantMix) { return player.instantMix(item); } @@ -3486,8 +3455,7 @@ class PlaybackManager { }); } - shuffle(shuffleItem, player) { - player = player || this._currentPlayer; + shuffle(shuffleItem, player = this._currentPlayer) { if (player && player.shuffle) { return player.shuffle(shuffleItem); } @@ -3495,8 +3463,7 @@ class PlaybackManager { return this.play({ items: [shuffleItem], shuffle: true }); } - audioTracks(player) { - player = player || this._currentPlayer; + audioTracks(player = this._currentPlayer) { if (player.audioTracks) { const result = player.audioTracks(); if (result) { @@ -3512,8 +3479,7 @@ class PlaybackManager { }); } - subtitleTracks(player) { - player = player || this._currentPlayer; + subtitleTracks(player = this._currentPlayer) { if (player.subtitleTracks) { const result = player.subtitleTracks(); if (result) { @@ -3661,8 +3627,7 @@ class PlaybackManager { }); } - displayContent(options, player) { - player = player || this._currentPlayer; + displayContent(options, player = this._currentPlayer) { if (player && player.displayContent) { player.displayContent(options); } diff --git a/src/libraries/screensavermanager.js b/src/libraries/screensavermanager.js index b9d7082850..557b31e0f4 100644 --- a/src/libraries/screensavermanager.js +++ b/src/libraries/screensavermanager.js @@ -1,6 +1,8 @@ define(["events", "playbackManager", "pluginManager", "inputManager", "connectionManager", "userSettings"], function (events, playbackManager, pluginManager, inputManager, connectionManager, userSettings) { "use strict"; + 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 From 042cb4119bd22fbe8679592d110041597bd7a196 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 2 Aug 2020 09:22:03 +0100 Subject: [PATCH 032/155] lint --- src/components/imageeditor/imageeditor.js | 2 -- src/components/playback/playbackmanager.js | 2 +- src/controllers/livetvsettings.js | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index 166ebb2245..46e2dae999 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -19,8 +19,6 @@ import 'css!./imageeditor'; const enableFocusTransform = !browser.slow && !browser.edge; - loading = loading.default || loading; - let currentItem; let hasChanges = false; diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 1c181c0025..ffbb88522c 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3365,7 +3365,7 @@ class PlaybackManager { return !textStream.IsExternalUrl ? apiClient.getUrl(textStream.DeliveryUrl) : textStream.DeliveryUrl; } - stop(player ) { + stop(player) { player = player || this._currentPlayer; if (player) { if (enableLocalPlaylistManagement(player)) { diff --git a/src/controllers/livetvsettings.js b/src/controllers/livetvsettings.js index 8c296cdd3c..29ec4a10a5 100644 --- a/src/controllers/livetvsettings.js +++ b/src/controllers/livetvsettings.js @@ -3,8 +3,6 @@ import loading from 'loading'; import globalize from 'globalize'; import 'emby-button'; -loading = loading.default || loading; - function loadPage(page, config) { $('.liveTvSettingsForm', page).show(); $('.noLiveTvServices', page).hide(); From 9067047403eddf24a24b0f8b81111464359b6bc9 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 2 Aug 2020 09:27:03 +0100 Subject: [PATCH 033/155] Update src/components/playback/playbackmanager.js Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com> --- src/components/playback/playbackmanager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index ffbb88522c..437127be18 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -620,7 +620,7 @@ function supportsDirectPlay(apiClient, item, mediaSource) { } else if (mediaSource.Protocol === 'File') { return new Promise(function (resolve, reject) { // Determine if the file can be accessed directly - import('filesystem').then(({ default: filesystem }) => { + import('filesystem').then((filesystem) => { const method = isFolderRip ? 'directoryExists' : 'fileExists'; From 1fe25e14ddb6131be62b1ed4dbb12f3a821a5702 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 2 Aug 2020 17:28:25 +0900 Subject: [PATCH 034/155] move themes and plugins into config file --- package.json | 2 + src/components/appRouter.js | 17 +- src/components/apphost.js | 9 +- .../displaySettings/displaySettings.js | 114 ++--------- .../displaySettings.template.html | 20 -- src/components/skinManager.js | 184 ------------------ src/config.template.json | 36 +++- src/index.html | 8 +- src/manifest.json | 2 +- ...romecastHelpers.js => chromecastHelper.js} | 0 src/plugins/chromecastPlayer/plugin.js | 2 +- src/scripts/autoThemes.js | 8 + src/scripts/inputManager.js | 1 + src/scripts/settings/appSettings.js | 41 ---- src/scripts/settings/webSettings.js | 20 +- src/scripts/site.js | 57 +++--- src/scripts/themeLoader.js | 29 --- src/scripts/themeManager.js | 66 +++++++ 18 files changed, 180 insertions(+), 436 deletions(-) delete mode 100644 src/components/skinManager.js rename src/plugins/chromecastPlayer/{chromecastHelpers.js => chromecastHelper.js} (100%) create mode 100644 src/scripts/autoThemes.js delete mode 100644 src/scripts/themeLoader.js create mode 100644 src/scripts/themeManager.js diff --git a/package.json b/package.json index 7943c22e54..8e725e1052 100644 --- a/package.json +++ b/package.json @@ -266,6 +266,8 @@ "src/scripts/globalize.js", "src/scripts/imagehelper.js", "src/scripts/inputManager.js", + "src/scripts/autoThemes.js", + "src/scripts/themeManager.js", "src/scripts/keyboardNavigation.js", "src/scripts/libraryBrowser.js", "src/scripts/multiDownload.js", diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 8c9b953d39..5dbcf765be 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -36,7 +36,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro switch (result.State) { case 'SignedIn': loading.hide(); - skinManager.loadUserSkin(); + Emby.Page.goHome(); break; case 'ServerSignIn': result.ApiClient.getPublicUsers().then(function (users) { @@ -149,7 +149,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro if (typeof route.path === 'string') { loadContentUrl(ctx, next, route, currentRequest); } else { - // ? TODO next(); } }; @@ -287,12 +286,9 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro connectionManager.connect({ enableAutoLogin: appSettings.enableAutoLogin() - }).then(function (result) { firstConnectionResult = result; - options = options || {}; - page({ click: options.click !== false, hashbang: options.hashbang !== false @@ -344,7 +340,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro if (route.isDefaultRoute) { console.debug('appRouter - loading skin home page'); - loadUserSkinWithOptions(ctx); + Emby.Page.goHome(); return; } else if (route.roles) { validateRoles(apiClient, route.roles).then(function () { @@ -358,15 +354,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro callback(); } - function loadUserSkinWithOptions(ctx) { - require(['queryString'], function (queryString) { - var params = queryString.parse(ctx.querystring); - skinManager.loadUserSkin({ - start: params.start - }); - }); - } - function validateRoles(apiClient, roles) { return Promise.all(roles.split(',').map(function (role) { return validateRole(apiClient, role); diff --git a/src/components/apphost.js b/src/components/apphost.js index 8a5581d817..931fcae1db 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -277,7 +277,7 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g features.push('targetblank'); features.push('screensaver'); - webSettings.enableMultiServer().then(enabled => { + webSettings.getMultiServer().then(enabled => { if (enabled) features.push('multiserver'); }); @@ -407,13 +407,6 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g getPushTokenInfo: function () { return {}; }, - setThemeColor: function (color) { - var metaThemeColor = document.querySelector('meta[name=theme-color]'); - - if (metaThemeColor) { - metaThemeColor.setAttribute('content', color); - } - }, setUserScalable: function (scalable) { if (!browser.tv) { var att = scalable ? 'width=device-width, initial-scale=1, minimum-scale=1, user-scalable=yes' : 'width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no'; diff --git a/src/components/displaySettings/displaySettings.js b/src/components/displaySettings/displaySettings.js index ba78ab99e1..d9c2fc0b49 100644 --- a/src/components/displaySettings/displaySettings.js +++ b/src/components/displaySettings/displaySettings.js @@ -16,17 +16,22 @@ import 'emby-button'; /* eslint-disable indent */ - function fillThemes(select, isDashboard) { - select.innerHTML = skinManager.getThemes().map(t => { - let value = t.id; - if (t.isDefault && !isDashboard) { - value = ''; - } else if (t.isDefaultServerDashboard && isDashboard) { - value = ''; - } + function fillThemes(context, userSettings) { + const select = context.querySelector('#selectTheme'); - return ``; - }).join(''); + skinManager.getThemes().then(themes => { + select.innerHTML = themes.map(t => { + return ``; + }).join(''); + + // get default theme + var defaultTheme = themes.find(theme => { + return theme.default; + }); + + // set the current theme + select.value = userSettings.theme() || defaultTheme.id; + }); } function loadScreensavers(context, userSettings) { @@ -46,6 +51,7 @@ import 'emby-button'; selectScreensaver.innerHTML = options.map(o => { return ``; }).join(''); + selectScreensaver.value = userSettings.screensaver(); if (!selectScreensaver.value) { @@ -54,57 +60,6 @@ import 'emby-button'; } } - function loadSoundEffects(context, userSettings) { - const selectSoundEffects = context.querySelector('.selectSoundEffects'); - const options = pluginManager.ofType('soundeffects').map(plugin => { - return { - name: plugin.name, - value: plugin.id - }; - }); - - options.unshift({ - name: globalize.translate('None'), - value: 'none' - }); - - selectSoundEffects.innerHTML = options.map(o => { - return ``; - }).join(''); - selectSoundEffects.value = userSettings.soundEffects(); - - if (!selectSoundEffects.value) { - // TODO: set the default instead of none - selectSoundEffects.value = 'none'; - } - } - - function loadSkins(context, userSettings) { - const selectSkin = context.querySelector('.selectSkin'); - - const options = pluginManager.ofType('skin').map(plugin => { - return { - name: plugin.name, - value: plugin.id - }; - }); - - selectSkin.innerHTML = options.map(o => { - return ``; - }).join(''); - selectSkin.value = userSettings.skin(); - - if (!selectSkin.value && options.length) { - selectSkin.value = options[0].value; - } - - if (options.length > 1 && appHost.supports('skins')) { - context.querySelector('.selectSkinContainer').classList.remove('hide'); - } else { - context.querySelector('.selectSkinContainer').classList.add('hide'); - } - } - function showOrHideMissingEpisodesField(context) { if (browser.tizen || browser.web0s) { context.querySelector('.fldDisplayMissingEpisodes').classList.add('hide'); @@ -115,12 +70,6 @@ import 'emby-button'; } function loadForm(context, user, userSettings) { - if (user.Policy.IsAdministrator) { - context.querySelector('.selectDashboardThemeContainer').classList.remove('hide'); - } else { - context.querySelector('.selectDashboardThemeContainer').classList.add('hide'); - } - if (appHost.supports('displaylanguage')) { context.querySelector('.languageSection').classList.remove('hide'); } else { @@ -139,18 +88,6 @@ import 'emby-button'; context.querySelector('.learnHowToContributeContainer').classList.add('hide'); } - if (appHost.supports('runatstartup')) { - context.querySelector('.fldAutorun').classList.remove('hide'); - } else { - context.querySelector('.fldAutorun').classList.add('hide'); - } - - if (appHost.supports('soundeffects')) { - context.querySelector('.fldSoundEffects').classList.remove('hide'); - } else { - context.querySelector('.fldSoundEffects').classList.add('hide'); - } - if (appHost.supports('screensaver')) { context.querySelector('.selectScreensaverContainer').classList.remove('hide'); } else { @@ -173,16 +110,8 @@ import 'emby-button'; context.querySelector('.fldThemeVideo').classList.add('hide'); } - context.querySelector('.chkRunAtStartup').checked = appSettings.runAtStartup(); - - const selectTheme = context.querySelector('#selectTheme'); - const selectDashboardTheme = context.querySelector('#selectDashboardTheme'); - - fillThemes(selectTheme); - fillThemes(selectDashboardTheme, true); + fillThemes(context, userSettings); loadScreensavers(context, userSettings); - loadSoundEffects(context, userSettings); - loadSkins(context, userSettings); context.querySelector('.chkDisplayMissingEpisodes').checked = user.Configuration.DisplayMissingEpisodes || false; @@ -198,9 +127,6 @@ import 'emby-button'; context.querySelector('#txtLibraryPageSize').value = userSettings.libraryPageSize(); - selectDashboardTheme.value = userSettings.dashboardTheme() || ''; - selectTheme.value = userSettings.theme() || ''; - context.querySelector('.selectLayout').value = layoutManager.getSavedLayout() || ''; showOrHideMissingEpisodesField(context); @@ -209,8 +135,6 @@ import 'emby-button'; } function saveUser(context, user, userSettingsInstance, apiClient) { - appSettings.runAtStartup(context.querySelector('.chkRunAtStartup').checked); - user.Configuration.DisplayMissingEpisodes = context.querySelector('.chkDisplayMissingEpisodes').checked; if (appHost.supports('displaylanguage')) { @@ -221,15 +145,11 @@ import 'emby-button'; userSettingsInstance.enableThemeSongs(context.querySelector('#chkThemeSong').checked); userSettingsInstance.enableThemeVideos(context.querySelector('#chkThemeVideo').checked); - userSettingsInstance.dashboardTheme(context.querySelector('#selectDashboardTheme').value); userSettingsInstance.theme(context.querySelector('#selectTheme').value); - userSettingsInstance.soundEffects(context.querySelector('.selectSoundEffects').value); userSettingsInstance.screensaver(context.querySelector('.selectScreensaver').value); userSettingsInstance.libraryPageSize(context.querySelector('#txtLibraryPageSize').value); - userSettingsInstance.skin(context.querySelector('.selectSkin').value); - userSettingsInstance.enableFastFadein(context.querySelector('#chkFadein').checked); userSettingsInstance.enableBlurhash(context.querySelector('#chkBlurhash').checked); userSettingsInstance.enableBackdrops(context.querySelector('#chkBackdrops').checked); diff --git a/src/components/displaySettings/displaySettings.template.html b/src/components/displaySettings/displaySettings.template.html index 7258edf208..fdaf8d70f1 100644 --- a/src/components/displaySettings/displaySettings.template.html +++ b/src/components/displaySettings/displaySettings.template.html @@ -1,5 +1,4 @@
-

${Display}

@@ -123,26 +122,14 @@
${LabelPleaseRestart}
-
- -
-
-
- -
-
-
- -
-
${LabelLibraryPageSizeHelp}
@@ -196,13 +183,6 @@
${EnableThemeVideosHelp}
-
- -
-