From 257ce4974ebee7c0977ae95cba4269805f6f8b77 Mon Sep 17 00:00:00 2001 From: Christoph Potas Date: Sun, 3 May 2020 20:30:35 +0200 Subject: [PATCH 0001/1168] ~ migrate subtitlesettings.js to es6 ~ migrate subtitleappearancehelper.js to es6 ~ replace duplicated "populateLanguages" function ( playbacksettings.js:18 ) ~ replace duplicated "onSubmit" function ( playbacksettings.js:266 ) - remove empty function getWindowStyles Signed-off-by: Christoph Potas --- package.json | 2 + .../subtitleappearancehelper.js | 242 ++++++------- .../subtitlesettings/subtitlesettings.js | 330 +++++++++--------- 3 files changed, 276 insertions(+), 298 deletions(-) diff --git a/package.json b/package.json index 53f3d225a..fda29b810 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,8 @@ "test": [ "src/components/autoFocuser.js", "src/components/cardbuilder/cardBuilder.js", + "src/components/subtitlesettings/subtitlesettings.js", + "src/components/subtitlesettings/subtitleappearancehelper.js", "src/scripts/dom.js", "src/components/filedownloader.js", "src/scripts/filesystem.js", diff --git a/src/components/subtitlesettings/subtitleappearancehelper.js b/src/components/subtitlesettings/subtitleappearancehelper.js index fdc64f0df..7bf473783 100644 --- a/src/components/subtitlesettings/subtitleappearancehelper.js +++ b/src/components/subtitlesettings/subtitleappearancehelper.js @@ -1,159 +1,149 @@ -define([], function () { - "use strict"; +function getTextStyles(settings, isCue) { - function getTextStyles(settings, isCue) { + let list = []; - var list = []; + if (isCue) { + switch (settings.textSize || '') { - 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.dropShadow || '') { - - case 'raised': - list.push({ name: 'text-shadow', value: '-1px -1px white, 0px -1px white, -1px 0px white, 1px 1px black, 0px 1px black, 1px 0px black' }); + case 'smaller': + list.push({ name: 'font-size', value: '.5em' }); break; - case 'depressed': - list.push({ name: 'text-shadow', value: '1px 1px white, 0px 1px white, 1px 0px white, -1px -1px black, 0px -1px black, -1px 0px black' }); + case 'small': + list.push({ name: 'font-size', value: '.7em' }); break; - case 'uniform': - list.push({ name: 'text-shadow', value: '-1px 0px #000000, 0px 1px #000000, 1px 0px #000000, 0px -1px #000000' }); + case 'large': + list.push({ name: 'font-size', value: '1.3em' }); break; - case 'none': - list.push({ name: 'text-shadow', value: 'none' }); + case 'larger': + list.push({ name: 'font-size', value: '1.72em' }); + break; + case 'extralarge': + list.push({ name: 'font-size', value: '2em' }); break; default: - case 'dropshadow': - list.push({ name: 'text-shadow', value: '#000000 0px 0px 7px' }); + case 'medium': break; } + } else { + switch (settings.textSize || '') { - var background = settings.textBackground || 'transparent'; - if (background) { - list.push({ name: 'background-color', value: background }); - } - - var textColor = settings.textColor || '#ffffff'; - if (textColor) { - list.push({ name: 'color', value: textColor }); - } - - switch (settings.font || '') { - - case 'typewriter': - list.push({ name: 'font-family', value: '"Courier New",monospace' }); - list.push({ name: 'font-variant', value: 'none' }); + case 'smaller': + list.push({ name: 'font-size', value: '.8em' }); break; - case 'print': - list.push({ name: 'font-family', value: 'Georgia,Times New Roman,Arial,Helvetica,serif' }); - list.push({ name: 'font-variant', value: 'none' }); + case 'small': + list.push({ name: 'font-size', value: 'inherit' }); break; - case 'console': - list.push({ name: 'font-family', value: 'Consolas,Lucida Console,Menlo,Monaco,monospace' }); - list.push({ name: 'font-variant', value: 'none' }); + case 'larger': + list.push({ name: 'font-size', value: '2em' }); break; - case 'cursive': - list.push({ name: 'font-family', value: 'Lucida Handwriting,Brush Script MT,Segoe Script,cursive,Quintessential,system-ui,-apple-system,BlinkMacSystemFont,sans-serif' }); - list.push({ name: 'font-variant', value: 'none' }); + case 'extralarge': + list.push({ name: 'font-size', value: '2.2em' }); break; - case 'casual': - list.push({ name: 'font-family', value: 'Gabriola,Segoe Print,Comic Sans MS,Chalkboard,Short Stack,system-ui,-apple-system,BlinkMacSystemFont,sans-serif' }); - list.push({ name: 'font-variant', value: 'none' }); - break; - case 'smallcaps': - list.push({ name: 'font-family', value: 'Copperplate Gothic,Copperplate Gothic Bold,Copperplate,system-ui,-apple-system,BlinkMacSystemFont,sans-serif' }); - list.push({ name: 'font-variant', value: 'small-caps' }); + case 'large': + list.push({ name: 'font-size', value: '1.72em' }); break; default: - list.push({ name: 'font-family', value: 'inherit' }); - list.push({ name: 'font-variant', value: 'none' }); + case 'medium': + list.push({ name: 'font-size', value: '1.36em' }); break; } - - return list; } - function getWindowStyles(settings) { + switch (settings.dropShadow || '') { - return []; + case 'raised': + list.push({ name: 'text-shadow', value: '-1px -1px white, 0px -1px white, -1px 0px white, 1px 1px black, 0px 1px black, 1px 0px black' }); + break; + case 'depressed': + list.push({ name: 'text-shadow', value: '1px 1px white, 0px 1px white, 1px 0px white, -1px -1px black, 0px -1px black, -1px 0px black' }); + break; + case 'uniform': + list.push({ name: 'text-shadow', value: '-1px 0px #000000, 0px 1px #000000, 1px 0px #000000, 0px -1px #000000' }); + break; + case 'none': + list.push({ name: 'text-shadow', value: 'none' }); + break; + default: + case 'dropshadow': + list.push({ name: 'text-shadow', value: '#000000 0px 0px 7px' }); + break; } - function getStyles(settings, isCue) { - - return { - text: getTextStyles(settings, isCue), - window: getWindowStyles(settings) - }; + const background = settings.textBackground || 'transparent'; + if (background) { + list.push({ name: 'background-color', value: background }); } - function applyStyleList(styles, elem) { - - for (var i = 0, length = styles.length; i < length; i++) { - - var style = styles[i]; - - elem.style[style.name] = style.value; - } + const textColor = settings.textColor || '#ffffff'; + if (textColor) { + list.push({ name: 'color', value: textColor }); } - function applyStyles(elements, appearanceSettings) { + switch (settings.font || '') { - var styles = getStyles(appearanceSettings); - - if (elements.text) { - applyStyleList(styles.text, elements.text); - } - if (elements.window) { - applyStyleList(styles.window, elements.window); - } + case 'typewriter': + list.push({ name: 'font-family', value: '"Courier New",monospace' }); + list.push({ name: 'font-variant', value: 'none' }); + break; + case 'print': + list.push({ name: 'font-family', value: 'Georgia,Times New Roman,Arial,Helvetica,serif' }); + list.push({ name: 'font-variant', value: 'none' }); + break; + case 'console': + list.push({ name: 'font-family', value: 'Consolas,Lucida Console,Menlo,Monaco,monospace' }); + list.push({ name: 'font-variant', value: 'none' }); + break; + case 'cursive': + list.push({ name: 'font-family', value: 'Lucida Handwriting,Brush Script MT,Segoe Script,cursive,Quintessential,system-ui,-apple-system,BlinkMacSystemFont,sans-serif' }); + list.push({ name: 'font-variant', value: 'none' }); + break; + case 'casual': + list.push({ name: 'font-family', value: 'Gabriola,Segoe Print,Comic Sans MS,Chalkboard,Short Stack,system-ui,-apple-system,BlinkMacSystemFont,sans-serif' }); + list.push({ name: 'font-variant', value: 'none' }); + break; + case 'smallcaps': + list.push({ name: 'font-family', value: 'Copperplate Gothic,Copperplate Gothic Bold,Copperplate,system-ui,-apple-system,BlinkMacSystemFont,sans-serif' }); + list.push({ name: 'font-variant', value: 'small-caps' }); + break; + default: + list.push({ name: 'font-family', value: 'inherit' }); + list.push({ name: 'font-variant', value: 'none' }); + break; } + return list; +} + +export function getStyles(settings, isCue) { + return { - getStyles: getStyles, - applyStyles: applyStyles + text: getTextStyles(settings, isCue), + window: [] }; -}); +} + +function applyStyleList(styles, elem) { + + for (let i = 0, length = styles.length; i < length; i++) { + + let style = styles[i]; + + elem.style[style.name] = style.value; + } +} + +export function applyStyles(elements, appearanceSettings) { + + let styles = getStyles(appearanceSettings); + + if (elements.text) { + applyStyleList(styles.text, elements.text); + } + if (elements.window) { + applyStyleList(styles.window, elements.window); + } +} +export default { + getStyles: getStyles, + applyStyles: applyStyles +}; diff --git a/src/components/subtitlesettings/subtitlesettings.js b/src/components/subtitlesettings/subtitlesettings.js index 2c8692919..8f5038fd6 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -1,213 +1,199 @@ -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) { - "use strict"; +import require from 'require'; +import globalize from 'globalize'; +import appHost from 'apphost'; +import appSettings from 'appSettings'; +import focusManager from 'focusManager'; +import loading from 'loading'; +import connectionManager from 'connectionmanager'; +import subtitleAppearanceHelper from 'subtitleappearancehelper'; +import playbacksettings from 'playbacksettings'; +import dom from 'dom'; +import events from 'events'; +import 'listViewStyle'; +import 'emby-select'; +import 'emby-input'; +import 'emby-checkbox'; +import 'flexStyles'; - function populateLanguages(select, languages) { - var html = ""; +function getSubtitleAppearanceObject(context) { + let appearanceSettings = {}; - html += ""; - for (var i = 0, length = languages.length; i < length; i++) { - var culture = languages[i]; - html += ""; + appearanceSettings.textSize = context.querySelector('#selectTextSize').value; + appearanceSettings.dropShadow = context.querySelector('#selectDropShadow').value; + appearanceSettings.font = context.querySelector('#selectFont').value; + appearanceSettings.textBackground = context.querySelector('#inputTextBackground').value; + appearanceSettings.textColor = context.querySelector('#inputTextColor').value; + + return appearanceSettings; +} + +function loadForm(context, user, userSettings, appearanceSettings, apiClient) { + + apiClient.getCultures().then(function (allCultures) { + + if (appHost.supports('subtitleburnsettings') && user.Policy.EnableVideoPlaybackTranscoding) { + context.querySelector('.fldBurnIn').classList.remove('hide'); } - select.innerHTML = html; - } + let selectSubtitleLanguage = context.querySelector( '#selectSubtitleLanguage' ); - function getSubtitleAppearanceObject(context) { - var appearanceSettings = {}; + playbacksettings.populateLanguages(selectSubtitleLanguage, allCultures); - appearanceSettings.textSize = context.querySelector('#selectTextSize').value; - appearanceSettings.dropShadow = context.querySelector('#selectDropShadow').value; - appearanceSettings.font = context.querySelector('#selectFont').value; - appearanceSettings.textBackground = context.querySelector('#inputTextBackground').value; - appearanceSettings.textColor = context.querySelector('#inputTextColor').value; + selectSubtitleLanguage.value = user.Configuration.SubtitleLanguagePreference || ""; + context.querySelector('#selectSubtitlePlaybackMode').value = user.Configuration.SubtitleMode || ""; - return appearanceSettings; - } + context.querySelector('#selectSubtitlePlaybackMode').dispatchEvent(new CustomEvent('change', {})); - function loadForm(context, user, userSettings, appearanceSettings, apiClient) { + context.querySelector('#selectTextSize').value = appearanceSettings.textSize || ''; + context.querySelector('#selectDropShadow').value = appearanceSettings.dropShadow || ''; + context.querySelector('#inputTextBackground').value = appearanceSettings.textBackground || 'transparent'; + context.querySelector('#inputTextColor').value = appearanceSettings.textColor || '#ffffff'; + context.querySelector('#selectFont').value = appearanceSettings.font || ''; - apiClient.getCultures().then(function (allCultures) { + context.querySelector('#selectSubtitleBurnIn').value = appSettings.get('subtitleburnin') || ''; - if (appHost.supports('subtitleburnsettings') && user.Policy.EnableVideoPlaybackTranscoding) { - context.querySelector('.fldBurnIn').classList.remove('hide'); - } + onAppearanceFieldChange({ + target: context.querySelector('#selectTextSize') + }); - var selectSubtitleLanguage = context.querySelector('#selectSubtitleLanguage'); + loading.hide(); + }); +} - populateLanguages(selectSubtitleLanguage, allCultures); +function saveUser(context, user, userSettingsInstance, appearanceKey, apiClient) { - selectSubtitleLanguage.value = user.Configuration.SubtitleLanguagePreference || ""; - context.querySelector('#selectSubtitlePlaybackMode').value = user.Configuration.SubtitleMode || ""; + let appearanceSettings = userSettingsInstance.getSubtitleAppearanceSettings( appearanceKey ); + appearanceSettings = Object.assign(appearanceSettings, getSubtitleAppearanceObject(context)); - context.querySelector('#selectSubtitlePlaybackMode').dispatchEvent(new CustomEvent('change', {})); + userSettingsInstance.setSubtitleAppearanceSettings(appearanceSettings, appearanceKey); - context.querySelector('#selectTextSize').value = appearanceSettings.textSize || ''; - context.querySelector('#selectDropShadow').value = appearanceSettings.dropShadow || ''; - context.querySelector('#inputTextBackground').value = appearanceSettings.textBackground || 'transparent'; - context.querySelector('#inputTextColor').value = appearanceSettings.textColor || '#ffffff'; - context.querySelector('#selectFont').value = appearanceSettings.font || ''; + user.Configuration.SubtitleLanguagePreference = context.querySelector('#selectSubtitleLanguage').value; + user.Configuration.SubtitleMode = context.querySelector('#selectSubtitlePlaybackMode').value; - context.querySelector('#selectSubtitleBurnIn').value = appSettings.get('subtitleburnin') || ''; + return apiClient.updateUserConfiguration(user.Id, user.Configuration); +} - onAppearanceFieldChange({ - target: context.querySelector('#selectTextSize') - }); +export function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) { + + loading.show(); + + appSettings.set('subtitleburnin', context.querySelector('#selectSubtitleBurnIn').value); + + apiClient.getUser(userId).then(function (user) { + + saveUser(context, user, userSettings, instance.appearanceKey, apiClient).then(function () { loading.hide(); + if (enableSaveConfirmation) { + require(['toast'], function (toast) { + toast(globalize.translate('SettingsSaved')); + }); + } + + events.trigger(instance, 'saved'); + + }, function () { + loading.hide(); }); + }); +} + +function onSubtitleModeChange(e) { + + let view = dom.parentWithClass( e.target, 'subtitlesettings' ); + + let subtitlesHelp = view.querySelectorAll( '.subtitlesHelp' ); + for (let i = 0, length = subtitlesHelp.length; i < length; i++) { + subtitlesHelp[i].classList.add('hide'); } + view.querySelector('.subtitles' + this.value + 'Help').classList.remove('hide'); +} - function saveUser(context, user, userSettingsInstance, appearanceKey, apiClient) { +function onAppearanceFieldChange(e) { - var appearanceSettings = userSettingsInstance.getSubtitleAppearanceSettings(appearanceKey); - appearanceSettings = Object.assign(appearanceSettings, getSubtitleAppearanceObject(context)); + let view = dom.parentWithClass( e.target, 'subtitlesettings' ); - userSettingsInstance.setSubtitleAppearanceSettings(appearanceSettings, appearanceKey); + let appearanceSettings = getSubtitleAppearanceObject( view ); - user.Configuration.SubtitleLanguagePreference = context.querySelector('#selectSubtitleLanguage').value; - user.Configuration.SubtitleMode = context.querySelector('#selectSubtitlePlaybackMode').value; + let elements = { + window: view.querySelector( '.subtitleappearance-preview-window' ), + text: view.querySelector( '.subtitleappearance-preview-text' ) + }; - return apiClient.updateUserConfiguration(user.Id, user.Configuration); - } + subtitleAppearanceHelper.applyStyles(elements, appearanceSettings); +} - function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) { +export function embed(options, self) { - loading.show(); + require(['text!./subtitlesettings.template.html'], function (template) { - appSettings.set('subtitleburnin', context.querySelector('#selectSubtitleBurnIn').value); + options.element.classList.add('subtitlesettings'); + options.element.innerHTML = globalize.translateDocument(template, 'core'); - apiClient.getUser(userId).then(function (user) { + options.element.querySelector('form').addEventListener('submit', playbacksettings.OnSubmit.bind(self)); - saveUser(context, user, userSettings, instance.appearanceKey, apiClient).then(function () { + options.element.querySelector('#selectSubtitlePlaybackMode').addEventListener('change', onSubtitleModeChange); + options.element.querySelector('#selectTextSize').addEventListener('change', onAppearanceFieldChange); + options.element.querySelector('#selectDropShadow').addEventListener('change', onAppearanceFieldChange); + options.element.querySelector('#selectFont').addEventListener('change', onAppearanceFieldChange); + options.element.querySelector('#inputTextColor').addEventListener('change', onAppearanceFieldChange); + options.element.querySelector('#inputTextBackground').addEventListener('change', onAppearanceFieldChange); - loading.hide(); - if (enableSaveConfirmation) { - require(['toast'], function (toast) { - toast(globalize.translate('SettingsSaved')); - }); - } + if (options.enableSaveButton) { + options.element.querySelector('.btnSave').classList.remove('hide'); + } - events.trigger(instance, 'saved'); + if (appHost.supports('subtitleappearancesettings')) { + options.element.querySelector('.subtitleAppearanceSection').classList.remove('hide'); + } - }, function () { - loading.hide(); - }); - }); - } + self.loadData(); - function onSubmit(e) { - var self = this; - var apiClient = connectionManager.getApiClient(self.options.serverId); - var userId = self.options.userId; - var userSettings = self.options.userSettings; + if (options.autoFocus) { + focusManager.autoFocus(options.element); + } + }); +} +export function SubtitleSettings(options) { + + this.options = options; + + embed(options, this); +} + +SubtitleSettings.prototype.loadData = function () { + + let self = this; + let context = self.options.element; + + loading.show(); + + let userId = self.options.userId; + let apiClient = connectionManager.getApiClient( self.options.serverId ); + let userSettings = self.options.userSettings; + + apiClient.getUser(userId).then(function (user) { userSettings.setUserInfo(userId, apiClient).then(function () { - var enableSaveConfirmation = self.options.enableSaveConfirmation; - save(self, self.options.element, userId, userSettings, apiClient, enableSaveConfirmation); + self.dataLoaded = true; + + let appearanceSettings = userSettings.getSubtitleAppearanceSettings( self.options.appearanceKey ); + + loadForm(context, user, userSettings, appearanceSettings, apiClient); }); + }); +}; - // Disable default form submission - if (e) { - e.preventDefault(); - } +SubtitleSettings.prototype.submit = function () { + playbacksettings.onSubmit.call(this); +}; - return false; - } +SubtitleSettings.prototype.destroy = function () { + this.options = null; +}; - function onSubtitleModeChange(e) { - - var view = dom.parentWithClass(e.target, 'subtitlesettings'); - - var subtitlesHelp = view.querySelectorAll('.subtitlesHelp'); - for (var i = 0, length = subtitlesHelp.length; i < length; i++) { - subtitlesHelp[i].classList.add('hide'); - } - view.querySelector('.subtitles' + this.value + 'Help').classList.remove('hide'); - } - - function onAppearanceFieldChange(e) { - - var view = dom.parentWithClass(e.target, 'subtitlesettings'); - - var appearanceSettings = getSubtitleAppearanceObject(view); - - var elements = { - window: view.querySelector('.subtitleappearance-preview-window'), - text: view.querySelector('.subtitleappearance-preview-text') - }; - - subtitleAppearanceHelper.applyStyles(elements, appearanceSettings); - } - - function embed(options, self) { - - require(['text!./subtitlesettings.template.html'], function (template) { - - options.element.classList.add('subtitlesettings'); - options.element.innerHTML = globalize.translateDocument(template, 'core'); - - options.element.querySelector('form').addEventListener('submit', onSubmit.bind(self)); - - options.element.querySelector('#selectSubtitlePlaybackMode').addEventListener('change', onSubtitleModeChange); - options.element.querySelector('#selectTextSize').addEventListener('change', onAppearanceFieldChange); - options.element.querySelector('#selectDropShadow').addEventListener('change', onAppearanceFieldChange); - options.element.querySelector('#selectFont').addEventListener('change', onAppearanceFieldChange); - options.element.querySelector('#inputTextColor').addEventListener('change', onAppearanceFieldChange); - options.element.querySelector('#inputTextBackground').addEventListener('change', onAppearanceFieldChange); - - if (options.enableSaveButton) { - options.element.querySelector('.btnSave').classList.remove('hide'); - } - - if (appHost.supports('subtitleappearancesettings')) { - options.element.querySelector('.subtitleAppearanceSection').classList.remove('hide'); - } - - self.loadData(); - - if (options.autoFocus) { - focusManager.autoFocus(options.element); - } - }); - } - - function SubtitleSettings(options) { - - this.options = options; - - embed(options, this); - } - - SubtitleSettings.prototype.loadData = function () { - - var self = this; - var context = self.options.element; - - loading.show(); - - var userId = self.options.userId; - var apiClient = connectionManager.getApiClient(self.options.serverId); - var userSettings = self.options.userSettings; - - apiClient.getUser(userId).then(function (user) { - userSettings.setUserInfo(userId, apiClient).then(function () { - self.dataLoaded = true; - - var appearanceSettings = userSettings.getSubtitleAppearanceSettings(self.options.appearanceKey); - - loadForm(context, user, userSettings, appearanceSettings, apiClient); - }); - }); - }; - - SubtitleSettings.prototype.submit = function () { - onSubmit.call(this); - }; - - SubtitleSettings.prototype.destroy = function () { - this.options = null; - }; - - return SubtitleSettings; -}); +export default { + save: save, + embed: embed, + SubtitleSettings: SubtitleSettings +}; From 6f0843cc6d30629c6e8f190558389785b9037e3a Mon Sep 17 00:00:00 2001 From: Christoph Potas Date: Mon, 4 May 2020 03:20:38 +0200 Subject: [PATCH 0002/1168] ~ convert subtitlesettings to class ~ use base import name instead of relative file path ~ fix "new" calling Signed-off-by: Christoph Potas --- package.json | 1 + src/components/settingshelper.js | 24 ++++ .../subtitleappearancehelper.js | 4 + .../subtitlesettings/subtitlesettings.js | 112 +++++++++++------- src/controllers/user/subtitles.js | 2 +- 5 files changed, 97 insertions(+), 46 deletions(-) create mode 100644 src/components/settingshelper.js diff --git a/package.json b/package.json index fda29b810..c11b6db91 100644 --- a/package.json +++ b/package.json @@ -92,6 +92,7 @@ "src/components/cardbuilder/cardBuilder.js", "src/components/subtitlesettings/subtitlesettings.js", "src/components/subtitlesettings/subtitleappearancehelper.js", + "src/components/settingshelper.js", "src/scripts/dom.js", "src/components/filedownloader.js", "src/scripts/filesystem.js", diff --git a/src/components/settingshelper.js b/src/components/settingshelper.js new file mode 100644 index 000000000..0c942ed04 --- /dev/null +++ b/src/components/settingshelper.js @@ -0,0 +1,24 @@ +import globalize from 'globalize'; +/** + * Helper for handling settings + * @module components/settingsHelper + */ +export function populateLanguages(select, languages) { + + let html = ""; + + html += ""; + + for (let i = 0, length = languages.length; i < length; i++) { + + const culture = languages[i]; + + html += ""; + } + + select.innerHTML = html; +} + +export default { + populateLanguages: populateLanguages +}; diff --git a/src/components/subtitlesettings/subtitleappearancehelper.js b/src/components/subtitlesettings/subtitleappearancehelper.js index 7bf473783..d1c55e1ae 100644 --- a/src/components/subtitlesettings/subtitleappearancehelper.js +++ b/src/components/subtitlesettings/subtitleappearancehelper.js @@ -1,3 +1,7 @@ +/** + * Subtitle settings visual helper + * @module components/subtitleSettings/subtitleAppearanceHelper + */ function getTextStyles(settings, isCue) { let list = []; diff --git a/src/components/subtitlesettings/subtitlesettings.js b/src/components/subtitlesettings/subtitlesettings.js index 8f5038fd6..3e41da953 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -4,9 +4,9 @@ import appHost from 'apphost'; import appSettings from 'appSettings'; import focusManager from 'focusManager'; import loading from 'loading'; -import connectionManager from 'connectionmanager'; -import subtitleAppearanceHelper from 'subtitleappearancehelper'; -import playbacksettings from 'playbacksettings'; +import connectionManager from 'connectionManager'; +import subtitleAppearanceHelper from 'subtitleAppearanceHelper'; +import settingsHelper from '../settingshelper'; import dom from 'dom'; import events from 'events'; import 'listViewStyle'; @@ -15,6 +15,11 @@ import 'emby-input'; import 'emby-checkbox'; import 'flexStyles'; +/** + * Subtitle settings + * @module components/subtitleSettings/subtitleSettings + */ + function getSubtitleAppearanceObject(context) { let appearanceSettings = {}; @@ -37,7 +42,7 @@ function loadForm(context, user, userSettings, appearanceSettings, apiClient) { let selectSubtitleLanguage = context.querySelector( '#selectSubtitleLanguage' ); - playbacksettings.populateLanguages(selectSubtitleLanguage, allCultures); + settingsHelper.populateLanguages(selectSubtitleLanguage, allCultures); selectSubtitleLanguage.value = user.Configuration.SubtitleLanguagePreference || ""; context.querySelector('#selectSubtitlePlaybackMode').value = user.Configuration.SubtitleMode || ""; @@ -73,7 +78,7 @@ function saveUser(context, user, userSettingsInstance, appearanceKey, apiClient) return apiClient.updateUserConfiguration(user.Id, user.Configuration); } -export function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) { +function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) { loading.show(); @@ -123,14 +128,14 @@ function onAppearanceFieldChange(e) { subtitleAppearanceHelper.applyStyles(elements, appearanceSettings); } -export function embed(options, self) { +function embed(options, self) { require(['text!./subtitlesettings.template.html'], function (template) { options.element.classList.add('subtitlesettings'); options.element.innerHTML = globalize.translateDocument(template, 'core'); - options.element.querySelector('form').addEventListener('submit', playbacksettings.OnSubmit.bind(self)); + options.element.querySelector('form').addEventListener('submit', self.onSubmit ); options.element.querySelector('#selectSubtitlePlaybackMode').addEventListener('change', onSubtitleModeChange); options.element.querySelector('#selectTextSize').addEventListener('change', onAppearanceFieldChange); @@ -155,45 +160,62 @@ export function embed(options, self) { }); } -export function SubtitleSettings(options) { +export class SubtitleSettings { - this.options = options; + constructor(options) { - embed(options, this); + this.options = options; + + embed(options, this); + } + + loadData() { + let self = this; + let context = self.options.element; + + loading.show(); + + let userId = self.options.userId; + let apiClient = connectionManager.getApiClient( self.options.serverId ); + let userSettings = self.options.userSettings; + + apiClient.getUser(userId).then(function (user) { + userSettings.setUserInfo(userId, apiClient).then(function () { + self.dataLoaded = true; + + let appearanceSettings = userSettings.getSubtitleAppearanceSettings( self.options.appearanceKey ); + + loadForm(context, user, userSettings, appearanceSettings, apiClient); + }); + }); + } + + submit() { + this.onSubmit( null ); + } + + destroy() { + this.options = null; + } + + onSubmit( e ) { + const self = this; + let apiClient = connectionManager.getApiClient(self.options.serverId); + let userId = self.options.userId; + let userSettings = self.options.userSettings; + + userSettings.setUserInfo(userId, apiClient).then(function () { + + let enableSaveConfirmation = self.options.enableSaveConfirmation; + save(self, self.options.element, userId, userSettings, apiClient, enableSaveConfirmation); + }); + + // Disable default form submission + if (e) { + e.preventDefault(); + } + return false; + } } -SubtitleSettings.prototype.loadData = function () { - - let self = this; - let context = self.options.element; - - loading.show(); - - let userId = self.options.userId; - let apiClient = connectionManager.getApiClient( self.options.serverId ); - let userSettings = self.options.userSettings; - - apiClient.getUser(userId).then(function (user) { - userSettings.setUserInfo(userId, apiClient).then(function () { - self.dataLoaded = true; - - let appearanceSettings = userSettings.getSubtitleAppearanceSettings( self.options.appearanceKey ); - - loadForm(context, user, userSettings, appearanceSettings, apiClient); - }); - }); -}; - -SubtitleSettings.prototype.submit = function () { - playbacksettings.onSubmit.call(this); -}; - -SubtitleSettings.prototype.destroy = function () { - this.options = null; -}; - -export default { - save: save, - embed: embed, - SubtitleSettings: SubtitleSettings -}; +export default SubtitleSettings; diff --git a/src/controllers/user/subtitles.js b/src/controllers/user/subtitles.js index e2b98dc2d..f449b655c 100644 --- a/src/controllers/user/subtitles.js +++ b/src/controllers/user/subtitles.js @@ -18,7 +18,7 @@ define(["subtitleSettings", "userSettings", "autoFocuser"], function (SubtitleSe if (subtitleSettingsInstance) { subtitleSettingsInstance.loadData(); } else { - subtitleSettingsInstance = new SubtitleSettings({ + subtitleSettingsInstance = new SubtitleSettings.default({ serverId: ApiClient.serverId(), userId: userId, element: view.querySelector(".settingsContainer"), From 658710e982db7a435d5396549d5712b955fb320b Mon Sep 17 00:00:00 2001 From: Christoph Potas Date: Sat, 9 May 2020 01:20:32 +0200 Subject: [PATCH 0003/1168] + added settingshelper to site defines ~ convert subtitles controller to es6 module + added support for class controller Signed-off-by: Christoph Potas --- .../subtitlesettings/subtitlesettings.js | 2 +- src/components/viewManager/viewManager.js | 4 + src/controllers/user/subtitles.js | 102 ++++++++++-------- src/scripts/site.js | 1 + 4 files changed, 64 insertions(+), 45 deletions(-) diff --git a/src/components/subtitlesettings/subtitlesettings.js b/src/components/subtitlesettings/subtitlesettings.js index 3e41da953..e03c718fc 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -6,7 +6,7 @@ import focusManager from 'focusManager'; import loading from 'loading'; import connectionManager from 'connectionManager'; import subtitleAppearanceHelper from 'subtitleAppearanceHelper'; -import settingsHelper from '../settingshelper'; +import settingsHelper from 'settingsHelper'; import dom from 'dom'; import events from 'events'; import 'listViewStyle'; diff --git a/src/components/viewManager/viewManager.js b/src/components/viewManager/viewManager.js index a8e514e06..f39c4995f 100644 --- a/src/components/viewManager/viewManager.js +++ b/src/components/viewManager/viewManager.js @@ -25,6 +25,10 @@ define(['viewContainer', 'focusManager', 'queryString', 'layoutManager'], functi // Use controller method var controller = new options.controllerFactory(newView, eventDetail.detail.params); + } else if (typeof options.controllerFactory === 'object') { + + // Use controller class + var controller = new options.controllerFactory.default(newView, eventDetail.detail.params); } if (!options.controllerFactory || dispatchPageEvents) { diff --git a/src/controllers/user/subtitles.js b/src/controllers/user/subtitles.js index f449b655c..f1efe0c21 100644 --- a/src/controllers/user/subtitles.js +++ b/src/controllers/user/subtitles.js @@ -1,49 +1,63 @@ -define(["subtitleSettings", "userSettings", "autoFocuser"], function (SubtitleSettings, userSettings, autoFocuser) { - "use strict"; +import subtitleSettings from 'subtitleSettings'; +import * as userSettings from 'userSettings'; +import autoFocuser from 'autoFocuser'; - return function (view, params) { - function onBeforeUnload(e) { - if (hasChanges) { - e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?"; - } +export class SubtitleController { + constructor(view, params) { + this.userId = params.userId || ApiClient.getCurrentUserId(); + this.currentSettings = this.userId === ApiClient.getCurrentUserId() ? userSettings : new userSettings(); + this.hasChanges = false; + this.subtitleSettingsInstance = null; + this.view = view; + + view.addEventListener("viewshow", this.viewShow.bind(this)); + view.addEventListener("change", this.change.bind(this)); + view.addEventListener("viewbeforehide", this.viewBeforeHide.bind(this)); + view.addEventListener("viewdestroy", this.viewDestroy.bind(this)); + } + + viewShow() { + window.addEventListener("beforeunload", this.beforeUnload.bind(this)); + + if (this.subtitleSettingsInstance) { + this.subtitleSettingsInstance.loadData(); + } else { + this.subtitleSettingsInstance = new subtitleSettings({ + serverId: ApiClient.serverId(), + userId: this.userId, + element: this.view.querySelector(".settingsContainer"), + userSettings: this.currentSettings, + enableSaveButton: false, + enableSaveConfirmation: false, + autoFocus: autoFocuser.isEnabled() + }); } + } - var subtitleSettingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new userSettings(); - view.addEventListener("viewshow", function () { - window.addEventListener("beforeunload", onBeforeUnload); + viewDestroy() { + if (this.subtitleSettingsInstance) { + this.subtitleSettingsInstance.destroy(); + this.subtitleSettingsInstance = null; + } + } - if (subtitleSettingsInstance) { - subtitleSettingsInstance.loadData(); - } else { - subtitleSettingsInstance = new SubtitleSettings.default({ - serverId: ApiClient.serverId(), - userId: userId, - element: view.querySelector(".settingsContainer"), - userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, - autoFocus: autoFocuser.isEnabled() - }); - } - }); - view.addEventListener("change", function () { - hasChanges = true; - }); - view.addEventListener("viewbeforehide", function () { - hasChanges = false; + viewBeforeHide() { + this.hasChanges = false; - if (subtitleSettingsInstance) { - subtitleSettingsInstance.submit(); - } - }); - view.addEventListener("viewdestroy", function () { - if (subtitleSettingsInstance) { - subtitleSettingsInstance.destroy(); - subtitleSettingsInstance = null; - } - }); - }; -}); + if (this.subtitleSettingsInstance) { + this.subtitleSettingsInstance.submit(); + } + } + + change() { + this.hasChanges = true; + } + + beforeUnload(e) { + if (this.hasChanges) { + e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?"; + } + } +} + +export default SubtitleController; diff --git a/src/scripts/site.js b/src/scripts/site.js index 5ce093e62..37832af5c 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -831,6 +831,7 @@ var AppInfo = {}; define("upNextDialog", [componentsPath + "/upnextdialog/upnextdialog"], returnFirstDependency); define("subtitleAppearanceHelper", [componentsPath + "/subtitlesettings/subtitleappearancehelper"], returnFirstDependency); define("subtitleSettings", [componentsPath + "/subtitlesettings/subtitlesettings"], returnFirstDependency); + define("settingsHelper", [componentsPath + "/settingshelper"], returnFirstDependency); define("displaySettings", [componentsPath + "/displaysettings/displaysettings"], returnFirstDependency); define("playbackSettings", [componentsPath + "/playbacksettings/playbacksettings"], returnFirstDependency); define("homescreenSettings", [componentsPath + "/homescreensettings/homescreensettings"], returnFirstDependency); From e5bf9bc074d59af7b5e76c734e0af1c6741add52 Mon Sep 17 00:00:00 2001 From: Christoph Potas Date: Sat, 9 May 2020 01:53:13 +0200 Subject: [PATCH 0004/1168] + add controller to es6 module list Signed-off-by: Christoph Potas --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index c11b6db91..4d3d3047b 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "src/components/subtitlesettings/subtitlesettings.js", "src/components/subtitlesettings/subtitleappearancehelper.js", "src/components/settingshelper.js", + "src/controllers/user/subtitles.js", "src/scripts/dom.js", "src/components/filedownloader.js", "src/scripts/filesystem.js", From 9469c208e19f34b97fda261ca58e7201c1359aed Mon Sep 17 00:00:00 2001 From: Christoph Potas Date: Sat, 9 May 2020 15:42:37 +0200 Subject: [PATCH 0005/1168] ~ switch all strings to single quotes to match ESLint requirements Signed-off-by: Christoph Potas --- src/components/settingshelper.js | 6 +++--- src/controllers/user/subtitles.js | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/settingshelper.js b/src/components/settingshelper.js index 0c942ed04..3bbff9d8e 100644 --- a/src/components/settingshelper.js +++ b/src/components/settingshelper.js @@ -5,15 +5,15 @@ import globalize from 'globalize'; */ export function populateLanguages(select, languages) { - let html = ""; + let html = ''; - html += ""; + html += "'; for (let i = 0, length = languages.length; i < length; i++) { const culture = languages[i]; - html += ""; + html += "'; } select.innerHTML = html; diff --git a/src/controllers/user/subtitles.js b/src/controllers/user/subtitles.js index f1efe0c21..e88109cc6 100644 --- a/src/controllers/user/subtitles.js +++ b/src/controllers/user/subtitles.js @@ -10,14 +10,14 @@ export class SubtitleController { this.subtitleSettingsInstance = null; this.view = view; - view.addEventListener("viewshow", this.viewShow.bind(this)); - view.addEventListener("change", this.change.bind(this)); - view.addEventListener("viewbeforehide", this.viewBeforeHide.bind(this)); - view.addEventListener("viewdestroy", this.viewDestroy.bind(this)); + view.addEventListener('viewshow', this.viewShow.bind(this)); + view.addEventListener('change', this.change.bind(this)); + view.addEventListener('viewbeforehide', this.viewBeforeHide.bind(this)); + view.addEventListener('viewdestroy', this.viewDestroy.bind(this)); } viewShow() { - window.addEventListener("beforeunload", this.beforeUnload.bind(this)); + window.addEventListener('beforeunload', this.beforeUnload.bind(this)); if (this.subtitleSettingsInstance) { this.subtitleSettingsInstance.loadData(); @@ -25,7 +25,7 @@ export class SubtitleController { this.subtitleSettingsInstance = new subtitleSettings({ serverId: ApiClient.serverId(), userId: this.userId, - element: this.view.querySelector(".settingsContainer"), + element: this.view.querySelector('.settingsContainer'), userSettings: this.currentSettings, enableSaveButton: false, enableSaveConfirmation: false, @@ -55,7 +55,7 @@ export class SubtitleController { beforeUnload(e) { if (this.hasChanges) { - e.returnValue = "You currently have unsaved changes. Are you sure you wish to leave?"; + e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; } } } From 7e7613d5de732bc5b59164613252b680895fba77 Mon Sep 17 00:00:00 2001 From: Guilherme Danno Date: Fri, 8 May 2020 19:06:44 -0300 Subject: [PATCH 0006/1168] Update CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 2eae7e693..65bb24e9f 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 0007/1168] 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 000000000..ed23ab083 --- /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 2ea2132740238f79136e7e398d78a9d25329c9fa Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Fri, 29 May 2020 23:32:45 +0200 Subject: [PATCH 0008/1168] Add barebones comic book reader --- package.json | 2 + src/bundle.js | 6 + src/components/comicsPlayer/plugin.js | 215 +++++++++++++++++++++ src/components/playback/playbackmanager.js | 6 +- src/components/pluginManager.js | 2 +- src/scripts/site.js | 4 +- webpack.common.js | 18 +- yarn.lock | 5 + 8 files changed, 252 insertions(+), 6 deletions(-) create mode 100644 src/components/comicsPlayer/plugin.js diff --git a/package.json b/package.json index 749c62d39..aefec20d7 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto", "jquery": "^3.5.1", "jstree": "^3.3.7", + "libarchive.js": "^1.3.0", "libass-wasm": "https://github.com/jellyfin/JavascriptSubtitlesOctopus#4.0.0-jf-smarttv", "material-design-icons-iconfont": "^5.0.1", "native-promise-only": "^0.8.0-a", @@ -92,6 +93,7 @@ "src/components/autoFocuser.js", "src/components/cardbuilder/cardBuilder.js", "src/scripts/fileDownloader.js", + "src/components/comicsPlayer/plugin.js", "src/components/images/imageLoader.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", "src/components/playback/mediasession.js", diff --git a/src/bundle.js b/src/bundle.js index d7ba6c6a5..fd9099aaf 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -176,3 +176,9 @@ _define('connectionManagerFactory', function () { _define('appStorage', function () { return apiclient.AppStorage; }); + +// libarchive.js +var libarchive = require('libarchive.js'); +_define('libarchive', function () { + return libarchive; +}); diff --git a/src/components/comicsPlayer/plugin.js b/src/components/comicsPlayer/plugin.js new file mode 100644 index 000000000..43469bfed --- /dev/null +++ b/src/components/comicsPlayer/plugin.js @@ -0,0 +1,215 @@ +import connectionManager from 'connectionManager'; +import loading from 'loading'; +import dialogHelper from 'dialogHelper'; +import keyboardnavigation from 'keyboardnavigation'; +import appRouter from 'appRouter'; +import 'css!../slideshow/style'; +import * as libarchive from 'libarchive'; + +export class ComicsPlayer { + constructor() { + this.name = 'Comics Player'; + this.type = 'mediaplayer'; + this.id = 'comicsplayer'; + this.priority = 1; + this.imageMap = new Map(); + + this.onDialogClosed = this.onDialogClosed.bind(this); + this.onWindowKeyUp = this.onWindowKeyUp.bind(this); + } + + play(options) { + this._progress = 0; + + let elem = this.createMediaElement(); + return this.setCurrentSrc(elem, options); + } + + stop() { + this.unbindEvents(); + + let elem = this._mediaElement; + + if (elem) { + dialogHelper.close(elem); + this._mediaElement = null; + } + + // Hide loader in case player was not fully loaded yet + loading.hide(); + } + + onDialogClosed() { + this.stop(); + } + + onWindowKeyUp(e) { + let key = keyboardnavigation.getKeyName(e); + switch (key) { + case 'Escape': + this.stop(); + break; + } + } + + bindEvents() { + document.addEventListener('keyup', this.onWindowKeyUp); + } + + unbindEvents() { + document.removeEventListener('keyup', this.onWindowKeyUp); + } + + createMediaElement() { + let elem = this._mediaElement; + + if (elem) { + return elem; + } + + elem = document.getElementById('comicsPlayer'); + if (!elem) { + elem = dialogHelper.createDialog({ + exitAnimationDuration: 400, + size: 'fullscreen', + autoFocus: false, + scrollY: false, + exitAnimation: 'fadeout', + removeOnClose: true + }); + elem.id = 'bookPlayer'; + + elem.classList.add('slideshowDialog'); + + elem.innerHTML = '
'; + + this.bindEvents(); + + dialogHelper.open(elem); + } + + this._mediaElement = elem; + + return elem; + } + + setCurrentSrc(elem, options) { + let item = options.items[0]; + this._currentItem = item; + + loading.show(); + + let serverId = item.ServerId; + let apiClient = connectionManager.getApiClient(serverId); + + libarchive.Archive.init({ + workerUrl: appRouter.baseUrl() + '/libraries/worker-bundle.js' + }); + + return new Promise((resolve, reject) => { + let downloadUrl = apiClient.getItemDownloadUrl(item.Id); + const archiveSource = new ArchiveSource(downloadUrl); + var instance = this; + import('swiper').then(({default: Swiper}) => { + archiveSource.load().then(() => { + loading.hide(); + this.swiperInstance = new Swiper(elem.querySelector('.slideshowSwiperContainer'), { + direction: 'horizontal', + // Loop is disabled due to the virtual slides option not supporting it. + loop: false, + zoom: { + minRatio: 1, + toggle: true, + containerClass: 'slider-zoom-container' + }, + autoplay: false, + keyboard: { + enabled: true + }, + preloadImages: true, + slidesPerView: 1, + slidesPerColumn: 1, + initialSlide: 0, + // Virtual slides reduce memory consumption for large libraries while allowing preloading of images; + virtual: { + slides: archiveSource.urls, + cache: true, + renderSlide: instance.getImgFromUrl, + addSlidesBefore: 1, + addSlidesAfter: 1 + } + }); + }); + }); + }); + } + + getImgFromUrl(url) { + return `
+
+ +
+
`; + } + + canPlayMediaType(mediaType) { + return (mediaType || '').toLowerCase() === 'book'; + } + + canPlayItem(item) { + if (item.Path && (item.Path.endsWith('cbz') || item.Path.endsWith('cbr'))) { + return true; + } + return false; + } +} + +class ArchiveSource { + constructor(url) { + this.url = url; + this.files = []; + this.urls = []; + this.loadPromise = this.load(); + this.itemsLoaded = 0; + } + + async load() { + let res = await fetch(this.url); + if (!res.ok) { + return; + } + let blob = await res.blob(); + this.archive = await libarchive.Archive.open(blob); + this.raw = await this.archive.getFilesArray(); + this.numberOfFiles = this.raw.length; + await this.archive.extractFiles(); + + let files = await this.archive.getFilesArray(); + files.sort((a, b) => { + if (a.file.name < b.file.name) + return -1; + else + return 1; + }); + + for (let file of files) { + let url = URL.createObjectURL(file.file); + this.urls.push(url); + } + } + + getLength() { + return this.raw.length; + } + + async item(index) { + if (this.urls[index]) { + return this.urls[index]; + } + + await this.loadPromise; + return this.urls[index]; + } +} + +export default ComicsPlayer; diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 59108cf72..053088ef2 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -2187,7 +2187,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla // Only used internally self.getCurrentTicks = getCurrentTicks; - function playPhotos(items, options, user) { + function playOther(items, options, user) { var playStartIndex = options.startIndex || 0; var player = getPlayer(items[playStartIndex], options); @@ -2216,9 +2216,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return Promise.reject(); } - if (firstItem.MediaType === 'Photo') { + if (firstItem.MediaType === 'Photo' || firstItem.MediaType === 'Book') { - return playPhotos(items, options, user); + return playOther(items, options, user); } var apiClient = connectionManager.getApiClient(firstItem.ServerId); diff --git a/src/components/pluginManager.js b/src/components/pluginManager.js index 6cb56d767..fd35d344b 100644 --- a/src/components/pluginManager.js +++ b/src/components/pluginManager.js @@ -58,7 +58,7 @@ define(['events', 'globalize'], function (events, globalize) { return new Promise(function (resolve, reject) { require([pluginSpec], (pluginFactory) => { - var plugin = new pluginFactory(); + var plugin = pluginFactory.default ? new pluginFactory.default() : new pluginFactory(); // See if it's already installed var existing = instance.pluginsList.filter(function (p) { diff --git a/src/scripts/site.js b/src/scripts/site.js index aeb651d88..2e83928f9 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -490,6 +490,7 @@ var AppInfo = {}; 'components/playback/experimentalwarnings', 'components/htmlAudioPlayer/plugin', 'components/htmlVideoPlayer/plugin', + 'components/comicsPlayer/plugin', 'components/photoPlayer/plugin', 'components/youtubeplayer/plugin', 'components/backdropScreensaver/plugin', @@ -701,7 +702,8 @@ var AppInfo = {}; 'events', 'credentialprovider', 'connectionManagerFactory', - 'appStorage' + 'appStorage', + 'comicReader' ] }, urlArgs: urlArgs, diff --git a/webpack.common.js b/webpack.common.js index 03beb63a7..2cc8478d8 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -1,10 +1,12 @@ const path = require('path'); const CopyPlugin = require('copy-webpack-plugin'); +const WorkerPlugin = require('worker-plugin'); const Assets = [ 'alameda/alameda.js', 'native-promise-only/npo.js', + 'libarchive.js/dist/worker-bundle.js', 'libass-wasm/dist/js/subtitles-octopus-worker.js', 'libass-wasm/dist/js/subtitles-octopus-worker.data', 'libass-wasm/dist/js/subtitles-octopus-worker.wasm', @@ -13,6 +15,11 @@ const Assets = [ 'libass-wasm/dist/js/subtitles-octopus-worker-legacy.js.mem' ]; +const LibarchiveWasm = [ + 'libarchive.js/dist/wasm-gen/libarchive.js', + 'libarchive.js/dist/wasm-gen/libarchive.wasm' +]; + module.exports = { context: path.resolve(__dirname, 'src'), entry: './bundle.js', @@ -34,6 +41,15 @@ module.exports = { to: path.resolve(__dirname, './dist/libraries') }; }) - ) + ), + new CopyPlugin( + LibarchiveWasm.map(asset => { + return { + from: path.resolve(__dirname, `./node_modules/${asset}`), + to: path.resolve(__dirname, './dist/libraries/wasm-gen/') + }; + }) + ), + new WorkerPlugin() ] }; diff --git a/yarn.lock b/yarn.lock index 20fdef5de..5b8df85f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6783,6 +6783,11 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +libarchive.js@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/libarchive.js/-/libarchive.js-1.3.0.tgz#18c42c6b4ce727a02359c90769e4e454cf3743cd" + integrity sha512-EkQfRXt9DhWwj6BnEA2TNpOf4jTnzSTUPGgE+iFxcdNqjktY8GitbDeHnx8qZA0/IukNyyBUR3oQKRdYkO+HFg== + "libass-wasm@https://github.com/jellyfin/JavascriptSubtitlesOctopus#4.0.0-jf-smarttv": version "4.0.0" resolved "https://github.com/jellyfin/JavascriptSubtitlesOctopus#58e9a3f1a7f7883556ee002545f445a430120639" From 8b96577fba91f5535a7bde1f9727cc51581ce3a4 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Tue, 9 Jun 2020 22:14:24 +0300 Subject: [PATCH 0009/1168] Migration shortcuts to ES6 modules --- package.json | 1 + src/components/shortcuts.js | 149 +++++++++++++++++++----------------- 2 files changed, 81 insertions(+), 69 deletions(-) diff --git a/package.json b/package.json index 785878d20..b60e24ad1 100644 --- a/package.json +++ b/package.json @@ -104,6 +104,7 @@ "src/components/syncplay/playbackPermissionManager.js", "src/components/syncplay/syncPlayManager.js", "src/components/syncplay/timeSyncManager.js", + "src/components/shortcuts.js", "src/plugins/bookPlayer/plugin.js", "src/plugins/bookPlayer/tableOfContent.js", "src/plugins/photoPlayer/plugin.js", diff --git a/src/components/shortcuts.js b/src/components/shortcuts.js index ab606ab1d..83a4dfc31 100644 --- a/src/components/shortcuts.js +++ b/src/components/shortcuts.js @@ -1,18 +1,30 @@ -define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'globalize', 'loading', 'dom', 'recordingHelper'], function (playbackManager, inputManager, connectionManager, appRouter, globalize, loading, dom, recordingHelper) { - 'use strict'; +/* eslint-disable indent */ + +/** + * Module shortcuts. + * @module components/shortcuts + */ + +import playbackManager from 'playbackManager'; +import inputManager from 'inputManager'; +import connectionManager from 'connectionManager'; +import appRouter from 'appRouter'; +import globalize from 'globalize'; +import dom from 'dom'; +import recordingHelper from 'recordingHelper'; function playAllFromHere(card, serverId, queue) { - var parent = card.parentNode; - var className = card.classList.length ? ('.' + card.classList[0]) : ''; - var cards = parent.querySelectorAll(className + '[data-id]'); + const parent = card.parentNode; + const className = card.classList.length ? (`.${card.classList[0]}`) : ''; + const cards = parent.querySelectorAll(`${className}[data-id]`); - var ids = []; + const ids = []; - var foundCard = false; - var startIndex; + let foundCard = false; + let startIndex; - for (var i = 0, length = cards.length; i < length; i++) { + for (let i = 0, length = cards.length; i < length; i++) { if (cards[i] === card) { foundCard = true; startIndex = i; @@ -22,12 +34,12 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl } } - var itemsContainer = dom.parentWithClass(card, 'itemsContainer'); + const itemsContainer = dom.parentWithClass(card, 'itemsContainer'); if (itemsContainer && itemsContainer.fetchData) { - var queryOptions = queue ? { StartIndex: startIndex } : {}; + const queryOptions = queue ? { StartIndex: startIndex } : {}; - return itemsContainer.fetchData(queryOptions).then(function (result) { + return itemsContainer.fetchData(queryOptions).then(result => { if (queue) { return playbackManager.queue({ @@ -64,7 +76,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl function showProgramDialog(item) { - require(['recordingCreator'], function (recordingCreator) { + import('recordingCreator').then((recordingCreator) => { recordingCreator.show(item.Id, item.ServerId); }); @@ -73,11 +85,11 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl function getItem(button) { button = dom.parentWithAttribute(button, 'data-id'); - var serverId = button.getAttribute('data-serverid'); - var id = button.getAttribute('data-id'); - var type = button.getAttribute('data-type'); + const serverId = button.getAttribute('data-serverid'); + const id = button.getAttribute('data-id'); + const type = button.getAttribute('data-type'); - var apiClient = connectionManager.getApiClient(serverId); + const apiClient = connectionManager.getApiClient(serverId); if (type === 'Timer') { return apiClient.getLiveTvTimer(id); @@ -99,19 +111,19 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl function showContextMenu(card, options) { - getItem(card).then(function (item) { + getItem(card).then(item => { - var playlistId = card.getAttribute('data-playlistid'); - var collectionId = card.getAttribute('data-collectionid'); + const playlistId = card.getAttribute('data-playlistid'); + const collectionId = card.getAttribute('data-collectionid'); if (playlistId) { - var elem = dom.parentWithAttribute(card, 'data-playlistitemid'); + const elem = dom.parentWithAttribute(card, 'data-playlistitemid'); item.PlaylistItemId = elem ? elem.getAttribute('data-playlistitemid') : null; } - require(['itemContextMenu'], function (itemContextMenu) { + import('itemContextMenu').then((itemContextMenu) => { - connectionManager.getApiClient(item.ServerId).getCurrentUser().then(function (user) { + connectionManager.getApiClient(item.ServerId).getCurrentUser().then(user => { itemContextMenu.show(Object.assign({ item: item, play: true, @@ -122,9 +134,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl collectionId: collectionId, user: user - }, options || {})).then(function (result) { - - var itemsContainer; + }, options || {})).then(result => { if (result.command === 'playallfromhere' || result.command === 'queueallfromhere') { executeAction(card, options.positionTo, result.command); @@ -157,9 +167,9 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl function showPlayMenu(card, target) { - var item = getItemInfoFromCard(card); + const item = getItemInfoFromCard(card); - require(['playMenu'], function (playMenu) { + import('playMenu').then((playMenu) => { playMenu.show({ @@ -170,7 +180,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl } function sendToast(text) { - require(['toast'], function (toast) { + import('toast').then((toast) => { toast(text); }); } @@ -179,19 +189,19 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl target = target || card; - var id = card.getAttribute('data-id'); + let id = card.getAttribute('data-id'); if (!id) { card = dom.parentWithAttribute(card, 'data-id'); id = card.getAttribute('data-id'); } - var item = getItemInfoFromCard(card); + const item = getItemInfoFromCard(card); - var serverId = item.ServerId; - var type = item.Type; + const serverId = item.ServerId; + const type = item.Type; - var playableItemId = type === 'Program' ? item.ChannelId : item.Id; + const playableItemId = type === 'Program' ? item.ChannelId : item.Id; if (item.MediaType === 'Photo' && action === 'link') { action = 'play'; @@ -213,7 +223,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl }); } else if (action === 'play' || action === 'resume') { - var startPositionTicks = parseInt(card.getAttribute('data-positionticks') || '0'); + const startPositionTicks = parseInt(card.getAttribute('data-positionticks') || '0'); playbackManager.play({ ids: [playableItemId], @@ -244,7 +254,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl onRecordCommand(serverId, id, type, card.getAttribute('data-timerid'), card.getAttribute('data-seriestimerid')); } else if (action === 'menu') { - var options = target.getAttribute('data-playoptions') === 'false' ? + const options = target.getAttribute('data-playoptions') === 'false' ? { shuffle: false, instantMix: false, @@ -261,7 +271,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl } else if (action === 'playmenu') { showPlayMenu(card, target); } else if (action === 'edit') { - getItem(target).then(function (item) { + getItem(target).then(item => { editItem(item, serverId); }); } else if (action === 'playtrailer') { @@ -270,9 +280,9 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl getItem(target).then(addToPlaylist); } else if (action === 'custom') { - var customAction = target.getAttribute('data-customaction'); + const customAction = target.getAttribute('data-customaction'); - card.dispatchEvent(new CustomEvent('action-' + customAction, { + card.dispatchEvent(new CustomEvent(`action-${customAction}`, { detail: { playlistItemId: card.getAttribute('data-playlistitemid') }, @@ -283,7 +293,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl } function addToPlaylist(item) { - require(['playlistEditor'], function (playlistEditor) { + import('playlistEditor').then((playlistEditor) => { new playlistEditor().show({ items: [item.Id], @@ -295,35 +305,35 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl function playTrailer(item) { - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); - apiClient.getLocalTrailers(apiClient.getCurrentUserId(), item.Id).then(function (trailers) { + apiClient.getLocalTrailers(apiClient.getCurrentUserId(), item.Id).then(trailers => { playbackManager.play({ items: trailers }); }); } function editItem(item, serverId) { - var apiClient = connectionManager.getApiClient(serverId); + const apiClient = connectionManager.getApiClient(serverId); - return new Promise(function (resolve, reject) { + return new Promise((resolve, reject) => { - var serverId = apiClient.serverInfo().Id; + const serverId = apiClient.serverInfo().Id; if (item.Type === 'Timer') { if (item.ProgramId) { - require(['recordingCreator'], function (recordingCreator) { + import('recordingCreator').then((recordingCreator) => { recordingCreator.show(item.ProgramId, serverId).then(resolve, reject); }); } else { - require(['recordingEditor'], function (recordingEditor) { + import('recordingEditor').then((recordingEditor) => { recordingEditor.show(item.Id, serverId).then(resolve, reject); }); } } else { - require(['metadataEditor'], function (metadataEditor) { + import('metadataEditor').then((metadataEditor) => { metadataEditor.show(item.Id, serverId).then(resolve, reject); }); @@ -335,19 +345,19 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl if (type === 'Program' || timerId || seriesTimerId) { - var programId = type === 'Program' ? id : null; + const programId = type === 'Program' ? id : null; recordingHelper.toggleRecording(serverId, programId, timerId, seriesTimerId); } } - function onClick(e) { + export function onClick(e) { - var card = dom.parentWithClass(e.target, 'itemAction'); + const card = dom.parentWithClass(e.target, 'itemAction'); if (card) { - var actionElement = card; - var action = actionElement.getAttribute('data-action'); + let actionElement = card; + let action = actionElement.getAttribute('data-action'); if (!action) { actionElement = dom.parentWithAttribute(actionElement, 'data-action'); @@ -368,12 +378,12 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl function onCommand(e) { - var cmd = e.detail.command; + const cmd = e.detail.command; if (cmd === 'play' || cmd === 'resume' || cmd === 'record' || cmd === 'menu' || cmd === 'info') { - var target = e.target; - var card = dom.parentWithClass(target, 'itemAction') || dom.parentWithAttribute(target, 'data-id'); + const target = e.target; + const card = dom.parentWithClass(target, 'itemAction') || dom.parentWithAttribute(target, 'data-id'); if (card) { e.preventDefault(); @@ -383,7 +393,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl } } - function on(context, options) { + export function on(context, options) { options = options || {}; @@ -396,7 +406,7 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl } } - function off(context, options) { + export function off(context, options) { options = options || {}; context.removeEventListener('click', onClick); @@ -406,23 +416,24 @@ define(['playbackManager', 'inputManager', 'connectionManager', 'appRouter', 'gl } } - function getShortcutAttributesHtml(item, serverId) { + export function getShortcutAttributesHtml(item, serverId) { - var html = 'data-id="' + item.Id + '" data-serverid="' + (serverId || item.ServerId) + '" data-type="' + item.Type + '" data-mediatype="' + item.MediaType + '" data-channelid="' + item.ChannelId + '" data-isfolder="' + item.IsFolder + '"'; + let html = `data-id="${item.Id}" data-serverid="${serverId || item.ServerId}" data-type="${item.Type}" data-mediatype="${item.MediaType}" data-channelid="${item.ChannelId}" data-isfolder="${item.IsFolder}"`; - var collectionType = item.CollectionType; + const collectionType = item.CollectionType; if (collectionType) { - html += ' data-collectiontype="' + collectionType + '"'; + html += ` data-collectiontype="${collectionType}"`; } return html; } - return { - on: on, - off: off, - onClick: onClick, - getShortcutAttributesHtml: getShortcutAttributesHtml - }; +/* eslint-enable indent */ + +export default { + on: on, + off: off, + onClick: onClick, + getShortcutAttributesHtml: getShortcutAttributesHtml +}; -}); From eff468dc82b98e7c8bdf0db853ed1926c0783ed9 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Tue, 9 Jun 2020 22:28:08 +0300 Subject: [PATCH 0010/1168] Migration imageOptionsEditor and libraryoptionseditor to es6 --- package.json | 2 + .../imageOptionsEditor/imageOptionsEditor.js | 66 ++-- .../libraryoptionseditor.js | 307 +++++++++--------- 3 files changed, 196 insertions(+), 179 deletions(-) diff --git a/package.json b/package.json index d9b2ed761..fdeacda2f 100644 --- a/package.json +++ b/package.json @@ -93,8 +93,10 @@ "src/components/actionSheet/actionSheet.js", "src/components/autoFocuser.js", "src/components/cardbuilder/cardBuilder.js", + "src/components/imageOptionsEditor/imageOptionsEditor.js", "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", + "src/components/libraryoptionseditor/libraryoptionseditor.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", "src/components/playback/brightnessosd.js", "src/components/playback/mediasession.js", diff --git a/src/components/imageOptionsEditor/imageOptionsEditor.js b/src/components/imageOptionsEditor/imageOptionsEditor.js index 257921dfa..5e4f88f15 100644 --- a/src/components/imageOptionsEditor/imageOptionsEditor.js +++ b/src/components/imageOptionsEditor/imageOptionsEditor.js @@ -1,5 +1,16 @@ -define(['globalize', 'dom', 'dialogHelper', 'emby-checkbox', 'emby-select', 'emby-input'], function (globalize, dom, dialogHelper) { - 'use strict'; +/* eslint-disable indent */ + +/** + * Module for image Options Editor. + * @module components/imageOptionsEditor/imageOptionsEditor + */ + +import globalize from 'globalize'; +import dom from 'dom'; +import dialogHelper from 'dialogHelper'; +import 'emby-checkbox'; +import 'emby-select'; +import 'emby-input'; function getDefaultImageConfig(itemType, type) { return { @@ -10,7 +21,7 @@ define(['globalize', 'dom', 'dialogHelper', 'emby-checkbox', 'emby-select', 'emb } function findImageOptions(imageOptions, type) { - return imageOptions.filter(function (i) { + return imageOptions.filter(i => { return i.Type == type; })[0]; } @@ -31,14 +42,14 @@ define(['globalize', 'dom', 'dialogHelper', 'emby-checkbox', 'emby-select', 'emb } function loadValues(context, itemType, options, availableOptions) { - var supportedImageTypes = availableOptions.SupportedImageTypes || []; - setVisibilityOfBackdrops(context.querySelector('.backdropFields'), -1 != supportedImageTypes.indexOf('Backdrop')); - setVisibilityOfBackdrops(context.querySelector('.screenshotFields'), -1 != supportedImageTypes.indexOf('Screenshot')); - Array.prototype.forEach.call(context.querySelectorAll('.imageType'), function (i) { - var imageType = i.getAttribute('data-imagetype'); - var container = dom.parentWithTag(i, 'LABEL'); + const supportedImageTypes = availableOptions.SupportedImageTypes || []; + setVisibilityOfBackdrops(context.querySelector('.backdropFields'), supportedImageTypes.includes('Backdrop')); + setVisibilityOfBackdrops(context.querySelector('.screenshotFields'), supportedImageTypes.includes('Screenshot')); + Array.prototype.forEach.call(context.querySelectorAll('.imageType'), i => { + const imageType = i.getAttribute('data-imagetype'); + const container = dom.parentWithTag(i, 'LABEL'); - if (-1 == supportedImageTypes.indexOf(imageType)) { + if (!supportedImageTypes.includes(imageType)) { container.classList.add('hide'); } else { container.classList.remove('hide'); @@ -50,16 +61,16 @@ define(['globalize', 'dom', 'dialogHelper', 'emby-checkbox', 'emby-select', 'emb i.checked = false; } }); - var backdropConfig = getImageConfig(options, availableOptions, 'Backdrop', itemType); + const backdropConfig = getImageConfig(options, availableOptions, 'Backdrop', itemType); context.querySelector('#txtMaxBackdrops').value = backdropConfig.Limit; context.querySelector('#txtMinBackdropDownloadWidth').value = backdropConfig.MinWidth; - var screenshotConfig = getImageConfig(options, availableOptions, 'Screenshot', itemType); + const screenshotConfig = getImageConfig(options, availableOptions, 'Screenshot', itemType); context.querySelector('#txtMaxScreenshots').value = screenshotConfig.Limit; context.querySelector('#txtMinScreenshotDownloadWidth').value = screenshotConfig.MinWidth; } function saveValues(context, options) { - options.ImageOptions = Array.prototype.map.call(context.querySelectorAll('.imageType:not(.hide)'), function (c) { + options.ImageOptions = Array.prototype.map.call(context.querySelectorAll('.imageType:not(.hide)'), c => { return { Type: c.getAttribute('data-imagetype'), Limit: c.checked ? 1 : 0, @@ -78,35 +89,32 @@ define(['globalize', 'dom', 'dialogHelper', 'emby-checkbox', 'emby-select', 'emb }); } - function editor() { - this.show = function (itemType, options, availableOptions) { - return new Promise(function (resolve, reject) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', 'components/imageOptionsEditor/imageOptionsEditor.template.html', true); - - xhr.onload = function (e) { - var template = this.response; - var dlg = dialogHelper.createDialog({ +export class editor { + constructor() { + this.show = (itemType, options, availableOptions) => { + return new Promise((resolve) => { + //TODO: remove require + require(['text!./components/imageOptionsEditor/imageOptionsEditor.template.html'], template => { + const dlg = dialogHelper.createDialog({ size: 'small', removeOnClose: true, scrollY: false }); dlg.classList.add('formDialog'); dlg.innerHTML = globalize.translateDocument(template); - dlg.addEventListener('close', function () { + dlg.addEventListener('close', () => { saveValues(dlg, options); }); loadValues(dlg, itemType, options, availableOptions); dialogHelper.open(dlg).then(resolve, resolve); - dlg.querySelector('.btnCancel').addEventListener('click', function () { + dlg.querySelector('.btnCancel').addEventListener('click', () => { dialogHelper.close(dlg); }); - }; - - xhr.send(); + }); }); }; } +} - return editor; -}); +/* eslint-enable indent */ +export default editor; diff --git a/src/components/libraryoptionseditor/libraryoptionseditor.js b/src/components/libraryoptionseditor/libraryoptionseditor.js index 832a6ffc5..f9a9d4327 100644 --- a/src/components/libraryoptionseditor/libraryoptionseditor.js +++ b/src/components/libraryoptionseditor/libraryoptionseditor.js @@ -1,63 +1,73 @@ -define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], function(globalize, dom) { - 'use strict'; +/* eslint-disable indent */ + +/** + * Module for library options editor. + * @module components/libraryoptionseditor/libraryoptionseditor + */ + +import globalize from 'globalize'; +import dom from 'dom'; +import 'emby-checkbox'; +import 'emby-select'; +import 'emby-input'; function populateLanguages(parent) { - return ApiClient.getCultures().then(function(languages) { + return ApiClient.getCultures().then(languages => { populateLanguagesIntoSelect(parent.querySelector('#selectLanguage'), languages); populateLanguagesIntoList(parent.querySelector('.subtitleDownloadLanguages'), languages); }); } function populateLanguagesIntoSelect(select, languages) { - var html = ''; + let html = ''; html += ""; - for (var i = 0; i < languages.length; i++) { - var culture = languages[i]; - html += "'; + for (let i = 0; i < languages.length; i++) { + const culture = languages[i]; + html += ``; } select.innerHTML = html; } function populateLanguagesIntoList(element, languages) { - var html = ''; - for (var i = 0; i < languages.length; i++) { - var culture = languages[i]; - html += ''; + let html = ''; + for (let i = 0; i < languages.length; i++) { + const culture = languages[i]; + html += ``; } element.innerHTML = html; } function populateCountries(select) { - return ApiClient.getCountries().then(function(allCountries) { - var html = ''; + return ApiClient.getCountries().then(allCountries => { + let html = ''; html += ""; - for (var i = 0; i < allCountries.length; i++) { - var culture = allCountries[i]; - html += "'; + for (let i = 0; i < allCountries.length; i++) { + const culture = allCountries[i]; + html += ``; } select.innerHTML = html; }); } function populateRefreshInterval(select) { - var html = ''; - html += "'; - html += [30, 60, 90].map(function(val) { - return "'; + let html = ''; + html += ``; + html += [30, 60, 90].map(val => { + return ``; }).join(''); select.innerHTML = html; } function renderMetadataReaders(page, plugins) { - var html = ''; - var elem = page.querySelector('.metadataReaders'); + let html = ''; + const elem = page.querySelector('.metadataReaders'); if (plugins.length < 1) return elem.innerHTML = '', elem.classList.add('hide'), !1; - html += '

' + globalize.translate('LabelMetadataReaders') + '

'; + html += `

${globalize.translate('LabelMetadataReaders')}

`; html += '
'; - for (var i = 0; i < plugins.length; i++) { - var plugin = plugins[i]; - html += '
'; + for (let i = 0; i < plugins.length; i++) { + const plugin = plugins[i]; + html += `
`; html += ''; html += '
'; html += '

'; @@ -65,14 +75,14 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct html += '

'; html += '
'; if (i > 0) { - html += ''; + html += ``; } else if (plugins.length > 1) { - html += ''; + html += ``; } html += '
'; } html += '
'; - html += '
' + globalize.translate('LabelMetadataReadersHelp') + '
'; + html += `
${globalize.translate('LabelMetadataReadersHelp')}
`; if (plugins.length < 2) { elem.classList.add('hide'); } else { @@ -83,25 +93,25 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct } function renderMetadataSavers(page, metadataSavers) { - var html = ''; - var elem = page.querySelector('.metadataSavers'); + let html = ''; + const elem = page.querySelector('.metadataSavers'); if (!metadataSavers.length) return elem.innerHTML = '', elem.classList.add('hide'), false; - html += '

' + globalize.translate('LabelMetadataSavers') + '

'; + html += `

${globalize.translate('LabelMetadataSavers')}

`; html += '
'; - for (var i = 0; i < metadataSavers.length; i++) { - var plugin = metadataSavers[i]; - html += ''; + for (let i = 0; i < metadataSavers.length; i++) { + const plugin = metadataSavers[i]; + html += ``; } html += '
'; - html += '
' + globalize.translate('LabelMetadataSaversHelp') + '
'; + html += `
${globalize.translate('LabelMetadataSaversHelp')}
`; elem.innerHTML = html; elem.classList.remove('hide'); return true; } function getMetadataFetchersForTypeHtml(availableTypeOptions, libraryOptionsForType) { - var html = ''; - var plugins = availableTypeOptions.MetadataFetchers; + let html = ''; + let plugins = availableTypeOptions.MetadataFetchers; plugins = getOrderedPlugins(plugins, libraryOptionsForType.MetadataFetcherOrder || []); if (!plugins.length) return html; @@ -112,8 +122,8 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct plugins.forEach((plugin, index) => { html += '
'; - var isChecked = libraryOptionsForType.MetadataFetchers ? -1 !== libraryOptionsForType.MetadataFetchers.indexOf(plugin.Name) : plugin.DefaultEnabled; - var checkedHtml = isChecked ? ' checked="checked"' : ''; + const isChecked = libraryOptionsForType.MetadataFetchers ? libraryOptionsForType.MetadataFetchers.includes(plugin.Name) : plugin.DefaultEnabled; + const checkedHtml = isChecked ? ' checked="checked"' : ''; html += ''; html += '
'; html += '

'; @@ -135,19 +145,19 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct } function getTypeOptions(allOptions, type) { - var allTypeOptions = allOptions.TypeOptions || []; - for (var i = 0; i < allTypeOptions.length; i++) { - var typeOptions = allTypeOptions[i]; + const allTypeOptions = allOptions.TypeOptions || []; + for (let i = 0; i < allTypeOptions.length; i++) { + const typeOptions = allTypeOptions[i]; if (typeOptions.Type === type) return typeOptions; } return null; } function renderMetadataFetchers(page, availableOptions, libraryOptions) { - var html = ''; - var elem = page.querySelector('.metadataFetchers'); - for (var i = 0; i < availableOptions.TypeOptions.length; i++) { - var availableTypeOptions = availableOptions.TypeOptions[i]; + let html = ''; + const elem = page.querySelector('.metadataFetchers'); + for (let i = 0; i < availableOptions.TypeOptions.length; i++) { + const availableTypeOptions = availableOptions.TypeOptions[i]; html += getMetadataFetchersForTypeHtml(availableTypeOptions, getTypeOptions(libraryOptions, availableTypeOptions.Type) || {}); } elem.innerHTML = html; @@ -166,41 +176,41 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct } function renderSubtitleFetchers(page, availableOptions, libraryOptions) { - var html = ''; - var elem = page.querySelector('.subtitleFetchers'); + let html = ''; + const elem = page.querySelector('.subtitleFetchers'); - var plugins = availableOptions.SubtitleFetchers; + let plugins = availableOptions.SubtitleFetchers; plugins = getOrderedPlugins(plugins, libraryOptions.SubtitleFetcherOrder || []); if (!plugins.length) return html; - html += '

' + globalize.translate('LabelSubtitleDownloaders') + '

'; + html += `

${globalize.translate('LabelSubtitleDownloaders')}

`; html += '
'; - for (var i = 0; i < plugins.length; i++) { - var plugin = plugins[i]; - html += '
'; - var isChecked = libraryOptions.DisabledSubtitleFetchers ? -1 === libraryOptions.DisabledSubtitleFetchers.indexOf(plugin.Name) : plugin.DefaultEnabled; - var checkedHtml = isChecked ? ' checked="checked"' : ''; - html += ''; + for (let i = 0; i < plugins.length; i++) { + const plugin = plugins[i]; + html += `
`; + const isChecked = libraryOptions.DisabledSubtitleFetchers ? !libraryOptions.DisabledSubtitleFetchers.includes(plugin.Name) : plugin.DefaultEnabled; + const checkedHtml = isChecked ? ' checked="checked"' : ''; + html += ``; html += '
'; html += '

'; html += plugin.Name; html += '

'; html += '
'; if (i > 0) { - html += ''; + html += ``; } else if (plugins.length > 1) { - html += ''; + html += ``; } html += '
'; } html += '
'; - html += '
' + globalize.translate('SubtitleDownloadersHelp') + '
'; + html += `
${globalize.translate('SubtitleDownloadersHelp')}
`; elem.innerHTML = html; } function getImageFetchersForTypeHtml(availableTypeOptions, libraryOptionsForType) { - var html = ''; - var plugins = availableTypeOptions.ImageFetchers; + let html = ''; + let plugins = availableTypeOptions.ImageFetchers; plugins = getOrderedPlugins(plugins, libraryOptionsForType.ImageFetcherOrder || []); if (!plugins.length) return html; @@ -208,17 +218,17 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct html += '
'; html += '
'; html += '

' + globalize.translate('HeaderTypeImageFetchers', availableTypeOptions.Type) + '

'; - var supportedImageTypes = availableTypeOptions.SupportedImageTypes || []; + const supportedImageTypes = availableTypeOptions.SupportedImageTypes || []; if (supportedImageTypes.length > 1 || 1 === supportedImageTypes.length && 'Primary' !== supportedImageTypes[0]) { html += ''; } html += '
'; html += '
'; - for (var i = 0; i < plugins.length; i++) { - var plugin = plugins[i]; + for (let i = 0; i < plugins.length; i++) { + const plugin = plugins[i]; html += '
'; - var isChecked = libraryOptionsForType.ImageFetchers ? -1 !== libraryOptionsForType.ImageFetchers.indexOf(plugin.Name) : plugin.DefaultEnabled; - var checkedHtml = isChecked ? ' checked="checked"' : ''; + const isChecked = libraryOptionsForType.ImageFetchers ? libraryOptionsForType.ImageFetchers.includes(plugin.Name) : plugin.DefaultEnabled; + const checkedHtml = isChecked ? ' checked="checked"' : ''; html += ''; html += '
'; html += '

'; @@ -239,10 +249,10 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct } function renderImageFetchers(page, availableOptions, libraryOptions) { - var html = ''; - var elem = page.querySelector('.imageFetchers'); - for (var i = 0; i < availableOptions.TypeOptions.length; i++) { - var availableTypeOptions = availableOptions.TypeOptions[i]; + let html = ''; + const elem = page.querySelector('.imageFetchers'); + for (let i = 0; i < availableOptions.TypeOptions.length; i++) { + const availableTypeOptions = availableOptions.TypeOptions[i]; html += getImageFetchersForTypeHtml(availableTypeOptions, getTypeOptions(libraryOptions, availableTypeOptions.Type) || {}); } elem.innerHTML = html; @@ -259,11 +269,11 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct } function populateMetadataSettings(parent, contentType, isNewLibrary) { - var isNewLibrary = parent.classList.contains('newlibrary'); + isNewLibrary = parent.classList.contains('newlibrary'); return ApiClient.getJSON(ApiClient.getUrl('Libraries/AvailableOptions', { LibraryContentType: contentType, IsNewLibrary: isNewLibrary - })).then(function(availableOptions) { + })).then(availableOptions => { currentAvailableOptions = availableOptions; parent.availableOptions = availableOptions; renderMetadataSavers(parent, availableOptions.MetadataSavers); @@ -272,14 +282,14 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct renderSubtitleFetchers(parent, availableOptions, {}); renderImageFetchers(parent, availableOptions, {}); availableOptions.SubtitleFetchers.length ? parent.querySelector('.subtitleDownloadSettings').classList.remove('hide') : parent.querySelector('.subtitleDownloadSettings').classList.add('hide'); - }).catch(function() { + }).catch(() => { return Promise.resolve(); }); } function adjustSortableListElement(elem) { - var btnSortable = elem.querySelector('.btnSortable'); - var inner = btnSortable.querySelector('.material-icons'); + const btnSortable = elem.querySelector('.btnSortable'); + const inner = btnSortable.querySelector('.material-icons'); if (elem.previousSibling) { btnSortable.title = globalize.translate('ButtonUp'); btnSortable.classList.add('btnSortableMoveUp'); @@ -296,22 +306,22 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct } function showImageOptionsForType(type) { - require(['imageoptionseditor'], function(ImageOptionsEditor) { - var typeOptions = getTypeOptions(currentLibraryOptions, type); + import('imageoptionseditor').then(({default: ImageOptionsEditor}) => { + let typeOptions = getTypeOptions(currentLibraryOptions, type); if (!typeOptions) { typeOptions = { Type: type }; currentLibraryOptions.TypeOptions.push(typeOptions); } - var availableOptions = getTypeOptions(currentAvailableOptions || {}, type); - var imageOptionsEditor = new ImageOptionsEditor(); + const availableOptions = getTypeOptions(currentAvailableOptions || {}, type); + const imageOptionsEditor = new ImageOptionsEditor(); imageOptionsEditor.show(type, typeOptions, availableOptions); }); } function onImageFetchersContainerClick(e) { - var btnImageOptionsForType = dom.parentWithClass(e.target, 'btnImageOptionsForType'); + const btnImageOptionsForType = dom.parentWithClass(e.target, 'btnImageOptionsForType'); if (btnImageOptionsForType) { return void showImageOptionsForType(dom.parentWithClass(btnImageOptionsForType, 'imageFetcher').getAttribute('data-type')); } @@ -319,18 +329,18 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct } function onSortableContainerClick(e) { - var btnSortable = dom.parentWithClass(e.target, 'btnSortable'); + const btnSortable = dom.parentWithClass(e.target, 'btnSortable'); if (btnSortable) { - var li = dom.parentWithClass(btnSortable, 'sortableOption'); - var list = dom.parentWithClass(li, 'paperList'); + const li = dom.parentWithClass(btnSortable, 'sortableOption'); + const list = dom.parentWithClass(li, 'paperList'); if (btnSortable.classList.contains('btnSortableMoveDown')) { - var next = li.nextSibling; + const next = li.nextSibling; if (next) { li.parentNode.removeChild(li); next.parentNode.insertBefore(li, next.nextSibling); } } else { - var prev = li.previousSibling; + const prev = li.previousSibling; if (prev) { li.parentNode.removeChild(li); prev.parentNode.insertBefore(li, prev); @@ -347,41 +357,38 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct parent.querySelector('.imageFetchers').addEventListener('click', onImageFetchersContainerClick); } - function embed(parent, contentType, libraryOptions) { + export function embed(parent, contentType, libraryOptions) { currentLibraryOptions = { TypeOptions: [] }; currentAvailableOptions = null; - var isNewLibrary = null === libraryOptions; + const isNewLibrary = null === libraryOptions; isNewLibrary && parent.classList.add('newlibrary'); - return new Promise(function(resolve, reject) { - var xhr = new XMLHttpRequest; - xhr.open('GET', 'components/libraryoptionseditor/libraryoptionseditor.template.html', true); - xhr.onload = function(e) { - var template = this.response; + return new Promise((resolve) => { + //TODO: remove require + require(['text!./components/libraryoptionseditor/libraryoptionseditor.template.html'], function (template) { parent.innerHTML = globalize.translateDocument(template); populateRefreshInterval(parent.querySelector('#selectAutoRefreshInterval')); - var promises = [populateLanguages(parent), populateCountries(parent.querySelector('#selectCountry'))]; - Promise.all(promises).then(function() { - return setContentType(parent, contentType).then(function() { + const promises = [populateLanguages(parent), populateCountries(parent.querySelector('#selectCountry'))]; + Promise.all(promises).then(() => { + return setContentType(parent, contentType).then(() => { libraryOptions && setLibraryOptions(parent, libraryOptions); bindEvents(parent); resolve(); }); }); - }; - xhr.send(); + }); }); } - function setAdvancedVisible(parent, visible) { - var elems = parent.querySelectorAll('.advanced'); - for (var i = 0; i < elems.length; i++) { + export function setAdvancedVisible(parent, visible) { + const elems = parent.querySelectorAll('.advanced'); + for (let i = 0; i < elems.length; i++) { visible ? elems[i].classList.remove('advancedHide') : elems[i].classList.add('advancedHide'); } } - function setContentType(parent, contentType) { + export function setContentType(parent, contentType) { if (contentType === 'homevideos' || contentType === 'photos') { parent.querySelector('.chkEnablePhotosContainer').classList.remove('hide'); } else { @@ -422,47 +429,47 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct } function setSubtitleFetchersIntoOptions(parent, options) { - options.DisabledSubtitleFetchers = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkSubtitleFetcher'), function(elem) { + options.DisabledSubtitleFetchers = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkSubtitleFetcher'), elem => { return !elem.checked; - }), function(elem) { + }), elem => { return elem.getAttribute('data-pluginname'); }); - options.SubtitleFetcherOrder = Array.prototype.map.call(parent.querySelectorAll('.subtitleFetcherItem'), function(elem) { + options.SubtitleFetcherOrder = Array.prototype.map.call(parent.querySelectorAll('.subtitleFetcherItem'), elem => { return elem.getAttribute('data-pluginname'); }); } function setMetadataFetchersIntoOptions(parent, options) { - var sections = parent.querySelectorAll('.metadataFetcher'); - for (var i = 0; i < sections.length; i++) { - var section = sections[i]; - var type = section.getAttribute('data-type'); - var typeOptions = getTypeOptions(options, type); + const sections = parent.querySelectorAll('.metadataFetcher'); + for (let i = 0; i < sections.length; i++) { + const section = sections[i]; + const type = section.getAttribute('data-type'); + let typeOptions = getTypeOptions(options, type); if (!typeOptions) { typeOptions = { Type: type }; options.TypeOptions.push(typeOptions); } - typeOptions.MetadataFetchers = Array.prototype.map.call(Array.prototype.filter.call(section.querySelectorAll('.chkMetadataFetcher'), function(elem) { + typeOptions.MetadataFetchers = Array.prototype.map.call(Array.prototype.filter.call(section.querySelectorAll('.chkMetadataFetcher'), elem => { return elem.checked; - }), function(elem) { + }), elem => { return elem.getAttribute('data-pluginname'); }); - typeOptions.MetadataFetcherOrder = Array.prototype.map.call(section.querySelectorAll('.metadataFetcherItem'), function(elem) { + typeOptions.MetadataFetcherOrder = Array.prototype.map.call(section.querySelectorAll('.metadataFetcherItem'), elem => { return elem.getAttribute('data-pluginname'); }); } } function setImageFetchersIntoOptions(parent, options) { - var sections = parent.querySelectorAll('.imageFetcher'); - for (var i = 0; i < sections.length; i++) { - var section = sections[i]; - var type = section.getAttribute('data-type'); - var typeOptions = getTypeOptions(options, type); + const sections = parent.querySelectorAll('.imageFetcher'); + for (let i = 0; i < sections.length; i++) { + const section = sections[i]; + const type = section.getAttribute('data-type'); + let typeOptions = getTypeOptions(options, type); if (!typeOptions) { typeOptions = { Type: type @@ -470,23 +477,23 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct options.TypeOptions.push(typeOptions); } - typeOptions.ImageFetchers = Array.prototype.map.call(Array.prototype.filter.call(section.querySelectorAll('.chkImageFetcher'), function(elem) { + typeOptions.ImageFetchers = Array.prototype.map.call(Array.prototype.filter.call(section.querySelectorAll('.chkImageFetcher'), elem => { return elem.checked; - }), function(elem) { + }), elem => { return elem.getAttribute('data-pluginname'); }); - typeOptions.ImageFetcherOrder = Array.prototype.map.call(section.querySelectorAll('.imageFetcherItem'), function(elem) { + typeOptions.ImageFetcherOrder = Array.prototype.map.call(section.querySelectorAll('.imageFetcherItem'), elem => { return elem.getAttribute('data-pluginname'); }); } } - function setImageOptionsIntoOptions(parent, options) { - var originalTypeOptions = (currentLibraryOptions || {}).TypeOptions || []; - for (var i = 0; i < originalTypeOptions.length; i++) { - var originalTypeOption = originalTypeOptions[i]; - var typeOptions = getTypeOptions(options, originalTypeOption.Type); + function setImageOptionsIntoOptions(options) { + const originalTypeOptions = (currentLibraryOptions || {}).TypeOptions || []; + for (let i = 0; i < originalTypeOptions.length; i++) { + const originalTypeOption = originalTypeOptions[i]; + let typeOptions = getTypeOptions(options, originalTypeOption.Type); if (!typeOptions) { typeOptions = { @@ -498,8 +505,8 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct } } - function getLibraryOptions(parent) { - var options = { + export function getLibraryOptions(parent) { + const options = { EnableArchiveMediaFiles: false, EnablePhotos: parent.querySelector('.chkEnablePhotos').checked, EnableRealtimeMonitor: parent.querySelector('.chkEnableRealtimeMonitor').checked, @@ -520,39 +527,39 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct SkipSubtitlesIfAudioTrackMatches: parent.querySelector('#chkSkipIfAudioTrackPresent').checked, SaveSubtitlesWithMedia: parent.querySelector('#chkSaveSubtitlesLocally').checked, RequirePerfectSubtitleMatch: parent.querySelector('#chkRequirePerfectMatch').checked, - MetadataSavers: Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkMetadataSaver'), function(elem) { + MetadataSavers: Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkMetadataSaver'), elem => { return elem.checked; - }), function(elem) { + }), elem => { return elem.getAttribute('data-pluginname'); }), TypeOptions: [] }; - options.LocalMetadataReaderOrder = Array.prototype.map.call(parent.querySelectorAll('.localReaderOption'), function(elem) { + options.LocalMetadataReaderOrder = Array.prototype.map.call(parent.querySelectorAll('.localReaderOption'), elem => { return elem.getAttribute('data-pluginname'); }); - options.SubtitleDownloadLanguages = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkSubtitleLanguage'), function(elem) { + options.SubtitleDownloadLanguages = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkSubtitleLanguage'), elem => { return elem.checked; - }), function(elem) { + }), elem => { return elem.getAttribute('data-lang'); }); setSubtitleFetchersIntoOptions(parent, options); setMetadataFetchersIntoOptions(parent, options); setImageFetchersIntoOptions(parent, options); - setImageOptionsIntoOptions(parent, options); + setImageOptionsIntoOptions(options); return options; } function getOrderedPlugins(plugins, configuredOrder) { plugins = plugins.slice(0); - plugins.sort(function(a, b) { + plugins.sort((a, b) => { return a = configuredOrder.indexOf(a.Name), b = configuredOrder.indexOf(b.Name), a < b ? -1 : a > b ? 1 : 0; }); return plugins; } - function setLibraryOptions(parent, options) { + export function setLibraryOptions(parent, options) { currentLibraryOptions = options; currentAvailableOptions = parent.availableOptions; parent.querySelector('#selectLanguage').value = options.PreferredMetadataLanguage || ''; @@ -573,11 +580,11 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct parent.querySelector('#chkSaveSubtitlesLocally').checked = options.SaveSubtitlesWithMedia; parent.querySelector('#chkSkipIfAudioTrackPresent').checked = options.SkipSubtitlesIfAudioTrackMatches; parent.querySelector('#chkRequirePerfectMatch').checked = options.RequirePerfectSubtitleMatch; - Array.prototype.forEach.call(parent.querySelectorAll('.chkMetadataSaver'), function(elem) { - elem.checked = options.MetadataSavers ? -1 !== options.MetadataSavers.indexOf(elem.getAttribute('data-pluginname')) : 'true' === elem.getAttribute('data-defaultenabled'); + Array.prototype.forEach.call(parent.querySelectorAll('.chkMetadataSaver'), elem => { + elem.checked = options.MetadataSavers ? options.MetadataSavers.includes(elem.getAttribute('data-pluginname')) : 'true' === elem.getAttribute('data-defaultenabled'); }); - Array.prototype.forEach.call(parent.querySelectorAll('.chkSubtitleLanguage'), function(elem) { - elem.checked = !!options.SubtitleDownloadLanguages && -1 !== options.SubtitleDownloadLanguages.indexOf(elem.getAttribute('data-lang')); + Array.prototype.forEach.call(parent.querySelectorAll('.chkSubtitleLanguage'), elem => { + elem.checked = !!options.SubtitleDownloadLanguages && options.SubtitleDownloadLanguages.includes(elem.getAttribute('data-lang')); }); renderMetadataReaders(parent, getOrderedPlugins(parent.availableOptions.MetadataReaders, options.LocalMetadataReaderOrder || [])); renderMetadataFetchers(parent, parent.availableOptions, options); @@ -585,14 +592,14 @@ define(['globalize', 'dom', 'emby-checkbox', 'emby-select', 'emby-input'], funct renderSubtitleFetchers(parent, parent.availableOptions, options); } - var currentLibraryOptions; - var currentAvailableOptions; + let currentLibraryOptions; + let currentAvailableOptions; - return { - embed: embed, - setContentType: setContentType, - getLibraryOptions: getLibraryOptions, - setLibraryOptions: setLibraryOptions, - setAdvancedVisible: setAdvancedVisible - }; -}); +/* eslint-enable indent */ +export default { + embed: embed, + setContentType: setContentType, + getLibraryOptions: getLibraryOptions, + setLibraryOptions: setLibraryOptions, + setAdvancedVisible: setAdvancedVisible +}; From bb5d37f3e7d6e954b50274edd83f0f849985c33e Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Tue, 9 Jun 2020 22:37:34 +0300 Subject: [PATCH 0011/1168] Migration mediaLibraryEditor and mediaLibraryCreator to es6 --- package.json | 2 + .../mediaLibraryCreator.js | 131 +++++++++-------- .../mediaLibraryEditor/mediaLibraryEditor.js | 137 ++++++++++-------- src/controllers/dashboard/mediaLibrary.js | 4 +- 4 files changed, 154 insertions(+), 120 deletions(-) diff --git a/package.json b/package.json index d9b2ed761..117477a70 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,8 @@ "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", + "src/components/mediaLibraryCreator/mediaLibraryCreator.js", + "src/components/mediaLibraryEditor/mediaLibraryEditor.js", "src/components/playback/brightnessosd.js", "src/components/playback/mediasession.js", "src/components/playback/nowplayinghelper.js", diff --git a/src/components/mediaLibraryCreator/mediaLibraryCreator.js b/src/components/mediaLibraryCreator/mediaLibraryCreator.js index bbef6e1f0..c7011ba1d 100644 --- a/src/components/mediaLibraryCreator/mediaLibraryCreator.js +++ b/src/components/mediaLibraryCreator/mediaLibraryCreator.js @@ -1,5 +1,24 @@ -define(['loading', 'dialogHelper', 'dom', 'jQuery', 'components/libraryoptionseditor/libraryoptionseditor', 'globalize', 'emby-toggle', 'emby-input', 'emby-select', 'paper-icon-button-light', 'listViewStyle', 'formDialogStyle', 'emby-button', 'flexStyles'], function (loading, dialogHelper, dom, $, libraryoptionseditor, globalize) { - 'use strict'; +/* eslint-disable indent */ + +/** + * Module for media library creator. + * @module components/mediaLibraryCreator/mediaLibraryCreator + */ + +import loading from 'loading'; +import dialogHelper from 'dialogHelper'; +import dom from 'dom'; +import $ from 'jQuery'; +import libraryoptionseditor from 'components/libraryoptionseditor/libraryoptionseditor'; +import globalize from 'globalize'; +import 'emby-toggle'; +import 'emby-input'; +import 'emby-select'; +import 'paper-icon-button-light'; +import 'listViewStyle'; +import 'formDialogStyle'; +import 'emby-button'; +import 'flexStyles'; function onAddLibrary() { if (isCreating) { @@ -7,7 +26,7 @@ define(['loading', 'dialogHelper', 'dom', 'jQuery', 'components/libraryoptionsed } if (pathInfos.length == 0) { - require(['alert'], function (alert) { + import('alert').then(({default: alert}) => { alert({ text: globalize.translate('PleaseAddAtLeastOneFolder'), type: 'error' @@ -19,23 +38,23 @@ define(['loading', 'dialogHelper', 'dom', 'jQuery', 'components/libraryoptionsed isCreating = true; loading.show(); - var dlg = dom.parentWithClass(this, 'dlg-librarycreator'); - var name = $('#txtValue', dlg).val(); - var type = $('#selectCollectionType', dlg).val(); + const dlg = dom.parentWithClass(this, 'dlg-librarycreator'); + const name = $('#txtValue', dlg).val(); + let type = $('#selectCollectionType', dlg).val(); if (type == 'mixed') { type = null; } - var libraryOptions = libraryoptionseditor.getLibraryOptions(dlg.querySelector('.libraryOptions')); + const libraryOptions = libraryoptionseditor.getLibraryOptions(dlg.querySelector('.libraryOptions')); libraryOptions.PathInfos = pathInfos; - ApiClient.addVirtualFolder(name, type, currentOptions.refresh, libraryOptions).then(function () { + ApiClient.addVirtualFolder(name, type, currentOptions.refresh, libraryOptions).then(() => { hasChanges = true; isCreating = false; loading.hide(); dialogHelper.close(dlg); - }, function () { - require(['toast'], function (toast) { + }, () => { + import('toast').then(({default: toast}) => { toast(globalize.translate('ErrorAddingMediaPathToVirtualFolder')); }); @@ -46,15 +65,15 @@ define(['loading', 'dialogHelper', 'dom', 'jQuery', 'components/libraryoptionsed } function getCollectionTypeOptionsHtml(collectionTypeOptions) { - return collectionTypeOptions.map(function (i) { - return ''; + return collectionTypeOptions.map(i => { + return ``; }).join(''); } function initEditor(page, collectionTypeOptions) { $('#selectCollectionType', page).html(getCollectionTypeOptionsHtml(collectionTypeOptions)).val('').on('change', function () { - var value = this.value; - var dlg = $(this).parents('.dialog')[0]; + const value = this.value; + const dlg = $(this).parents('.dialog')[0]; libraryoptionseditor.setContentType(dlg.querySelector('.libraryOptions'), value == 'mixed' ? '' : value); if (value) { @@ -64,12 +83,12 @@ define(['loading', 'dialogHelper', 'dom', 'jQuery', 'components/libraryoptionsed } if (value != 'mixed') { - var index = this.selectedIndex; + const index = this.selectedIndex; if (index != -1) { - var name = this.options[index].innerHTML.replace('*', '').replace('&', '&'); + const name = this.options[index].innerHTML.replace('*', '').replace('&', '&'); $('#txtValue', dlg).val(name); - var folderOption = collectionTypeOptions.filter(function (i) { + const folderOption = collectionTypeOptions.filter(i => { return i.value == value; })[0]; $('.collectionTypeFieldDescription', dlg).html(folderOption.message || ''); @@ -83,15 +102,15 @@ define(['loading', 'dialogHelper', 'dom', 'jQuery', 'components/libraryoptionsed } function onToggleAdvancedChange() { - var dlg = dom.parentWithClass(this, 'dlg-librarycreator'); + const dlg = dom.parentWithClass(this, 'dlg-librarycreator'); libraryoptionseditor.setAdvancedVisible(dlg.querySelector('.libraryOptions'), this.checked); } function onAddButtonClick() { - var page = dom.parentWithClass(this, 'dlg-librarycreator'); + const page = dom.parentWithClass(this, 'dlg-librarycreator'); - require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + import('directorybrowser').then(({default: directoryBrowser}) => { + const picker = new directoryBrowser(); picker.show({ enableNetworkSharePath: true, callback: function (path, networkSharePath) { @@ -106,24 +125,24 @@ define(['loading', 'dialogHelper', 'dom', 'jQuery', 'components/libraryoptionsed } function getFolderHtml(pathInfo, index) { - var html = ''; + let html = ''; html += '
'; - html += '
'; - html += '
' + pathInfo.Path + '
'; + html += `
`; + html += `
${pathInfo.Path}
`; if (pathInfo.NetworkPath) { - html += '
' + pathInfo.NetworkPath + '
'; + html += `
${pathInfo.NetworkPath}
`; } html += '
'; - html += ''; + html += ``; html += '
'; return html; } function renderPaths(page) { - var foldersHtml = pathInfos.map(getFolderHtml).join(''); - var folderList = page.querySelector('.folderList'); + const foldersHtml = pathInfos.map(getFolderHtml).join(''); + const folderList = page.querySelector('.folderList'); folderList.innerHTML = foldersHtml; if (foldersHtml) { @@ -134,13 +153,13 @@ define(['loading', 'dialogHelper', 'dom', 'jQuery', 'components/libraryoptionsed } function addMediaLocation(page, path, networkSharePath) { - var pathLower = path.toLowerCase(); - var pathFilter = pathInfos.filter(function (p) { + const pathLower = path.toLowerCase(); + const pathFilter = pathInfos.filter(p => { return p.Path.toLowerCase() == pathLower; }); if (!pathFilter.length) { - var pathInfo = { + const pathInfo = { Path: path }; @@ -154,11 +173,11 @@ define(['loading', 'dialogHelper', 'dom', 'jQuery', 'components/libraryoptionsed } function onRemoveClick(e) { - var button = dom.parentWithClass(e.target, 'btnRemovePath'); - var index = parseInt(button.getAttribute('data-index')); - var location = pathInfos[index].Path; - var locationLower = location.toLowerCase(); - pathInfos = pathInfos.filter(function (p) { + const button = dom.parentWithClass(e.target, 'btnRemovePath'); + const index = parseInt(button.getAttribute('data-index')); + const location = pathInfos[index].Path; + const locationLower = location.toLowerCase(); + pathInfos = pathInfos.filter(p => { return p.Path.toLowerCase() != locationLower; }); renderPaths(dom.parentWithClass(button, 'dlg-librarycreator')); @@ -169,24 +188,22 @@ define(['loading', 'dialogHelper', 'dom', 'jQuery', 'components/libraryoptionsed } function initLibraryOptions(dlg) { - libraryoptionseditor.embed(dlg.querySelector('.libraryOptions')).then(function () { + libraryoptionseditor.embed(dlg.querySelector('.libraryOptions')).then(() => { $('#selectCollectionType', dlg).trigger('change'); onToggleAdvancedChange.call(dlg.querySelector('.chkAdvanced')); }); } - function editor() { - this.show = function (options) { - return new Promise(function (resolve, reject) { +export class editor { + constructor() { + this.show = options => { + return new Promise((resolve) => { currentOptions = options; currentResolve = resolve; hasChanges = false; - var xhr = new XMLHttpRequest(); - xhr.open('GET', 'components/mediaLibraryCreator/mediaLibraryCreator.template.html', true); - - xhr.onload = function (e) { - var template = this.response; - var dlg = dialogHelper.createDialog({ + // TODO: remove require + require(['text!./components/mediaLibraryCreator/mediaLibraryCreator.template.html'], template => { + const dlg = dialogHelper.createDialog({ size: 'small', modal: false, removeOnClose: true, @@ -200,23 +217,23 @@ define(['loading', 'dialogHelper', 'dom', 'jQuery', 'components/libraryoptionsed initEditor(dlg, options.collectionTypeOptions); dlg.addEventListener('close', onDialogClosed); dialogHelper.open(dlg); - dlg.querySelector('.btnCancel').addEventListener('click', function () { + dlg.querySelector('.btnCancel').addEventListener('click', () => { dialogHelper.close(dlg); }); pathInfos = []; renderPaths(dlg); initLibraryOptions(dlg); - }; - - xhr.send(); + }); }); }; } +} - var pathInfos = []; - var currentResolve; - var currentOptions; - var hasChanges = false; - var isCreating = false; - return editor; -}); + let pathInfos = []; + let currentResolve; + let currentOptions; + let hasChanges = false; + let isCreating = false; + +/* eslint-enable indent */ +export default editor; diff --git a/src/components/mediaLibraryEditor/mediaLibraryEditor.js b/src/components/mediaLibraryEditor/mediaLibraryEditor.js index 554cf4cc0..5b533b2ac 100644 --- a/src/components/mediaLibraryEditor/mediaLibraryEditor.js +++ b/src/components/mediaLibraryEditor/mediaLibraryEditor.js @@ -1,5 +1,22 @@ -define(['jQuery', 'loading', 'dialogHelper', 'dom', 'components/libraryoptionseditor/libraryoptionseditor', 'globalize', 'emby-button', 'listViewStyle', 'paper-icon-button-light', 'formDialogStyle', 'emby-toggle', 'flexStyles'], function (jQuery, loading, dialogHelper, dom, libraryoptionseditor, globalize) { - 'use strict'; +/* eslint-disable indent */ + +/** + * Module for media library editor. + * @module components/mediaLibraryEditor/mediaLibraryEditor + */ + +import jQuery from 'jQuery'; +import loading from 'loading'; +import dialogHelper from 'dialogHelper'; +import dom from 'dom'; +import libraryoptionseditor from 'components/libraryoptionseditor/libraryoptionseditor'; +import globalize from 'globalize'; +import 'emby-button'; +import 'listViewStyle'; +import 'paper-icon-button-light'; +import 'formDialogStyle'; +import 'emby-toggle'; +import 'flexStyles'; function onEditLibrary() { if (isCreating) { @@ -8,15 +25,15 @@ define(['jQuery', 'loading', 'dialogHelper', 'dom', 'components/libraryoptionsed isCreating = true; loading.show(); - var dlg = dom.parentWithClass(this, 'dlg-libraryeditor'); - var libraryOptions = libraryoptionseditor.getLibraryOptions(dlg.querySelector('.libraryOptions')); + const dlg = dom.parentWithClass(this, 'dlg-libraryeditor'); + let libraryOptions = libraryoptionseditor.getLibraryOptions(dlg.querySelector('.libraryOptions')); libraryOptions = Object.assign(currentOptions.library.LibraryOptions || {}, libraryOptions); - ApiClient.updateVirtualFolderOptions(currentOptions.library.ItemId, libraryOptions).then(function () { + ApiClient.updateVirtualFolderOptions(currentOptions.library.ItemId, libraryOptions).then(() => { hasChanges = true; isCreating = false; loading.hide(); dialogHelper.close(dlg); - }, function () { + }, () => { isCreating = false; loading.hide(); }); @@ -24,50 +41,50 @@ define(['jQuery', 'loading', 'dialogHelper', 'dom', 'components/libraryoptionsed } function addMediaLocation(page, path, networkSharePath) { - var virtualFolder = currentOptions.library; - var refreshAfterChange = currentOptions.refresh; - ApiClient.addMediaPath(virtualFolder.Name, path, networkSharePath, refreshAfterChange).then(function () { + const virtualFolder = currentOptions.library; + const refreshAfterChange = currentOptions.refresh; + ApiClient.addMediaPath(virtualFolder.Name, path, networkSharePath, refreshAfterChange).then(() => { hasChanges = true; refreshLibraryFromServer(page); - }, function () { - require(['toast'], function (toast) { + }, () => { + import('toast').then(({default: toast}) => { toast(globalize.translate('ErrorAddingMediaPathToVirtualFolder')); }); }); } function updateMediaLocation(page, path, networkSharePath) { - var virtualFolder = currentOptions.library; + const virtualFolder = currentOptions.library; ApiClient.updateMediaPath(virtualFolder.Name, { Path: path, NetworkPath: networkSharePath - }).then(function () { + }).then(() => { hasChanges = true; refreshLibraryFromServer(page); - }, function () { - require(['toast'], function (toast) { + }, () => { + import('toast').then(({default: toast}) => { toast(globalize.translate('ErrorAddingMediaPathToVirtualFolder')); }); }); } function onRemoveClick(btnRemovePath, location) { - var button = btnRemovePath; - var virtualFolder = currentOptions.library; + const button = btnRemovePath; + const virtualFolder = currentOptions.library; - require(['confirm'], function (confirm) { + import('confirm').then(({default: confirm}) => { confirm({ title: globalize.translate('HeaderRemoveMediaLocation'), text: globalize.translate('MessageConfirmRemoveMediaLocation'), confirmText: globalize.translate('ButtonDelete'), primary: 'delete' - }).then(function () { - var refreshAfterChange = currentOptions.refresh; - ApiClient.removeMediaPath(virtualFolder.Name, location, refreshAfterChange).then(function () { + }).then(() => { + const refreshAfterChange = currentOptions.refresh; + ApiClient.removeMediaPath(virtualFolder.Name, location, refreshAfterChange).then(() => { hasChanges = true; refreshLibraryFromServer(dom.parentWithClass(button, 'dlg-libraryeditor')); - }, function () { - require(['toast'], function (toast) { + }, () => { + import('toast').then(({default: toast}) => { toast(globalize.translate('DefaultErrorMessage')); }); }); @@ -76,14 +93,14 @@ define(['jQuery', 'loading', 'dialogHelper', 'dom', 'components/libraryoptionsed } function onListItemClick(e) { - var listItem = dom.parentWithClass(e.target, 'listItem'); + const listItem = dom.parentWithClass(e.target, 'listItem'); if (listItem) { - var index = parseInt(listItem.getAttribute('data-index')); - var pathInfos = (currentOptions.library.LibraryOptions || {}).PathInfos || []; - var pathInfo = null == index ? {} : pathInfos[index] || {}; - var originalPath = pathInfo.Path || (null == index ? null : currentOptions.library.Locations[index]); - var btnRemovePath = dom.parentWithClass(e.target, 'btnRemovePath'); + const index = parseInt(listItem.getAttribute('data-index')); + const pathInfos = (currentOptions.library.LibraryOptions || {}).PathInfos || []; + const pathInfo = null == index ? {} : pathInfos[index] || {}; + const originalPath = pathInfo.Path || (null == index ? null : currentOptions.library.Locations[index]); + const btnRemovePath = dom.parentWithClass(e.target, 'btnRemovePath'); if (btnRemovePath) { onRemoveClick(btnRemovePath, originalPath); @@ -95,26 +112,26 @@ define(['jQuery', 'loading', 'dialogHelper', 'dom', 'components/libraryoptionsed } function getFolderHtml(pathInfo, index) { - var html = ''; - html += '
'; - html += '
'; + let html = ''; + html += `
`; + html += `
`; html += '

'; html += pathInfo.Path; html += '

'; if (pathInfo.NetworkPath) { - html += '
' + pathInfo.NetworkPath + '
'; + html += `
${pathInfo.NetworkPath}
`; } html += '
'; - html += ''; + html += ``; html += '
'; return html; } function refreshLibraryFromServer(page) { - ApiClient.getVirtualFolders().then(function (result) { - var library = result.filter(function (f) { + ApiClient.getVirtualFolders().then(result => { + const library = result.filter(f => { return f.Name === currentOptions.library.Name; })[0]; @@ -126,10 +143,10 @@ define(['jQuery', 'loading', 'dialogHelper', 'dom', 'components/libraryoptionsed } function renderLibrary(page, options) { - var pathInfos = (options.library.LibraryOptions || {}).PathInfos || []; + let pathInfos = (options.library.LibraryOptions || {}).PathInfos || []; if (!pathInfos.length) { - pathInfos = options.library.Locations.map(function (p) { + pathInfos = options.library.Locations.map(p => { return { Path: p }; @@ -150,8 +167,8 @@ define(['jQuery', 'loading', 'dialogHelper', 'dom', 'components/libraryoptionsed } function showDirectoryBrowser(context, originalPath, networkPath) { - require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + import('directorybrowser').then(({default: directoryBrowser}) => { + const picker = new directoryBrowser(); picker.show({ enableNetworkSharePath: true, pathReadOnly: null != originalPath, @@ -173,7 +190,7 @@ define(['jQuery', 'loading', 'dialogHelper', 'dom', 'components/libraryoptionsed } function onToggleAdvancedChange() { - var dlg = dom.parentWithClass(this, 'dlg-libraryeditor'); + const dlg = dom.parentWithClass(this, 'dlg-libraryeditor'); libraryoptionseditor.setAdvancedVisible(dlg.querySelector('.libraryOptions'), this.checked); } @@ -183,7 +200,7 @@ define(['jQuery', 'loading', 'dialogHelper', 'dom', 'components/libraryoptionsed dlg.querySelector('.folderList').addEventListener('click', onListItemClick); dlg.querySelector('.chkAdvanced').addEventListener('change', onToggleAdvancedChange); dlg.querySelector('.btnSubmit').addEventListener('click', onEditLibrary); - libraryoptionseditor.embed(dlg.querySelector('.libraryOptions'), options.library.CollectionType, options.library.LibraryOptions).then(function () { + libraryoptionseditor.embed(dlg.querySelector('.libraryOptions'), options.library.CollectionType, options.library.LibraryOptions).then(() => { onToggleAdvancedChange.call(dlg.querySelector('.chkAdvanced')); }); } @@ -192,18 +209,16 @@ define(['jQuery', 'loading', 'dialogHelper', 'dom', 'components/libraryoptionsed currentDeferred.resolveWith(null, [hasChanges]); } - function editor() { - this.show = function (options) { - var deferred = jQuery.Deferred(); +export class editor { + constructor() { + this.show = options => { + const deferred = jQuery.Deferred(); currentOptions = options; currentDeferred = deferred; hasChanges = false; - var xhr = new XMLHttpRequest(); - xhr.open('GET', 'components/mediaLibraryEditor/mediaLibraryEditor.template.html', true); - - xhr.onload = function (e) { - var template = this.response; - var dlg = dialogHelper.createDialog({ + // TODO: remove require + require(['text!./components/mediaLibraryEditor/mediaLibraryEditor.template.html'], template => { + const dlg = dialogHelper.createDialog({ size: 'small', modal: false, removeOnClose: true, @@ -218,20 +233,20 @@ define(['jQuery', 'loading', 'dialogHelper', 'dom', 'components/libraryoptionsed initEditor(dlg, options); dlg.addEventListener('close', onDialogClosed); dialogHelper.open(dlg); - dlg.querySelector('.btnCancel').addEventListener('click', function () { + dlg.querySelector('.btnCancel').addEventListener('click', () => { dialogHelper.close(dlg); }); refreshLibraryFromServer(dlg); - }; - - xhr.send(); + }); return deferred.promise(); }; } +} - var currentDeferred; - var currentOptions; - var hasChanges = false; - var isCreating = false; - return editor; -}); + let currentDeferred; + let currentOptions; + let hasChanges = false; + let isCreating = false; + + /* eslint-enable indent */ +export default editor; diff --git a/src/controllers/dashboard/mediaLibrary.js b/src/controllers/dashboard/mediaLibrary.js index 06eba37cb..ed6aabc8f 100644 --- a/src/controllers/dashboard/mediaLibrary.js +++ b/src/controllers/dashboard/mediaLibrary.js @@ -3,7 +3,7 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl function addVirtualFolder(page) { require(['medialibrarycreator'], function (medialibrarycreator) { - new medialibrarycreator().show({ + new medialibrarycreator.default().show({ collectionTypeOptions: getCollectionTypeOptions().filter(function (f) { return !f.hidden; }), @@ -18,7 +18,7 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl function editVirtualFolder(page, virtualFolder) { require(['medialibraryeditor'], function (medialibraryeditor) { - new medialibraryeditor().show({ + new medialibraryeditor.default().show({ refresh: shouldRefreshLibraryAfterChanges(page), library: virtualFolder }).then(function (hasChanges) { From 7296dbc28428690386e7f873a7feda70f46d63b1 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Tue, 9 Jun 2020 22:40:39 +0300 Subject: [PATCH 0012/1168] Migration imageUploader, itemidentifier and itemMediaInfo to es6 --- package.json | 3 + src/components/imageUploader/imageUploader.js | 93 +++++--- src/components/itemMediaInfo/itemMediaInfo.js | 96 +++++--- .../itemidentifier/itemidentifier.js | 225 ++++++++++-------- 4 files changed, 241 insertions(+), 176 deletions(-) diff --git a/package.json b/package.json index d9b2ed761..41bbc013e 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,10 @@ "src/components/autoFocuser.js", "src/components/cardbuilder/cardBuilder.js", "src/components/images/imageLoader.js", + "src/components/imageUploader/imageUploader.js", "src/components/indicators/indicators.js", + "src/components/itemidentifier/itemidentifier.js", + "src/components/itemMediaInfo/itemMediaInfo.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", "src/components/playback/brightnessosd.js", "src/components/playback/mediasession.js", diff --git a/src/components/imageUploader/imageUploader.js b/src/components/imageUploader/imageUploader.js index e078a9fa3..e2d2c60f1 100644 --- a/src/components/imageUploader/imageUploader.js +++ b/src/components/imageUploader/imageUploader.js @@ -1,10 +1,26 @@ -define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', 'layoutManager', 'globalize', 'require', 'emby-button', 'emby-select', 'formDialogStyle', 'css!./style'], function (dialogHelper, connectionManager, dom, loading, scrollHelper, layoutManager, globalize, require) { - 'use strict'; +/* eslint-disable indent */ - var currentItemId; - var currentServerId; - var currentFile; - var hasChanges = false; +/** + * Module for imageUploader. + * @module components/imageUploader/imageUploader + */ + +import dialogHelper from 'dialogHelper'; +import connectionManager from 'connectionManager'; +import dom from 'dom'; +import loading from 'loading'; +import scrollHelper from 'scrollHelper'; +import layoutManager from 'layoutManager'; +import globalize from 'globalize'; +import 'emby-button'; +import 'emby-select'; +import 'formDialogStyle'; +import 'css!./style'; + + let currentItemId; + let currentServerId; + let currentFile; + let hasChanges = false; function onFileReaderError(evt) { @@ -12,14 +28,14 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', ' switch (evt.target.error.code) { case evt.target.error.NOT_FOUND_ERR: - require(['toast'], function (toast) { + import('toast').then(({default: toast}) => { toast(globalize.translate('MessageFileReadError')); }); break; case evt.target.error.ABORT_ERR: break; // noop default: - require(['toast'], function (toast) { + import('toast').then(({default: toast}) => { toast(globalize.translate('MessageFileReadError')); }); break; @@ -28,7 +44,7 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', ' function setFiles(page, files) { - var file = files[0]; + const file = files[0]; if (!file || !file.type.match('image.*')) { page.querySelector('#imageOutput').innerHTML = ''; @@ -39,23 +55,23 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', ' currentFile = file; - var reader = new FileReader(); + const reader = new FileReader(); reader.onerror = onFileReaderError; - reader.onloadstart = function () { + reader.onloadstart = () => { page.querySelector('#fldUpload').classList.add('hide'); }; - reader.onabort = function () { + reader.onabort = () => { loading.hide(); console.debug('File read cancelled'); }; // Closure to capture the file information. - reader.onload = (function (theFile) { - return function (e) { + reader.onload = (theFile => { + return e => { // Render thumbnail. - var html = [''].join(''); + const html = [''].join(''); page.querySelector('#imageOutput').innerHTML = html; page.querySelector('#fldUpload').classList.remove('hide'); @@ -68,14 +84,14 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', ' function onSubmit(e) { - var file = currentFile; + const file = currentFile; if (!file) { return false; } if (!file.type.startsWith('image/')) { - require(['toast'], function (toast) { + import('toast').then(({default: toast}) => { toast(globalize.translate('MessageImageFileTypeAllowed')); }); e.preventDefault(); @@ -84,18 +100,18 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', ' loading.show(); - var dlg = dom.parentWithClass(this, 'dialog'); + const dlg = dom.parentWithClass(this, 'dialog'); - var imageType = dlg.querySelector('#selectImageType').value; + const imageType = dlg.querySelector('#selectImageType').value; if (imageType === 'None') { - require(['toast'], function(toast) { + import('toast').then(({default: toast}) => { toast(globalize.translate('MessageImageTypeNotSelected')); }); e.preventDefault(); return false; } - connectionManager.getApiClient(currentServerId).uploadItemImage(currentItemId, imageType, file).then(function () { + connectionManager.getApiClient(currentServerId).uploadItemImage(currentItemId, imageType, file).then(() => { dlg.querySelector('#uploadImage').value = ''; @@ -116,21 +132,22 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', ' setFiles(page, this.files); }); - page.querySelector('.btnBrowse').addEventListener('click', function () { + page.querySelector('.btnBrowse').addEventListener('click', () => { page.querySelector('#uploadImage').click(); }); } - function showEditor(options, resolve, reject) { + function showEditor(options, resolve) { options = options || {}; - require(['text!./imageUploader.template.html'], function (template) { + // TODO: remove require + require(['text!./components/imageUploader/imageUploader.template.html'], template => { currentItemId = options.itemId; currentServerId = options.serverId; - var dialogOptions = { + const dialogOptions = { removeOnClose: true }; @@ -140,7 +157,7 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', ' dialogOptions.size = 'small'; } - var dlg = dialogHelper.createDialog(dialogOptions); + const dlg = dialogHelper.createDialog(dialogOptions); dlg.classList.add('formDialog'); @@ -151,7 +168,7 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', ' } // Has to be assigned a z-index after the call to .open() - dlg.addEventListener('close', function () { + dlg.addEventListener('close', () => { if (layoutManager.tv) { scrollHelper.centerFocus.off(dlg, false); @@ -167,22 +184,24 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', ' dlg.querySelector('#selectImageType').value = options.imageType || 'Primary'; - dlg.querySelector('.btnCancel').addEventListener('click', function () { + dlg.querySelector('.btnCancel').addEventListener('click', () => { dialogHelper.close(dlg); }); }); } - return { - show: function (options) { + export function show(options) { - return new Promise(function (resolve, reject) { + return new Promise((resolve, reject) => { - hasChanges = false; + hasChanges = false; - showEditor(options, resolve, reject); - }); - } - }; -}); + showEditor(options, resolve, reject); + }); + } + +/* eslint-enable indent */ +export default { + show: show +}; diff --git a/src/components/itemMediaInfo/itemMediaInfo.js b/src/components/itemMediaInfo/itemMediaInfo.js index 81c84b6a2..492b27e2c 100644 --- a/src/components/itemMediaInfo/itemMediaInfo.js +++ b/src/components/itemMediaInfo/itemMediaInfo.js @@ -1,44 +1,61 @@ -define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', 'connectionManager', 'loading', 'focusManager', 'dom', 'apphost', 'emby-select', 'listViewStyle', 'paper-icon-button-light', 'css!./../formdialog', 'material-icons', 'emby-button', 'flexStyles'], function (dialogHelper, require, layoutManager, globalize, userSettings, connectionManager, loading, focusManager, dom, appHost) { - 'use strict'; +/* eslint-disable indent */ + +/** + * Module for display media info. + * @module components/itemMediaInfo/itemMediaInfo + */ + +import dialogHelper from 'dialogHelper'; +import layoutManager from 'layoutManager'; +import globalize from 'globalize'; +import connectionManager from 'connectionManager'; +import loading from 'loading'; +import 'emby-select'; +import 'listViewStyle'; +import 'paper-icon-button-light'; +import 'css!./../formdialog'; +import 'material-icons'; +import 'emby-button'; +import 'flexStyles'; function setMediaInfo(user, page, item) { - var html = item.MediaSources.map(function (version) { + let html = item.MediaSources.map(version => { return getMediaSourceHtml(user, item, version); }).join('
'); if (item.MediaSources.length > 1) { - html = '
' + html; + html = `
${html}`; } - var mediaInfoContent = page.querySelector('#mediaInfoContent'); + const mediaInfoContent = page.querySelector('#mediaInfoContent'); mediaInfoContent.innerHTML = html; } function getMediaSourceHtml(user, item, version) { - var html = ''; + let html = ''; if (version.Name) { - html += '

' + version.Name + '

'; + html += `

${version.Name}

`; } if (version.Container) { - html += createAttribute(globalize.translate('MediaInfoContainer'), version.Container) + '
'; + html += `${createAttribute(globalize.translate('MediaInfoContainer'), version.Container)}
`; } if (version.Formats && version.Formats.length) { - html += createAttribute(globalize.translate('MediaInfoFormat'), version.Formats.join(',')) + '
'; + html += `${createAttribute(globalize.translate('MediaInfoFormat'), version.Formats.join(','))}
`; } if (version.Path && user && user.Policy.IsAdministrator) { - html += createAttribute(globalize.translate('MediaInfoPath'), version.Path) + '
'; + html += `${createAttribute(globalize.translate('MediaInfoPath'), version.Path)}
`; } if (version.Size) { - var size = (version.Size / (1024 * 1024)).toFixed(0) + ' MB'; - html += createAttribute(globalize.translate('MediaInfoSize'), size) + '
'; + const size = `${(version.Size / (1024 * 1024)).toFixed(0)} MB`; + html += `${createAttribute(globalize.translate('MediaInfoSize'), size)}
`; } - for (var i = 0, length = version.MediaStreams.length; i < length; i++) { - var stream = version.MediaStreams[i]; + for (let i = 0, length = version.MediaStreams.length; i < length; i++) { + const stream = version.MediaStreams[i]; if (stream.Type === 'Data') { continue; } html += '
'; - var displayType = globalize.translate('MediaInfoStreamType' + stream.Type); - html += '

' + displayType + '

'; - var attributes = []; + const displayType = globalize.translate(`MediaInfoStreamType${stream.Type}`); + html += `

${displayType}

`; + const attributes = []; if (stream.DisplayTitle) { attributes.push(createAttribute('Title', stream.DisplayTitle)); } @@ -61,7 +78,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', attributes.push(createAttribute(globalize.translate('MediaInfoLevel'), stream.Level)); } if (stream.Width || stream.Height) { - attributes.push(createAttribute(globalize.translate('MediaInfoResolution'), stream.Width + 'x' + stream.Height)); + attributes.push(createAttribute(globalize.translate('MediaInfoResolution'), `${stream.Width}x${stream.Height}`)); } if (stream.AspectRatio && stream.Codec !== 'mjpeg') { attributes.push(createAttribute(globalize.translate('MediaInfoAspectRatio'), stream.AspectRatio)); @@ -79,16 +96,16 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', attributes.push(createAttribute(globalize.translate('MediaInfoLayout'), stream.ChannelLayout)); } if (stream.Channels) { - attributes.push(createAttribute(globalize.translate('MediaInfoChannels'), stream.Channels + ' ch')); + attributes.push(createAttribute(globalize.translate('MediaInfoChannels'), `${stream.Channels} ch`)); } if (stream.BitRate && stream.Codec !== 'mjpeg') { - attributes.push(createAttribute(globalize.translate('MediaInfoBitrate'), (parseInt(stream.BitRate / 1000)) + ' kbps')); + attributes.push(createAttribute(globalize.translate('MediaInfoBitrate'), `${parseInt(stream.BitRate / 1000)} kbps`)); } if (stream.SampleRate) { - attributes.push(createAttribute(globalize.translate('MediaInfoSampleRate'), stream.SampleRate + ' Hz')); + attributes.push(createAttribute(globalize.translate('MediaInfoSampleRate'), `${stream.SampleRate} Hz`)); } if (stream.BitDepth) { - attributes.push(createAttribute(globalize.translate('MediaInfoBitDepth'), stream.BitDepth + ' bit')); + attributes.push(createAttribute(globalize.translate('MediaInfoBitDepth'), `${stream.BitDepth} bit`)); } if (stream.PixelFormat) { attributes.push(createAttribute(globalize.translate('MediaInfoPixelFormat'), stream.PixelFormat)); @@ -116,13 +133,13 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', } function createAttribute(label, value) { - return '' + label + '' + value + ''; + return `${label}${value}`; } - function showMediaInfoMore(itemId, serverId, template) { - var apiClient = connectionManager.getApiClient(serverId); - return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) { - var dialogOptions = { + function loadMediaInfo(itemId, serverId, template) { + const apiClient = connectionManager.getApiClient(serverId); + return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(item => { + const dialogOptions = { size: 'small', removeOnClose: true, scrollY: false @@ -130,35 +147,36 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', if (layoutManager.tv) { dialogOptions.size = 'fullscreen'; } - var dlg = dialogHelper.createDialog(dialogOptions); + const dlg = dialogHelper.createDialog(dialogOptions); dlg.classList.add('formDialog'); - var html = ''; + let html = ''; html += globalize.translateDocument(template, 'core'); dlg.innerHTML = html; if (layoutManager.tv) { dlg.querySelector('.formDialogContent'); } dialogHelper.open(dlg); - dlg.querySelector('.btnCancel').addEventListener('click', function (e) { + dlg.querySelector('.btnCancel').addEventListener('click', () => { dialogHelper.close(dlg); }); - apiClient.getCurrentUser().then(function (user) { + apiClient.getCurrentUser().then(user => { setMediaInfo(user, dlg, item); }); loading.hide(); }); } - function showMediaInfo(itemId, serverId) { + export function show(itemId, serverId) { loading.show(); - return new Promise(function (resolve, reject) { - require(['text!./itemMediaInfo.template.html'], function (template) { - showMediaInfoMore(itemId, serverId, template).then(resolve, reject); + return new Promise((resolve, reject) => { + // TODO: remove require + require(['text!./components/itemMediaInfo/itemMediaInfo.template.html'], template => { + loadMediaInfo(itemId, serverId, template).then(resolve, reject); }); }); } - return { - show: showMediaInfo - }; -}); +/* eslint-enable indent */ +export default { + show: show +}; diff --git a/src/components/itemidentifier/itemidentifier.js b/src/components/itemidentifier/itemidentifier.js index b335d1dfd..a1520928c 100644 --- a/src/components/itemidentifier/itemidentifier.js +++ b/src/components/itemidentifier/itemidentifier.js @@ -1,15 +1,34 @@ -define(['dialogHelper', 'loading', 'connectionManager', 'require', 'globalize', 'scrollHelper', 'layoutManager', 'focusManager', 'browser', 'emby-input', 'emby-checkbox', 'paper-icon-button-light', 'css!./../formdialog', 'material-icons', 'cardStyle'], function (dialogHelper, loading, connectionManager, require, globalize, scrollHelper, layoutManager, focusManager, browser) { - 'use strict'; +/* eslint-disable indent */ - var enableFocusTransform = !browser.slow && !browser.edge; +/** + * Module for itemidentifier media item. + * @module components/itemidentifier/itemidentifier + */ - var currentItem; - var currentItemType; - var currentServerId; - var currentResolve; - var currentReject; - var hasChanges = false; - var currentSearchResult; +import dialogHelper from 'dialogHelper'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; +import globalize from 'globalize'; +import scrollHelper from 'scrollHelper'; +import layoutManager from 'layoutManager'; +import focusManager from 'focusManager'; +import browser from 'browser'; +import 'emby-input'; +import 'emby-checkbox'; +import 'paper-icon-button-light'; +import 'css!./../formdialog'; +import 'material-icons'; +import 'cardStyle'; + + const enableFocusTransform = !browser.slow && !browser.edge; + + let currentItem; + let currentItemType; + let currentServerId; + let currentResolve; + let currentReject; + let hasChanges = false; + let currentSearchResult; function getApiClient() { return connectionManager.getApiClient(currentServerId); @@ -17,14 +36,14 @@ define(['dialogHelper', 'loading', 'connectionManager', 'require', 'globalize', function searchForIdentificationResults(page) { - var lookupInfo = { + let lookupInfo = { ProviderIds: {} }; - var i; - var length; - var identifyField = page.querySelectorAll('.identifyField'); - var value; + let i; + let length; + const identifyField = page.querySelectorAll('.identifyField'); + let value; for (i = 0, length = identifyField.length; i < length; i++) { value = identifyField[i].value; @@ -39,9 +58,9 @@ define(['dialogHelper', 'loading', 'connectionManager', 'require', 'globalize', } } - var hasId = false; + let hasId = false; - var txtLookupId = page.querySelectorAll('.txtLookupId'); + const txtLookupId = page.querySelectorAll('.txtLookupId'); for (i = 0, length = txtLookupId.length; i < length; i++) { value = txtLookupId[i].value; @@ -53,7 +72,7 @@ define(['dialogHelper', 'loading', 'connectionManager', 'require', 'globalize', } if (!hasId && !lookupInfo.Name) { - require(['toast'], function (toast) { + import('toast').then(({default: toast}) => { toast(globalize.translate('PleaseEnterNameOrId')); }); return; @@ -71,16 +90,16 @@ define(['dialogHelper', 'loading', 'connectionManager', 'require', 'globalize', loading.show(); - var apiClient = getApiClient(); + const apiClient = getApiClient(); apiClient.ajax({ type: 'POST', - url: apiClient.getUrl('Items/RemoteSearch/' + currentItemType), + url: apiClient.getUrl(`Items/RemoteSearch/${currentItemType}`), data: JSON.stringify(lookupInfo), contentType: 'application/json', dataType: 'json' - }).then(function (results) { + }).then(results => { loading.hide(); showIdentificationSearchResults(page, results); @@ -89,29 +108,29 @@ define(['dialogHelper', 'loading', 'connectionManager', 'require', 'globalize', function showIdentificationSearchResults(page, results) { - var identificationSearchResults = page.querySelector('.identificationSearchResults'); + const identificationSearchResults = page.querySelector('.identificationSearchResults'); page.querySelector('.popupIdentifyForm').classList.add('hide'); identificationSearchResults.classList.remove('hide'); page.querySelector('.identifyOptionsForm').classList.add('hide'); page.querySelector('.dialogContentInner').classList.remove('dialog-content-centered'); - var html = ''; - var i; - var length; + let html = ''; + let i; + let length; for (i = 0, length = results.length; i < length; i++) { - var result = results[i]; + const result = results[i]; html += getSearchResultHtml(result, i); } - var elem = page.querySelector('.identificationSearchResultList'); + const elem = page.querySelector('.identificationSearchResultList'); elem.innerHTML = html; function onSearchImageClick() { - var index = parseInt(this.getAttribute('data-index')); + const index = parseInt(this.getAttribute('data-index')); - var currentResult = results[index]; + const currentResult = results[index]; if (currentItem != null) { @@ -122,7 +141,7 @@ define(['dialogHelper', 'loading', 'connectionManager', 'require', 'globalize', } } - var searchImages = elem.querySelectorAll('.card'); + const searchImages = elem.querySelectorAll('.card'); for (i = 0, length = searchImages.length; i < length; i++) { searchImages[i].addEventListener('click', onSearchImageClick); @@ -143,7 +162,7 @@ define(['dialogHelper', 'loading', 'connectionManager', 'require', 'globalize', function showIdentifyOptions(page, identifyResult) { - var identifyOptionsForm = page.querySelector('.identifyOptionsForm'); + const identifyOptionsForm = page.querySelector('.identifyOptionsForm'); page.querySelector('.popupIdentifyForm').classList.add('hide'); page.querySelector('.identificationSearchResults').classList.add('hide'); @@ -153,19 +172,19 @@ define(['dialogHelper', 'loading', 'connectionManager', 'require', 'globalize', currentSearchResult = identifyResult; - var lines = []; + const lines = []; lines.push(identifyResult.Name); if (identifyResult.ProductionYear) { lines.push(identifyResult.ProductionYear); } - var resultHtml = lines.join('
'); + let resultHtml = lines.join('
'); if (identifyResult.ImageUrl) { - var displayUrl = getSearchImageDisplayUrl(identifyResult.ImageUrl, identifyResult.SearchProviderName); + const displayUrl = getSearchImageDisplayUrl(identifyResult.ImageUrl, identifyResult.SearchProviderName); - resultHtml = '
' + resultHtml + '
'; + resultHtml = `
${resultHtml}
`; } page.querySelector('.selectedSearchResult').innerHTML = resultHtml; @@ -177,10 +196,10 @@ define(['dialogHelper', 'loading', 'connectionManager', 'require', 'globalize', // TODO move card creation code to Card component - var html = ''; - var cssClass = 'card scalableCard'; - var cardBoxCssClass = 'cardBox'; - var padderClass; + let html = ''; + let cssClass = 'card scalableCard'; + let cardBoxCssClass = 'cardBox'; + let padderClass; if (currentItemType === 'Episode') { cssClass += ' backdropCard backdropCard-scalable'; @@ -203,30 +222,30 @@ define(['dialogHelper', 'loading', 'connectionManager', 'require', 'globalize', cardBoxCssClass += ' cardBox-bottompadded'; - html += ''; + html += ``; } return html; @@ -171,34 +186,34 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan return item.Id; } - function getListViewHtml(options) { + export function getListViewHtml(options) { - var items = options.items; + const items = options.items; - var groupTitle = ''; - var action = options.action || 'link'; + let groupTitle = ''; + const action = options.action || 'link'; - var isLargeStyle = options.imageSize === 'large'; - var enableOverview = options.enableOverview; + const isLargeStyle = options.imageSize === 'large'; + const enableOverview = options.enableOverview; - var clickEntireItem = layoutManager.tv ? true : false; - var outerTagName = clickEntireItem ? 'button' : 'div'; - var enableSideMediaInfo = options.enableSideMediaInfo != null ? options.enableSideMediaInfo : true; + const clickEntireItem = layoutManager.tv ? true : false; + const outerTagName = clickEntireItem ? 'button' : 'div'; + const enableSideMediaInfo = options.enableSideMediaInfo != null ? options.enableSideMediaInfo : true; - var outerHtml = ''; + let outerHtml = ''; - var enableContentWrapper = options.enableOverview && !layoutManager.tv; - var containerAlbumArtistIds = (options.containerAlbumArtists || []).map(getId); + const enableContentWrapper = options.enableOverview && !layoutManager.tv; + const containerAlbumArtistIds = (options.containerAlbumArtists || []).map(getId); - for (var i = 0, length = items.length; i < length; i++) { + for (let i = 0, length = items.length; i < length; i++) { - var item = items[i]; + const item = items[i]; - var html = ''; + let html = ''; if (options.showIndex) { - var itemGroupTitle = getIndex(item, options); + const itemGroupTitle = getIndex(item, options); if (itemGroupTitle !== groupTitle) { @@ -220,7 +235,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan } } - var cssClass = 'listItem'; + let cssClass = 'listItem'; if (options.border || (options.highlight !== false && !layoutManager.tv)) { cssClass += ' listItem-border'; @@ -234,28 +249,28 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan cssClass += ' listItem-focusscale'; } - var downloadWidth = 80; + let downloadWidth = 80; if (isLargeStyle) { cssClass += ' listItem-largeImage'; downloadWidth = 500; } - var playlistItemId = item.PlaylistItemId ? (' data-playlistitemid="' + item.PlaylistItemId + '"') : ''; + const playlistItemId = item.PlaylistItemId ? (` data-playlistitemid="${item.PlaylistItemId}"`) : ''; - var positionTicksData = item.UserData && item.UserData.PlaybackPositionTicks ? (' data-positionticks="' + item.UserData.PlaybackPositionTicks + '"') : ''; - var collectionIdData = options.collectionId ? (' data-collectionid="' + options.collectionId + '"') : ''; - var playlistIdData = options.playlistId ? (' data-playlistid="' + options.playlistId + '"') : ''; - var mediaTypeData = item.MediaType ? (' data-mediatype="' + item.MediaType + '"') : ''; - var collectionTypeData = item.CollectionType ? (' data-collectiontype="' + item.CollectionType + '"') : ''; - var channelIdData = item.ChannelId ? (' data-channelid="' + item.ChannelId + '"') : ''; + const positionTicksData = item.UserData && item.UserData.PlaybackPositionTicks ? (` data-positionticks="${item.UserData.PlaybackPositionTicks}"`) : ''; + const collectionIdData = options.collectionId ? (` data-collectionid="${options.collectionId}"`) : ''; + const playlistIdData = options.playlistId ? (` data-playlistid="${options.playlistId}"`) : ''; + const mediaTypeData = item.MediaType ? (` data-mediatype="${item.MediaType}"`) : ''; + const collectionTypeData = item.CollectionType ? (` data-collectiontype="${item.CollectionType}"`) : ''; + const channelIdData = item.ChannelId ? (` data-channelid="${item.ChannelId}"`) : ''; if (enableContentWrapper) { cssClass += ' listItem-withContentWrapper'; } - html += '<' + outerTagName + ' class="' + cssClass + '"' + playlistItemId + ' data-action="' + action + '" data-isfolder="' + item.IsFolder + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-type="' + item.Type + '"' + mediaTypeData + collectionTypeData + channelIdData + positionTicksData + collectionIdData + playlistIdData + '>'; + html += `<${outerTagName} class="${cssClass}"${playlistItemId} data-action="${action}" data-isfolder="${item.IsFolder}" data-id="${item.Id}" data-serverid="${item.ServerId}" data-type="${item.Type}"${mediaTypeData}${collectionTypeData}${channelIdData}${positionTicksData}${collectionIdData}${playlistIdData}>`; if (enableContentWrapper) { @@ -278,37 +293,37 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan imageClass += ' listItemImage-large-tv'; } - var playOnImageClick = options.imagePlayButton && !layoutManager.tv; + const playOnImageClick = options.imagePlayButton && !layoutManager.tv; if (!clickEntireItem) { imageClass += ' itemAction'; } - var imageAction = playOnImageClick ? 'resume' : action; + const imageAction = playOnImageClick ? 'resume' : action; let blurhashAttrib = ''; if (blurhash && blurhash.length > 0) { - blurhashAttrib = 'data-blurhash="' + blurhash + '"'; + blurhashAttrib = `data-blurhash="${blurhash}"`; } if (imgUrl) { - html += '
'; + html += `
`; } else { - html += '
'; + html += `
`; } - var indicatorsHtml = ''; + let indicatorsHtml = ''; indicatorsHtml += indicators.getPlayedIndicatorHtml(item); if (indicatorsHtml) { - html += '
' + indicatorsHtml + '
'; + html += `
${indicatorsHtml}
`; } if (playOnImageClick) { html += ''; } - var progressHtml = indicators.getProgressBarHtml(item, { + const progressHtml = indicators.getProgressBarHtml(item, { containerClass: 'listItemProgressBar' }); @@ -325,7 +340,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan html += '
'; } - var textlines = []; + const textlines = []; if (options.showProgramDateTime) { textlines.push(datetime.toLocaleString(datetime.parseISO8601Date(item.StartDate), { @@ -348,7 +363,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan } } - var parentTitle = null; + let parentTitle = null; if (options.showParentTitle) { if (item.Type === 'Episode') { @@ -358,12 +373,12 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan } } - var displayName = itemHelper.getDisplayName(item, { + let displayName = itemHelper.getDisplayName(item, { includeParentInfo: options.includeParentInfoInTitle }); if (options.showIndexNumber && item.IndexNumber != null) { - displayName = item.IndexNumber + '. ' + displayName; + displayName = `${item.IndexNumber}. ${displayName}`; } if (options.showParentTitle && options.parentTitleWithTitle) { @@ -394,14 +409,14 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan } } else { - var showArtist = options.artist === true; - var artistItems = item.ArtistItems; + let showArtist = options.artist === true; + const artistItems = item.ArtistItems; if (!showArtist && options.artist !== false) { if (!artistItems || !artistItems.length) { showArtist = true; - } else if (artistItems.length > 1 || containerAlbumArtistIds.indexOf(artistItems[0].Id) === -1) { + } else if (artistItems.length > 1 || !containerAlbumArtistIds.includes(artistItems[0].Id)) { showArtist = true; } } @@ -409,7 +424,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan if (showArtist) { if (artistItems && item.Type !== 'MusicAlbum') { - textlines.push(artistItems.map(function (a) { + textlines.push(artistItems.map(a => { return a.Name; }).join(', ')); } @@ -432,7 +447,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan cssClass += ' listItemBody-noleftpadding'; } - html += '
'; + html += `
`; const moreIcon = 'more_vert'; @@ -441,14 +456,16 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan if (options.mediaInfo !== false) { if (!enableSideMediaInfo) { - var mediaInfoClass = 'secondary listItemMediaInfo listItemBodyText'; + const mediaInfoClass = 'secondary listItemMediaInfo listItemBodyText'; - html += '
' + mediaInfo.getPrimaryMediaInfoHtml(item, { + html += `
`; + html += mediaInfo.getPrimaryMediaInfoHtml(item, { episodeTitle: false, originalAirDate: false, subtitles: false - }) + '
'; + }); + html += '
'; } } @@ -462,7 +479,8 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan if (options.mediaInfo !== false) { if (enableSideMediaInfo) { - html += '
' + mediaInfo.getPrimaryMediaInfoHtml(item, { + html += '
'; + html += mediaInfo.getPrimaryMediaInfoHtml(item, { year: false, container: false, @@ -470,7 +488,8 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan criticRating: false, endsAt: false - }) + '
'; + }); + html += '
'; } } @@ -487,7 +506,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan } if (options.moreButton !== false) { - html += ''; + html += ``; } if (options.infoButton) { @@ -500,15 +519,15 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan if (options.enableUserDataButtons !== false) { - var userData = item.UserData || {}; - var likes = userData.Likes == null ? '' : userData.Likes; + const userData = item.UserData || {}; + const likes = userData.Likes == null ? '' : userData.Likes; if (itemHelper.canMarkPlayed(item)) { - html += ''; + html += ``; } if (itemHelper.canRate(item)) { - html += ''; + html += ``; } } } @@ -524,7 +543,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan } } - html += ''; + html += ``; outerHtml += html; } @@ -532,7 +551,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan return outerHtml; } - return { - getListViewHtml: getListViewHtml - }; -}); +/* eslint-enable indent */ +export default { + getListViewHtml: getListViewHtml +}; From 9e123ad60b48294d47b46e88c2dda30018ddfb2f Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Tue, 9 Jun 2020 22:57:27 +0300 Subject: [PATCH 0014/1168] Migration channelMapper to ES6 modules --- package.json | 1 + src/components/channelMapper/channelMapper.js | 74 +++++++++++-------- src/controllers/livetvstatus.js | 4 +- 3 files changed, 45 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index fd84432e8..dafbb3625 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "src/components/cardbuilder/cardBuilder.js", "src/components/cardbuilder/chaptercardbuilder.js", "src/components/cardbuilder/peoplecardbuilder.js", + "src/components/channelMapper/channelMapper.js", "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", diff --git a/src/components/channelMapper/channelMapper.js b/src/components/channelMapper/channelMapper.js index f2ad88e71..89d085c18 100644 --- a/src/components/channelMapper/channelMapper.js +++ b/src/components/channelMapper/channelMapper.js @@ -1,10 +1,21 @@ -define(['dom', 'dialogHelper', 'loading', 'connectionManager', 'globalize', 'actionsheet', 'emby-input', 'paper-icon-button-light', 'emby-button', 'listViewStyle', 'material-icons', 'formDialogStyle'], function (dom, dialogHelper, loading, connectionManager, globalize, actionsheet) { - 'use strict'; +import dom from 'dom'; +import dialogHelper from 'dialogHelper'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; +import globalize from 'globalize'; +import actionsheet from 'actionsheet'; +import 'emby-input'; +import 'paper-icon-button-light'; +import 'emby-button'; +import 'listViewStyle'; +import 'material-icons'; +import 'formDialogStyle'; - return function (options) { +export default class channelMapper { + constructor(options) { function mapChannel(button, channelId, providerChannelId) { loading.show(); - var providerId = options.providerId; + const providerId = options.providerId; connectionManager.getApiClient(options.serverId).ajax({ type: 'POST', url: ApiClient.getUrl('LiveTv/ChannelMappings'), @@ -14,8 +25,8 @@ define(['dom', 'dialogHelper', 'loading', 'connectionManager', 'globalize', 'act providerChannelId: providerChannelId }, dataType: 'json' - }).then(function (mapping) { - var listItem = dom.parentWithClass(button, 'listItem'); + }).then(mapping => { + const listItem = dom.parentWithClass(button, 'listItem'); button.setAttribute('data-providerid', mapping.ProviderChannelId); listItem.querySelector('.secondary').innerHTML = getMappingSecondaryName(mapping, currentMappingOptions.ProviderName); loading.hide(); @@ -23,42 +34,42 @@ define(['dom', 'dialogHelper', 'loading', 'connectionManager', 'globalize', 'act } function onChannelsElementClick(e) { - var btnMap = dom.parentWithClass(e.target, 'btnMap'); + const btnMap = dom.parentWithClass(e.target, 'btnMap'); if (btnMap) { - var channelId = btnMap.getAttribute('data-id'); - var providerChannelId = btnMap.getAttribute('data-providerid'); - var menuItems = currentMappingOptions.ProviderChannels.map(function (m) { + const channelId = btnMap.getAttribute('data-id'); + const providerChannelId = btnMap.getAttribute('data-providerid'); + const menuItems = currentMappingOptions.ProviderChannels.map(m => { return { name: m.Name, id: m.Id, selected: m.Id.toLowerCase() === providerChannelId.toLowerCase() }; - }).sort(function (a, b) { + }).sort((a, b) => { return a.name.localeCompare(b.name); }); actionsheet.show({ positionTo: btnMap, items: menuItems - }).then(function (newChannelId) { + }).then(newChannelId => { mapChannel(btnMap, channelId, newChannelId); }); } } function getChannelMappingOptions(serverId, providerId) { - var apiClient = connectionManager.getApiClient(serverId); + const apiClient = connectionManager.getApiClient(serverId); return apiClient.getJSON(apiClient.getUrl('LiveTv/ChannelMappingOptions', { providerId: providerId })); } function getMappingSecondaryName(mapping, providerName) { - return (mapping.ProviderChannelName || '') + ' - ' + providerName; + return `${mapping.ProviderChannelName || ''} - ${providerName}`; } function getTunerChannelHtml(channel, providerName) { - var html = ''; + let html = ''; html += '
'; html += ''; html += '
'; @@ -73,16 +84,16 @@ define(['dom', 'dialogHelper', 'loading', 'connectionManager', 'globalize', 'act html += '
'; html += '
'; - html += ''; + html += ``; return html += '
'; } function getEditorHtml() { - var html = ''; + let html = ''; html += '
'; html += '
'; html += '
'; - html += '

' + globalize.translate('HeaderChannels') + '

'; + html += `

${globalize.translate('HeaderChannels')}

`; html += '
'; html += '
'; html += '
'; @@ -91,30 +102,29 @@ define(['dom', 'dialogHelper', 'loading', 'connectionManager', 'globalize', 'act } function initEditor(dlg, options) { - getChannelMappingOptions(options.serverId, options.providerId).then(function (result) { + getChannelMappingOptions(options.serverId, options.providerId).then(result => { currentMappingOptions = result; - var channelsElement = dlg.querySelector('.channels'); - channelsElement.innerHTML = result.TunerChannels.map(function (channel) { + const channelsElement = dlg.querySelector('.channels'); + channelsElement.innerHTML = result.TunerChannels.map(channel => { return getTunerChannelHtml(channel, result.ProviderName); }).join(''); channelsElement.addEventListener('click', onChannelsElementClick); }); } - var currentMappingOptions; - var self = this; + let currentMappingOptions; - self.show = function () { - var dialogOptions = { + this.show = () => { + const dialogOptions = { removeOnClose: true }; dialogOptions.size = 'small'; - var dlg = dialogHelper.createDialog(dialogOptions); + const dlg = dialogHelper.createDialog(dialogOptions); dlg.classList.add('formDialog'); dlg.classList.add('ui-body-a'); dlg.classList.add('background-theme-a'); - var html = ''; - var title = globalize.translate('MapChannels'); + let html = ''; + const title = globalize.translate('MapChannels'); html += '
'; html += ''; html += '

'; @@ -124,13 +134,13 @@ define(['dom', 'dialogHelper', 'loading', 'connectionManager', 'globalize', 'act html += getEditorHtml(); dlg.innerHTML = html; initEditor(dlg, options); - dlg.querySelector('.btnCancel').addEventListener('click', function () { + dlg.querySelector('.btnCancel').addEventListener('click', () => { dialogHelper.close(dlg); }); - return new Promise(function (resolve, reject) { + return new Promise(resolve => { dlg.addEventListener('close', resolve); dialogHelper.open(dlg); }); }; - }; -}); + } +} diff --git a/src/controllers/livetvstatus.js b/src/controllers/livetvstatus.js index 82d0b697d..c6daf53a4 100644 --- a/src/controllers/livetvstatus.js +++ b/src/controllers/livetvstatus.js @@ -155,8 +155,8 @@ define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layo } function mapChannels(page, providerId) { - require(['components/channelMapper/channelMapper'], function (channelmapper) { - new channelmapper({ + require(['components/channelMapper/channelMapper'], function (channelMapper) { + new channelMapper.default({ serverId: ApiClient.serverInfo().Id, providerId: providerId }).show(); From 64125541fbc7d4240ab937c6571521fd0cd352cf Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Tue, 9 Jun 2020 23:03:23 +0300 Subject: [PATCH 0015/1168] Fix bug reporter by sonarqube --- src/components/imageUploader/imageUploader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/imageUploader/imageUploader.js b/src/components/imageUploader/imageUploader.js index e2d2c60f1..ca8322227 100644 --- a/src/components/imageUploader/imageUploader.js +++ b/src/components/imageUploader/imageUploader.js @@ -193,11 +193,11 @@ import 'css!./style'; export function show(options) { - return new Promise((resolve, reject) => { + return new Promise(resolve => { hasChanges = false; - showEditor(options, resolve, reject); + showEditor(options, resolve); }); } From 2d53cb5f8538543822abb356bb4faeafea0d11d9 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Thu, 11 Jun 2020 21:52:00 +0300 Subject: [PATCH 0016/1168] replace require with Dynamic Imports --- src/components/mediaLibraryCreator/mediaLibraryCreator.js | 3 +-- src/components/mediaLibraryEditor/mediaLibraryEditor.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/mediaLibraryCreator/mediaLibraryCreator.js b/src/components/mediaLibraryCreator/mediaLibraryCreator.js index c7011ba1d..6940da1ba 100644 --- a/src/components/mediaLibraryCreator/mediaLibraryCreator.js +++ b/src/components/mediaLibraryCreator/mediaLibraryCreator.js @@ -201,8 +201,7 @@ export class editor { currentOptions = options; currentResolve = resolve; hasChanges = false; - // TODO: remove require - require(['text!./components/mediaLibraryCreator/mediaLibraryCreator.template.html'], template => { + import('text!./components/mediaLibraryCreator/mediaLibraryCreator.template.html').then(({default: template}) => { const dlg = dialogHelper.createDialog({ size: 'small', modal: false, diff --git a/src/components/mediaLibraryEditor/mediaLibraryEditor.js b/src/components/mediaLibraryEditor/mediaLibraryEditor.js index 5b533b2ac..7996867b2 100644 --- a/src/components/mediaLibraryEditor/mediaLibraryEditor.js +++ b/src/components/mediaLibraryEditor/mediaLibraryEditor.js @@ -216,8 +216,7 @@ export class editor { currentOptions = options; currentDeferred = deferred; hasChanges = false; - // TODO: remove require - require(['text!./components/mediaLibraryEditor/mediaLibraryEditor.template.html'], template => { + import('text!./components/mediaLibraryEditor/mediaLibraryEditor.template.html').then(({default: template}) => { const dlg = dialogHelper.createDialog({ size: 'small', modal: false, From cf1ca53f9c8ed65ab8f492ad2ba3fdf257bcf938 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Thu, 11 Jun 2020 22:07:24 +0300 Subject: [PATCH 0017/1168] replace require with Dynamic Imports --- src/components/imageOptionsEditor/imageOptionsEditor.js | 3 +-- .../libraryoptionseditor/libraryoptionseditor.js | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/imageOptionsEditor/imageOptionsEditor.js b/src/components/imageOptionsEditor/imageOptionsEditor.js index 5e4f88f15..a1e7f71a9 100644 --- a/src/components/imageOptionsEditor/imageOptionsEditor.js +++ b/src/components/imageOptionsEditor/imageOptionsEditor.js @@ -93,8 +93,7 @@ export class editor { constructor() { this.show = (itemType, options, availableOptions) => { return new Promise((resolve) => { - //TODO: remove require - require(['text!./components/imageOptionsEditor/imageOptionsEditor.template.html'], template => { + import('text!./components/imageOptionsEditor/imageOptionsEditor.template.html').then(({default: template}) => { const dlg = dialogHelper.createDialog({ size: 'small', removeOnClose: true, diff --git a/src/components/libraryoptionseditor/libraryoptionseditor.js b/src/components/libraryoptionseditor/libraryoptionseditor.js index f9a9d4327..6a5f4f6e9 100644 --- a/src/components/libraryoptionseditor/libraryoptionseditor.js +++ b/src/components/libraryoptionseditor/libraryoptionseditor.js @@ -268,8 +268,8 @@ import 'emby-input'; return true; } - function populateMetadataSettings(parent, contentType, isNewLibrary) { - isNewLibrary = parent.classList.contains('newlibrary'); + function populateMetadataSettings(parent, contentType) { + const isNewLibrary = parent.classList.contains('newlibrary'); return ApiClient.getJSON(ApiClient.getUrl('Libraries/AvailableOptions', { LibraryContentType: contentType, IsNewLibrary: isNewLibrary @@ -365,8 +365,7 @@ import 'emby-input'; const isNewLibrary = null === libraryOptions; isNewLibrary && parent.classList.add('newlibrary'); return new Promise((resolve) => { - //TODO: remove require - require(['text!./components/libraryoptionseditor/libraryoptionseditor.template.html'], function (template) { + import('text!./libraryoptionseditor.template.html').then(({default: template}) => { parent.innerHTML = globalize.translateDocument(template); populateRefreshInterval(parent.querySelector('#selectAutoRefreshInterval')); const promises = [populateLanguages(parent), populateCountries(parent.querySelector('#selectCountry'))]; From b7d9dba32feccb6225f435326b7ff3c17329efa4 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Thu, 11 Jun 2020 23:21:46 +0300 Subject: [PATCH 0018/1168] replace require with Dynamic Imports --- src/components/imageUploader/imageUploader.js | 3 +-- src/components/itemMediaInfo/itemMediaInfo.js | 3 +-- src/components/itemidentifier/itemidentifier.js | 7 +++---- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/imageUploader/imageUploader.js b/src/components/imageUploader/imageUploader.js index ca8322227..fec536388 100644 --- a/src/components/imageUploader/imageUploader.js +++ b/src/components/imageUploader/imageUploader.js @@ -141,8 +141,7 @@ import 'css!./style'; options = options || {}; - // TODO: remove require - require(['text!./components/imageUploader/imageUploader.template.html'], template => { + import('text!./imageUploader.template.html').then(({default: template}) => { currentItemId = options.itemId; currentServerId = options.serverId; diff --git a/src/components/itemMediaInfo/itemMediaInfo.js b/src/components/itemMediaInfo/itemMediaInfo.js index 492b27e2c..dcfaf3864 100644 --- a/src/components/itemMediaInfo/itemMediaInfo.js +++ b/src/components/itemMediaInfo/itemMediaInfo.js @@ -169,8 +169,7 @@ import 'flexStyles'; export function show(itemId, serverId) { loading.show(); return new Promise((resolve, reject) => { - // TODO: remove require - require(['text!./components/itemMediaInfo/itemMediaInfo.template.html'], template => { + import('text!./itemMediaInfo.template.html').then(({default: template}) => { loadMediaInfo(itemId, serverId, template).then(resolve, reject); }); }); diff --git a/src/components/itemidentifier/itemidentifier.js b/src/components/itemidentifier/itemidentifier.js index a1520928c..10655b127 100644 --- a/src/components/itemidentifier/itemidentifier.js +++ b/src/components/itemidentifier/itemidentifier.js @@ -357,8 +357,7 @@ import 'cardStyle'; loading.show(); - // TODO: remove require - require(['text!./components/itemidentifier/itemidentifier.template.html'], template => { + import('text!./itemidentifier.template.html').then(({default: template}) => { const apiClient = getApiClient(); @@ -441,13 +440,13 @@ import 'cardStyle'; } } + //TODO investigate where was used this? function showEditorFindNew(itemName, itemYear, itemType, resolveFunc) { currentItem = null; currentItemType = itemType; - // TODO: remove require - require(['text!./components/itemidentifier/itemidentifier.template.html'], template => { + import('text!./itemidentifier.template.html').then(({default: template}) => { const dialogOptions = { size: 'small', From 7b93106bc93fd776d78f1a626e3b905ed4afd420 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Fri, 12 Jun 2020 01:09:35 +0300 Subject: [PATCH 0019/1168] Migration alphaPicker to ES6 modules --- package.json | 1 + src/components/alphaPicker/alphaPicker.js | 406 +++++++++++----------- src/components/search/searchfields.js | 2 +- src/components/tabbedview/itemstab.js | 2 +- src/controllers/list.js | 4 +- src/controllers/movies/movies.js | 4 +- src/controllers/movies/movietrailers.js | 4 +- src/controllers/music/musicalbums.js | 4 +- src/controllers/music/musicartists.js | 4 +- src/controllers/shows/tvshows.js | 4 +- 10 files changed, 224 insertions(+), 211 deletions(-) diff --git a/package.json b/package.json index 785878d20..cf8b33ca6 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ { "test": [ "src/components/actionSheet/actionSheet.js", + "src/components/alphaPicker/alphaPicker.js", "src/components/autoFocuser.js", "src/components/cardbuilder/cardBuilder.js", "src/components/images/imageLoader.js", diff --git a/src/components/alphaPicker/alphaPicker.js b/src/components/alphaPicker/alphaPicker.js index 79f74879e..576e35cb4 100644 --- a/src/components/alphaPicker/alphaPicker.js +++ b/src/components/alphaPicker/alphaPicker.js @@ -1,11 +1,22 @@ -define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-button-light', 'material-icons'], function (focusManager, layoutManager, dom) { - 'use strict'; +/* eslint-disable indent */ - var selectedButtonClass = 'alphaPickerButton-selected'; +/** + * Module alphaPicker. + * @module components/alphaPicker/alphaPicker + */ + +import focusManager from 'focusManager'; +import layoutManager from 'layoutManager'; +import dom from 'dom'; +import 'css!./style.css'; +import 'paper-icon-button-light'; +import 'material-icons'; + + const selectedButtonClass = 'alphaPickerButton-selected'; function focus() { - var scope = this; - var selected = scope.querySelector('.' + selectedButtonClass); + const scope = this; + const selected = scope.querySelector(`.${selectedButtonClass}`); if (selected) { focusManager.focus(selected); @@ -16,7 +27,7 @@ define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-b function getAlphaPickerButtonClassName(vertical) { - var alphaPickerButtonClassName = 'alphaPickerButton'; + let alphaPickerButtonClassName = 'alphaPickerButton'; if (layoutManager.tv) { alphaPickerButtonClassName += ' alphaPickerButton-tv'; @@ -30,12 +41,12 @@ define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-b } function getLetterButton(l, vertical) { - return ''; + return ``; } function mapLetters(letters, vertical) { - return letters.map(function (l) { + return letters.map(l => { return getLetterButton(l, vertical); }); } @@ -48,26 +59,26 @@ define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-b element.classList.add('alphaPicker-tv'); } - var vertical = element.classList.contains('alphaPicker-vertical'); + const vertical = element.classList.contains('alphaPicker-vertical'); if (!vertical) { element.classList.add('focuscontainer-x'); } - var html = ''; - var letters; + let html = ''; + let letters; - var alphaPickerButtonClassName = getAlphaPickerButtonClassName(vertical); + const alphaPickerButtonClassName = getAlphaPickerButtonClassName(vertical); - var rowClassName = 'alphaPickerRow'; + let rowClassName = 'alphaPickerRow'; if (vertical) { rowClassName += ' alphaPickerRow-vertical'; } - html += '
'; + html += `
`; if (options.mode === 'keyboard') { - html += ''; + html += ``; } else { letters = ['#']; html += mapLetters(letters, vertical).join(''); @@ -77,11 +88,11 @@ define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-b html += mapLetters(letters, vertical).join(''); if (options.mode === 'keyboard') { - html += ''; + html += ``; html += '
'; letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; - html += '
'; + html += `
`; html += '
'; html += mapLetters(letters, vertical).join(''); html += '
'; @@ -95,227 +106,228 @@ define(['focusManager', 'layoutManager', 'dom', 'css!./style.css', 'paper-icon-b element.focus = focus; } - function AlphaPicker(options) { + export class AlphaPicker { + constructor(options) { - var self = this; - this.options = options; + this.options = options; - var element = options.element; - var itemsContainer = options.itemsContainer; - var itemClass = options.itemClass; + const element = options.element; + const itemsContainer = options.itemsContainer; + const itemClass = options.itemClass; - var itemFocusValue; - var itemFocusTimeout; + let itemFocusValue; + let itemFocusTimeout; - function onItemFocusTimeout() { - itemFocusTimeout = null; - self.value(itemFocusValue); - } - - var alphaFocusedElement; - var alphaFocusTimeout; - - function onAlphaFocusTimeout() { - - alphaFocusTimeout = null; - - if (document.activeElement === alphaFocusedElement) { - var value = alphaFocusedElement.getAttribute('data-value'); - self.value(value, true); + function onItemFocusTimeout() { + itemFocusTimeout = null; + this.value(itemFocusValue); } - } - function onAlphaPickerInKeyboardModeClick(e) { + let alphaFocusedElement; + let alphaFocusTimeout; - var alphaPickerButton = dom.parentWithClass(e.target, 'alphaPickerButton'); + function onAlphaFocusTimeout() { - if (alphaPickerButton) { - var value = alphaPickerButton.getAttribute('data-value'); - - element.dispatchEvent(new CustomEvent('alphavalueclicked', { - cancelable: false, - detail: { - value: value - } - })); - } - } - - function onAlphaPickerClick(e) { - - var alphaPickerButton = dom.parentWithClass(e.target, 'alphaPickerButton'); - - if (alphaPickerButton) { - var value = alphaPickerButton.getAttribute('data-value'); - if ((this._currentValue || '').toUpperCase() === value.toUpperCase()) { - self.value(null, true); - } else { - self.value(value, true); - } - } - } - - function onAlphaPickerFocusIn(e) { - - if (alphaFocusTimeout) { - clearTimeout(alphaFocusTimeout); alphaFocusTimeout = null; + + if (document.activeElement === alphaFocusedElement) { + const value = alphaFocusedElement.getAttribute('data-value'); + this.value(value, true); + } } - var alphaPickerButton = dom.parentWithClass(e.target, 'alphaPickerButton'); + function onAlphaPickerInKeyboardModeClick(e) { - if (alphaPickerButton) { - alphaFocusedElement = alphaPickerButton; - alphaFocusTimeout = setTimeout(onAlphaFocusTimeout, 600); + const alphaPickerButton = dom.parentWithClass(e.target, 'alphaPickerButton'); + + if (alphaPickerButton) { + const value = alphaPickerButton.getAttribute('data-value'); + + element.dispatchEvent(new CustomEvent('alphavalueclicked', { + cancelable: false, + detail: { + value + } + })); + } } - } - function onItemsFocusIn(e) { + function onAlphaPickerClick(e) { - var item = dom.parentWithClass(e.target, itemClass); + const alphaPickerButton = dom.parentWithClass(e.target, 'alphaPickerButton'); - if (item) { - var prefix = item.getAttribute('data-prefix'); - if (prefix && prefix.length) { - - itemFocusValue = prefix[0]; - if (itemFocusTimeout) { - clearTimeout(itemFocusTimeout); + if (alphaPickerButton) { + const value = alphaPickerButton.getAttribute('data-value'); + if ((this._currentValue || '').toUpperCase() === value.toUpperCase()) { + this.value(null, true); + } else { + this.value(value, true); } - itemFocusTimeout = setTimeout(onItemFocusTimeout, 100); } } - } - self.enabled = function (enabled) { + function onAlphaPickerFocusIn(e) { - if (enabled) { - - if (itemsContainer) { - itemsContainer.addEventListener('focus', onItemsFocusIn, true); + if (alphaFocusTimeout) { + clearTimeout(alphaFocusTimeout); + alphaFocusTimeout = null; } - if (options.mode === 'keyboard') { - element.addEventListener('click', onAlphaPickerInKeyboardModeClick); - } + const alphaPickerButton = dom.parentWithClass(e.target, 'alphaPickerButton'); + + if (alphaPickerButton) { + alphaFocusedElement = alphaPickerButton; + alphaFocusTimeout = setTimeout(onAlphaFocusTimeout, 600); + } + } + + function onItemsFocusIn(e) { + + const item = dom.parentWithClass(e.target, itemClass); + + if (item) { + const prefix = item.getAttribute('data-prefix'); + if (prefix && prefix.length) { + + itemFocusValue = prefix[0]; + if (itemFocusTimeout) { + clearTimeout(itemFocusTimeout); + } + itemFocusTimeout = setTimeout(onItemFocusTimeout, 100); + } + } + } + + this.enabled = function (enabled) { + + if (enabled) { + + if (itemsContainer) { + itemsContainer.addEventListener('focus', onItemsFocusIn, true); + } + + if (options.mode === 'keyboard') { + element.addEventListener('click', onAlphaPickerInKeyboardModeClick); + } + + if (options.valueChangeEvent !== 'click') { + element.addEventListener('focus', onAlphaPickerFocusIn, true); + } else { + element.addEventListener('click', onAlphaPickerClick.bind(this)); + } - if (options.valueChangeEvent !== 'click') { - element.addEventListener('focus', onAlphaPickerFocusIn, true); } else { - element.addEventListener('click', onAlphaPickerClick.bind(this)); - } - } else { - - if (itemsContainer) { - itemsContainer.removeEventListener('focus', onItemsFocusIn, true); - } - - element.removeEventListener('click', onAlphaPickerInKeyboardModeClick); - element.removeEventListener('focus', onAlphaPickerFocusIn, true); - element.removeEventListener('click', onAlphaPickerClick.bind(this)); - } - }; - - render(element, options); - - this.enabled(true); - this.visible(true); - } - - AlphaPicker.prototype.value = function (value, applyValue) { - - var element = this.options.element; - var btn; - var selected; - - if (value !== undefined) { - if (value != null) { - - value = value.toUpperCase(); - this._currentValue = value; - - if (this.options.mode !== 'keyboard') { - selected = element.querySelector('.' + selectedButtonClass); - - try { - btn = element.querySelector('.alphaPickerButton[data-value=\'' + value + '\']'); - } catch (err) { - console.error('error in querySelector: ' + err); + if (itemsContainer) { + itemsContainer.removeEventListener('focus', onItemsFocusIn, true); } - if (btn && btn !== selected) { - btn.classList.add(selectedButtonClass); + element.removeEventListener('click', onAlphaPickerInKeyboardModeClick); + element.removeEventListener('focus', onAlphaPickerFocusIn, true); + element.removeEventListener('click', onAlphaPickerClick.bind(this)); + } + }; + + render(element, options); + + this.enabled(true); + this.visible(true); + } + + value(value, applyValue) { + + const element = this.options.element; + let btn; + let selected; + + if (value !== undefined) { + if (value != null) { + + value = value.toUpperCase(); + this._currentValue = value; + + if (this.options.mode !== 'keyboard') { + selected = element.querySelector(`.${selectedButtonClass}`); + + try { + btn = element.querySelector(`.alphaPickerButton[data-value='${value}']`); + } catch (err) { + console.error(`error in querySelector: ${err}`); + } + + if (btn && btn !== selected) { + btn.classList.add(selectedButtonClass); + } + if (selected && selected !== btn) { + selected.classList.remove(selectedButtonClass); + } } - if (selected && selected !== btn) { + } else { + this._currentValue = value; + + selected = element.querySelector(`.${selectedButtonClass}`); + if (selected) { selected.classList.remove(selectedButtonClass); } } - } else { - this._currentValue = value; - - selected = element.querySelector('.' + selectedButtonClass); - if (selected) { - selected.classList.remove(selectedButtonClass); - } } + + if (applyValue) { + element.dispatchEvent(new CustomEvent('alphavaluechanged', { + cancelable: false, + detail: { + value + } + })); + } + + return this._currentValue; } - if (applyValue) { - element.dispatchEvent(new CustomEvent('alphavaluechanged', { - cancelable: false, - detail: { - value: value - } - })); + on(name, fn) { + const element = this.options.element; + element.addEventListener(name, fn); } - return this._currentValue; - }; - - AlphaPicker.prototype.on = function (name, fn) { - var element = this.options.element; - element.addEventListener(name, fn); - }; - - AlphaPicker.prototype.off = function (name, fn) { - var element = this.options.element; - element.removeEventListener(name, fn); - }; - - AlphaPicker.prototype.visible = function (visible) { - - var element = this.options.element; - element.style.visibility = visible ? 'visible' : 'hidden'; - }; - - AlphaPicker.prototype.values = function () { - - var element = this.options.element; - var elems = element.querySelectorAll('.alphaPickerButton'); - var values = []; - for (var i = 0, length = elems.length; i < length; i++) { - - values.push(elems[i].getAttribute('data-value')); - + off(name, fn) { + const element = this.options.element; + element.removeEventListener(name, fn); } - return values; - }; + visible(visible) { - AlphaPicker.prototype.focus = function () { + const element = this.options.element; + element.style.visibility = visible ? 'visible' : 'hidden'; + } - var element = this.options.element; - focusManager.autoFocus(element, true); - }; + values() { - AlphaPicker.prototype.destroy = function () { + const element = this.options.element; + const elems = element.querySelectorAll('.alphaPickerButton'); + const values = []; + for (let i = 0, length = elems.length; i < length; i++) { - var element = this.options.element; - this.enabled(false); - element.classList.remove('focuscontainer-x'); - this.options = null; - }; + values.push(elems[i].getAttribute('data-value')); - return AlphaPicker; -}); + } + + return values; + } + + focus() { + + const element = this.options.element; + focusManager.autoFocus(element, true); + } + + destroy() { + + const element = this.options.element; + this.enabled(false); + element.classList.remove('focuscontainer-x'); + this.options = null; + } + } + +/* eslint-enable indent */ +export default AlphaPicker; diff --git a/src/components/search/searchfields.js b/src/components/search/searchfields.js index 53ab187a8..7e7781477 100644 --- a/src/components/search/searchfields.js +++ b/src/components/search/searchfields.js @@ -43,7 +43,7 @@ define(['layoutManager', 'globalize', 'require', 'events', 'browser', 'alphaPick function initAlphaPicker(alphaPickerElement, instance) { - instance.alphaPicker = new AlphaPicker({ + instance.alphaPicker = new AlphaPicker.default({ element: alphaPickerElement, mode: 'keyboard' }); diff --git a/src/components/tabbedview/itemstab.js b/src/components/tabbedview/itemstab.js index 884cfa201..4aac2f747 100644 --- a/src/components/tabbedview/itemstab.js +++ b/src/components/tabbedview/itemstab.js @@ -51,7 +51,7 @@ define(['playbackManager', 'userSettings', 'alphaPicker', 'alphaNumericShortcuts instance.itemsContainer = view.querySelector('.itemsContainer'); - instance.alphaPicker = new AlphaPicker({ + instance.alphaPicker = new AlphaPicker.default({ element: instance.alphaPickerElement, itemsContainer: instance.itemsContainer, itemClass: 'card' diff --git a/src/controllers/list.js b/src/controllers/list.js index d05616ec9..fafbd1b41 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -1,4 +1,4 @@ -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) { +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'; function getInitialLiveTvQuery(instance, params) { @@ -544,7 +544,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' alphaPickerElement.classList.add('focuscontainer-right'); self.itemsContainer.parentNode.classList.add('padded-right-withalphapicker'); - self.alphaPicker = new alphaPicker({ + self.alphaPicker = new AlphaPicker.default({ element: alphaPickerElement, itemsContainer: layoutManager.tv ? self.itemsContainer : null, itemClass: 'card', diff --git a/src/controllers/movies/movies.js b/src/controllers/movies/movies.js index 89bcc215e..55947e6a9 100644 --- a/src/controllers/movies/movies.js +++ b/src/controllers/movies/movies.js @@ -1,4 +1,4 @@ -define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser', 'alphaPicker', 'listView', 'cardBuilder', 'globalize', 'emby-itemscontainer'], function (loading, layoutManager, userSettings, events, libraryBrowser, alphaPicker, listView, cardBuilder, globalize) { +define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser', 'alphaPicker', 'listView', 'cardBuilder', 'globalize', 'emby-itemscontainer'], function (loading, layoutManager, userSettings, events, libraryBrowser, AlphaPicker, listView, cardBuilder, globalize) { 'use strict'; return function (view, params, tabContent, options) { @@ -168,7 +168,7 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser', query.StartIndex = 0; itemsContainer.refreshItems(); }); - self.alphaPicker = new alphaPicker({ + self.alphaPicker = new AlphaPicker.default({ element: alphaPickerElement, valueChangeEvent: 'click' }); diff --git a/src/controllers/movies/movietrailers.js b/src/controllers/movies/movietrailers.js index 25d41d4fb..9a7d4c009 100644 --- a/src/controllers/movies/movietrailers.js +++ b/src/controllers/movies/movietrailers.js @@ -1,4 +1,4 @@ -define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, userSettings, globalize) { +define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (layoutManager, loading, events, libraryBrowser, imageLoader, AlphaPicker, listView, cardBuilder, userSettings, globalize) { 'use strict'; return function (view, params, tabContent) { @@ -208,7 +208,7 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' query.StartIndex = 0; reloadItems(); }); - self.alphaPicker = new alphaPicker({ + self.alphaPicker = new AlphaPicker.default({ element: alphaPickerElement, valueChangeEvent: 'click' }); diff --git a/src/controllers/music/musicalbums.js b/src/controllers/music/musicalbums.js index ecb51f9dc..b9f1333e6 100644 --- a/src/controllers/music/musicalbums.js +++ b/src/controllers/music/musicalbums.js @@ -1,4 +1,4 @@ -define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, userSettings, globalize) { +define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, AlphaPicker, listView, cardBuilder, userSettings, globalize) { 'use strict'; return function (view, params, tabContent) { @@ -215,7 +215,7 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser query.StartIndex = 0; reloadItems(tabContent); }); - self.alphaPicker = new alphaPicker({ + self.alphaPicker = new AlphaPicker.default({ element: alphaPickerElement, valueChangeEvent: 'click' }); diff --git a/src/controllers/music/musicartists.js b/src/controllers/music/musicartists.js index bd9341be6..4341250f8 100644 --- a/src/controllers/music/musicartists.js +++ b/src/controllers/music/musicartists.js @@ -1,4 +1,4 @@ -define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'apphost', 'userSettings', 'emby-itemscontainer'], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost, userSettings) { +define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'apphost', 'userSettings', 'emby-itemscontainer'], function (layoutManager, loading, events, libraryBrowser, imageLoader, AlphaPicker, listView, cardBuilder, appHost, userSettings) { 'use strict'; return function (view, params, tabContent) { @@ -199,7 +199,7 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' query.StartIndex = 0; reloadItems(tabContent); }); - self.alphaPicker = new alphaPicker({ + self.alphaPicker = new AlphaPicker.default({ element: alphaPickerElement, valueChangeEvent: 'click' }); diff --git a/src/controllers/shows/tvshows.js b/src/controllers/shows/tvshows.js index 753516f90..0aa2dd444 100644 --- a/src/controllers/shows/tvshows.js +++ b/src/controllers/shows/tvshows.js @@ -1,4 +1,4 @@ -define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardBuilder', 'alphaPicker', 'userSettings', 'globalize', 'emby-itemscontainer'], function (layoutManager, loading, events, libraryBrowser, imageLoader, listView, cardBuilder, alphaPicker, userSettings, globalize) { +define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardBuilder', 'alphaPicker', 'userSettings', 'globalize', 'emby-itemscontainer'], function (layoutManager, loading, events, libraryBrowser, imageLoader, listView, cardBuilder, AlphaPicker, userSettings, globalize) { 'use strict'; return function (view, params, tabContent) { @@ -226,7 +226,7 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' query.StartIndex = 0; reloadItems(tabContent); }); - self.alphaPicker = new alphaPicker({ + self.alphaPicker = new AlphaPicker.default({ element: alphaPickerElement, valueChangeEvent: 'click' }); From 7f87c4671df12b8efaed65e1cc921a51efd5d2cd Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com> Date: Fri, 12 Jun 2020 16:37:11 +0300 Subject: [PATCH 0020/1168] Fix 'this' in event handler --- 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 0c00bbc80..0db6999ba 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -135,7 +135,7 @@ function embed(options, self) { options.element.classList.add('subtitlesettings'); options.element.innerHTML = globalize.translateDocument(template, 'core'); - options.element.querySelector('form').addEventListener('submit', self.onSubmit ); + options.element.querySelector('form').addEventListener('submit', self.onSubmit.bind(self)); options.element.querySelector('#selectSubtitlePlaybackMode').addEventListener('change', onSubtitleModeChange); options.element.querySelector('#selectTextSize').addEventListener('change', onAppearanceFieldChange); From 857c1d8e2a5e05c7c8fcf8b714fa536373bb990c Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Sat, 13 Jun 2020 17:33:56 +0300 Subject: [PATCH 0021/1168] apply suggestion --- src/components/imageOptionsEditor/imageOptionsEditor.js | 4 ++-- src/components/libraryoptionseditor/libraryoptionseditor.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/imageOptionsEditor/imageOptionsEditor.js b/src/components/imageOptionsEditor/imageOptionsEditor.js index a1e7f71a9..2a3022b0d 100644 --- a/src/components/imageOptionsEditor/imageOptionsEditor.js +++ b/src/components/imageOptionsEditor/imageOptionsEditor.js @@ -92,8 +92,8 @@ import 'emby-input'; export class editor { constructor() { this.show = (itemType, options, availableOptions) => { - return new Promise((resolve) => { - import('text!./components/imageOptionsEditor/imageOptionsEditor.template.html').then(({default: template}) => { + return import('text!./components/imageOptionsEditor/imageOptionsEditor.template.html').then(({default: template}) => { + return new Promise((resolve) => { const dlg = dialogHelper.createDialog({ size: 'small', removeOnClose: true, diff --git a/src/components/libraryoptionseditor/libraryoptionseditor.js b/src/components/libraryoptionseditor/libraryoptionseditor.js index 6a5f4f6e9..8b365e51a 100644 --- a/src/components/libraryoptionseditor/libraryoptionseditor.js +++ b/src/components/libraryoptionseditor/libraryoptionseditor.js @@ -364,8 +364,8 @@ import 'emby-input'; currentAvailableOptions = null; const isNewLibrary = null === libraryOptions; isNewLibrary && parent.classList.add('newlibrary'); - return new Promise((resolve) => { - import('text!./libraryoptionseditor.template.html').then(({default: template}) => { + return import('text!./libraryoptionseditor.template.html').then(({default: template}) => { + return new Promise((resolve) => { parent.innerHTML = globalize.translateDocument(template); populateRefreshInterval(parent.querySelector('#selectAutoRefreshInterval')); const promises = [populateLanguages(parent), populateCountries(parent.querySelector('#selectCountry'))]; From 09fe6b4d3b3c07941d01d733d137b68b090f3440 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Sat, 13 Jun 2020 17:44:54 +0300 Subject: [PATCH 0022/1168] apply suggestion --- src/components/imageUploader/imageUploader.js | 2 +- src/components/itemMediaInfo/itemMediaInfo.js | 4 ++-- src/components/itemidentifier/itemidentifier.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/imageUploader/imageUploader.js b/src/components/imageUploader/imageUploader.js index fec536388..345475b53 100644 --- a/src/components/imageUploader/imageUploader.js +++ b/src/components/imageUploader/imageUploader.js @@ -141,7 +141,7 @@ import 'css!./style'; options = options || {}; - import('text!./imageUploader.template.html').then(({default: template}) => { + return import('text!./imageUploader.template.html').then(({default: template}) => { currentItemId = options.itemId; currentServerId = options.serverId; diff --git a/src/components/itemMediaInfo/itemMediaInfo.js b/src/components/itemMediaInfo/itemMediaInfo.js index dcfaf3864..9c2c8c966 100644 --- a/src/components/itemMediaInfo/itemMediaInfo.js +++ b/src/components/itemMediaInfo/itemMediaInfo.js @@ -168,8 +168,8 @@ import 'flexStyles'; export function show(itemId, serverId) { loading.show(); - return new Promise((resolve, reject) => { - import('text!./itemMediaInfo.template.html').then(({default: template}) => { + return import('text!./itemMediaInfo.template.html').then(({default: template}) => { + return new Promise((resolve, reject) => { loadMediaInfo(itemId, serverId, template).then(resolve, reject); }); }); diff --git a/src/components/itemidentifier/itemidentifier.js b/src/components/itemidentifier/itemidentifier.js index 10655b127..9b3afcde2 100644 --- a/src/components/itemidentifier/itemidentifier.js +++ b/src/components/itemidentifier/itemidentifier.js @@ -357,7 +357,7 @@ import 'cardStyle'; loading.show(); - import('text!./itemidentifier.template.html').then(({default: template}) => { + return import('text!./itemidentifier.template.html').then(({default: template}) => { const apiClient = getApiClient(); @@ -446,7 +446,7 @@ import 'cardStyle'; currentItem = null; currentItemType = itemType; - import('text!./itemidentifier.template.html').then(({default: template}) => { + return import('text!./itemidentifier.template.html').then(({default: template}) => { const dialogOptions = { size: 'small', From 5cca460986d3f43232d5e5e18f94cdc742cb61dc Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Sat, 13 Jun 2020 19:32:38 +0300 Subject: [PATCH 0023/1168] Migration mediainfo to ES6 modules --- package.json | 1 + src/components/mediainfo/mediainfo.js | 192 ++++++++++++++------------ 2 files changed, 102 insertions(+), 91 deletions(-) diff --git a/package.json b/package.json index 91d070e04..308979060 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", + "src/components/mediainfo/mediainfo.js", "src/components/playback/brightnessosd.js", "src/components/playback/mediasession.js", "src/components/playback/nowplayinghelper.js", diff --git a/src/components/mediainfo/mediainfo.js b/src/components/mediainfo/mediainfo.js index 7de11c42f..f64e67035 100644 --- a/src/components/mediainfo/mediainfo.js +++ b/src/components/mediainfo/mediainfo.js @@ -1,9 +1,18 @@ -define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'material-icons', 'css!./mediainfo.css', 'programStyles', 'emby-button'], function (datetime, globalize, appRouter, itemHelper, indicators) { - 'use strict'; +import datetime from 'datetime'; +import globalize from 'globalize'; +import appRouter from 'appRouter'; +import itemHelper from 'itemHelper'; +import indicators from 'indicators'; +import 'material-icons'; +import 'css!./mediainfo.css'; +import 'programStyles'; +import 'emby-button'; + +/* eslint-disable indent */ function getTimerIndicator(item) { - var status; + let status; if (item.Type === 'SeriesTimer') { return ''; @@ -30,11 +39,11 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater } function getProgramInfoHtml(item, options) { - var html = ''; + let html = ''; - var miscInfo = []; - var text; - var date; + const miscInfo = []; + let text; + let date; if (item.StartDate && options.programTime !== false) { @@ -48,35 +57,35 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater text += datetime.toLocaleDateString(date, { weekday: 'short', month: 'short', day: 'numeric' }); } - text += ' ' + datetime.getDisplayTime(date); + text += ` ${datetime.getDisplayTime(date)}`; if (item.EndDate) { date = datetime.parseISO8601Date(item.EndDate); - text += ' - ' + datetime.getDisplayTime(date); + text += ` - ${datetime.getDisplayTime(date)}`; } miscInfo.push(text); } catch (e) { - console.error('error parsing date: ' + item.StartDate); + console.error(`error parsing date: ${item.StartDate}`); } } if (item.ChannelNumber) { - miscInfo.push('CH ' + item.ChannelNumber); + miscInfo.push(`CH ${item.ChannelNumber}`); } if (item.ChannelName) { if (options.interactive && item.ChannelId) { miscInfo.push({ - html: '' + item.ChannelName + '' + })}">${item.ChannelName}` }); } else { miscInfo.push(item.ChannelName); @@ -84,7 +93,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater } if (options.timerIndicator !== false) { - var timerHtml = getTimerIndicator(item); + const timerHtml = getTimerIndicator(item); if (timerHtml) { miscInfo.push({ html: timerHtml @@ -92,24 +101,24 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater } } - html += miscInfo.map(function (m) { + html += miscInfo.map(m => { return getMediaInfoItem(m); }).join(''); return html; } - function getMediaInfoHtml(item, options) { - var html = ''; + export function getMediaInfoHtml(item, options) { + let html = ''; - var miscInfo = []; + const miscInfo = []; options = options || {}; - var text; - var date; - var minutes; - var count; + let text; + let date; + let minutes; + let count; - var showFolderRuntime = item.Type === 'MusicAlbum' || item.MediaType === 'MusicArtist' || item.MediaType === 'Playlist' || item.MediaType === 'MusicGenre'; + const showFolderRuntime = item.Type === 'MusicAlbum' || item.MediaType === 'MusicArtist' || item.MediaType === 'Playlist' || item.MediaType === 'MusicGenre'; if (showFolderRuntime) { @@ -143,7 +152,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater text = datetime.toLocaleDateString(date); miscInfo.push(text); } catch (e) { - console.error('error parsing date: ' + item.PremiereDate); + console.error(`error parsing date: ${item.PremiereDate}`); } } } @@ -176,7 +185,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater miscInfo.push(text); } } catch (e) { - console.error('error parsing date: ' + item.StartDate); + console.error(`error parsing date: ${item.StartDate}`); } } @@ -193,14 +202,14 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater try { - var endYear = datetime.parseISO8601Date(item.EndDate).getFullYear(); + const endYear = datetime.parseISO8601Date(item.EndDate).getFullYear(); if (endYear !== item.ProductionYear) { - text += '-' + datetime.parseISO8601Date(item.EndDate).getFullYear(); + text += `-${datetime.parseISO8601Date(item.EndDate).getFullYear()}`; } } catch (e) { - console.error('error parsing date: ' + item.EndDate); + console.error(`error parsing date: ${item.EndDate}`); } } @@ -213,19 +222,19 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater if (options.programIndicator !== false) { if (item.IsLive) { miscInfo.push({ - html: '
' + globalize.translate('Live') + '
' + html: `
${globalize.translate('Live')}
` }); } else if (item.IsPremiere) { miscInfo.push({ - html: '
' + globalize.translate('Premiere') + '
' + html: `
${globalize.translate('Premiere')}
` }); } else if (item.IsSeries && !item.IsRepeat) { miscInfo.push({ - html: '
' + globalize.translate('AttributeNew') + '
' + html: `
${globalize.translate('AttributeNew')}
` }); } else if (item.IsSeries && item.IsRepeat) { miscInfo.push({ - html: '
' + globalize.translate('Repeat') + '
' + html: `
${globalize.translate('Repeat')}
` }); } } @@ -248,7 +257,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater text = globalize.translate('OriginalAirDateValue', datetime.toLocaleDateString(date)); miscInfo.push(text); } catch (e) { - console.error('error parsing date: ' + item.PremiereDate); + console.error(`error parsing date: ${item.PremiereDate}`); } } else if (item.ProductionYear) { miscInfo.push(item.ProductionYear); @@ -267,7 +276,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater text = datetime.parseISO8601Date(item.PremiereDate).getFullYear(); miscInfo.push(text); } catch (e) { - console.error('error parsing date: ' + item.PremiereDate); + console.error(`error parsing date: ${item.PremiereDate}`); } } } @@ -284,7 +293,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater minutes = minutes || 1; - miscInfo.push(Math.round(minutes) + ' mins'); + miscInfo.push(`${Math.round(minutes)} mins`); } } @@ -300,14 +309,14 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater } if (item.MediaType === 'Photo' && item.Width && item.Height) { - miscInfo.push(item.Width + 'x' + item.Height); + miscInfo.push(`${item.Width}x${item.Height}`); } if (options.container !== false && item.Type === 'Audio' && item.Container) { miscInfo.push(item.Container); } - html += miscInfo.map(function (m) { + html += miscInfo.map(m => { return getMediaInfoItem(m); }).join(''); @@ -320,15 +329,15 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater if (item.CriticRating && options.criticRating !== false) { if (item.CriticRating >= 60) { - html += '
' + item.CriticRating + '
'; + html += `
${item.CriticRating}
`; } else { - html += '
' + item.CriticRating + '
'; + html += `
${item.CriticRating}
`; } } if (options.endsAt !== false) { - var endsAt = getEndsAt(item); + const endsAt = getEndsAt(item); if (endsAt) { html += getMediaInfoItem(endsAt, 'endsAt'); } @@ -339,15 +348,15 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater return html; } - function getEndsAt(item) { + export function getEndsAt(item) { if (item.MediaType === 'Video' && item.RunTimeTicks) { if (!item.StartDate) { - var endDate = new Date().getTime() + (item.RunTimeTicks / 10000); + let endDate = new Date().getTime() + (item.RunTimeTicks / 10000); endDate = new Date(endDate); - var displayTime = datetime.getDisplayTime(endDate); + const displayTime = datetime.getDisplayTime(endDate); return globalize.translate('EndsAtValue', displayTime); } } @@ -355,12 +364,12 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater return null; } - function getEndsAtFromPosition(runtimeTicks, positionTicks, includeText) { + export function getEndsAtFromPosition(runtimeTicks, positionTicks, includeText) { - var endDate = new Date().getTime() + ((runtimeTicks - (positionTicks || 0)) / 10000); + let endDate = new Date().getTime() + ((runtimeTicks - (positionTicks || 0)) / 10000); endDate = new Date(endDate); - var displayTime = datetime.getDisplayTime(endDate); + const displayTime = datetime.getDisplayTime(endDate); if (includeText === false) { return displayTime; @@ -370,8 +379,8 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater function getMediaInfoItem(m, cssClass) { - cssClass = cssClass ? (cssClass + ' mediaInfoItem') : 'mediaInfoItem'; - var mediaInfoText = m; + cssClass = cssClass ? (`${cssClass} mediaInfoItem`) : 'mediaInfoItem'; + let mediaInfoText = m; if (typeof (m) !== 'string' && typeof (m) !== 'number') { @@ -379,13 +388,13 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater return m.html; } mediaInfoText = m.text; - cssClass += ' ' + m.cssClass; + cssClass += ` ${m.cssClass}`; } - return '
' + mediaInfoText + '
'; + return `
${mediaInfoText}
`; } function getStarIconsHtml(item) { - var html = ''; + let html = ''; if (item.CommunityRating) { html += '
'; @@ -400,7 +409,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater function dynamicEndTime(elem, item) { - var interval = setInterval(function () { + const interval = setInterval(() => { if (!document.body.contains(elem)) { @@ -413,15 +422,15 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater }, 60000); } - function fillPrimaryMediaInfo(elem, item, options) { - var html = getPrimaryMediaInfoHtml(item, options); + export function fillPrimaryMediaInfo(elem, item, options) { + const html = getPrimaryMediaInfoHtml(item, options); elem.innerHTML = html; afterFill(elem, item, options); } - function fillSecondaryMediaInfo(elem, item, options) { - var html = getSecondaryMediaInfoHtml(item, options); + export function fillSecondaryMediaInfo(elem, item, options) { + const html = getSecondaryMediaInfoHtml(item, options); elem.innerHTML = html; afterFill(elem, item, options); @@ -430,13 +439,13 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater function afterFill(elem, item, options) { if (options.endsAt !== false) { - var endsAtElem = elem.querySelector('.endsAt'); + const endsAtElem = elem.querySelector('.endsAt'); if (endsAtElem) { dynamicEndTime(endsAtElem, item); } } - var lnkChannel = elem.querySelector('.lnkChannel'); + const lnkChannel = elem.querySelector('.lnkChannel'); if (lnkChannel) { lnkChannel.addEventListener('click', onChannelLinkClick); } @@ -444,8 +453,8 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater function onChannelLinkClick(e) { - var channelId = this.getAttribute('data-id'); - var serverId = this.getAttribute('data-serverid'); + const channelId = this.getAttribute('data-id'); + const serverId = this.getAttribute('data-serverid'); appRouter.showItem(channelId, serverId); @@ -453,7 +462,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater return false; } - function getPrimaryMediaInfoHtml(item, options) { + export function getPrimaryMediaInfoHtml(item, options) { options = options || {}; if (options.interactive == null) { @@ -463,7 +472,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater return getMediaInfoHtml(item, options); } - function getSecondaryMediaInfoHtml(item, options) { + export function getSecondaryMediaInfoHtml(item, options) { options = options || {}; if (options.interactive == null) { @@ -476,10 +485,10 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater return ''; } - function getResolutionText(i) { + export function getResolutionText(i) { - var width = i.Width; - var height = i.Height; + const width = i.Width; + const height = i.Height; if (width && height) { @@ -522,28 +531,28 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater return null; } - var mediaSource = item.MediaSources[0]; + const mediaSource = item.MediaSources[0]; if (!mediaSource) { return null; } - return (mediaSource.MediaStreams || []).filter(function (i) { + return (mediaSource.MediaStreams || []).filter(i => { return i.Type === 'Audio' && (i.Index === mediaSource.DefaultAudioStreamIndex || mediaSource.DefaultAudioStreamIndex == null); })[0]; } - function getMediaInfoStats(item, options) { + export function getMediaInfoStats(item, options) { options = options || {}; - var list = []; + const list = []; - var mediaSource = (item.MediaSources || [])[0] || {}; + const mediaSource = (item.MediaSources || [])[0] || {}; - var videoStream = (mediaSource.MediaStreams || []).filter(function (i) { + const videoStream = (mediaSource.MediaStreams || []).filter(i => { return i.Type === 'Video'; })[0] || {}; - var audioStream = getAudioStreamForDisplay(item) || {}; + const audioStream = getAudioStreamForDisplay(item) || {}; if (item.VideoType === 'Dvd') { list.push({ @@ -563,7 +572,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater // html += '
' + mediaSource.Container + '
'; //} - var resolutionText = getResolutionText(videoStream); + const resolutionText = getResolutionText(videoStream); if (resolutionText) { list.push({ type: 'mediainfo', @@ -578,8 +587,8 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater }); } - var channels = audioStream.Channels; - var channelText; + const channels = audioStream.Channels; + let channelText; if (channels === 8) { @@ -605,7 +614,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater }); } - var audioCodec = (audioStream.Codec || '').toLowerCase(); + const audioCodec = (audioStream.Codec || '').toLowerCase(); if ((audioCodec === 'dca' || audioCodec === 'dts') && audioStream.Profile) { list.push({ @@ -621,27 +630,28 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater if (item.DateCreated && itemHelper.enableDateAddedDisplay(item)) { - var dateCreated = datetime.parseISO8601Date(item.DateCreated); + const dateCreated = datetime.parseISO8601Date(item.DateCreated); list.push({ type: 'added', - text: globalize.translate('AddedOnValue', datetime.toLocaleDateString(dateCreated) + ' ' + datetime.getDisplayTime(dateCreated)) + text: globalize.translate('AddedOnValue', `${datetime.toLocaleDateString(dateCreated)} ${datetime.getDisplayTime(dateCreated)}`) }); } return list; } - return { - getMediaInfoHtml: getPrimaryMediaInfoHtml, - fill: fillPrimaryMediaInfo, - getEndsAt: getEndsAt, - getEndsAtFromPosition: getEndsAtFromPosition, - getPrimaryMediaInfoHtml: getPrimaryMediaInfoHtml, - getSecondaryMediaInfoHtml: getSecondaryMediaInfoHtml, - fillPrimaryMediaInfo: fillPrimaryMediaInfo, - fillSecondaryMediaInfo: fillSecondaryMediaInfo, - getMediaInfoStats: getMediaInfoStats, - getResolutionText: getResolutionText - }; -}); +/* eslint-enable indent */ + +export default { + getMediaInfoHtml: getPrimaryMediaInfoHtml, + fill: fillPrimaryMediaInfo, + getEndsAt: getEndsAt, + getEndsAtFromPosition: getEndsAtFromPosition, + getPrimaryMediaInfoHtml: getPrimaryMediaInfoHtml, + getSecondaryMediaInfoHtml: getSecondaryMediaInfoHtml, + fillPrimaryMediaInfo: fillPrimaryMediaInfo, + fillSecondaryMediaInfo: fillSecondaryMediaInfo, + getMediaInfoStats: getMediaInfoStats, + getResolutionText: getResolutionText +}; From 1556cc10e1ba94f490d9f902e62fd3b19c736826 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Sat, 13 Jun 2020 19:36:44 +0300 Subject: [PATCH 0024/1168] remove duplicate code --- src/components/mediainfo/mediainfo.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/mediainfo/mediainfo.js b/src/components/mediainfo/mediainfo.js index f64e67035..724d3462f 100644 --- a/src/components/mediainfo/mediainfo.js +++ b/src/components/mediainfo/mediainfo.js @@ -645,7 +645,6 @@ import 'emby-button'; export default { getMediaInfoHtml: getPrimaryMediaInfoHtml, - fill: fillPrimaryMediaInfo, getEndsAt: getEndsAt, getEndsAtFromPosition: getEndsAtFromPosition, getPrimaryMediaInfoHtml: getPrimaryMediaInfoHtml, From 6982176c676864e850493197e9623d2b1a837082 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Sun, 14 Jun 2020 01:30:00 +0300 Subject: [PATCH 0025/1168] add default --- src/components/shortcuts.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/shortcuts.js b/src/components/shortcuts.js index 83a4dfc31..f105d6c59 100644 --- a/src/components/shortcuts.js +++ b/src/components/shortcuts.js @@ -76,7 +76,7 @@ import recordingHelper from 'recordingHelper'; function showProgramDialog(item) { - import('recordingCreator').then((recordingCreator) => { + import('recordingCreator').then(({default:recordingCreator}) => { recordingCreator.show(item.Id, item.ServerId); }); @@ -121,7 +121,7 @@ import recordingHelper from 'recordingHelper'; item.PlaylistItemId = elem ? elem.getAttribute('data-playlistitemid') : null; } - import('itemContextMenu').then((itemContextMenu) => { + import('itemContextMenu').then(({default: itemContextMenu}) => { connectionManager.getApiClient(item.ServerId).getCurrentUser().then(user => { itemContextMenu.show(Object.assign({ @@ -169,7 +169,7 @@ import recordingHelper from 'recordingHelper'; const item = getItemInfoFromCard(card); - import('playMenu').then((playMenu) => { + import('playMenu').then(({default: playMenu}) => { playMenu.show({ @@ -180,7 +180,7 @@ import recordingHelper from 'recordingHelper'; } function sendToast(text) { - import('toast').then((toast) => { + import('toast').then(({default: toast}) => { toast(text); }); } @@ -293,7 +293,7 @@ import recordingHelper from 'recordingHelper'; } function addToPlaylist(item) { - import('playlistEditor').then((playlistEditor) => { + import('playlistEditor').then(({default: playlistEditor}) => { new playlistEditor().show({ items: [item.Id], @@ -322,18 +322,18 @@ import recordingHelper from 'recordingHelper'; if (item.Type === 'Timer') { if (item.ProgramId) { - import('recordingCreator').then((recordingCreator) => { + import('recordingCreator').then(({default: recordingCreator}) => { recordingCreator.show(item.ProgramId, serverId).then(resolve, reject); }); } else { - import('recordingEditor').then((recordingEditor) => { + import('recordingEditor').then(({default: recordingEditor}) => { recordingEditor.show(item.Id, serverId).then(resolve, reject); }); } } else { - import('metadataEditor').then((metadataEditor) => { + import('metadataEditor').then(({default: metadataEditor}) => { metadataEditor.show(item.Id, serverId).then(resolve, reject); }); From e81a7dbb8f08be452bebcf23693a6b9e7d2d4484 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Sun, 14 Jun 2020 02:28:15 +0300 Subject: [PATCH 0026/1168] Migration collectionEditor and playlisteditor to ES6 modules --- package.json | 2 + .../collectionEditor/collectionEditor.js | 194 ++++++++++-------- src/components/itemContextMenu.js | 4 +- src/components/multiSelect/multiSelect.js | 4 +- .../playlisteditor/playlisteditor.js | 193 +++++++++-------- src/components/remotecontrol/remotecontrol.js | 2 +- src/controllers/list.js | 2 +- src/controllers/movies/moviecollections.js | 2 +- src/scripts/playlists.js | 2 +- 9 files changed, 217 insertions(+), 188 deletions(-) diff --git a/package.json b/package.json index 91d070e04..c3cc49076 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "src/components/cardbuilder/cardBuilder.js", "src/components/cardbuilder/chaptercardbuilder.js", "src/components/cardbuilder/peoplecardbuilder.js", + "src/components/collectionEditor/collectionEditor.js", "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", @@ -108,6 +109,7 @@ "src/components/playback/playmethodhelper.js", "src/components/playback/remotecontrolautoplay.js", "src/components/playback/volumeosd.js", + "src/components/playlisteditor/playlisteditor.js", "src/components/playmenu.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", diff --git a/src/components/collectionEditor/collectionEditor.js b/src/components/collectionEditor/collectionEditor.js index 46b064030..a6bdc51ee 100644 --- a/src/components/collectionEditor/collectionEditor.js +++ b/src/components/collectionEditor/collectionEditor.js @@ -1,16 +1,32 @@ -define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectionManager', 'appRouter', 'globalize', 'emby-checkbox', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button', 'flexStyles'], function (dom, dialogHelper, loading, appHost, layoutManager, connectionManager, appRouter, globalize) { - 'use strict'; +import dom from 'dom'; +import dialogHelper from 'dialogHelper'; +import loading from 'loading'; +import appHost from 'apphost'; +import layoutManager from 'layoutManager'; +import connectionManager from 'connectionManager'; +import appRouter from 'appRouter'; +import globalize from 'globalize'; +import 'emby-checkbox'; +import 'emby-input'; +import 'paper-icon-button-light'; +import 'emby-select'; +import 'material-icons'; +import 'css!./../formdialog'; +import 'emby-button'; +import 'flexStyles'; - var currentServerId; +/* eslint-disable indent */ + + let currentServerId; function onSubmit(e) { loading.show(); - var panel = dom.parentWithClass(this, 'dialog'); + const panel = dom.parentWithClass(this, 'dialog'); - var collectionId = panel.querySelector('#selectCollectionToAddTo').value; + const collectionId = panel.querySelector('#selectCollectionToAddTo').value; - var apiClient = connectionManager.getApiClient(currentServerId); + const apiClient = connectionManager.getApiClient(currentServerId); if (collectionId) { addToCollection(apiClient, panel, collectionId); @@ -24,7 +40,7 @@ define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectio function createCollection(apiClient, dlg) { - var url = apiClient.getUrl('Collections', { + const url = apiClient.getUrl('Collections', { Name: dlg.querySelector('#txtNewCollectionName').value, IsLocked: !dlg.querySelector('#chkEnableInternetMetadata').checked, @@ -36,11 +52,11 @@ define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectio url: url, dataType: 'json' - }).then(function (result) { + }).then(result => { loading.hide(); - var id = result.Id; + const id = result.Id; dlg.submitted = true; dialogHelper.close(dlg); @@ -56,7 +72,7 @@ define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectio function addToCollection(apiClient, dlg, id) { - var url = apiClient.getUrl('Collections/' + id + '/Items', { + const url = apiClient.getUrl(`Collections/${id}/Items`, { Ids: dlg.querySelector('.fldSelectedItemIds').value || '' }); @@ -65,14 +81,14 @@ define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectio type: 'POST', url: url - }).then(function () { + }).then(() => { loading.hide(); dlg.submitted = true; dialogHelper.close(dlg); - require(['toast'], function (toast) { + import('toast').then(({default: toast}) => { toast(globalize.translate('MessageItemsAdded')); }); }); @@ -86,11 +102,11 @@ define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectio loading.show(); - var select = panel.querySelector('#selectCollectionToAddTo'); + const select = panel.querySelector('#selectCollectionToAddTo'); panel.querySelector('.newCollectionInfo').classList.add('hide'); - var options = { + const options = { Recursive: true, IncludeItemTypes: 'BoxSet', @@ -98,16 +114,16 @@ define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectio EnableTotalRecordCount: false }; - var apiClient = connectionManager.getApiClient(currentServerId); - apiClient.getItems(apiClient.getCurrentUserId(), options).then(function (result) { + const apiClient = connectionManager.getApiClient(currentServerId); + apiClient.getItems(apiClient.getCurrentUserId(), options).then(result => { - var html = ''; + let html = ''; - html += ''; + html += ``; - html += result.Items.map(function (i) { + html += result.Items.map(i => { - return ''; + return ``; }); select.innerHTML = html; @@ -120,7 +136,7 @@ define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectio function getEditorHtml() { - var html = ''; + let html = ''; html += '
'; html += '
'; @@ -134,27 +150,27 @@ define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectio html += '
'; html += '
'; html += '
'; - html += ''; + html += ``; html += '
'; html += '
'; html += '
'; html += '
'; - html += ''; - html += '
' + globalize.translate('NewCollectionNameExample') + '
'; + html += ``; + html += `
${globalize.translate('NewCollectionNameExample')}
`; html += '
'; html += ''; // newCollectionInfo html += '
'; html += '
'; - html += ''; + html += ``; html += '
'; html += ''; @@ -188,7 +204,7 @@ define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectio } else { content.querySelector('.fldSelectCollection').classList.add('hide'); - var selectCollectionToAddTo = content.querySelector('#selectCollectionToAddTo'); + const selectCollectionToAddTo = content.querySelector('#selectCollectionToAddTo'); selectCollectionToAddTo.innerHTML = ''; selectCollectionToAddTo.value = ''; triggerChange(selectCollectionToAddTo); @@ -196,79 +212,77 @@ define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectio } function centerFocus(elem, horiz, on) { - require(['scrollHelper'], function (scrollHelper) { - var fn = on ? 'on' : 'off'; + import('scrollHelper').then(scrollHelper => { + const fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); } - function CollectionEditor() { + class CollectionEditor { + show(options) { - } + const items = options.items || {}; + currentServerId = options.serverId; - CollectionEditor.prototype.show = function (options) { - - var items = options.items || {}; - currentServerId = options.serverId; - - var dialogOptions = { - removeOnClose: true, - scrollY: false - }; - - if (layoutManager.tv) { - dialogOptions.size = 'fullscreen'; - } else { - dialogOptions.size = 'small'; - } - - var dlg = dialogHelper.createDialog(dialogOptions); - - dlg.classList.add('formDialog'); - - var html = ''; - var title = items.length ? globalize.translate('HeaderAddToCollection') : globalize.translate('NewCollection'); - - html += '
'; - html += ''; - html += '

'; - html += title; - html += '

'; - - if (appHost.supports('externallinks')) { - html += '' + globalize.translate('Help') + ''; - } - - html += '
'; - - html += getEditorHtml(); - - dlg.innerHTML = html; - - initEditor(dlg, items); - - dlg.querySelector('.btnCancel').addEventListener('click', function () { - - dialogHelper.close(dlg); - }); - - if (layoutManager.tv) { - centerFocus(dlg.querySelector('.formDialogContent'), false, true); - } - - return dialogHelper.open(dlg).then(function () { + const dialogOptions = { + removeOnClose: true, + scrollY: false + }; if (layoutManager.tv) { - centerFocus(dlg.querySelector('.formDialogContent'), false, false); + dialogOptions.size = 'fullscreen'; + } else { + dialogOptions.size = 'small'; } - if (dlg.submitted) { - return Promise.resolve(); + const dlg = dialogHelper.createDialog(dialogOptions); + + dlg.classList.add('formDialog'); + + let html = ''; + const title = items.length ? globalize.translate('HeaderAddToCollection') : globalize.translate('NewCollection'); + + html += '
'; + html += ''; + html += '

'; + html += title; + html += '

'; + + if (appHost.supports('externallinks')) { + html += `${globalize.translate('Help')}`; } - return Promise.reject(); - }); - }; + html += '
'; - return CollectionEditor; -}); + html += getEditorHtml(); + + dlg.innerHTML = html; + + initEditor(dlg, items); + + dlg.querySelector('.btnCancel').addEventListener('click', () => { + + dialogHelper.close(dlg); + }); + + if (layoutManager.tv) { + centerFocus(dlg.querySelector('.formDialogContent'), false, true); + } + + return dialogHelper.open(dlg).then(() => { + + if (layoutManager.tv) { + centerFocus(dlg.querySelector('.formDialogContent'), false, false); + } + + if (dlg.submitted) { + return Promise.resolve(); + } + + return Promise.reject(); + }); + } + } + +/* eslint-enable indent */ +export default CollectionEditor; diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index f258f5fe4..e969721d6 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -319,7 +319,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', switch (id) { case 'addtocollection': require(['collectionEditor'], function (collectionEditor) { - new collectionEditor().show({ + new collectionEditor.default().show({ items: [itemId], serverId: serverId }).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); @@ -327,7 +327,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', break; case 'addtoplaylist': require(['playlistEditor'], function (playlistEditor) { - new playlistEditor().show({ + new playlistEditor.default().show({ items: [itemId], serverId: serverId }).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); diff --git a/src/components/multiSelect/multiSelect.js b/src/components/multiSelect/multiSelect.js index 83982413a..4919b9dd3 100644 --- a/src/components/multiSelect/multiSelect.js +++ b/src/components/multiSelect/multiSelect.js @@ -255,7 +255,7 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo switch (id) { case 'addtocollection': require(['collectionEditor'], function (collectionEditor) { - new collectionEditor().show({ + new collectionEditor.default().show({ items: items, serverId: serverId }); @@ -265,7 +265,7 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo break; case 'playlist': require(['playlistEditor'], function (playlistEditor) { - new playlistEditor().show({ + new playlistEditor.default().show({ items: items, serverId: serverId }); diff --git a/src/components/playlisteditor/playlisteditor.js b/src/components/playlisteditor/playlisteditor.js index 56d7142ad..12aa54f30 100644 --- a/src/components/playlisteditor/playlisteditor.js +++ b/src/components/playlisteditor/playlisteditor.js @@ -1,13 +1,28 @@ -define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager', 'connectionManager', 'userSettings', 'appRouter', 'globalize', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button'], function (dom, shell, dialogHelper, loading, layoutManager, playbackManager, connectionManager, userSettings, appRouter, globalize) { - 'use strict'; +import dom from 'dom'; +import dialogHelper from 'dialogHelper'; +import loading from 'loading'; +import layoutManager from 'layoutManager'; +import playbackManager from 'playbackManager'; +import connectionManager from 'connectionManager'; +import userSettings from 'userSettings'; +import appRouter from 'appRouter'; +import globalize from 'globalize'; +import 'emby-input'; +import 'paper-icon-button-light'; +import 'emby-select'; +import 'material-icons'; +import 'css!./../formdialog'; +import 'emby-button'; - var currentServerId; +/* eslint-disable indent */ + + let currentServerId; function onSubmit(e) { - var panel = dom.parentWithClass(this, 'dialog'); + const panel = dom.parentWithClass(this, 'dialog'); - var playlistId = panel.querySelector('#selectPlaylistToAddTo').value; - var apiClient = connectionManager.getApiClient(currentServerId); + const playlistId = panel.querySelector('#selectPlaylistToAddTo').value; + const apiClient = connectionManager.getApiClient(currentServerId); if (playlistId) { userSettings.set('playlisteditor-lastplaylistid', playlistId); @@ -23,7 +38,7 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackMan function createPlaylist(apiClient, dlg) { loading.show(); - var url = apiClient.getUrl('Playlists', { + const url = apiClient.getUrl('Playlists', { Name: dlg.querySelector('#txtNewPlaylistName').value, Ids: dlg.querySelector('.fldSelectedItemIds').value || '', userId: apiClient.getCurrentUserId() @@ -34,10 +49,10 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackMan type: 'POST', url: url, dataType: 'json' - }).then(function (result) { + }).then(result => { loading.hide(); - var id = result.Id; + const id = result.Id; dlg.submitted = true; dialogHelper.close(dlg); redirectToPlaylist(apiClient, id); @@ -49,7 +64,7 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackMan } function addToPlaylist(apiClient, dlg, id) { - var itemIds = dlg.querySelector('.fldSelectedItemIds').value || ''; + const itemIds = dlg.querySelector('.fldSelectedItemIds').value || ''; if (id === 'queue') { playbackManager.queue({ @@ -63,7 +78,7 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackMan loading.show(); - var url = apiClient.getUrl('Playlists/' + id + '/Items', { + const url = apiClient.getUrl(`Playlists/${id}/Items`, { Ids: itemIds, userId: apiClient.getCurrentUserId() }); @@ -72,7 +87,7 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackMan type: 'POST', url: url - }).then(function () { + }).then(() => { loading.hide(); dlg.submitted = true; @@ -85,36 +100,36 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackMan } function populatePlaylists(editorOptions, panel) { - var select = panel.querySelector('#selectPlaylistToAddTo'); + const select = panel.querySelector('#selectPlaylistToAddTo'); loading.hide(); panel.querySelector('.newPlaylistInfo').classList.add('hide'); - var options = { + const options = { Recursive: true, IncludeItemTypes: 'Playlist', SortBy: 'SortName', EnableTotalRecordCount: false }; - var apiClient = connectionManager.getApiClient(currentServerId); - apiClient.getItems(apiClient.getCurrentUserId(), options).then(function (result) { - var html = ''; + const apiClient = connectionManager.getApiClient(currentServerId); + apiClient.getItems(apiClient.getCurrentUserId(), options).then(result => { + let html = ''; if (editorOptions.enableAddToPlayQueue !== false && playbackManager.isPlaying()) { - html += ''; + html += ``; } - html += ''; + html += ``; - html += result.Items.map(function (i) { - return ''; + html += result.Items.map(i => { + return ``; }); select.innerHTML = html; - var defaultValue = editorOptions.defaultValue; + let defaultValue = editorOptions.defaultValue; if (!defaultValue) { defaultValue = userSettings.get('playlisteditor-lastplaylistid') || ''; } @@ -132,29 +147,29 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackMan } function getEditorHtml(items) { - var html = ''; + let html = ''; html += '
'; html += '
'; html += '
'; html += '
'; - var autoFocus = items.length ? ' autofocus' : ''; - html += ''; + let autoFocus = items.length ? ' autofocus' : ''; + html += ``; html += '
'; html += '
'; html += '
'; autoFocus = items.length ? '' : ' autofocus'; - html += ''; + html += ``; html += '
'; // newPlaylistInfo html += '
'; html += '
'; - html += ''; + html += ``; html += '
'; html += ''; @@ -187,7 +202,7 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackMan } else { content.querySelector('.fldSelectPlaylist').classList.add('hide'); - var selectPlaylistToAddTo = content.querySelector('#selectPlaylistToAddTo'); + const selectPlaylistToAddTo = content.querySelector('#selectPlaylistToAddTo'); selectPlaylistToAddTo.innerHTML = ''; selectPlaylistToAddTo.value = ''; triggerChange(selectPlaylistToAddTo); @@ -195,72 +210,70 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackMan } function centerFocus(elem, horiz, on) { - require(['scrollHelper'], function (scrollHelper) { - var fn = on ? 'on' : 'off'; + import('scrollHelper').then(scrollHelper => { + const fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); } - function PlaylistEditor() { + class PlaylistEditor { + show(options) { + const items = options.items || {}; + currentServerId = options.serverId; + const dialogOptions = { + removeOnClose: true, + scrollY: false + }; + + if (layoutManager.tv) { + dialogOptions.size = 'fullscreen'; + } else { + dialogOptions.size = 'small'; + } + + const dlg = dialogHelper.createDialog(dialogOptions); + + dlg.classList.add('formDialog'); + + let html = ''; + const title = globalize.translate('HeaderAddToPlaylist'); + + html += '
'; + html += ''; + html += '

'; + html += title; + html += '

'; + + html += '
'; + + html += getEditorHtml(items); + + dlg.innerHTML = html; + + initEditor(dlg, options, items); + + dlg.querySelector('.btnCancel').addEventListener('click', () => { + dialogHelper.close(dlg); + }); + + if (layoutManager.tv) { + centerFocus(dlg.querySelector('.formDialogContent'), false, true); + } + + return dialogHelper.open(dlg).then(() => { + if (layoutManager.tv) { + centerFocus(dlg.querySelector('.formDialogContent'), false, false); + } + + if (dlg.submitted) { + return Promise.resolve(); + } + + return Promise.reject(); + }); + } } - PlaylistEditor.prototype.show = function (options) { - var items = options.items || {}; - currentServerId = options.serverId; - - var dialogOptions = { - removeOnClose: true, - scrollY: false - }; - - if (layoutManager.tv) { - dialogOptions.size = 'fullscreen'; - } else { - dialogOptions.size = 'small'; - } - - var dlg = dialogHelper.createDialog(dialogOptions); - - dlg.classList.add('formDialog'); - - var html = ''; - var title = globalize.translate('HeaderAddToPlaylist'); - - html += '
'; - html += ''; - html += '

'; - html += title; - html += '

'; - - html += '
'; - - html += getEditorHtml(items); - - dlg.innerHTML = html; - - initEditor(dlg, options, items); - - dlg.querySelector('.btnCancel').addEventListener('click', function () { - dialogHelper.close(dlg); - }); - - if (layoutManager.tv) { - centerFocus(dlg.querySelector('.formDialogContent'), false, true); - } - - return dialogHelper.open(dlg).then(function () { - if (layoutManager.tv) { - centerFocus(dlg.querySelector('.formDialogContent'), false, false); - } - - if (dlg.submitted) { - return Promise.resolve(); - } - - return Promise.reject(); - }); - }; - - return PlaylistEditor; -}); +/* eslint-enable indent */ +export default PlaylistEditor; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 089915a83..b1cc84f81 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -589,7 +589,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL require(['playlistEditor'], function (playlistEditor) { getSaveablePlaylistItems().then(function (items) { var serverId = items.length ? items[0].ServerId : ApiClient.serverId(); - new playlistEditor().show({ + new playlistEditor.default().show({ items: items.map(function (i) { return i.Id; }), diff --git a/src/controllers/list.js b/src/controllers/list.js index d05616ec9..f5af412cd 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -386,7 +386,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' var instance = this; require(['playlistEditor'], function (playlistEditor) { - new playlistEditor().show({ + new playlistEditor.default().show({ items: [], serverId: instance.params.serverId }); diff --git a/src/controllers/movies/moviecollections.js b/src/controllers/movies/moviecollections.js index 54d30c0c3..bc47eecd2 100644 --- a/src/controllers/movies/moviecollections.js +++ b/src/controllers/movies/moviecollections.js @@ -242,7 +242,7 @@ define(['loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardB tabContent.querySelector('.btnNewCollection').addEventListener('click', function () { require(['collectionEditor'], function (collectionEditor) { var serverId = ApiClient.serverInfo().Id; - new collectionEditor().show({ + new collectionEditor.default().show({ items: [], serverId: serverId }); diff --git a/src/scripts/playlists.js b/src/scripts/playlists.js index 974d00f8e..7e5ec7ae4 100644 --- a/src/scripts/playlists.js +++ b/src/scripts/playlists.js @@ -184,7 +184,7 @@ define(['loading', 'listView', 'cardBuilder', 'libraryMenu', 'libraryBrowser', ' view.querySelector('.btnNewPlaylist').addEventListener('click', function () { require(['playlistEditor'], function (playlistEditor) { var serverId = ApiClient.serverInfo().Id; - new playlistEditor().show({ + new playlistEditor.default().show({ items: [], serverId: serverId }); From 3e583fcf212cc2fa4e3003d6a028f6cf07a8f091 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Tue, 16 Jun 2020 22:23:19 +0300 Subject: [PATCH 0027/1168] Fix userSettings Cannot read property 'get' of undefined --- src/components/playlisteditor/playlisteditor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/playlisteditor/playlisteditor.js b/src/components/playlisteditor/playlisteditor.js index 12aa54f30..283acfd0f 100644 --- a/src/components/playlisteditor/playlisteditor.js +++ b/src/components/playlisteditor/playlisteditor.js @@ -4,7 +4,7 @@ import loading from 'loading'; import layoutManager from 'layoutManager'; import playbackManager from 'playbackManager'; import connectionManager from 'connectionManager'; -import userSettings from 'userSettings'; +import * as userSettings from 'userSettings'; import appRouter from 'appRouter'; import globalize from 'globalize'; import 'emby-input'; From cfd2ec1ddca3e017a6603e693a2c9c59520bd2f8 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Tue, 16 Jun 2020 23:45:03 +0300 Subject: [PATCH 0028/1168] Migration backdrop to ES6 modules (cherry picked from commit 4ff4df6477cec4ea71ab042340bfd8875561221e) --- package.json | 1 + src/components/appRouter.js | 4 +- src/components/backdrop/backdrop.js | 186 +++++++++--------- src/components/remotecontrol/remotecontrol.js | 2 +- src/components/skinManager.js | 2 +- src/components/tabbedview/tabbedview.js | 2 +- src/controllers/itemDetails.js | 2 +- src/scripts/autoBackdrops.js | 6 +- 8 files changed, 106 insertions(+), 99 deletions(-) diff --git a/package.json b/package.json index 29aa2f82a..4f5b607b6 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "src/components/accessSchedule/accessSchedule.js", "src/components/actionSheet/actionSheet.js", "src/components/autoFocuser.js", + "src/components/backdrop/backdrop.js", "src/components/cardbuilder/cardBuilder.js", "src/components/cardbuilder/chaptercardbuilder.js", "src/components/cardbuilder/peoplecardbuilder.js", diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 0861cf7e0..1791aef7e 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -21,7 +21,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro }; function beginConnectionWizard() { - backdrop.clear(); + backdrop.clearBackdrop(); loading.show(); connectionManager.connect({ enableAutoLogin: appSettings.enableAutoLogin() @@ -657,7 +657,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } if (level === 'full' || level === 2) { - backdrop.clear(true); + backdrop.clearBackdrop(true); document.documentElement.classList.add('transparentDocument'); backgroundContainer.classList.add('backgroundContainer-transparent'); backdropContainer.classList.add('hide'); diff --git a/src/components/backdrop/backdrop.js b/src/components/backdrop/backdrop.js index c15e35524..51bb28076 100644 --- a/src/components/backdrop/backdrop.js +++ b/src/components/backdrop/backdrop.js @@ -1,5 +1,11 @@ -define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings', 'css!./backdrop'], function (browser, connectionManager, playbackManager, dom, userSettings) { - 'use strict'; +import browser from 'browser'; +import connectionManager from 'connectionManager'; +import playbackManager from 'playbackManager'; +import dom from 'dom'; +import * as userSettings from 'userSettings'; +import 'css!./backdrop'; + +/* eslint-disable indent */ function enableAnimation(elem) { if (browser.slow) { @@ -22,71 +28,70 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' return true; } - function Backdrop() { - } + class Backdrop { + load(url, parent, existingBackdropImage) { + const img = new Image(); + const self = this; - Backdrop.prototype.load = function (url, parent, existingBackdropImage) { - var img = new Image(); - var self = this; - - img.onload = function () { - if (self.isDestroyed) { - return; - } - - var backdropImage = document.createElement('div'); - backdropImage.classList.add('backdropImage'); - backdropImage.classList.add('displayingBackdropImage'); - backdropImage.style.backgroundImage = "url('" + url + "')"; - backdropImage.setAttribute('data-url', url); - - backdropImage.classList.add('backdropImageFadeIn'); - parent.appendChild(backdropImage); - - if (!enableAnimation(backdropImage)) { - if (existingBackdropImage && existingBackdropImage.parentNode) { - existingBackdropImage.parentNode.removeChild(existingBackdropImage); + img.onload = () => { + if (self.isDestroyed) { + return; } - internalBackdrop(true); - return; - } - var onAnimationComplete = function () { - dom.removeEventListener(backdropImage, dom.whichAnimationEvent(), onAnimationComplete, { + const backdropImage = document.createElement('div'); + backdropImage.classList.add('backdropImage'); + backdropImage.classList.add('displayingBackdropImage'); + backdropImage.style.backgroundImage = `url('${url}')`; + backdropImage.setAttribute('data-url', url); + + backdropImage.classList.add('backdropImageFadeIn'); + parent.appendChild(backdropImage); + + if (!enableAnimation(backdropImage)) { + if (existingBackdropImage && existingBackdropImage.parentNode) { + existingBackdropImage.parentNode.removeChild(existingBackdropImage); + } + internalBackdrop(true); + return; + } + + const onAnimationComplete = () => { + dom.removeEventListener(backdropImage, dom.whichAnimationEvent(), onAnimationComplete, { + once: true + }); + if (backdropImage === self.currentAnimatingElement) { + self.currentAnimatingElement = null; + } + if (existingBackdropImage && existingBackdropImage.parentNode) { + existingBackdropImage.parentNode.removeChild(existingBackdropImage); + } + }; + + dom.addEventListener(backdropImage, dom.whichAnimationEvent(), onAnimationComplete, { once: true }); - if (backdropImage === self.currentAnimatingElement) { - self.currentAnimatingElement = null; - } - if (existingBackdropImage && existingBackdropImage.parentNode) { - existingBackdropImage.parentNode.removeChild(existingBackdropImage); - } + + internalBackdrop(true); }; - dom.addEventListener(backdropImage, dom.whichAnimationEvent(), onAnimationComplete, { - once: true - }); - - internalBackdrop(true); - }; - - img.src = url; - }; - - Backdrop.prototype.cancelAnimation = function () { - var elem = this.currentAnimatingElement; - if (elem) { - elem.classList.remove('backdropImageFadeIn'); - this.currentAnimatingElement = null; + img.src = url; } - }; - Backdrop.prototype.destroy = function () { - this.isDestroyed = true; - this.cancelAnimation(); - }; + cancelAnimation() { + const elem = this.currentAnimatingElement; + if (elem) { + elem.classList.remove('backdropImageFadeIn'); + this.currentAnimatingElement = null; + } + } - var backdropContainer; + destroy() { + this.isDestroyed = true; + this.cancelAnimation(); + } + } + + let backdropContainer; function getBackdropContainer() { if (!backdropContainer) { backdropContainer = document.querySelector('.backdropContainer'); @@ -101,7 +106,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' return backdropContainer; } - function clearBackdrop(clearAll) { + export function clearBackdrop(clearAll) { clearRotation(); if (currentLoadingBackdrop) { @@ -109,7 +114,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' currentLoadingBackdrop = null; } - var elem = getBackdropContainer(); + const elem = getBackdropContainer(); elem.innerHTML = ''; if (clearAll) { @@ -119,7 +124,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' internalBackdrop(false); } - var backgroundContainer; + let backgroundContainer; function getBackgroundContainer() { if (!backgroundContainer) { backgroundContainer = document.querySelector('.backgroundContainer'); @@ -135,14 +140,14 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' } } - var hasInternalBackdrop; + let hasInternalBackdrop; function internalBackdrop(enabled) { hasInternalBackdrop = enabled; setBackgroundContainerBackgroundEnabled(); } - var hasExternalBackdrop; - function externalBackdrop(enabled) { + let hasExternalBackdrop; + export function externalBackdrop(enabled) { hasExternalBackdrop = enabled; setBackgroundContainerBackgroundEnabled(); } @@ -151,15 +156,15 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' return Math.floor(Math.random() * (max - min) + min); } - var currentLoadingBackdrop; + let currentLoadingBackdrop; function setBackdropImage(url) { if (currentLoadingBackdrop) { currentLoadingBackdrop.destroy(); currentLoadingBackdrop = null; } - var elem = getBackdropContainer(); - var existingBackdropImage = elem.querySelector('.displayingBackdropImage'); + const elem = getBackdropContainer(); + const existingBackdropImage = elem.querySelector('.displayingBackdropImage'); if (existingBackdropImage && existingBackdropImage.getAttribute('data-url') === url) { if (existingBackdropImage.getAttribute('data-url') === url) { @@ -168,7 +173,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' existingBackdropImage.classList.remove('displayingBackdropImage'); } - var instance = new Backdrop(); + const instance = new Backdrop(); instance.load(url, elem, existingBackdropImage); currentLoadingBackdrop = instance; } @@ -176,9 +181,9 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' function getItemImageUrls(item, imageOptions) { imageOptions = imageOptions || {}; - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); if (item.BackdropImageTags && item.BackdropImageTags.length > 0) { - return item.BackdropImageTags.map(function (imgTag, index) { + return item.BackdropImageTags.map((imgTag, index) => { return apiClient.getScaledImageUrl(item.BackdropItemId || item.Id, Object.assign(imageOptions, { type: 'Backdrop', tag: imgTag, @@ -189,7 +194,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' } if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) { - return item.ParentBackdropImageTags.map(function (imgTag, index) { + return item.ParentBackdropImageTags.map((imgTag, index) => { return apiClient.getScaledImageUrl(item.ParentBackdropItemId, Object.assign(imageOptions, { type: 'Backdrop', tag: imgTag, @@ -203,13 +208,13 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' } function getImageUrls(items, imageOptions) { - var list = []; - var onImg = function (img) { + const list = []; + const onImg = img => { list.push(img); }; - for (var i = 0, length = items.length; i < length; i++) { - var itemImages = getItemImageUrls(items[i], imageOptions); + for (let i = 0, length = items.length; i < length; i++) { + const itemImages = getItemImageUrls(items[i], imageOptions); itemImages.forEach(onImg); } @@ -229,7 +234,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' // If you don't care about the order of the elements inside // the array, you should sort both arrays here. - for (var i = 0; i < a.length; ++i) { + for (let i = 0; i < a.length; ++i) { if (a[i] !== b[i]) { return false; } @@ -242,12 +247,12 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' return userSettings.enableBackdrops(); } - var rotationInterval; - var currentRotatingImages = []; - var currentRotationIndex = -1; - function setBackdrops(items, imageOptions, enableImageRotation) { + let rotationInterval; + let currentRotatingImages = []; + let currentRotationIndex = -1; + export function setBackdrops(items, imageOptions, enableImageRotation) { if (enabled()) { - var images = getImageUrls(items, imageOptions); + const images = getImageUrls(items, imageOptions); if (images.length) { startRotation(images, enableImageRotation); @@ -279,7 +284,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' return; } - var newIndex = currentRotationIndex + 1; + let newIndex = currentRotationIndex + 1; if (newIndex >= currentRotatingImages.length) { newIndex = 0; } @@ -289,7 +294,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' } function clearRotation() { - var interval = rotationInterval; + const interval = rotationInterval; if (interval) { clearInterval(interval); } @@ -299,7 +304,7 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' currentRotationIndex = -1; } - function setBackdrop(url, imageOptions) { + export function setBackdrop(url, imageOptions) { if (url && typeof url !== 'string') { url = getImageUrls([url], imageOptions)[0]; } @@ -312,10 +317,11 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'userSettings' } } - return { - setBackdrops: setBackdrops, - setBackdrop: setBackdrop, - clear: clearBackdrop, - externalBackdrop: externalBackdrop - }; -}); +/* eslint-enable indent */ + +export default { + setBackdrops: setBackdrops, + setBackdrop: setBackdrop, + clearBackdrop: clearBackdrop, + externalBackdrop: externalBackdrop +}; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 089915a83..0f713dbe0 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -175,7 +175,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL context.querySelector('.nowPlayingPageUserDataButtons').innerHTML = ''; }); } else { - backdrop.clear(); + backdrop.clearBackdrop(); context.querySelector('.nowPlayingPageUserDataButtons').innerHTML = ''; } } diff --git a/src/components/skinManager.js b/src/components/skinManager.js index c38d34181..faa1a1f30 100644 --- a/src/components/skinManager.js +++ b/src/components/skinManager.js @@ -84,7 +84,7 @@ define(['apphost', 'userSettings', 'browser', 'events', 'backdrop', 'globalize', currentSound = null; } - backdrop.clear(); + backdrop.clearBackdrop(); } function onThemeLoaded() { diff --git a/src/components/tabbedview/tabbedview.js b/src/components/tabbedview/tabbedview.js index a67e8e0fa..4fec69f61 100644 --- a/src/components/tabbedview/tabbedview.js +++ b/src/components/tabbedview/tabbedview.js @@ -95,7 +95,7 @@ define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function ( TabbedView.prototype.onResume = function (options) { this.setTitle(); - backdrop.clear(); + backdrop.clearBackdrop(); var currentTabController = this.currentTabController; diff --git a/src/controllers/itemDetails.js b/src/controllers/itemDetails.js index 67aa5f940..58b0861e1 100644 --- a/src/controllers/itemDetails.js +++ b/src/controllers/itemDetails.js @@ -462,7 +462,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti if (dom.getWindowSize().innerWidth >= 1000) { backdrop.setBackdrops([item]); } else { - backdrop.clear(); + backdrop.clearBackdrop(); } } diff --git a/src/scripts/autoBackdrops.js b/src/scripts/autoBackdrops.js index abd86c9db..678aa4c33 100644 --- a/src/scripts/autoBackdrops.js +++ b/src/scripts/autoBackdrops.js @@ -50,7 +50,7 @@ define(['backdrop', 'userSettings', 'libraryMenu'], function (backdrop, userSett return i; })); } else { - backdrop.clear(); + backdrop.clearBackdrop(); } }); } @@ -67,10 +67,10 @@ define(['backdrop', 'userSettings', 'libraryMenu'], function (backdrop, userSett showBackdrop(type, parentId); } else { page.classList.remove('backdropPage'); - backdrop.clear(); + backdrop.clearBackdrop(); } } else { - backdrop.clear(); + backdrop.clearBackdrop(); } } }); From 2b156bfe57b1ecb8a35a2b971964b00f2798e5bc Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Tue, 16 Jun 2020 23:51:30 +0300 Subject: [PATCH 0029/1168] Remove unused function (cherry picked from commit c1b65c0122949ccb99be794a6a81e59e8146d450) --- src/components/backdrop/backdrop.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/backdrop/backdrop.js b/src/components/backdrop/backdrop.js index 51bb28076..d3c9e58b5 100644 --- a/src/components/backdrop/backdrop.js +++ b/src/components/backdrop/backdrop.js @@ -152,10 +152,6 @@ import 'css!./backdrop'; setBackgroundContainerBackgroundEnabled(); } - function getRandom(min, max) { - return Math.floor(Math.random() * (max - min) + min); - } - let currentLoadingBackdrop; function setBackdropImage(url) { if (currentLoadingBackdrop) { From 582ea612675a8a24d39a87ffc5e217aa24a8c97d Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Wed, 17 Jun 2020 00:43:22 +0300 Subject: [PATCH 0030/1168] Migration dialog to ES6 modules --- package.json | 1 + src/components/alert.js | 2 +- src/components/confirm/confirm.js | 2 +- src/components/dialog/dialog.js | 72 ++++++++++++++++++------------- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index 29aa2f82a..b1873fa7d 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "src/components/cardbuilder/cardBuilder.js", "src/components/cardbuilder/chaptercardbuilder.js", "src/components/cardbuilder/peoplecardbuilder.js", + "src/components/dialog/dialog.js", "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", diff --git a/src/components/alert.js b/src/components/alert.js index 8a37ac184..97b580f8f 100644 --- a/src/components/alert.js +++ b/src/components/alert.js @@ -31,7 +31,7 @@ define(['browser', 'dialog', 'globalize'], function (browser, dialog, globalize) options.buttons = items; - return dialog(options).then(function (result) { + return dialog.show(options).then(function (result) { if (result === 'ok') { return Promise.resolve(); } diff --git a/src/components/confirm/confirm.js b/src/components/confirm/confirm.js index 517d6fa9b..6b9252b5f 100644 --- a/src/components/confirm/confirm.js +++ b/src/components/confirm/confirm.js @@ -53,7 +53,7 @@ define(['browser', 'dialog', 'globalize'], function(browser, dialog, globalize) options.buttons = items; - return dialog(options).then(function (result) { + return dialog.show(options).then(function (result) { if (result === 'ok') { return Promise.resolve(); } diff --git a/src/components/dialog/dialog.js b/src/components/dialog/dialog.js index cfb5821b3..937e96d29 100644 --- a/src/components/dialog/dialog.js +++ b/src/components/dialog/dialog.js @@ -1,20 +1,31 @@ -define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 'require', 'material-icons', 'emby-button', 'paper-icon-button-light', 'emby-input', 'formDialogStyle', 'flexStyles'], function (dialogHelper, dom, layoutManager, scrollHelper, globalize, require) { - 'use strict'; +import dialogHelper from 'dialogHelper'; +import dom from 'dom'; +import layoutManager from 'layoutManager'; +import scrollHelper from 'scrollHelper'; +import globalize from 'globalize'; +import 'material-icons'; +import 'emby-button'; +import 'paper-icon-button-light'; +import 'emby-input'; +import 'formDialogStyle'; +import 'flexStyles'; + +/* eslint-disable indent */ function showDialog(options, template) { - var dialogOptions = { + const dialogOptions = { removeOnClose: true, scrollY: false }; - var enableTvLayout = layoutManager.tv; + const enableTvLayout = layoutManager.tv; if (enableTvLayout) { dialogOptions.size = 'fullscreen'; } - var dlg = dialogHelper.createDialog(dialogOptions); + const dlg = dialogHelper.createDialog(dialogOptions); dlg.classList.add('formDialog'); @@ -22,7 +33,7 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're dlg.classList.add('align-items-center'); dlg.classList.add('justify-content-center'); - var formDialogContent = dlg.querySelector('.formDialogContent'); + const formDialogContent = dlg.querySelector('.formDialogContent'); formDialogContent.classList.add('no-grow'); if (enableTvLayout) { @@ -30,7 +41,7 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're formDialogContent.style['max-height'] = '60%'; scrollHelper.centerFocus.on(formDialogContent, false); } else { - formDialogContent.style.maxWidth = (Math.min((options.buttons.length * 150) + 200, dom.getWindowSize().innerWidth - 50)) + 'px'; + formDialogContent.style.maxWidth = `${Math.min((options.buttons.length * 150) + 200, dom.getWindowSize().innerWidth - 50)}px`; dlg.classList.add('dialog-fullscreen-lowres'); } @@ -44,27 +55,27 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're dlg.querySelector('.formDialogHeaderTitle').classList.add('hide'); } - var displayText = options.html || options.text || ''; + const displayText = options.html || options.text || ''; dlg.querySelector('.text').innerHTML = displayText; if (!displayText) { dlg.querySelector('.dialogContentInner').classList.add('hide'); } - var i; - var length; - var html = ''; - var hasDescriptions = false; + let i; + let length; + let html = ''; + let hasDescriptions = false; for (i = 0, length = options.buttons.length; i < length; i++) { - var item = options.buttons[i]; - var autoFocus = i === 0 ? ' autofocus' : ''; + const item = options.buttons[i]; + const autoFocus = i === 0 ? ' autofocus' : ''; - var buttonClass = 'btnOption raised formDialogFooterItem formDialogFooterItem-autosize'; + let buttonClass = 'btnOption raised formDialogFooterItem formDialogFooterItem-autosize'; if (item.type) { - buttonClass += ' button-' + item.type; + buttonClass += ` button-${item.type}`; } if (item.description) { @@ -75,10 +86,10 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're buttonClass += ' formDialogFooterItem-vertical formDialogFooterItem-nomarginbottom'; } - html += ''; + html += ``; if (item.description) { - html += '
' + item.description + '
'; + html += `
${item.description}
`; } } @@ -88,18 +99,18 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're dlg.querySelector('.formDialogFooter').classList.add('formDialogFooter-vertical'); } - var dialogResult; + let dialogResult; function onButtonClick() { dialogResult = this.getAttribute('data-id'); dialogHelper.close(dlg); } - var buttons = dlg.querySelectorAll('.btnOption'); + const buttons = dlg.querySelectorAll('.btnOption'); for (i = 0, length = buttons.length; i < length; i++) { buttons[i].addEventListener('click', onButtonClick); } - return dialogHelper.open(dlg).then(function () { + return dialogHelper.open(dlg).then(() => { if (enableTvLayout) { scrollHelper.centerFocus.off(dlg.querySelector('.formDialogContent'), false); @@ -113,9 +124,9 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're }); } - return function (text, title) { + export async function show(text, title) { - var options; + let options; if (typeof text === 'string') { options = { title: title, @@ -125,10 +136,13 @@ define(['dialogHelper', 'dom', 'layoutManager', 'scrollHelper', 'globalize', 're options = text; } - return new Promise(function (resolve, reject) { - require(['text!./dialog.template.html'], function (template) { - showDialog(options, template).then(resolve, reject); - }); + const { default: template } = await import('text!./dialog.template.html'); + return new Promise((resolve, reject) => { + showDialog(options, template).then(resolve, reject); }); - }; -}); + } + +/* eslint-enable indent */ +export default { + show: show +}; From 7c8a5d31846cef50b590be9ea72f9b128fc7b80e Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Wed, 17 Jun 2020 01:19:59 +0300 Subject: [PATCH 0031/1168] Migration dialogHelper to ES6 modules --- package.json | 1 + src/components/dialogHelper/dialogHelper.js | 127 +++++++++++--------- 2 files changed, 69 insertions(+), 59 deletions(-) diff --git a/package.json b/package.json index b1873fa7d..a1f2fe9a0 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "src/components/cardbuilder/chaptercardbuilder.js", "src/components/cardbuilder/peoplecardbuilder.js", "src/components/dialog/dialog.js", + "src/components/dialogHelper/dialogHelper.js", "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", diff --git a/src/components/dialogHelper/dialogHelper.js b/src/components/dialogHelper/dialogHelper.js index 8b08cde67..73aee88f0 100644 --- a/src/components/dialogHelper/dialogHelper.js +++ b/src/components/dialogHelper/dialogHelper.js @@ -1,7 +1,15 @@ -define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', 'dom', 'css!./dialoghelper.css', 'scrollStyles'], function (appRouter, focusManager, browser, layoutManager, inputManager, dom) { - 'use strict'; +import appRouter from 'appRouter'; +import focusManager from 'focusManager'; +import browser from 'browser'; +import layoutManager from 'layoutManager'; +import inputManager from 'inputManager'; +import dom from 'dom'; +import 'css!./dialoghelper.css'; +import 'scrollStyles'; - var globalOnOpenCallback; +/* eslint-disable indent */ + + let globalOnOpenCallback; function enableAnimation() { @@ -25,28 +33,28 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', } function tryRemoveElement(elem) { - var parentNode = elem.parentNode; + const parentNode = elem.parentNode; if (parentNode) { // Seeing crashes in edge webview try { parentNode.removeChild(elem); } catch (err) { - console.error('error removing dialog element: ' + err); + console.error(`error removing dialog element: ${err}`); } } } function DialogHashHandler(dlg, hash, resolve) { - var self = this; + const self = this; self.originalUrl = window.location.href; - var activeElement = document.activeElement; - var removeScrollLockOnClose = false; + const activeElement = document.activeElement; + let removeScrollLockOnClose = false; function onHashChange(e) { - var isBack = self.originalUrl === window.location.href; + const isBack = self.originalUrl === window.location.href; if (isBack || !isOpened(dlg)) { window.removeEventListener('popstate', onHashChange); @@ -84,7 +92,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', } if (!self.closedByBack && isHistoryEnabled(dlg)) { - var state = history.state || {}; + const state = history.state || {}; if (state.dialogId === hash) { history.back(); } @@ -97,7 +105,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', if (dlg.getAttribute('data-removeonclose') !== 'false') { removeCenterFocus(dlg); - var dialogContainer = dlg.dialogContainer; + const dialogContainer = dlg.dialogContainer; if (dialogContainer) { tryRemoveElement(dialogContainer); dlg.dialogContainer = null; @@ -108,7 +116,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', //resolve(); // if we just called history.back(), then use a timeout to allow the history events to fire first - setTimeout(function () { + setTimeout(() => { resolve({ element: dlg, closedByBack: self.closedByBack @@ -118,7 +126,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', dlg.addEventListener('close', onDialogClosed); - var center = !dlg.classList.contains('dialog-fixedSize'); + const center = !dlg.classList.contains('dialog-fixedSize'); if (center) { dlg.classList.add('centeredDialog'); } @@ -141,7 +149,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', animateDialogOpen(dlg); if (isHistoryEnabled(dlg)) { - appRouter.pushState({ dialogId: hash }, 'Dialog', '#' + hash); + appRouter.pushState({ dialogId: hash }, 'Dialog', `#${hash}`); window.addEventListener('popstate', onHashChange); } else { @@ -151,10 +159,10 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', function addBackdropOverlay(dlg) { - var backdrop = document.createElement('div'); + const backdrop = document.createElement('div'); backdrop.classList.add('dialogBackdrop'); - var backdropParent = dlg.dialogContainer || dlg; + const backdropParent = dlg.dialogContainer || dlg; backdropParent.parentNode.insertBefore(backdrop, backdropParent); dlg.backdrop = backdrop; @@ -162,7 +170,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', void backdrop.offsetWidth; backdrop.classList.add('dialogBackdropOpened'); - dom.addEventListener((dlg.dialogContainer || backdrop), 'click', function (e) { + dom.addEventListener((dlg.dialogContainer || backdrop), 'click', e => { if (e.target === dlg.dialogContainer) { close(dlg); } @@ -170,7 +178,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', passive: true }); - dom.addEventListener((dlg.dialogContainer || backdrop), 'contextmenu', function (e) { + dom.addEventListener((dlg.dialogContainer || backdrop), 'contextmenu', e => { if (e.target === dlg.dialogContainer) { // Close the application dialog menu close(dlg); @@ -184,26 +192,26 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', return dlg.getAttribute('data-history') === 'true'; } - function open(dlg) { + export function open(dlg) { if (globalOnOpenCallback) { globalOnOpenCallback(dlg); } - var parent = dlg.parentNode; + const parent = dlg.parentNode; if (parent) { parent.removeChild(dlg); } - var dialogContainer = document.createElement('div'); + const dialogContainer = document.createElement('div'); dialogContainer.classList.add('dialogContainer'); dialogContainer.appendChild(dlg); dlg.dialogContainer = dialogContainer; document.body.appendChild(dialogContainer); - return new Promise(function (resolve, reject) { + return new Promise((resolve, reject) => { - new DialogHashHandler(dlg, 'dlg' + new Date().getTime(), resolve); + new DialogHashHandler(dlg, `dlg${new Date().getTime()}`, resolve); }); } @@ -213,7 +221,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', return !dlg.classList.contains('hide'); } - function close(dlg) { + export function close(dlg) { if (isOpened(dlg)) { if (isHistoryEnabled(dlg)) { @@ -233,7 +241,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', cancelable: false })); - var onAnimationFinish = function () { + const onAnimationFinish = () => { focusManager.popScope(dlg); dlg.classList.add('hide'); @@ -249,7 +257,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', function animateDialogOpen(dlg) { - var onAnimationFinish = function () { + const onAnimationFinish = () => { focusManager.pushScope(dlg); if (dlg.getAttribute('data-autofocus') === 'true') { @@ -264,7 +272,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', if (enableAnimation()) { - var onFinish = function () { + const onFinish = () => { dom.removeEventListener(dlg, dom.whichAnimationEvent(), onFinish, { once: true }); @@ -283,24 +291,24 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', if (enableAnimation()) { - var animated = true; + let animated = true; switch (dlg.animationConfig.exit.name) { case 'fadeout': - dlg.style.animation = 'fadeout ' + dlg.animationConfig.exit.timing.duration + 'ms ease-out normal both'; + dlg.style.animation = `fadeout ${dlg.animationConfig.exit.timing.duration}ms ease-out normal both`; break; case 'scaledown': - dlg.style.animation = 'scaledown ' + dlg.animationConfig.exit.timing.duration + 'ms ease-out normal both'; + dlg.style.animation = `scaledown ${dlg.animationConfig.exit.timing.duration}ms ease-out normal both`; break; case 'slidedown': - dlg.style.animation = 'slidedown ' + dlg.animationConfig.exit.timing.duration + 'ms ease-out normal both'; + dlg.style.animation = `slidedown ${dlg.animationConfig.exit.timing.duration}ms ease-out normal both`; break; default: animated = false; break; } - var onFinish = function () { + const onFinish = () => { dom.removeEventListener(dlg, dom.whichAnimationEvent(), onFinish, { once: true }); @@ -318,7 +326,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', onAnimationFinish(); } - var supportsOverscrollBehavior = 'overscroll-behavior-y' in document.body.style; + const supportsOverscrollBehavior = 'overscroll-behavior-y' in document.body.style; function shouldLockDocumentScroll(options) { @@ -343,7 +351,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', function removeBackdrop(dlg) { - var backdrop = dlg.backdrop; + const backdrop = dlg.backdrop; if (!backdrop) { return; @@ -351,7 +359,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', dlg.backdrop = null; - var onAnimationFinish = function () { + const onAnimationFinish = () => { tryRemoveElement(backdrop); }; @@ -368,20 +376,20 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', } function centerFocus(elem, horiz, on) { - require(['scrollHelper'], function (scrollHelper) { - var fn = on ? 'on' : 'off'; + import('scrollHelper').then(scrollHelper => { + const fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); } - function createDialog(options) { + export function createDialog(options) { options = options || {}; // If there's no native dialog support, use a plain div // Also not working well in samsung tizen browser, content inside not clickable // Just go ahead and always use a plain div because we're seeing issues overlaying absoltutely positioned content over a modal dialog - var dlg = document.createElement('div'); + const dlg = document.createElement('div'); dlg.classList.add('focuscontainer'); dlg.classList.add('hide'); @@ -406,17 +414,17 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', dlg.setAttribute('data-autofocus', 'true'); } - var defaultEntryAnimation; - var defaultExitAnimation; + let defaultEntryAnimation; + let defaultExitAnimation; defaultEntryAnimation = 'scaleup'; defaultExitAnimation = 'scaledown'; - var entryAnimation = options.entryAnimation || defaultEntryAnimation; - var exitAnimation = options.exitAnimation || defaultExitAnimation; + const entryAnimation = options.entryAnimation || defaultEntryAnimation; + const exitAnimation = options.exitAnimation || defaultExitAnimation; // If it's not fullscreen then lower the default animation speed to make it open really fast - var entryAnimationDuration = options.entryAnimationDuration || (options.size !== 'fullscreen' ? 180 : 280); - var exitAnimationDuration = options.exitAnimationDuration || (options.size !== 'fullscreen' ? 120 : 220); + const entryAnimationDuration = options.entryAnimationDuration || (options.size !== 'fullscreen' ? 180 : 280); + const exitAnimationDuration = options.exitAnimationDuration || (options.size !== 'fullscreen' ? 120 : 220); dlg.animationConfig = { // scale up @@ -461,7 +469,7 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', if (options.size) { dlg.classList.add('dialog-fixedSize'); - dlg.classList.add('dialog-' + options.size); + dlg.classList.add(`dialog-${options.size}`); } if (enableAnimation()) { @@ -469,16 +477,16 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', switch (dlg.animationConfig.entry.name) { case 'fadein': - dlg.style.animation = 'fadein ' + entryAnimationDuration + 'ms ease-out normal'; + dlg.style.animation = `fadein ${entryAnimationDuration}ms ease-out normal`; break; case 'scaleup': - dlg.style.animation = 'scaleup ' + entryAnimationDuration + 'ms ease-out normal both'; + dlg.style.animation = `scaleup ${entryAnimationDuration}ms ease-out normal both`; break; case 'slideup': - dlg.style.animation = 'slideup ' + entryAnimationDuration + 'ms ease-out normal'; + dlg.style.animation = `slideup ${entryAnimationDuration}ms ease-out normal`; break; case 'slidedown': - dlg.style.animation = 'slidedown ' + entryAnimationDuration + 'ms ease-out normal'; + dlg.style.animation = `slidedown ${entryAnimationDuration}ms ease-out normal`; break; default: break; @@ -488,12 +496,13 @@ define(['appRouter', 'focusManager', 'browser', 'layoutManager', 'inputManager', return dlg; } - return { - open: open, - close: close, - createDialog: createDialog, - setOnOpen: function (val) { - globalOnOpenCallback = val; - } - }; -}); +/* eslint-enable indent */ + +export default { + open: open, + close: close, + createDialog: createDialog, + setOnOpen: function (val) { + globalOnOpenCallback = val; + } +}; From dd4cc0328a54ffc34251aee1e10e56d2250daeb1 Mon Sep 17 00:00:00 2001 From: ferferga Date: Wed, 17 Jun 2020 20:28:42 +0200 Subject: [PATCH 0032/1168] Attempt to fix miniplayer context menu --- src/components/nowPlayingBar/nowPlayingBar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index bc9c3c1a8..9732951f5 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -545,7 +545,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', apiClient.getItem(apiClient.getCurrentUserId(), nowPlayingItem.Id).then(function (item) { var userData = item.UserData || {}; var likes = userData.Likes == null ? '' : userData.Likes; - var contextButton = document.querySelector('.btnToggleContextMenu'); + var contextButton = document.querySelector('.nowPlayingBar').querySelector('.btnToggleContextMenu'); var options = { play: false, queue: false, From e2f61c67b9c50ad815d4d778a451a70ffb9599b3 Mon Sep 17 00:00:00 2001 From: ferferga Date: Wed, 17 Jun 2020 20:29:08 +0200 Subject: [PATCH 0033/1168] Show all artists of an item and set bottom bar transparent on mobile devices --- .../remotecontrol/remotecontrol.css | 3 ++ src/components/remotecontrol/remotecontrol.js | 30 ++++++++++++------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index 073c92533..115fc2c24 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -364,6 +364,9 @@ padding-left: 7.3%; padding-right: 7.3%; } + .playlistSectionButtonTransparent { + background: rgba(0, 0, 0, 0) !important; + } .playlistSectionButton .btnTogglePlaylist { font-size: larger; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 089915a83..f5de415a3 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -1,4 +1,4 @@ -define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageLoader', 'playbackManager', 'nowPlayingHelper', 'events', 'connectionManager', 'apphost', 'globalize', 'layoutManager', 'userSettings', 'cardBuilder', 'cardStyle', 'emby-itemscontainer', 'css!./remotecontrol.css', 'emby-ratingbutton'], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize, layoutManager, userSettings, cardBuilder) { +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'; function showAudioMenu(context, player, button, item) { @@ -119,18 +119,21 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var songName = item.Name; if (item.Album != null && item.Artists != null) { var albumName = item.Album; - var artistName; if (item.ArtistItems != null) { - artistName = item.ArtistItems[0].Name; - context.querySelector('.nowPlayingAlbum').innerHTML = '${albumName}`; - context.querySelector('.nowPlayingArtist').innerHTML = '${artistName}`; - context.querySelector('.contextMenuAlbum').innerHTML = ' ` + globalize.translate('ViewAlbum') + ''; + var artistsSeries = ''; + for (let artist of item.ArtistItems) { + let artistName = artist.Name; + let artistId = artist.Id; + artistsSeries += `${artistName}`; + if (artist !== item.ArtistItems.slice(-1)[0]) { + artistsSeries += ', '; + } + } + context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries; context.querySelector('.contextMenuArtist').innerHTML = ' ` + globalize.translate('ViewArtist') + ''; - } else { - artistName = item.Artists; - context.querySelector('.nowPlayingAlbum').innerHTML = albumName; - context.querySelector('.nowPlayingArtist').innerHTML = artistName; } + context.querySelector('.nowPlayingAlbum').innerHTML = '${albumName}`; + context.querySelector('.contextMenuAlbum').innerHTML = ' ` + globalize.translate('ViewAlbum') + ''; } context.querySelector('.nowPlayingSongName').innerHTML = songName; } else if (item.Type == 'Episode') { @@ -703,10 +706,16 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL context.querySelector('.btnSavePlaylist').classList.remove('hide'); context.querySelector('.contextMenu').classList.add('hide'); context.querySelector('.volumecontrol').classList.add('hide'); + if (layoutManager.mobile) { + context.querySelector('.playlistSectionButton').classList.remove('playlistSectionButtonTransparent'); + } } else { context.querySelector('.playlist').classList.add('hide'); context.querySelector('.btnSavePlaylist').classList.add('hide'); context.querySelector('.volumecontrol').classList.remove('hide'); + if (layoutManager.mobile) { + context.querySelector('.playlistSectionButton').classList.add('playlistSectionButtonTransparent'); + } } }); context.querySelector('.btnToggleContextMenu').addEventListener('click', function () { @@ -774,6 +783,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL context.querySelector('.playlistSectionButton').innerHTML += contextmenuHtml; } else { context.querySelector('.playlistSectionButton').innerHTML += volumecontrolHtml + contextmenuHtml; + context.querySelector('.playlistSectionButton').classList.add('playlistSectionButtonTransparent'); } bindEvents(context); From 4159268949d433f42dc99969cbf2060c4624842f Mon Sep 17 00:00:00 2001 From: ferferga Date: Wed, 17 Jun 2020 21:02:50 +0200 Subject: [PATCH 0034/1168] Repeat track if going back when less than 5 seconds of the item has been playing --- src/components/nowPlayingBar/nowPlayingBar.js | 22 ++++++++++++------- src/components/remotecontrol/remotecontrol.js | 15 ++++++++++--- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 9732951f5..33f9aa405 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -117,8 +117,13 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', nowPlayingImageElement = elem.querySelector('.nowPlayingImage'); nowPlayingTextElement = elem.querySelector('.nowPlayingBarText'); nowPlayingUserData = elem.querySelector('.nowPlayingBarUserDataButtons'); - + positionSlider = elem.querySelector('.nowPlayingBarPositionSlider'); muteButton = elem.querySelector('.muteButton'); + playPauseButtons = elem.querySelectorAll('.playPauseButton'); + toggleRepeatButton = elem.querySelector('.toggleRepeatButton'); + volumeSlider = elem.querySelector('.nowPlayingBarVolumeSlider'); + volumeSliderContainer = elem.querySelector('.nowPlayingBarVolumeSliderContainer'); + muteButton.addEventListener('click', function () { if (currentPlayer) { @@ -134,7 +139,6 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } }); - playPauseButtons = elem.querySelectorAll('.playPauseButton'); playPauseButtons.forEach((button) => { button.addEventListener('click', onPlayPauseClick); }); @@ -147,9 +151,15 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', }); elem.querySelector('.previousTrackButton').addEventListener('click', function () { - if (currentPlayer) { - playbackManager.previousTrack(currentPlayer); + if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime <= 5 || !playbackManager.previousTrack(currentPlayer))) { + playbackManager.seekPercent(0, currentPlayer); + // This is done automatically by playbackManager, however, setting this here + // gives instant visual feedback + positionSlider.value = 0; + } else { + playbackManager.previousTrack(currentPlayer); + } } }); @@ -174,9 +184,6 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', toggleRepeatButtonIcon = toggleRepeatButton.querySelector('.material-icons'); - volumeSlider = elem.querySelector('.nowPlayingBarVolumeSlider'); - volumeSliderContainer = elem.querySelector('.nowPlayingBarVolumeSliderContainer'); - if (appHost.supports('physicalvolumecontrol')) { volumeSliderContainer.classList.add('hide'); } else { @@ -193,7 +200,6 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', volumeSlider.addEventListener('mousemove', setVolume); volumeSlider.addEventListener('touchmove', setVolume); - positionSlider = elem.querySelector('.nowPlayingBarPositionSlider'); positionSlider.addEventListener('change', function () { if (currentPlayer) { diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index f5de415a3..c1c5bfd6d 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -606,6 +606,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function bindEvents(context) { var btnCommand = context.querySelectorAll('.btnCommand'); + var positionSlider = context.querySelector('.nowPlayingPositionSlider'); for (var i = 0, length = btnCommand.length; i < length; i++) { btnCommand[i].addEventListener('click', onBtnCommandClick); @@ -654,11 +655,19 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } }); context.querySelector('.btnPreviousTrack').addEventListener('click', function () { + console.log(currentPlayer); if (currentPlayer) { - playbackManager.previousTrack(currentPlayer); + if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime <= 5 || !playbackManager.previousTrack(currentPlayer))) { + playbackManager.seekPercent(0, currentPlayer); + // This is done automatically by playbackManager. However, setting this here + // gives instant visual feedback + positionSlider.value = 0; + } else { + playbackManager.previousTrack(currentPlayer); + } } }); - context.querySelector('.nowPlayingPositionSlider').addEventListener('change', function () { + positionSlider.addEventListener('change', function () { var value = this.value; if (currentPlayer) { @@ -667,7 +676,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } }); - context.querySelector('.nowPlayingPositionSlider').getBubbleText = function (value) { + positionSlider.getBubbleText = function (value) { var state = lastPlayerState; if (!state || !state.NowPlayingItem || !currentRuntimeTicks) { From 8b4b67254a57b5544daa0b0cc086bfab40c9f3b3 Mon Sep 17 00:00:00 2001 From: ferferga Date: Wed, 17 Jun 2020 22:09:30 +0200 Subject: [PATCH 0035/1168] Show playlist on desktop layout and use native context menu --- src/assets/css/flexstyles.css | 4 + src/components/remotecontrol/remotecontrol.js | 93 +++++++++++-------- src/nowplaying.html | 10 +- 3 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/assets/css/flexstyles.css b/src/assets/css/flexstyles.css index a5a479f2f..2f3a386bf 100644 --- a/src/assets/css/flexstyles.css +++ b/src/assets/css/flexstyles.css @@ -30,6 +30,10 @@ align-items: flex-start; } +.align-items-flex-end { + align-items: flex-end; +} + .justify-content-center { justify-content: center; } diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index c1c5bfd6d..89c56090e 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -1,5 +1,7 @@ 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'; + var showMuteButton = true; + var showVolumeSlider = true; function showAudioMenu(context, player, button, item) { var currentIndex = playbackManager.getAudioStreamIndex(player); @@ -130,10 +132,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } } context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries; - context.querySelector('.contextMenuArtist').innerHTML = ' ` + globalize.translate('ViewArtist') + ''; } context.querySelector('.nowPlayingAlbum').innerHTML = '${albumName}`; - context.querySelector('.contextMenuAlbum').innerHTML = ' ` + globalize.translate('ViewAlbum') + ''; } context.querySelector('.nowPlayingSongName').innerHTML = songName; } else if (item.Type == 'Episode') { @@ -167,10 +167,25 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL }) : null; console.debug('updateNowPlayingInfo'); + var contextButton = context.querySelector('.btnToggleContextMenu'); + var options = { + play: false, + queue: false, + openAlbum: false, + positionTo: contextButton + }; + var apiClient = connectionManager.getApiClient(item.ServerId); + apiClient.getCurrentUser().then(function (user) { + contextButton.addEventListener('click', function () { + itemContextMenu.show(Object.assign({ + item: item, + user: user + }, options)); + }); + }); setImageUrl(context, state, url); if (item) { backdrop.setBackdrops([item]); - var apiClient = connectionManager.getApiClient(item.ServerId); apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (fullItem) { var userData = fullItem.UserData || {}; var likes = null == userData.Likes ? '' : userData.Likes; @@ -336,8 +351,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function updatePlayerVolumeState(context, isMuted, volumeLevel) { var view = context; var supportedCommands = currentPlayerSupportedCommands; - var showMuteButton = true; - var showVolumeSlider = true; if (-1 === supportedCommands.indexOf('Mute')) { showMuteButton = false; @@ -365,24 +378,28 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL buttonMuteIcon.classList.add('volume_up'); } - if (showMuteButton) { - buttonMute.classList.remove('hide'); + if (!showMuteButton && !showVolumeSlider) { + context.querySelector('.volumecontrol').classList.add('hide'); } else { - buttonMute.classList.add('hide'); - } - - var nowPlayingVolumeSlider = context.querySelector('.nowPlayingVolumeSlider'); - var nowPlayingVolumeSliderContainer = context.querySelector('.nowPlayingVolumeSliderContainer'); - - if (nowPlayingVolumeSlider) { - if (showVolumeSlider) { - nowPlayingVolumeSliderContainer.classList.remove('hide'); + if (showMuteButton) { + buttonMute.classList.remove('hide'); } else { - nowPlayingVolumeSliderContainer.classList.add('hide'); + buttonMute.classList.add('hide'); } - if (!nowPlayingVolumeSlider.dragging) { - nowPlayingVolumeSlider.value = volumeLevel || 0; + var nowPlayingVolumeSlider = context.querySelector('.nowPlayingVolumeSlider'); + var nowPlayingVolumeSliderContainer = context.querySelector('.nowPlayingVolumeSliderContainer'); + + if (nowPlayingVolumeSlider) { + if (showVolumeSlider) { + nowPlayingVolumeSliderContainer.classList.remove('hide'); + } else { + nowPlayingVolumeSliderContainer.classList.add('hide'); + } + + if (!nowPlayingVolumeSlider.dragging) { + nowPlayingVolumeSlider.value = volumeLevel || 0; + } } } } @@ -435,11 +452,12 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL }], dragHandle: true }); - - if (items.length) { - context.querySelector('.btnTogglePlaylist').classList.remove('hide'); - } else { - context.querySelector('.btnTogglePlaylist').classList.add('hide'); + if (layoutManager.mobile) { + if (items.length > 0) { + context.querySelector('.btnTogglePlaylist').classList.remove('hide'); + } else { + context.querySelector('.btnTogglePlaylist').classList.add('hide'); + } } var itemsContainer = context.querySelector('.playlist'); @@ -456,8 +474,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } imageLoader.lazyChildren(itemsContainer); - context.querySelector('.playlist').classList.add('hide'); - context.querySelector('.contextMenu').classList.add('hide'); context.querySelector('.btnSavePlaylist').classList.add('hide'); }); } @@ -713,7 +729,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (context.querySelector('.playlist').classList.contains('hide')) { context.querySelector('.playlist').classList.remove('hide'); context.querySelector('.btnSavePlaylist').classList.remove('hide'); - context.querySelector('.contextMenu').classList.add('hide'); context.querySelector('.volumecontrol').classList.add('hide'); if (layoutManager.mobile) { context.querySelector('.playlistSectionButton').classList.remove('playlistSectionButtonTransparent'); @@ -721,21 +736,14 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } else { context.querySelector('.playlist').classList.add('hide'); context.querySelector('.btnSavePlaylist').classList.add('hide'); - context.querySelector('.volumecontrol').classList.remove('hide'); + if (showMuteButton && showVolumeSlider) { + context.querySelector('.volumecontrol').classList.remove('hide'); + } if (layoutManager.mobile) { context.querySelector('.playlistSectionButton').classList.add('playlistSectionButtonTransparent'); } } }); - context.querySelector('.btnToggleContextMenu').addEventListener('click', function () { - if (context.querySelector('.contextMenu').classList.contains('hide')) { - context.querySelector('.contextMenu').classList.remove('hide'); - context.querySelector('.btnSavePlaylist').classList.add('hide'); - context.querySelector('.playlist').classList.add('hide'); - } else { - context.querySelector('.contextMenu').classList.add('hide'); - } - }); } function onPlayerChange() { @@ -787,12 +795,17 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL volumecontrolHtml += ``; volumecontrolHtml += '
'; volumecontrolHtml += '
'; + let optionsSection = context.querySelector('.playlistSectionButton'); if (!layoutManager.mobile) { context.querySelector('.nowPlayingSecondaryButtons').innerHTML += volumecontrolHtml; - context.querySelector('.playlistSectionButton').innerHTML += contextmenuHtml; + optionsSection.innerHTML += contextmenuHtml; + optionsSection.classList.remove('align-items-center', 'justify-content-center'); + optionsSection.classList.add('align-items-right', 'justify-content-flex-end'); + context.querySelector('.playlist').classList.remove('hide'); } else { - context.querySelector('.playlistSectionButton').innerHTML += volumecontrolHtml + contextmenuHtml; - context.querySelector('.playlistSectionButton').classList.add('playlistSectionButtonTransparent'); + optionsSection.innerHTML += volumecontrolHtml + contextmenuHtml; + optionsSection.classList.add('playlistSectionButtonTransparent'); + context.querySelector('.btnTogglePlaylist').classList.remove('hide'); } bindEvents(context); diff --git a/src/nowplaying.html b/src/nowplaying.html index 5f235a562..efeb2526d 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -163,20 +163,14 @@
- -
-
-
-
-
-
-
From 74d32d3cbd5cbe6e2845317cc9d92ed733813570 Mon Sep 17 00:00:00 2001 From: ferferga Date: Wed, 17 Jun 2020 22:30:59 +0200 Subject: [PATCH 0036/1168] Add repeat button in mobile layout --- src/components/remotecontrol/remotecontrol.css | 2 +- src/components/remotecontrol/remotecontrol.js | 10 ++++++++-- src/nowplaying.html | 8 +++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index 115fc2c24..de7e689ac 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -290,7 +290,7 @@ border-radius: 0; } - .nowPlayingInfoButtons .btnRewind { + .nowPlayingInfoButtons .btnRepeatMobile { position: absolute; left: 0; margin-left: 0; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 89c56090e..d850d1be6 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -293,8 +293,14 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL buttonVisible(context.querySelector('.btnStop'), null != item); buttonVisible(context.querySelector('.btnNextTrack'), null != item); buttonVisible(context.querySelector('.btnPreviousTrack'), null != item); - buttonVisible(context.querySelector('.btnRewind'), null != item); - buttonVisible(context.querySelector('.btnFastForward'), null != item); + if (layoutManager.mobile) { + buttonVisible(context.querySelector('.btnRewind'), false); + buttonVisible(context.querySelector('.btnFastForward'), false); + buttonVisible(context.querySelector('.nowPlayingInfoButtons').querySelector('.repeatToggleButton'), true); + } else { + buttonVisible(context.querySelector('.btnRewind'), null != item); + buttonVisible(context.querySelector('.btnFastForward'), null != item); + } var positionSlider = context.querySelector('.nowPlayingPositionSlider'); if (positionSlider && item && item.RunTimeTicks) { diff --git a/src/nowplaying.html b/src/nowplaying.html index efeb2526d..4266b01f0 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -29,6 +29,11 @@
+ + - From ff6bfbf2b43ed14f4ff99aeb4afb7cffb7c6883b Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 01:19:59 +0200 Subject: [PATCH 0037/1168] Add playlist shuffling toggle to remotecontrol.js --- src/components/playback/playbackmanager.js | 35 ++++++++++++- src/components/playback/playqueuemanager.js | 50 +++++++++++++++++-- .../remotecontrol/remotecontrol.css | 2 +- src/components/remotecontrol/remotecontrol.js | 27 +++++++++- src/nowplaying.html | 5 +- src/plugins/sessionPlayer/plugin.js | 7 +++ src/themes/appletv/theme.css | 4 ++ src/themes/blueradiance/theme.css | 4 ++ src/themes/dark/theme.css | 4 ++ src/themes/light/theme.css | 4 ++ src/themes/purplehaze/theme.css | 4 ++ src/themes/wmc/theme.css | 4 ++ 12 files changed, 143 insertions(+), 7 deletions(-) diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 73f07a05f..ad1b156d6 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -2097,6 +2097,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla state.PlayState.IsMuted = player.isMuted(); state.PlayState.IsPaused = player.paused(); state.PlayState.RepeatMode = self.getRepeatMode(player); + state.PlayState.ShuffleMode = self.getPlaylistShuffleMode(player); state.PlayState.MaxStreamingBitrate = self.getMaxStreamingBitrate(player); state.PlayState.PositionTicks = getCurrentTicks(player); @@ -3304,6 +3305,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla sendProgressUpdate(player, 'repeatmodechange'); } + function onShufflePlaylistModeChange() { + var player = this; + sendProgressUpdate(player, 'shuffleplaylistmodechange'); + } + function onPlaylistItemMove(e) { var player = this; sendProgressUpdate(player, 'playlistitemmove', true); @@ -3358,6 +3364,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.on(player, 'unpause', onPlaybackUnpause); events.on(player, 'volumechange', onPlaybackVolumeChange); events.on(player, 'repeatmodechange', onRepeatModeChange); + events.on(player, 'shuffleplaylistmodechange', onShufflePlaylistModeChange); events.on(player, 'playlistitemmove', onPlaylistItemMove); events.on(player, 'playlistitemremove', onPlaylistItemRemove); events.on(player, 'playlistitemadd', onPlaylistItemAdd); @@ -3370,6 +3377,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.on(player, 'unpause', onPlaybackUnpause); events.on(player, 'volumechange', onPlaybackVolumeChange); events.on(player, 'repeatmodechange', onRepeatModeChange); + events.on(player, 'shuffleplaylistmodechange', onShufflePlaylistModeChange); events.on(player, 'playlistitemmove', onPlaylistItemMove); events.on(player, 'playlistitemremove', onPlaylistItemRemove); events.on(player, 'playlistitemadd', onPlaylistItemAdd); @@ -3811,7 +3819,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }); }; - PlaybackManager.prototype.shuffle = function (shuffleItem, player, queryOptions) { + PlaybackManager.prototype.shuffle = function (shuffleItem, player) { player = player || this._currentPlayer; if (player && player.shuffle) { @@ -3878,6 +3886,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', + 'SetPlaylistShuffleMode', 'PlayMediaSource', 'PlayTrailers' ]; @@ -3932,6 +3941,27 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return this._playQueueManager.getRepeatMode(); }; + PlaybackManager.prototype.setPlaylistShuffleMode = function (value, player) { + + player = player || this._currentPlayer; + if (player && !enableLocalPlaylistManagement(player)) { + return player.setShuffleMode(value); + } + + this._playQueueManager.setShuffleMode(value); + events.trigger(player, 'shuffleplaylistmodechange'); + }; + + PlaybackManager.prototype.getPlaylistShuffleMode = function (player) { + + player = player || this._currentPlayer; + if (player && !enableLocalPlaylistManagement(player)) { + return player.getPlaylistShuffleMode(); + } + + return this._playQueueManager.getShuffleMode(); + }; + PlaybackManager.prototype.trySetActiveDeviceName = function (name) { name = normalizeName(name); @@ -4000,6 +4030,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla case 'SetRepeatMode': this.setRepeatMode(cmd.Arguments.RepeatMode, player); break; + case 'SetPlaylistShuffleMode': + this.setPlaylistShuffleMode(cmd.Arguments.ShuffleMode, player); + break; case 'VolumeUp': this.volumeUp(player); break; diff --git a/src/components/playback/playqueuemanager.js b/src/components/playback/playqueuemanager.js index 565cb6993..e26a738a0 100644 --- a/src/components/playback/playqueuemanager.js +++ b/src/components/playback/playqueuemanager.js @@ -24,8 +24,10 @@ define([], function () { function PlayQueueManager() { + this._sortedPlaylist = []; this._playlist = []; this._repeatMode = 'RepeatNone'; + this._shuffleMode = 'Sorted'; } PlayQueueManager.prototype.getPlaylist = function () { @@ -56,6 +58,30 @@ define([], function () { } }; + PlayQueueManager.prototype.shufflePlaylist = function () { + this._sortedPlaylist = []; + for (let item of this._playlist) { + this._sortedPlaylist.push(item); + } + + for (let i = this._playlist.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * i); + const temp = this._playlist[i]; + this._playlist[i] = this._playlist[j]; + this._playlist[j] = temp; + } + this._shuffleMode = 'Shuffle'; + }; + + PlayQueueManager.prototype.sortShuffledPlaylist = function () { + this._playlist = []; + for (let item of this._sortedPlaylist) { + this._playlist.push(item); + } + this._sortedPlaylist = []; + this._shuffleMode = 'Sorted'; + }; + function arrayInsertAt(destArray, pos, arrayToInsert) { var args = []; args.push(pos); // where to insert @@ -176,21 +202,39 @@ define([], function () { PlayQueueManager.prototype.reset = function () { + this._sortedPlaylist = []; this._playlist = []; this._currentPlaylistItemId = null; this._repeatMode = 'RepeatNone'; + this._shuffleMode = 'Sorted'; }; PlayQueueManager.prototype.setRepeatMode = function (value) { - - this._repeatMode = value; + if (value === 'RepeatOne' || value === 'RepeatAll' || value === 'RepeatNone') { + this._repeatMode = value; + } else { + throw new TypeError('invalid value provided for setRepeatMode'); + } }; PlayQueueManager.prototype.getRepeatMode = function () { - return this._repeatMode; }; + PlayQueueManager.prototype.setShuffleMode = function (value) { + if (value === 'Sorted') { + this.sortShuffledPlaylist(); + } else if (value === 'Shuffle') { + this.shufflePlaylist(); + } else { + throw new TypeError('invalid value provided for setShuffleMode'); + } + }; + + PlayQueueManager.prototype.getShuffleMode = function () { + return this._shuffleMode; + }; + PlayQueueManager.prototype.getNextItemInfo = function () { var newIndex; diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index de7e689ac..34a65f61e 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -298,7 +298,7 @@ font-size: smaller; } - .nowPlayingInfoButtons .btnFastForward { + .nowPlayingInfoButtons .btnShuffleMobile { position: absolute; right: 0; margin-right: 0; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index d850d1be6..8755fb491 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -297,6 +297,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL buttonVisible(context.querySelector('.btnRewind'), false); buttonVisible(context.querySelector('.btnFastForward'), false); buttonVisible(context.querySelector('.nowPlayingInfoButtons').querySelector('.repeatToggleButton'), true); + buttonVisible(context.querySelector('.nowPlayingInfoButtons').querySelector('.btnShuffleMobile'), true); } else { buttonVisible(context.querySelector('.btnRewind'), null != item); buttonVisible(context.querySelector('.btnFastForward'), null != item); @@ -495,6 +496,18 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL updateRepeatModeDisplay(playbackManager.getRepeatMode(player)); } + function onShufflePlaylistModeChange() { + let shuffleMode = playbackManager.getPlaylistShuffleMode(this); + let context = dlg; + let shuffleButton = context.querySelector('.btnShuffle'); + if ('Sorted' === shuffleMode) { + shuffleButton.classList.remove('shuffleButton-active'); + } else if ('Shuffle' === shuffleMode) { + shuffleButton.classList.add('shuffleButton-active'); + } + onPlaylistUpdate(); + } + function onPlaylistUpdate(e) { loadPlaylist(dlg, this); } @@ -556,7 +569,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL events.off(player, 'playbackstart', onPlaybackStart); events.off(player, 'statechange', onStateChanged); events.off(player, 'repeatmodechange', onRepeatModeChange); - events.off(player, 'playlistitemremove', onPlaylistUpdate); + events.off(player, 'shuffleplaylistmodechange', onShufflePlaylistModeChange); + events.off(player, 'playlistitemremove', onPlaylistItemRemoved); events.off(player, 'playlistitemmove', onPlaylistUpdate); events.off(player, 'playbackstop', onPlaybackStopped); events.off(player, 'volumechange', onVolumeChanged); @@ -576,6 +590,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL events.on(player, 'playbackstart', onPlaybackStart); events.on(player, 'statechange', onStateChanged); events.on(player, 'repeatmodechange', onRepeatModeChange); + events.on(player, 'shuffleplaylistmodechange', onShufflePlaylistModeChange); events.on(player, 'playlistitemremove', onPlaylistItemRemoved); events.on(player, 'playlistitemmove', onPlaylistUpdate); events.on(player, 'playbackstop', onPlaybackStopped); @@ -676,6 +691,16 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL playbackManager.fastForward(currentPlayer); } }); + context.querySelector('.btnShuffle').addEventListener('click', function () { + if (currentPlayer) { + if (playbackManager.getPlaylistShuffleMode(currentPlayer) === 'Sorted') { + playbackManager.setPlaylistShuffleMode('Shuffle', currentPlayer); + } else { + playbackManager.setPlaylistShuffleMode('Sorted', currentPlayer); + } + } + }); + context.querySelector('.btnPreviousTrack').addEventListener('click', function () { console.log(currentPlayer); if (currentPlayer) { diff --git a/src/nowplaying.html b/src/nowplaying.html index 4266b01f0..70f8e298e 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -58,7 +58,10 @@ - + +
diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index 489b57493..241d3fba4 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -506,6 +506,13 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'] }); }; + SessionPlayer.prototype.setPlaylistShuffleMode = function (mode) { + + sendCommandByName(this, 'SetPlaylistShuffleMode', { + ShuffleMode: mode + }); + }; + SessionPlayer.prototype.displayContent = function (options) { sendCommandByName(this, 'DisplayContent', options); diff --git a/src/themes/appletv/theme.css b/src/themes/appletv/theme.css index b3ce2c7e9..9d0ccdc9d 100644 --- a/src/themes/appletv/theme.css +++ b/src/themes/appletv/theme.css @@ -450,6 +450,10 @@ html { color: #4285f4; } +.shuffleButton-active { + color: #4285f4 !important; +} + .card:focus .cardBox.visualCardBox, .card:focus .cardBox:not(.visualCardBox) .cardScalable { border-color: #00a4dc !important; diff --git a/src/themes/blueradiance/theme.css b/src/themes/blueradiance/theme.css index 74a60c91c..5215f4bb6 100644 --- a/src/themes/blueradiance/theme.css +++ b/src/themes/blueradiance/theme.css @@ -450,6 +450,10 @@ html { color: #4285f4; } +.shuffleButton-active { + color: #4285f4 !important; +} + .card:focus .cardBox.visualCardBox, .card:focus .cardBox:not(.visualCardBox) .cardScalable { border-color: #00a4dc !important; diff --git a/src/themes/dark/theme.css b/src/themes/dark/theme.css index a32e60638..1e8a996c9 100644 --- a/src/themes/dark/theme.css +++ b/src/themes/dark/theme.css @@ -421,6 +421,10 @@ html { color: #4285f4; } +.shuffleButton-active { + color: #4285f4 !important; +} + .card:focus .cardBox.visualCardBox, .card:focus .cardBox:not(.visualCardBox) .cardScalable { border-color: #00a4dc !important; diff --git a/src/themes/light/theme.css b/src/themes/light/theme.css index 114ef7c3b..82b2f5075 100644 --- a/src/themes/light/theme.css +++ b/src/themes/light/theme.css @@ -432,6 +432,10 @@ html { color: #4285f4; } +.shuffleButton-active { + color: #4285f4 !important; +} + .card:focus .cardBox.visualCardBox, .card:focus .cardBox:not(.visualCardBox) .cardScalable { border-color: #00a4dc !important; diff --git a/src/themes/purplehaze/theme.css b/src/themes/purplehaze/theme.css index de69a5542..140969f65 100644 --- a/src/themes/purplehaze/theme.css +++ b/src/themes/purplehaze/theme.css @@ -547,6 +547,10 @@ a[data-role=button] { color: #4285f4; } +.shuffleButton-active { + color: #4285f4 !important; +} + .personCard .cardScalable { border-radius: 50%; border: 1px solid rgb(255, 255, 255); diff --git a/src/themes/wmc/theme.css b/src/themes/wmc/theme.css index e7d4c0371..a62d38297 100644 --- a/src/themes/wmc/theme.css +++ b/src/themes/wmc/theme.css @@ -430,6 +430,10 @@ html { color: #4285f4; } +.shuffleButton-active { + color: #4285f4 !important; +} + .card:focus .cardBox.visualCardBox, .card:focus .cardBox:not(.visualCardBox) .cardScalable { border-color: #fff !important; From 40c2ccaab3a1bfbbddf39ae29dbe6504b2e7dc90 Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 01:24:04 +0200 Subject: [PATCH 0038/1168] Minor style improvements to nowPlaying --- src/components/nowPlayingBar/nowPlayingBar.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.css b/src/components/nowPlayingBar/nowPlayingBar.css index b1e77715f..e83ef729d 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.css +++ b/src/components/nowPlayingBar/nowPlayingBar.css @@ -56,8 +56,8 @@ text-align: left; flex-grow: 1; font-size: 92%; - margin-right: 2.4em; - margin-left: 1em; + margin-right: 1em; + margin-left: 0.2em; } .nowPlayingBarCenter { @@ -159,7 +159,7 @@ } .nowPlayingBarInfoContainer { - width: 70%; + width: 100%; } } From 2ab476f073790845e1b12b79181da1a6f30d4a5a Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 08:04:33 +0200 Subject: [PATCH 0039/1168] Fix playlist for items without images --- src/components/listview/listview.js | 90 +++++++++++++++-------------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/components/listview/listview.js b/src/components/listview/listview.js index 42f32ba79..4ce8526c9 100644 --- a/src/components/listview/listview.js +++ b/src/components/listview/listview.js @@ -270,52 +270,54 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan if (options.image !== false) { let imgData = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth); - let imgUrl = imgData.url; - let blurhash = imgData.blurhash; - let imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage'; + if (imgData) { + let imgUrl = imgData.url; + let blurhash = imgData.blurhash; + let imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage'; - if (isLargeStyle && layoutManager.tv) { - imageClass += ' listItemImage-large-tv'; + if (isLargeStyle && layoutManager.tv) { + imageClass += ' listItemImage-large-tv'; + } + + var playOnImageClick = options.imagePlayButton && !layoutManager.tv; + + if (!clickEntireItem) { + imageClass += ' itemAction'; + } + + var imageAction = playOnImageClick ? 'resume' : action; + + let blurhashAttrib = ''; + if (blurhash && blurhash.length > 0) { + blurhashAttrib = 'data-blurhash="' + blurhash + '"'; + } + + if (imgUrl) { + html += '
'; + } else { + html += '
'; + } + + var indicatorsHtml = ''; + indicatorsHtml += indicators.getPlayedIndicatorHtml(item); + + if (indicatorsHtml) { + html += '
' + indicatorsHtml + '
'; + } + + if (playOnImageClick) { + html += ''; + } + + var progressHtml = indicators.getProgressBarHtml(item, { + containerClass: 'listItemProgressBar' + }); + + if (progressHtml) { + html += progressHtml; + } + html += '
'; } - - var playOnImageClick = options.imagePlayButton && !layoutManager.tv; - - if (!clickEntireItem) { - imageClass += ' itemAction'; - } - - var imageAction = playOnImageClick ? 'resume' : action; - - let blurhashAttrib = ''; - if (blurhash && blurhash.length > 0) { - blurhashAttrib = 'data-blurhash="' + blurhash + '"'; - } - - if (imgUrl) { - html += '
'; - } else { - html += '
'; - } - - var indicatorsHtml = ''; - indicatorsHtml += indicators.getPlayedIndicatorHtml(item); - - if (indicatorsHtml) { - html += '
' + indicatorsHtml + '
'; - } - - if (playOnImageClick) { - html += ''; - } - - var progressHtml = indicators.getProgressBarHtml(item, { - containerClass: 'listItemProgressBar' - }); - - if (progressHtml) { - html += progressHtml; - } - html += '
'; } if (options.showIndexNumberLeft) { From 2a74d53c35cfe8a9388a6f33c06f347c7eb1f93f Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 08:39:23 +0200 Subject: [PATCH 0040/1168] Finish work on shuffle mode --- src/components/nowPlayingBar/nowPlayingBar.js | 72 ++++++++++++++----- .../remotecontrol/remotecontrol.css | 4 +- src/components/remotecontrol/remotecontrol.js | 10 ++- src/nowplaying.html | 13 ---- 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 33f9aa405..e1d8ebba6 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -47,7 +47,9 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', html += ''; html += ''; - html += ''; + if (!layoutManager.mobile) { + html += ''; + } html += '
'; html += '
'; @@ -61,12 +63,17 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', html += '
'; html += ''; + html += ''; html += '
'; html += '
'; html += ''; - html += ''; + if (layoutManager.mobile) { + html += ''; + } else { + html += ''; + } html += '
'; html += '
'; @@ -163,6 +170,16 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } }); + elem.querySelector('.btnShuffle').addEventListener('click', function () { + if (currentPlayer) { + if (playbackManager.getPlaylistShuffleMode(currentPlayer) === 'Sorted') { + playbackManager.setPlaylistShuffleMode('Shuffle', currentPlayer); + } else { + playbackManager.setPlaylistShuffleMode('Sorted', currentPlayer); + } + } + }); + toggleRepeatButton = elem.querySelector('.toggleRepeatButton'); toggleRepeatButton.addEventListener('click', function () { @@ -263,6 +280,10 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', parentContainer.insertAdjacentHTML('afterbegin', getNowPlayingBarHtml()); nowPlayingBarElement = parentContainer.querySelector('.nowPlayingBar'); + if (layoutManager.mobile) { + hideButton(nowPlayingBarElement.querySelector('.shuffle')); + } + if (browser.safari && browser.slow) { // Not handled well here. The wrong elements receive events, bar doesn't update quickly enough, etc. nowPlayingBarElement.classList.add('noMediaProgress'); @@ -316,6 +337,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } updateRepeatModeDisplay(playState.RepeatMode); + onPlaylistShuffleModeChange(); updatePlayerVolumeState(playState.IsMuted, playState.VolumeLevel); @@ -550,22 +572,24 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', var apiClient = connectionManager.getApiClient(nowPlayingItem.ServerId); apiClient.getItem(apiClient.getCurrentUserId(), nowPlayingItem.Id).then(function (item) { var userData = item.UserData || {}; - var likes = userData.Likes == null ? '' : userData.Likes; - var contextButton = document.querySelector('.nowPlayingBar').querySelector('.btnToggleContextMenu'); - var options = { - play: false, - queue: false, - positionTo: contextButton - }; - nowPlayingUserData.innerHTML = ''; - apiClient.getCurrentUser().then(function(user) { - contextButton.addEventListener('click', function () { - itemContextMenu.show(Object.assign({ - item: item, - user: user - }, options )); + if (!layoutManager.mobile) { + var likes = userData.Likes == null ? '' : userData.Likes; + var contextButton = document.querySelector('.nowPlayingBar').querySelector('.btnToggleContextMenu'); + var options = { + play: false, + queue: false, + positionTo: contextButton + }; + apiClient.getCurrentUser().then(function (user) { + contextButton.addEventListener('click', function () { + itemContextMenu.show(Object.assign({ + item: item, + user: user + }, options)); + }); }); - }); + } + nowPlayingUserData.innerHTML = ''; }); } } else { @@ -592,6 +616,18 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', updateRepeatModeDisplay(playbackManager.getRepeatMode(player)); } + function onPlaylistShuffleModeChange() { + let shuffleMode = playbackManager.getPlaylistShuffleMode(this); + let context = nowPlayingBarElement; + let toggleShuffleButton = context.querySelector('.btnShuffle'); + + if ('Sorted' === shuffleMode) { + toggleShuffleButton.classList.remove('shuffleButton-active'); + } else if ('Shuffle' === shuffleMode) { + toggleShuffleButton.classList.add('shuffleButton-active'); + } + } + function showNowPlayingBar() { if (!isVisibilityAllowed) { @@ -697,6 +733,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', events.off(player, 'playbackstart', onPlaybackStart); events.off(player, 'statechange', onPlaybackStart); events.off(player, 'repeatmodechange', onRepeatModeChange); + events.off(player, 'shuffleplaylistmodechange', onPlaylistShuffleModeChange); events.off(player, 'playbackstop', onPlaybackStopped); events.off(player, 'volumechange', onVolumeChanged); events.off(player, 'pause', onPlayPauseStateChanged); @@ -745,6 +782,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', events.on(player, 'playbackstart', onPlaybackStart); events.on(player, 'statechange', onPlaybackStart); events.on(player, 'repeatmodechange', onRepeatModeChange); + events.on(player, 'shuffleplaylistmodechange', onPlaylistShuffleModeChange); events.on(player, 'playbackstop', onPlaybackStopped); events.on(player, 'volumechange', onVolumeChanged); events.on(player, 'pause', onPlayPauseStateChanged); diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index 34a65f61e..6e6dc3bf1 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -290,7 +290,7 @@ border-radius: 0; } - .nowPlayingInfoButtons .btnRepeatMobile { + .nowPlayingInfoButtons .btnRepeat { position: absolute; left: 0; margin-left: 0; @@ -298,7 +298,7 @@ font-size: smaller; } - .nowPlayingInfoButtons .btnShuffleMobile { + .nowPlayingInfoButtons .btnShuffle { position: absolute; right: 0; margin-right: 0; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 8755fb491..0b6ba6d57 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -2,6 +2,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL 'use strict'; var showMuteButton = true; var showVolumeSlider = true; + var shuffleButton; function showAudioMenu(context, player, button, item) { var currentIndex = playbackManager.getAudioStreamIndex(player); @@ -296,8 +297,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (layoutManager.mobile) { buttonVisible(context.querySelector('.btnRewind'), false); buttonVisible(context.querySelector('.btnFastForward'), false); - buttonVisible(context.querySelector('.nowPlayingInfoButtons').querySelector('.repeatToggleButton'), true); - buttonVisible(context.querySelector('.nowPlayingInfoButtons').querySelector('.btnShuffleMobile'), true); } else { buttonVisible(context.querySelector('.btnRewind'), null != item); buttonVisible(context.querySelector('.btnFastForward'), null != item); @@ -326,6 +325,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } updateRepeatModeDisplay(playState.RepeatMode); + onShufflePlaylistModeChange(); updateNowPlayingInfo(context, state); } @@ -826,9 +826,11 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL volumecontrolHtml += ``; volumecontrolHtml += '
'; volumecontrolHtml += '
'; + let shuffleButtonHtml = ``; + let repeatButtonHtml = ``; let optionsSection = context.querySelector('.playlistSectionButton'); if (!layoutManager.mobile) { - context.querySelector('.nowPlayingSecondaryButtons').innerHTML += volumecontrolHtml; + context.querySelector('.nowPlayingSecondaryButtons').insertAdjacentHTML('beforeend', repeatButtonHtml + shuffleButtonHtml + volumecontrolHtml); optionsSection.innerHTML += contextmenuHtml; optionsSection.classList.remove('align-items-center', 'justify-content-center'); optionsSection.classList.add('align-items-right', 'justify-content-flex-end'); @@ -837,6 +839,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL optionsSection.innerHTML += volumecontrolHtml + contextmenuHtml; optionsSection.classList.add('playlistSectionButtonTransparent'); context.querySelector('.btnTogglePlaylist').classList.remove('hide'); + context.querySelector('.nowPlayingInfoButtons').insertAdjacentHTML('afterbegin', repeatButtonHtml); + context.querySelector('.nowPlayingInfoButtons').insertAdjacentHTML('beforeend', shuffleButtonHtml); } bindEvents(context); diff --git a/src/nowplaying.html b/src/nowplaying.html index 70f8e298e..0c7688246 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -29,11 +29,6 @@
- - -
@@ -80,11 +72,6 @@ - -
From e2da870f3282d13d66ea38e6d5f0aeea55fe3016 Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 08:56:09 +0200 Subject: [PATCH 0041/1168] Take out likes variable from condition --- src/components/nowPlayingBar/nowPlayingBar.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index e1d8ebba6..958b0ebfc 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -572,10 +572,10 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', var apiClient = connectionManager.getApiClient(nowPlayingItem.ServerId); apiClient.getItem(apiClient.getCurrentUserId(), nowPlayingItem.Id).then(function (item) { var userData = item.UserData || {}; + var likes = userData.Likes == null ? '' : userData.Likes; if (!layoutManager.mobile) { - var likes = userData.Likes == null ? '' : userData.Likes; - var contextButton = document.querySelector('.nowPlayingBar').querySelector('.btnToggleContextMenu'); - var options = { + let contextButton = document.querySelector('.nowPlayingBar').querySelector('.btnToggleContextMenu'); + let options = { play: false, queue: false, positionTo: contextButton From dcb0eb8c01c5e70daf229d6b6b9f0f3999886e70 Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 09:06:12 +0200 Subject: [PATCH 0042/1168] Show .btnSavePlaylist always on desktop --- src/components/remotecontrol/remotecontrol.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 0b6ba6d57..e084afc8e 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -481,7 +481,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } imageLoader.lazyChildren(itemsContainer); - context.querySelector('.btnSavePlaylist').classList.add('hide'); }); } @@ -835,6 +834,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL optionsSection.classList.remove('align-items-center', 'justify-content-center'); optionsSection.classList.add('align-items-right', 'justify-content-flex-end'); context.querySelector('.playlist').classList.remove('hide'); + context.querySelector('.btnSavePlaylist').classList.remove('hide'); } else { optionsSection.innerHTML += volumecontrolHtml + contextmenuHtml; optionsSection.classList.add('playlistSectionButtonTransparent'); From 1a6e0973f3399e0606f5a0ac3d8b06aa6b4c551e Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 09:22:17 +0200 Subject: [PATCH 0043/1168] Fix duplicated context menus --- src/components/nowPlayingBar/nowPlayingBar.js | 4 ++++ src/components/remotecontrol/remotecontrol.js | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 958b0ebfc..e50c0cee5 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -575,6 +575,10 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', var likes = userData.Likes == null ? '' : userData.Likes; if (!layoutManager.mobile) { let contextButton = document.querySelector('.nowPlayingBar').querySelector('.btnToggleContextMenu'); + // We remove the previous event listener by replacing the item in each update event + let contextButtonClone = contextButton.cloneNode(true); + contextButton.parentNode.replaceChild(contextButtonClone, contextButton); + contextButton = document.querySelector('.nowPlayingBar').querySelector('.btnToggleContextMenu'); let options = { play: false, queue: false, diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index e084afc8e..f2a298ac2 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -168,7 +168,11 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL }) : null; console.debug('updateNowPlayingInfo'); - var contextButton = context.querySelector('.btnToggleContextMenu'); + let contextButton = context.querySelector('.btnToggleContextMenu'); + // We remove the previous event listener by replacing the item in each update event + let contextButtonClone = contextButton.cloneNode(true); + contextButton.parentNode.replaceChild(contextButtonClone, contextButton); + contextButton = context.querySelector('.btnToggleContextMenu'); var options = { play: false, queue: false, From 989c99521fc8e820157aedd74e95c14af66a893a Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 09:30:31 +0200 Subject: [PATCH 0044/1168] Go to previous track on double click --- src/components/nowPlayingBar/nowPlayingBar.js | 15 ++++++++++++--- src/components/remotecontrol/remotecontrol.js | 17 ++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index e50c0cee5..9eebdfcfc 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -157,12 +157,15 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } }); - elem.querySelector('.previousTrackButton').addEventListener('click', function () { + elem.querySelector('.previousTrackButton').addEventListener('click', function (e) { if (currentPlayer) { if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime <= 5 || !playbackManager.previousTrack(currentPlayer))) { + // Cancel this event if doubleclick is fired + if (e.originalEvent.detail > 1) { + return; + } playbackManager.seekPercent(0, currentPlayer); - // This is done automatically by playbackManager, however, setting this here - // gives instant visual feedback + // This is done automatically by playbackManager, however, setting this here gives instant visual feedback positionSlider.value = 0; } else { playbackManager.previousTrack(currentPlayer); @@ -170,6 +173,12 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } }); + elem.querySelector('.previousTrackButton').addEventListener('dblclick', function () { + if (currentPlayer) { + playbackManager.previousTrack(currentPlayer); + } + }); + elem.querySelector('.btnShuffle').addEventListener('click', function () { if (currentPlayer) { if (playbackManager.getPlaylistShuffleMode(currentPlayer) === 'Sorted') { diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index f2a298ac2..3d1faadff 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -2,7 +2,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL 'use strict'; var showMuteButton = true; var showVolumeSlider = true; - var shuffleButton; function showAudioMenu(context, player, button, item) { var currentIndex = playbackManager.getAudioStreamIndex(player); @@ -704,19 +703,27 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } }); - context.querySelector('.btnPreviousTrack').addEventListener('click', function () { - console.log(currentPlayer); + context.querySelector('.btnPreviousTrack').addEventListener('click', function (e) { if (currentPlayer) { if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime <= 5 || !playbackManager.previousTrack(currentPlayer))) { + // Cancel this event if doubleclick is fired + if (e.originalEvent.detail > 1) { + return; + } playbackManager.seekPercent(0, currentPlayer); - // This is done automatically by playbackManager. However, setting this here - // gives instant visual feedback + // This is done automatically by playbackManager. However, setting this here gives instant visual feedback positionSlider.value = 0; } else { playbackManager.previousTrack(currentPlayer); } } }); + + context.querySelector('.btnPreviousTrack').addEventListener('dblclick', function () { + if (currentPlayer) { + playbackManager.previousTrack(currentPlayer); + } + }); positionSlider.addEventListener('change', function () { var value = this.value; From 0e2b960ae795ef2e6be7553bc92ca9f286d8fe23 Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 10:15:30 +0200 Subject: [PATCH 0045/1168] Repeat song on double click only if there is a previous item --- src/components/nowPlayingBar/nowPlayingBar.js | 2 +- src/components/remotecontrol/remotecontrol.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 9eebdfcfc..1c1fbb9f0 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -161,7 +161,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', if (currentPlayer) { if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime <= 5 || !playbackManager.previousTrack(currentPlayer))) { // Cancel this event if doubleclick is fired - if (e.originalEvent.detail > 1) { + if (e.originalEvent.detail > 1 && playbackManager.previousTrack(currentPlayer)) { return; } playbackManager.seekPercent(0, currentPlayer); diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 3d1faadff..dd4e42c0c 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -707,7 +707,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (currentPlayer) { if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime <= 5 || !playbackManager.previousTrack(currentPlayer))) { // Cancel this event if doubleclick is fired - if (e.originalEvent.detail > 1) { + if (e.originalEvent.detail > 1 && playbackManager.previousTrack(currentPlayer)) { return; } playbackManager.seekPercent(0, currentPlayer); From f9119cc2f6164eb561693d729ad0dcd525e28391 Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 10:55:58 +0200 Subject: [PATCH 0046/1168] Replace context menu 'ViewArtist' with 'ViewAlbumArtist' option for players and fix texting bits --- src/components/itemContextMenu.js | 9 +++++---- src/components/nowPlayingBar/nowPlayingBar.js | 2 +- src/components/remotecontrol/remotecontrol.js | 2 +- src/strings/en-us.json | 3 +-- src/strings/es.json | 5 +++-- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index f258f5fe4..4f0e4e506 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -288,10 +288,11 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', icon: 'album' }); } - - if (options.openArtist !== false && item.ArtistItems && item.ArtistItems.length) { + // Show Album Artist by default, as a song can have multiple artists, which specific one would this option refer to? + // Although some albums can have multiple artists, it's not as common as songs. + if (options.openArtist !== false && item.AlbumArtists && item.AlbumArtists.length) { commands.push({ - name: globalize.translate('ViewArtist'), + name: globalize.translate('ViewAlbumArtist'), id: 'artist', icon: 'person' }); @@ -458,7 +459,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', getResolveFunction(resolve, id)(); break; case 'artist': - appRouter.showItem(item.ArtistItems[0].Id, item.ServerId); + appRouter.showItem(item.AlbumArtists[0].Id, item.ServerId); getResolveFunction(resolve, id)(); break; case 'playallfromhere': diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 1c1fbb9f0..50830af10 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -161,7 +161,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', if (currentPlayer) { if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime <= 5 || !playbackManager.previousTrack(currentPlayer))) { // Cancel this event if doubleclick is fired - if (e.originalEvent.detail > 1 && playbackManager.previousTrack(currentPlayer)) { + if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) { return; } playbackManager.seekPercent(0, currentPlayer); diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index dd4e42c0c..3a87fff80 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -707,7 +707,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (currentPlayer) { if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime <= 5 || !playbackManager.previousTrack(currentPlayer))) { // Cancel this event if doubleclick is fired - if (e.originalEvent.detail > 1 && playbackManager.previousTrack(currentPlayer)) { + if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) { return; } playbackManager.seekPercent(0, currentPlayer); diff --git a/src/strings/en-us.json b/src/strings/en-us.json index bf77f630a..fcfb3e711 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1521,7 +1521,7 @@ "Vertical": "Vertical", "VideoRange": "Video range", "ViewAlbum": "View album", - "ViewArtist": "View artist", + "ViewAlbumArtist": "View album artist", "ViewPlaybackInfo": "View playback info", "Watched": "Watched", "Wednesday": "Wednesday", @@ -1554,5 +1554,4 @@ "UnsupportedPlayback": "Jellyfin cannot decrypt content protected by DRM but all content will be attempted regardless, including protected titles. Some files may appear completely black due to encryption or other unsupported features, such as interactive titles.", "EnableBlurhash": "Enable blurred placeholders for images", "EnableBlurhashHelp": "Images that are still being loaded will be displayed with a blurred placeholder" - } diff --git a/src/strings/es.json b/src/strings/es.json index eedfa3d73..09b5f2cae 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1205,7 +1205,7 @@ "ValueTimeLimitSingleHour": "Tiempo límite: 1 hora", "ValueVideoCodec": "Códec de video: {0}", "ViewAlbum": "Ver album", - "ViewArtist": "Ver artista", + "ViewAlbumArtist": "Ver artista del álbum", "ViewPlaybackInfo": "Ver información de la reproducción", "Watched": "Visto", "Wednesday": "Miércoles", @@ -1560,5 +1560,6 @@ "EnableDetailsBannerHelp": "Mostrar imagen de banner en el tope de la página de detalles del elemento.", "EnableDetailsBanner": "Barra de Detalles", "ShowMore": "Mostrar más", - "ShowLess": "Mostrar menos" + "ShowLess": "Mostrar menos", + "ViewAlbumArtist": "Ver artista del álbum" } From 5a87754c2adc452ba9cdd80e538e0b3e5106482a Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 11:12:03 +0200 Subject: [PATCH 0047/1168] Switch wrong condition for the new previous track behaviour and fix lint --- src/components/nowPlayingBar/nowPlayingBar.js | 2 +- src/components/remotecontrol/remotecontrol.css | 1 + src/components/remotecontrol/remotecontrol.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 50830af10..f76055226 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -159,7 +159,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', elem.querySelector('.previousTrackButton').addEventListener('click', function (e) { if (currentPlayer) { - if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime <= 5 || !playbackManager.previousTrack(currentPlayer))) { + if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) { // Cancel this event if doubleclick is fired if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) { return; diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index 6e6dc3bf1..7df8fefc3 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -364,6 +364,7 @@ padding-left: 7.3%; padding-right: 7.3%; } + .playlistSectionButtonTransparent { background: rgba(0, 0, 0, 0) !important; } diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 3a87fff80..c31d57a74 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -705,7 +705,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL context.querySelector('.btnPreviousTrack').addEventListener('click', function (e) { if (currentPlayer) { - if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime <= 5 || !playbackManager.previousTrack(currentPlayer))) { + if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) { // Cancel this event if doubleclick is fired if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) { return; From 6c0f3a39c745f7e818d535d45a273ec1f8dadaab Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 12:27:15 +0200 Subject: [PATCH 0048/1168] Remove blank space when item doesn't have an image --- src/components/nowPlayingBar/nowPlayingBar.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index f76055226..6fc526489 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -570,8 +570,12 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', if (url) { imageLoader.lazyImage(nowPlayingImageElement, url); + nowPlayingImageElement.style.display = null; + nowPlayingTextElement.style.marginLeft = null; } else { nowPlayingImageElement.style.backgroundImage = ''; + nowPlayingImageElement.style.display = 'none'; + nowPlayingTextElement.style.marginLeft = '1em'; } } From 3b938e9b00ac33b6a37090a233d5ce88ad3d16a6 Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 13:47:57 +0200 Subject: [PATCH 0049/1168] Remove repeated string in es.json --- src/strings/es.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/strings/es.json b/src/strings/es.json index 09b5f2cae..126692923 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1560,6 +1560,5 @@ "EnableDetailsBannerHelp": "Mostrar imagen de banner en el tope de la página de detalles del elemento.", "EnableDetailsBanner": "Barra de Detalles", "ShowMore": "Mostrar más", - "ShowLess": "Mostrar menos", - "ViewAlbumArtist": "Ver artista del álbum" + "ShowLess": "Mostrar menos" } From a62d69f81360528d057ca74daf3c4abe08f74b4a Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 18:31:46 +0200 Subject: [PATCH 0050/1168] CSS fixes when resizing the window --- .../nowPlayingBar/nowPlayingBar.css | 19 +- .../remotecontrol/remotecontrol.css | 322 ++++-------------- src/components/remotecontrol/remotecontrol.js | 4 + 3 files changed, 86 insertions(+), 259 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.css b/src/components/nowPlayingBar/nowPlayingBar.css index e83ef729d..a2d5b4479 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.css +++ b/src/components/nowPlayingBar/nowPlayingBar.css @@ -57,7 +57,7 @@ flex-grow: 1; font-size: 92%; margin-right: 1em; - margin-left: 0.2em; + margin-left: 0.5em; } .nowPlayingBarCenter { @@ -135,12 +135,23 @@ } } -@media all and (max-width: 62em) { - .nowPlayingBarCenter .nowPlayingBarCurrentTime { +@media all and (max-width: 66em) { + .btnShuffle { display: none !important; } } +@media all and (max-width: 80em) { + .nowPlayingBarCenter .nowPlayingBarCurrentTime, + .nowPlayingBarCenter .stopButton { + display: none !important; + } + + .nowPlayingBarInfoContainer { + width: 45%; + } +} + @media all and (max-width: 56em) { .nowPlayingBarCenter { display: none !important; @@ -153,7 +164,7 @@ } } -@media all and (max-width: 36em) { +@media all and (max-width: 60em) { .nowPlayingBarRight .nowPlayingBarVolumeSliderContainer { display: none !important; } diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index 7df8fefc3..d80d7a3c3 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -171,6 +171,72 @@ z-index: 0; } +.mobilePlayer.playlistSectionButtonTransparent { + background: rgba(0, 0, 0, 0) !important; +} + +.mobilePlayer.playlistSection .playlist, +.mobilePlayer.playlistSection .contextMenu { + position: absolute; + top: 12.2em; + bottom: 4.2em; + overflow: scroll; + padding: 0 1em; + display: inline-block; + left: 0; + right: 0; + z-index: 1000; +} + +.mobilePlayer.playlistSectionButton { + position: fixed; + bottom: 0; + left: 0; + height: 4.2em; + right: 0; + padding-left: 7.3%; + padding-right: 7.3%; +} + +.playlistSectionButton:not(.mobilePlayer) { + background: unset !important; +} + +.nowPlayingPlaylist:not(.mobilePlayer) { + background: unset !important; +} + +.mobilePlayer.playlistSectionButton .btnTogglePlaylist { + font-size: larger; + margin: 0; + padding-left: 0; +} + +.mobilePlayer.playlistSectionButton .btnSavePlaylist { + margin: 0; + padding-right: 0; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + flex-grow: 1; + -webkit-box-pack: end; + -webkit-justify-content: flex-end; + justify-content: flex-end; + border-radius: 0; +} + +.mobilePlayer.playlistSectionButton .btnToggleContextMenu { + font-size: larger; + margin: 0; + padding-right: 0; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + flex-grow: 1; + -webkit-box-pack: end; + -webkit-justify-content: flex-end; + justify-content: flex-end; + border-radius: 0; +} + @media all and (min-width: 63em) { .nowPlayingPage { padding: 8em 0 0 0 !important; @@ -188,12 +254,6 @@ .nowPlayingPageUserDataButtonsTitle { display: none !important; } - - .playlistSectionButton, - .nowPlayingPlaylist, - .nowPlayingContextMenu { - background: unset !important; - } } @media all and (min-width: 80em) { @@ -202,7 +262,7 @@ } } -@media all and (orientation: portrait) and (max-width: 47em) { +@media all and (orientation: portrait) and (max-width: 43em) { .remoteControlContent { padding-left: 7.3% !important; padding-right: 7.3% !important; @@ -342,254 +402,6 @@ width: auto; } - #nowPlayingPage .playlistSection .playlist, - #nowPlayingPage .playlistSection .contextMenu { - position: absolute; - top: 12.2em; - bottom: 4.2em; - overflow: scroll; - padding: 0 1em; - display: inline-block; - left: 0; - right: 0; - z-index: 1000; - } - - .playlistSectionButton { - position: fixed; - bottom: 0; - left: 0; - height: 4.2em; - right: 0; - padding-left: 7.3%; - padding-right: 7.3%; - } - - .playlistSectionButtonTransparent { - background: rgba(0, 0, 0, 0) !important; - } - - .playlistSectionButton .btnTogglePlaylist { - font-size: larger; - margin: 0; - padding-left: 0; - } - - .playlistSectionButton .btnSavePlaylist { - margin: 0; - padding-right: 0; - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - justify-content: flex-end; - border-radius: 0; - } - - .playlistSectionButton .btnToggleContextMenu { - font-size: larger; - margin: 0; - padding-right: 0; - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - justify-content: flex-end; - border-radius: 0; - } - - .playlistSectionButton .volumecontrol { - width: 100%; - } - - .remoteControlSection { - margin: 0; - padding: 0 0 4.2em 0; - } - - .nowPlayingButtonsContainer { - display: flex; - height: 100%; - flex-direction: column; - } -} - -@media all and (orientation: landscape) and (max-width: 63em) { - .remoteControlContent { - padding-left: 4.3% !important; - padding-right: 4.3% !important; - display: flex; - height: 100%; - flex-direction: column; - } - - .nowPlayingInfoContainer { - -webkit-box-orient: horizontal !important; - -webkit-box-direction: normal !important; - -webkit-flex-direction: row !important; - flex-direction: row !important; - -webkit-box-align: center; - -webkit-align-items: center; - align-items: center; - width: 100%; - height: calc(100% - 4.2em); - } - - .nowPlayingPageTitle { - /* text-align: center; */ - margin: 0; - } - - .nowPlayingInfoContainerMedia { - text-align: left !important; - width: 80%; - } - - .nowPlayingPositionSliderContainer { - margin: 0.2em 1em 0.2em 1em; - } - - .nowPlayingInfoButtons { - /* margin: 1.5em 0 0 0; */ - -webkit-box-pack: center; - -webkit-justify-content: center; - justify-content: center; - font-size: x-large; - height: 100%; - } - - .nowPlayingPageImageContainer { - width: 30%; - margin: auto 1em auto auto; - } - - .nowPlayingPageImageContainerNoAlbum .cardImageContainer .cardImageIcon { - font-size: 12em; - color: inherit; - } - - .nowPlayingInfoControls { - margin: 0.5em 0 1em 0; - width: 100%; - -webkit-box-pack: start !important; - -webkit-justify-content: start !important; - justify-content: start !important; - } - - .nowPlayingSecondaryButtons { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: center; - -webkit-justify-content: center; - justify-content: center; - } - - .nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle { - width: 20%; - font-size: large; - } - - .nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle button { - padding-top: 0; - padding-right: 0; - margin-right: 0; - float: right; - border-radius: 0; - } - - .paper-icon-button-light:hover { - color: #fff !important; - background-color: transparent !important; - } - - .btnPlayPause { - padding: 0; - margin: 0; - font-size: 1.7em; - } - - .btnPlayPause:hover { - background-color: transparent !important; - } - - .nowPlayingPageImage { - /* width: inherit; */ - overflow-y: hidden; - overflow: hidden; - margin: 0 auto; - } - - .nowPlayingPageImage.nowPlayingPageImageAudio { - width: 100%; - } - - .nowPlayingPageImageContainer.nowPlayingPageImagePoster { - height: 100%; - overflow: hidden; - } - - .nowPlayingPageImageContainer.nowPlayingPageImagePoster img { - height: 100%; - width: auto; - } - - #nowPlayingPage .playlistSection .playlist, - #nowPlayingPage .playlistSection .contextMenu { - position: absolute; - top: 7.2em; - bottom: 4.2em; - overflow: scroll; - padding: 0 1em; - display: inline-block; - left: 0; - right: 0; - z-index: 1000; - } - - .playlistSectionButton { - position: fixed; - bottom: 0; - left: 0; - height: 4.2em; - right: 0; - padding-left: 4.3%; - padding-right: 4.3%; - } - - .playlistSectionButton .btnTogglePlaylist { - font-size: larger; - margin: 0; - padding-left: 0; - } - - .playlistSectionButton .btnSavePlaylist { - margin: 0; - padding-right: 0; - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - justify-content: flex-end; - border-radius: 0; - } - - .playlistSectionButton .btnToggleContextMenu { - font-size: larger; - margin: 0; - padding-right: 0; - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - justify-content: flex-end; - border-radius: 0; - } - .playlistSectionButton .volumecontrol { width: 100%; } diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index c31d57a74..0cf8e2f95 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -852,6 +852,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL context.querySelector('.btnTogglePlaylist').classList.remove('hide'); context.querySelector('.nowPlayingInfoButtons').insertAdjacentHTML('afterbegin', repeatButtonHtml); context.querySelector('.nowPlayingInfoButtons').insertAdjacentHTML('beforeend', shuffleButtonHtml); + let childs = context.querySelectorAll('*'); + for (let child of childs) { + child.classList.add('mobilePlayer'); + } } bindEvents(context); From 49c719348c80632f0fad29e552e6d55212d4e37d Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 18 Jun 2020 20:11:14 +0200 Subject: [PATCH 0051/1168] CSS fixes when resizing library browser --- src/assets/css/librarybrowser.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/assets/css/librarybrowser.css b/src/assets/css/librarybrowser.css index 88598fb94..ddcf9acc0 100644 --- a/src/assets/css/librarybrowser.css +++ b/src/assets/css/librarybrowser.css @@ -272,7 +272,7 @@ } } -@media all and (max-width: 84em) { +@media all and (max-width: 100em) { .withSectionTabs .headerTop { padding-bottom: 0.55em; } @@ -282,7 +282,7 @@ } } -@media all and (min-width: 84em) { +@media all and (min-width: 100em) { .headerTop { padding: 0.8em 0.8em; } @@ -820,7 +820,7 @@ div.itemDetailGalleryLink.defaultCardBackground { } } -@media all and (min-width: 62.5em) { +@media all and (min-width: 100em) { .headerTop { padding-left: 0.8em; padding-right: 0.8em; From 999f27614081f687d500bafa87ad4803d5ebb0ee Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Thu, 18 Jun 2020 22:34:03 +0300 Subject: [PATCH 0052/1168] Migration multiSelect to ES6 modules --- package.json | 1 + src/components/multiSelect/multiSelect.js | 168 +++++++++--------- .../emby-itemscontainer.js | 2 +- 3 files changed, 90 insertions(+), 81 deletions(-) diff --git a/package.json b/package.json index 29aa2f82a..632030879 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", + "src/components/multiSelect/multiSelect.js", "src/components/playback/brightnessosd.js", "src/components/playback/mediasession.js", "src/components/playback/nowplayinghelper.js", diff --git a/src/components/multiSelect/multiSelect.js b/src/components/multiSelect/multiSelect.js index 83982413a..5c8a378b4 100644 --- a/src/components/multiSelect/multiSelect.js +++ b/src/components/multiSelect/multiSelect.js @@ -1,13 +1,20 @@ -define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'globalize', 'appRouter', 'dom', 'css!./multiSelect'], function (browser, appStorage, appHost, loading, connectionManager, globalize, appRouter, dom) { - 'use strict'; +import browser from 'browser'; +import appHost from 'apphost'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; +import globalize from 'globalize'; +import dom from 'dom'; +import 'css!./multiSelect'; - var selectedItems = []; - var selectedElements = []; - var currentSelectionCommandsPanel; +/* eslint-disable indent */ + + let selectedItems = []; + let selectedElements = []; + let currentSelectionCommandsPanel; function hideSelections() { - var selectionCommandsPanel = currentSelectionCommandsPanel; + const selectionCommandsPanel = currentSelectionCommandsPanel; if (selectionCommandsPanel) { selectionCommandsPanel.parentNode.removeChild(selectionCommandsPanel); @@ -15,10 +22,10 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo selectedItems = []; selectedElements = []; - var elems = document.querySelectorAll('.itemSelectionPanel'); - for (var i = 0, length = elems.length; i < length; i++) { + const elems = document.querySelectorAll('.itemSelectionPanel'); + for (let i = 0, length = elems.length; i < length; i++) { - var parent = elems[i].parentNode; + const parent = elems[i].parentNode; parent.removeChild(elems[i]); parent.classList.remove('withMultiSelect'); } @@ -29,14 +36,14 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo // toggle the checkbox, if it wasn't clicked on if (!dom.parentWithClass(e.target, 'chkItemSelect')) { - var chkItemSelect = itemSelectionPanel.querySelector('.chkItemSelect'); + const chkItemSelect = itemSelectionPanel.querySelector('.chkItemSelect'); if (chkItemSelect) { if (chkItemSelect.classList.contains('checkedInitial')) { chkItemSelect.classList.remove('checkedInitial'); } else { - var newValue = !chkItemSelect.checked; + const newValue = !chkItemSelect.checked; chkItemSelect.checked = newValue; updateItemSelection(chkItemSelect, newValue); } @@ -50,11 +57,11 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo function updateItemSelection(chkItemSelect, selected) { - var id = dom.parentWithAttribute(chkItemSelect, 'data-id').getAttribute('data-id'); + const id = dom.parentWithAttribute(chkItemSelect, 'data-id').getAttribute('data-id'); if (selected) { - var current = selectedItems.filter(function (i) { + const current = selectedItems.filter(i => { return i === id; }); @@ -64,16 +71,16 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo } } else { - selectedItems = selectedItems.filter(function (i) { + selectedItems = selectedItems.filter(i => { return i !== id; }); - selectedElements = selectedElements.filter(function (i) { + selectedElements = selectedElements.filter(i => { return i !== chkItemSelect; }); } if (selectedItems.length) { - var itemSelectionCount = document.querySelector('.itemSelectionCount'); + const itemSelectionCount = document.querySelector('.itemSelectionCount'); if (itemSelectionCount) { itemSelectionCount.innerHTML = selectedItems.length; } @@ -88,33 +95,33 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo function showSelection(item, isChecked) { - var itemSelectionPanel = item.querySelector('.itemSelectionPanel'); + let itemSelectionPanel = item.querySelector('.itemSelectionPanel'); if (!itemSelectionPanel) { itemSelectionPanel = document.createElement('div'); itemSelectionPanel.classList.add('itemSelectionPanel'); - var parent = item.querySelector('.cardBox') || item.querySelector('.cardContent'); + const parent = item.querySelector('.cardBox') || item.querySelector('.cardContent'); parent.classList.add('withMultiSelect'); parent.appendChild(itemSelectionPanel); - var cssClass = 'chkItemSelect'; + let cssClass = 'chkItemSelect'; if (isChecked && !browser.firefox) { // In firefox, the initial tap hold doesnt' get treated as a click // In other browsers it does, so we need to make sure that initial click is ignored cssClass += ' checkedInitial'; } - var checkedAttribute = isChecked ? ' checked' : ''; - itemSelectionPanel.innerHTML = ''; - var chkItemSelect = itemSelectionPanel.querySelector('.chkItemSelect'); + const checkedAttribute = isChecked ? ' checked' : ''; + itemSelectionPanel.innerHTML = ``; + const chkItemSelect = itemSelectionPanel.querySelector('.chkItemSelect'); chkItemSelect.addEventListener('change', onSelectionChange); } } function showSelectionCommands() { - var selectionCommandsPanel = currentSelectionCommandsPanel; + let selectionCommandsPanel = currentSelectionCommandsPanel; if (!selectionCommandsPanel) { @@ -124,19 +131,19 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo document.body.appendChild(selectionCommandsPanel); currentSelectionCommandsPanel = selectionCommandsPanel; - var html = ''; + let html = ''; html += ''; html += '

'; const moreIcon = 'more_vert'; - html += ''; + html += ``; selectionCommandsPanel.innerHTML = html; selectionCommandsPanel.querySelector('.btnCloseSelectionPanel').addEventListener('click', hideSelections); - var btnSelectionPanelOptions = selectionCommandsPanel.querySelector('.btnSelectionPanelOptions'); + const btnSelectionPanelOptions = selectionCommandsPanel.querySelector('.btnSelectionPanelOptions'); dom.addEventListener(btnSelectionPanelOptions, 'click', showMenuForSelectedItems, { passive: true }); } @@ -144,9 +151,9 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo function alertText(options) { - return new Promise(function (resolve, reject) { + return new Promise((resolve, reject) => { - require(['alert'], function (alert) { + import('alert').then(({default: alert}) => { alert(options).then(resolve, resolve); }); }); @@ -154,24 +161,24 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo function deleteItems(apiClient, itemIds) { - return new Promise(function (resolve, reject) { + return new Promise((resolve, reject) => { - var msg = globalize.translate('ConfirmDeleteItem'); - var title = globalize.translate('HeaderDeleteItem'); + let msg = globalize.translate('ConfirmDeleteItem'); + let title = globalize.translate('HeaderDeleteItem'); if (itemIds.length > 1) { msg = globalize.translate('ConfirmDeleteItems'); title = globalize.translate('HeaderDeleteItems'); } - require(['confirm'], function (confirm) { + import('confirm').then(({default: confirm}) => { - confirm(msg, title).then(function () { - var promises = itemIds.map(function (itemId) { + confirm(msg, title).then(() => { + const promises = itemIds.map(itemId => { apiClient.deleteItem(itemId); }); - Promise.all(promises).then(resolve, function () { + Promise.all(promises).then(resolve, () => { alertText(globalize.translate('ErrorDeletingItem')).then(reject, reject); }); @@ -183,11 +190,11 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo function showMenuForSelectedItems(e) { - var apiClient = connectionManager.currentApiClient(); + const apiClient = connectionManager.currentApiClient(); - apiClient.getCurrentUser().then(function (user) { + apiClient.getCurrentUser().then(user => { - var menuItems = []; + const menuItems = []; menuItems.push({ name: globalize.translate('AddToCollection'), @@ -244,17 +251,17 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo icon: 'refresh' }); - require(['actionsheet'], function (actionsheet) { + import('actionsheet').then(({default: actionsheet}) => { actionsheet.show({ items: menuItems, positionTo: e.target, callback: function (id) { - var items = selectedItems.slice(0); - var serverId = apiClient.serverInfo().Id; + const items = selectedItems.slice(0); + const serverId = apiClient.serverInfo().Id; switch (id) { case 'addtocollection': - require(['collectionEditor'], function (collectionEditor) { + import('collectionEditor').then(({default: collectionEditor}) => { new collectionEditor().show({ items: items, serverId: serverId @@ -264,7 +271,7 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo dispatchNeedsRefresh(); break; case 'playlist': - require(['playlistEditor'], function (playlistEditor) { + import('playlistEditor').then(({default: playlistEditor}) => { new playlistEditor().show({ items: items, serverId: serverId @@ -282,21 +289,21 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo combineVersions(apiClient, items); break; case 'markplayed': - items.forEach(function (itemId) { + items.forEach(itemId => { apiClient.markPlayed(apiClient.getCurrentUserId(), itemId); }); hideSelections(); dispatchNeedsRefresh(); break; case 'markunplayed': - items.forEach(function (itemId) { + items.forEach(itemId => { apiClient.markUnplayed(apiClient.getCurrentUserId(), itemId); }); hideSelections(); dispatchNeedsRefresh(); break; case 'refresh': - require(['refreshDialog'], function (refreshDialog) { + import('refreshDialog').then(({default: refreshDialog}) => { new refreshDialog({ itemIds: items, serverId: serverId @@ -317,18 +324,18 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo function dispatchNeedsRefresh() { - var elems = []; + const elems = []; - [].forEach.call(selectedElements, function (i) { + [].forEach.call(selectedElements, i => { - var container = dom.parentWithAttribute(i, 'is', 'emby-itemscontainer'); + const container = dom.parentWithAttribute(i, 'is', 'emby-itemscontainer'); - if (container && elems.indexOf(container) === -1) { + if (container && !elems.includes(container)) { elems.push(container); } }); - for (var i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].notifyRefreshNeeded(true); } } @@ -337,7 +344,7 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo if (selection.length < 2) { - require(['alert'], function (alert) { + import('alert').then(({default: alert}) => { alert({ text: globalize.translate('PleaseSelectTwoItems') }); @@ -352,7 +359,7 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo type: 'POST', url: apiClient.getUrl('Videos/MergeVersions', { Ids: selection.join(',') }) - }).then(function () { + }).then(() => { loading.hide(); hideSelections(); @@ -362,9 +369,9 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo function showSelections(initialCard) { - require(['emby-checkbox'], function () { - var cards = document.querySelectorAll('.card'); - for (var i = 0, length = cards.length; i < length; i++) { + import('emby-checkbox').then(() => { + const cards = document.querySelectorAll('.card'); + for (let i = 0, length = cards.length; i < length; i++) { showSelection(cards[i], initialCard === cards[i]); } @@ -375,13 +382,13 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo function onContainerClick(e) { - var target = e.target; + const target = e.target; if (selectedItems.length) { - var card = dom.parentWithClass(target, 'card'); + const card = dom.parentWithClass(target, 'card'); if (card) { - var itemSelectionPanel = card.querySelector('.itemSelectionPanel'); + const itemSelectionPanel = card.querySelector('.itemSelectionPanel'); if (itemSelectionPanel) { return onItemSelectionPanelClick(e, itemSelectionPanel); } @@ -395,15 +402,15 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo document.addEventListener('viewbeforehide', hideSelections); - return function (options) { + export default function (options) { - var self = this; + const self = this; - var container = options.container; + const container = options.container; function onTapHold(e) { - var card = dom.parentWithClass(e.target, 'card'); + const card = dom.parentWithClass(e.target, 'card'); if (card) { @@ -423,13 +430,13 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo return e.changedTouches || e.targetTouches || e.touches; } - var touchTarget; - var touchStartTimeout; - var touchStartX; - var touchStartY; + let touchTarget; + let touchStartTimeout; + let touchStartX; + let touchStartY; function onTouchStart(e) { - var touch = getTouches(e)[0]; + const touch = getTouches(e)[0]; touchTarget = null; touchStartX = 0; touchStartY = 0; @@ -437,10 +444,10 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo if (touch) { touchStartX = touch.clientX; touchStartY = touch.clientY; - var element = touch.target; + const element = touch.target; if (element) { - var card = dom.parentWithClass(element, 'card'); + const card = dom.parentWithClass(element, 'card'); if (card) { @@ -459,13 +466,13 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo function onTouchMove(e) { if (touchTarget) { - var touch = getTouches(e)[0]; - var deltaX; - var deltaY; + const touch = getTouches(e)[0]; + let deltaX; + let deltaY; if (touch) { - var touchEndX = touch.clientX || 0; - var touchEndY = touch.clientY || 0; + const touchEndX = touch.clientX || 0; + const touchEndY = touch.clientY || 0; deltaX = Math.abs(touchEndX - (touchStartX || 0)); deltaY = Math.abs(touchEndY - (touchStartY || 0)); } else { @@ -509,7 +516,7 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo return; } - var card = dom.parentWithClass(touchTarget, 'card'); + const card = dom.parentWithClass(touchTarget, 'card'); touchTarget = null; if (card) { @@ -556,12 +563,12 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo self.onContainerClick = onContainerClick; - self.destroy = function () { + self.destroy = () => { container.removeEventListener('click', onContainerClick); container.removeEventListener('contextmenu', onTapHold); - var element = container; + const element = container; dom.removeEventListener(element, 'touchstart', onTouchStart, { passive: true @@ -586,5 +593,6 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo passive: true }); }; - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/elements/emby-itemscontainer/emby-itemscontainer.js b/src/elements/emby-itemscontainer/emby-itemscontainer.js index 5d3772ca9..593e50794 100644 --- a/src/elements/emby-itemscontainer/emby-itemscontainer.js +++ b/src/elements/emby-itemscontainer/emby-itemscontainer.js @@ -63,7 +63,7 @@ define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager', var self = this; require(['multiSelect'], function (MultiSelect) { - self.multiSelect = new MultiSelect({ + self.multiSelect = new MultiSelect.default({ container: self, bindOnClick: false }); From 1b581077f23892635cfe3c78d0d0891dd261b14e Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Thu, 18 Jun 2020 22:41:43 +0300 Subject: [PATCH 0053/1168] Migration confirm to ES6 modules --- package.json | 1 + src/components/confirm/confirm.js | 25 +++++++++++-------- src/components/imageeditor/imageeditor.js | 2 +- .../recordingcreator/recordinghelper.js | 4 +-- .../subtitleeditor/subtitleeditor.js | 2 +- src/controllers/dashboard/apikeys.js | 2 +- src/controllers/dashboard/dashboard.js | 4 +-- src/controllers/dashboard/devices/devices.js | 2 +- src/controllers/dashboard/dlna/profiles.js | 2 +- src/controllers/dashboard/mediaLibrary.js | 2 +- src/controllers/dashboard/plugins/add.js | 2 +- .../dashboard/plugins/installed.js | 2 +- .../dashboard/scheduledtasks/scheduledtask.js | 2 +- .../dashboard/users/userpasswordpage.js | 4 +-- .../dashboard/users/userprofilespage.js | 2 +- src/controllers/itemDetails.js | 2 +- src/controllers/livetvstatus.js | 4 +-- src/controllers/user/profile.js | 2 +- 18 files changed, 36 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 632030879..b3b529849 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "src/components/cardbuilder/cardBuilder.js", "src/components/cardbuilder/chaptercardbuilder.js", "src/components/cardbuilder/peoplecardbuilder.js", + "src/components/confirm/confirm.js", "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", diff --git a/src/components/confirm/confirm.js b/src/components/confirm/confirm.js index 517d6fa9b..2d5cfdb55 100644 --- a/src/components/confirm/confirm.js +++ b/src/components/confirm/confirm.js @@ -1,5 +1,9 @@ -define(['browser', 'dialog', 'globalize'], function(browser, dialog, globalize) { - 'use strict'; +import browser from 'browser'; +import dialog from 'dialog'; +import globalize from 'globalize'; + +/* eslint-disable indent */ +export default (() => { function replaceAll(str, find, replace) { return str.split(find).join(replace); @@ -7,7 +11,7 @@ define(['browser', 'dialog', 'globalize'], function(browser, dialog, globalize) if (browser.tv && window.confirm) { // Use the native confirm dialog - return function (options) { + return options => { if (typeof options === 'string') { options = { title: '', @@ -15,8 +19,8 @@ define(['browser', 'dialog', 'globalize'], function(browser, dialog, globalize) }; } - var text = replaceAll(options.text || '', '
', '\n'); - var result = confirm(text); + const text = replaceAll(options.text || '', '
', '\n'); + const result = confirm(text); if (result) { return Promise.resolve(); @@ -26,8 +30,8 @@ define(['browser', 'dialog', 'globalize'], function(browser, dialog, globalize) }; } else { // Use our own dialog - return function (text, title) { - var options; + return (text, title) => { + let options; if (typeof text === 'string') { options = { title: title, @@ -37,7 +41,7 @@ define(['browser', 'dialog', 'globalize'], function(browser, dialog, globalize) options = text; } - var items = []; + const items = []; items.push({ name: options.cancelText || globalize.translate('ButtonCancel'), @@ -53,7 +57,7 @@ define(['browser', 'dialog', 'globalize'], function(browser, dialog, globalize) options.buttons = items; - return dialog(options).then(function (result) { + return dialog.show(options).then(result => { if (result === 'ok') { return Promise.resolve(); } @@ -62,4 +66,5 @@ define(['browser', 'dialog', 'globalize'], function(browser, dialog, globalize) }); }; } -}); +})(); +/* eslint-enable indent */ diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index 2927a0b12..93495eec0 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -200,7 +200,7 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', require(['confirm'], function (confirm) { - confirm({ + confirm.default({ text: globalize.translate('ConfirmDeleteImage'), confirmText: globalize.translate('Delete'), diff --git a/src/components/recordingcreator/recordinghelper.js b/src/components/recordingcreator/recordinghelper.js index a071cb203..c773368f2 100644 --- a/src/components/recordingcreator/recordinghelper.js +++ b/src/components/recordingcreator/recordinghelper.js @@ -34,7 +34,7 @@ define(['globalize', 'loading', 'connectionManager'], function (globalize, loadi require(['confirm'], function (confirm) { - confirm({ + confirm.default({ text: globalize.translate('MessageConfirmRecordingCancellation'), primary: 'delete', @@ -59,7 +59,7 @@ define(['globalize', 'loading', 'connectionManager'], function (globalize, loadi require(['confirm'], function (confirm) { - confirm({ + confirm.default({ text: globalize.translate('MessageConfirmRecordingCancellation'), primary: 'delete', diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js index e9bcc0bfc..b356c4f07 100644 --- a/src/components/subtitleeditor/subtitleeditor.js +++ b/src/components/subtitleeditor/subtitleeditor.js @@ -69,7 +69,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', require(['confirm'], function (confirm) { - confirm({ + confirm.default({ title: globalize.translate('ConfirmDeletion'), text: msg, diff --git a/src/controllers/dashboard/apikeys.js b/src/controllers/dashboard/apikeys.js index f43bfd032..dc17d43c5 100644 --- a/src/controllers/dashboard/apikeys.js +++ b/src/controllers/dashboard/apikeys.js @@ -3,7 +3,7 @@ define(['datetime', 'loading', 'libraryMenu', 'dom', 'globalize', 'emby-button'] function revoke(page, key) { require(['confirm'], function (confirm) { - confirm(globalize.translate('MessageConfirmRevokeApiKey'), globalize.translate('HeaderConfirmRevokeApiKey')).then(function () { + confirm.default(globalize.translate('MessageConfirmRevokeApiKey'), globalize.translate('HeaderConfirmRevokeApiKey')).then(function () { loading.show(); ApiClient.ajax({ type: 'DELETE', diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index 1bae9a0b3..dcd56921e 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -708,7 +708,7 @@ define(['datetime', 'events', 'itemHelper', 'serverNotifications', 'dom', 'globa }, restart: function (btn) { require(['confirm'], function (confirm) { - confirm({ + confirm.default({ title: globalize.translate('HeaderRestart'), text: globalize.translate('MessageConfirmRestart'), confirmText: globalize.translate('ButtonRestart'), @@ -723,7 +723,7 @@ define(['datetime', 'events', 'itemHelper', 'serverNotifications', 'dom', 'globa }, shutdown: function (btn) { require(['confirm'], function (confirm) { - confirm({ + confirm.default({ title: globalize.translate('HeaderShutdown'), text: globalize.translate('MessageConfirmShutdown'), confirmText: globalize.translate('ButtonShutdown'), diff --git a/src/controllers/dashboard/devices/devices.js b/src/controllers/dashboard/devices/devices.js index 0dea81c75..d20132db8 100644 --- a/src/controllers/dashboard/devices/devices.js +++ b/src/controllers/dashboard/devices/devices.js @@ -9,7 +9,7 @@ define(['loading', 'dom', 'libraryMenu', 'globalize', 'scripts/imagehelper', 'da var msg = globalize.translate('DeleteDeviceConfirmation'); require(['confirm'], function (confirm) { - confirm({ + confirm.default({ text: msg, title: globalize.translate('HeaderDeleteDevice'), confirmText: globalize.translate('ButtonDelete'), diff --git a/src/controllers/dashboard/dlna/profiles.js b/src/controllers/dashboard/dlna/profiles.js index fb4caadeb..a6eccd233 100644 --- a/src/controllers/dashboard/dlna/profiles.js +++ b/src/controllers/dashboard/dlna/profiles.js @@ -59,7 +59,7 @@ define(['jQuery', 'globalize', 'loading', 'libraryMenu', 'listViewStyle', 'emby- function deleteProfile(page, id) { require(['confirm'], function (confirm) { - confirm(globalize.translate('MessageConfirmProfileDeletion'), globalize.translate('HeaderConfirmProfileDeletion')).then(function () { + confirm.default(globalize.translate('MessageConfirmProfileDeletion'), globalize.translate('HeaderConfirmProfileDeletion')).then(function () { loading.show(); ApiClient.ajax({ type: 'DELETE', diff --git a/src/controllers/dashboard/mediaLibrary.js b/src/controllers/dashboard/mediaLibrary.js index 06eba37cb..2d0d45438 100644 --- a/src/controllers/dashboard/mediaLibrary.js +++ b/src/controllers/dashboard/mediaLibrary.js @@ -38,7 +38,7 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl } require(['confirm'], function (confirm) { - confirm({ + confirm.default({ text: msg, title: globalize.translate('HeaderRemoveMediaFolder'), diff --git a/src/controllers/dashboard/plugins/add.js b/src/controllers/dashboard/plugins/add.js index 8b1deb804..375a0c0ec 100644 --- a/src/controllers/dashboard/plugins/add.js +++ b/src/controllers/dashboard/plugins/add.js @@ -91,7 +91,7 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'e msg += globalize.translate('PleaseConfirmPluginInstallation'); require(['confirm'], function (confirm) { - confirm(msg, globalize.translate('HeaderConfirmPluginInstallation')).then(function () { + confirm.default(msg, globalize.translate('HeaderConfirmPluginInstallation')).then(function () { alertCallback(); }, function () { console.debug('plugin not installed'); diff --git a/src/controllers/dashboard/plugins/installed.js b/src/controllers/dashboard/plugins/installed.js index 87e9428cc..7a8110f8b 100644 --- a/src/controllers/dashboard/plugins/installed.js +++ b/src/controllers/dashboard/plugins/installed.js @@ -5,7 +5,7 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button' var msg = globalize.translate('UninstallPluginConfirmation', name); require(['confirm'], function (confirm) { - confirm({ + confirm.default({ title: globalize.translate('UninstallPluginHeader'), text: msg, primary: 'delete', diff --git a/src/controllers/dashboard/scheduledtasks/scheduledtask.js b/src/controllers/dashboard/scheduledtasks/scheduledtask.js index 52050d1f8..b632d176f 100644 --- a/src/controllers/dashboard/scheduledtasks/scheduledtask.js +++ b/src/controllers/dashboard/scheduledtasks/scheduledtask.js @@ -130,7 +130,7 @@ define(['jQuery', 'loading', 'datetime', 'dom', 'globalize', 'emby-input', 'emby }, confirmDeleteTrigger: function (view, index) { require(['confirm'], function (confirm) { - confirm(globalize.translate('MessageDeleteTaskTrigger'), globalize.translate('HeaderDeleteTaskTrigger')).then(function () { + confirm.default(globalize.translate('MessageDeleteTaskTrigger'), globalize.translate('HeaderDeleteTaskTrigger')).then(function () { ScheduledTaskPage.deleteTrigger(view, index); }); }); diff --git a/src/controllers/dashboard/users/userpasswordpage.js b/src/controllers/dashboard/users/userpasswordpage.js index 186e39b15..9061c00c7 100644 --- a/src/controllers/dashboard/users/userpasswordpage.js +++ b/src/controllers/dashboard/users/userpasswordpage.js @@ -142,7 +142,7 @@ define(['loading', 'libraryMenu', 'globalize', 'emby-button'], function (loading var msg = globalize.translate('PasswordResetConfirmation'); require(['confirm'], function (confirm) { - confirm(msg, globalize.translate('PasswordResetHeader')).then(function () { + confirm.default(msg, globalize.translate('PasswordResetHeader')).then(function () { var userId = params.userId; loading.show(); ApiClient.resetUserPassword(userId).then(function () { @@ -161,7 +161,7 @@ define(['loading', 'libraryMenu', 'globalize', 'emby-button'], function (loading var msg = globalize.translate('PinCodeResetConfirmation'); require(['confirm'], function (confirm) { - confirm(msg, globalize.translate('HeaderPinCodeReset')).then(function () { + confirm.default(msg, globalize.translate('HeaderPinCodeReset')).then(function () { var userId = params.userId; loading.show(); ApiClient.resetEasyPassword(userId).then(function () { diff --git a/src/controllers/dashboard/users/userprofilespage.js b/src/controllers/dashboard/users/userprofilespage.js index c691c665f..f04c7ad08 100644 --- a/src/controllers/dashboard/users/userprofilespage.js +++ b/src/controllers/dashboard/users/userprofilespage.js @@ -5,7 +5,7 @@ define(['loading', 'dom', 'globalize', 'date-fns', 'dfnshelper', 'paper-icon-but var msg = globalize.translate('DeleteUserConfirmation'); require(['confirm'], function (confirm) { - confirm({ + confirm.default({ title: globalize.translate('DeleteUser'), text: msg, confirmText: globalize.translate('ButtonDelete'), diff --git a/src/controllers/itemDetails.js b/src/controllers/itemDetails.js index 67aa5f940..aa131999a 100644 --- a/src/controllers/itemDetails.js +++ b/src/controllers/itemDetails.js @@ -1936,7 +1936,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti function splitVersions(instance, page, apiClient, params) { require(['confirm'], function (confirm) { - confirm('Are you sure you wish to split the media sources into separate items?', 'Split Media Apart').then(function () { + confirm.default('Are you sure you wish to split the media sources into separate items?', 'Split Media Apart').then(function () { loading.show(); apiClient.ajax({ type: 'DELETE', diff --git a/src/controllers/livetvstatus.js b/src/controllers/livetvstatus.js index 82d0b697d..b070098b9 100644 --- a/src/controllers/livetvstatus.js +++ b/src/controllers/livetvstatus.js @@ -49,7 +49,7 @@ define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layo var message = globalize.translate('MessageConfirmDeleteTunerDevice'); require(['confirm'], function (confirm) { - confirm(message, globalize.translate('HeaderDeleteDevice')).then(function () { + confirm.default(message, globalize.translate('HeaderDeleteDevice')).then(function () { loading.show(); ApiClient.ajax({ type: 'DELETE', @@ -167,7 +167,7 @@ define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layo var message = globalize.translate('MessageConfirmDeleteGuideProvider'); require(['confirm'], function (confirm) { - confirm(message, globalize.translate('HeaderDeleteProvider')).then(function () { + confirm.default(message, globalize.translate('HeaderDeleteProvider')).then(function () { loading.show(); ApiClient.ajax({ type: 'DELETE', diff --git a/src/controllers/user/profile.js b/src/controllers/user/profile.js index fd7d1e32c..8e2977180 100644 --- a/src/controllers/user/profile.js +++ b/src/controllers/user/profile.js @@ -86,7 +86,7 @@ define(['controllers/dashboard/users/userpasswordpage', 'loading', 'libraryMenu' new UserPasswordPage(view, params); view.querySelector('#btnDeleteImage').addEventListener('click', function () { require(['confirm'], function (confirm) { - confirm(globalize.translate('DeleteImageConfirmation'), globalize.translate('DeleteImage')).then(function () { + confirm.default(globalize.translate('DeleteImageConfirmation'), globalize.translate('DeleteImage')).then(function () { loading.show(); var userId = getParameterByName('userId'); ApiClient.deleteUserImage(userId, 'primary').then(function () { From 30cd42ae7cdd084ab73e87ee3d7dbbf3b46994ff Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Thu, 18 Jun 2020 22:43:30 +0300 Subject: [PATCH 0054/1168] Migration prompt to ES6 modules --- package.json | 1 + .../metadataEditor/metadataEditor.js | 2 +- src/components/prompt/prompt.js | 49 ++++++++++++------- src/controllers/dashboard/apikeys.js | 2 +- src/controllers/dashboard/dashboard.js | 2 +- src/controllers/dashboard/mediaLibrary.js | 2 +- .../dashboard/users/userparentalcontrol.js | 2 +- 7 files changed, 37 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index b3b529849..a88fa394b 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,7 @@ "src/components/playback/playmethodhelper.js", "src/components/playback/remotecontrolautoplay.js", "src/components/playback/volumeosd.js", + "src/components/prompt/prompt.js", "src/components/playmenu.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", diff --git a/src/components/metadataEditor/metadataEditor.js b/src/components/metadataEditor/metadataEditor.js index 52f030cd2..2f7bfc951 100644 --- a/src/components/metadataEditor/metadataEditor.js +++ b/src/components/metadataEditor/metadataEditor.js @@ -212,7 +212,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function addElementToList(source, sortCallback) { require(['prompt'], function (prompt) { - prompt({ + prompt.default({ label: 'Value:' }).then(function (text) { var list = dom.parentWithClass(source, 'editableListviewContainer').querySelector('.paperList'); diff --git a/src/components/prompt/prompt.js b/src/components/prompt/prompt.js index a76083cf0..f3bf72f8f 100644 --- a/src/components/prompt/prompt.js +++ b/src/components/prompt/prompt.js @@ -1,12 +1,24 @@ -define(['browser', 'dialogHelper', 'layoutManager', 'scrollHelper', 'globalize', 'dom', 'require', 'material-icons', 'emby-button', 'paper-icon-button-light', 'emby-input', 'formDialogStyle'], function(browser, dialogHelper, layoutManager, scrollHelper, globalize, dom, require) { - 'use strict'; +import browser from 'browser'; +import dialogHelper from 'dialogHelper'; +import layoutManager from 'layoutManager'; +import scrollHelper from 'scrollHelper'; +import globalize from 'globalize'; +import dom from 'dom'; +import 'material-icons'; +import 'emby-button'; +import 'paper-icon-button-light'; +import 'emby-input'; +import 'formDialogStyle'; + +/* eslint-disable indent */ +export default (() => { function replaceAll(str, find, replace) { return str.split(find).join(replace); } function setInputProperties(dlg, options) { - var txtInput = dlg.querySelector('#txtInput'); + const txtInput = dlg.querySelector('#txtInput'); if (txtInput.label) { txtInput.label(options.label || ''); @@ -17,7 +29,7 @@ define(['browser', 'dialogHelper', 'layoutManager', 'scrollHelper', 'globalize', } function showDialog(options, template) { - var dialogOptions = { + const dialogOptions = { removeOnClose: true, scrollY: false }; @@ -26,7 +38,7 @@ define(['browser', 'dialogHelper', 'layoutManager', 'scrollHelper', 'globalize', dialogOptions.size = 'fullscreen'; } - var dlg = dialogHelper.createDialog(dialogOptions); + const dlg = dialogHelper.createDialog(dialogOptions); dlg.classList.add('formDialog'); @@ -39,7 +51,7 @@ define(['browser', 'dialogHelper', 'layoutManager', 'scrollHelper', 'globalize', dlg.classList.add('dialog-fullscreen-lowres'); } - dlg.querySelector('.btnCancel').addEventListener('click', function (e) { + dlg.querySelector('.btnCancel').addEventListener('click', () => { dialogHelper.close(dlg); }); @@ -53,16 +65,16 @@ define(['browser', 'dialogHelper', 'layoutManager', 'scrollHelper', 'globalize', setInputProperties(dlg, options); - var submitValue; + let submitValue; - dlg.querySelector('form').addEventListener('submit', function (e) { + dlg.querySelector('form').addEventListener('submit', e => { submitValue = dlg.querySelector('#txtInput').value; e.preventDefault(); e.stopPropagation(); // Important, don't close the dialog until after the form has completed submitting, or it will cause an error in Chrome - setTimeout(function () { + setTimeout(() => { dialogHelper.close(dlg); }, 300); @@ -71,9 +83,9 @@ define(['browser', 'dialogHelper', 'layoutManager', 'scrollHelper', 'globalize', dlg.querySelector('.submitText').innerHTML = options.confirmText || globalize.translate('ButtonOk'); - dlg.style.minWidth = (Math.min(400, dom.getWindowSize().innerWidth - 50)) + 'px'; + dlg.style.minWidth = `${Math.min(400, dom.getWindowSize().innerWidth - 50)}px`; - return dialogHelper.open(dlg).then(function () { + return dialogHelper.open(dlg).then(() => { if (layoutManager.tv) { scrollHelper.centerFocus.off(dlg.querySelector('.formDialogContent'), false); } @@ -87,7 +99,7 @@ define(['browser', 'dialogHelper', 'layoutManager', 'scrollHelper', 'globalize', } if ((browser.tv || browser.xboxOne) && window.confirm) { - return function (options) { + return options => { if (typeof options === 'string') { options = { label: '', @@ -95,8 +107,8 @@ define(['browser', 'dialogHelper', 'layoutManager', 'scrollHelper', 'globalize', }; } - var label = replaceAll(options.label || '', '
', '\n'); - var result = prompt(label, options.text || ''); + const label = replaceAll(options.label || '', '
', '\n'); + const result = prompt(label, options.text || ''); if (result) { return Promise.resolve(result); @@ -105,9 +117,9 @@ define(['browser', 'dialogHelper', 'layoutManager', 'scrollHelper', 'globalize', } }; } else { - return function (options) { - return new Promise(function (resolve, reject) { - require(['text!./prompt.template.html'], function (template) { + return options => { + return new Promise((resolve, reject) => { + import('text!./prompt.template.html').then(({default: template}) => { if (typeof options === 'string') { options = { title: '', @@ -119,4 +131,5 @@ define(['browser', 'dialogHelper', 'layoutManager', 'scrollHelper', 'globalize', }); }; } -}); +})(); +/* eslint-enable indent */ diff --git a/src/controllers/dashboard/apikeys.js b/src/controllers/dashboard/apikeys.js index dc17d43c5..d3e824ed5 100644 --- a/src/controllers/dashboard/apikeys.js +++ b/src/controllers/dashboard/apikeys.js @@ -47,7 +47,7 @@ define(['datetime', 'loading', 'libraryMenu', 'dom', 'globalize', 'emby-button'] function showNewKeyPrompt(page) { require(['prompt'], function (prompt) { - prompt({ + prompt.default({ title: globalize.translate('HeaderNewApiKey'), label: globalize.translate('LabelAppName'), description: globalize.translate('LabelAppNameExample') diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index dcd56921e..116c8574f 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -34,7 +34,7 @@ define(['datetime', 'events', 'itemHelper', 'serverNotifications', 'dom', 'globa function showSendMessageForm(btn, session) { require(['prompt'], function (prompt) { - prompt({ + prompt.default({ title: globalize.translate('HeaderSendMessage'), label: globalize.translate('LabelMessageText'), confirmText: globalize.translate('ButtonSend') diff --git a/src/controllers/dashboard/mediaLibrary.js b/src/controllers/dashboard/mediaLibrary.js index 2d0d45438..bfa4ab1b3 100644 --- a/src/controllers/dashboard/mediaLibrary.js +++ b/src/controllers/dashboard/mediaLibrary.js @@ -66,7 +66,7 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl function renameVirtualFolder(page, virtualFolder) { require(['prompt'], function (prompt) { - prompt({ + prompt.default({ label: globalize.translate('LabelNewName'), confirmText: globalize.translate('ButtonRename') }).then(function (newName) { diff --git a/src/controllers/dashboard/users/userparentalcontrol.js b/src/controllers/dashboard/users/userparentalcontrol.js index e8255512d..f5d4e70af 100644 --- a/src/controllers/dashboard/users/userparentalcontrol.js +++ b/src/controllers/dashboard/users/userparentalcontrol.js @@ -225,7 +225,7 @@ define(['jQuery', 'datetime', 'loading', 'libraryMenu', 'globalize', 'listViewSt function showBlockedTagPopup(page) { require(['prompt'], function (prompt) { - prompt({ + prompt.default({ label: globalize.translate('LabelTag') }).then(function (value) { var tags = getBlockedTagsFromPage(page); From 4e6792309d953cca4938abbcad092adfc26fd93d Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Thu, 18 Jun 2020 22:45:35 +0300 Subject: [PATCH 0055/1168] Fix context Event Listener (cherry picked from commit 27d1c21089a0996c9e53c49f2b10e98636467a5f) --- src/components/metadataEditor/metadataEditor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/metadataEditor/metadataEditor.js b/src/components/metadataEditor/metadataEditor.js index 2f7bfc951..eb387828f 100644 --- a/src/components/metadataEditor/metadataEditor.js +++ b/src/components/metadataEditor/metadataEditor.js @@ -308,8 +308,8 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi } }); - context.removeEventListener('submit', onEditorClick); - context.addEventListener('submit', onEditorClick); + context.removeEventListener('click', onEditorClick); + context.addEventListener('click', onEditorClick); var form = context.querySelector('form'); form.removeEventListener('submit', onSubmit); From 88d7f52ce74072ac5eac5cfac4d9bb64bb0bd4a4 Mon Sep 17 00:00:00 2001 From: ferferga Date: Fri, 19 Jun 2020 00:07:58 +0200 Subject: [PATCH 0056/1168] Remove repeated rule --- src/assets/css/librarybrowser.css | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/assets/css/librarybrowser.css b/src/assets/css/librarybrowser.css index ddcf9acc0..4ed8e272f 100644 --- a/src/assets/css/librarybrowser.css +++ b/src/assets/css/librarybrowser.css @@ -821,20 +821,6 @@ div.itemDetailGalleryLink.defaultCardBackground { } @media all and (min-width: 100em) { - .headerTop { - padding-left: 0.8em; - padding-right: 0.8em; - } - - .headerTabs { - align-self: center; - width: auto; - align-items: center; - justify-content: center; - margin-top: -4.2em; - position: relative; - } - .detailFloatingButton { display: none !important; } From 58205e11bbecc1a0d1b5cd06faaf98584c09f9ce Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Fri, 19 Jun 2020 18:56:12 +0300 Subject: [PATCH 0057/1168] Migration directorybrowser to ES6 modules --- package.json | 1 + .../directorybrowser/directorybrowser.js | 214 +++++++++--------- src/components/tvproviders/xmltv.js | 2 +- src/controllers/dashboard/encodingsettings.js | 4 +- src/controllers/dashboard/general.js | 4 +- src/controllers/dashboard/networking.js | 2 +- src/controllers/livetvsettings.js | 8 +- src/controllers/livetvtuner.js | 2 +- 8 files changed, 125 insertions(+), 112 deletions(-) diff --git a/package.json b/package.json index 29aa2f82a..675e7a6b3 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "src/components/cardbuilder/cardBuilder.js", "src/components/cardbuilder/chaptercardbuilder.js", "src/components/cardbuilder/peoplecardbuilder.js", + "src/components/directorybrowser/directorybrowser.js", "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", diff --git a/src/components/directorybrowser/directorybrowser.js b/src/components/directorybrowser/directorybrowser.js index e08fcc833..fbe99154f 100644 --- a/src/components/directorybrowser/directorybrowser.js +++ b/src/components/directorybrowser/directorybrowser.js @@ -1,9 +1,19 @@ -define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-input', 'paper-icon-button-light', 'css!./directorybrowser', 'formDialogStyle', 'emby-button'], function(loading, dialogHelper, dom, globalize) { - 'use strict'; +import loading from 'loading'; +import dialogHelper from 'dialogHelper'; +import dom from 'dom'; +import globalize from 'globalize'; +import 'listViewStyle'; +import 'emby-input'; +import 'paper-icon-button-light'; +import 'css!./directorybrowser'; +import 'formDialogStyle'; +import 'emby-button'; + +/* eslint-disable indent */ function getSystemInfo() { return systemInfo ? Promise.resolve(systemInfo) : ApiClient.getPublicSystemInfo().then( - function(info) { + info => { systemInfo = info; return info; } @@ -21,9 +31,9 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in loading.show(); - var promises = []; + const promises = []; - if ('Network' === path) { + if (path === 'Network') { promises.push(ApiClient.getNetworkDevices()); } else { if (path) { @@ -35,10 +45,10 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in } Promise.all(promises).then( - function(responses) { - var folders = responses[0]; - var parentPath = responses[1] || ''; - var html = ''; + responses => { + const folders = responses[0]; + const parentPath = responses[1] || ''; + let html = ''; page.querySelector('.results').scrollTop = 0; page.querySelector('#txtDirectoryPickerPath').value = path || ''; @@ -46,9 +56,9 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in if (path) { html += getItem('lnkPath lnkDirectory', '', parentPath, '...'); } - for (var i = 0, length = folders.length; i < length; i++) { - var folder = folders[i]; - var cssClass = 'File' === folder.Type ? 'lnkPath lnkFile' : 'lnkPath lnkDirectory'; + for (let i = 0, length = folders.length; i < length; i++) { + const folder = folders[i]; + const cssClass = folder.Type === 'File' ? 'lnkPath lnkFile' : 'lnkPath lnkDirectory'; html += getItem(cssClass, folder.Type, folder.Path, folder.Name); } @@ -58,7 +68,7 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in page.querySelector('.results').innerHTML = html; loading.hide(); - }, function() { + }, () => { if (updatePathOnError) { page.querySelector('#txtDirectoryPickerPath').value = ''; page.querySelector('.results').innerHTML = ''; @@ -69,8 +79,8 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in } function getItem(cssClass, type, path, name) { - var html = ''; - html += '
'; + let html = ''; + html += `
`; html += '
'; html += '
'; html += name; @@ -82,19 +92,19 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in } function getEditorHtml(options, systemInfo) { - var html = ''; + let html = ''; html += '
'; html += '
'; if (!options.pathReadOnly) { - var instruction = options.instruction ? options.instruction + '

' : ''; + const instruction = options.instruction ? `${options.instruction}

` : ''; html += '
'; html += instruction; - if ('bsd' === systemInfo.OperatingSystem.toLowerCase()) { + if (systemInfo.OperatingSystem.toLowerCase() === 'bsd') { html += '
'; html += '
'; html += globalize.translate('MessageDirectoryPickerBSDInstruction'); html += '
'; - } else if ('linux' === systemInfo.OperatingSystem.toLowerCase()) { + } else if (systemInfo.OperatingSystem.toLowerCase() === 'linux') { html += '
'; html += '
'; html += globalize.translate('MessageDirectoryPickerLinuxInstruction'); @@ -105,17 +115,17 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in html += ''; html += '
'; html += '
'; - var labelKey; + let labelKey; if (options.includeFiles !== true) { labelKey = 'LabelFolder'; } else { labelKey = 'LabelPath'; } - var readOnlyAttribute = options.pathReadOnly ? ' readonly' : ''; - html += ''; + const readOnlyAttribute = options.pathReadOnly ? ' readonly' : ''; + html += ``; html += '
'; if (!readOnlyAttribute) { - html += ''; + html += ``; } html += '
'; if (!readOnlyAttribute) { @@ -123,14 +133,14 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in } if (options.enableNetworkSharePath) { html += '
'; - html += ''; + html += ``; html += '
'; html += globalize.translate('LabelOptionalNetworkPathHelp', '\\\\server', '\\\\192.168.1.101'); html += '
'; html += '
'; } html += '
'; - html += ''; + html += ``; html += '
'; html += ''; html += '
'; @@ -147,7 +157,7 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in } function alertTextWithOptions(options) { - require(['alert'], function(alert) { + require(['alert'], alert => { alert(options); }); } @@ -160,7 +170,7 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in ValidateWriteable: validateWriteable, Path: path } - }).catch(function(response) { + }).catch(response => { if (response) { if (response.status === 404) { alertText(globalize.translate('PathNotFound')); @@ -180,10 +190,10 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in } function initEditor(content, options, fileOptions) { - content.addEventListener('click', function(e) { - var lnkPath = dom.parentWithClass(e.target, 'lnkPath'); + content.addEventListener('click', e => { + const lnkPath = dom.parentWithClass(e.target, 'lnkPath'); if (lnkPath) { - var path = lnkPath.getAttribute('data-path'); + const path = lnkPath.getAttribute('data-path'); if (lnkPath.classList.contains('lnkFile')) { content.querySelector('#txtDirectoryPickerPath').value = path; } else { @@ -192,25 +202,25 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in } }); - content.addEventListener('click', function(e) { + content.addEventListener('click', e => { if (dom.parentWithClass(e.target, 'btnRefreshDirectories')) { - var path = content.querySelector('#txtDirectoryPickerPath').value; + const path = content.querySelector('#txtDirectoryPickerPath').value; refreshDirectoryBrowser(content, path, fileOptions); } }); - content.addEventListener('change', function(e) { - var txtDirectoryPickerPath = dom.parentWithTag(e.target, 'INPUT'); - if (txtDirectoryPickerPath && 'txtDirectoryPickerPath' === txtDirectoryPickerPath.id) { + content.addEventListener('change', e => { + const txtDirectoryPickerPath = dom.parentWithTag(e.target, 'INPUT'); + if (txtDirectoryPickerPath && txtDirectoryPickerPath.id === 'txtDirectoryPickerPath') { refreshDirectoryBrowser(content, txtDirectoryPickerPath.value, fileOptions); } }); content.querySelector('form').addEventListener('submit', function(e) { if (options.callback) { - var networkSharePath = this.querySelector('#txtNetworkPath'); + let networkSharePath = this.querySelector('#txtNetworkPath'); networkSharePath = networkSharePath ? networkSharePath.value : null; - var path = this.querySelector('#txtDirectoryPickerPath').value; + const path = this.querySelector('#txtDirectoryPickerPath').value; validatePath(path, options.validateWriteable, ApiClient).then(options.callback(path, networkSharePath)); } e.preventDefault(); @@ -224,77 +234,79 @@ define(['loading', 'dialogHelper', 'dom', 'globalize', 'listViewStyle', 'emby-in return Promise.resolve(options.path); } else { return ApiClient.getJSON(ApiClient.getUrl('Environment/DefaultDirectoryBrowser')).then( - function(result) { + result => { return result.Path || ''; - }, function() { + }, () => { return ''; } ); } } - function directoryBrowser() { - var currentDialog; - var self = this; - self.show = function(options) { - options = options || {}; - var fileOptions = { - includeDirectories: true - }; - if (options.includeDirectories != null) { - fileOptions.includeDirectories = options.includeDirectories; - } - if (options.includeFiles != null) { - fileOptions.includeFiles = options.includeFiles; - } - Promise.all([getSystemInfo(), getDefaultPath(options)]).then( - function(responses) { - var systemInfo = responses[0]; - var initialPath = responses[1]; - var dlg = dialogHelper.createDialog({ - size: 'small', - removeOnClose: true, - scrollY: false - }); - dlg.classList.add('ui-body-a'); - dlg.classList.add('background-theme-a'); - dlg.classList.add('directoryPicker'); - dlg.classList.add('formDialog'); - - var html = ''; - html += '
'; - html += ''; - html += '

'; - html += options.header || globalize.translate('HeaderSelectPath'); - html += '

'; - html += '
'; - html += getEditorHtml(options, systemInfo); - dlg.innerHTML = html; - initEditor(dlg, options, fileOptions); - dlg.addEventListener('close', onDialogClosed); - dialogHelper.open(dlg); - dlg.querySelector('.btnCloseDialog').addEventListener('click', function() { - dialogHelper.close(dlg); - }); - currentDialog = dlg; - dlg.querySelector('#txtDirectoryPickerPath').value = initialPath; - var txtNetworkPath = dlg.querySelector('#txtNetworkPath'); - if (txtNetworkPath) { - txtNetworkPath.value = options.networkSharePath || ''; - } - if (!options.pathReadOnly) { - refreshDirectoryBrowser(dlg, initialPath, fileOptions, true); - } + class directoryBrowser { + constructor() { + let currentDialog; + this.show = options => { + options = options || {}; + const fileOptions = { + includeDirectories: true + }; + if (options.includeDirectories != null) { + fileOptions.includeDirectories = options.includeDirectories; } - ); - }; - self.close = function() { - if (currentDialog) { - dialogHelper.close(currentDialog); - } - }; + if (options.includeFiles != null) { + fileOptions.includeFiles = options.includeFiles; + } + Promise.all([getSystemInfo(), getDefaultPath(options)]).then( + responses => { + const systemInfo = responses[0]; + const initialPath = responses[1]; + const dlg = dialogHelper.createDialog({ + size: 'small', + removeOnClose: true, + scrollY: false + }); + dlg.classList.add('ui-body-a'); + dlg.classList.add('background-theme-a'); + dlg.classList.add('directoryPicker'); + dlg.classList.add('formDialog'); + + let html = ''; + html += '
'; + html += ''; + html += '

'; + html += options.header || globalize.translate('HeaderSelectPath'); + html += '

'; + html += '
'; + html += getEditorHtml(options, systemInfo); + dlg.innerHTML = html; + initEditor(dlg, options, fileOptions); + dlg.addEventListener('close', onDialogClosed); + dialogHelper.open(dlg); + dlg.querySelector('.btnCloseDialog').addEventListener('click', () => { + dialogHelper.close(dlg); + }); + currentDialog = dlg; + dlg.querySelector('#txtDirectoryPickerPath').value = initialPath; + const txtNetworkPath = dlg.querySelector('#txtNetworkPath'); + if (txtNetworkPath) { + txtNetworkPath.value = options.networkSharePath || ''; + } + if (!options.pathReadOnly) { + refreshDirectoryBrowser(dlg, initialPath, fileOptions, true); + } + } + ); + }; + this.close = () => { + if (currentDialog) { + dialogHelper.close(currentDialog); + } + }; + } } - var systemInfo; - return directoryBrowser; -}); + let systemInfo; + +/* eslint-enable indent */ +export default directoryBrowser; diff --git a/src/components/tvproviders/xmltv.js b/src/components/tvproviders/xmltv.js index 4c39b1443..054c5b640 100644 --- a/src/components/tvproviders/xmltv.js +++ b/src/components/tvproviders/xmltv.js @@ -139,7 +139,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'emby-input', 'listVi var page = $(e.target).parents('.xmltvForm')[0]; require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + var picker = new directoryBrowser.default(); picker.show({ includeFiles: true, callback: function (path) { diff --git a/src/controllers/dashboard/encodingsettings.js b/src/controllers/dashboard/encodingsettings.js index 0f54f9d70..b8cdd6665 100644 --- a/src/controllers/dashboard/encodingsettings.js +++ b/src/controllers/dashboard/encodingsettings.js @@ -151,7 +151,7 @@ define(['jQuery', 'loading', 'globalize', 'dom', 'libraryMenu'], function ($, lo }); $('#btnSelectEncoderPath', page).on('click.selectDirectory', function () { require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + var picker = new directoryBrowser.default(); picker.show({ includeFiles: true, callback: function (path) { @@ -166,7 +166,7 @@ define(['jQuery', 'loading', 'globalize', 'dom', 'libraryMenu'], function ($, lo }); $('#btnSelectTranscodingTempPath', page).on('click.selectDirectory', function () { require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + var picker = new directoryBrowser.default(); picker.show({ callback: function (path) { if (path) { diff --git a/src/controllers/dashboard/general.js b/src/controllers/dashboard/general.js index f215ace28..eb0f7edfa 100644 --- a/src/controllers/dashboard/general.js +++ b/src/controllers/dashboard/general.js @@ -59,7 +59,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'emby-textarea', 'emb return function (view, params) { $('#btnSelectCachePath', view).on('click.selectDirectory', function () { require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + var picker = new directoryBrowser.default(); picker.show({ callback: function (path) { if (path) { @@ -76,7 +76,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'emby-textarea', 'emb }); $('#btnSelectMetadataPath', view).on('click.selectDirectory', function () { require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + var picker = new directoryBrowser.default(); picker.show({ path: $('#txtMetadataPath', view).val(), networkSharePath: $('#txtMetadataNetworkPath', view).val(), diff --git a/src/controllers/dashboard/networking.js b/src/controllers/dashboard/networking.js index 4ddde7f24..33fc75b48 100644 --- a/src/controllers/dashboard/networking.js +++ b/src/controllers/dashboard/networking.js @@ -136,7 +136,7 @@ define(['loading', 'libraryMenu', 'globalize', 'emby-checkbox', 'emby-select'], }); view.querySelector('#btnSelectCertPath').addEventListener('click', function () { require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + var picker = new directoryBrowser.default(); picker.show({ includeFiles: true, includeDirectories: true, diff --git a/src/controllers/livetvsettings.js b/src/controllers/livetvsettings.js index 4c5fdc60d..715eb0621 100644 --- a/src/controllers/livetvsettings.js +++ b/src/controllers/livetvsettings.js @@ -59,7 +59,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, $('.liveTvSettingsForm').off('submit', onSubmit).on('submit', onSubmit); $('#btnSelectRecordingPath', page).on('click.selectDirectory', function () { require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + var picker = new directoryBrowser.default(); picker.show({ callback: function (path) { if (path) { @@ -74,7 +74,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, }); $('#btnSelectMovieRecordingPath', page).on('click.selectDirectory', function () { require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + var picker = new directoryBrowser.default(); picker.show({ callback: function (path) { if (path) { @@ -89,7 +89,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, }); $('#btnSelectSeriesRecordingPath', page).on('click.selectDirectory', function () { require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + var picker = new directoryBrowser.default(); picker.show({ callback: function (path) { if (path) { @@ -104,7 +104,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, }); $('#btnSelectPostProcessorPath', page).on('click.selectDirectory', function () { require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + var picker = new directoryBrowser.default(); picker.show({ includeFiles: true, callback: function (path) { diff --git a/src/controllers/livetvtuner.js b/src/controllers/livetvtuner.js index d7a4d92db..92f705c02 100644 --- a/src/controllers/livetvtuner.js +++ b/src/controllers/livetvtuner.js @@ -215,7 +215,7 @@ define(['globalize', 'loading', 'libraryMenu', 'dom', 'emby-input', 'emby-button }); view.querySelector('.btnSelectPath').addEventListener('click', function () { require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser(); + var picker = new directoryBrowser.default(); picker.show({ includeFiles: true, callback: function (path) { From 0aeff0b4648f265ee2e4b90127162d086fa5b358 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Sun, 21 Jun 2020 05:53:59 +0300 Subject: [PATCH 0058/1168] Migration displaySettings to ES6 modules --- package.json | 1 + .../displaySettings/displaySettings.js | 157 ++++++++++-------- src/controllers/user/display.js | 2 +- 3 files changed, 87 insertions(+), 73 deletions(-) diff --git a/package.json b/package.json index 034c92a7d..5811839a3 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "src/components/cardbuilder/cardBuilder.js", "src/components/cardbuilder/chaptercardbuilder.js", "src/components/cardbuilder/peoplecardbuilder.js", + "src/components/displaySettings/displaySettings.js", "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", diff --git a/src/components/displaySettings/displaySettings.js b/src/components/displaySettings/displaySettings.js index c4eb35f49..801c8657b 100644 --- a/src/components/displaySettings/displaySettings.js +++ b/src/components/displaySettings/displaySettings.js @@ -1,22 +1,37 @@ -define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', 'apphost', 'focusManager', 'datetime', 'globalize', 'loading', 'connectionManager', 'skinManager', 'dom', 'events', 'emby-select', 'emby-checkbox', 'emby-button'], function (require, browser, layoutManager, appSettings, pluginManager, appHost, focusManager, datetime, globalize, loading, connectionManager, skinManager, dom, events) { - 'use strict'; +import browser from 'browser'; +import layoutManager from 'layoutManager'; +import appSettings from 'appSettings'; +import pluginManager from 'pluginManager'; +import appHost from 'apphost'; +import focusManager from 'focusManager'; +import datetime from 'datetime'; +import globalize from 'globalize'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; +import skinManager from 'skinManager'; +import events from 'events'; +import 'emby-select'; +import 'emby-checkbox'; +import 'emby-button'; + +/* eslint-disable indent */ function fillThemes(select, isDashboard) { - select.innerHTML = skinManager.getThemes().map(function (t) { - var value = t.id; + select.innerHTML = skinManager.getThemes().map(t => { + let value = t.id; if (t.isDefault && !isDashboard) { value = ''; } else if (t.isDefaultServerDashboard && isDashboard) { value = ''; } - return ''; + return ``; }).join(''); } function loadScreensavers(context, userSettings) { - var selectScreensaver = context.querySelector('.selectScreensaver'); - var options = pluginManager.ofType('screensaver').map(function (plugin) { + const selectScreensaver = context.querySelector('.selectScreensaver'); + const options = pluginManager.ofType('screensaver').map(plugin => { return { name: plugin.name, value: plugin.id @@ -28,8 +43,8 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' value: 'none' }); - selectScreensaver.innerHTML = options.map(function (o) { - return ''; + selectScreensaver.innerHTML = options.map(o => { + return ``; }).join(''); selectScreensaver.value = userSettings.screensaver(); @@ -41,8 +56,8 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' function loadSoundEffects(context, userSettings) { - var selectSoundEffects = context.querySelector('.selectSoundEffects'); - var options = pluginManager.ofType('soundeffects').map(function (plugin) { + const selectSoundEffects = context.querySelector('.selectSoundEffects'); + const options = pluginManager.ofType('soundeffects').map(plugin => { return { name: plugin.name, value: plugin.id @@ -54,8 +69,8 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' value: 'none' }); - selectSoundEffects.innerHTML = options.map(function (o) { - return ''; + selectSoundEffects.innerHTML = options.map(o => { + return ``; }).join(''); selectSoundEffects.value = userSettings.soundEffects(); @@ -67,17 +82,17 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' function loadSkins(context, userSettings) { - var selectSkin = context.querySelector('.selectSkin'); + const selectSkin = context.querySelector('.selectSkin'); - var options = pluginManager.ofType('skin').map(function (plugin) { + const options = pluginManager.ofType('skin').map(plugin => { return { name: plugin.name, value: plugin.id }; }); - selectSkin.innerHTML = options.map(function (o) { - return ''; + selectSkin.innerHTML = options.map(o => { + return ``; }).join(''); selectSkin.value = userSettings.skin(); @@ -92,7 +107,7 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' } } - function showOrHideMissingEpisodesField(context, user, apiClient) { + function showOrHideMissingEpisodesField(context) { if (browser.tizen || browser.web0s) { context.querySelector('.fldDisplayMissingEpisodes').classList.add('hide'); @@ -102,10 +117,7 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' context.querySelector('.fldDisplayMissingEpisodes').classList.remove('hide'); } - function loadForm(context, user, userSettings, apiClient) { - - var loggedInUserId = apiClient.getCurrentUserId(); - var userId = user.Id; + function loadForm(context, user, userSettings) { if (user.Policy.IsAdministrator) { context.querySelector('.selectDashboardThemeContainer').classList.remove('hide'); @@ -167,8 +179,8 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' context.querySelector('.chkRunAtStartup').checked = appSettings.runAtStartup(); - var selectTheme = context.querySelector('#selectTheme'); - var selectDashboardTheme = context.querySelector('#selectDashboardTheme'); + const selectTheme = context.querySelector('#selectTheme'); + const selectDashboardTheme = context.querySelector('#selectDashboardTheme'); fillThemes(selectTheme); fillThemes(selectDashboardTheme, true); @@ -195,7 +207,7 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' context.querySelector('.selectLayout').value = layoutManager.getSavedLayout() || ''; - showOrHideMissingEpisodesField(context, user, apiClient); + showOrHideMissingEpisodesField(context); loading.hide(); } @@ -239,29 +251,29 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' function save(instance, context, userId, userSettings, apiClient, enableSaveConfirmation) { loading.show(); - apiClient.getUser(userId).then(function (user) { - saveUser(context, user, userSettings, apiClient).then(function () { + apiClient.getUser(userId).then(user => { + saveUser(context, user, userSettings, apiClient).then(() => { loading.hide(); if (enableSaveConfirmation) { - require(['toast'], function (toast) { + import('toast').then(({default: toast}) => { toast(globalize.translate('SettingsSaved')); }); } events.trigger(instance, 'saved'); - }, function () { + }, () => { loading.hide(); }); }); } function onSubmit(e) { - var self = this; - var apiClient = connectionManager.getApiClient(self.options.serverId); - var userId = self.options.userId; - var userSettings = self.options.userSettings; + const self = this; + const apiClient = connectionManager.getApiClient(self.options.serverId); + const userId = self.options.userId; + const userSettings = self.options.userSettings; - userSettings.setUserInfo(userId, apiClient).then(function () { - var enableSaveConfirmation = self.options.enableSaveConfirmation; + userSettings.setUserInfo(userId, apiClient).then(() => { + const enableSaveConfirmation = self.options.enableSaveConfirmation; save(self, self.options.element, userId, userSettings, apiClient, enableSaveConfirmation); }); @@ -272,50 +284,51 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', ' return false; } - function embed(options, self) { - require(['text!./displaySettings.template.html'], function (template) { - options.element.innerHTML = globalize.translateDocument(template, 'core'); - options.element.querySelector('form').addEventListener('submit', onSubmit.bind(self)); - if (options.enableSaveButton) { - options.element.querySelector('.btnSave').classList.remove('hide'); - } - self.loadData(options.autoFocus); - }); + async function embed(options, self) { + const { default: template } = await import('text!./displaySettings.template.html'); + options.element.innerHTML = globalize.translateDocument(template, 'core'); + options.element.querySelector('form').addEventListener('submit', onSubmit.bind(self)); + if (options.enableSaveButton) { + options.element.querySelector('.btnSave').classList.remove('hide'); + } + self.loadData(options.autoFocus); } - function DisplaySettings(options) { - this.options = options; - embed(options, this); - } + class DisplaySettings { + constructor(options) { + this.options = options; + embed(options, this); + } - DisplaySettings.prototype.loadData = function (autoFocus) { - var self = this; - var context = self.options.element; + loadData(autoFocus) { + const self = this; + const context = self.options.element; - loading.show(); + loading.show(); - var userId = self.options.userId; - var apiClient = connectionManager.getApiClient(self.options.serverId); - var userSettings = self.options.userSettings; + const userId = self.options.userId; + const apiClient = connectionManager.getApiClient(self.options.serverId); + const userSettings = self.options.userSettings; - return apiClient.getUser(userId).then(function (user) { - return userSettings.setUserInfo(userId, apiClient).then(function () { - self.dataLoaded = true; - loadForm(context, user, userSettings, apiClient); - if (autoFocus) { - focusManager.autoFocus(context); - } + return apiClient.getUser(userId).then(user => { + return userSettings.setUserInfo(userId, apiClient).then(() => { + self.dataLoaded = true; + loadForm(context, user, userSettings); + if (autoFocus) { + focusManager.autoFocus(context); + } + }); }); - }); - }; + } - DisplaySettings.prototype.submit = function () { - onSubmit.call(this); - }; + submit() { + onSubmit.call(this); + } - DisplaySettings.prototype.destroy = function () { - this.options = null; - }; + destroy() { + this.options = null; + } + } - return DisplaySettings; -}); +/* eslint-enable indent */ +export default DisplaySettings; diff --git a/src/controllers/user/display.js b/src/controllers/user/display.js index 26c75f209..408631b38 100644 --- a/src/controllers/user/display.js +++ b/src/controllers/user/display.js @@ -21,7 +21,7 @@ define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySett if (settingsInstance) { settingsInstance.loadData(); } else { - settingsInstance = new DisplaySettings({ + settingsInstance = new DisplaySettings.default({ serverId: ApiClient.serverId(), userId: userId, element: view.querySelector('.settingsContainer'), From 30bddd04b0d91679b28cf402ae609f365cd4afd5 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Sun, 21 Jun 2020 04:38:42 +0300 Subject: [PATCH 0059/1168] Migration homeScreenSettings to ES6 modules --- package.json | 1 + .../homeScreenSettings/homeScreenSettings.js | 277 +++++++++--------- src/controllers/user/home.js | 2 +- 3 files changed, 137 insertions(+), 143 deletions(-) diff --git a/package.json b/package.json index 5811839a3..3c2f9ef1d 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "src/components/cardbuilder/chaptercardbuilder.js", "src/components/cardbuilder/peoplecardbuilder.js", "src/components/displaySettings/displaySettings.js", + "src/components/homeScreenSettings/homeScreenSettings.js", "src/components/images/imageLoader.js", "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", diff --git a/src/components/homeScreenSettings/homeScreenSettings.js b/src/components/homeScreenSettings/homeScreenSettings.js index 9eae944d2..5e7d6b4c5 100644 --- a/src/components/homeScreenSettings/homeScreenSettings.js +++ b/src/components/homeScreenSettings/homeScreenSettings.js @@ -1,26 +1,37 @@ -define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loading', 'connectionManager', 'homeSections', 'dom', 'events', 'listViewStyle', 'emby-select', 'emby-checkbox'], function (require, appHost, layoutManager, focusManager, globalize, loading, connectionManager, homeSections, dom, events) { - 'use strict'; +import layoutManager from 'layoutManager'; +import focusManager from 'focusManager'; +import globalize from 'globalize'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; +import homeSections from 'homeSections'; +import dom from 'dom'; +import events from 'events'; +import 'listViewStyle'; +import 'emby-select'; +import 'emby-checkbox'; - var numConfigurableSections = 7; +/* eslint-disable indent */ + + const numConfigurableSections = 7; function renderViews(page, user, result) { - var folderHtml = ''; + let folderHtml = ''; folderHtml += '
'; - folderHtml += result.map(function (i) { + folderHtml += result.map(i => { - var currentHtml = ''; + let currentHtml = ''; - var id = 'chkGroupFolder' + i.Id; + const id = `chkGroupFolder${i.Id}`; - var isChecked = user.Configuration.GroupedFolders.indexOf(i.Id) !== -1; + const isChecked = user.Configuration.GroupedFolders.includes(i.Id); - var checkedHtml = isChecked ? ' checked="checked"' : ''; + const checkedHtml = isChecked ? ' checked="checked"' : ''; currentHtml += ''; return currentHtml; @@ -34,7 +45,7 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa function getLandingScreenOptions(type) { - var list = []; + const list = []; if (type === 'movies') { list.push({ @@ -123,27 +134,27 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa function getLandingScreenOptionsHtml(type, userValue) { - return getLandingScreenOptions(type).map(function (o) { + return getLandingScreenOptions(type).map(o => { - var selected = userValue === o.value || (o.isDefault && !userValue); - var selectedHtml = selected ? ' selected' : ''; - var optionValue = o.isDefault ? '' : o.value; + const selected = userValue === o.value || (o.isDefault && !userValue); + const selectedHtml = selected ? ' selected' : ''; + const optionValue = o.isDefault ? '' : o.value; - return ''; + return ``; }).join(''); } function renderViewOrder(context, user, result) { - var html = ''; + let html = ''; - var index = 0; + let index = 0; - html += result.Items.map(function (view) { + html += result.Items.map(view => { - var currentHtml = ''; + let currentHtml = ''; - currentHtml += '
'; + currentHtml += `
`; currentHtml += ''; @@ -155,8 +166,8 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa currentHtml += '
'; - currentHtml += ''; - currentHtml += ''; + currentHtml += ``; + currentHtml += ``; currentHtml += '
'; @@ -170,14 +181,14 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa function updateHomeSectionValues(context, userSettings) { - for (var i = 1; i <= 7; i++) { + for (let i = 1; i <= 7; i++) { - var select = context.querySelector('#selectHomeSection' + i); - var defaultValue = homeSections.getDefaultSection(i - 1); + const select = context.querySelector(`#selectHomeSection${i}`); + const defaultValue = homeSections.getDefaultSection(i - 1); - var option = select.querySelector('option[value=' + defaultValue + ']') || select.querySelector('option[value=""]'); + const option = select.querySelector(`option[value=${defaultValue}]`) || select.querySelector('option[value=""]'); - var userValue = userSettings.get('homesection' + (i - 1)); + const userValue = userSettings.get(`homesection${i - 1}`); option.value = ''; @@ -193,42 +204,42 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa function getPerLibrarySettingsHtml(item, user, userSettings, apiClient) { - var html = ''; + let html = ''; - var isChecked; + let isChecked; if (item.Type === 'Channel' || item.CollectionType === 'boxsets' || item.CollectionType === 'playlists') { - isChecked = (user.Configuration.MyMediaExcludes || []).indexOf(item.Id) === -1; + isChecked = !(user.Configuration.MyMediaExcludes || []).includes(item.Id); html += '
'; html += ''; html += '
'; } - var excludeFromLatest = ['playlists', 'livetv', 'boxsets', 'channels']; - if (excludeFromLatest.indexOf(item.CollectionType || '') === -1) { + const excludeFromLatest = ['playlists', 'livetv', 'boxsets', 'channels']; + if (!excludeFromLatest.includes(item.CollectionType || '')) { - isChecked = user.Configuration.LatestItemsExcludes.indexOf(item.Id) === -1; + isChecked = !user.Configuration.LatestItemsExcludes.includes(item.Id); html += ''; } if (html) { - html = '
' + html + '
'; + html = `
${html}
`; } if (item.CollectionType === 'movies' || item.CollectionType === 'tvshows' || item.CollectionType === 'music' || item.CollectionType === 'livetv') { - var idForLanding = item.CollectionType === 'livetv' ? item.CollectionType : item.Id; + const idForLanding = item.CollectionType === 'livetv' ? item.CollectionType : item.Id; html += '
'; - html += '`; - var userValue = userSettings.get('landing-' + idForLanding); + const userValue = userSettings.get(`landing-${idForLanding}`); html += getLandingScreenOptionsHtml(item.CollectionType, userValue); @@ -238,7 +249,7 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa if (html) { - var prefix = ''; + let prefix = ''; prefix += '
'; prefix += '

'; @@ -254,10 +265,10 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa function renderPerLibrarySettings(context, user, userViews, userSettings, apiClient) { - var elem = context.querySelector('.perLibrarySettings'); - var html = ''; + const elem = context.querySelector('.perLibrarySettings'); + let html = ''; - for (var i = 0, length = userViews.length; i < length; i++) { + for (let i = 0, length = userViews.length; i < length; i++) { html += getPerLibrarySettingsHtml(userViews[i], user, userSettings, apiClient); } @@ -271,10 +282,10 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa updateHomeSectionValues(context, userSettings); - var promise1 = apiClient.getUserViews({ IncludeHidden: true }, user.Id); - var promise2 = apiClient.getJSON(apiClient.getUrl('Users/' + user.Id + '/GroupingOptions')); + const promise1 = apiClient.getUserViews({ IncludeHidden: true }, user.Id); + const promise2 = apiClient.getJSON(apiClient.getUrl(`Users/${user.Id}/GroupingOptions`)); - Promise.all([promise1, promise2]).then(function (responses) { + Promise.all([promise1, promise2]).then(responses => { renderViewOrder(context, user, responses[0]); @@ -286,38 +297,19 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa }); } - function getSibling(elem, type, className) { - - var sibling = elem[type]; - - while (sibling != null) { - if (sibling.classList.contains(className)) { - break; - } - } - - if (sibling != null) { - if (!sibling.classList.contains(className)) { - sibling = null; - } - } - - return sibling; - } - function onSectionOrderListClick(e) { - var target = dom.parentWithClass(e.target, 'btnViewItemMove'); + const target = dom.parentWithClass(e.target, 'btnViewItemMove'); if (target) { - var viewItem = dom.parentWithClass(target, 'viewItem'); + const viewItem = dom.parentWithClass(target, 'viewItem'); if (viewItem) { - var ul = dom.parentWithClass(viewItem, 'paperList'); + const ul = dom.parentWithClass(viewItem, 'paperList'); if (target.classList.contains('btnViewItemDown')) { - var next = viewItem.nextSibling; + const next = viewItem.nextSibling; if (next) { viewItem.parentNode.removeChild(viewItem); @@ -327,7 +319,7 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa } else { - var prev = viewItem.previousSibling; + const prev = viewItem.previousSibling; if (prev) { viewItem.parentNode.removeChild(viewItem); @@ -341,10 +333,10 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa function getCheckboxItems(selector, context, isChecked) { - var inputs = context.querySelectorAll(selector); - var list = []; + const inputs = context.querySelectorAll(selector); + const list = []; - for (var i = 0, length = inputs.length; i < length; i++) { + for (let i = 0, length = inputs.length; i < length; i++) { if (inputs[i].checked === isChecked) { list.push(inputs[i]); @@ -359,25 +351,25 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa user.Configuration.HidePlayedInLatest = context.querySelector('.chkHidePlayedFromLatest').checked; - user.Configuration.LatestItemsExcludes = getCheckboxItems('.chkIncludeInLatest', context, false).map(function (i) { + user.Configuration.LatestItemsExcludes = getCheckboxItems('.chkIncludeInLatest', context, false).map(i => { return i.getAttribute('data-folderid'); }); - user.Configuration.MyMediaExcludes = getCheckboxItems('.chkIncludeInMyMedia', context, false).map(function (i) { + user.Configuration.MyMediaExcludes = getCheckboxItems('.chkIncludeInMyMedia', context, false).map(i => { return i.getAttribute('data-folderid'); }); - user.Configuration.GroupedFolders = getCheckboxItems('.chkGroupFolder', context, true).map(function (i) { + user.Configuration.GroupedFolders = getCheckboxItems('.chkGroupFolder', context, true).map(i => { return i.getAttribute('data-folderid'); }); - var viewItems = context.querySelectorAll('.viewItem'); - var orderedViews = []; - var i; - var length; + const viewItems = context.querySelectorAll('.viewItem'); + const orderedViews = []; + let i; + let length; for (i = 0, length = viewItems.length; i < length; i++) { orderedViews.push(viewItems[i].getAttribute('data-viewid')); } @@ -394,10 +386,10 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa userSettingsInstance.set('homesection5', context.querySelector('#selectHomeSection6').value); userSettingsInstance.set('homesection6', context.querySelector('#selectHomeSection7').value); - var selectLandings = context.querySelectorAll('.selectLanding'); + const selectLandings = context.querySelectorAll('.selectLanding'); for (i = 0, length = selectLandings.length; i < length; i++) { - var selectLanding = selectLandings[i]; - userSettingsInstance.set('landing-' + selectLanding.getAttribute('data-folderid'), selectLanding.value); + const selectLanding = selectLandings[i]; + userSettingsInstance.set(`landing-${selectLanding.getAttribute('data-folderid')}`, selectLanding.value); } return apiClient.updateUserConfiguration(user.Id, user.Configuration); @@ -407,20 +399,20 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa loading.show(); - apiClient.getUser(userId).then(function (user) { + apiClient.getUser(userId).then(user => { - saveUser(context, user, userSettings, apiClient).then(function () { + saveUser(context, user, userSettings, apiClient).then(() => { loading.hide(); if (enableSaveConfirmation) { - require(['toast'], function (toast) { + import('toast').then(({default: toast}) => { toast(globalize.translate('SettingsSaved')); }); } events.trigger(instance, 'saved'); - }, function () { + }, () => { loading.hide(); }); }); @@ -428,14 +420,14 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa function onSubmit(e) { - var self = this; - var apiClient = connectionManager.getApiClient(self.options.serverId); - var userId = self.options.userId; - var userSettings = self.options.userSettings; + const self = this; + const apiClient = connectionManager.getApiClient(self.options.serverId); + const userId = self.options.userId; + const userSettings = self.options.userSettings; - userSettings.setUserInfo(userId, apiClient).then(function () { + userSettings.setUserInfo(userId, apiClient).then(() => { - var enableSaveConfirmation = self.options.enableSaveConfirmation; + const enableSaveConfirmation = self.options.enableSaveConfirmation; save(self, self.options.element, userId, userSettings, apiClient, enableSaveConfirmation); }); @@ -448,13 +440,13 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa function onChange(e) { - var chkIncludeInMyMedia = dom.parentWithClass(e.target, 'chkIncludeInMyMedia'); + const chkIncludeInMyMedia = dom.parentWithClass(e.target, 'chkIncludeInMyMedia'); if (!chkIncludeInMyMedia) { return; } - var section = dom.parentWithClass(chkIncludeInMyMedia, 'verticalSection'); - var fldIncludeInLatest = section.querySelector('.fldIncludeInLatest'); + const section = dom.parentWithClass(chkIncludeInMyMedia, 'verticalSection'); + const fldIncludeInLatest = section.querySelector('.fldIncludeInLatest'); if (fldIncludeInLatest) { if (chkIncludeInMyMedia.checked) { fldIncludeInLatest.classList.remove('hide'); @@ -466,10 +458,10 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa function embed(options, self) { - require(['text!./homeScreenSettings.template.html'], function (template) { + return import('text!./homeScreenSettings.template.html').then(({default: template}) => { - for (var i = 1; i <= numConfigurableSections; i++) { - template = template.replace('{section' + i + 'label}', globalize.translate('LabelHomeScreenSectionValue', i)); + for (let i = 1; i <= numConfigurableSections; i++) { + template = template.replace(`{section${i}label}`, globalize.translate('LabelHomeScreenSectionValue', i)); } options.element.innerHTML = globalize.translateDocument(template, 'core'); @@ -492,47 +484,48 @@ define(['require', 'apphost', 'layoutManager', 'focusManager', 'globalize', 'loa }); } - function HomeScreenSettings(options) { + class HomeScreenSettings { + constructor(options) { + this.options = options; + embed(options, this); + } - this.options = options; + loadData(autoFocus) { - embed(options, this); + const self = this; + const context = self.options.element; + + loading.show(); + + const userId = self.options.userId; + const apiClient = connectionManager.getApiClient(self.options.serverId); + const userSettings = self.options.userSettings; + + apiClient.getUser(userId).then(user => { + + userSettings.setUserInfo(userId, apiClient).then(() => { + + self.dataLoaded = true; + + loadForm(context, user, userSettings, apiClient); + + if (autoFocus) { + focusManager.autoFocus(context); + } + }); + }); + } + + submit() { + onSubmit.call(this); + } + + destroy() { + + this.options = null; + } } - HomeScreenSettings.prototype.loadData = function (autoFocus) { +/* eslint-enable indent */ - var self = this; - var context = self.options.element; - - loading.show(); - - var userId = self.options.userId; - var apiClient = connectionManager.getApiClient(self.options.serverId); - var userSettings = self.options.userSettings; - - apiClient.getUser(userId).then(function (user) { - - userSettings.setUserInfo(userId, apiClient).then(function () { - - self.dataLoaded = true; - - loadForm(context, user, userSettings, apiClient); - - if (autoFocus) { - focusManager.autoFocus(context); - } - }); - }); - }; - - HomeScreenSettings.prototype.submit = function () { - onSubmit.call(this); - }; - - HomeScreenSettings.prototype.destroy = function () { - - this.options = null; - }; - - return HomeScreenSettings; -}); +export default HomeScreenSettings; diff --git a/src/controllers/user/home.js b/src/controllers/user/home.js index 8f826c425..117a457d3 100644 --- a/src/controllers/user/home.js +++ b/src/controllers/user/home.js @@ -21,7 +21,7 @@ define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'au if (homescreenSettingsInstance) { homescreenSettingsInstance.loadData(); } else { - homescreenSettingsInstance = new HomescreenSettings({ + homescreenSettingsInstance = new HomescreenSettings.default({ serverId: ApiClient.serverId(), userId: userId, element: view.querySelector('.homeScreenSettingsContainer'), From 7cb209fa10ddeed3a90054673cf930579fdbe852 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Sun, 21 Jun 2020 04:56:48 +0300 Subject: [PATCH 0060/1168] Migration playbackSettings to ES6 modules --- package.json | 1 + .../playbackSettings/playbackSettings.js | 161 ++++++++++-------- src/controllers/user/playback.js | 2 +- 3 files changed, 88 insertions(+), 76 deletions(-) diff --git a/package.json b/package.json index 3c2f9ef1d..85225a15f 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,7 @@ "src/components/playback/playmethodhelper.js", "src/components/playback/remotecontrolautoplay.js", "src/components/playback/volumeosd.js", + "src/components/playbackSettings/playbackSettings.js", "src/components/playmenu.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", diff --git a/src/components/playbackSettings/playbackSettings.js b/src/components/playbackSettings/playbackSettings.js index 06d2e38d2..846efe1fd 100644 --- a/src/components/playbackSettings/playbackSettings.js +++ b/src/components/playbackSettings/playbackSettings.js @@ -1,31 +1,42 @@ -define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'qualityoptions', 'globalize', 'loading', 'connectionManager', 'dom', 'events', 'emby-select', 'emby-checkbox'], function (require, browser, appSettings, appHost, focusManager, qualityoptions, globalize, loading, connectionManager, dom, events) { - 'use strict'; +import browser from 'browser'; +import appSettings from 'appSettings'; +import appHost from 'apphost'; +import focusManager from 'focusManager'; +import qualityoptions from 'qualityoptions'; +import globalize from 'globalize'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; +import events from 'events'; +import 'emby-select'; +import 'emby-checkbox'; + +/* eslint-disable indent */ function fillSkipLengths(select) { - var options = [5, 10, 15, 20, 25, 30]; + const options = [5, 10, 15, 20, 25, 30]; - select.innerHTML = options.map(function (option) { + select.innerHTML = options.map(option => { return { name: globalize.translate('ValueSeconds', option), value: option * 1000 }; - }).map(function (o) { - return ''; + }).map(o => { + return ``; }).join(''); } function populateLanguages(select, languages) { - var html = ''; + let html = ''; - html += "'; + html += ``; - for (var i = 0, length = languages.length; i < length; i++) { + for (let i = 0, length = languages.length; i < length; i++) { - var culture = languages[i]; + const culture = languages[i]; - html += "'; + html += ``; } select.innerHTML = html; @@ -33,7 +44,7 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality function setMaxBitrateIntoField(select, isInNetwork, mediatype) { - var options = mediatype === 'Audio' ? qualityoptions.getAudioQualityOptions({ + const options = mediatype === 'Audio' ? qualityoptions.getAudioQualityOptions({ currentMaxBitrate: appSettings.maxStreamingBitrate(isInNetwork, mediatype), isAutomaticBitrateEnabled: appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype), @@ -47,10 +58,10 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality }); - select.innerHTML = options.map(function (i) { + select.innerHTML = options.map(i => { // render empty string instead of 0 for the auto option - return ''; + return ``; }).join(''); if (appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype)) { @@ -62,23 +73,23 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality function fillChromecastQuality(select) { - var options = qualityoptions.getVideoQualityOptions({ + const options = qualityoptions.getVideoQualityOptions({ currentMaxBitrate: appSettings.maxChromecastBitrate(), isAutomaticBitrateEnabled: !appSettings.maxChromecastBitrate(), enableAuto: true }); - select.innerHTML = options.map(function (i) { + select.innerHTML = options.map(i => { // render empty string instead of 0 for the auto option - return ''; + return ``; }).join(''); select.value = appSettings.maxChromecastBitrate() || ''; } - function setMaxBitrateFromField(select, isInNetwork, mediatype, value) { + function setMaxBitrateFromField(select, isInNetwork, mediatype) { if (select.value) { appSettings.maxStreamingBitrate(isInNetwork, mediatype, select.value); @@ -110,7 +121,7 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality return; } - apiClient.getEndpointInfo().then(function (endpointInfo) { + apiClient.getEndpointInfo().then(endpointInfo => { if (endpointInfo.IsInNetwork) { @@ -133,7 +144,7 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality }); } - function showOrHideEpisodesField(context, user, apiClient) { + function showOrHideEpisodesField(context) { if (browser.tizen || browser.web0s) { context.querySelector('.fldEpisodeAutoPlay').classList.add('hide'); @@ -145,12 +156,12 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality function loadForm(context, user, userSettings, apiClient) { - var loggedInUserId = apiClient.getCurrentUserId(); - var userId = user.Id; + const loggedInUserId = apiClient.getCurrentUserId(); + const userId = user.Id; showHideQualityFields(context, user, apiClient); - apiClient.getCultures().then(function (allCultures) { + apiClient.getCultures().then(allCultures => { populateLanguages(context.querySelector('#selectAudioLanguage'), allCultures); @@ -159,7 +170,7 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality }); // hide cinema mode options if disabled at server level - apiClient.getNamedConfiguration('cinemamode').then(function (cinemaConfig) { + apiClient.getNamedConfiguration('cinemamode').then(cinemaConfig => { if (cinemaConfig.EnableIntrosForMovies || cinemaConfig.EnableIntrosForEpisodes) { context.querySelector('.cinemaModeOptions').classList.remove('hide'); @@ -204,18 +215,18 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality fillChromecastQuality(context.querySelector('.selectChromecastVideoQuality')); - var selectChromecastVersion = context.querySelector('.selectChromecastVersion'); + const selectChromecastVersion = context.querySelector('.selectChromecastVersion'); selectChromecastVersion.value = userSettings.chromecastVersion(); - var selectSkipForwardLength = context.querySelector('.selectSkipForwardLength'); + const selectSkipForwardLength = context.querySelector('.selectSkipForwardLength'); fillSkipLengths(selectSkipForwardLength); selectSkipForwardLength.value = userSettings.skipForwardLength(); - var selectSkipBackLength = context.querySelector('.selectSkipBackLength'); + const selectSkipBackLength = context.querySelector('.selectSkipBackLength'); fillSkipLengths(selectSkipBackLength); selectSkipBackLength.value = userSettings.skipBackLength(); - showOrHideEpisodesField(context, user, apiClient); + showOrHideEpisodesField(context); loading.hide(); } @@ -248,20 +259,20 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality loading.show(); - apiClient.getUser(userId).then(function (user) { + apiClient.getUser(userId).then(user => { - saveUser(context, user, userSettings, apiClient).then(function () { + saveUser(context, user, userSettings, apiClient).then(() => { loading.hide(); if (enableSaveConfirmation) { - require(['toast'], function (toast) { + import('toast').then(({default: toast}) => { toast(globalize.translate('SettingsSaved')); }); } events.trigger(instance, 'saved'); - }, function () { + }, () => { loading.hide(); }); }); @@ -269,14 +280,14 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality function onSubmit(e) { - var self = this; - var apiClient = connectionManager.getApiClient(self.options.serverId); - var userId = self.options.userId; - var userSettings = self.options.userSettings; + const self = this; + const apiClient = connectionManager.getApiClient(self.options.serverId); + const userId = self.options.userId; + const userSettings = self.options.userSettings; - userSettings.setUserInfo(userId, apiClient).then(function () { + userSettings.setUserInfo(userId, apiClient).then(() => { - var enableSaveConfirmation = self.options.enableSaveConfirmation; + const enableSaveConfirmation = self.options.enableSaveConfirmation; save(self, self.options.element, userId, userSettings, apiClient, enableSaveConfirmation); }); @@ -289,7 +300,7 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality function embed(options, self) { - require(['text!./playbackSettings.template.html'], function (template) { + return import('text!./playbackSettings.template.html').then(({default: template}) => { options.element.innerHTML = globalize.translateDocument(template, 'core'); @@ -307,43 +318,43 @@ define(['require', 'browser', 'appSettings', 'apphost', 'focusManager', 'quality }); } - function PlaybackSettings(options) { + class PlaybackSettings { + constructor(options) { + this.options = options; + embed(options, this); + } - this.options = options; + loadData() { - embed(options, this); + const self = this; + const context = self.options.element; + + loading.show(); + + const userId = self.options.userId; + const apiClient = connectionManager.getApiClient(self.options.serverId); + const userSettings = self.options.userSettings; + + apiClient.getUser(userId).then(user => { + + userSettings.setUserInfo(userId, apiClient).then(() => { + + self.dataLoaded = true; + + loadForm(context, user, userSettings, apiClient); + }); + }); + } + + submit() { + onSubmit.call(this); + } + + destroy() { + + this.options = null; + } } - PlaybackSettings.prototype.loadData = function () { - - var self = this; - var context = self.options.element; - - loading.show(); - - var userId = self.options.userId; - var apiClient = connectionManager.getApiClient(self.options.serverId); - var userSettings = self.options.userSettings; - - apiClient.getUser(userId).then(function (user) { - - userSettings.setUserInfo(userId, apiClient).then(function () { - - self.dataLoaded = true; - - loadForm(context, user, userSettings, apiClient); - }); - }); - }; - - PlaybackSettings.prototype.submit = function () { - onSubmit.call(this); - }; - - PlaybackSettings.prototype.destroy = function () { - - this.options = null; - }; - - return PlaybackSettings; -}); +/* eslint-enable indent */ +export default PlaybackSettings; diff --git a/src/controllers/user/playback.js b/src/controllers/user/playback.js index 02a718eb8..c138b5a86 100644 --- a/src/controllers/user/playback.js +++ b/src/controllers/user/playback.js @@ -21,7 +21,7 @@ define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'auto if (settingsInstance) { settingsInstance.loadData(); } else { - settingsInstance = new PlaybackSettings({ + settingsInstance = new PlaybackSettings.default({ serverId: ApiClient.serverId(), userId: userId, element: view.querySelector('.settingsContainer'), From ad72f590f7294e3bc3e1a00ed7bc4ea7db4e3584 Mon Sep 17 00:00:00 2001 From: ferferga Date: Mon, 22 Jun 2020 10:51:42 +0200 Subject: [PATCH 0061/1168] Use layout-mobile class --- .../remotecontrol/remotecontrol.css | 22 +++++++++++-------- src/components/remotecontrol/remotecontrol.js | 4 ---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index d80d7a3c3..6dbd3b716 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -171,12 +171,16 @@ z-index: 0; } -.mobilePlayer.playlistSectionButtonTransparent { +.layout-mobile .playlistSectionButtonTransparent { background: rgba(0, 0, 0, 0) !important; } -.mobilePlayer.playlistSection .playlist, -.mobilePlayer.playlistSection .contextMenu { +.layout-mobile .btnShuffle { + display: unset !important; +} + +.layout-mobile .playlistSection .playlist, +.layout-mobile .playlistSection .contextMenu { position: absolute; top: 12.2em; bottom: 4.2em; @@ -188,7 +192,7 @@ z-index: 1000; } -.mobilePlayer.playlistSectionButton { +.layout-mobile .playlistSectionButton { position: fixed; bottom: 0; left: 0; @@ -198,21 +202,21 @@ padding-right: 7.3%; } -.playlistSectionButton:not(.mobilePlayer) { +.playlistSectionButton:not(>.layout-mobile) { background: unset !important; } -.nowPlayingPlaylist:not(.mobilePlayer) { +.nowPlayingPlaylist:not(>.layout-mobile) { background: unset !important; } -.mobilePlayer.playlistSectionButton .btnTogglePlaylist { +.layout-mobile .playlistSectionButton .btnTogglePlaylist { font-size: larger; margin: 0; padding-left: 0; } -.mobilePlayer.playlistSectionButton .btnSavePlaylist { +.layout-mobile .playlistSectionButton .btnSavePlaylist { margin: 0; padding-right: 0; -webkit-box-flex: 1; @@ -224,7 +228,7 @@ border-radius: 0; } -.mobilePlayer.playlistSectionButton .btnToggleContextMenu { +.layout-mobile .playlistSectionButton .btnToggleContextMenu { font-size: larger; margin: 0; padding-right: 0; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 0cf8e2f95..c31d57a74 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -852,10 +852,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL context.querySelector('.btnTogglePlaylist').classList.remove('hide'); context.querySelector('.nowPlayingInfoButtons').insertAdjacentHTML('afterbegin', repeatButtonHtml); context.querySelector('.nowPlayingInfoButtons').insertAdjacentHTML('beforeend', shuffleButtonHtml); - let childs = context.querySelectorAll('*'); - for (let child of childs) { - child.classList.add('mobilePlayer'); - } } bindEvents(context); From 2e8e240aa0ff3de9faedf6fbb6a3aa19524a1491 Mon Sep 17 00:00:00 2001 From: ferferga Date: Mon, 22 Jun 2020 11:10:26 +0200 Subject: [PATCH 0062/1168] Add shuffle mode to Chromecast --- src/plugins/chromecastPlayer/plugin.js | 19 ++++++++++++++++++- src/plugins/sessionPlayer/plugin.js | 4 ++++ src/scripts/serverNotifications.js | 3 +++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/plugins/chromecastPlayer/plugin.js b/src/plugins/chromecastPlayer/plugin.js index b3f75f7a6..22242959f 100644 --- a/src/plugins/chromecastPlayer/plugin.js +++ b/src/plugins/chromecastPlayer/plugin.js @@ -548,7 +548,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' events.trigger(instance, 'playbackstop', [state]); - var state = instance.lastPlayerData.PlayState || {}; + state = instance.lastPlayerData.PlayState || {}; var volume = state.VolumeLevel || 0.5; var mute = state.IsMuted || false; @@ -572,6 +572,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' bindEventForRelay(instance, 'unpause'); bindEventForRelay(instance, 'volumechange'); bindEventForRelay(instance, 'repeatmodechange'); + bindEventForRelay(instance, 'shuffleplaylistmodechange'); events.on(instance._castPlayer, 'playstatechange', function (e, data) { @@ -651,6 +652,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' 'SetSubtitleStreamIndex', 'DisplayContent', 'SetRepeatMode', + 'SetPlaylistShuffleMode', 'EndSession', 'PlayMediaSource', 'PlayTrailers' @@ -864,6 +866,12 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' return state.RepeatMode; }; + ChromecastPlayer.prototype.getPlaylistShuffleMode = function () { + var state = this.lastPlayerData || {}; + state = state.PlayState || {}; + return state.ShuffleMode; + }; + ChromecastPlayer.prototype.playTrailers = function (item) { this._castPlayer.sendMessage({ @@ -884,6 +892,15 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }); }; + ChromecastPlayer.prototype.setPlaylistShuffleMode = function (value) { + this._castPlayer.sendMessage({ + options: { + ShuffleMode: value + }, + command: 'SetPlaylistShuffleMode' + }); + }; + ChromecastPlayer.prototype.toggleMute = function () { this._castPlayer.sendMessage({ diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index 241d3fba4..b607f0441 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -513,6 +513,10 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'] }); }; + SessionPlayer.prototype.getPlaylistShuffleMode = function () { + + }; + SessionPlayer.prototype.displayContent = function (options) { sendCommandByName(this, 'DisplayContent', options); diff --git a/src/scripts/serverNotifications.js b/src/scripts/serverNotifications.js index 2553c284f..77c51f33c 100644 --- a/src/scripts/serverNotifications.js +++ b/src/scripts/serverNotifications.js @@ -65,6 +65,9 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in case 'SetRepeatMode': playbackManager.setRepeatMode(cmd.Arguments.RepeatMode); break; + case 'SetPlaylistShuffleMode': + playbackManager.setPlaylistShuffleMode(cmd.Arguments.ShuffleMode); + break; case 'VolumeUp': inputManager.trigger('volumeup'); return; From 6aae85e99141521fc77322563642f54571744a1e Mon Sep 17 00:00:00 2001 From: ferferga Date: Mon, 22 Jun 2020 11:25:16 +0200 Subject: [PATCH 0063/1168] Rename 'Playlist' term to 'Queue' --- src/components/nowPlayingBar/nowPlayingBar.js | 16 ++++++------- src/components/playback/playbackmanager.js | 24 +++++++++---------- src/components/remotecontrol/remotecontrol.js | 16 ++++++------- src/plugins/chromecastPlayer/plugin.js | 10 ++++---- src/plugins/sessionPlayer/plugin.js | 6 ++--- src/scripts/serverNotifications.js | 4 ++-- 6 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 6fc526489..eb21f9044 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -181,10 +181,10 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', elem.querySelector('.btnShuffle').addEventListener('click', function () { if (currentPlayer) { - if (playbackManager.getPlaylistShuffleMode(currentPlayer) === 'Sorted') { - playbackManager.setPlaylistShuffleMode('Shuffle', currentPlayer); + if (playbackManager.getQueueShuffleMode(currentPlayer) === 'Sorted') { + playbackManager.setQueueShuffleMode('Shuffle', currentPlayer); } else { - playbackManager.setPlaylistShuffleMode('Sorted', currentPlayer); + playbackManager.setQueueShuffleMode('Sorted', currentPlayer); } } }); @@ -346,7 +346,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } updateRepeatModeDisplay(playState.RepeatMode); - onPlaylistShuffleModeChange(); + onQueueShuffleModeChange(); updatePlayerVolumeState(playState.IsMuted, playState.VolumeLevel); @@ -633,8 +633,8 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', updateRepeatModeDisplay(playbackManager.getRepeatMode(player)); } - function onPlaylistShuffleModeChange() { - let shuffleMode = playbackManager.getPlaylistShuffleMode(this); + function onQueueShuffleModeChange() { + let shuffleMode = playbackManager.getQueueShuffleMode(this); let context = nowPlayingBarElement; let toggleShuffleButton = context.querySelector('.btnShuffle'); @@ -750,7 +750,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', events.off(player, 'playbackstart', onPlaybackStart); events.off(player, 'statechange', onPlaybackStart); events.off(player, 'repeatmodechange', onRepeatModeChange); - events.off(player, 'shuffleplaylistmodechange', onPlaylistShuffleModeChange); + events.off(player, 'shufflequeuemodechange', onQueueShuffleModeChange); events.off(player, 'playbackstop', onPlaybackStopped); events.off(player, 'volumechange', onVolumeChanged); events.off(player, 'pause', onPlayPauseStateChanged); @@ -799,7 +799,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', events.on(player, 'playbackstart', onPlaybackStart); events.on(player, 'statechange', onPlaybackStart); events.on(player, 'repeatmodechange', onRepeatModeChange); - events.on(player, 'shuffleplaylistmodechange', onPlaylistShuffleModeChange); + events.on(player, 'shufflequeuemodechange', onQueueShuffleModeChange); events.on(player, 'playbackstop', onPlaybackStopped); events.on(player, 'volumechange', onVolumeChanged); events.on(player, 'pause', onPlayPauseStateChanged); diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index ad1b156d6..4d58e85cf 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -2097,7 +2097,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla state.PlayState.IsMuted = player.isMuted(); state.PlayState.IsPaused = player.paused(); state.PlayState.RepeatMode = self.getRepeatMode(player); - state.PlayState.ShuffleMode = self.getPlaylistShuffleMode(player); + state.PlayState.ShuffleMode = self.getQueueShuffleMode(player); state.PlayState.MaxStreamingBitrate = self.getMaxStreamingBitrate(player); state.PlayState.PositionTicks = getCurrentTicks(player); @@ -3305,9 +3305,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla sendProgressUpdate(player, 'repeatmodechange'); } - function onShufflePlaylistModeChange() { + function onShuffleQueueModeChange() { var player = this; - sendProgressUpdate(player, 'shuffleplaylistmodechange'); + sendProgressUpdate(player, 'shufflequeuemodechange'); } function onPlaylistItemMove(e) { @@ -3364,7 +3364,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.on(player, 'unpause', onPlaybackUnpause); events.on(player, 'volumechange', onPlaybackVolumeChange); events.on(player, 'repeatmodechange', onRepeatModeChange); - events.on(player, 'shuffleplaylistmodechange', onShufflePlaylistModeChange); + events.on(player, 'shufflequeuemodechange', onShuffleQueueModeChange); events.on(player, 'playlistitemmove', onPlaylistItemMove); events.on(player, 'playlistitemremove', onPlaylistItemRemove); events.on(player, 'playlistitemadd', onPlaylistItemAdd); @@ -3377,7 +3377,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.on(player, 'unpause', onPlaybackUnpause); events.on(player, 'volumechange', onPlaybackVolumeChange); events.on(player, 'repeatmodechange', onRepeatModeChange); - events.on(player, 'shuffleplaylistmodechange', onShufflePlaylistModeChange); + events.on(player, 'shufflequeuemodechange', onShuffleQueueModeChange); events.on(player, 'playlistitemmove', onPlaylistItemMove); events.on(player, 'playlistitemremove', onPlaylistItemRemove); events.on(player, 'playlistitemadd', onPlaylistItemAdd); @@ -3886,7 +3886,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', - 'SetPlaylistShuffleMode', + 'SetQueueShuffleMode', 'PlayMediaSource', 'PlayTrailers' ]; @@ -3941,7 +3941,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return this._playQueueManager.getRepeatMode(); }; - PlaybackManager.prototype.setPlaylistShuffleMode = function (value, player) { + PlaybackManager.prototype.setQueueShuffleMode = function (value, player) { player = player || this._currentPlayer; if (player && !enableLocalPlaylistManagement(player)) { @@ -3949,14 +3949,14 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } this._playQueueManager.setShuffleMode(value); - events.trigger(player, 'shuffleplaylistmodechange'); + events.trigger(player, 'shufflequeuemodechange'); }; - PlaybackManager.prototype.getPlaylistShuffleMode = function (player) { + PlaybackManager.prototype.getQueueShuffleMode = function (player) { player = player || this._currentPlayer; if (player && !enableLocalPlaylistManagement(player)) { - return player.getPlaylistShuffleMode(); + return player.getQueueShuffleMode(); } return this._playQueueManager.getShuffleMode(); @@ -4030,8 +4030,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla case 'SetRepeatMode': this.setRepeatMode(cmd.Arguments.RepeatMode, player); break; - case 'SetPlaylistShuffleMode': - this.setPlaylistShuffleMode(cmd.Arguments.ShuffleMode, player); + case 'SetQueueShuffleMode': + this.setQueueShuffleMode(cmd.Arguments.ShuffleMode, player); break; case 'VolumeUp': this.volumeUp(player); diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index c31d57a74..a671bf5af 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -328,7 +328,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } updateRepeatModeDisplay(playState.RepeatMode); - onShufflePlaylistModeChange(); + onShuffleQueueModeChange(); updateNowPlayingInfo(context, state); } @@ -498,8 +498,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL updateRepeatModeDisplay(playbackManager.getRepeatMode(player)); } - function onShufflePlaylistModeChange() { - let shuffleMode = playbackManager.getPlaylistShuffleMode(this); + function onShuffleQueueModeChange() { + let shuffleMode = playbackManager.getQueueShuffleMode(this); let context = dlg; let shuffleButton = context.querySelector('.btnShuffle'); if ('Sorted' === shuffleMode) { @@ -571,7 +571,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL events.off(player, 'playbackstart', onPlaybackStart); events.off(player, 'statechange', onStateChanged); events.off(player, 'repeatmodechange', onRepeatModeChange); - events.off(player, 'shuffleplaylistmodechange', onShufflePlaylistModeChange); + events.off(player, 'shufflequeuemodechange', onShuffleQueueModeChange); events.off(player, 'playlistitemremove', onPlaylistItemRemoved); events.off(player, 'playlistitemmove', onPlaylistUpdate); events.off(player, 'playbackstop', onPlaybackStopped); @@ -592,7 +592,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL events.on(player, 'playbackstart', onPlaybackStart); events.on(player, 'statechange', onStateChanged); events.on(player, 'repeatmodechange', onRepeatModeChange); - events.on(player, 'shuffleplaylistmodechange', onShufflePlaylistModeChange); + events.on(player, 'shufflequeuemodechange', onShuffleQueueModeChange); events.on(player, 'playlistitemremove', onPlaylistItemRemoved); events.on(player, 'playlistitemmove', onPlaylistUpdate); events.on(player, 'playbackstop', onPlaybackStopped); @@ -695,10 +695,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL }); context.querySelector('.btnShuffle').addEventListener('click', function () { if (currentPlayer) { - if (playbackManager.getPlaylistShuffleMode(currentPlayer) === 'Sorted') { - playbackManager.setPlaylistShuffleMode('Shuffle', currentPlayer); + if (playbackManager.getQueueShuffleMode(currentPlayer) === 'Sorted') { + playbackManager.setQueueShuffleMode('Shuffle', currentPlayer); } else { - playbackManager.setPlaylistShuffleMode('Sorted', currentPlayer); + playbackManager.setQueueShuffleMode('Sorted', currentPlayer); } } }); diff --git a/src/plugins/chromecastPlayer/plugin.js b/src/plugins/chromecastPlayer/plugin.js index 22242959f..0809fb82c 100644 --- a/src/plugins/chromecastPlayer/plugin.js +++ b/src/plugins/chromecastPlayer/plugin.js @@ -572,7 +572,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' bindEventForRelay(instance, 'unpause'); bindEventForRelay(instance, 'volumechange'); bindEventForRelay(instance, 'repeatmodechange'); - bindEventForRelay(instance, 'shuffleplaylistmodechange'); + bindEventForRelay(instance, 'shufflequeuemodechange'); events.on(instance._castPlayer, 'playstatechange', function (e, data) { @@ -652,7 +652,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' 'SetSubtitleStreamIndex', 'DisplayContent', 'SetRepeatMode', - 'SetPlaylistShuffleMode', + 'SetQueueShuffleMode', 'EndSession', 'PlayMediaSource', 'PlayTrailers' @@ -866,7 +866,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' return state.RepeatMode; }; - ChromecastPlayer.prototype.getPlaylistShuffleMode = function () { + ChromecastPlayer.prototype.getQueueShuffleMode = function () { var state = this.lastPlayerData || {}; state = state.PlayState || {}; return state.ShuffleMode; @@ -892,12 +892,12 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }); }; - ChromecastPlayer.prototype.setPlaylistShuffleMode = function (value) { + ChromecastPlayer.prototype.setQueueShuffleMode = function (value) { this._castPlayer.sendMessage({ options: { ShuffleMode: value }, - command: 'SetPlaylistShuffleMode' + command: 'SetQueueShuffleMode' }); }; diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index b607f0441..5ed07bb4f 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -506,14 +506,14 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'] }); }; - SessionPlayer.prototype.setPlaylistShuffleMode = function (mode) { + SessionPlayer.prototype.setQueueShuffleMode = function (mode) { - sendCommandByName(this, 'SetPlaylistShuffleMode', { + sendCommandByName(this, 'SetQueueShuffleMode', { ShuffleMode: mode }); }; - SessionPlayer.prototype.getPlaylistShuffleMode = function () { + SessionPlayer.prototype.getQueueShuffleMode = function () { }; diff --git a/src/scripts/serverNotifications.js b/src/scripts/serverNotifications.js index 77c51f33c..c1d9c95e9 100644 --- a/src/scripts/serverNotifications.js +++ b/src/scripts/serverNotifications.js @@ -65,8 +65,8 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in case 'SetRepeatMode': playbackManager.setRepeatMode(cmd.Arguments.RepeatMode); break; - case 'SetPlaylistShuffleMode': - playbackManager.setPlaylistShuffleMode(cmd.Arguments.ShuffleMode); + case 'SetQueueShuffleMode': + playbackManager.setQueueShuffleMode(cmd.Arguments.ShuffleMode); break; case 'VolumeUp': inputManager.trigger('volumeup'); From d13e1acf8de3c03d27992014a616425031fa650d Mon Sep 17 00:00:00 2001 From: ferferga Date: Mon, 22 Jun 2020 12:41:22 +0200 Subject: [PATCH 0064/1168] Fix 'undefined' on Chromecast and cleanup on nowPlayingBar.js --- src/components/nowPlayingBar/nowPlayingBar.js | 36 +++++++++---------- src/components/playback/playbackmanager.js | 2 +- src/components/remotecontrol/remotecontrol.js | 14 ++++++-- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index eb21f9044..07cdaac4f 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -457,15 +457,6 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } } - function getTextActionButton(item, text) { - - if (!text) { - text = itemHelper.getDisplayName(item); - } - - return `${text}`; - } - function seriesImageUrl(item, options) { if (!item) { @@ -541,18 +532,25 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', if (textLines.length > 1) { textLines[1].secondary = true; } - nowPlayingTextElement.innerHTML = textLines.map(function (nowPlayingName) { - var cssClass = nowPlayingName.secondary ? ' class="nowPlayingBarSecondaryText"' : ''; - - if (nowPlayingName.item) { - var nowPlayingText = getTextActionButton(nowPlayingName.item, nowPlayingName.text); - return `
${nowPlayingText}
`; + if (textLines) { + nowPlayingTextElement.innerHTML = ''; + let itemText = document.createElement('div'); + let secondaryText = document.createElement('div'); + secondaryText.classList.add('nowPlayingBarSecondaryText'); + if (textLines[0].text) { + let text = document.createElement('a'); + text.innerHTML = textLines[0].text; + itemText.appendChild(text); } - - return `
${nowPlayingText}
`; - - }).join(''); + if (textLines[1].text) { + let text = document.createElement('a'); + text.innerHTML = textLines[1].text; + secondaryText.appendChild(text); + } + nowPlayingTextElement.appendChild(itemText); + nowPlayingTextElement.appendChild(secondaryText); + } var imgHeight = 70; diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 4d58e85cf..38ce9bf9f 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3945,7 +3945,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla player = player || this._currentPlayer; if (player && !enableLocalPlaylistManagement(player)) { - return player.setShuffleMode(value); + return player.setQueueShuffleMode(value); } this._playQueueManager.setShuffleMode(value); diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index a671bf5af..784e7ff5b 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -120,9 +120,9 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (item.Type == 'Audio' || item.MediaStreams[0].Type == 'Audio') { var songName = item.Name; if (item.Album != null && item.Artists != null) { + var artistsSeries = ''; var albumName = item.Album; if (item.ArtistItems != null) { - var artistsSeries = ''; for (let artist of item.ArtistItems) { let artistName = artist.Name; let artistId = artist.Id; @@ -131,8 +131,18 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL artistsSeries += ', '; } } - context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries; + } else if (item.Artists) { + // For some reason, Chromecast Player doesn't return a item.ArtistItems object, so we need to fallback + // to normal item.Artists item. + // TODO: Normalise fields returned by all the players + for (let artist of item.Artists) { + artistsSeries += `${artist}`; + if (artist !== item.Artists.slice(-1)[0]) { + artistsSeries += ', '; + } + } } + context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries; context.querySelector('.nowPlayingAlbum').innerHTML = '${albumName}`; } context.querySelector('.nowPlayingSongName').innerHTML = songName; From f6a9f4679ae14f81b664d63efd09918c977583d3 Mon Sep 17 00:00:00 2001 From: ferferga Date: Mon, 22 Jun 2020 17:37:06 +0200 Subject: [PATCH 0065/1168] Style cleanup, address suggestions and placeholders for songs in cardBuilder and listView --- src/assets/css/flexstyles.css | 4 + src/components/cardbuilder/card.css | 3 +- src/components/cardbuilder/cardBuilder.js | 3 + src/components/listview/listview.js | 96 ++++++++++--------- .../nowPlayingBar/nowPlayingBar.css | 20 ++-- src/components/nowPlayingBar/nowPlayingBar.js | 17 ++-- .../remotecontrol/remotecontrol.css | 87 ++++++++++------- src/components/remotecontrol/remotecontrol.js | 20 ++-- src/nowplaying.html | 21 ++++ src/themes/appletv/theme.css | 2 +- src/themes/blueradiance/theme.css | 2 +- src/themes/dark/theme.css | 2 +- src/themes/light/theme.css | 2 +- src/themes/purplehaze/theme.css | 2 +- src/themes/wmc/theme.css | 2 +- 15 files changed, 167 insertions(+), 116 deletions(-) diff --git a/src/assets/css/flexstyles.css b/src/assets/css/flexstyles.css index 2f3a386bf..429ed7a65 100644 --- a/src/assets/css/flexstyles.css +++ b/src/assets/css/flexstyles.css @@ -42,6 +42,10 @@ justify-content: flex-end; } +.justify-content-space-between { + justify-content: space-between; +} + .flex-wrap-wrap { flex-wrap: wrap; } diff --git a/src/components/cardbuilder/card.css b/src/components/cardbuilder/card.css index c24fcf6ba..f02f1de6b 100644 --- a/src/components/cardbuilder/card.css +++ b/src/components/cardbuilder/card.css @@ -167,8 +167,9 @@ button::-moz-focus-inner { position: relative; background-clip: content-box !important; color: inherit; +} - /* This is only needed for scalable cards */ +.cardImageContainer.cardScalable { height: 100%; contain: strict; } diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index e540a4021..37c0e2696 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -1537,8 +1537,11 @@ import 'programStyles'; case 'MusicAlbum': return ''; case 'MusicArtist': + return ''; case 'Person': return ''; + case 'Audio': + return ''; case 'Movie': return ''; case 'Series': diff --git a/src/components/listview/listview.js b/src/components/listview/listview.js index 4ce8526c9..1bbde6fdb 100644 --- a/src/components/listview/listview.js +++ b/src/components/listview/listview.js @@ -1,4 +1,4 @@ -define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutManager', 'globalize', 'datetime', 'apphost', 'css!./listview', 'emby-ratingbutton', 'emby-playstatebutton'], function (itemHelper, mediaInfo, indicators, connectionManager, layoutManager, globalize, datetime, appHost) { +define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutManager', 'globalize', 'datetime', 'cardBuilder', 'css!./listview', 'emby-ratingbutton', 'emby-playstatebutton'], function (itemHelper, mediaInfo, indicators, connectionManager, layoutManager, globalize, datetime, cardBuilder) { 'use strict'; function getIndex(item, options) { @@ -270,54 +270,56 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan if (options.image !== false) { let imgData = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth); + let imgUrl; + let blurhash; if (imgData) { - let imgUrl = imgData.url; - let blurhash = imgData.blurhash; - let imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage'; - - if (isLargeStyle && layoutManager.tv) { - imageClass += ' listItemImage-large-tv'; - } - - var playOnImageClick = options.imagePlayButton && !layoutManager.tv; - - if (!clickEntireItem) { - imageClass += ' itemAction'; - } - - var imageAction = playOnImageClick ? 'resume' : action; - - let blurhashAttrib = ''; - if (blurhash && blurhash.length > 0) { - blurhashAttrib = 'data-blurhash="' + blurhash + '"'; - } - - if (imgUrl) { - html += '
'; - } else { - html += '
'; - } - - var indicatorsHtml = ''; - indicatorsHtml += indicators.getPlayedIndicatorHtml(item); - - if (indicatorsHtml) { - html += '
' + indicatorsHtml + '
'; - } - - if (playOnImageClick) { - html += ''; - } - - var progressHtml = indicators.getProgressBarHtml(item, { - containerClass: 'listItemProgressBar' - }); - - if (progressHtml) { - html += progressHtml; - } - html += '
'; + imgUrl = imgData.url; + blurhash = imgData.blurhash; } + let imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage'; + + if (isLargeStyle && layoutManager.tv) { + imageClass += ' listItemImage-large-tv'; + } + + var playOnImageClick = options.imagePlayButton && !layoutManager.tv; + + if (!clickEntireItem) { + imageClass += ' itemAction'; + } + + var imageAction = playOnImageClick ? 'resume' : action; + + let blurhashAttrib = ''; + if (blurhash && blurhash.length > 0) { + blurhashAttrib = 'data-blurhash="' + blurhash + '"'; + } + + if (imgUrl) { + html += '
'; + } else { + html += '
' + cardBuilder.getDefaultText(item, options); + } + + var indicatorsHtml = ''; + indicatorsHtml += indicators.getPlayedIndicatorHtml(item); + + if (indicatorsHtml) { + html += '
' + indicatorsHtml + '
'; + } + + if (playOnImageClick) { + html += ''; + } + + var progressHtml = indicators.getProgressBarHtml(item, { + containerClass: 'listItemProgressBar' + }); + + if (progressHtml) { + html += progressHtml; + } + html += '
'; } if (options.showIndexNumberLeft) { diff --git a/src/components/nowPlayingBar/nowPlayingBar.css b/src/components/nowPlayingBar/nowPlayingBar.css index a2d5b4479..c22429eed 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.css +++ b/src/components/nowPlayingBar/nowPlayingBar.css @@ -133,10 +133,7 @@ .toggleRepeatButton { display: none !important; } -} - -@media all and (max-width: 66em) { - .btnShuffle { + .nowPlayingBar .btnShuffleQueue { display: none !important; } } @@ -152,18 +149,21 @@ } } +.layout-mobile .nowPlayingBarRight button:not(.playPauseButton, .nextTrackButton) { + display: none; +} + +.layout-mobile .nowPlayingBarRight input, +.layout-mobile .nowPlayingBarRight div { + display: none; +} + @media all and (max-width: 56em) { .nowPlayingBarCenter { display: none !important; } } -@media all and (min-width: 56em) { - .nowPlayingBarRight .playPauseButton { - display: none; - } -} - @media all and (max-width: 60em) { .nowPlayingBarRight .nowPlayingBarVolumeSliderContainer { display: none !important; diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 07cdaac4f..f0b585e9d 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -63,7 +63,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', html += '
'; html += ''; - html += ''; + html += ''; html += '
'; html += '
'; @@ -179,7 +179,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } }); - elem.querySelector('.btnShuffle').addEventListener('click', function () { + elem.querySelector('.btnShuffleQueue').addEventListener('click', function () { if (currentPlayer) { if (playbackManager.getQueueShuffleMode(currentPlayer) === 'Sorted') { playbackManager.setQueueShuffleMode('Shuffle', currentPlayer); @@ -290,7 +290,8 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', nowPlayingBarElement = parentContainer.querySelector('.nowPlayingBar'); if (layoutManager.mobile) { - hideButton(nowPlayingBarElement.querySelector('.shuffle')); + hideButton(nowPlayingBarElement.querySelector('.btnShuffleQueue')); + hideButton(nowPlayingBarElement.querySelector('.nowPlayingBarCenter')); } if (browser.safari && browser.slow) { @@ -634,12 +635,12 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', function onQueueShuffleModeChange() { let shuffleMode = playbackManager.getQueueShuffleMode(this); let context = nowPlayingBarElement; - let toggleShuffleButton = context.querySelector('.btnShuffle'); + let toggleShuffleButton = context.querySelector('.btnShuffleQueue'); - if ('Sorted' === shuffleMode) { - toggleShuffleButton.classList.remove('shuffleButton-active'); - } else if ('Shuffle' === shuffleMode) { - toggleShuffleButton.classList.add('shuffleButton-active'); + if (shuffleMode === 'Sorted') { + toggleShuffleButton.classList.remove('shuffleQueue-active'); + } else if (shuffleMode === 'Shuffle') { + toggleShuffleButton.classList.add('shuffleQueue-active'); } } diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index 6dbd3b716..3fd0ab097 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -175,10 +175,6 @@ background: rgba(0, 0, 0, 0) !important; } -.layout-mobile .btnShuffle { - display: unset !important; -} - .layout-mobile .playlistSection .playlist, .layout-mobile .playlistSection .contextMenu { position: absolute; @@ -202,62 +198,82 @@ padding-right: 7.3%; } -.playlistSectionButton:not(>.layout-mobile) { - background: unset !important; +.layout-desktop .playlistSectionButton, +.layout-tv .playlistSectionButton { + background: none; } -.nowPlayingPlaylist:not(>.layout-mobile) { - background: unset !important; +.layout-desktop .nowPlayingPlaylist, +.layout-tv .nowPlayingPlaylist { + background: none; } .layout-mobile .playlistSectionButton .btnTogglePlaylist { font-size: larger; margin: 0; - padding-left: 0; } .layout-mobile .playlistSectionButton .btnSavePlaylist { margin: 0; padding-right: 0; - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - justify-content: flex-end; + border-radius: 0; +} + +.layout-mobile .playlistSectionButton .volumecontrol { + margin: 0; + padding-right: 0; border-radius: 0; } .layout-mobile .playlistSectionButton .btnToggleContextMenu { font-size: larger; margin: 0; - padding-right: 0; +} + +.layout-mobile .nowPlayingSecondaryButtons .btnShuffleQueue { + display: none; +} + +.layout-mobile .nowPlayingSecondaryButtons .volumecontrol { + display: none; +} + +.layout-mobile .nowPlayingSecondaryButtons .btnRepeat { + display: none; +} + +.layout-desktop .nowPlayingInfoButtons .btnRepeat, +.layout-tv .nowPlayingInfoButtons .btnRepeat { + display: none; +} + +.layout-desktop .nowPlayingInfoButtons .btnShuffleQueue, +.layout-tv .nowPlayingInfoButtons .btnShuffleQueue{ + display: none; +} + +.layout-desktop .playlistSectionButton .volumecontrol, +.layout-tv .playlistSectionButton .volumecontrol { + display: none; +} + +.nowPlayingSecondaryButtons { -webkit-box-flex: 1; -webkit-flex-grow: 1; flex-grow: 1; -webkit-box-pack: end; -webkit-justify-content: flex-end; justify-content: flex-end; - border-radius: 0; +} + +.nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle { + display: none; } @media all and (min-width: 63em) { .nowPlayingPage { padding: 8em 0 0 0 !important; } - - .nowPlayingSecondaryButtons { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - justify-content: flex-end; - } - - .nowPlayingPageUserDataButtonsTitle { - display: none !important; - } } @media all and (min-width: 80em) { @@ -275,6 +291,10 @@ flex-direction: column; } + .nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle { + display: unset; + } + .nowPlayingInfoContainer { -webkit-box-orient: vertical !important; -webkit-box-direction: normal !important; @@ -362,7 +382,7 @@ font-size: smaller; } - .nowPlayingInfoButtons .btnShuffle { + .nowPlayingInfoButtons .btnShuffleQueue { position: absolute; right: 0; margin-right: 0; @@ -447,6 +467,10 @@ background-image: url(../../assets/img/equalizer.gif) !important; } +.playlistIndexIndicatorImage > * { + display: none; +} + .hideVideoButtons .videoButton { display: none; } @@ -456,7 +480,6 @@ } @media all and (max-width: 63em) { - .nowPlayingSecondaryButtons .nowPlayingPageUserDataButtons, .nowPlayingSecondaryButtons .repeatToggleButton, .nowPlayingInfoButtons .playlist .listItemMediaInfo, .nowPlayingInfoButtons .btnStop { diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 784e7ff5b..18a8f2005 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -511,11 +511,11 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function onShuffleQueueModeChange() { let shuffleMode = playbackManager.getQueueShuffleMode(this); let context = dlg; - let shuffleButton = context.querySelector('.btnShuffle'); + let shuffleButton = context.querySelector('.btnShuffleQueue'); if ('Sorted' === shuffleMode) { - shuffleButton.classList.remove('shuffleButton-active'); + shuffleButton.classList.remove('shuffleQueue-active'); } else if ('Shuffle' === shuffleMode) { - shuffleButton.classList.add('shuffleButton-active'); + shuffleButton.classList.add('shuffleQueue-active'); } onPlaylistUpdate(); } @@ -703,7 +703,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL playbackManager.fastForward(currentPlayer); } }); - context.querySelector('.btnShuffle').addEventListener('click', function () { + context.querySelector('.btnShuffleQueue').addEventListener('click', function () { if (currentPlayer) { if (playbackManager.getQueueShuffleMode(currentPlayer) === 'Sorted') { playbackManager.setQueueShuffleMode('Shuffle', currentPlayer); @@ -841,27 +841,23 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } function init(ownerView, context) { - let contextmenuHtml = ``; let volumecontrolHtml = '
'; volumecontrolHtml += ``; volumecontrolHtml += '
'; volumecontrolHtml += '
'; - let shuffleButtonHtml = ``; - let repeatButtonHtml = ``; let optionsSection = context.querySelector('.playlistSectionButton'); if (!layoutManager.mobile) { - context.querySelector('.nowPlayingSecondaryButtons').insertAdjacentHTML('beforeend', repeatButtonHtml + shuffleButtonHtml + volumecontrolHtml); - optionsSection.innerHTML += contextmenuHtml; + context.querySelector('.nowPlayingSecondaryButtons').insertAdjacentHTML('beforeend', volumecontrolHtml); optionsSection.classList.remove('align-items-center', 'justify-content-center'); optionsSection.classList.add('align-items-right', 'justify-content-flex-end'); context.querySelector('.playlist').classList.remove('hide'); context.querySelector('.btnSavePlaylist').classList.remove('hide'); } else { - optionsSection.innerHTML += volumecontrolHtml + contextmenuHtml; + optionsSection.querySelector('.btnTogglePlaylist').insertAdjacentHTML('afterend', volumecontrolHtml); optionsSection.classList.add('playlistSectionButtonTransparent'); context.querySelector('.btnTogglePlaylist').classList.remove('hide'); - context.querySelector('.nowPlayingInfoButtons').insertAdjacentHTML('afterbegin', repeatButtonHtml); - context.querySelector('.nowPlayingInfoButtons').insertAdjacentHTML('beforeend', shuffleButtonHtml); + context.querySelector('.playlistSectionButton').classList.remove('justify-content-center'); + context.querySelector('.playlistSectionButton').classList.add('justify-content-space-between'); } bindEvents(context); diff --git a/src/nowplaying.html b/src/nowplaying.html index 0c7688246..e42964707 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -29,6 +29,11 @@
+ + + +
@@ -72,6 +81,15 @@ + + + +
@@ -165,6 +183,9 @@ +

diff --git a/src/themes/appletv/theme.css b/src/themes/appletv/theme.css index 9d0ccdc9d..8b6b3e190 100644 --- a/src/themes/appletv/theme.css +++ b/src/themes/appletv/theme.css @@ -450,7 +450,7 @@ html { color: #4285f4; } -.shuffleButton-active { +.shuffleQueue-active { color: #4285f4 !important; } diff --git a/src/themes/blueradiance/theme.css b/src/themes/blueradiance/theme.css index 5215f4bb6..d8d7525d3 100644 --- a/src/themes/blueradiance/theme.css +++ b/src/themes/blueradiance/theme.css @@ -450,7 +450,7 @@ html { color: #4285f4; } -.shuffleButton-active { +.shuffleQueue-active { color: #4285f4 !important; } diff --git a/src/themes/dark/theme.css b/src/themes/dark/theme.css index 1e8a996c9..9491b2cae 100644 --- a/src/themes/dark/theme.css +++ b/src/themes/dark/theme.css @@ -421,7 +421,7 @@ html { color: #4285f4; } -.shuffleButton-active { +.shuffleQueue-active { color: #4285f4 !important; } diff --git a/src/themes/light/theme.css b/src/themes/light/theme.css index 82b2f5075..abb5a58fb 100644 --- a/src/themes/light/theme.css +++ b/src/themes/light/theme.css @@ -432,7 +432,7 @@ html { color: #4285f4; } -.shuffleButton-active { +.shuffleQueue-active { color: #4285f4 !important; } diff --git a/src/themes/purplehaze/theme.css b/src/themes/purplehaze/theme.css index 140969f65..ca8fe1fdf 100644 --- a/src/themes/purplehaze/theme.css +++ b/src/themes/purplehaze/theme.css @@ -547,7 +547,7 @@ a[data-role=button] { color: #4285f4; } -.shuffleButton-active { +.shuffleQueue-active { color: #4285f4 !important; } diff --git a/src/themes/wmc/theme.css b/src/themes/wmc/theme.css index a62d38297..7def8215f 100644 --- a/src/themes/wmc/theme.css +++ b/src/themes/wmc/theme.css @@ -430,7 +430,7 @@ html { color: #4285f4; } -.shuffleButton-active { +.shuffleQueue-active { color: #4285f4 !important; } From dba995c5f068169fc10bd6426afd7cd27a6bacab Mon Sep 17 00:00:00 2001 From: ferferga Date: Mon, 22 Jun 2020 17:55:28 +0200 Subject: [PATCH 0066/1168] Fix not usable buttons in desktop layout --- src/components/remotecontrol/remotecontrol.js | 53 +++++++++++-------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 18a8f2005..6626d83c4 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -354,17 +354,19 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function updateRepeatModeDisplay(repeatMode) { var context = dlg; - var toggleRepeatButton = context.querySelector('.repeatToggleButton'); + let toggleRepeatButtons = context.querySelectorAll('.repeatToggleButton'); - if ('RepeatAll' == repeatMode) { - toggleRepeatButton.innerHTML = ""; - toggleRepeatButton.classList.add('repeatButton-active'); - } else if ('RepeatOne' == repeatMode) { - toggleRepeatButton.innerHTML = ""; - toggleRepeatButton.classList.add('repeatButton-active'); - } else { - toggleRepeatButton.innerHTML = ""; - toggleRepeatButton.classList.remove('repeatButton-active'); + for (let toggleRepeatButton of toggleRepeatButtons) { + if ('RepeatAll' == repeatMode) { + toggleRepeatButton.innerHTML = ""; + toggleRepeatButton.classList.add('repeatButton-active'); + } else if ('RepeatOne' == repeatMode) { + toggleRepeatButton.innerHTML = ""; + toggleRepeatButton.classList.add('repeatButton-active'); + } else { + toggleRepeatButton.innerHTML = ""; + toggleRepeatButton.classList.remove('repeatButton-active'); + } } } @@ -511,11 +513,14 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function onShuffleQueueModeChange() { let shuffleMode = playbackManager.getQueueShuffleMode(this); let context = dlg; - let shuffleButton = context.querySelector('.btnShuffleQueue'); - if ('Sorted' === shuffleMode) { - shuffleButton.classList.remove('shuffleQueue-active'); - } else if ('Shuffle' === shuffleMode) { - shuffleButton.classList.add('shuffleQueue-active'); + let shuffleButtons = context.querySelectorAll('.btnShuffleQueue'); + + for (let shuffleButton of shuffleButtons) { + if ('Sorted' === shuffleMode) { + shuffleButton.classList.remove('shuffleQueue-active'); + } else if ('Shuffle' === shuffleMode) { + shuffleButton.classList.add('shuffleQueue-active'); + } } onPlaylistUpdate(); } @@ -703,15 +708,17 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL playbackManager.fastForward(currentPlayer); } }); - context.querySelector('.btnShuffleQueue').addEventListener('click', function () { - if (currentPlayer) { - if (playbackManager.getQueueShuffleMode(currentPlayer) === 'Sorted') { - playbackManager.setQueueShuffleMode('Shuffle', currentPlayer); - } else { - playbackManager.setQueueShuffleMode('Sorted', currentPlayer); + for (let shuffleButton of context.querySelectorAll('.btnShuffleQueue')) { + shuffleButton.addEventListener('click', function () { + if (currentPlayer) { + if (playbackManager.getQueueShuffleMode(currentPlayer) === 'Sorted') { + playbackManager.setQueueShuffleMode('Shuffle', currentPlayer); + } else { + playbackManager.setQueueShuffleMode('Sorted', currentPlayer); + } } - } - }); + }); + } context.querySelector('.btnPreviousTrack').addEventListener('click', function (e) { if (currentPlayer) { From 3e1d24d9a25a63aa2b1aa2a4ad5c142d699204a0 Mon Sep 17 00:00:00 2001 From: ferferga Date: Mon, 22 Jun 2020 18:02:45 +0200 Subject: [PATCH 0067/1168] Don't shuffle first item --- src/components/playback/playqueuemanager.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/playback/playqueuemanager.js b/src/components/playback/playqueuemanager.js index e26a738a0..4eac7d7c7 100644 --- a/src/components/playback/playqueuemanager.js +++ b/src/components/playback/playqueuemanager.js @@ -60,16 +60,22 @@ define([], function () { PlayQueueManager.prototype.shufflePlaylist = function () { this._sortedPlaylist = []; + let currentPlaylistItem = this._playlist[this.getCurrentPlaylistIndex()]; for (let item of this._playlist) { this._sortedPlaylist.push(item); } for (let i = this._playlist.length - 1; i > 0; i--) { + if (this._playlist[i] === currentPlaylistItem) { + this._playlist.splice(i, 1); + continue; + } const j = Math.floor(Math.random() * i); const temp = this._playlist[i]; this._playlist[i] = this._playlist[j]; this._playlist[j] = temp; } + this._playlist.unshift(currentPlaylistItem); this._shuffleMode = 'Shuffle'; }; From ae8d06533c9a902a120c57ab896aed0d3372187f Mon Sep 17 00:00:00 2001 From: ferferga Date: Tue, 23 Jun 2020 16:55:37 +0200 Subject: [PATCH 0068/1168] Add space-between in desktop and hide duplicate heart on mobile --- src/components/remotecontrol/remotecontrol.css | 4 ++++ src/nowplaying.html | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index 0386981bf..69f7025d6 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -254,6 +254,10 @@ display: none; } +.layout-mobile .nowPlayingPageUserDataButtons { + display: none; +} + @media all and (min-width: 63em) { .nowPlayingPage { padding: 8em 0 0 0 !important; diff --git a/src/nowplaying.html b/src/nowplaying.html index e42964707..56610ca6e 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -26,7 +26,7 @@
-
+
From b7714eea14d78088dd3c86d123af1989761f1290 Mon Sep 17 00:00:00 2001 From: ferferga Date: Tue, 23 Jun 2020 19:09:22 +0200 Subject: [PATCH 0069/1168] Address review comments --- src/components/cardbuilder/card.css | 2 +- src/components/cardbuilder/cardBuilder.js | 1 - src/components/nowPlayingBar/nowPlayingBar.js | 81 +++++++++++-------- src/components/playback/playbackmanager.js | 32 ++++++-- src/components/playback/playqueuemanager.js | 39 ++++++--- .../remotecontrol/remotecontrol.css | 1 - src/components/remotecontrol/remotecontrol.js | 61 ++++++++------ src/plugins/chromecastPlayer/plugin.js | 4 +- src/plugins/sessionPlayer/plugin.js | 2 +- src/scripts/serverNotifications.js | 2 +- 10 files changed, 138 insertions(+), 87 deletions(-) diff --git a/src/components/cardbuilder/card.css b/src/components/cardbuilder/card.css index f02f1de6b..75943a0c4 100644 --- a/src/components/cardbuilder/card.css +++ b/src/components/cardbuilder/card.css @@ -169,7 +169,7 @@ button::-moz-focus-inner { color: inherit; } -.cardImageContainer.cardScalable { +.cardScalable .cardImageContainer { height: 100%; contain: strict; } diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index f594a3daf..b08e5024a 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -1534,7 +1534,6 @@ import 'programStyles'; case 'MusicAlbum': return ''; case 'MusicArtist': - return ''; case 'Person': return ''; case 'Audio': diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index f0b585e9d..b8a2a5082 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -165,7 +165,8 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', return; } playbackManager.seekPercent(0, currentPlayer); - // This is done automatically by playbackManager, however, setting this here gives instant visual feedback + // This is done automatically by playbackManager, however, setting this here gives instant visual feedback. + // TODO: Check why seekPercentage doesn't reflect the changes inmmediately, so we can remove this workaround. positionSlider.value = 0; } else { playbackManager.previousTrack(currentPlayer); @@ -181,11 +182,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', elem.querySelector('.btnShuffleQueue').addEventListener('click', function () { if (currentPlayer) { - if (playbackManager.getQueueShuffleMode(currentPlayer) === 'Sorted') { - playbackManager.setQueueShuffleMode('Shuffle', currentPlayer); - } else { - playbackManager.setQueueShuffleMode('Sorted', currentPlayer); - } + playbackManager.toggleQueueShuffleMode(currentPlayer); } }); @@ -367,16 +364,23 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', function updateRepeatModeDisplay(repeatMode) { toggleRepeatButtonIcon.classList.remove('repeat', 'repeat_one'); + const cssClass = 'repeatButton-active'; - if (repeatMode === 'RepeatAll') { - toggleRepeatButtonIcon.classList.add('repeat'); - toggleRepeatButton.classList.add('repeatButton-active'); - } else if (repeatMode === 'RepeatOne') { - toggleRepeatButtonIcon.classList.add('repeat_one'); - toggleRepeatButton.classList.add('repeatButton-active'); - } else { - toggleRepeatButtonIcon.classList.add('repeat'); - toggleRepeatButton.classList.remove('repeatButton-active'); + switch (repeatMode) { + case 'RepeatAll': + toggleRepeatButtonIcon.classList.add('repeat'); + toggleRepeatButton.classList.add(cssClass); + break; + case 'RepeatOne': + toggleRepeatButtonIcon.classList.add('repeat_one'); + toggleRepeatButton.classList.add(cssClass); + break; + case 'RepeatNone': + toggleRepeatButtonIcon.classList.add('repeat'); + toggleRepeatButton.classList.remove(cssClass); + break; + default: + throw new TypeError('invalid value for repeatMode'); } } @@ -530,24 +534,26 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', var nowPlayingItem = state.NowPlayingItem; var textLines = nowPlayingItem ? nowPlayingHelper.getNowPlayingNames(nowPlayingItem) : []; - if (textLines.length > 1) { - textLines[1].secondary = true; - } - + nowPlayingTextElement.innerHTML = ''; if (textLines) { - nowPlayingTextElement.innerHTML = ''; - let itemText = document.createElement('div'); let secondaryText = document.createElement('div'); secondaryText.classList.add('nowPlayingBarSecondaryText'); - if (textLines[0].text) { - let text = document.createElement('a'); - text.innerHTML = textLines[0].text; - itemText.appendChild(text); + let itemText = document.createElement('div'); + if (textLines.length > 1) { + textLines[1].secondary = true; + if (textLines[1].text) { + let text = document.createElement('a'); + text.innerHTML = textLines[1].text; + secondaryText.appendChild(text); + } } - if (textLines[1].text) { - let text = document.createElement('a'); - text.innerHTML = textLines[1].text; - secondaryText.appendChild(text); + + if (textLines[0].text) { + if (textLines[0].text) { + let text = document.createElement('a'); + text.innerHTML = textLines[0].text; + itemText.appendChild(text); + } } nowPlayingTextElement.appendChild(itemText); nowPlayingTextElement.appendChild(secondaryText); @@ -586,11 +592,11 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', var userData = item.UserData || {}; var likes = userData.Likes == null ? '' : userData.Likes; if (!layoutManager.mobile) { - let contextButton = document.querySelector('.nowPlayingBar').querySelector('.btnToggleContextMenu'); + let contextButton = nowPlayingBarElement.querySelector('.btnToggleContextMenu'); // We remove the previous event listener by replacing the item in each update event let contextButtonClone = contextButton.cloneNode(true); contextButton.parentNode.replaceChild(contextButtonClone, contextButton); - contextButton = document.querySelector('.nowPlayingBar').querySelector('.btnToggleContextMenu'); + contextButton = nowPlayingBarElement.querySelector('.btnToggleContextMenu'); let options = { play: false, queue: false, @@ -637,10 +643,15 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', let context = nowPlayingBarElement; let toggleShuffleButton = context.querySelector('.btnShuffleQueue'); - if (shuffleMode === 'Sorted') { - toggleShuffleButton.classList.remove('shuffleQueue-active'); - } else if (shuffleMode === 'Shuffle') { - toggleShuffleButton.classList.add('shuffleQueue-active'); + switch (shuffleMode) { + case 'Sorted': + toggleShuffleButton.classList.remove('shuffleQueue-active'); + break; + case 'Shuffle': + toggleShuffleButton.classList.add('shuffleQueue-active'); + break; + default: + throw new TypeError('invalid value for shuffleMode'); } } diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 38ce9bf9f..3bd4be9c0 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3886,7 +3886,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', - 'SetQueueShuffleMode', + 'SetShuffleQueue', 'PlayMediaSource', 'PlayTrailers' ]; @@ -3941,9 +3941,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return this._playQueueManager.getRepeatMode(); }; - PlaybackManager.prototype.setQueueShuffleMode = function (value, player) { - - player = player || this._currentPlayer; + PlaybackManager.prototype.setQueueShuffleMode = function (value, player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.setQueueShuffleMode(value); } @@ -3952,9 +3950,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.trigger(player, 'shufflequeuemodechange'); }; - PlaybackManager.prototype.getQueueShuffleMode = function (player) { - - player = player || this._currentPlayer; + PlaybackManager.prototype.getQueueShuffleMode = function (player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.getQueueShuffleMode(); } @@ -3962,6 +3958,26 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return this._playQueueManager.getShuffleMode(); }; + PlaybackManager.prototype.toggleQueueShuffleMode = function (player = this._currentPlayer) { + let currentvalue; + if (player && !enableLocalPlaylistManagement(player)) { + currentvalue = player.getQueueShuffleMode(); + switch (currentvalue) { + case 'Shuffle': + player.setQueueShuffleMode('Sorted'); + break; + case 'Sorted': + player.setQueueShuffleMode('Shuffle'); + break; + default: + throw new TypeError('current value for shufflequeue is invalid'); + } + } else { + this._playQueueManager.toggleShuffleMode(); + } + events.trigger(player, 'shufflequeuemodechange'); + }; + PlaybackManager.prototype.trySetActiveDeviceName = function (name) { name = normalizeName(name); @@ -4030,7 +4046,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla case 'SetRepeatMode': this.setRepeatMode(cmd.Arguments.RepeatMode, player); break; - case 'SetQueueShuffleMode': + case 'SetShuffleQueue': this.setQueueShuffleMode(cmd.Arguments.ShuffleMode, player); break; case 'VolumeUp': diff --git a/src/components/playback/playqueuemanager.js b/src/components/playback/playqueuemanager.js index 4eac7d7c7..03f5246b8 100644 --- a/src/components/playback/playqueuemanager.js +++ b/src/components/playback/playqueuemanager.js @@ -60,16 +60,12 @@ define([], function () { PlayQueueManager.prototype.shufflePlaylist = function () { this._sortedPlaylist = []; - let currentPlaylistItem = this._playlist[this.getCurrentPlaylistIndex()]; - for (let item of this._playlist) { + for (const item of this._playlist) { this._sortedPlaylist.push(item); } + const currentPlaylistItem = this._playlist.splice(this.getCurrentPlaylistIndex(), 1)[0]; for (let i = this._playlist.length - 1; i > 0; i--) { - if (this._playlist[i] === currentPlaylistItem) { - this._playlist.splice(i, 1); - continue; - } const j = Math.floor(Math.random() * i); const temp = this._playlist[i]; this._playlist[i] = this._playlist[j]; @@ -216,7 +212,8 @@ define([], function () { }; PlayQueueManager.prototype.setRepeatMode = function (value) { - if (value === 'RepeatOne' || value === 'RepeatAll' || value === 'RepeatNone') { + const repeatModes = ['RepeatOne', 'RepeatAll', 'RepeatNone']; + if (repeatModes.includes(value)) { this._repeatMode = value; } else { throw new TypeError('invalid value provided for setRepeatMode'); @@ -228,12 +225,28 @@ define([], function () { }; PlayQueueManager.prototype.setShuffleMode = function (value) { - if (value === 'Sorted') { - this.sortShuffledPlaylist(); - } else if (value === 'Shuffle') { - this.shufflePlaylist(); - } else { - throw new TypeError('invalid value provided for setShuffleMode'); + switch (value) { + case 'Shuffle': + this.shufflePlaylist(); + break; + case 'Sorted': + this.sortShuffledPlaylist(); + break; + default: + throw new TypeError('invalid value provided to setShuffleMode'); + } + }; + + PlayQueueManager.prototype.toggleShuffleMode = function () { + switch (this._shuffleMode) { + case 'Shuffle': + this.setShuffleMode('Sorted'); + break; + case 'Sorted': + this.setShuffleMode('Shuffle'); + break; + default: + throw new TypeError('current value for shufflequeue is invalid'); } }; diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index 69f7025d6..d4511a9dd 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -208,7 +208,6 @@ .layout-mobile .playlistSectionButton .btnSavePlaylist { margin: 0; - padding-right: 0; border-radius: 0; } diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 6626d83c4..89598d09a 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -123,7 +123,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var artistsSeries = ''; var albumName = item.Album; if (item.ArtistItems != null) { - for (let artist of item.ArtistItems) { + for (const artist of item.ArtistItems) { let artistName = artist.Name; let artistId = artist.Id; artistsSeries += `${artistName}`; @@ -135,7 +135,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL // For some reason, Chromecast Player doesn't return a item.ArtistItems object, so we need to fallback // to normal item.Artists item. // TODO: Normalise fields returned by all the players - for (let artist of item.Artists) { + for (const artist of item.Artists) { artistsSeries += `${artist}`; if (artist !== item.Artists.slice(-1)[0]) { artistsSeries += ', '; @@ -176,7 +176,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL maxHeight: 300 * 2 }) : null; - console.debug('updateNowPlayingInfo'); let contextButton = context.querySelector('.btnToggleContextMenu'); // We remove the previous event listener by replacing the item in each update event let contextButtonClone = contextButton.cloneNode(true); @@ -355,18 +354,30 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function updateRepeatModeDisplay(repeatMode) { var context = dlg; let toggleRepeatButtons = context.querySelectorAll('.repeatToggleButton'); + const cssClass = 'repeatButton-active'; + let innHtml = ''; + let repeatOn = undefined; - for (let toggleRepeatButton of toggleRepeatButtons) { - if ('RepeatAll' == repeatMode) { - toggleRepeatButton.innerHTML = ""; - toggleRepeatButton.classList.add('repeatButton-active'); - } else if ('RepeatOne' == repeatMode) { - toggleRepeatButton.innerHTML = ""; - toggleRepeatButton.classList.add('repeatButton-active'); + switch (repeatMode) { + case 'RepeatAll': + break; + case 'RepeatOne': + innHtml = ''; + break; + case 'RepeatNone': + repeatOn = null; + break; + default: + throw new TypeError('invalid value for repeatMode'); + } + + for (const toggleRepeatButton of toggleRepeatButtons) { + if (repeatOn === null) { + toggleRepeatButton.classList.remove(cssClass); } else { - toggleRepeatButton.innerHTML = ""; - toggleRepeatButton.classList.remove('repeatButton-active'); + toggleRepeatButton.classList.add(cssClass); } + toggleRepeatButton.innerHTML = innHtml; } } @@ -516,10 +527,15 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL let shuffleButtons = context.querySelectorAll('.btnShuffleQueue'); for (let shuffleButton of shuffleButtons) { - if ('Sorted' === shuffleMode) { - shuffleButton.classList.remove('shuffleQueue-active'); - } else if ('Shuffle' === shuffleMode) { - shuffleButton.classList.add('shuffleQueue-active'); + switch (shuffleMode) { + case 'Sorted': + shuffleButton.classList.remove('shuffleQueue-active'); + break; + case 'Shuffle': + shuffleButton.classList.add('shuffleQueue-active'); + break; + default: + throw new TypeError('invalid shuffle mode'); } } onPlaylistUpdate(); @@ -708,14 +724,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL playbackManager.fastForward(currentPlayer); } }); - for (let shuffleButton of context.querySelectorAll('.btnShuffleQueue')) { + for (const shuffleButton of context.querySelectorAll('.btnShuffleQueue')) { shuffleButton.addEventListener('click', function () { if (currentPlayer) { - if (playbackManager.getQueueShuffleMode(currentPlayer) === 'Sorted') { - playbackManager.setQueueShuffleMode('Shuffle', currentPlayer); - } else { - playbackManager.setQueueShuffleMode('Sorted', currentPlayer); - } + playbackManager.toggleQueueShuffleMode(currentPlayer); } }); } @@ -728,7 +740,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL return; } playbackManager.seekPercent(0, currentPlayer); - // This is done automatically by playbackManager. However, setting this here gives instant visual feedback + // This is done automatically by playbackManager. However, setting this here gives instant visual feedback. + // TODO: Check why seekPercentage doesn't reflect the changes inmmediately, so we can remove this workaround. positionSlider.value = 0; } else { playbackManager.previousTrack(currentPlayer); @@ -794,7 +807,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } else { context.querySelector('.playlist').classList.add('hide'); context.querySelector('.btnSavePlaylist').classList.add('hide'); - if (showMuteButton && showVolumeSlider) { + if (showMuteButton || showVolumeSlider) { context.querySelector('.volumecontrol').classList.remove('hide'); } if (layoutManager.mobile) { diff --git a/src/plugins/chromecastPlayer/plugin.js b/src/plugins/chromecastPlayer/plugin.js index 0809fb82c..6384ce769 100644 --- a/src/plugins/chromecastPlayer/plugin.js +++ b/src/plugins/chromecastPlayer/plugin.js @@ -652,7 +652,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' 'SetSubtitleStreamIndex', 'DisplayContent', 'SetRepeatMode', - 'SetQueueShuffleMode', + 'SetShuffleQueue', 'EndSession', 'PlayMediaSource', 'PlayTrailers' @@ -897,7 +897,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' options: { ShuffleMode: value }, - command: 'SetQueueShuffleMode' + command: 'SetShuffleQueue' }); }; diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index 5ed07bb4f..6a266941d 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -508,7 +508,7 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'] SessionPlayer.prototype.setQueueShuffleMode = function (mode) { - sendCommandByName(this, 'SetQueueShuffleMode', { + sendCommandByName(this, 'SetShuffleQueue', { ShuffleMode: mode }); }; diff --git a/src/scripts/serverNotifications.js b/src/scripts/serverNotifications.js index c1d9c95e9..cddd2cf79 100644 --- a/src/scripts/serverNotifications.js +++ b/src/scripts/serverNotifications.js @@ -65,7 +65,7 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in case 'SetRepeatMode': playbackManager.setRepeatMode(cmd.Arguments.RepeatMode); break; - case 'SetQueueShuffleMode': + case 'SetShuffleQueue': playbackManager.setQueueShuffleMode(cmd.Arguments.ShuffleMode); break; case 'VolumeUp': From 78cdbbb14f4ab3ffb0dfafe5fbaa92101f17b53b Mon Sep 17 00:00:00 2001 From: ferferga Date: Tue, 23 Jun 2020 20:32:39 +0200 Subject: [PATCH 0070/1168] Remove item from sorted playlist when on shuffle mode and address review comments --- src/components/nowPlayingBar/nowPlayingBar.js | 14 ++++++++------ src/components/playback/playqueuemanager.js | 6 ++++++ src/components/remotecontrol/remotecontrol.js | 10 +++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index b8a2a5082..97227ca71 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -379,6 +379,8 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', toggleRepeatButtonIcon.classList.add('repeat'); toggleRepeatButton.classList.remove(cssClass); break; + case undefined: + break; default: throw new TypeError('invalid value for repeatMode'); } @@ -536,9 +538,9 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', var textLines = nowPlayingItem ? nowPlayingHelper.getNowPlayingNames(nowPlayingItem) : []; nowPlayingTextElement.innerHTML = ''; if (textLines) { + let itemText = document.createElement('div'); let secondaryText = document.createElement('div'); secondaryText.classList.add('nowPlayingBarSecondaryText'); - let itemText = document.createElement('div'); if (textLines.length > 1) { textLines[1].secondary = true; if (textLines[1].text) { @@ -549,11 +551,9 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } if (textLines[0].text) { - if (textLines[0].text) { - let text = document.createElement('a'); - text.innerHTML = textLines[0].text; - itemText.appendChild(text); - } + let text = document.createElement('a'); + text.innerHTML = textLines[0].text; + itemText.appendChild(text); } nowPlayingTextElement.appendChild(itemText); nowPlayingTextElement.appendChild(secondaryText); @@ -650,6 +650,8 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', case 'Shuffle': toggleShuffleButton.classList.add('shuffleQueue-active'); break; + case undefined: + break; default: throw new TypeError('invalid value for shuffleMode'); } diff --git a/src/components/playback/playqueuemanager.js b/src/components/playback/playqueuemanager.js index 03f5246b8..8ffefd6b8 100644 --- a/src/components/playback/playqueuemanager.js +++ b/src/components/playback/playqueuemanager.js @@ -155,6 +155,12 @@ define([], function () { var currentPlaylistItemId = this.getCurrentPlaylistItemId(); var isCurrentIndex = playlistItemIds.indexOf(currentPlaylistItemId) !== -1; + if (this._sortedPlaylist.length <= playlistItemIds.length) { + this._sortedPlaylist = this._sortedPlaylist.splice(0).filter(function (item) { + return playlistItemIds.indexOf(item.PlaylistItemId) === -1; + }); + } + this._playlist = playlist.filter(function (item) { return playlistItemIds.indexOf(item.PlaylistItemId) === -1; }); diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index b9c2c9eb8..36d703fd8 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -356,7 +356,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL let toggleRepeatButtons = context.querySelectorAll('.repeatToggleButton'); const cssClass = 'repeatButton-active'; let innHtml = ''; - let repeatOn = undefined; + let repeatOn = true; switch (repeatMode) { case 'RepeatAll': @@ -365,14 +365,16 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL innHtml = ''; break; case 'RepeatNone': - repeatOn = null; + repeatOn = false; + break; + case undefined: break; default: throw new TypeError('invalid value for repeatMode'); } for (const toggleRepeatButton of toggleRepeatButtons) { - if (repeatOn === null) { + if (!repeatOn) { toggleRepeatButton.classList.remove(cssClass); } else { toggleRepeatButton.classList.add(cssClass); @@ -534,6 +536,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL case 'Shuffle': shuffleButton.classList.add('shuffleQueue-active'); break; + case undefined: + break; default: throw new TypeError('invalid shuffle mode'); } From 4fe179214c822d74a120e2df5dad86ab17832525 Mon Sep 17 00:00:00 2001 From: ferferga Date: Tue, 23 Jun 2020 23:41:52 +0200 Subject: [PATCH 0071/1168] Address review comments --- src/components/nowPlayingBar/nowPlayingBar.js | 40 ++++++---------- src/components/playback/playbackmanager.js | 8 +--- src/components/playback/playqueuemanager.js | 16 +++---- src/components/remotecontrol/remotecontrol.js | 48 +++++++------------ 4 files changed, 41 insertions(+), 71 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 97227ca71..8573d9418 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -182,26 +182,22 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', elem.querySelector('.btnShuffleQueue').addEventListener('click', function () { if (currentPlayer) { - playbackManager.toggleQueueShuffleMode(currentPlayer); + playbackManager.toggleQueueShuffleMode(); } }); toggleRepeatButton = elem.querySelector('.toggleRepeatButton'); toggleRepeatButton.addEventListener('click', function () { - - if (currentPlayer) { - - switch (playbackManager.getRepeatMode(currentPlayer)) { - case 'RepeatAll': - playbackManager.setRepeatMode('RepeatOne', currentPlayer); - break; - case 'RepeatOne': - playbackManager.setRepeatMode('RepeatNone', currentPlayer); - break; - default: - playbackManager.setRepeatMode('RepeatAll', currentPlayer); - break; - } + switch (playbackManager.getRepeatMode()) { + case 'RepeatAll': + playbackManager.setRepeatMode('RepeatOne'); + break; + case 'RepeatOne': + playbackManager.setRepeatMode('RepeatNone'); + break; + default: + playbackManager.setRepeatMode('RepeatAll'); + break; } }); @@ -343,7 +339,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', toggleRepeatButton.classList.remove('hide'); } - updateRepeatModeDisplay(playState.RepeatMode); + updateRepeatModeDisplay(playbackManager.getRepeatMode()); onQueueShuffleModeChange(); updatePlayerVolumeState(playState.IsMuted, playState.VolumeLevel); @@ -379,8 +375,6 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', toggleRepeatButtonIcon.classList.add('repeat'); toggleRepeatButton.classList.remove(cssClass); break; - case undefined: - break; default: throw new TypeError('invalid value for repeatMode'); } @@ -627,19 +621,17 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', onStateChanged.call(player, e, state); } - function onRepeatModeChange(e) { + function onRepeatModeChange() { if (!isEnabled) { return; } - var player = this; - - updateRepeatModeDisplay(playbackManager.getRepeatMode(player)); + updateRepeatModeDisplay(playbackManager.getRepeatMode()); } function onQueueShuffleModeChange() { - let shuffleMode = playbackManager.getQueueShuffleMode(this); + let shuffleMode = playbackManager.getQueueShuffleMode(); let context = nowPlayingBarElement; let toggleShuffleButton = context.querySelector('.btnShuffleQueue'); @@ -650,8 +642,6 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', case 'Shuffle': toggleShuffleButton.classList.add('shuffleQueue-active'); break; - case undefined: - break; default: throw new TypeError('invalid value for shuffleMode'); } diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 3bd4be9c0..b3193f750 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3920,9 +3920,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return info ? info.supportedCommands : []; }; - PlaybackManager.prototype.setRepeatMode = function (value, player) { - - player = player || this._currentPlayer; + PlaybackManager.prototype.setRepeatMode = function (value, player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.setRepeatMode(value); } @@ -3931,9 +3929,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.trigger(player, 'repeatmodechange'); }; - PlaybackManager.prototype.getRepeatMode = function (player) { - - player = player || this._currentPlayer; + PlaybackManager.prototype.getRepeatMode = function (player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.getRepeatMode(); } diff --git a/src/components/playback/playqueuemanager.js b/src/components/playback/playqueuemanager.js index 8ffefd6b8..7d2f941f0 100644 --- a/src/components/playback/playqueuemanager.js +++ b/src/components/playback/playqueuemanager.js @@ -144,9 +144,7 @@ define([], function () { PlayQueueManager.prototype.removeFromPlaylist = function (playlistItemIds) { - var playlist = this.getPlaylist(); - - if (playlist.length <= playlistItemIds.length) { + if (this._playlist.length <= playlistItemIds.length) { return { result: 'empty' }; @@ -155,14 +153,12 @@ define([], function () { var currentPlaylistItemId = this.getCurrentPlaylistItemId(); var isCurrentIndex = playlistItemIds.indexOf(currentPlaylistItemId) !== -1; - if (this._sortedPlaylist.length <= playlistItemIds.length) { - this._sortedPlaylist = this._sortedPlaylist.splice(0).filter(function (item) { - return playlistItemIds.indexOf(item.PlaylistItemId) === -1; - }); - } + this._sortedPlaylist = this._sortedPlaylist.filter(function (item) { + return !playlistItemIds.includes(item.PlaylistItemId); + }); - this._playlist = playlist.filter(function (item) { - return playlistItemIds.indexOf(item.PlaylistItemId) === -1; + this._playlist = this._playlist.filter(function (item) { + return !playlistItemIds.includes(item.PlaylistItemId); }); return { diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 36d703fd8..cbc726238 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -250,20 +250,16 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var currentImgUrl; return function () { - function toggleRepeat(player) { - if (player) { - switch (playbackManager.getRepeatMode(player)) { - case 'RepeatNone': - playbackManager.setRepeatMode('RepeatAll', player); - break; - - case 'RepeatAll': - playbackManager.setRepeatMode('RepeatOne', player); - break; - - case 'RepeatOne': - playbackManager.setRepeatMode('RepeatNone', player); - } + function toggleRepeat() { + switch (playbackManager.getRepeatMode()) { + case 'RepeatNone': + playbackManager.setRepeatMode('RepeatAll'); + break; + case 'RepeatAll': + playbackManager.setRepeatMode('RepeatOne'); + break; + case 'RepeatOne': + playbackManager.setRepeatMode('RepeatNone'); } } @@ -336,7 +332,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL context.classList.add('hideVideoButtons'); } - updateRepeatModeDisplay(playState.RepeatMode); + updateRepeatModeDisplay(playbackManager.getRepeatMode()); onShuffleQueueModeChange(); updateNowPlayingInfo(context, state); } @@ -367,18 +363,12 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL case 'RepeatNone': repeatOn = false; break; - case undefined: - break; default: throw new TypeError('invalid value for repeatMode'); } for (const toggleRepeatButton of toggleRepeatButtons) { - if (!repeatOn) { - toggleRepeatButton.classList.remove(cssClass); - } else { - toggleRepeatButton.classList.add(cssClass); - } + toggleRepeatButton.classList.toggle(cssClass, repeatOn); toggleRepeatButton.innerHTML = innHtml; } } @@ -518,25 +508,23 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL onStateChanged.call(player, e, state); } - function onRepeatModeChange(e) { - var player = this; - updateRepeatModeDisplay(playbackManager.getRepeatMode(player)); + function onRepeatModeChange() { + updateRepeatModeDisplay(playbackManager.getRepeatMode()); } function onShuffleQueueModeChange() { let shuffleMode = playbackManager.getQueueShuffleMode(this); let context = dlg; + const cssClass = 'shuffleQueue-active'; let shuffleButtons = context.querySelectorAll('.btnShuffleQueue'); for (let shuffleButton of shuffleButtons) { switch (shuffleMode) { case 'Sorted': - shuffleButton.classList.remove('shuffleQueue-active'); + shuffleButton.classList.toggle(cssClass, false); break; case 'Shuffle': - shuffleButton.classList.add('shuffleQueue-active'); - break; - case undefined: + shuffleButton.classList.toggle(cssClass, true); break; default: throw new TypeError('invalid shuffle mode'); @@ -645,7 +633,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function onBtnCommandClick() { if (currentPlayer) { if (this.classList.contains('repeatToggleButton')) { - toggleRepeat(currentPlayer); + toggleRepeat(); } else { playbackManager.sendCommand({ Name: this.getAttribute('data-command') From 8d31d507c270ca6c97723ec720ed1634fe449947 Mon Sep 17 00:00:00 2001 From: ferferga Date: Tue, 23 Jun 2020 23:45:21 +0200 Subject: [PATCH 0072/1168] Show favorite icon in playlist items on desktop layout --- src/components/remotecontrol/remotecontrol.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index cbc726238..050ab3eb1 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -465,11 +465,21 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function loadPlaylist(context, player) { getPlaylistItems(player).then(function (items) { var html = ''; + let favoritesEnabled = true; + if (layoutManager.mobile) { + if (items.length > 0) { + context.querySelector('.btnTogglePlaylist').classList.remove('hide'); + } else { + context.querySelector('.btnTogglePlaylist').classList.add('hide'); + } + favoritesEnabled = false; + } + html += listView.getListViewHtml({ items: items, smallIcon: true, action: 'setplaylistindex', - enableUserDataButtons: false, + enableUserDataButtons: favoritesEnabled, rightButtons: [{ icon: 'remove_circle_outline', title: globalize.translate('ButtonRemove'), @@ -477,13 +487,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL }], dragHandle: true }); - if (layoutManager.mobile) { - if (items.length > 0) { - context.querySelector('.btnTogglePlaylist').classList.remove('hide'); - } else { - context.querySelector('.btnTogglePlaylist').classList.add('hide'); - } - } var itemsContainer = context.querySelector('.playlist'); itemsContainer.innerHTML = html; From 6325046b96ffca33e35bbe240ae2fdd1da2d9d6e Mon Sep 17 00:00:00 2001 From: ferferga Date: Tue, 23 Jun 2020 23:57:38 +0200 Subject: [PATCH 0073/1168] Fix breakage on remote sessions and address review comments --- .../nowPlayingBar/nowPlayingBar.css | 4 ++++ src/components/nowPlayingBar/nowPlayingBar.js | 15 +++++++-------- src/components/remotecontrol/remotecontrol.js | 19 ++++++++++--------- src/nowplaying.html | 2 +- src/plugins/sessionPlayer/plugin.js | 4 ++-- src/scripts/site.js | 2 +- 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.css b/src/components/nowPlayingBar/nowPlayingBar.css index 35d71f054..6c6aeb001 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.css +++ b/src/components/nowPlayingBar/nowPlayingBar.css @@ -154,6 +154,10 @@ display: none; } +.layout-desktop .nowPlayingBarRight .playPauseButton { + display: none; +} + .layout-mobile .nowPlayingBarRight input, .layout-mobile .nowPlayingBarRight div { display: none; diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 8573d9418..4158ae6f9 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -196,8 +196,8 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', playbackManager.setRepeatMode('RepeatNone'); break; default: + case 'RepeatNone': playbackManager.setRepeatMode('RepeatAll'); - break; } }); @@ -371,12 +371,11 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', toggleRepeatButtonIcon.classList.add('repeat_one'); toggleRepeatButton.classList.add(cssClass); break; + default: case 'RepeatNone': toggleRepeatButtonIcon.classList.add('repeat'); toggleRepeatButton.classList.remove(cssClass); break; - default: - throw new TypeError('invalid value for repeatMode'); } } @@ -633,17 +632,17 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', function onQueueShuffleModeChange() { let shuffleMode = playbackManager.getQueueShuffleMode(); let context = nowPlayingBarElement; + const cssClass = 'shuffleQueue-active'; let toggleShuffleButton = context.querySelector('.btnShuffleQueue'); switch (shuffleMode) { - case 'Sorted': - toggleShuffleButton.classList.remove('shuffleQueue-active'); - break; case 'Shuffle': - toggleShuffleButton.classList.add('shuffleQueue-active'); + toggleShuffleButton.classList.toggle(cssClass, true); break; default: - throw new TypeError('invalid value for shuffleMode'); + case 'Sorted': + toggleShuffleButton.classList.toggle(cssClass, false); + break; } } diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 050ab3eb1..81ea967ec 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -252,14 +252,16 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL return function () { function toggleRepeat() { switch (playbackManager.getRepeatMode()) { - case 'RepeatNone': - playbackManager.setRepeatMode('RepeatAll'); - break; case 'RepeatAll': playbackManager.setRepeatMode('RepeatOne'); break; case 'RepeatOne': playbackManager.setRepeatMode('RepeatNone'); + break; + default: + case 'RepeatNone': + playbackManager.setRepeatMode('RepeatAll'); + break; } } @@ -360,11 +362,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL case 'RepeatOne': innHtml = ''; break; + default: case 'RepeatNone': repeatOn = false; break; - default: - throw new TypeError('invalid value for repeatMode'); } for (const toggleRepeatButton of toggleRepeatButtons) { @@ -523,14 +524,13 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL for (let shuffleButton of shuffleButtons) { switch (shuffleMode) { - case 'Sorted': - shuffleButton.classList.toggle(cssClass, false); - break; case 'Shuffle': shuffleButton.classList.toggle(cssClass, true); break; default: - throw new TypeError('invalid shuffle mode'); + case 'Sorted': + shuffleButton.classList.toggle(cssClass, false); + break; } } onPlaylistUpdate(); @@ -867,6 +867,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL optionsSection.classList.add('align-items-right', 'justify-content-flex-end'); context.querySelector('.playlist').classList.remove('hide'); context.querySelector('.btnSavePlaylist').classList.remove('hide'); + context.classList.add('padded-bottom'); } else { optionsSection.querySelector('.btnTogglePlaylist').insertAdjacentHTML('afterend', volumecontrolHtml); optionsSection.classList.add('playlistSectionButtonTransparent'); diff --git a/src/nowplaying.html b/src/nowplaying.html index 56610ca6e..9460cb814 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -176,7 +176,7 @@
-
+
diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index 6a266941d..095cbc696 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -257,13 +257,13 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'] return { name: s.DeviceName, deviceName: s.DeviceName, - deviceType: s.DeviceType, + deviceType: 'Remote Control', id: s.Id, playerName: name, appName: s.Client, playableMediaTypes: s.PlayableMediaTypes, isLocalPlayer: false, - supportedCommands: s.SupportedCommands, + supportedCommands: s.Capabilities.SupportedCommands, user: s.UserId ? { Id: s.UserId, diff --git a/src/scripts/site.js b/src/scripts/site.js index 27818f34b..e5c188bdc 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -196,7 +196,7 @@ var Dashboard = { capabilities: function (appHost) { var capabilities = { PlayableMediaTypes: ['Audio', 'Video'], - SupportedCommands: ['MoveUp', 'MoveDown', 'MoveLeft', 'MoveRight', 'PageUp', 'PageDown', 'PreviousLetter', 'NextLetter', 'ToggleOsd', 'ToggleContextMenu', 'Select', 'Back', 'SendKey', 'SendString', 'GoHome', 'GoToSettings', 'VolumeUp', 'VolumeDown', 'Mute', 'Unmute', 'ToggleMute', 'SetVolume', 'SetAudioStreamIndex', 'SetSubtitleStreamIndex', 'DisplayContent', 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', 'ChannelUp', 'ChannelDown', 'PlayMediaSource', 'PlayTrailers'], + SupportedCommands: ['MoveUp', 'MoveDown', 'MoveLeft', 'MoveRight', 'PageUp', 'PageDown', 'PreviousLetter', 'NextLetter', 'ToggleOsd', 'ToggleContextMenu', 'Select', 'Back', 'SendKey', 'SendString', 'GoHome', 'GoToSettings', 'VolumeUp', 'VolumeDown', 'Mute', 'Unmute', 'ToggleMute', 'SetVolume', 'SetAudioStreamIndex', 'SetSubtitleStreamIndex', 'DisplayContent', 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', 'SetShuffleQueue', 'ChannelUp', 'ChannelDown', 'PlayMediaSource', 'PlayTrailers'], SupportsPersistentIdentifier: 'cordova' === self.appMode || 'android' === self.appMode, SupportsMediaControl: true }; From 4c55a07b0a46386a9141ff930492ba99bbd766d4 Mon Sep 17 00:00:00 2001 From: ferferga Date: Wed, 24 Jun 2020 07:48:25 +0200 Subject: [PATCH 0074/1168] Remove legacy loading --- src/components/loading/loader.gif | Bin 11493 -> 0 bytes src/components/loading/loading.js | 6 +---- src/components/loading/loadingLegacy.css | 10 -------- src/components/loading/loadingLegacy.js | 28 ----------------------- 4 files changed, 1 insertion(+), 43 deletions(-) delete mode 100644 src/components/loading/loader.gif delete mode 100644 src/components/loading/loadingLegacy.css delete mode 100644 src/components/loading/loadingLegacy.js diff --git a/src/components/loading/loader.gif b/src/components/loading/loader.gif deleted file mode 100644 index 86fb6daa79669dabcdf43da630e5de612a44140e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11493 zcmaKyWn5Hk!|jJo=>`#yZV+h&L5ZQeyHmP*=8v*GCiJ?;gWsdjrp6B=8 z=gZk2_iyiy>sr_PuO%%jB`9Q~ji`-yg93m;p%)hyot>RiQ&XFpn{YTB@Slekj-~iT zT}|?n@)urCZX|@iFKHi2xRDm^t3uCf^!b zV}IJ?#6Iihu30e513SsEQzVR)xQyEi7tBH2fYrLS8Ux~hW1rrgx?dvLnX|`D zKGXbW+gEK=rLWg7e|2?lTs*^r>|H^jVIs)-KG89;aRz?DNy#ax2;mu-S;+CZdHHdP zX+^~)!CB>y4><)@)iu$Dr45Zu0Tr!n6qU7I-95e%%>#o&E$ySO2)&b2(OdJ zLZ-gFcO7Y8Whs%i5Y;)Mn)qxsr^G7MB09ms@~vDUi1+-UX=hOpq0sh~XIjdvnQEuw z2Jm4TP#*)`(~b7Po^EhLt9PK3;$ZCX>KWO59$_}**1?+o^PFC5B5wr`XQ5)MH|33Z zTkP`tSJLW)A)?$?F3XwOh^i>t(q#J`&6L3ze_@q&U7XL#J6C;!=cipu`hbZ6`3 zb{`1qjbc~Z_5N52o6$^H`|Z(Ov0Q;-w-4v4n}*&tr>T?PIZzpiX1e<~%Jo4~9koMG zH|jOGyb6xB)$M=g^R`c5kCP(V($84&&F9Sz`Gh&k8u zENhU)@{f+!N_ZMZs45m0?>7>ZB=#m1G^CR2m zLW$DbbpT8rrHq{RFZ0uB<;X!Yc@op!C(OIIbjkA=Up_8&)*fk3z*94Qf0^}2I8|M@~fn6!@eG98*JB~t6Zrb}c zEzpL_c2+k;Vs}u z*o$YAYnQChg^`^=v2Z(=haNAq#m6cy>F=Zv4!f&|IxqW@?|cWd07?wp{n#m{PUuRE zQ)b++wAiNy-^%=sD);iRtnVS4M3-bt`Ne zk!JoTs?~iT)xG+P7@p3hC?tPX2%^}}nFSdVMcndvA5*0TESx+B#0#qn_HaI*H7z?n zpSK;=JYRJEym-D`nmZ@BB4P5`uoqwSJk zeQWmT+ST09^H+#xfGqfU_WDCsMW&J6vyS|j53jw4k{I4TnmgRUePHXwxb8z)kfOLB z!45!Hx$lwXhccSJG1AsiUmBm27s2O#Fi~XEiw!GCP&xJ`pRSia_zJ!3boyB_v)S-- z9lNJ7Eo;yNzsT=d)y@^!%$_9{97i;hf<%*%xjoiH0FSCfD4Fr!4&stP;<9ZSKq_tEi*g06yejlfsS(=B4C+b7w zK7>B4PGrv+Pm`YLjq}}zSjZQ>Mhg0O0TyFY!Z%5Yu_g3Ovg1JAo8-)?5=MdXaYdh- z6fkxvv$QM_0|pC6rq^PL(~kIvVnS9)4{YJiE1RhmId6)HD*Agw8eAr5&k!aqn5C0TBOUrN}y=a3`Ab5BBE5TW^ZEErR zX>wfAGS^(4I|PwcSuy8 ze+x;?huG9%w#Xad6KT>^3gOXy9OfkcE4!o z&BYdc90HrJuwpEJTlDy*T6H9ZsVRb}sR;hg_?bS2$LM+qu?}JzlFFE~1WdpRsZG7C z0!t%OrZ(s%*RlA~6kvCbx2)|$kPuR}uF;vt{))-{OVx*8x{bmL9?5=BRRnxF@f|?p zniFGtE3}d|sIVqwZs~ws-Z$N*WKA0#(`p+L?)93H1pm%^fNi6R4iok=dC@t86BZA6 z502W3(0YGv>wddINR>fe&w&(_t7m}z*^_+LVe`175)lx#j0T|lisf?}b9*7~53@k< zHLwmleG2KkuI}^nPud`wBDH)B>kl+g(eviz>f<4EV!QH1GNuzmeJH&oBoZw}8{O$s zip&c$+gY~1(?TY~*$cP8GXW(08e&$gkJg&nBkBA#%pG4JYbC!=vHojBaHc-qb84Sj zj%FzTms0>wt_kcZ6OkbxEKz#SWR2PzQM?RzV0>qONuYx%>wyB&=rY1kL+H_ncTuXD zJFr)82bdm)`g$r`9#F4#Ia|BFYoRg{GW*GQGVPrGeQM);ZDnRk`v$vV3hPsX3%ou2 zm{-=Y%c^2Vxs^?mFL0T^5b>+Vd`}%JxYT-A%It@u`$TQIkjaTqXiG==#b{aHCoB1y z4syHrM)OMGu~AbtUS?SZpQ}T8{MFi0rC)Q3+>M=apz2ChI7UO~FWE1fYgAI4rBjpJ<3c@_NM#T=i?PGJ`ux1(a zRj|q8d4#le`JbqS&ez;^`>6Cn)u}wiT#9$shn#QpIHJG!X zT51?f+OZpFBK&fbIoow8F#9;;`*I7$?LL-PdYaF9xq~Qm!?b3fmO5YV>k_)ptdySD z)?XglX1gyul^X478*;|ZkS_0&yp-vi2nI)kcU%n>P3hsUdlS~KE3W;p*x^+-_9wU7 zGbs@h>JRM)zPE+mPaQGC&uiOVkLMp>f)D-wMA`;QdrtYcO$L@&Me@LZOMdYGT}eCq z{PXjlqri|vBLsAo1LfvG`gN0=9?j%F#jzD5$ zufFXE13;iJ*1;Xc4x-Ybax(s{gCMh#P?bo922iMxd6-rkXPg;G$I6d!CG1v0$Yji3 zOgxr2mP&-mf#S@DDwdRFcQ8VDD}yg$Wuo;d(S@4_ zmL_1a8+sLD>$V%8T_#s{Pc{{at!wR|;coGsHq;oPk*GE0%~`m!pBJjt5m`nE!ZP)pTKlnjGaE%&{& zbhq?#L0kvfbW}lyL+%WIka0k}<8n~O0eVu}QW9ZN8gG-POgb@Ue=u;;driSc%Csh?};Jr zgH+z!31V+no(5yCc4DrVQ~pM;Kt1SHA7+z@ENve3@_+>CM9SSC};Cm?;7l=g0nm=FWB5#}=Kbq4a zM39+Oguq|uj)2m&>P?0zpg!V_$yzi%=*`&?r{GkazYKo!gvbN)melo^@+pzYE&+Cw z$ghaUd=K9w3%l$i>bnd_EW`jlB`m)T+>h_88n z>7bzZDSQt@7I{Kp7tSOgMPc;u>S8Iv#4F0SDpag1%+f0VE+ZU*=|$#Kj+a!7nhgPA zR+x|!`oJJ}mJq|8azgrwkNjX`HE;$jPaPgqxctk!Bs#7LW`+rM_vbOZJ{E>dR0v4r zeR?vi$TrK&u5hk{?te4eSj}r-HCtS*bm^<4V)dvz`8fJ$g%lEzV`Da)B{;2XHmD2r zLbc=`sU(MGO%vyAW@D7Bp~O-s<_Q_3LrvSCP_icoD#lG8Kv>^_RV*Wn1UFSomRZKZ zwQr@e=qhS))5XG0YIihi;s$Sn;l5D4l8b zM5cIDY_$jxoLKlZ&zc(Oa>=Nl8s?8Z8X57GvJ_Y=YZNh<_bEOyRp!fhN44J7f3J8; z$yda2+9*s3B+02`#BY3RmyK?y5r+pg6%I9a_#`9C#l06I%8yp_kd?S5mAixzb3$Xi zvmG4p8>;I`C3Un62T9`|^qq;x#dVS*2gyMKb#rDEvMsf|{Y^bYiC&ejntcee7!w^2 zDPQQ#I`}m{+q88lH_|E)-SlAy}ZXRpUo;I3=0{Gs|amftoHV z2iVx-4m%l^bKLDB`re%}(aFCjh#k0|WX&L7B$O||5(uV%JZhA*gmmzgC*yzq%kx+YYMBps|;(ducm#X zN7cLO41sx+2KbW=t7{U8c4|m}YQ%49EO%<6Yiep^YUcOU9M$x^==7rg^pfB7${9Px zzhFxQfDWL5U;zO93$_R#Pl+H0apQ#^=KT+BfiTWeVuQRmBP|^M16y+E;u}p_NA1I< zK9>H4Eo+G@#l-t({GM~wUh?^tvtu_ylNXpkSeu{Xr}c$9Dc?)#AMhY`PmouzUxdF? za7-*qXhK*}WQt)xTt+5NVop+EYJp>PREzo|PJ#AM~DDnqHinTi952UEUG=y0*T#*}HoJK-xNpJ-j-G zoqRpNaJhPXu)Y05`~1`RWPxdRThs~x1&1Co1r|d95MJoE)qw{C_UTCq$G*Y$z62uk zA@0iX?qw!0FJ}?yl+(*5u>7evvzhua8O|dnQ4-Z(rjRN0>f(T`d42w|^KZT2Cy6R*~7_qd0?ve(WvOTl5bdtk3_GLVGX+G(=uM@UM4bFlka zGnke6aP#H#Cv43#1g)1NSJSa#$nBZ8CsP3DpgWn#$W8vRVP`7)nzMWF@!js68Lk#f z9vL4jrdXpc{Osv|dxhF^;iE%mJ>F)9-Om>hf?pTIgIN2Vw!hm-4ze{S9jS8#?wZnE z)oSB^`eO7B zEQwf+3uo$dkoBVkK;0v15W_g1))G%H8zbng4P*VGlm)a+BG+|5wLFAFJj;sQTvO08 zCUE8xAmub^$+$2GS=Z3{nP+XRaPCideu)n)1qJ@P$y0Q3Hj7Da`B0x=7CCvcE_SI? z^++CctY;mRaX8wN9MCZjQ=VjFyc70uz-=YIH>f z+av|b%Q@svn66uYTnDakaK~j5)|Af)dt)RYB~t`(_j+Ho+n4<&Oo z?>DHx7~$caUnytBRh>HTefpPPW6eI-5MHd{JNLgT7*{7D<*KUsoadHX+f4UJcQZ~g z9&|GSr2m&58UN}L2Dtct^!OKk`qF}!{(+y&XgG*FJvM*g=ZA)`HAo(paB+M{GuvUv zSjjvZuW-yH#0}d2p;iRyQQ2(TD_rBXaT_u#-QdGP1>RO}@%zX#c*)ses6?{|xA6@z z^$!X+0Y#}fM#OPPCw_{JPZdqd;7dtM%gkfS&dJFyrVc19FR35}mqVbnxM9_e33V-1 zP1P-RW$o>q72Q3(eVGk|W9h@uZR10eA=5LnbFT9Xi{EXRS60{bH#WDnWA+Zc4-Ae@ zPt=f4ug+Dj?rvlU?lvF9cOS=|Eq*^DX-k5|LwK*q`6BSX^oGq)WCyh=@4bp9=79F0 ztHAeB!>CrhyRJCRN0W%fvx%a3CC1a3^gb$Mq?F2|z8Bguzv3=$%fqyOYKpq~p&Ts` zM$G_qu8>XrkjHxmQD;>P(bUrA%O)-!f*6z&R8c(Gb~JF~7k!6%RL_Jv{=py%ONk%rM9KBA!V;KYIz_C{+@>G6i)Dp#z4 zN%6_;V8PAEh|sw+-(;kFve3eyD^qQ4`f^p>@B_K@$tJEakzqiQ*!4MEN3j@j_HX!~ zFNjk92&OJ5K`0c~pM5d5GQNQN4uWVxi`)8kJP?%86#!JW=-3f7KImAH^wAK^D2D7~ zjA&+PBt{H-2N^~z&x9a)9QRrqT09?25G_IQX$&>-6Q&Sqk|@PEO0qa>1xkv7FgZ%< zXJ7?#nv8A~a=MP~2~viSBQ zfl%Q8WP<=U$J9kA45OexD6(e7L@16Eo&c2C1EGLYC*5e9vS>%3Re8P()C%JDBx_sY zl0RVug%+_|Rt9BboI(v}C@RxiwqWKpO~CQfa?Kaavzh@-3j6vf>KOa{s|n6^#+sRr z>-J3sigFIgbB1~r)oYG+4z2Gku^bcj;wdj$4=sP$b{suTIL4gzP|~&Dc#wVVZdj`1 z?7o3kT=x8EIIZnL`kBMkgVuY>*pGpwUpIg&;#WIFSl(IJ|4NUlzMa%e|GKS8qKjwj zEr^nL_>HG;!w5s=2G1miQ77*>m#b*w`1=K_cg-F?x%HDm`&4{$A|fKJ6JmDjjbmT9 zeEFsn-gfdW%1(+lPYba5H_u7x=$25!sxT|@f0 zWyx&+PxGcHXtQO}KPInr2Xt%Dw(FbYV1@X<4G1G30$>4Sb%hceVa|q4>4yH5 z@2mYW&0FkhjmD9)Y7t`ijI{gBYvft!pA-SsL8OKu4x#v*5uhmCSm*dx;fWr}8fi(% zS>Eyfxjv!bfS}akIM?zJ*D@$XKc=R{q#;(npgCKuJyET?t3$Rg4cI%_|8X?y^T@=Q z-OP~C^f!BKonfc9OM)9enXVt6(*>OV zNV+(H(|q0`Q=IKO7UCfa%?SAgU#$;Oh;iOPm?h!61F;lFckf7D#+s6;X&5CRKVi$! zu?tNkdL@wqvv>_(u72TKVdv3EKKX$f#uSPfG@f?aacyKu*(6C!guj}9s`zZp*_2&d z!d+0%U^dZC@v?8 z^_B}$hJcWw6yM}}wFpO7Lv>M*!-8oYl`es~GFG-)xk*Q`WX)fc;~G?LcN; zU4T}HnL~HHO(k&;_rq-e(5s@6>yGu5!C>%?f)Pp}d(rGI$9pl{BP)A^yi3;malG@9`|+Yn z5VHhv)T})s36jVnQH4`P*bgDIxk4RZVh0swQicMY^oxcxj?x0ET&{>5YtK zmWXOpS(0rHhGmW;HHKBLCF`f79N7)>gIu3AFUtbX8;s)=51i;?a5!qTbrCz~1SC5C zqmM;lGJ)>rQn|yZlb9qR@TBaWEv7A`D86H_yiC#C23lT}4XrF2pg4tAN$9dxHpKg| z)pX7P?W$7<5UQ#Na4KQABd9U<4ePy#>!+2&6zlfYvrjO|h6%$-`=&ufIgZwu5XzdC zbxu7;oE6I$$&S4Mxr_GGhUc25!vPV=4%kG{*B+i7z1r@lrt3i5u_WFJzEx+2)w=w#>Em#T9^_?t|>oqmsO`oia)Z0W| z3rvD+N6H-4g(J#6xq*>|QP`{)GZ`D+)OjcE6OIwx{$=`1f33kTSCI>U|D+>emUid6o?nP>pp7{w(lN|CD$Xj#G(OqLDN#u^B}?5i zT{xrDuSyPb712jB;4GV0@-y zl5l2$H1`|P;^Hz#%j)1d$JY4V4$j`#(huCtqt;>=*Lly?{7v^A!P!IQ!LR3wUv$4a ziSa^ug29*);$y4^pTet%gay%6l0Ul=OWqfIvcvaFJV|rB-Q4Q?WfU05l|{!#cO}zF z)DVNn-<8T_`|{5ZW}zPpr->4e=aQ=@Dtf(+nZNc{VJRpCBnvyZs&7tLSY`r;bkSfM zHHP{<$m^)A$_*M|f-iPb_IUE_tM3l&8q#3cIe%PJOAr{YdWGkWGKJ1{cojoFQ|cDm%ir z)p|>oYu%sh<0<^^uJ(97MtsIG6LdagOce-o91wDXk(S6!#eE37y`ax^Mcv-z?>Su= zb}e_z=k?z0+6GzUD!!l(JxF$GX25%n;Ji*R7WMCkp{Zbjga`ox46OhVBI<|ngdE_%ldV=iVE zWMwH~kg+`}Obu~5Db4b!J1Nhzy*hzpdH`7~%JO|!OQ0>f(7c)vOuMS47TMG4TF0o< z8p8{iU5(@mt9|kSNu^c%2qRWi1bl)&#Nu|&EP0B)w{j^U_TGMozPlnr9f@2j8dq!HP=kY)>+E+7`ZRL z2-y5;YkDNtveNBupuaSwpkT1DN1$LhcXOU=G!5vf0*~W|RP7GaI_ejVa)rm9jrT)0 z4!S#f`#dmWxK`{(Uis27E)1LNNVrI+#Nc zFZ$Os;^P8e?*E-eq-?p@T#CNA>&S6J`DYp-ZJgzYQ4mt*2DIR)?S&nWmsyr)r_a^TA_0@VsGGa!JH9ndBYmH?(TDM4uXdAR`PZ z&a28UL`~+Dn@;$BYCK9K5d`%tw!4PT7KEC-6T}3X8|$4;f>WDV7U!Z}LHG7Ma)Js5pMnXk29(>b z--Oc;%aJgQ*8kwNWVFK}-fcKy$`XkANWa^7f>9`4$vL>wbh=n+#znUC#CNt*Ns0&g z^T_Y`z1myv;g2sL62br_Ay-d3!uf$;#=8t`geSw31tdLj$JZPWXJ6l)U0mFYcr{S9 zr5M@1h%VyJE~7bIZZXL{3Z5)$$x3{9iHAR(M|{KB|1+u*gh;n2;fIPDY8-MmHV2l# zl@P>vg{|nN7)Cmon1tTbqt&(*%jf>id zd`m`t6B(XBU$a}3D1m2VLM4O4f*SvA2j4sexFkK6DyoT*&mi3cVQ_`IRqST8-P4r? znSc5nvkMwzcsfxV=<%^KnmhzWlA2feB{)8&c(7q1 z6!-9!x2^cuy=~e6>*2L`p$<6KUzj#S@~D<_*t(?W%P)IT`sAqk{*A)q5abZf{>O#? zcXwn*((#|&5xL_(C@d%2i9N^h@9t=3+7I{i@9t>jiag;>k;}LrZ9(^6adAl0)Q){&3Pz5bMy4(x+fK4MuWQ$_TyOmgW=IK)VVBg`X}5Rx2|pbl zpPv83JX|Ab%NPSf!jb9NAx^Y3Ae=|>*fuM=FCrvd1LKfu_^Z))Yiw%dlX}|mk8hMP zffWtWW9hUy1Lk)whrkqmgQckoHO5&^k-+&o7NW?pq%S#C3Q#we1qQ_esc2RW^zTrq zTGMG~q7%&;-QJ~Rmv6{l&X0C=fHlD+W z%VD+U>;6bZ=R@aK))4}3fa9-F_YoE%r2s!l*U8y@$v2Ff0}Zg03bWQ4JCOs8EsbDY z_#cADp2OLguO$IU&kq-W`rhbUe*7c*pfWd(+x8Lu0{`{L(})NWdjC1tH7bOLxt@KD z1{WuvK{C{dM{-wNOkbN;kfLSSB!YSXsfdB@g&~Mt79F)Onz<%@3BWcYXo|zLgx(kX zzR%h$POwJ2FJAm1G6Wz_!a|QKMpAK*M2uH)kRmU&bC9AgwHg$!Zs}c|CTn|Qk*enN zXpvwN&2kuPk!@ocVFRsT40Gr>ISg^0U?~rBU$ZIqM?R=1&p&s6JOWFFM=%sdqUsnF zMDcgfyG97JR>TeR2%nTj&y%o}{)`NZDHxLX+AJ$h)xHrGOVYRwW=xp z={q1`30kR+JOw?iO?^3FtsAmkRjq9&sXU8^lhWp#HOyH?D>p5^oG3T1YzaBEY~;%- zx9(72DYqR+tSYr11J@Nh&Th1oI;-E6+AWs`Hz5klx0gb%fY=gJqO8DwbvJbq@Q95~~1^M~Qaabffz{?V zhZDa!815@@y$S1P72msxdioW~BxwjPru5JgIzG_k1t0FmzLRA*&NJG%10aPO3M2pf zy!eI?3a|pG{5PfJh2#CRQ~YrBV$2N86Uet-OU;AzywMwQJ0Gj69&GD^ms8`&9H9FT zoBvo*6V{qKTp%Y_O#8l{mTBSWxp~}5LXu$g1E!NUQv-6i7a_WwF>`-@oq~JG2n&h8igJiSiF1xfN)AkQ_sz(3&G!D9=WhirG%60(D=Sy42ve%6)~>D7Z-{DY zZWL}yGVYA)?rGug@9h|B=Np9%PLxbdr;W_T_bmi`U-Fq>brjoJUf(v{+H+a?A$f4D z3p+hIy5JDMRz1ICeE3Op`*id8v-OGi`wwoUL=QSZj*=RT%XY-SO zrZap~D&`H3B9YLI@mK`Y`?5Q-m;*644wafvp++j=3@(QyB2Tr$FXip1F(w$cq2)d3ny8mHQhCYwFOYb3{O zX3pnZuhN&#bc)^GQ8h(8b&dKpc5$R~$gWIBZOAY0-7~L@I+BRR)~4DUk7mJ=G1Lkj zO(zQwwMxV3j^@+lIO5)AC;pADfI^UAgG<4Zoi?16TZL!O9J8n2qY_8L5g)&J0U;DM|VK5KWMw506ZC5 z(2J1sE{L45a3>sv4l?9NLt$+ag^(Xf7pR0+XBzaHtoLyh5|V7i##xqn`Sxy4o!T>omS1vev`18 zgM8x)-0hI(fhN}%pk$|*`7>+X-NVE=&V#KTs4W`i>i{_~!$RyDThpl!K`=uJ7w~#H#Km&B(Pcrs@^1ET4w19FkxxY%osHWjsn{ zanw>V%rL46p{ITD9p8Tobm2GuX7u|PdHfAsH{G07)nCwA<}h|QN2vN|G_>*qnY#^^ z4~KhnZQ(1*K)slrRUXHH66_cFijd4Jx$w@(4d_E%#>fvrtD(6Xl;`PXy+K;-`b DwI{5l diff --git a/src/components/loading/loading.js b/src/components/loading/loading.js index 9a9aa3ca7..f36e41f44 100644 --- a/src/components/loading/loading.js +++ b/src/components/loading/loading.js @@ -1,10 +1,6 @@ -define(['components/loading/loadingLegacy', 'browser', 'css!./loading'], function (loadingLegacy, browser) { +define(['css!./loading'], function () { 'use strict'; - if (browser.tizen || browser.operaTv || browser.chromecast || browser.orsay || browser.web0s || browser.ps4) { - return loadingLegacy; - } - var loadingElem; var layer1; var layer2; diff --git a/src/components/loading/loadingLegacy.css b/src/components/loading/loadingLegacy.css deleted file mode 100644 index 17ea94950..000000000 --- a/src/components/loading/loadingLegacy.css +++ /dev/null @@ -1,10 +0,0 @@ -.loading-spinner { - margin-top: -3em; - margin-left: -3em; - width: 6em; - height: 6em; - position: fixed; - top: 50%; - left: 50%; - z-index: 9999999; -} diff --git a/src/components/loading/loadingLegacy.js b/src/components/loading/loadingLegacy.js deleted file mode 100644 index d766a4aca..000000000 --- a/src/components/loading/loadingLegacy.js +++ /dev/null @@ -1,28 +0,0 @@ -define(['require', 'css!./loadingLegacy'], function (require) { - 'use strict'; - - var loadingElem; - - return { - show: function () { - var elem = loadingElem; - if (!elem) { - elem = document.createElement('img'); - elem.src = require.toUrl('.').split('?')[0] + '/loader.gif'; - - loadingElem = elem; - elem.classList.add('loading-spinner'); - - document.body.appendChild(elem); - } - - elem.classList.remove('hide'); - }, - hide: function () { - var elem = loadingElem; - if (elem) { - elem.classList.add('hide'); - } - } - }; -}); From ab12e6e4ad35adb2c23288c28d364b8aba909c96 Mon Sep 17 00:00:00 2001 From: ferferga Date: Wed, 24 Jun 2020 19:50:54 +0200 Subject: [PATCH 0075/1168] Address review comments --- src/components/nowPlayingBar/nowPlayingBar.js | 25 ++++++++----------- src/components/remotecontrol/remotecontrol.js | 17 +++---------- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 4158ae6f9..dfb73a860 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -195,7 +195,6 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', case 'RepeatOne': playbackManager.setRepeatMode('RepeatNone'); break; - default: case 'RepeatNone': playbackManager.setRepeatMode('RepeatAll'); } @@ -203,11 +202,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', toggleRepeatButtonIcon = toggleRepeatButton.querySelector('.material-icons'); - if (appHost.supports('physicalvolumecontrol')) { - volumeSliderContainer.classList.add('hide'); - } else { - volumeSliderContainer.classList.remove('hide'); - } + volumeSliderContainer.classList.toggle('hide', appHost.supports('physicalvolumecontrol')); function setVolume() { if (currentPlayer) { @@ -371,8 +366,8 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', toggleRepeatButtonIcon.classList.add('repeat_one'); toggleRepeatButton.classList.add(cssClass); break; - default: case 'RepeatNone': + default: toggleRepeatButtonIcon.classList.add('repeat'); toggleRepeatButton.classList.remove(cssClass); break; @@ -445,11 +440,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', // See bindEvents for why this is necessary if (volumeSlider) { - if (showVolumeSlider) { - volumeSliderContainer.classList.remove('hide'); - } else { - volumeSliderContainer.classList.add('hide'); - } + volumeSliderContainer.classList.toggle('hide', showVolumeSlider); if (!volumeSlider.dragging) { volumeSlider.value = volumeLevel || 0; @@ -630,6 +621,10 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } function onQueueShuffleModeChange() { + if (!isEnabled) { + return; + } + let shuffleMode = playbackManager.getQueueShuffleMode(); let context = nowPlayingBarElement; const cssClass = 'shuffleQueue-active'; @@ -637,11 +632,11 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', switch (shuffleMode) { case 'Shuffle': - toggleShuffleButton.classList.toggle(cssClass, true); + toggleShuffleButton.classList.add(cssClass); break; - default: case 'Sorted': - toggleShuffleButton.classList.toggle(cssClass, false); + default: + toggleShuffleButton.classList.remove(cssClass); break; } } diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 81ea967ec..3a69353b4 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -258,10 +258,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL case 'RepeatOne': playbackManager.setRepeatMode('RepeatNone'); break; - default: case 'RepeatNone': playbackManager.setRepeatMode('RepeatAll'); - break; } } @@ -362,8 +360,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL case 'RepeatOne': innHtml = ''; break; - default: case 'RepeatNone': + default: repeatOn = false; break; } @@ -407,21 +405,14 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (!showMuteButton && !showVolumeSlider) { context.querySelector('.volumecontrol').classList.add('hide'); } else { - if (showMuteButton) { - buttonMute.classList.remove('hide'); - } else { - buttonMute.classList.add('hide'); - } + buttonMute.classList.toggle('hide', showMuteButton); var nowPlayingVolumeSlider = context.querySelector('.nowPlayingVolumeSlider'); var nowPlayingVolumeSliderContainer = context.querySelector('.nowPlayingVolumeSliderContainer'); if (nowPlayingVolumeSlider) { - if (showVolumeSlider) { - nowPlayingVolumeSliderContainer.classList.remove('hide'); - } else { - nowPlayingVolumeSliderContainer.classList.add('hide'); - } + + nowPlayingVolumeSliderContainer.classList.toggle('hide', !showVolumeSlider); if (!nowPlayingVolumeSlider.dragging) { nowPlayingVolumeSlider.value = volumeLevel || 0; From fd6b20d88ceef8cc9df111109352f580083476ec Mon Sep 17 00:00:00 2001 From: ferferga Date: Wed, 24 Jun 2020 19:52:47 +0200 Subject: [PATCH 0076/1168] Add missing CSS selector for TV Layout + fix code smell --- src/components/nowPlayingBar/nowPlayingBar.css | 3 ++- src/components/remotecontrol/remotecontrol.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.css b/src/components/nowPlayingBar/nowPlayingBar.css index 6c6aeb001..e545d82d1 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.css +++ b/src/components/nowPlayingBar/nowPlayingBar.css @@ -154,7 +154,8 @@ display: none; } -.layout-desktop .nowPlayingBarRight .playPauseButton { +.layout-desktop .nowPlayingBarRight .playPauseButton, +.layout-tv .nowPlayingBarRight .playPauseButton { display: none; } diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 3a69353b4..a83009ad9 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -518,8 +518,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL case 'Shuffle': shuffleButton.classList.toggle(cssClass, true); break; - default: case 'Sorted': + default: shuffleButton.classList.toggle(cssClass, false); break; } From c5e2bbf87fa55e76fea264e663a576af6bd1dfac Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Fri, 26 Jun 2020 17:31:48 +0300 Subject: [PATCH 0077/1168] apply suggestion --- src/components/mediaLibraryEditor/mediaLibraryEditor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/mediaLibraryEditor/mediaLibraryEditor.js b/src/components/mediaLibraryEditor/mediaLibraryEditor.js index 7996867b2..332c9a410 100644 --- a/src/components/mediaLibraryEditor/mediaLibraryEditor.js +++ b/src/components/mediaLibraryEditor/mediaLibraryEditor.js @@ -247,5 +247,5 @@ export class editor { let hasChanges = false; let isCreating = false; - /* eslint-enable indent */ +/* eslint-enable indent */ export default editor; From daedd3a61d33df9a52ff096daf12c80e62b72060 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Fri, 26 Jun 2020 19:30:44 +0300 Subject: [PATCH 0078/1168] apply suggestion --- .../mediaLibraryCreator.js | 58 +++++++++---------- .../mediaLibraryEditor/mediaLibraryEditor.js | 58 +++++++++---------- src/controllers/dashboard/mediaLibrary.js | 4 +- 3 files changed, 58 insertions(+), 62 deletions(-) diff --git a/src/components/mediaLibraryCreator/mediaLibraryCreator.js b/src/components/mediaLibraryCreator/mediaLibraryCreator.js index 6940da1ba..c1b7453ca 100644 --- a/src/components/mediaLibraryCreator/mediaLibraryCreator.js +++ b/src/components/mediaLibraryCreator/mediaLibraryCreator.js @@ -194,37 +194,35 @@ import 'flexStyles'; }); } -export class editor { - constructor() { - this.show = options => { - return new Promise((resolve) => { - currentOptions = options; - currentResolve = resolve; - hasChanges = false; - import('text!./components/mediaLibraryCreator/mediaLibraryCreator.template.html').then(({default: template}) => { - const dlg = dialogHelper.createDialog({ - size: 'small', - modal: false, - removeOnClose: true, - scrollY: false - }); - dlg.classList.add('ui-body-a'); - dlg.classList.add('background-theme-a'); - dlg.classList.add('dlg-librarycreator'); - dlg.classList.add('formDialog'); - dlg.innerHTML = globalize.translateDocument(template); - initEditor(dlg, options.collectionTypeOptions); - dlg.addEventListener('close', onDialogClosed); - dialogHelper.open(dlg); - dlg.querySelector('.btnCancel').addEventListener('click', () => { - dialogHelper.close(dlg); - }); - pathInfos = []; - renderPaths(dlg); - initLibraryOptions(dlg); +export class showEditor { + constructor(options) { + return new Promise((resolve) => { + currentOptions = options; + currentResolve = resolve; + hasChanges = false; + import('text!./components/mediaLibraryCreator/mediaLibraryCreator.template.html').then(({default: template}) => { + const dlg = dialogHelper.createDialog({ + size: 'small', + modal: false, + removeOnClose: true, + scrollY: false }); + dlg.classList.add('ui-body-a'); + dlg.classList.add('background-theme-a'); + dlg.classList.add('dlg-librarycreator'); + dlg.classList.add('formDialog'); + dlg.innerHTML = globalize.translateDocument(template); + initEditor(dlg, options.collectionTypeOptions); + dlg.addEventListener('close', onDialogClosed); + dialogHelper.open(dlg); + dlg.querySelector('.btnCancel').addEventListener('click', () => { + dialogHelper.close(dlg); + }); + pathInfos = []; + renderPaths(dlg); + initLibraryOptions(dlg); }); - }; + }); } } @@ -235,4 +233,4 @@ export class editor { let isCreating = false; /* eslint-enable indent */ -export default editor; +export default showEditor; diff --git a/src/components/mediaLibraryEditor/mediaLibraryEditor.js b/src/components/mediaLibraryEditor/mediaLibraryEditor.js index 332c9a410..4577b6713 100644 --- a/src/components/mediaLibraryEditor/mediaLibraryEditor.js +++ b/src/components/mediaLibraryEditor/mediaLibraryEditor.js @@ -209,36 +209,34 @@ import 'flexStyles'; currentDeferred.resolveWith(null, [hasChanges]); } -export class editor { - constructor() { - this.show = options => { - const deferred = jQuery.Deferred(); - currentOptions = options; - currentDeferred = deferred; - hasChanges = false; - import('text!./components/mediaLibraryEditor/mediaLibraryEditor.template.html').then(({default: template}) => { - const dlg = dialogHelper.createDialog({ - size: 'small', - modal: false, - removeOnClose: true, - scrollY: false - }); - dlg.classList.add('dlg-libraryeditor'); - dlg.classList.add('ui-body-a'); - dlg.classList.add('background-theme-a'); - dlg.classList.add('formDialog'); - dlg.innerHTML = globalize.translateDocument(template); - dlg.querySelector('.formDialogHeaderTitle').innerHTML = options.library.Name; - initEditor(dlg, options); - dlg.addEventListener('close', onDialogClosed); - dialogHelper.open(dlg); - dlg.querySelector('.btnCancel').addEventListener('click', () => { - dialogHelper.close(dlg); - }); - refreshLibraryFromServer(dlg); +export class showEditor { + constructor(options) { + const deferred = jQuery.Deferred(); + currentOptions = options; + currentDeferred = deferred; + hasChanges = false; + import('text!./components/mediaLibraryEditor/mediaLibraryEditor.template.html').then(({default: template}) => { + const dlg = dialogHelper.createDialog({ + size: 'small', + modal: false, + removeOnClose: true, + scrollY: false }); - return deferred.promise(); - }; + dlg.classList.add('dlg-libraryeditor'); + dlg.classList.add('ui-body-a'); + dlg.classList.add('background-theme-a'); + dlg.classList.add('formDialog'); + dlg.innerHTML = globalize.translateDocument(template); + dlg.querySelector('.formDialogHeaderTitle').innerHTML = options.library.Name; + initEditor(dlg, options); + dlg.addEventListener('close', onDialogClosed); + dialogHelper.open(dlg); + dlg.querySelector('.btnCancel').addEventListener('click', () => { + dialogHelper.close(dlg); + }); + refreshLibraryFromServer(dlg); + }); + return deferred.promise(); } } @@ -248,4 +246,4 @@ export class editor { let isCreating = false; /* eslint-enable indent */ -export default editor; +export default showEditor; diff --git a/src/controllers/dashboard/mediaLibrary.js b/src/controllers/dashboard/mediaLibrary.js index ed6aabc8f..d9b288c62 100644 --- a/src/controllers/dashboard/mediaLibrary.js +++ b/src/controllers/dashboard/mediaLibrary.js @@ -3,7 +3,7 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl function addVirtualFolder(page) { require(['medialibrarycreator'], function (medialibrarycreator) { - new medialibrarycreator.default().show({ + new medialibrarycreator.showEditor({ collectionTypeOptions: getCollectionTypeOptions().filter(function (f) { return !f.hidden; }), @@ -18,7 +18,7 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl function editVirtualFolder(page, virtualFolder) { require(['medialibraryeditor'], function (medialibraryeditor) { - new medialibraryeditor.default().show({ + new medialibraryeditor.showEditor({ refresh: shouldRefreshLibraryAfterChanges(page), library: virtualFolder }).then(function (hasChanges) { From 7fe80dcbf14be43a1e56f43aadd67a5264c34191 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Fri, 26 Jun 2020 21:15:00 +0300 Subject: [PATCH 0079/1168] apply suggestion --- .../imageOptionsEditor/imageOptionsEditor.js | 42 +++++++++---------- .../libraryoptionseditor.js | 5 +-- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/components/imageOptionsEditor/imageOptionsEditor.js b/src/components/imageOptionsEditor/imageOptionsEditor.js index 2a3022b0d..8177e1b77 100644 --- a/src/components/imageOptionsEditor/imageOptionsEditor.js +++ b/src/components/imageOptionsEditor/imageOptionsEditor.js @@ -89,31 +89,29 @@ import 'emby-input'; }); } -export class editor { - constructor() { - this.show = (itemType, options, availableOptions) => { - return import('text!./components/imageOptionsEditor/imageOptionsEditor.template.html').then(({default: template}) => { - return new Promise((resolve) => { - const dlg = dialogHelper.createDialog({ - size: 'small', - removeOnClose: true, - scrollY: false - }); - dlg.classList.add('formDialog'); - dlg.innerHTML = globalize.translateDocument(template); - dlg.addEventListener('close', () => { - saveValues(dlg, options); - }); - loadValues(dlg, itemType, options, availableOptions); - dialogHelper.open(dlg).then(resolve, resolve); - dlg.querySelector('.btnCancel').addEventListener('click', () => { - dialogHelper.close(dlg); - }); +export class showEditor { + constructor(itemType, options, availableOptions) { + return import('text!./components/imageOptionsEditor/imageOptionsEditor.template.html').then(({default: template}) => { + return new Promise((resolve) => { + const dlg = dialogHelper.createDialog({ + size: 'small', + removeOnClose: true, + scrollY: false + }); + dlg.classList.add('formDialog'); + dlg.innerHTML = globalize.translateDocument(template); + dlg.addEventListener('close', () => { + saveValues(dlg, options); + }); + loadValues(dlg, itemType, options, availableOptions); + dialogHelper.open(dlg).then(resolve, resolve); + dlg.querySelector('.btnCancel').addEventListener('click', () => { + dialogHelper.close(dlg); }); }); - }; + }); } } /* eslint-enable indent */ -export default editor; +export default showEditor; diff --git a/src/components/libraryoptionseditor/libraryoptionseditor.js b/src/components/libraryoptionseditor/libraryoptionseditor.js index 8b365e51a..f7c1ff136 100644 --- a/src/components/libraryoptionseditor/libraryoptionseditor.js +++ b/src/components/libraryoptionseditor/libraryoptionseditor.js @@ -306,7 +306,7 @@ import 'emby-input'; } function showImageOptionsForType(type) { - import('imageoptionseditor').then(({default: ImageOptionsEditor}) => { + import('imageoptionseditor').then(ImageOptionsEditor => { let typeOptions = getTypeOptions(currentLibraryOptions, type); if (!typeOptions) { typeOptions = { @@ -315,8 +315,7 @@ import 'emby-input'; currentLibraryOptions.TypeOptions.push(typeOptions); } const availableOptions = getTypeOptions(currentAvailableOptions || {}, type); - const imageOptionsEditor = new ImageOptionsEditor(); - imageOptionsEditor.show(type, typeOptions, availableOptions); + new ImageOptionsEditor.showEditor(type, typeOptions, availableOptions); }); } From cf931d429a1913e6272d7347a41817dc199e68ae Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Fri, 26 Jun 2020 21:39:47 +0300 Subject: [PATCH 0080/1168] apply suggestion --- src/components/collectionEditor/collectionEditor.js | 6 +++--- src/components/itemContextMenu.js | 4 ++-- src/components/multiSelect/multiSelect.js | 4 ++-- src/components/playlisteditor/playlisteditor.js | 6 +++--- src/components/remotecontrol/remotecontrol.js | 2 +- src/controllers/list.js | 2 +- src/controllers/movies/moviecollections.js | 2 +- src/scripts/playlists.js | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/components/collectionEditor/collectionEditor.js b/src/components/collectionEditor/collectionEditor.js index a6bdc51ee..18cc0d311 100644 --- a/src/components/collectionEditor/collectionEditor.js +++ b/src/components/collectionEditor/collectionEditor.js @@ -218,8 +218,8 @@ import 'flexStyles'; }); } - class CollectionEditor { - show(options) { + export class showEditor { + constructor(options) { const items = options.items || {}; currentServerId = options.serverId; @@ -285,4 +285,4 @@ import 'flexStyles'; } /* eslint-enable indent */ -export default CollectionEditor; +export default showEditor; diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index e969721d6..89834eefc 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -319,7 +319,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', switch (id) { case 'addtocollection': require(['collectionEditor'], function (collectionEditor) { - new collectionEditor.default().show({ + new collectionEditor.showEditor({ items: [itemId], serverId: serverId }).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); @@ -327,7 +327,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', break; case 'addtoplaylist': require(['playlistEditor'], function (playlistEditor) { - new playlistEditor.default().show({ + new playlistEditor.showEditor({ items: [itemId], serverId: serverId }).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); diff --git a/src/components/multiSelect/multiSelect.js b/src/components/multiSelect/multiSelect.js index 4919b9dd3..05a2b68f4 100644 --- a/src/components/multiSelect/multiSelect.js +++ b/src/components/multiSelect/multiSelect.js @@ -255,7 +255,7 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo switch (id) { case 'addtocollection': require(['collectionEditor'], function (collectionEditor) { - new collectionEditor.default().show({ + new collectionEditor.showEditor({ items: items, serverId: serverId }); @@ -265,7 +265,7 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo break; case 'playlist': require(['playlistEditor'], function (playlistEditor) { - new playlistEditor.default().show({ + new playlistEditor.showEditor({ items: items, serverId: serverId }); diff --git a/src/components/playlisteditor/playlisteditor.js b/src/components/playlisteditor/playlisteditor.js index 283acfd0f..7b1e915e1 100644 --- a/src/components/playlisteditor/playlisteditor.js +++ b/src/components/playlisteditor/playlisteditor.js @@ -216,8 +216,8 @@ import 'emby-button'; }); } - class PlaylistEditor { - show(options) { + export class showEditor { + constructor(options) { const items = options.items || {}; currentServerId = options.serverId; @@ -276,4 +276,4 @@ import 'emby-button'; } /* eslint-enable indent */ -export default PlaylistEditor; +export default showEditor; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index b1cc84f81..86273c89e 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -589,7 +589,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL require(['playlistEditor'], function (playlistEditor) { getSaveablePlaylistItems().then(function (items) { var serverId = items.length ? items[0].ServerId : ApiClient.serverId(); - new playlistEditor.default().show({ + new playlistEditor.showEditor({ items: items.map(function (i) { return i.Id; }), diff --git a/src/controllers/list.js b/src/controllers/list.js index f5af412cd..401df3f4d 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -386,7 +386,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' var instance = this; require(['playlistEditor'], function (playlistEditor) { - new playlistEditor.default().show({ + new playlistEditor.showEditor({ items: [], serverId: instance.params.serverId }); diff --git a/src/controllers/movies/moviecollections.js b/src/controllers/movies/moviecollections.js index bc47eecd2..65abca46e 100644 --- a/src/controllers/movies/moviecollections.js +++ b/src/controllers/movies/moviecollections.js @@ -242,7 +242,7 @@ define(['loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardB tabContent.querySelector('.btnNewCollection').addEventListener('click', function () { require(['collectionEditor'], function (collectionEditor) { var serverId = ApiClient.serverInfo().Id; - new collectionEditor.default().show({ + new collectionEditor.showEditor({ items: [], serverId: serverId }); diff --git a/src/scripts/playlists.js b/src/scripts/playlists.js index 7e5ec7ae4..a1868d313 100644 --- a/src/scripts/playlists.js +++ b/src/scripts/playlists.js @@ -184,7 +184,7 @@ define(['loading', 'listView', 'cardBuilder', 'libraryMenu', 'libraryBrowser', ' view.querySelector('.btnNewPlaylist').addEventListener('click', function () { require(['playlistEditor'], function (playlistEditor) { var serverId = ApiClient.serverInfo().Id; - new playlistEditor.default().show({ + new playlistEditor.showEditor({ items: [], serverId: serverId }); From 44320ef50526bf68154cbc490e4a88f9bf378da5 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Fri, 26 Jun 2020 23:16:10 +0300 Subject: [PATCH 0081/1168] apply suggestion --- src/components/dialogHelper/dialogHelper.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/dialogHelper/dialogHelper.js b/src/components/dialogHelper/dialogHelper.js index 73aee88f0..ca7c94a41 100644 --- a/src/components/dialogHelper/dialogHelper.js +++ b/src/components/dialogHelper/dialogHelper.js @@ -40,7 +40,7 @@ import 'scrollStyles'; try { parentNode.removeChild(elem); } catch (err) { - console.error(`error removing dialog element: ${err}`); + console.error('error removing dialog element: ' + err); } } } @@ -496,13 +496,15 @@ import 'scrollStyles'; return dlg; } + export function setOnOpen(val) { + globalOnOpenCallback = val; + } + /* eslint-enable indent */ export default { open: open, close: close, createDialog: createDialog, - setOnOpen: function (val) { - globalOnOpenCallback = val; - } + setOnOpen: setOnOpen }; From fbdd2328694e75b6a8b10479bc447770b9f605c9 Mon Sep 17 00:00:00 2001 From: Influence365 Date: Tue, 16 Jun 2020 18:42:55 +0100 Subject: [PATCH 0082/1168] Migrate htmlMediaHelper to ES6 fix typo --- package.json | 1 + src/components/htmlMediaHelper.js | 64 ++++++++++++------------------- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/package.json b/package.json index da5119035..00dfd9be7 100644 --- a/package.json +++ b/package.json @@ -114,6 +114,7 @@ "src/components/playback/remotecontrolautoplay.js", "src/components/playback/volumeosd.js", "src/components/playlisteditor/playlisteditor.js", + "src/components/htmlMediaHelper.js", "src/components/playmenu.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", diff --git a/src/components/htmlMediaHelper.js b/src/components/htmlMediaHelper.js index 3f17eeb33..4ff44cdcf 100644 --- a/src/components/htmlMediaHelper.js +++ b/src/components/htmlMediaHelper.js @@ -1,17 +1,22 @@ -define(['appSettings', 'browser', 'events'], function (appSettings, browser, events) { +/* eslint-disable indent */ + +import appSettings from 'appSettings' ; +import browser from 'browser'; +import events from 'events'; + 'use strict'; - function getSavedVolume() { + export function getSavedVolume() { return appSettings.get('volume') || 1; } - function saveVolume(value) { + export function saveVolume(value) { if (value) { appSettings.set('volume', value); } } - function getCrossOriginValue(mediaSource) { + export function getCrossOriginValue(mediaSource) { if (mediaSource.IsRemote) { return null; } @@ -30,7 +35,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve return false; } - function enableHlsShakaPlayer(item, mediaSource, mediaType) { + export function enableHlsShakaPlayer(item, mediaSource, mediaType) { /* eslint-disable-next-line compat/compat */ if (!!window.MediaSource && !!MediaSource.isTypeSupported) { @@ -56,7 +61,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve return false; } - function enableHlsJsPlayer(runTimeTicks, mediaType) { + export function enableHlsJsPlayer(runTimeTicks, mediaType) { if (window.MediaSource == null) { return false; @@ -98,7 +103,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve var recoverDecodingErrorDate; var recoverSwapAudioCodecDate; - function handleHlsJsMediaError(instance, reject) { + export function handleHlsJsMediaError(instance, reject) { var hlsPlayer = instance._hlsPlayer; @@ -134,7 +139,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve } } - function onErrorInternal(instance, type) { + export function onErrorInternal(instance, type) { // Needed for video if (instance.destroyCustomTrack) { @@ -148,7 +153,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve ]); } - function isValidDuration(duration) { + export function isValidDuration(duration) { if (duration && !isNaN(duration) && duration !== Number.POSITIVE_INFINITY && duration !== Number.NEGATIVE_INFINITY) { return true; } @@ -162,7 +167,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve } } - function seekOnPlaybackStart(instance, element, ticks, onMediaReady) { + export function seekOnPlaybackStart(instance, element, ticks, onMediaReady) { var seconds = (ticks || 0) / 10000000; @@ -200,7 +205,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve } } - function applySrc(elem, src, options) { + export function applySrc(elem, src, options) { if (window.Windows && options.mediaSource && options.mediaSource.IsLocal) { @@ -228,7 +233,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve elem.addEventListener('error', onErrorFn); } - function playWithPromise(elem, onErrorFn) { + export function playWithPromise(elem, onErrorFn) { try { var promise = elem.play(); @@ -256,7 +261,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve } } - function destroyCastPlayer(instance) { + export function destroyCastPlayer(instance) { var player = instance._castPlayer; if (player) { @@ -270,7 +275,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve } } - function destroyShakaPlayer(instance) { + export function destroyShakaPlayer(instance) { var player = instance._shakaPlayer; if (player) { try { @@ -283,7 +288,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve } } - function destroyHlsPlayer(instance) { + export function destroyHlsPlayer(instance) { var player = instance._hlsPlayer; if (player) { try { @@ -296,7 +301,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve } } - function destroyFlvPlayer(instance) { + export function destroyFlvPlayer(instance) { var player = instance._flvPlayer; if (player) { try { @@ -311,7 +316,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve } } - function bindEventsToHlsPlayer(instance, hls, elem, onErrorFn, resolve, reject) { + export function bindEventsToHlsPlayer(instance, hls, elem, onErrorFn, resolve, reject) { hls.on(Hls.Events.MANIFEST_PARSED, function () { playWithPromise(elem, onErrorFn).then(resolve, function () { @@ -403,7 +408,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve }); } - function onEndedInternal(instance, elem, onErrorFn) { + export function onEndedInternal(instance, elem, onErrorFn) { elem.removeEventListener('error', onErrorFn); @@ -427,7 +432,7 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve instance._currentPlayOptions = null; } - function getBufferedRanges(instance, elem) { + export function getBufferedRanges(instance, elem) { var ranges = []; var seekable = elem.buffered || []; @@ -462,23 +467,4 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve return ranges; } - return { - getSavedVolume: getSavedVolume, - saveVolume: saveVolume, - enableHlsJsPlayer: enableHlsJsPlayer, - enableHlsShakaPlayer: enableHlsShakaPlayer, - handleHlsJsMediaError: handleHlsJsMediaError, - isValidDuration: isValidDuration, - onErrorInternal: onErrorInternal, - seekOnPlaybackStart: seekOnPlaybackStart, - applySrc: applySrc, - playWithPromise: playWithPromise, - destroyHlsPlayer: destroyHlsPlayer, - destroyFlvPlayer: destroyFlvPlayer, - destroyCastPlayer: destroyCastPlayer, - bindEventsToHlsPlayer: bindEventsToHlsPlayer, - onEndedInternal: onEndedInternal, - getCrossOriginValue: getCrossOriginValue, - getBufferedRanges: getBufferedRanges - }; -}); + From d27fb43d682134a4c7a3d2ec47fe469648e5ff8b Mon Sep 17 00:00:00 2001 From: Influence365 Date: Tue, 16 Jun 2020 18:45:21 +0100 Subject: [PATCH 0083/1168] Migrate Groupedcards.js to ES6 --- package.json | 1 + src/components/groupedcards.js | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 00dfd9be7..24574d83d 100644 --- a/package.json +++ b/package.json @@ -114,6 +114,7 @@ "src/components/playback/remotecontrolautoplay.js", "src/components/playback/volumeosd.js", "src/components/playlisteditor/playlisteditor.js", + "src/components/groupedcards.js", "src/components/htmlMediaHelper.js", "src/components/playmenu.js", "src/components/sanatizefilename.js", diff --git a/src/components/groupedcards.js b/src/components/groupedcards.js index 602c4310f..2412e0f73 100644 --- a/src/components/groupedcards.js +++ b/src/components/groupedcards.js @@ -1,4 +1,9 @@ -define(['dom', 'appRouter', 'connectionManager'], function (dom, appRouter, connectionManager) { +/* eslint-disable indent */ + +import dom from 'dom'; +import appRouter from 'appRouter'; +import connectionManager from 'connectionManager'; + 'use strict'; function onGroupedCardClick(e, card) { @@ -31,15 +36,10 @@ define(['dom', 'appRouter', 'connectionManager'], function (dom, appRouter, conn } } - function onItemsContainerClick(e) { + export function onItemsContainerClick(e) { var groupedCard = dom.parentWithClass(e.target, 'groupedCard'); if (groupedCard) { onGroupedCardClick(e, groupedCard); } } - - return { - onItemsContainerClick: onItemsContainerClick - }; -}); From eab7ef00df508e1fcc2a29ade4b9f5f0d93a5eda Mon Sep 17 00:00:00 2001 From: Influence365 Date: Tue, 16 Jun 2020 18:46:54 +0100 Subject: [PATCH 0084/1168] Migrate themeLoader to ES6 fix bug remove console log Revert "remove console log" This reverts commit 944c1673df95b4047864f38a5e3c6fceb90b991c. Revert "Revert "remove console log"" This reverts commit 7b086194443b37a2515e17faaaa36e89161a9a5b. fix lint added eslint-enable indent fix lint fix lint remove console log Revert "remove console log" This reverts commit 944c1673df95b4047864f38a5e3c6fceb90b991c. Revert "Revert "remove console log"" This reverts commit 7b086194443b37a2515e17faaaa36e89161a9a5b. added eslint-enable indent fix lint --- package.json | 1 + src/components/groupedcards.js | 4 +-- src/components/htmlMediaHelper.js | 4 +-- src/scripts/themeLoader.js | 47 ++++++++++++++++--------------- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 24574d83d..16a94df5b 100644 --- a/package.json +++ b/package.json @@ -142,6 +142,7 @@ "src/scripts/keyboardNavigation.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", + "src/scripts/themeLoader.js", "src/scripts/settings/webSettings.js" ], "plugins": [ diff --git a/src/components/groupedcards.js b/src/components/groupedcards.js index 2412e0f73..719a599a6 100644 --- a/src/components/groupedcards.js +++ b/src/components/groupedcards.js @@ -4,8 +4,6 @@ import dom from 'dom'; import appRouter from 'appRouter'; import connectionManager from 'connectionManager'; - 'use strict'; - function onGroupedCardClick(e, card) { var itemId = card.getAttribute('data-id'); var serverId = card.getAttribute('data-serverid'); @@ -43,3 +41,5 @@ import connectionManager from 'connectionManager'; onGroupedCardClick(e, groupedCard); } } + + /* eslint-enable indent */ diff --git a/src/components/htmlMediaHelper.js b/src/components/htmlMediaHelper.js index 4ff44cdcf..062c80efa 100644 --- a/src/components/htmlMediaHelper.js +++ b/src/components/htmlMediaHelper.js @@ -4,8 +4,6 @@ import appSettings from 'appSettings' ; import browser from 'browser'; import events from 'events'; - 'use strict'; - export function getSavedVolume() { return appSettings.get('volume') || 1; } @@ -467,4 +465,4 @@ import events from 'events'; return ranges; } - +/* eslint-enable indent */ diff --git a/src/scripts/themeLoader.js b/src/scripts/themeLoader.js index f75d6d0e2..b071ee678 100644 --- a/src/scripts/themeLoader.js +++ b/src/scripts/themeLoader.js @@ -1,27 +1,30 @@ -define(['userSettings', 'skinManager', 'connectionManager', 'events'], function (userSettings, skinManager, connectionManager, events) { - 'use strict'; +import * as userSettings from 'userSettings'; +import skinManager from 'skinManager'; +import connectionManager from 'connectionManager'; +import events from 'events'; - var currentViewType; - pageClassOn('viewbeforeshow', 'page', function () { - var classList = this.classList; - var viewType = classList.contains('type-interior') || classList.contains('wizardPage') ? 'a' : 'b'; +var currentViewType; +pageClassOn('viewbeforeshow', 'page', function () { + var classList = this.classList; + var viewType = classList.contains('type-interior') || classList.contains('wizardPage') ? 'a' : 'b'; - if (viewType !== currentViewType) { - currentViewType = viewType; - var theme; - var context; + if (viewType !== currentViewType) { + currentViewType = viewType; + var theme; + var context; - if ('a' === viewType) { - theme = userSettings.dashboardTheme(); - context = 'serverdashboard'; - } else { - theme = userSettings.theme(); - } - - skinManager.setTheme(theme, context); + if ('a' === viewType) { + theme = userSettings.dashboardTheme(); + context = 'serverdashboard'; + } else { + theme = userSettings.theme(); } - }); - events.on(connectionManager, 'localusersignedin', function (e, user) { - currentViewType = null; - }); + + skinManager.setTheme(theme, context); + } }); + +events.on(connectionManager, 'localusersignedin', function (e, user) { + currentViewType = null; +}); + From c0c66dea5778ea0b36cf7b00828392b819ba7ebe Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 28 Jun 2020 16:36:00 +0900 Subject: [PATCH 0085/1168] code style changes --- src/components/settingshelper.js | 8 +++--- .../subtitleappearancehelper.js | 3 ++- .../subtitlesettings/subtitlesettings.js | 26 +++++++++---------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/components/settingshelper.js b/src/components/settingshelper.js index 3bbff9d8e..3db638c7a 100644 --- a/src/components/settingshelper.js +++ b/src/components/settingshelper.js @@ -1,18 +1,16 @@ import globalize from 'globalize'; + /** - * Helper for handling settings + * Helper for handling settings. * @module components/settingsHelper */ -export function populateLanguages(select, languages) { +export function populateLanguages(select, languages) { let html = ''; html += "'; - for (let i = 0, length = languages.length; i < length; i++) { - const culture = languages[i]; - html += "'; } diff --git a/src/components/subtitlesettings/subtitleappearancehelper.js b/src/components/subtitlesettings/subtitleappearancehelper.js index d1c55e1ae..f71075137 100644 --- a/src/components/subtitlesettings/subtitleappearancehelper.js +++ b/src/components/subtitlesettings/subtitleappearancehelper.js @@ -1,7 +1,8 @@ /** - * Subtitle settings visual helper + * Subtitle settings visual helper. * @module components/subtitleSettings/subtitleAppearanceHelper */ + function getTextStyles(settings, isCue) { let list = []; diff --git a/src/components/subtitlesettings/subtitlesettings.js b/src/components/subtitlesettings/subtitlesettings.js index 0db6999ba..73dddb9a2 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -16,7 +16,7 @@ import 'emby-checkbox'; import 'flexStyles'; /** - * Subtitle settings + * Subtitle settings. * @module components/subtitleSettings/subtitleSettings */ @@ -40,7 +40,7 @@ function loadForm(context, user, userSettings, appearanceSettings, apiClient) { context.querySelector('.fldBurnIn').classList.remove('hide'); } - let selectSubtitleLanguage = context.querySelector( '#selectSubtitleLanguage' ); + let selectSubtitleLanguage = context.querySelector('#selectSubtitleLanguage'); settingsHelper.populateLanguages(selectSubtitleLanguage, allCultures); @@ -67,7 +67,7 @@ function loadForm(context, user, userSettings, appearanceSettings, apiClient) { function saveUser(context, user, userSettingsInstance, appearanceKey, apiClient) { - let appearanceSettings = userSettingsInstance.getSubtitleAppearanceSettings( appearanceKey ); + let appearanceSettings = userSettingsInstance.getSubtitleAppearanceSettings(appearanceKey); appearanceSettings = Object.assign(appearanceSettings, getSubtitleAppearanceObject(context)); userSettingsInstance.setSubtitleAppearanceSettings(appearanceSettings, appearanceKey); @@ -105,9 +105,9 @@ function save(instance, context, userId, userSettings, apiClient, enableSaveConf function onSubtitleModeChange(e) { - let view = dom.parentWithClass( e.target, 'subtitlesettings' ); + let view = dom.parentWithClass(e.target, 'subtitlesettings'); - let subtitlesHelp = view.querySelectorAll( '.subtitlesHelp' ); + let subtitlesHelp = view.querySelectorAll('.subtitlesHelp'); for (let i = 0, length = subtitlesHelp.length; i < length; i++) { subtitlesHelp[i].classList.add('hide'); } @@ -116,13 +116,13 @@ function onSubtitleModeChange(e) { function onAppearanceFieldChange(e) { - let view = dom.parentWithClass( e.target, 'subtitlesettings' ); + let view = dom.parentWithClass(e.target, 'subtitlesettings'); - let appearanceSettings = getSubtitleAppearanceObject( view ); + let appearanceSettings = getSubtitleAppearanceObject(view); let elements = { - window: view.querySelector( '.subtitleappearance-preview-window' ), - text: view.querySelector( '.subtitleappearance-preview-text' ) + window: view.querySelector('.subtitleappearance-preview-window'), + text: view.querySelector('.subtitleappearance-preview-text') }; subtitleAppearanceHelper.applyStyles(elements, appearanceSettings); @@ -176,14 +176,14 @@ export class SubtitleSettings { loading.show(); let userId = self.options.userId; - let apiClient = connectionManager.getApiClient( self.options.serverId ); + let apiClient = connectionManager.getApiClient(self.options.serverId); let userSettings = self.options.userSettings; apiClient.getUser(userId).then(function (user) { userSettings.setUserInfo(userId, apiClient).then(function () { self.dataLoaded = true; - let appearanceSettings = userSettings.getSubtitleAppearanceSettings( self.options.appearanceKey ); + let appearanceSettings = userSettings.getSubtitleAppearanceSettings(self.options.appearanceKey); loadForm(context, user, userSettings, appearanceSettings, apiClient); }); @@ -191,14 +191,14 @@ export class SubtitleSettings { } submit() { - this.onSubmit( null ); + this.onSubmit(null); } destroy() { this.options = null; } - onSubmit( e ) { + onSubmit(e) { const self = this; let apiClient = connectionManager.getApiClient(self.options.serverId); let userId = self.options.userId; From b2de904b5196953d9f9d75a3ba41649e896bcc42 Mon Sep 17 00:00:00 2001 From: Influence365 Date: Tue, 16 Jun 2020 18:46:54 +0100 Subject: [PATCH 0086/1168] Migrate themeLoader to ES6 --- src/scripts/themeLoader.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/scripts/themeLoader.js b/src/scripts/themeLoader.js index b071ee678..3a3a60e56 100644 --- a/src/scripts/themeLoader.js +++ b/src/scripts/themeLoader.js @@ -27,4 +27,3 @@ pageClassOn('viewbeforeshow', 'page', function () { events.on(connectionManager, 'localusersignedin', function (e, user) { currentViewType = null; }); - From fd2d2a638615a17e9ea00ec9add3f514f9d6b81f Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 28 Jun 2020 09:38:06 +0200 Subject: [PATCH 0087/1168] Fix issue in eslintrc --- .eslintrc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index ab53f0f03..baf6d0e08 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -193,4 +193,4 @@ module.exports = { } } ] -} +}; From e663aecb3e80a2909a70ade18ff65d2c3e9a9441 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 28 Jun 2020 16:55:05 +0900 Subject: [PATCH 0088/1168] fix indentation --- src/components/groupedcards.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/groupedcards.js b/src/components/groupedcards.js index 719a599a6..543b295fe 100644 --- a/src/components/groupedcards.js +++ b/src/components/groupedcards.js @@ -42,4 +42,4 @@ import connectionManager from 'connectionManager'; } } - /* eslint-enable indent */ +/* eslint-enable indent */ From 62a2f4b17d6d7e5c53a8903c0ab3f7cccc9d335a Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Sun, 28 Jun 2020 23:46:27 +0300 Subject: [PATCH 0089/1168] Rearrange keydown event handling --- src/components/subtitlesync/subtitlesync.js | 3 +++ src/controllers/playback/videoosd.js | 15 ++++++++++++--- src/scripts/keyboardNavigation.js | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/components/subtitlesync/subtitlesync.js b/src/components/subtitlesync/subtitlesync.js index fb986ec34..c3c4b1bf6 100644 --- a/src/components/subtitlesync/subtitlesync.js +++ b/src/components/subtitlesync/subtitlesync.js @@ -65,6 +65,9 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html', event.preventDefault(); } } + + // FIXME: TV layout will require special handling for navigation keys. But now field is not focusable + event.stopPropagation(); }); subtitleSyncTextField.blur = function() { diff --git a/src/controllers/playback/videoosd.js b/src/controllers/playback/videoosd.js index 9be5660b4..60ae60e25 100644 --- a/src/controllers/playback/videoosd.js +++ b/src/controllers/playback/videoosd.js @@ -1080,7 +1080,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med */ var clickedElement; - function onWindowKeyDown(e) { + function onKeyDown(e) { clickedElement = e.srcElement; var key = keyboardnavigation.getKeyName(e); @@ -1194,6 +1194,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } } + function onKeyDownCapture() { + // Restart hide timer if OSD is currently visible + if (currentVisibleMenu) { + showOsd(); + } + } + function onWindowMouseDown(e) { clickedElement = e.srcElement; } @@ -1330,7 +1337,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med }); showOsd(); inputManager.on(window, onInputCommand); - dom.addEventListener(window, 'keydown', onWindowKeyDown, { + document.addEventListener('keydown', onKeyDown); + dom.addEventListener(document, 'keydown', onKeyDownCapture, { capture: true }); dom.addEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, { @@ -1350,7 +1358,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med statsOverlay.enabled(false); } - dom.removeEventListener(window, 'keydown', onWindowKeyDown, { + document.removeEventListener('keydown', onKeyDown); + dom.removeEventListener(document, 'keydown', onKeyDownCapture, { capture: true }); dom.removeEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, { diff --git a/src/scripts/keyboardNavigation.js b/src/scripts/keyboardNavigation.js index 6664afed5..6543207fe 100644 --- a/src/scripts/keyboardNavigation.js +++ b/src/scripts/keyboardNavigation.js @@ -78,7 +78,7 @@ export function isNavigationKey(key) { } export function enable() { - document.addEventListener('keydown', function (e) { + window.addEventListener('keydown', function (e) { const key = getKeyName(e); // Ignore navigation keys for non-TV From 33547e0d77b931612ee6e2addfee80a3f1697598 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 29 Jun 2020 11:20:57 +0200 Subject: [PATCH 0090/1168] Add defer to apploader script --- gulpfile.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 84f4558e6..8b407ec2a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -184,7 +184,12 @@ function copy(query) { function injectBundle() { return src(options.injectBundle.query, { base: './src/' }) .pipe(inject( - src(['src/scripts/apploader.js'], { read: false }, { base: './src/' }), { relative: true } + src(['src/scripts/apploader.js'], { read: false }, { base: './src/' }), { + relative: true, + transform: function (filepath) { + return ``; + } + } )) .pipe(dest('dist/')) .pipe(browserSync.stream()); From 3fcb8ed00ef28d3870fad748f9fce4386a20b3f8 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 29 Jun 2020 11:21:20 +0200 Subject: [PATCH 0091/1168] Add splash screen during app load --- src/index.html | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/index.html b/src/index.html index ed63ca1a9..d52be4346 100644 --- a/src/index.html +++ b/src/index.html @@ -52,7 +52,7 @@ - + @@ -69,12 +69,19 @@ Jellyfin @@ -103,7 +136,9 @@
-
+
+ +
From 783d4764482e52268c07ea94a5d954efbb004dba Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 29 Jun 2020 11:48:55 +0200 Subject: [PATCH 0092/1168] Add async to scripts injected by appLoader --- src/scripts/apploader.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scripts/apploader.js b/src/scripts/apploader.js index 0353c9535..183b765d1 100644 --- a/src/scripts/apploader.js +++ b/src/scripts/apploader.js @@ -11,6 +11,7 @@ src += `?v=${self.dashboardVersion}`; } script.src = src; + script.setAttribute('async', ''); if (onload) { script.onload = onload; From a66291a33d6f69037134d6082b2c9984c89d1889 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Mon, 29 Jun 2020 13:03:31 +0300 Subject: [PATCH 0093/1168] Fix handling of keydown event by volume slider and videoosd --- src/controllers/playback/videoosd.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/controllers/playback/videoosd.js b/src/controllers/playback/videoosd.js index 60ae60e25..30ac22e65 100644 --- a/src/controllers/playback/videoosd.js +++ b/src/controllers/playback/videoosd.js @@ -1319,9 +1319,11 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med var headerElement = document.querySelector('.skinHeader'); var osdBottomElement = document.querySelector('.videoOsdBottom-maincontrols'); + nowPlayingPositionSlider.enableKeyboardDragging(); + nowPlayingVolumeSlider.enableKeyboardDragging(); + if (layoutManager.tv) { nowPlayingPositionSlider.classList.add('focusable'); - nowPlayingPositionSlider.enableKeyboardDragging(); } view.addEventListener('viewbeforeshow', function (e) { @@ -1456,16 +1458,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med }, options); } - function setVolume() { - playbackManager.setVolume(this.value, currentPlayer); - } - view.querySelector('.buttonMute').addEventListener('click', function () { playbackManager.toggleMute(currentPlayer); }); - nowPlayingVolumeSlider.addEventListener('change', setVolume); - nowPlayingVolumeSlider.addEventListener('mousemove', setVolume); - nowPlayingVolumeSlider.addEventListener('touchmove', setVolume); + + nowPlayingVolumeSlider.addEventListener('input', (e) => { + playbackManager.setVolume(e.target.value, currentPlayer); + }); nowPlayingPositionSlider.addEventListener('change', function () { var player = currentPlayer; From 5924c17c7267ef96760c4fa978a4caa685ac97a4 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 29 Jun 2020 23:38:46 +0200 Subject: [PATCH 0094/1168] Improve blurhash performance --- src/components/images/imageLoader.js | 68 ++++++++++++---------------- src/components/images/style.css | 1 - 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index f7183515c..46e1c30e8 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -12,7 +12,7 @@ import 'css!./style'; fillImageElement(elem, source); } - async function itemBlurhashing(target, blurhashstr) { + function itemBlurhashing(target, blurhashstr) { if (blurhash.isBlurhashValid(blurhashstr)) { // Although the default values recommended by Blurhash developers is 32x32, a size of 18x18 seems to be the sweet spot for us, // improving the performance and reducing the memory usage, while retaining almost full blur quality. @@ -36,27 +36,21 @@ import 'css!./style'; imgData.data.set(pixels); ctx.putImageData(imgData, 0, 0); - let child = target.appendChild(canvas); + let child = target.parentNode.insertBefore(canvas, target); child.classList.add('blurhash-canvas'); - child.style.opacity = 1; if (userSettings.enableFastFadein()) { child.classList.add('lazy-blurhash-fadein-fast'); } else { child.classList.add('lazy-blurhash-fadein'); } + child.style.opacity = 1; + target.classList.add('blurhashed'); target.removeAttribute('data-blurhash'); } } - function switchCanvas(elem) { - let child = elem.getElementsByClassName('blurhash-canvas')[0]; - if (child) { - child.style.opacity = elem.getAttribute('data-src') ? 1 : 0; - } - } - export function fillImage(entry) { if (!entry) { throw new Error('entry cannot be null'); @@ -66,23 +60,16 @@ import 'css!./style'; if (target) { source = target.getAttribute('data-src'); - var blurhashstr = target.getAttribute('data-blurhash'); } else { source = entry; } - if (userSettings.enableBlurhash()) { - if (!target.classList.contains('blurhashed', 'non-blurhashable') && blurhashstr) { - itemBlurhashing(target, blurhashstr); - } else if (!blurhashstr && !target.classList.contains('blurhashed')) { - target.classList.add('non-blurhashable'); - } - } - if (entry.intersectionRatio > 0) { if (source) fillImageElement(target, source); } else if (!source) { - emptyImageElement(target); + requestAnimationFrame(() => { + emptyImageElement(target); + }); } } @@ -94,29 +81,24 @@ import 'css!./style'; let preloaderImg = new Image(); preloaderImg.src = url; - // This is necessary here, so changing blurhash settings without reloading the page works - if (!userSettings.enableBlurhash() || elem.classList.contains('non-blurhashable')) { - elem.classList.add('lazy-hidden'); - } + elem.classList.add('lazy-hidden'); preloaderImg.addEventListener('load', () => { - if (elem.tagName !== 'IMG') { - elem.style.backgroundImage = "url('" + url + "')"; - } else { - elem.setAttribute('src', url); - } - elem.removeAttribute('data-src'); + requestAnimationFrame(() => { + if (elem.tagName !== 'IMG') { + elem.style.backgroundImage = "url('" + url + "')"; + } else { + elem.setAttribute('src', url); + } + elem.removeAttribute('data-src'); - if (elem.classList.contains('non-blurhashable') || !userSettings.enableBlurhash()) { elem.classList.remove('lazy-hidden'); if (userSettings.enableFastFadein()) { elem.classList.add('lazy-image-fadein-fast'); } else { elem.classList.add('lazy-image-fadein'); } - } else { - switchCanvas(elem); - } + }); }); } @@ -132,15 +114,21 @@ import 'css!./style'; } elem.setAttribute('data-src', url); - if (elem.classList.contains('non-blurhashable') || !userSettings.enableBlurhash()) { - elem.classList.remove('lazy-image-fadein-fast', 'lazy-image-fadein'); - elem.classList.add('lazy-hidden'); - } else { - switchCanvas(elem); - } + elem.classList.remove('lazy-image-fadein-fast', 'lazy-image-fadein'); + elem.classList.add('lazy-hidden'); } export function lazyChildren(elem) { + for (const lazyElem of elem.getElementsByClassName('lazy')) { + if (userSettings.enableBlurhash()) { + var blurhashstr = lazyElem.getAttribute('data-blurhash'); + if (!lazyElem.classList.contains('blurhashed', 'non-blurhashable') && blurhashstr) { + itemBlurhashing(lazyElem, blurhashstr); + } else if (!blurhashstr && !lazyElem.classList.contains('blurhashed')) { + lazyElem.classList.add('non-blurhashable'); + } + } + } lazyLoader.lazyChildren(elem, fillImage); } diff --git a/src/components/images/style.css b/src/components/images/style.css index 2b09da2da..e4c706221 100644 --- a/src/components/images/style.css +++ b/src/components/images/style.css @@ -28,6 +28,5 @@ left: 0; width: 100%; height: 100%; - z-index: 100; pointer-events: none; } From 0361a2d58d213c819717154ae111fd1382e29d96 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 29 Jun 2020 23:57:05 +0200 Subject: [PATCH 0095/1168] Fix blurhash entry animation --- src/components/images/imageLoader.js | 22 +++++++++++----------- src/components/images/style.css | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index 46e1c30e8..b15333180 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -36,18 +36,18 @@ import 'css!./style'; imgData.data.set(pixels); ctx.putImageData(imgData, 0, 0); - let child = target.parentNode.insertBefore(canvas, target); - child.classList.add('blurhash-canvas'); - if (userSettings.enableFastFadein()) { - child.classList.add('lazy-blurhash-fadein-fast'); - } else { - child.classList.add('lazy-blurhash-fadein'); - } + requestAnimationFrame(() => { + canvas.classList.add('blurhash-canvas'); + if (userSettings.enableFastFadein()) { + canvas.classList.add('lazy-blurhash-fadein-fast'); + } else { + canvas.classList.add('lazy-blurhash-fadein'); + } - child.style.opacity = 1; - - target.classList.add('blurhashed'); - target.removeAttribute('data-blurhash'); + target.parentNode.insertBefore(canvas, target); + target.classList.add('blurhashed'); + target.removeAttribute('data-blurhash'); + }); } } diff --git a/src/components/images/style.css b/src/components/images/style.css index e4c706221..af982f158 100644 --- a/src/components/images/style.css +++ b/src/components/images/style.css @@ -12,12 +12,22 @@ opacity: 0; } +@keyframes fadein { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + .lazy-blurhash-fadein-fast { - transition: opacity 0.2s; + animation: fadein 0.2s; } .lazy-blurhash-fadein { - transition: opacity 0.7s; + animation: fadein 0.7s; } .blurhash-canvas { From c70ba48082b6a449736a74d4b063b5dac225b00b Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Mon, 29 Jun 2020 23:57:56 +0200 Subject: [PATCH 0096/1168] Adjust blurhash entry animation timing --- src/components/images/style.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/images/style.css b/src/components/images/style.css index af982f158..7e8b01aff 100644 --- a/src/components/images/style.css +++ b/src/components/images/style.css @@ -23,11 +23,11 @@ } .lazy-blurhash-fadein-fast { - animation: fadein 0.2s; + animation: fadein 0.1s; } .lazy-blurhash-fadein { - animation: fadein 0.7s; + animation: fadein 0.4s; } .blurhash-canvas { From 0766d360c1ee14c54ae5166e553392b6c8d6c29f Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Tue, 30 Jun 2020 00:10:13 +0200 Subject: [PATCH 0097/1168] Move check outside of loop --- src/components/images/imageLoader.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index b15333180..9981430a6 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -119,9 +119,9 @@ import 'css!./style'; } export function lazyChildren(elem) { - for (const lazyElem of elem.getElementsByClassName('lazy')) { - if (userSettings.enableBlurhash()) { - var blurhashstr = lazyElem.getAttribute('data-blurhash'); + if (userSettings.enableBlurhash()) { + for (const lazyElem of elem.getElementsByClassName('lazy')) { + const blurhashstr = lazyElem.getAttribute('data-blurhash'); if (!lazyElem.classList.contains('blurhashed', 'non-blurhashable') && blurhashstr) { itemBlurhashing(lazyElem, blurhashstr); } else if (!blurhashstr && !lazyElem.classList.contains('blurhashed')) { From 74016894602aca95573add7b5a03c88fe8ed3bfd Mon Sep 17 00:00:00 2001 From: 4d1m Date: Tue, 30 Jun 2020 08:39:00 +0000 Subject: [PATCH 0098/1168] Translated using Weblate (Romanian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ro/ --- src/strings/ro.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/strings/ro.json b/src/strings/ro.json index 8b560a341..1b1a3d5df 100644 --- a/src/strings/ro.json +++ b/src/strings/ro.json @@ -1558,5 +1558,10 @@ "EnableFasterAnimationsHelp": "Utilizați animații și tranziții mai rapide", "EnableFasterAnimations": "Animații mai rapide", "EnableDecodingColorDepth10Vp9": "Activați decodarea hardware pe 10 biți pentru VP9", - "EnableDecodingColorDepth10Hevc": "Activați decodarea hardware pe 10 biți pentru HEVC" + "EnableDecodingColorDepth10Hevc": "Activați decodarea hardware pe 10 biți pentru HEVC", + "LabelRepositoryName": "Nume Repertoriu", + "LabelRepositoryUrlHelp": "Locația manifestului repertoriului pe care doriți să o includeți.", + "LabelRepositoryUrl": "URL Repertoriu", + "HeaderNewRepository": "Repertoriu Nou", + "MessageNoRepositories": "Fără repertoriu." } From e3dfb055577c892abb30ae2bc0dc1667009ff9b4 Mon Sep 17 00:00:00 2001 From: 4d1m Date: Tue, 30 Jun 2020 08:40:52 +0000 Subject: [PATCH 0099/1168] Translated using Weblate (Romanian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ro/ --- src/strings/ro.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/strings/ro.json b/src/strings/ro.json index 1b1a3d5df..c1ef5caf1 100644 --- a/src/strings/ro.json +++ b/src/strings/ro.json @@ -1563,5 +1563,10 @@ "LabelRepositoryUrlHelp": "Locația manifestului repertoriului pe care doriți să o includeți.", "LabelRepositoryUrl": "URL Repertoriu", "HeaderNewRepository": "Repertoriu Nou", - "MessageNoRepositories": "Fără repertoriu." + "MessageNoRepositories": "Fără repertoriu.", + "ButtonPlayer": "Redare", + "Writers": "Scriitori", + "TabRepositories": "Repertorii", + "MessageAddRepository": "Dacă doriți să adăugați un repertoriu, faceți clic pe butonul de lângă antet și completați informațiile solicitate.", + "LabelRepositoryNameHelp": "Un nume personalizat pentru a distinge acest repertoriu de altele adăugate la serverul dvs." } From 82fa5f554cc604055ce303cc03459b561ea88a7b Mon Sep 17 00:00:00 2001 From: ferferga Date: Tue, 30 Jun 2020 19:28:52 +0200 Subject: [PATCH 0100/1168] Address review comments and keep focus on playlist update --- src/components/nowPlayingBar/nowPlayingBar.js | 4 +-- src/components/remotecontrol/remotecontrol.js | 30 +++++++++++++------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index dfb73a860..ebae04b08 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -159,7 +159,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', elem.querySelector('.previousTrackButton').addEventListener('click', function (e) { if (currentPlayer) { - if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) { + if (lastPlayerState.NowPlayingItem.MediaType === 'Audio' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) { // Cancel this event if doubleclick is fired if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) { return; @@ -440,7 +440,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', // See bindEvents for why this is necessary if (volumeSlider) { - volumeSliderContainer.classList.toggle('hide', showVolumeSlider); + volumeSliderContainer.classList.toggle('hide', !showVolumeSlider); if (!volumeSlider.dragging) { volumeSlider.value = volumeLevel || 0; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index a83009ad9..092c08680 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -333,7 +333,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } updateRepeatModeDisplay(playbackManager.getRepeatMode()); - onShuffleQueueModeChange(); + onShuffleQueueModeChange(false); updateNowPlayingInfo(context, state); } @@ -405,7 +405,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (!showMuteButton && !showVolumeSlider) { context.querySelector('.volumecontrol').classList.add('hide'); } else { - buttonMute.classList.toggle('hide', showMuteButton); + buttonMute.classList.toggle('hide', !showMuteButton); var nowPlayingVolumeSlider = context.querySelector('.nowPlayingVolumeSlider'); var nowPlayingVolumeSliderContainer = context.querySelector('.nowPlayingVolumeSliderContainer'); @@ -481,7 +481,16 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL }); var itemsContainer = context.querySelector('.playlist'); + let focusedItemPlaylistId = itemsContainer.querySelector('button:focus'); itemsContainer.innerHTML = html; + if (focusedItemPlaylistId !== null) { + focusedItemPlaylistId = focusedItemPlaylistId.getAttribute('data-playlistitemid'); + const newFocusedItem = itemsContainer.querySelector(`button[data-playlistitemid=${focusedItemPlaylistId}]`); + if (newFocusedItem !== null) { + newFocusedItem.focus(); + } + } + var playlistItemId = playbackManager.getCurrentPlaylistItemId(player); if (playlistItemId) { @@ -507,7 +516,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL updateRepeatModeDisplay(playbackManager.getRepeatMode()); } - function onShuffleQueueModeChange() { + function onShuffleQueueModeChange(updateView = true) { let shuffleMode = playbackManager.getQueueShuffleMode(this); let context = dlg; const cssClass = 'shuffleQueue-active'; @@ -516,15 +525,18 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL for (let shuffleButton of shuffleButtons) { switch (shuffleMode) { case 'Shuffle': - shuffleButton.classList.toggle(cssClass, true); + shuffleButton.classList.add(cssClass); break; case 'Sorted': default: - shuffleButton.classList.toggle(cssClass, false); + shuffleButton.classList.remove(cssClass); break; } } - onPlaylistUpdate(); + + if (updateView) { + onPlaylistUpdate(); + } } function onPlaylistUpdate(e) { @@ -550,7 +562,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (!state.NextMediaType) { updatePlayerState(player, dlg, {}); - loadPlaylist(dlg); + //onPlaylistUpdate(); Emby.Page.back(); } } @@ -562,7 +574,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function onStateChanged(event, state) { var player = this; updatePlayerState(player, dlg, state); - loadPlaylist(dlg, player); + onPlaylistUpdate(); } function onTimeUpdate(e) { @@ -720,7 +732,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL context.querySelector('.btnPreviousTrack').addEventListener('click', function (e) { if (currentPlayer) { - if (currentPlayer.id === 'htmlaudioplayer' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) { + if (lastPlayerState.NowPlayingItem.MediaType === 'Audio' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) { // Cancel this event if doubleclick is fired if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) { return; From 5626380d7f0326fe8943be720eab6b25d656f4b0 Mon Sep 17 00:00:00 2001 From: ferferga Date: Tue, 30 Jun 2020 20:16:14 +0200 Subject: [PATCH 0101/1168] Revert changes caused by faulty API changes (jellyfin/jellyfin#3435) --- src/plugins/sessionPlayer/plugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index 095cbc696..084aa027c 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -257,7 +257,7 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'] return { name: s.DeviceName, deviceName: s.DeviceName, - deviceType: 'Remote Control', + deviceType: s.DeviceType, id: s.Id, playerName: name, appName: s.Client, From 0d5041910dec5f9382a5ba0fcedda78f052dfd90 Mon Sep 17 00:00:00 2001 From: Fernando Date: Tue, 30 Jun 2020 18:10:06 +0000 Subject: [PATCH 0102/1168] Translated using Weblate (Spanish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es/ --- src/strings/es.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/strings/es.json b/src/strings/es.json index a19f28e57..396382003 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -192,7 +192,7 @@ "ExitFullscreen": "Quitar pantalla completa", "ExtraLarge": "Extragrande", "ExtractChapterImagesHelp": "La extracción de imágenes de capítulos permitirá a los clientes mostrar gráficamente la selección de escenas. El proceso puede ser lento, intensivo en recursos y requerir varios gigabytes de espacio. Se ejecuta cuando se añaden vídeos y también como tarea programable por la noche. El horario es configurable en el área de tareas programadas. No se recomienda ejecutar esta tarea durante las horas pico de uso.", - "FFmpegSavePathNotFound": "No podemos localizar FFmpeg usando la ruta que has ingresado. FFprobe también es necesario y debe existir en la misma carpeta. Estos componentes normalmente se agrupan juntos en la misma descarga. Compruebe la ruta y vuelva a intentarlo.", + "FFmpegSavePathNotFound": "No se ha podido localizar ffmpeg ni ffprobe en la ruta especificada. Comprueba la ruta y vuelva a intentarlo.", "FastForward": "Avanzar rápido", "Favorite": "Favorito", "Favorites": "Favoritos", @@ -404,7 +404,7 @@ "HeaderTunerDevices": "Sintonizadores", "HeaderTuners": "Sintonizadores", "HeaderTypeImageFetchers": "{0} capturadores de imágenes", - "HeaderTypeText": "Entrar texto", + "HeaderTypeText": "Introducir texto", "HeaderUpcomingOnTV": "Próximamente en la televisión", "HeaderUploadImage": "Subir imagen", "HeaderUser": "Usuario", @@ -749,8 +749,8 @@ "LabelYourFirstName": "Tu nombre:", "LabelYoureDone": "¡Ya está!", "LabelZipCode": "Código postal:", - "LabelffmpegPath": "Ruta de FFmpeg:", - "LabelffmpegPathHelp": "a ruta de acceso al archivo de la aplicación FFmpeg o la carpeta que contiene FFmpeg.", + "LabelffmpegPath": "Ruta de ffmpeg:", + "LabelffmpegPathHelp": "Carpeta donde se encuentra ffmpeg, el componente utilizado para realizar las conversiones. No la cambies a no ser que sepas lo que haces.", "LanNetworksHelp": "Lista de direcciones IP separadas por comas o entradas de dirección IP / máscara de red para redes que se considerarán en la red local al imponer restricciones de ancho de banda. Si se establece, todas las demás direcciones IP se considerarán en la red externa y estarán sujetas a las restricciones de ancho de banda externo. Si se deja en blanco, solo se considera que la subred del servidor está en la red local.", "Large": "Grande", "LatestFromLibrary": "Reciente en {0}", From f6fc874ebe453b0c86b7443794f62975734217e4 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Tue, 30 Jun 2020 22:16:32 +0200 Subject: [PATCH 0103/1168] Prefix splash properties --- src/index.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/index.html b/src/index.html index d52be4346..f8d867cb1 100644 --- a/src/index.html +++ b/src/index.html @@ -104,6 +104,16 @@ width: 0.8em; } + @-webkit-keyframes fadein { + from { + opacity: 0; + } + + to { + opacity: 1; + } + } + @keyframes fadein { from { opacity: 0; @@ -115,6 +125,7 @@ } .splashLogo { + -webkit-animation: fadein 0.5s; animation: fadein 0.5s; width: 30%; height: 30%; @@ -125,6 +136,7 @@ position: fixed; top: 50%; left: 50%; + -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); } From 95978564fea6e2d0da08290a7d99a4c9c7f6532b Mon Sep 17 00:00:00 2001 From: Zyzto Date: Wed, 1 Jul 2020 00:24:14 +0000 Subject: [PATCH 0104/1168] Translated using Weblate (Arabic) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ar/ --- src/strings/ar.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/strings/ar.json b/src/strings/ar.json index 09de31d04..98825bf80 100644 --- a/src/strings/ar.json +++ b/src/strings/ar.json @@ -922,7 +922,7 @@ "ValueSpecialEpisodeName": "خاص - {0}", "HeaderFavoriteAlbums": "الألبومات المفضلة", "HeaderAlbumArtists": "فناني الألبومات", - "Genres": "الأنواع", + "Genres": "التضنيفات", "Folders": "المجلدات", "Favorites": "المفضلة", "Collections": "مجموعات", @@ -964,7 +964,7 @@ "AllEpisodes": "كل الحلقات", "AllComplexFormats": "جميع التنسيقات المعقدة (ASS ، SSA ، VOBSUB ، PGS ، SUB / IDX ، ...)", "AllChannels": "كل القنوات", - "Albums": "ألبومات", + "Albums": "البومات", "Aired": "عرضت", "AirDate": "تاريخ العرض", "AddedOnValue": "أضيفت", From a28cbe41164840b1b0484578d0737002210e63f0 Mon Sep 17 00:00:00 2001 From: Adam Bokor Date: Wed, 1 Jul 2020 06:24:32 +0000 Subject: [PATCH 0105/1168] Translated using Weblate (Hungarian) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/hu/ --- src/strings/hu.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/strings/hu.json b/src/strings/hu.json index dfd45cf63..0cd02587f 100644 --- a/src/strings/hu.json +++ b/src/strings/hu.json @@ -1571,5 +1571,6 @@ "LabelRepositoryUrlHelp": "A hivatkozni kívánt tároló manifeszt helye.", "LabelRepositoryUrl": "Tároló URL-je", "HeaderNewRepository": "Új tároló", - "MessageNoRepositories": "Nincs tároló." + "MessageNoRepositories": "Nincs tároló.", + "Writers": "Írók" } From 21b17e80972479072fe3886cd140f26d3db67dd7 Mon Sep 17 00:00:00 2001 From: Fernando Date: Wed, 1 Jul 2020 13:22:56 +0200 Subject: [PATCH 0106/1168] Focus contextbutton after update if focused beforehand Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com> --- src/components/remotecontrol/remotecontrol.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 655761d93..e23051870 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -178,9 +178,13 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL let contextButton = context.querySelector('.btnToggleContextMenu'); // We remove the previous event listener by replacing the item in each update event + const autoFocusContextButton = document.activeElement === contextButton; let contextButtonClone = contextButton.cloneNode(true); contextButton.parentNode.replaceChild(contextButtonClone, contextButton); contextButton = context.querySelector('.btnToggleContextMenu'); + if (autoFocusContextButton) { + contextButton.focus(); + } var options = { play: false, queue: false, From 737341934ac44dc1c3f8ce4bf73f79654994a344 Mon Sep 17 00:00:00 2001 From: ferferga Date: Wed, 1 Jul 2020 15:05:08 +0200 Subject: [PATCH 0107/1168] Add stop playback option in mobile's layout context menu --- src/components/itemContextMenu.js | 18 +++++++++++------- src/components/playback/playbackmanager.js | 5 +---- src/components/remotecontrol/remotecontrol.js | 2 ++ src/strings/en-us.json | 3 ++- src/strings/es.json | 3 ++- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index 434d29b32..835d62f9b 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -28,6 +28,14 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', } } + if (playbackManager.getCurrentPlayer() !== null && options.stopPlayback) { + commands.push({ + name: globalize.translate('StopPlayback'), + id: 'stopPlayback', + icon: 'stop' + }); + } + if (playbackManager.canQueue(item)) { if (options.queue !== false) { commands.push({ @@ -44,13 +52,6 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', icon: 'playlist_add' }); } - - //if (options.queueAllFromHere) { - // commands.push({ - // name: globalize.translate("QueueAllFromHere"), - // id: "queueallfromhere" - // }); - //} } if (item.IsFolder || item.Type === 'MusicArtist' || item.Type === 'MusicGenre') { @@ -431,6 +432,9 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', play(item, false, true, true); getResolveFunction(resolve, id)(); break; + case 'stopPlayback': + playbackManager.stop(); + break; case 'record': require(['recordingCreator'], function (recordingCreator) { recordingCreator.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index b3193f750..33d781687 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3709,10 +3709,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return textStreamUrl; }; - PlaybackManager.prototype.stop = function (player) { - - player = player || this._currentPlayer; - + PlaybackManager.prototype.stop = function (player = this._currentPlayer) { if (player) { if (enableLocalPlaylistManagement(player)) { diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index e23051870..fcc7a7fe4 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -185,9 +185,11 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (autoFocusContextButton) { contextButton.focus(); } + let stopPlayback = false || layoutManager.mobile; var options = { play: false, queue: false, + stopPlayback: stopPlayback, openAlbum: false, positionTo: contextButton }; diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 7df61c4c5..02fb652bf 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1563,5 +1563,6 @@ "EnableBlurhashHelp": "Images that are still being loaded will be displayed with a blurred placeholder", "ButtonSyncPlay": "SyncPlay", "ButtonCast": "Cast", - "ButtonPlayer": "Player" + "ButtonPlayer": "Player", + "StopPlayback": "Stop playback" } diff --git a/src/strings/es.json b/src/strings/es.json index 84f01c94e..b86c958b5 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1573,5 +1573,6 @@ "LabelRepositoryUrl": "URL del repositorio", "HeaderNewRepository": "Nuevo repositorio", "MessageNoRepositories": "Sin repositorios.", - "Writers": "Escritores" + "Writers": "Escritores", + "StopPlayback": "Detener la reproducción" } From 08a995fe2cdae4bd511428ab19f425508ac7b53a Mon Sep 17 00:00:00 2001 From: ferferga Date: Wed, 1 Jul 2020 15:54:51 +0200 Subject: [PATCH 0108/1168] Add 'Clear Queue' option --- src/components/itemContextMenu.js | 24 ++++++++++++++----- src/components/nowPlayingBar/nowPlayingBar.js | 1 + src/components/playback/playbackmanager.js | 9 +++++++ src/components/playback/playqueuemanager.js | 8 +++++++ src/components/remotecontrol/remotecontrol.js | 15 ++++++++---- src/strings/en-us.json | 3 ++- src/strings/es.json | 3 ++- 7 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index 835d62f9b..96f8f2d35 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -28,12 +28,21 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', } } - if (playbackManager.getCurrentPlayer() !== null && options.stopPlayback) { - commands.push({ - name: globalize.translate('StopPlayback'), - id: 'stopPlayback', - icon: 'stop' - }); + if (playbackManager.getCurrentPlayer() !== null) { + if (options.stopPlayback) { + commands.push({ + name: globalize.translate('StopPlayback'), + id: 'stopPlayback', + icon: 'stop' + }); + } + if (options.clearQueue) { + commands.push({ + name: globalize.translate('ClearQueue'), + id: 'clearQueue', + icon: 'clear_all' + }); + } } if (playbackManager.canQueue(item)) { @@ -435,6 +444,9 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', case 'stopPlayback': playbackManager.stop(); break; + case 'clearQueue': + playbackManager.clearQueue(); + break; case 'record': require(['recordingCreator'], function (recordingCreator) { recordingCreator.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index ebae04b08..a229fab4b 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -584,6 +584,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', let options = { play: false, queue: false, + clearQueue: true, positionTo: contextButton }; apiClient.getCurrentUser().then(function (user) { diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 33d781687..ae94ba8d4 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3971,6 +3971,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.trigger(player, 'shufflequeuemodechange'); }; + PlaybackManager.prototype.clearQueue = function (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) { name = normalizeName(name); diff --git a/src/components/playback/playqueuemanager.js b/src/components/playback/playqueuemanager.js index 7d2f941f0..2f411091c 100644 --- a/src/components/playback/playqueuemanager.js +++ b/src/components/playback/playqueuemanager.js @@ -84,6 +84,14 @@ define([], function () { this._shuffleMode = 'Sorted'; }; + PlayQueueManager.prototype.clearPlaylist = function (clearCurrentItem = false) { + const currentPlaylistItem = this._playlist.splice(this.getCurrentPlaylistIndex(), 1)[0]; + this._playlist = []; + if (!clearCurrentItem) { + this._playlist.push(currentPlaylistItem); + } + }; + function arrayInsertAt(destArray, pos, arrayToInsert) { var args = []; args.push(pos); // where to insert diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index fcc7a7fe4..6f02bed15 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -190,6 +190,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL play: false, queue: false, stopPlayback: stopPlayback, + clearQueue: true, openAlbum: false, positionTo: contextButton }; @@ -551,14 +552,18 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function onPlaylistItemRemoved(e, info) { var context = dlg; - var playlistItemIds = info.playlistItemIds; + if (info !== undefined) { + var playlistItemIds = info.playlistItemIds; - for (var i = 0, length = playlistItemIds.length; i < length; i++) { - var listItem = context.querySelector('.listItem[data-playlistItemId="' + playlistItemIds[i] + '"]'); + for (var i = 0, length = playlistItemIds.length; i < length; i++) { + var listItem = context.querySelector('.listItem[data-playlistItemId="' + playlistItemIds[i] + '"]'); - if (listItem) { - listItem.parentNode.removeChild(listItem); + if (listItem) { + listItem.parentNode.removeChild(listItem); + } } + } else { + onPlaylistUpdate(); } } diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 02fb652bf..41dd4cd50 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1564,5 +1564,6 @@ "ButtonSyncPlay": "SyncPlay", "ButtonCast": "Cast", "ButtonPlayer": "Player", - "StopPlayback": "Stop playback" + "StopPlayback": "Stop playback", + "ClearQueue": "Clear queue" } diff --git a/src/strings/es.json b/src/strings/es.json index b86c958b5..960e5a897 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1574,5 +1574,6 @@ "HeaderNewRepository": "Nuevo repositorio", "MessageNoRepositories": "Sin repositorios.", "Writers": "Escritores", - "StopPlayback": "Detener la reproducción" + "StopPlayback": "Detener la reproducción", + "ClearQueue": "Borrar la cola" } From b4d4b4fab9c5735cbc0b01f80cd1b4a83c076776 Mon Sep 17 00:00:00 2001 From: ferferga Date: Wed, 1 Jul 2020 15:56:47 +0200 Subject: [PATCH 0109/1168] Context menu option parity between miniplayer and fullscreen player --- src/components/remotecontrol/remotecontrol.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 6f02bed15..e77d29ae3 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -195,12 +195,14 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL positionTo: contextButton }; var apiClient = connectionManager.getApiClient(item.ServerId); - apiClient.getCurrentUser().then(function (user) { - contextButton.addEventListener('click', function () { - itemContextMenu.show(Object.assign({ - item: item, - user: user - }, options)); + apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (fullItem) { + apiClient.getCurrentUser().then(function (user) { + contextButton.addEventListener('click', function () { + itemContextMenu.show(Object.assign({ + item: fullItem, + user: user + }, options)); + }); }); }); setImageUrl(context, state, url); From a715bd8e6a5c2a89c7092c8f839d6835148e7619 Mon Sep 17 00:00:00 2001 From: Fernando Date: Wed, 1 Jul 2020 16:37:31 +0200 Subject: [PATCH 0110/1168] Improve syntax Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com> --- src/components/remotecontrol/remotecontrol.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index e77d29ae3..398f7bc26 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -185,7 +185,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (autoFocusContextButton) { contextButton.focus(); } - let stopPlayback = false || layoutManager.mobile; + const stopPlayback = !!layoutManager.mobile; var options = { play: false, queue: false, From 9277e1f951830ff82199703af8b1039c362b9a24 Mon Sep 17 00:00:00 2001 From: Viperinius Date: Wed, 1 Jul 2020 12:41:05 +0000 Subject: [PATCH 0111/1168] Translated using Weblate (German) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/ --- src/strings/de.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/strings/de.json b/src/strings/de.json index 2318cf810..6e3bd00f4 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -1586,5 +1586,7 @@ "LabelRepositoryName": "Name des Repository", "LabelRepositoryUrl": "URL des Repository", "HeaderNewRepository": "Neues Repository", - "MessageNoRepositories": "Keine Repositories." + "MessageNoRepositories": "Keine Repositories.", + "ButtonPlayer": "Player", + "Writers": "Autoren" } From f44a8bb6bef83610ce091490866643f5e7db5f71 Mon Sep 17 00:00:00 2001 From: Fernando Date: Wed, 1 Jul 2020 11:31:02 +0000 Subject: [PATCH 0112/1168] Translated using Weblate (Spanish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es/ --- src/strings/es.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/strings/es.json b/src/strings/es.json index 396382003..87e1f298c 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -249,7 +249,7 @@ "HeaderChannels": "Canales", "HeaderChapterImages": "Imágenes de capítulos", "HeaderCodecProfile": "Perfil de códec", - "HeaderCodecProfileHelp": "Perfiles de códec indican las limitaciones de un dispositivo cuando se reproducen códecs específicos. Si se aplica una limitación entonces el medio se transcodificará, incluso si el códec está configurado para reproducción directa.", + "HeaderCodecProfileHelp": "Los perfiles de los códecs indican las limitaciones de un dispositivo cuando reproduce un códec en específico. Si lo que se va a reproducir no está dentro de estos límites (por ejemplo, bitrate demasiado alto), el contenido se convertirá, incluso si el códec está configurado para reproducción directa.", "HeaderConfigureRemoteAccess": "Configurar acceso remoto", "HeaderConfirmPluginInstallation": "Confirmar la instalación del complemento", "HeaderConfirmProfileDeletion": "Confirmar borrado del perfil", @@ -257,7 +257,7 @@ "HeaderConnectToServer": "Conectar al servidor", "HeaderConnectionFailure": "Fallo de conexión", "HeaderContainerProfile": "Perfil de contenedor", - "HeaderContainerProfileHelp": "Perfiles de códec indican las limitaciones de un dispositivo mientras reproduce formatos específicos. Si se aplica una limitación entonces el medio se transcodificará, incluso si el formato está configurado para reproducción directa.", + "HeaderContainerProfileHelp": "Los perfiles de los contenedores indican las limitaciones de un dispositivo cuando reproduce contenido en un formato en específico. Si lo que se va a reproducir no está dentro de estos límites, el contenedor del contenido se cambiará, incluso si el formato está configurado para reproducción directa.", "HeaderContinueListening": "Continuar escuchando", "HeaderContinueWatching": "Continuar viendo", "HeaderCustomDlnaProfiles": "Perfiles personalizados", @@ -375,7 +375,7 @@ "HeaderSelectServer": "Selecionar servidor", "HeaderSelectServerCachePath": "Seleccione la ruta para el caché del servidor", "HeaderSelectServerCachePathHelp": "Navega o introduce la ruta para alojar los archivos caché del servidor. Tienes que tener permisos de escritura en esa carpeta.", - "HeaderSelectTranscodingPath": "Seleccione la ruta temporal del transcodificador", + "HeaderSelectTranscodingPath": "Ruta para los archivos temporales de las conversiones", "HeaderSelectTranscodingPathHelp": "Busca o escribe la ruta que se utilizará para guardar los archivos temporales que se generarán mientras se convierten los archivos. Jellyfin debe tener permisos de escritura en la carpeta.", "HeaderSendMessage": "Enviar mensaje", "HeaderSeries": "Series", @@ -621,7 +621,7 @@ "LabelMoviePrefixHelp": "Si se aplica un prefijo a títulos de películas, escríbalo para que el servidor pueda manejarlo correctamente.", "LabelMovieRecordingPath": "Ruta de grabaciones de películas (opcional):", "LabelMusicStreamingTranscodingBitrate": "Tasa de bits para la reproducción de música:", - "LabelMusicStreamingTranscodingBitrateHelp": "Especifique una tasa de bits máxima cuando transmita música.", + "LabelMusicStreamingTranscodingBitrateHelp": "Tasa de bits máxima para la música.", "LabelName": "Nombre:", "LabelNewName": "Nuevo nombre:", "LabelNewPassword": "Nueva contraseña:", @@ -674,7 +674,7 @@ "LabelRefreshMode": "Modo de refresco:", "LabelReleaseDate": "Fecha de lanzamiento:", "LabelRemoteClientBitrateLimit": "Límite de la transmisión de tasa de bits por internet (Mbps):", - "LabelRemoteClientBitrateLimitHelp": "Un límite opcional de tasa de bits para todos los dispositivos fuera de la red. Esto es útil para evitar que los dispositivos soliciten una tasa de bits más alta que la que su conexión a Internet puede manejar. Esto puede ocasionar una mayor carga de la CPU en su servidor para transcodificar vídeos sobre la marcha a una tasa de bits más baja.", + "LabelRemoteClientBitrateLimitHelp": "Especifica el bitrate máximo para los dispositivos que se encuentren fuera de la red local. Esto es útil para permitir la reproducción del contenido que tengas con una tasa de bits muy alta cuando la conexión a internet de tu servidor o la del cliente no sea lo suficientemente rápida. Esto ocasionará mayor carga, ya que el contenido que supere esta tasa de bits se convertirá para que esté dentro del límite establecido.", "LabelRuntimeMinutes": "Tiempo de ejecución (minutos):", "LabelSaveLocalMetadata": "Guardar imágenes y etiquetas en las carpetas de medios", "LabelSaveLocalMetadataHelp": "Guardar imágenes y etiquetas directamente en las carpetas en las que estén los elementos hará que se puedan editar más fácilmente.", @@ -935,7 +935,7 @@ "OptionEnableM2tsModeHelp": "Activar modo M2TS cuando se codifique a MPEGTS.", "OptionEnded": "Finalizado", "OptionEquals": "Igual", - "OptionEstimateContentLength": "Estimar la longitud del contenido al transcodificar", + "OptionEstimateContentLength": "Estimar la longitud del contenido al convertirse", "OptionEveryday": "Todos los días", "OptionExternallyDownloaded": "Descarga externa", "OptionExtractChapterImage": "Habilitar la extracción de imágenes de los capítulos", @@ -973,8 +973,8 @@ "OptionProfileVideoAudio": "Vídeo y audio", "OptionProtocolHls": "Emisión HTTP en directo", "OptionReleaseDate": "Fecha de lanzamiento", - "OptionReportByteRangeSeekingWhenTranscoding": "Indicar que el servidor soporta la búsqueda de byte al transcodificar", - "OptionReportByteRangeSeekingWhenTranscodingHelp": "Esto es necesario para algunos dispositivos que no buscan el tiempo muy bien.", + "OptionReportByteRangeSeekingWhenTranscoding": "Indicar que el servidor soporta la búsqueda de byte al convertir", + "OptionReportByteRangeSeekingWhenTranscodingHelp": "Esto es necesario para los dispositivos que no cambian entre los diferentes puntos de tiempo del contenido correctamente.", "OptionRequirePerfectSubtitleMatch": "Sólo descargar subtítulos que son una combinación perfecta para mis archivos de vídeo", "OptionRequirePerfectSubtitleMatchHelp": "Requerir una coincidencia perfecta filtra los subtítulos para incluir sólo aquellos que coinciden con el archivo de vídeo. Desmarcando esta opción, aumentará la probabilidad de que los subtítulos se descarguen, pero puede que el texto del subtítulo no coincida con el vídeo.", "OptionResElement": "Elemento res", @@ -1355,7 +1355,7 @@ "LabelPasswordResetProvider": "Proveedor de restablecimiento de contraseña:", "LabelServerName": "Nombre del servidor:", "LabelTranscodePath": "Ruta para los archivos temporales de las conversiones:", - "LabelTranscodes": "Transcodificaciones:", + "LabelTranscodes": "Archivos temporales de las conversiones:", "LabelUserLoginAttemptsBeforeLockout": "Intentos fallidos de inicio de sesión antes de que el usuario sea bloqueado:", "DashboardVersionNumber": "Versión: {0}", "DashboardServerName": "Servidor: {0}", @@ -1497,7 +1497,7 @@ "AlbumArtist": "Artista del álbum", "Album": "Álbum", "LabelDeinterlaceMethod": "Metodo de desentrelazar:", - "DeinterlaceMethodHelp": "Seleccione el método de desentrelazar para el transcodificar de contenido entrelazado.", + "DeinterlaceMethodHelp": "Seleccione el tipo de filtro que se aplicará para desentrelazar el contenido que esté entrelazado durante la conversión.", "LabelLibraryPageSize": "Tamaño de la página de la biblioteca:", "LabelLibraryPageSizeHelp": "Establece la cantidad de artículos a mostrar en una página de la biblioteca. Ponlo en 0 para desactivar la paginación.", "UnsupportedPlayback": "No es posible desencriptar contenido protegido mediante DRM; sin embargo se intentará su reproducción. Algunos archivos pueden aparecer completamente negros debido a encriptación u otras características no soportadas, como títulos interactivos.", From 429c47f414851bf95f24736ce2e08e370c397eac Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Thu, 25 Jun 2020 16:53:45 +0800 Subject: [PATCH 0113/1168] add tonemapping settings --- src/components/itemMediaInfo/itemMediaInfo.js | 12 +++++ src/components/playerstats/playerstats.js | 28 ++++++++++ src/controllers/dashboard/encodingsettings.js | 26 +++++++++ src/encodingsettings.html | 53 +++++++++++++++++++ src/strings/en-us.json | 26 ++++++++- src/strings/zh-cn.json | 26 ++++++++- 6 files changed, 169 insertions(+), 2 deletions(-) diff --git a/src/components/itemMediaInfo/itemMediaInfo.js b/src/components/itemMediaInfo/itemMediaInfo.js index 81c84b6a2..ad5f261ec 100644 --- a/src/components/itemMediaInfo/itemMediaInfo.js +++ b/src/components/itemMediaInfo/itemMediaInfo.js @@ -90,6 +90,18 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', if (stream.BitDepth) { attributes.push(createAttribute(globalize.translate('MediaInfoBitDepth'), stream.BitDepth + ' bit')); } + if (stream.VideoRange) { + attributes.push(createAttribute(globalize.translate('MediaInfoVideoRange'), stream.VideoRange)); + } + if (stream.ColorSpace) { + attributes.push(createAttribute(globalize.translate('MediaInfoColorSpace'), stream.ColorSpace)); + } + if (stream.ColorTransfer) { + attributes.push(createAttribute(globalize.translate('MediaInfoColorTransfer'), stream.ColorTransfer)); + } + if (stream.ColorPrimaries) { + attributes.push(createAttribute(globalize.translate('MediaInfoColorPrimaries'), stream.ColorPrimaries)); + } if (stream.PixelFormat) { attributes.push(createAttribute(globalize.translate('MediaInfoPixelFormat'), stream.PixelFormat)); } diff --git a/src/components/playerstats/playerstats.js b/src/components/playerstats/playerstats.js index a65baf355..e3fe6452f 100644 --- a/src/components/playerstats/playerstats.js +++ b/src/components/playerstats/playerstats.js @@ -279,6 +279,34 @@ define(['events', 'globalize', 'playbackManager', 'connectionManager', 'syncPlay }); } + if (videoStream.VideoRange) { + sessionStats.push({ + label: globalize.translate('LabelVideoRange'), + value: videoStream.VideoRange + }); + } + + if (videoStream.ColorSpace) { + sessionStats.push({ + label: globalize.translate('LabelColorSpace'), + value: videoStream.ColorSpace + }); + } + + if (videoStream.ColorTransfer) { + sessionStats.push({ + label: globalize.translate('LabelColorTransfer'), + value: videoStream.ColorTransfer + }); + } + + if (videoStream.ColorPrimaries) { + sessionStats.push({ + label: globalize.translate('LabelColorPrimaries'), + value: videoStream.ColorPrimaries + }); + } + var audioInfos = []; if (audioCodec) { diff --git a/src/controllers/dashboard/encodingsettings.js b/src/controllers/dashboard/encodingsettings.js index 0f54f9d70..d72832128 100644 --- a/src/controllers/dashboard/encodingsettings.js +++ b/src/controllers/dashboard/encodingsettings.js @@ -8,12 +8,20 @@ define(['jQuery', 'loading', 'globalize', 'dom', 'libraryMenu'], function ($, lo page.querySelector('#chkDecodingColorDepth10Hevc').checked = config.EnableDecodingColorDepth10Hevc; page.querySelector('#chkDecodingColorDepth10Vp9').checked = config.EnableDecodingColorDepth10Vp9; page.querySelector('#chkHardwareEncoding').checked = config.EnableHardwareEncoding; + page.querySelector('#chkTonemapping').checked = config.EnableTonemapping; $('#selectVideoDecoder', page).val(config.HardwareAccelerationType); $('#selectThreadCount', page).val(config.EncodingThreadCount); $('#txtDownMixAudioBoost', page).val(config.DownMixAudioBoost); page.querySelector('.txtEncoderPath').value = config.EncoderAppPathDisplay || ''; $('#txtTranscodingTempPath', page).val(systemInfo.TranscodingTempPath || ''); $('#txtVaapiDevice', page).val(config.VaapiDevice || ''); + $('#txtOpenclDevice', page).val(config.OpenclDevice || ''); + $('#selectTonemappingAlgorithm', page).val(config.TonemappingAlgorithm); + $('#selectTonemappingRange', page).val(config.TonemappingRange); + $('#txtTonemappingDesat', page).val(config.TonemappingDesat); + $('#txtTonemappingThreshold', page).val(config.TonemappingThreshold); + $('#txtTonemappingPeak', page).val(config.TonemappingPeak); + $('#txtTonemappingParam', page).val(config.TonemappingParam || ''); page.querySelector('#selectEncoderPreset').value = config.EncoderPreset || ''; page.querySelector('#txtH264Crf').value = config.H264Crf || ''; page.querySelector('#selectDeinterlaceMethod').value = config.DeinterlaceMethod || ''; @@ -59,6 +67,14 @@ define(['jQuery', 'loading', 'globalize', 'dom', 'libraryMenu'], function ($, lo config.EncodingThreadCount = $('#selectThreadCount', form).val(); config.HardwareAccelerationType = $('#selectVideoDecoder', form).val(); config.VaapiDevice = $('#txtVaapiDevice', form).val(); + config.OpenclDevice = $('#txtOpenclDevice', form).val(); + config.EnableTonemapping = form.querySelector('#chkTonemapping').checked; + config.TonemappingAlgorithm = form.querySelector('#selectTonemappingAlgorithm').value; + config.TonemappingRange = form.querySelector('#selectTonemappingRange').value; + config.TonemappingDesat = $('#txtTonemappingDesat', form).val(); + config.TonemappingThreshold = $('#txtTonemappingThreshold', form).val(); + config.TonemappingPeak = $('#txtTonemappingPeak', form).val(); + config.TonemappingParam = $('#txtTonemappingParam', form).val(); config.EncoderPreset = form.querySelector('#selectEncoderPreset').value; config.H264Crf = parseInt(form.querySelector('#txtH264Crf').value || '0'); config.DeinterlaceMethod = form.querySelector('#selectDeinterlaceMethod').value; @@ -141,6 +157,16 @@ define(['jQuery', 'loading', 'globalize', 'dom', 'libraryMenu'], function ($, lo page.querySelector('#txtVaapiDevice').removeAttribute('required'); } + if ('nvenc' == this.value) { + page.querySelector('.fldOpenclDevice').classList.remove('hide'); + page.querySelector('#txtOpenclDevice').setAttribute('required', 'required'); + page.querySelector('.tonemappingOptions').classList.remove('hide'); + } else { + page.querySelector('.fldOpenclDevice').classList.add('hide'); + page.querySelector('#txtOpenclDevice').removeAttribute('required'); + page.querySelector('.tonemappingOptions').classList.add('hide'); + } + if (this.value) { page.querySelector('.hardwareAccelerationOptions').classList.remove('hide'); } else { diff --git a/src/encodingsettings.html b/src/encodingsettings.html index 858375b14..c020df912 100644 --- a/src/encodingsettings.html +++ b/src/encodingsettings.html @@ -31,6 +31,11 @@
${LabelVaapiDeviceHelp}
+
+ +
${LabelOpenclDeviceHelp}
+
+

${LabelEnableHardwareDecodingFor}

@@ -89,6 +94,54 @@
+
+
+ +
${AllowTonemappingHelp}
+
+
+ + +
+
+ +
${TonemappingRangeHelp}
+
+
+ +
${LabelTonemappingDesatHelp}
+
+
+ +
${LabelTonemappingThresholdHelp}
+
+
+ +
${LabelTonemappingPeakHelp}
+
+
+ +
${LabelTonemappingParamHelp}
+
+
+
+ +
+
+ +
+
${SubtitleVerticalPositionHelp}
+
+ +
+ +
'; @@ -35,7 +35,7 @@ import 'emby-button'; html += item.AppName || ''; html += ''; html += ''; - var date = datetime.parseISO8601Date(item.DateCreated, true); + const date = datetime.parseISO8601Date(item.DateCreated, true); html += datetime.toLocaleDateString(date) + ' ' + datetime.getDisplayTime(date); html += ''; return html += ''; @@ -71,12 +71,12 @@ import 'emby-button'; } pageIdOn('pageinit', 'apiKeysPage', function () { - var page = this; + const page = this; page.querySelector('.btnNewKey').addEventListener('click', function () { showNewKeyPrompt(page); }); page.querySelector('.tblApiKeys').addEventListener('click', function (e) { - var btnRevoke = dom.parentWithClass(e.target, 'btnRevoke'); + const btnRevoke = dom.parentWithClass(e.target, 'btnRevoke'); if (btnRevoke) { revoke(page, btnRevoke.getAttribute('data-token')); diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index 55e24f49d..7aa706840 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -17,16 +17,15 @@ import indicators from 'indicators'; import 'listViewStyle'; import 'emby-button'; import 'flexStyles'; -import 'emby-button'; import 'emby-itemscontainer'; /* eslint-disable indent */ function showPlaybackInfo(btn, session) { - import('alert').then(({default: Alert}) => { - var title; - var text = []; - var displayPlayMethod = playMethodHelper.getDisplayPlayMethod(session); + import('alert').then(({default: alert}) => { + let title; + let text = []; + const displayPlayMethod = playMethodHelper.getDisplayPlayMethod(session); if (displayPlayMethod === 'DirectStream') { title = globalize.translate('DirectStreaming'); @@ -72,7 +71,7 @@ import 'emby-itemscontainer'; function showOptionsMenu(btn, session) { import('actionsheet').then(({default: actionsheet}) => { - var menuItems = []; + const menuItems = []; if (session.ServerId && session.DeviceId !== connectionManager.deviceId()) { menuItems.push({ @@ -105,14 +104,14 @@ import 'emby-itemscontainer'; } function onActiveDevicesClick(evt) { - var btn = dom.parentWithClass(evt.target, 'sessionCardButton'); + const btn = dom.parentWithClass(evt.target, 'sessionCardButton'); if (btn) { - var card = dom.parentWithClass(btn, 'card'); + const card = dom.parentWithClass(btn, 'card'); if (card) { - var sessionId = card.id; - var session = (DashboardPage.sessionsList || []).filter(function (dashboardSession) { + const sessionId = card.id; + const session = (DashboardPage.sessionsList || []).filter(function (dashboardSession) { return 'session' + dashboardSession.Id === sessionId; })[0]; @@ -134,11 +133,11 @@ import 'emby-itemscontainer'; } function filterSessions(sessions) { - var list = []; - var minActiveDate = new Date().getTime() - 9e5; + const list = []; + const minActiveDate = new Date().getTime() - 9e5; - for (var i = 0, length = sessions.length; i < length; i++) { - var session = sessions[i]; + for (let i = 0, length = sessions.length; i < length; i++) { + const session = sessions[i]; if (!session.NowPlayingItem && !session.UserId) { continue; @@ -160,7 +159,7 @@ import 'emby-itemscontainer'; EnableTotalRecordCount: false, EnableImageTypes: 'Primary,Thumb,Backdrop' }).then(function (result) { - var itemsContainer = view.querySelector('.activeRecordingItems'); + const itemsContainer = view.querySelector('.activeRecordingItems'); if (!result.Items.length) { view.querySelector('.activeRecordingsSection').classList.add('hide'); @@ -190,7 +189,7 @@ import 'emby-itemscontainer'; function reloadSystemInfo(view, apiClient) { apiClient.getSystemInfo().then(function (systemInfo) { view.querySelector('#serverName').innerHTML = globalize.translate('DashboardServerName', systemInfo.ServerName); - var localizedVersion = globalize.translate('DashboardVersionNumber', systemInfo.Version); + let localizedVersion = globalize.translate('DashboardVersionNumber', systemInfo.Version); if (systemInfo.SystemUpdateLevel !== 'Release') { localizedVersion += ' ' + systemInfo.SystemUpdateLevel; @@ -226,31 +225,31 @@ import 'emby-itemscontainer'; } function renderActiveConnections(view, sessions) { - var html = ''; + let html = ''; DashboardPage.sessionsList = sessions; - var parentElement = view.querySelector('.activeDevices'); - var cardElem = parentElement.querySelector('.card'); + const parentElement = view.querySelector('.activeDevices'); + const cardElem = parentElement.querySelector('.card'); if (cardElem) { cardElem.classList.add('deadSession'); } - for (var i = 0, length = sessions.length; i < length; i++) { - var session = sessions[i]; - var rowId = 'session' + session.Id; - var elem = view.querySelector('#' + rowId); + for (let i = 0, length = sessions.length; i < length; i++) { + const session = sessions[i]; + const rowId = 'session' + session.Id; + const elem = view.querySelector('#' + rowId); if (elem) { DashboardPage.updateSession(elem, session); } else { - var nowPlayingItem = session.NowPlayingItem; - var className = 'scalableCard card activeSession backdropCard backdropCard-scalable'; + const nowPlayingItem = session.NowPlayingItem; + const className = 'scalableCard card activeSession backdropCard backdropCard-scalable'; html += '
'; html += '
'; html += '
'; html += '
'; html += '
'; - var imgUrl = DashboardPage.getNowPlayingImageUrl(nowPlayingItem); + const imgUrl = DashboardPage.getNowPlayingImageUrl(nowPlayingItem); if (imgUrl) { html += '
'; html += nowPlayingName.html; html += '
'; @@ -282,7 +281,7 @@ import 'emby-itemscontainer'; html += '
'; if (nowPlayingItem && nowPlayingItem.RunTimeTicks) { - var percent = 100 * (session.PlayState.PositionTicks || 0) / nowPlayingItem.RunTimeTicks; + const percent = 100 * (session.PlayState.PositionTicks || 0) / nowPlayingItem.RunTimeTicks; html += indicators.getProgressHtml(percent, { containerClass: 'playbackProgress' }); @@ -294,7 +293,7 @@ import 'emby-itemscontainer'; } if (session.TranscodingInfo && session.TranscodingInfo.CompletionPercentage) { - var percent = session.TranscodingInfo.CompletionPercentage.toFixed(1); + const percent = session.TranscodingInfo.CompletionPercentage.toFixed(1); html += indicators.getProgressHtml(percent, { containerClass: 'transcodingProgress' }); @@ -311,7 +310,7 @@ import 'emby-itemscontainer'; html += '
'; html += '
'; - var btnCssClass = session.ServerId && session.NowPlayingItem && session.SupportsRemoteControl ? '' : ' hide'; + let btnCssClass = session.ServerId && session.NowPlayingItem && session.SupportsRemoteControl ? '' : ' hide'; const playIcon = session.PlayState.IsPaused ? 'pause' : 'play_arrow'; html += ''; @@ -329,7 +328,7 @@ import 'emby-itemscontainer'; html += '
'; html += '
'; - var userImage = DashboardPage.getUserImage(session); + const userImage = DashboardPage.getUserImage(session); html += userImage ? '
" : '
'; html += '
'; html += DashboardPage.getUsersHtml(session); @@ -343,7 +342,7 @@ import 'emby-itemscontainer'; } parentElement.insertAdjacentHTML('beforeend', html); - var deadSessionElem = parentElement.querySelector('.deadSession'); + const deadSessionElem = parentElement.querySelector('.deadSession'); if (deadSessionElem) { deadSessionElem.parentNode.removeChild(deadSessionElem); @@ -351,7 +350,7 @@ import 'emby-itemscontainer'; } function renderRunningTasks(view, tasks) { - var html = ''; + let html = ''; tasks = tasks.filter(function (task) { if ('Idle' != task.State) { return !task.IsHidden; @@ -366,13 +365,13 @@ import 'emby-itemscontainer'; view.querySelector('.runningTasksContainer').classList.add('hide'); } - for (var i = 0, length = tasks.length; i < length; i++) { - var task = tasks[i]; + for (let i = 0, length = tasks.length; i < length; i++) { + const task = tasks[i]; html += '

'; html += task.Name + '
'; if (task.State === 'Running') { - var progress = (task.CurrentProgressPercentage || 0).toFixed(1); + const progress = (task.CurrentProgressPercentage || 0).toFixed(1); html += ''; html += progress + '%'; html += ''; @@ -398,9 +397,9 @@ import 'emby-itemscontainer'; apiClient.sendMessage('ScheduledTasksInfoStop'); }, getSessionNowPlayingStreamInfo: function (session) { - var html = ''; - var showTranscodingInfo = false; - var displayPlayMethod = playMethodHelper.getDisplayPlayMethod(session); + let html = ''; + let showTranscodingInfo = false; + const displayPlayMethod = playMethodHelper.getDisplayPlayMethod(session); if (displayPlayMethod === 'DirectStream') { html += globalize.translate('DirectStreaming'); @@ -417,7 +416,7 @@ import 'emby-itemscontainer'; } if (showTranscodingInfo) { - var line = []; + const line = []; if (session.TranscodingInfo) { if (session.TranscodingInfo.Bitrate) { @@ -449,8 +448,8 @@ import 'emby-itemscontainer'; return html; }, getSessionNowPlayingTime: function (session) { - var nowPlayingItem = session.NowPlayingItem; - var html = ''; + const nowPlayingItem = session.NowPlayingItem; + let html = ''; if (nowPlayingItem) { if (session.PlayState.PositionTicks) { @@ -474,8 +473,8 @@ import 'emby-itemscontainer'; return session.Client + ' ' + session.ApplicationVersion; }, getNowPlayingName: function (session) { - var imgUrl = ''; - var nowPlayingItem = session.NowPlayingItem; + let imgUrl = ''; + const nowPlayingItem = session.NowPlayingItem; // FIXME: It seems that, sometimes, server sends date in the future, so date-fns displays messages like 'in less than a minute'. We should fix // how dates are returned by the server when the session is active and show something like 'Active now', instead of past/future sentences if (!nowPlayingItem) { @@ -485,8 +484,8 @@ import 'emby-itemscontainer'; }; } - var topText = itemHelper.getDisplayName(nowPlayingItem); - var bottomText = ''; + let topText = itemHelper.getDisplayName(nowPlayingItem); + let bottomText = ''; if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) { bottomText = topText; @@ -526,13 +525,13 @@ import 'emby-itemscontainer'; }; }, getUsersHtml: function (session) { - var html = []; + const html = []; if (session.UserId) { html.push(session.UserName); } - for (var i = 0, length = session.AdditionalUsers.length; i < length; i++) { + for (let i = 0, length = session.AdditionalUsers.length; i < length; i++) { html.push(session.AdditionalUsers[i].UserName); } @@ -550,7 +549,7 @@ import 'emby-itemscontainer'; }, updateSession: function (row, session) { row.classList.remove('deadSession'); - var nowPlayingItem = session.NowPlayingItem; + const nowPlayingItem = session.NowPlayingItem; if (nowPlayingItem) { row.classList.add('playingSession'); @@ -570,7 +569,7 @@ import 'emby-itemscontainer'; row.querySelector('.btnSessionInfo').classList.add('hide'); } - var btnSessionPlayPause = row.querySelector('.btnSessionPlayPause'); + const btnSessionPlayPause = row.querySelector('.btnSessionPlayPause'); if (session.ServerId && nowPlayingItem && session.SupportsRemoteControl && session.DeviceId !== connectionManager.deviceId()) { btnSessionPlayPause.classList.remove('hide'); @@ -588,18 +587,18 @@ import 'emby-itemscontainer'; row.querySelector('.sessionNowPlayingTime').innerHTML = DashboardPage.getSessionNowPlayingTime(session); row.querySelector('.sessionUserName').innerHTML = DashboardPage.getUsersHtml(session); row.querySelector('.sessionAppSecondaryText').innerHTML = DashboardPage.getAppSecondaryText(session); - var nowPlayingName = DashboardPage.getNowPlayingName(session); - var nowPlayingInfoElem = row.querySelector('.sessionNowPlayingInfo'); + const nowPlayingName = DashboardPage.getNowPlayingName(session); + const nowPlayingInfoElem = row.querySelector('.sessionNowPlayingInfo'); if (!(nowPlayingName.image && nowPlayingName.image == nowPlayingInfoElem.getAttribute('data-imgsrc'))) { nowPlayingInfoElem.innerHTML = nowPlayingName.html; nowPlayingInfoElem.setAttribute('data-imgsrc', nowPlayingName.image || ''); } - var playbackProgressElem = row.querySelector('.playbackProgress'); + const playbackProgressElem = row.querySelector('.playbackProgress'); if (nowPlayingItem && nowPlayingItem.RunTimeTicks) { - var percent = 100 * (session.PlayState.PositionTicks || 0) / nowPlayingItem.RunTimeTicks; + const percent = 100 * (session.PlayState.PositionTicks || 0) / nowPlayingItem.RunTimeTicks; playbackProgressElem.outerHTML = indicators.getProgressHtml(percent, { containerClass: 'playbackProgress' }); @@ -609,10 +608,10 @@ import 'emby-itemscontainer'; }); } - var transcodingProgress = row.querySelector('.transcodingProgress'); + const transcodingProgress = row.querySelector('.transcodingProgress'); if (session.TranscodingInfo && session.TranscodingInfo.CompletionPercentage) { - var percent = session.TranscodingInfo.CompletionPercentage.toFixed(1); + const percent = session.TranscodingInfo.CompletionPercentage.toFixed(1); transcodingProgress.outerHTML = indicators.getProgressHtml(percent, { containerClass: 'transcodingProgress' }); @@ -622,8 +621,8 @@ import 'emby-itemscontainer'; }); } - var imgUrl = DashboardPage.getNowPlayingImageUrl(nowPlayingItem) || ''; - var imgElem = row.querySelector('.sessionNowPlayingContent'); + const imgUrl = DashboardPage.getNowPlayingImageUrl(nowPlayingItem) || ''; + const imgElem = row.querySelector('.sessionNowPlayingContent'); if (imgUrl != imgElem.getAttribute('data-src')) { imgElem.style.backgroundImage = imgUrl ? "url('" + imgUrl + "')" : ''; @@ -637,7 +636,7 @@ import 'emby-itemscontainer'; } }, getClientImage: function (connection) { - var iconUrl = imageHelper.getDeviceIcon(connection); + const iconUrl = imageHelper.getDeviceIcon(connection); return ""; }, getNowPlayingImageUrl: function (item) { @@ -667,7 +666,7 @@ import 'emby-itemscontainer'; }); } - var imageTags = (item || {}).ImageTags || {}; + const imageTags = (item || {}).ImageTags || {}; if (item && imageTags.Thumb) { return ApiClient.getScaledImageUrl(item.Id, { @@ -721,7 +720,7 @@ import 'emby-itemscontainer'; }, systemUpdateTaskKey: 'SystemUpdateTask', stopTask: function (btn, id) { - var page = dom.parentWithClass(btn, 'page'); + const page = dom.parentWithClass(btn, 'page'); ApiClient.stopScheduledTask(id).then(function () { pollForInfo(page, ApiClient); }); @@ -734,7 +733,7 @@ import 'emby-itemscontainer'; confirmText: globalize.translate('ButtonRestart'), primary: 'delete' }).then(function () { - var page = dom.parentWithClass(btn, 'page'); + const page = dom.parentWithClass(btn, 'page'); page.querySelector('#btnRestartServer').disabled = true; page.querySelector('#btnShutdown').disabled = true; ApiClient.restartServer(); @@ -749,7 +748,7 @@ import 'emby-itemscontainer'; confirmText: globalize.translate('ButtonShutdown'), primary: 'delete' }).then(function () { - var page = dom.parentWithClass(btn, 'page'); + const page = dom.parentWithClass(btn, 'page'); page.querySelector('#btnRestartServer').disabled = true; page.querySelector('#btnShutdown').disabled = true; ApiClient.shutdownServer(); @@ -796,11 +795,11 @@ import 'emby-itemscontainer'; } } - var serverId = ApiClient.serverId(); + const serverId = ApiClient.serverId(); view.querySelector('.activeDevices').addEventListener('click', onActiveDevicesClick); view.addEventListener('viewshow', function () { - var page = this; - var apiClient = ApiClient; + const page = this; + const apiClient = ApiClient; if (apiClient) { loading.show(); @@ -837,7 +836,7 @@ import 'emby-itemscontainer'; } }); view.addEventListener('viewbeforehide', function () { - var apiClient = ApiClient; + const apiClient = ApiClient; events.off(serverNotifications, 'RestartRequired', onRestartRequired); events.off(serverNotifications, 'ServerShuttingDown', onServerShuttingDown); events.off(serverNotifications, 'ServerRestarting', onServerRestarting); @@ -851,14 +850,14 @@ import 'emby-itemscontainer'; } }); view.addEventListener('viewdestroy', function () { - var page = this; - var userActivityLog = page.userActivityLog; + const page = this; + const userActivityLog = page.userActivityLog; if (userActivityLog) { userActivityLog.destroy(); } - var serverActivityLog = page.serverActivityLog; + const serverActivityLog = page.serverActivityLog; if (serverActivityLog) { serverActivityLog.destroy(); diff --git a/src/controllers/dashboard/encodingsettings.js b/src/controllers/dashboard/encodingsettings.js index fd91db4bb..aac18360a 100644 --- a/src/controllers/dashboard/encodingsettings.js +++ b/src/controllers/dashboard/encodingsettings.js @@ -32,7 +32,7 @@ import libraryMenu from 'libraryMenu'; function onSaveEncodingPathFailure(response) { loading.hide(); - var msg = ''; + let msg = ''; msg = globalize.translate('FFmpegSavePathNotFound'); import('alert').then(({default: alert}) => { @@ -54,9 +54,9 @@ import libraryMenu from 'libraryMenu'; } function onSubmit() { - var form = this; + const form = this; - var onDecoderConfirmed = function () { + const onDecoderConfirmed = function () { loading.show(); ApiClient.getNamedConfiguration('encoding').then(function (config) { config.DownMixAudioBoost = $('#txtDownMixAudioBoost', form).val(); @@ -105,7 +105,7 @@ import libraryMenu from 'libraryMenu'; function setDecodingCodecsVisible(context, value) { value = value || ''; - var any; + let any; Array.prototype.forEach.call(context.querySelectorAll('.chkDecodeCodec'), function (c) { if (-1 === c.getAttribute('data-types').split(',').indexOf(value)) { dom.parentWithTag(c, 'LABEL').classList.add('hide'); @@ -136,7 +136,7 @@ import libraryMenu from 'libraryMenu'; } $(document).on('pageinit', '#encodingSettingsPage', function () { - var page = this; + const page = this; page.querySelector('#selectVideoDecoder').addEventListener('change', function () { if ('vaapi' == this.value) { page.querySelector('.fldVaapiDevice').classList.remove('hide'); @@ -156,7 +156,7 @@ import libraryMenu from 'libraryMenu'; }); $('#btnSelectEncoderPath', page).on('click.selectDirectory', function () { import('directorybrowser').then(({default: directoryBrowser}) => { - var picker = new directoryBrowser(); + const picker = new directoryBrowser(); picker.show({ includeFiles: true, callback: function (path) { @@ -171,7 +171,7 @@ import libraryMenu from 'libraryMenu'; }); $('#btnSelectTranscodingTempPath', page).on('click.selectDirectory', function () { import('directorybrowser').then(({default: directoryBrowser}) => { - var picker = new directoryBrowser(); + const picker = new directoryBrowser(); picker.show({ callback: function (path) { if (path) { @@ -190,7 +190,7 @@ import libraryMenu from 'libraryMenu'; }).on('pageshow', '#encodingSettingsPage', function () { loading.show(); libraryMenu.setTabs('playback', 0, getTabs); - var page = this; + const page = this; ApiClient.getNamedConfiguration('encoding').then(function (config) { ApiClient.getSystemInfo().then(function (systemInfo) { loadPage(page, config, systemInfo); From 5545c05089ea8197d3afa0f62c67010a72bfab0f Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 10 Jul 2020 13:54:05 +0100 Subject: [PATCH 0210/1168] updates to lint and profile --- src/controllers/dashboard/users/userparentalcontrol.js | 1 - src/controllers/dashboard/users/userpasswordpage.js | 3 +-- src/controllers/dashboard/users/userprofilespage.js | 2 +- src/controllers/user/profile.js | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/controllers/dashboard/users/userparentalcontrol.js b/src/controllers/dashboard/users/userparentalcontrol.js index 907f99b8c..38ada8b8f 100644 --- a/src/controllers/dashboard/users/userparentalcontrol.js +++ b/src/controllers/dashboard/users/userparentalcontrol.js @@ -6,7 +6,6 @@ import globalize from 'globalize'; import 'listViewStyle'; import 'paper-icon-button-light'; - /* eslint-disable indent */ function populateRatings(allParentalRatings, page) { diff --git a/src/controllers/dashboard/users/userpasswordpage.js b/src/controllers/dashboard/users/userpasswordpage.js index e9731e50e..4f9b7e251 100644 --- a/src/controllers/dashboard/users/userpasswordpage.js +++ b/src/controllers/dashboard/users/userpasswordpage.js @@ -3,7 +3,6 @@ import libraryMenu from 'libraryMenu'; import globalize from 'globalize'; import 'emby-button'; - /* eslint-disable indent */ function loadUser(page, params) { @@ -187,6 +186,6 @@ import 'emby-button'; view.addEventListener('viewshow', function () { loadUser(view, params); }); - }; + } /* eslint-enable indent */ diff --git a/src/controllers/dashboard/users/userprofilespage.js b/src/controllers/dashboard/users/userprofilespage.js index 46e9665b7..cf246cdea 100644 --- a/src/controllers/dashboard/users/userprofilespage.js +++ b/src/controllers/dashboard/users/userprofilespage.js @@ -276,5 +276,5 @@ import 'flexStyles'; pageIdOn('pagebeforeshow', 'userProfilesPage', function () { loadData(this); }); - + /* eslint-enable indent */ diff --git a/src/controllers/user/profile.js b/src/controllers/user/profile.js index fd7d1e32c..b8d1e209c 100644 --- a/src/controllers/user/profile.js +++ b/src/controllers/user/profile.js @@ -83,7 +83,7 @@ define(['controllers/dashboard/users/userpasswordpage', 'loading', 'libraryMenu' return function (view, params) { reloadUser(view); - new UserPasswordPage(view, params); + new UserPasswordPage.default(view, params); view.querySelector('#btnDeleteImage').addEventListener('click', function () { require(['confirm'], function (confirm) { confirm(globalize.translate('DeleteImageConfirmation'), globalize.translate('DeleteImage')).then(function () { From 376f00c0599d98978e9811bcd4d73bddb5d0a662 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 11 Jul 2020 14:04:11 +0100 Subject: [PATCH 0211/1168] update variable declerations --- src/controllers/dashboard/users/useredit.js | 30 ++++---- .../dashboard/users/userlibraryaccess.js | 54 +++++++------- src/controllers/dashboard/users/usernew.js | 22 +++--- .../dashboard/users/userparentalcontrol.js | 70 +++++++++---------- .../dashboard/users/userpasswordpage.js | 28 ++++---- .../dashboard/users/userprofilespage.js | 36 +++++----- 6 files changed, 117 insertions(+), 123 deletions(-) diff --git a/src/controllers/dashboard/users/useredit.js b/src/controllers/dashboard/users/useredit.js index 02e0dade0..ba14cbe1b 100644 --- a/src/controllers/dashboard/users/useredit.js +++ b/src/controllers/dashboard/users/useredit.js @@ -9,21 +9,19 @@ import globalize from 'globalize'; ApiClient.getJSON(ApiClient.getUrl('Channels', { SupportsMediaDeletion: true })).then(function (channelsResult) { - var i; - var length; - var folder; - var isChecked; - var checkedAttribute; - var html = ''; + let folder; + let isChecked; + let checkedAttribute; + let html = ''; - for (i = 0, length = mediaFolders.length; i < length; i++) { + for (let i = 0, length = mediaFolders.length; i < length; i++) { folder = mediaFolders[i]; isChecked = user.Policy.EnableContentDeletion || -1 != user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id); checkedAttribute = isChecked ? ' checked="checked"' : ''; html += ''; } - for (i = 0, length = channelsResult.Items.length; i < length; i++) { + for (let i = 0, length = channelsResult.Items.length; i < length; i++) { folder = channelsResult.Items[i]; isChecked = user.Policy.EnableContentDeletion || -1 != user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id); checkedAttribute = isChecked ? ' checked="checked"' : ''; @@ -42,9 +40,9 @@ import globalize from 'globalize'; page.querySelector('.fldSelectLoginProvider').classList.add('hide'); } - var currentProviderId = user.Policy.AuthenticationProviderId; + const currentProviderId = user.Policy.AuthenticationProviderId; page.querySelector('.selectLoginProvider').innerHTML = providers.map(function (provider) { - var selected = provider.Id === currentProviderId || providers.length < 2 ? ' selected' : ''; + const selected = provider.Id === currentProviderId || providers.length < 2 ? ' selected' : ''; return ''; }); } @@ -56,15 +54,14 @@ import globalize from 'globalize'; page.querySelector('.fldSelectPasswordResetProvider').classList.add('hide'); } - var currentProviderId = user.Policy.PasswordResetProviderId; + const currentProviderId = user.Policy.PasswordResetProviderId; page.querySelector('.selectPasswordResetProvider').innerHTML = providers.map(function (provider) { - var selected = provider.Id === currentProviderId || providers.length < 2 ? ' selected' : ''; + const selected = provider.Id === currentProviderId || providers.length < 2 ? ' selected' : ''; return ''; }); } function loadUser(page, user) { - currentUser = user; ApiClient.getJSON(ApiClient.getUrl('Auth/Providers')).then(function (providers) { loadAuthProviders(page, user, providers); }); @@ -159,7 +156,7 @@ import globalize from 'globalize'; } function onSubmit() { - var page = $(this).parents('.page')[0]; + const page = $(this).parents('.page')[0]; loading.show(); getUser().then(function (result) { saveUser(result, page); @@ -168,7 +165,7 @@ import globalize from 'globalize'; } function getUser() { - var userId = getParameterByName('userId'); + const userId = getParameterByName('userId'); return ApiClient.getUser(userId); } @@ -179,11 +176,10 @@ import globalize from 'globalize'; }); } - var currentUser; $(document).on('pageinit', '#editUserPage', function () { $('.editUserProfileForm').off('submit', onSubmit).on('submit', onSubmit); this.querySelector('.sharingHelp').innerHTML = globalize.translate('OptionAllowLinkSharingHelp', 30); - var page = this; + const page = this; $('#chkEnableDeleteAllFolders', this).on('change', function () { if (this.checked) { $('.deleteAccess', page).hide(); diff --git a/src/controllers/dashboard/users/userlibraryaccess.js b/src/controllers/dashboard/users/userlibraryaccess.js index 072b228c5..df42733f0 100644 --- a/src/controllers/dashboard/users/userlibraryaccess.js +++ b/src/controllers/dashboard/users/userlibraryaccess.js @@ -6,39 +6,39 @@ import globalize from 'globalize'; /* eslint-disable indent */ function triggerChange(select) { - var evt = document.createEvent('HTMLEvents'); + const evt = document.createEvent('HTMLEvents'); evt.initEvent('change', false, true); select.dispatchEvent(evt); } function loadMediaFolders(page, user, mediaFolders) { - var html = ''; + let html = ''; html += '

' + globalize.translate('HeaderLibraries') + '

'; html += '
'; - for (var i = 0, length = mediaFolders.length; i < length; i++) { - var folder = mediaFolders[i]; - var isChecked = user.Policy.EnableAllFolders || -1 != user.Policy.EnabledFolders.indexOf(folder.Id); - var checkedAttribute = isChecked ? ' checked="checked"' : ''; + for (let i = 0, length = mediaFolders.length; i < length; i++) { + const folder = mediaFolders[i]; + const isChecked = user.Policy.EnableAllFolders || -1 != user.Policy.EnabledFolders.indexOf(folder.Id); + const checkedAttribute = isChecked ? ' checked="checked"' : ''; html += ''; } html += '
'; page.querySelector('.folderAccess').innerHTML = html; - var chkEnableAllFolders = page.querySelector('#chkEnableAllFolders'); + const chkEnableAllFolders = page.querySelector('#chkEnableAllFolders'); chkEnableAllFolders.checked = user.Policy.EnableAllFolders; triggerChange(chkEnableAllFolders); } function loadChannels(page, user, channels) { - var html = ''; + let html = ''; html += '

' + globalize.translate('HeaderChannels') + '

'; html += '
'; - for (var i = 0, length = channels.length; i < length; i++) { - var folder = channels[i]; - var isChecked = user.Policy.EnableAllChannels || -1 != user.Policy.EnabledChannels.indexOf(folder.Id); - var checkedAttribute = isChecked ? ' checked="checked"' : ''; + for (let i = 0, length = channels.length; i < length; i++) { + const folder = channels[i]; + const isChecked = user.Policy.EnableAllChannels || -1 != user.Policy.EnabledChannels.indexOf(folder.Id); + const checkedAttribute = isChecked ? ' checked="checked"' : ''; html += ''; } @@ -55,13 +55,13 @@ import globalize from 'globalize'; } function loadDevices(page, user, devices) { - var html = ''; + let html = ''; html += '

' + globalize.translate('HeaderDevices') + '

'; html += '
'; - for (var i = 0, length = devices.length; i < length; i++) { - var device = devices[i]; - var checkedAttribute = user.Policy.EnableAllDevices || -1 != user.Policy.EnabledDevices.indexOf(device.Id) ? ' checked="checked"' : ''; + for (let i = 0, length = devices.length; i < length; i++) { + const device = devices[i]; + const checkedAttribute = user.Policy.EnableAllDevices || -1 != user.Policy.EnabledDevices.indexOf(device.Id) ? ' checked="checked"' : ''; html += ''; } @@ -120,9 +120,9 @@ import globalize from 'globalize'; } function onSubmit() { - var page = $(this).parents('.page'); + const page = $(this).parents('.page'); loading.show(); - var userId = getParameterByName('userId'); + const userId = getParameterByName('userId'); ApiClient.getUser(userId).then(function (result) { saveUser(result, page); }); @@ -130,7 +130,7 @@ import globalize from 'globalize'; } $(document).on('pageinit', '#userLibraryAccessPage', function () { - var page = this; + const page = this; $('#chkEnableAllDevices', page).on('change', function () { if (this.checked) { $('.deviceAccessListContainer', page).hide(); @@ -154,27 +154,27 @@ import globalize from 'globalize'; }); $('.userLibraryAccessForm').off('submit', onSubmit).on('submit', onSubmit); }).on('pageshow', '#userLibraryAccessPage', function () { - var page = this; + const page = this; loading.show(); - var promise1; - var userId = getParameterByName('userId'); + let promise1; + const userId = getParameterByName('userId'); if (userId) { promise1 = ApiClient.getUser(userId); } else { - var deferred = $.Deferred(); + const deferred = $.Deferred(); deferred.resolveWith(null, [{ Configuration: {} }]); promise1 = deferred.promise(); } - var promise2 = Dashboard.getCurrentUser(); - var promise4 = ApiClient.getJSON(ApiClient.getUrl('Library/MediaFolders', { + const promise2 = Dashboard.getCurrentUser(); + const promise4 = ApiClient.getJSON(ApiClient.getUrl('Library/MediaFolders', { IsHidden: false })); - var promise5 = ApiClient.getJSON(ApiClient.getUrl('Channels')); - var promise6 = ApiClient.getJSON(ApiClient.getUrl('Devices')); + const promise5 = ApiClient.getJSON(ApiClient.getUrl('Channels')); + const promise6 = ApiClient.getJSON(ApiClient.getUrl('Devices')); Promise.all([promise1, promise2, promise4, promise5, promise6]).then(function (responses) { loadUser(page, responses[0], responses[1], responses[2].Items, responses[3].Items, responses[4].Items); }); diff --git a/src/controllers/dashboard/users/usernew.js b/src/controllers/dashboard/users/usernew.js index 71072898d..f45cbf8ca 100644 --- a/src/controllers/dashboard/users/usernew.js +++ b/src/controllers/dashboard/users/usernew.js @@ -6,12 +6,12 @@ import 'emby-checkbox'; /* eslint-disable indent */ function loadMediaFolders(page, mediaFolders) { - var html = ''; + let html = ''; html += '

' + globalize.translate('HeaderLibraries') + '

'; html += '
'; - for (var i = 0; i < mediaFolders.length; i++) { - var folder = mediaFolders[i]; + for (let i = 0; i < mediaFolders.length; i++) { + const folder = mediaFolders[i]; html += ''; } @@ -21,12 +21,12 @@ import 'emby-checkbox'; } function loadChannels(page, channels) { - var html = ''; + let html = ''; html += '

' + globalize.translate('HeaderChannels') + '

'; html += '
'; - for (var i = 0; i < channels.length; i++) { - var folder = channels[i]; + for (let i = 0; i < channels.length; i++) { + const folder = channels[i]; html += ''; } @@ -46,10 +46,10 @@ import 'emby-checkbox'; $('#txtUsername', page).val(''); $('#txtPassword', page).val(''); loading.show(); - var promiseFolders = ApiClient.getJSON(ApiClient.getUrl('Library/MediaFolders', { + const promiseFolders = ApiClient.getJSON(ApiClient.getUrl('Library/MediaFolders', { IsHidden: false })); - var promiseChannels = ApiClient.getJSON(ApiClient.getUrl('Channels')); + const promiseChannels = ApiClient.getJSON(ApiClient.getUrl('Channels')); Promise.all([promiseFolders, promiseChannels]).then(function (responses) { loadMediaFolders(page, responses[0].Items); loadChannels(page, responses[1].Items); @@ -58,7 +58,7 @@ import 'emby-checkbox'; } function saveUser(page) { - var user = {}; + const user = {}; user.Name = $('#txtUsername', page).val(); user.Password = $('#txtPassword', page).val(); ApiClient.createUser(user).then(function (user) { @@ -97,7 +97,7 @@ import 'emby-checkbox'; } function onSubmit() { - var page = $(this).parents('.page')[0]; + const page = $(this).parents('.page')[0]; loading.show(); saveUser(page); return false; @@ -108,7 +108,7 @@ import 'emby-checkbox'; } $(document).on('pageinit', '#newUserPage', function () { - var page = this; + const page = this; $('#chkEnableAllChannels', page).on('change', function () { if (this.checked) { $('.channelAccessListContainer', page).hide(); diff --git a/src/controllers/dashboard/users/userparentalcontrol.js b/src/controllers/dashboard/users/userparentalcontrol.js index 38ada8b8f..e146aac56 100644 --- a/src/controllers/dashboard/users/userparentalcontrol.js +++ b/src/controllers/dashboard/users/userparentalcontrol.js @@ -9,16 +9,14 @@ import 'paper-icon-button-light'; /* eslint-disable indent */ function populateRatings(allParentalRatings, page) { - var html = ''; + let html = ''; html += ""; - var i; - var length; - var rating; - var ratings = []; + let rating; + const ratings = []; - for (i = 0, length = allParentalRatings.length; i < length; i++) { + for (let i = 0, length = allParentalRatings.length; i < length; i++) { if (rating = allParentalRatings[i], ratings.length) { - var lastRating = ratings[ratings.length - 1]; + const lastRating = ratings[ratings.length - 1]; if (lastRating.Value === rating.Value) { lastRating.Name += '/' + rating.Name; @@ -32,7 +30,7 @@ import 'paper-icon-button-light'; }); } - for (i = 0, length = ratings.length; i < length; i++) { + for (let i = 0, length = ratings.length; i < length; i++) { rating = ratings[i]; html += "'; } @@ -41,7 +39,7 @@ import 'paper-icon-button-light'; } function loadUnratedItems(page, user) { - var items = [{ + const items = [{ name: globalize.translate('OptionBlockBooks'), value: 'Book' }, { @@ -63,13 +61,13 @@ import 'paper-icon-button-light'; name: globalize.translate('OptionBlockTvShows'), value: 'Series' }]; - var html = ''; + let html = ''; html += '

' + globalize.translate('HeaderBlockItemsWithNoRating') + '

'; html += '
'; - for (var i = 0, length = items.length; i < length; i++) { - var item = items[i]; - var checkedAttribute = -1 != user.Policy.BlockUnratedItems.indexOf(item.value) ? ' checked="checked"' : ''; + for (let i = 0, length = items.length; i < length; i++) { + const item = items[i]; + const checkedAttribute = -1 != user.Policy.BlockUnratedItems.indexOf(item.value) ? ' checked="checked"' : ''; html += ''; } @@ -83,11 +81,11 @@ import 'paper-icon-button-light'; loadUnratedItems(page, user); loadBlockedTags(page, user.Policy.BlockedTags); populateRatings(allParentalRatings, page); - var ratingValue = ''; + let ratingValue = ''; if (user.Policy.MaxParentalRating) { - for (var i = 0, length = allParentalRatings.length; i < length; i++) { - var rating = allParentalRatings[i]; + for (let i = 0, length = allParentalRatings.length; i < length; i++) { + const rating = allParentalRatings[i]; if (user.Policy.MaxParentalRating >= rating.Value) { ratingValue = rating.Value; @@ -108,8 +106,8 @@ import 'paper-icon-button-light'; } function loadBlockedTags(page, tags) { - var html = tags.map(function (h) { - var li = '
'; + let html = tags.map(function (h) { + let li = '
'; li += '
'; li += '

'; li += h; @@ -123,10 +121,10 @@ import 'paper-icon-button-light'; html = '
' + html + '
'; } - var elem = $('.blockedTags', page).html(html).trigger('create'); + const elem = $('.blockedTags', page).html(html).trigger('create'); $('.btnDeleteTag', elem).on('click', function () { - var tag = this.getAttribute('data-tag'); - var newTags = tags.filter(function (t) { + const tag = this.getAttribute('data-tag'); + const newTags = tags.filter(function (t) { return t != tag; }); loadBlockedTags(page, newTags); @@ -139,10 +137,10 @@ import 'paper-icon-button-light'; } function renderAccessSchedule(page, schedules) { - var html = ''; - var index = 0; + let html = ''; + let index = 0; html += schedules.map(function (a) { - var itemHtml = ''; + let itemHtml = ''; itemHtml += '
'; itemHtml += '
'; itemHtml += '

'; @@ -155,7 +153,7 @@ import 'paper-icon-button-light'; index++; return itemHtml; }).join(''); - var accessScheduleList = page.querySelector('.accessScheduleList'); + const accessScheduleList = page.querySelector('.accessScheduleList'); accessScheduleList.innerHTML = html; $('.btnDelete', accessScheduleList).on('click', function () { deleteAccessSchedule(page, schedules, parseInt(this.getAttribute('data-index'))); @@ -185,8 +183,8 @@ import 'paper-icon-button-light'; } function getDisplayTime(hours) { - var minutes = 0; - var pct = hours % 1; + let minutes = 0; + const pct = hours % 1; if (pct) { minutes = parseInt(60 * pct); @@ -201,7 +199,7 @@ import 'paper-icon-button-light'; accessschedule.show({ schedule: schedule }).then(function (updatedSchedule) { - var schedules = getSchedulesFromPage(page); + const schedules = getSchedulesFromPage(page); if (-1 == index) { index = schedules.length; @@ -234,7 +232,7 @@ import 'paper-icon-button-light'; prompt({ label: globalize.translate('LabelTag') }).then(function (value) { - var tags = getBlockedTagsFromPage(page); + const tags = getBlockedTagsFromPage(page); if (-1 == tags.indexOf(value)) { tags.push(value); @@ -246,9 +244,9 @@ import 'paper-icon-button-light'; window.UserParentalControlPage = { onSubmit: function () { - var page = $(this).parents('.page'); + const page = $(this).parents('.page'); loading.show(); - var userId = getParameterByName('userId'); + const userId = getParameterByName('userId'); ApiClient.getUser(userId).then(function (result) { saveUser(result, page); }); @@ -256,7 +254,7 @@ import 'paper-icon-button-light'; } }; $(document).on('pageinit', '#userParentalControlPage', function () { - var page = this; + const page = this; $('.btnAddSchedule', page).on('click', function () { showSchedulePopup(page, {}, -1); }); @@ -265,11 +263,11 @@ import 'paper-icon-button-light'; }); $('.userParentalControlForm').off('submit', UserParentalControlPage.onSubmit).on('submit', UserParentalControlPage.onSubmit); }).on('pageshow', '#userParentalControlPage', function () { - var page = this; + const page = this; loading.show(); - var userId = getParameterByName('userId'); - var promise1 = ApiClient.getUser(userId); - var promise2 = ApiClient.getParentalRatings(); + const userId = getParameterByName('userId'); + const promise1 = ApiClient.getUser(userId); + const promise2 = ApiClient.getParentalRatings(); Promise.all([promise1, promise2]).then(function (responses) { loadUser(page, responses[0], responses[1]); }); diff --git a/src/controllers/dashboard/users/userpasswordpage.js b/src/controllers/dashboard/users/userpasswordpage.js index 4f9b7e251..d694bb2c5 100644 --- a/src/controllers/dashboard/users/userpasswordpage.js +++ b/src/controllers/dashboard/users/userpasswordpage.js @@ -6,13 +6,13 @@ import 'emby-button'; /* eslint-disable indent */ function loadUser(page, params) { - var userid = params.userId; + const userid = params.userId; ApiClient.getUser(userid).then(function (user) { Dashboard.getCurrentUser().then(function (loggedInUser) { libraryMenu.setTitle(user.Name); page.querySelector('.username').innerHTML = user.Name; - var showPasswordSection = true; - var showLocalAccessSection = false; + let showPasswordSection = true; + let showLocalAccessSection = false; if ('Guest' == user.ConnectLinkType) { page.querySelector('.localAccessSection').classList.add('hide'); @@ -38,7 +38,7 @@ import 'emby-button'; page.querySelector('.localAccessSection').classList.add('hide'); } - var txtEasyPassword = page.querySelector('#txtEasyPassword'); + const txtEasyPassword = page.querySelector('#txtEasyPassword'); txtEasyPassword.value = ''; if (user.HasConfiguredEasyPassword) { @@ -64,8 +64,8 @@ import 'emby-button'; export default function (view, params) { function saveEasyPassword() { - var userId = params.userId; - var easyPassword = view.querySelector('#txtEasyPassword').value; + const userId = params.userId; + const easyPassword = view.querySelector('#txtEasyPassword').value; if (easyPassword) { ApiClient.updateEasyPassword(userId, easyPassword).then(function () { @@ -92,9 +92,9 @@ import 'emby-button'; } function savePassword() { - var userId = params.userId; - var currentPassword = view.querySelector('#txtCurrentPassword').value; - var newPassword = view.querySelector('#txtNewPassword').value; + const userId = params.userId; + let currentPassword = view.querySelector('#txtCurrentPassword').value; + const newPassword = view.querySelector('#txtNewPassword').value; if (view.querySelector('#fldCurrentPassword').classList.contains('hide')) { // Firefox does not respect autocomplete=off, so clear it if the field is supposed to be hidden (and blank) @@ -120,7 +120,7 @@ import 'emby-button'; } function onSubmit(e) { - var form = this; + const form = this; if (form.querySelector('#txtNewPassword').value != form.querySelector('#txtNewPasswordConfirm').value) { import('toast').then(({default: toast}) => { @@ -143,10 +143,10 @@ import 'emby-button'; } function resetPassword() { - var msg = globalize.translate('PasswordResetConfirmation'); + const msg = globalize.translate('PasswordResetConfirmation'); import('confirm').then(({default: confirm}) => { confirm(msg, globalize.translate('PasswordResetHeader')).then(function () { - var userId = params.userId; + const userId = params.userId; loading.show(); ApiClient.resetUserPassword(userId).then(function () { loading.hide(); @@ -161,11 +161,11 @@ import 'emby-button'; } function resetEasyPassword() { - var msg = globalize.translate('PinCodeResetConfirmation'); + const msg = globalize.translate('PinCodeResetConfirmation'); import('confirm').then(({default: confirm}) => { confirm(msg, globalize.translate('HeaderPinCodeReset')).then(function () { - var userId = params.userId; + const userId = params.userId; loading.show(); ApiClient.resetEasyPassword(userId).then(function () { loading.hide(); diff --git a/src/controllers/dashboard/users/userprofilespage.js b/src/controllers/dashboard/users/userprofilespage.js index cf246cdea..dbdec4f75 100644 --- a/src/controllers/dashboard/users/userprofilespage.js +++ b/src/controllers/dashboard/users/userprofilespage.js @@ -12,7 +12,7 @@ import 'flexStyles'; /* eslint-disable indent */ function deleteUser(page, id) { - var msg = globalize.translate('DeleteUserConfirmation'); + const msg = globalize.translate('DeleteUserConfirmation'); import('confirm').then(({default: confirm}) => { confirm({ @@ -30,10 +30,10 @@ import 'flexStyles'; } function showUserMenu(elem) { - var card = dom.parentWithClass(elem, 'card'); - var page = dom.parentWithClass(card, 'page'); - var userId = card.getAttribute('data-userid'); - var menuItems = []; + const card = dom.parentWithClass(elem, 'card'); + const page = dom.parentWithClass(card, 'page'); + const userId = card.getAttribute('data-userid'); + const menuItems = []; menuItems.push({ name: globalize.translate('ButtonOpen'), id: 'open', @@ -82,8 +82,8 @@ import 'flexStyles'; } function getUserHtml(user, addConnectIndicator) { - var html = ''; - var cssClass = 'card squareCard scalableCard squareCard-scalable'; + let html = ''; + let cssClass = 'card squareCard scalableCard squareCard-scalable'; if (user.Policy.IsDisabled) { cssClass += ' grayscale'; @@ -94,7 +94,7 @@ import 'flexStyles'; html += ''; html += '
'; - var lastSeen = getLastSeenText(user.LastActivityDate); + const lastSeen = getLastSeenText(user.LastActivityDate); html += '' != lastSeen ? lastSeen : ' '; html += '
'; html += '

'; @@ -156,7 +156,7 @@ import 'flexStyles'; } function showPendingUserMenu(elem) { - var menuItems = []; + const menuItems = []; menuItems.push({ name: globalize.translate('ButtonCancel'), id: 'delete', @@ -164,9 +164,9 @@ import 'flexStyles'; }); import('actionsheet').then(({default: actionsheet}) => { - var card = dom.parentWithClass(elem, 'card'); - var page = dom.parentWithClass(card, 'page'); - var id = card.getAttribute('data-id'); + const card = dom.parentWithClass(elem, 'card'); + const page = dom.parentWithClass(card, 'page'); + const id = card.getAttribute('data-id'); actionsheet.show({ items: menuItems, positionTo: card, @@ -181,7 +181,7 @@ import 'flexStyles'; } function getPendingUserHtml(user) { - var html = ''; + let html = ''; html += "
"; html += '
'; html += '
'; @@ -254,19 +254,19 @@ import 'flexStyles'; } pageIdOn('pageinit', 'userProfilesPage', function () { - var page = this; + const page = this; page.querySelector('.btnAddUser').addEventListener('click', function() { Dashboard.navigate('usernew.html'); }); page.querySelector('.localUsers').addEventListener('click', function (e__e) { - var btnUserMenu = dom.parentWithClass(e__e.target, 'btnUserMenu'); + const btnUserMenu = dom.parentWithClass(e__e.target, 'btnUserMenu'); if (btnUserMenu) { showUserMenu(btnUserMenu); } }); page.querySelector('.pending').addEventListener('click', function (e__r) { - var btnUserMenu = dom.parentWithClass(e__r.target, 'btnUserMenu'); + const btnUserMenu = dom.parentWithClass(e__r.target, 'btnUserMenu'); if (btnUserMenu) { showPendingUserMenu(btnUserMenu); From cc1634e9f94f377a43674aa63044906ea7049d69 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 11 Jul 2020 14:10:12 +0100 Subject: [PATCH 0212/1168] update --- src/assets/css/dashboard.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/assets/css/dashboard.css b/src/assets/css/dashboard.css index 2cb5d7358..48e6fe807 100644 --- a/src/assets/css/dashboard.css +++ b/src/assets/css/dashboard.css @@ -237,6 +237,7 @@ div[data-role=controlgroup] a.ui-btn-active { .localUsers .cardText-secondary { white-space: pre-wrap; + height: 3em; } .customCssContainer textarea { From 8af1142000d47b21008259d481ca8788868b3c6b Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 9 Jul 2020 17:19:21 +0100 Subject: [PATCH 0213/1168] migration of display, home, playback and subtitles to ES6 modules --- package.json | 4 ++++ src/controllers/user/display.js | 18 +++++++++++------- src/controllers/user/home.js | 22 +++++++++++++++------- src/controllers/user/playback.js | 22 +++++++++++++++------- src/controllers/user/subtitles.js | 18 +++++++++++------- 5 files changed, 56 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index ab47eb538..28aec55b8 100644 --- a/package.json +++ b/package.json @@ -116,6 +116,10 @@ "src/components/syncPlay/timeSyncManager.js", "src/controllers/dashboard/logs.js", "src/controllers/dashboard/plugins/repositories.js", + "src/controllers/user/display.js", + "src/controllers/user/home.js", + "src/controllers/user/playback.js", + "src/controllers/user/subtitles.js", "src/plugins/bookPlayer/plugin.js", "src/plugins/bookPlayer/tableOfContents.js", "src/plugins/photoPlayer/plugin.js", diff --git a/src/controllers/user/display.js b/src/controllers/user/display.js index 26c75f209..fe2948b3a 100644 --- a/src/controllers/user/display.js +++ b/src/controllers/user/display.js @@ -1,10 +1,13 @@ -define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySettings, userSettings, autoFocuser) { - 'use strict'; +import DisplaySettings from 'displaySettings'; +import * as userSettings from 'userSettings'; +import autoFocuser from 'autoFocuser'; + +/* eslint-disable indent */ // Shortcuts const UserSettings = userSettings.UserSettings; - return function (view, params) { + export default function (view, params) { function onBeforeUnload(e) { if (hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; @@ -26,8 +29,8 @@ define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySett userId: userId, element: view.querySelector('.settingsContainer'), userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, + enableSaveButton: true, + enableSaveConfirmation: true, autoFocus: autoFocuser.isEnabled() }); } @@ -49,5 +52,6 @@ define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySett settingsInstance = null; } }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/user/home.js b/src/controllers/user/home.js index 8f826c425..8984a8291 100644 --- a/src/controllers/user/home.js +++ b/src/controllers/user/home.js @@ -1,10 +1,17 @@ -define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (HomescreenSettings, dom, globalize, loading, userSettings, autoFocuser) { - 'use strict'; +import HomescreenSettings from 'homescreenSettings'; +import dom from 'dom'; +import globalize from 'globalize'; +import loading from 'loading'; +import * as userSettings from 'userSettings'; +import autoFocuser from 'autoFocuser'; +import 'listViewStyle'; + +/* eslint-disable indent */ // Shortcuts const UserSettings = userSettings.UserSettings; - return function (view, params) { + export default function (view, params) { function onBeforeUnload(e) { if (hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; @@ -26,8 +33,8 @@ define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'au userId: userId, element: view.querySelector('.homeScreenSettingsContainer'), userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, + enableSaveButton: true, + enableSaveConfirmation: true, autoFocus: autoFocuser.isEnabled() }); } @@ -48,5 +55,6 @@ define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'au homescreenSettingsInstance = null; } }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/user/playback.js b/src/controllers/user/playback.js index 02a718eb8..edcb4e4e3 100644 --- a/src/controllers/user/playback.js +++ b/src/controllers/user/playback.js @@ -1,10 +1,17 @@ -define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (PlaybackSettings, dom, globalize, loading, userSettings, autoFocuser) { - 'use strict'; +import PlaybackSettings from 'playbackSettings'; +import dom from 'dom'; +import globalize from 'globalize'; +import loading from 'loading'; +import * as userSettings from 'userSettings'; +import autoFocuser from 'autoFocuser'; +import 'listViewStyle'; + +/* eslint-disable indent */ // Shortcuts const UserSettings = userSettings.UserSettings; - return function (view, params) { + export default function (view, params) { function onBeforeUnload(e) { if (hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; @@ -26,8 +33,8 @@ define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'auto userId: userId, element: view.querySelector('.settingsContainer'), userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, + enableSaveButton: true, + enableSaveConfirmation: true, autoFocus: autoFocuser.isEnabled() }); } @@ -48,5 +55,6 @@ define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'auto settingsInstance = null; } }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/user/subtitles.js b/src/controllers/user/subtitles.js index 7e7e7fb8a..66b41662c 100644 --- a/src/controllers/user/subtitles.js +++ b/src/controllers/user/subtitles.js @@ -1,10 +1,13 @@ -define(['subtitleSettings', 'userSettings', 'autoFocuser'], function (SubtitleSettings, userSettings, autoFocuser) { - 'use strict'; +import SubtitleSettings from 'subtitleSettings'; +import * as userSettings from 'userSettings'; +import autoFocuser from 'autoFocuser'; + +/* eslint-disable indent */ // Shortcuts const UserSettings = userSettings.UserSettings; - return function (view, params) { + export default function (view, params) { function onBeforeUnload(e) { if (hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; @@ -26,8 +29,8 @@ define(['subtitleSettings', 'userSettings', 'autoFocuser'], function (SubtitleSe userId: userId, element: view.querySelector('.settingsContainer'), userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, + enableSaveButton: true, + enableSaveConfirmation: true, autoFocus: autoFocuser.isEnabled() }); } @@ -48,5 +51,6 @@ define(['subtitleSettings', 'userSettings', 'autoFocuser'], function (SubtitleSe subtitleSettingsInstance = null; } }); - }; -}); + } + +/* eslint-enable indent */ From df2af2a6ef221be6d8f810aebca8fc26eb261594 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 11 Jul 2020 14:57:41 +0100 Subject: [PATCH 0214/1168] remove autosave and update variable declerations --- src/controllers/user/display.js | 16 +++++----------- src/controllers/user/home.js | 15 +++++---------- src/controllers/user/playback.js | 15 +++++---------- src/controllers/user/subtitles.js | 15 +++++---------- 4 files changed, 20 insertions(+), 41 deletions(-) diff --git a/src/controllers/user/display.js b/src/controllers/user/display.js index fe2948b3a..a400c50cc 100644 --- a/src/controllers/user/display.js +++ b/src/controllers/user/display.js @@ -14,10 +14,10 @@ import autoFocuser from 'autoFocuser'; } } - var settingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + let settingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); view.addEventListener('viewshow', function () { window.addEventListener('beforeunload', onBeforeUnload); @@ -35,17 +35,11 @@ import autoFocuser from 'autoFocuser'; }); } }); + view.addEventListener('change', function () { hasChanges = true; }); - view.addEventListener('viewbeforehide', function () { - window.removeEventListener('beforeunload', onBeforeUnload); - hasChanges = false; - if (settingsInstance) { - settingsInstance.submit(); - } - }); view.addEventListener('viewdestroy', function () { if (settingsInstance) { settingsInstance.destroy(); diff --git a/src/controllers/user/home.js b/src/controllers/user/home.js index 8984a8291..e7058fd3a 100644 --- a/src/controllers/user/home.js +++ b/src/controllers/user/home.js @@ -18,10 +18,10 @@ import 'listViewStyle'; } } - var homescreenSettingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + let homescreenSettingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); view.addEventListener('viewshow', function () { window.addEventListener('beforeunload', onBeforeUnload); @@ -39,16 +39,11 @@ import 'listViewStyle'; }); } }); + view.addEventListener('change', function () { hasChanges = true; }); - view.addEventListener('viewbeforehide', function () { - hasChanges = false; - if (homescreenSettingsInstance) { - homescreenSettingsInstance.submit(); - } - }); view.addEventListener('viewdestroy', function () { if (homescreenSettingsInstance) { homescreenSettingsInstance.destroy(); diff --git a/src/controllers/user/playback.js b/src/controllers/user/playback.js index edcb4e4e3..5bcf055cd 100644 --- a/src/controllers/user/playback.js +++ b/src/controllers/user/playback.js @@ -18,10 +18,10 @@ import 'listViewStyle'; } } - var settingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + let settingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); view.addEventListener('viewshow', function () { window.addEventListener('beforeunload', onBeforeUnload); @@ -39,16 +39,11 @@ import 'listViewStyle'; }); } }); + view.addEventListener('change', function () { hasChanges = true; }); - view.addEventListener('viewbeforehide', function () { - hasChanges = false; - if (settingsInstance) { - settingsInstance.submit(); - } - }); view.addEventListener('viewdestroy', function () { if (settingsInstance) { settingsInstance.destroy(); diff --git a/src/controllers/user/subtitles.js b/src/controllers/user/subtitles.js index 66b41662c..82f5270a4 100644 --- a/src/controllers/user/subtitles.js +++ b/src/controllers/user/subtitles.js @@ -14,10 +14,10 @@ import autoFocuser from 'autoFocuser'; } } - var subtitleSettingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + let subtitleSettingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); view.addEventListener('viewshow', function () { window.addEventListener('beforeunload', onBeforeUnload); @@ -35,16 +35,11 @@ import autoFocuser from 'autoFocuser'; }); } }); + view.addEventListener('change', function () { hasChanges = true; }); - view.addEventListener('viewbeforehide', function () { - hasChanges = false; - if (subtitleSettingsInstance) { - subtitleSettingsInstance.submit(); - } - }); view.addEventListener('viewdestroy', function () { if (subtitleSettingsInstance) { subtitleSettingsInstance.destroy(); From 7b509fdde4ef0d129ed2805bc19d00fd27cfecb1 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 11 Jul 2020 16:54:20 +0100 Subject: [PATCH 0215/1168] Migration of proflie, profiles and settings (DLNA) to ES6 Modules --- package.json | 3 + src/controllers/dashboard/dlna/profile.js | 165 +++++++++++---------- src/controllers/dashboard/dlna/profiles.js | 23 ++- src/controllers/dashboard/dlna/settings.js | 21 ++- 4 files changed, 118 insertions(+), 94 deletions(-) diff --git a/package.json b/package.json index 81c627f08..c49c53d41 100644 --- a/package.json +++ b/package.json @@ -137,6 +137,9 @@ "src/controllers/dashboard/logs.js", "src/controllers/user/subtitles.js", "src/controllers/dashboard/plugins/repositories.js", + "src/controllers/dashboard/dlna/profile.js", + "src/controllers/dashboard/dlna/profiles.js", + "src/controllers/dashboard/dlna/settings.js", "src/plugins/bookPlayer/plugin.js", "src/plugins/bookPlayer/tableOfContents.js", "src/plugins/photoPlayer/plugin.js", diff --git a/src/controllers/dashboard/dlna/profile.js b/src/controllers/dashboard/dlna/profile.js index 54ef75a6d..003cb8824 100644 --- a/src/controllers/dashboard/dlna/profile.js +++ b/src/controllers/dashboard/dlna/profile.js @@ -1,10 +1,18 @@ -define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-input', 'emby-checkbox', 'listViewStyle', 'emby-button'], function ($, loading, globalize) { - 'use strict'; +import $ from 'jQuery'; +import loading from 'loading'; +import globalize from 'globalize'; +import 'emby-select'; +import 'emby-button'; +import 'emby-input'; +import 'emby-checkbox'; +import 'listViewStyle'; + +/* eslint-disable indent */ function loadProfile(page) { loading.show(); - var promise1 = getProfile(); - var promise2 = ApiClient.getUsers(); + const promise1 = getProfile(); + const promise2 = ApiClient.getUsers(); Promise.all([promise1, promise2]).then(function (responses) { currentProfile = responses[0]; renderProfile(page, currentProfile, responses[1]); @@ -13,8 +21,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } function getProfile() { - var id = getParameterByName('id'); - var url = id ? 'Dlna/Profiles/' + id : 'Dlna/Profiles/Default'; + const id = getParameterByName('id'); + const url = id ? 'Dlna/Profiles/' + id : 'Dlna/Profiles/Default'; return ApiClient.getJSON(ApiClient.getUrl(url)); } @@ -26,7 +34,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in $('#chkEnableAlbumArtInDidl', page).prop('checked', profile.EnableAlbumArtInDidl); $('#chkEnableSingleImageLimit', page).prop('checked', profile.EnableSingleAlbumArtLimit); renderXmlDocumentAttributes(page, profile.XmlRootAttributes || []); - var idInfo = profile.Identification || {}; + const idInfo = profile.Identification || {}; renderIdentificationHeaders(page, idInfo.Headers || []); renderSubtitleProfiles(page, profile.SubtitleProfiles || []); $('#txtInfoFriendlyName', page).val(profile.FriendlyName || ''); @@ -65,7 +73,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in profile.ContainerProfiles = profile.ContainerProfiles || []; profile.CodecProfiles = profile.CodecProfiles || []; profile.ResponseProfiles = profile.ResponseProfiles || []; - var usersHtml = '' + users.map(function (u) { + const usersHtml = '' + users.map(function (u) { return ''; }).join(''); $('#selectUser', page).html(usersHtml).val(profile.UserId || ''); @@ -73,9 +81,9 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } function renderIdentificationHeaders(page, headers) { - var index = 0; - var html = '
' + headers.map(function (h) { - var li = '
'; + let index = 0; + const html = '
' + headers.map(function (h) { + let li = '
'; li += ''; li += '
'; li += '

' + h.Name + ': ' + (h.Value || '') + '

'; @@ -86,9 +94,9 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in index++; return li; }).join('') + '
'; - var elem = $('.httpHeaderIdentificationList', page).html(html).trigger('create'); + const elem = $('.httpHeaderIdentificationList', page).html(html).trigger('create'); $('.btnDeleteIdentificationHeader', elem).on('click', function () { - var itemIndex = parseInt(this.getAttribute('data-index')); + const itemIndex = parseInt(this.getAttribute('data-index')); currentProfile.Identification.Headers.splice(itemIndex, 1); renderIdentificationHeaders(page, currentProfile.Identification.Headers); }); @@ -106,7 +114,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in isSubProfileNew = null == header; header = header || {}; currentSubProfile = header; - var popup = $('#identificationHeaderPopup', page); + const popup = $('#identificationHeaderPopup', page); $('#txtIdentificationHeaderName', popup).val(header.Name || ''); $('#txtIdentificationHeaderValue', popup).val(header.Value || ''); $('#selectMatchType', popup).val(header.Match || 'Equals'); @@ -130,8 +138,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } function renderXmlDocumentAttributes(page, attribute) { - var html = '
' + attribute.map(function (h) { - var li = '
'; + const html = '
' + attribute.map(function (h) { + let li = '
'; li += ''; li += '
'; li += '

' + h.Name + ' = ' + (h.Value || '') + '

'; @@ -139,9 +147,9 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in li += ''; return li += '
'; }).join('') + '
'; - var elem = $('.xmlDocumentAttributeList', page).html(html).trigger('create'); + const elem = $('.xmlDocumentAttributeList', page).html(html).trigger('create'); $('.btnDeleteXmlAttribute', elem).on('click', function () { - var itemIndex = parseInt(this.getAttribute('data-index')); + const itemIndex = parseInt(this.getAttribute('data-index')); currentProfile.XmlRootAttributes.splice(itemIndex, 1); renderXmlDocumentAttributes(page, currentProfile.XmlRootAttributes); }); @@ -151,7 +159,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in isSubProfileNew = null == attribute; attribute = attribute || {}; currentSubProfile = attribute; - var popup = $('#xmlAttributePopup', page); + const popup = $('#xmlAttributePopup', page); $('#txtXmlAttributeName', popup).val(attribute.Name || ''); $('#txtXmlAttributeValue', popup).val(attribute.Value || ''); openPopup(popup[0]); @@ -171,9 +179,9 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } function renderSubtitleProfiles(page, profiles) { - var index = 0; - var html = '
' + profiles.map(function (h) { - var li = '
'; + let index = 0; + const html = '
' + profiles.map(function (h) { + let li = '
'; li += ''; li += '
'; li += '

' + (h.Format || '') + '

'; @@ -183,14 +191,14 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in index++; return li; }).join('') + '
'; - var elem = $('.subtitleProfileList', page).html(html).trigger('create'); + const elem = $('.subtitleProfileList', page).html(html).trigger('create'); $('.btnDeleteProfile', elem).on('click', function () { - var itemIndex = parseInt(this.getAttribute('data-index')); + const itemIndex = parseInt(this.getAttribute('data-index')); currentProfile.SubtitleProfiles.splice(itemIndex, 1); renderSubtitleProfiles(page, currentProfile.SubtitleProfiles); }); $('.lnkEditSubProfile', elem).on('click', function () { - var itemIndex = parseInt(this.getAttribute('data-index')); + const itemIndex = parseInt(this.getAttribute('data-index')); editSubtitleProfile(page, currentProfile.SubtitleProfiles[itemIndex]); }); } @@ -199,7 +207,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in isSubProfileNew = null == profile; profile = profile || {}; currentSubProfile = profile; - var popup = $('#subtitleProfilePopup', page); + const popup = $('#subtitleProfilePopup', page); $('#txtSubtitleProfileFormat', popup).val(profile.Format || ''); $('#selectSubtitleProfileMethod', popup).val(profile.Method || ''); $('#selectSubtitleProfileDidlMode', popup).val(profile.DidlMode || ''); @@ -244,12 +252,12 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } function renderDirectPlayProfiles(page, profiles) { - var html = ''; + let html = ''; html += '
    '; - var currentType; + let currentType; - for (var i = 0, length = profiles.length; i < length; i++) { - var profile = profiles[i]; + for (let i = 0, length = profiles.length; i < length; i++) { + const profile = profiles[i]; if (profile.Type !== currentType) { html += '
  • ' + profile.Type + '
  • '; @@ -275,13 +283,13 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } html += '
'; - var elem = $('.directPlayProfiles', page).html(html).trigger('create'); + const elem = $('.directPlayProfiles', page).html(html).trigger('create'); $('.btnDeleteProfile', elem).on('click', function () { - var index = this.getAttribute('data-profileindex'); + const index = this.getAttribute('data-profileindex'); deleteDirectPlayProfile(page, index); }); $('.lnkEditSubProfile', elem).on('click', function () { - var index = parseInt(this.getAttribute('data-profileindex')); + const index = parseInt(this.getAttribute('data-profileindex')); editDirectPlayProfile(page, currentProfile.DirectPlayProfiles[index]); }); } @@ -295,7 +303,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in isSubProfileNew = null == directPlayProfile; directPlayProfile = directPlayProfile || {}; currentSubProfile = directPlayProfile; - var popup = $('#popupEditDirectPlayProfile', page); + const popup = $('#popupEditDirectPlayProfile', page); $('#selectDirectPlayProfileType', popup).val(directPlayProfile.Type || 'Video').trigger('change'); $('#txtDirectPlayContainer', popup).val(directPlayProfile.Container || ''); $('#txtDirectPlayAudioCodec', popup).val(directPlayProfile.AudioCodec || ''); @@ -304,12 +312,12 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } function renderTranscodingProfiles(page, profiles) { - var html = ''; + let html = ''; html += '
    '; - var currentType; + let currentType; - for (var i = 0, length = profiles.length; i < length; i++) { - var profile = profiles[i]; + for (let i = 0, length = profiles.length; i < length; i++) { + let profile = profiles[i]; if (profile.Type !== currentType) { html += '
  • ' + profile.Type + '
  • '; @@ -336,13 +344,13 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } html += '
'; - var elem = $('.transcodingProfiles', page).html(html).trigger('create'); + const elem = $('.transcodingProfiles', page).html(html).trigger('create'); $('.btnDeleteProfile', elem).on('click', function () { - var index = this.getAttribute('data-profileindex'); + const index = this.getAttribute('data-profileindex'); deleteTranscodingProfile(page, index); }); $('.lnkEditSubProfile', elem).on('click', function () { - var index = parseInt(this.getAttribute('data-profileindex')); + const index = parseInt(this.getAttribute('data-profileindex')); editTranscodingProfile(page, currentProfile.TranscodingProfiles[index]); }); } @@ -351,7 +359,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in isSubProfileNew = null == transcodingProfile; transcodingProfile = transcodingProfile || {}; currentSubProfile = transcodingProfile; - var popup = $('#transcodingProfilePopup', page); + const popup = $('#transcodingProfilePopup', page); $('#selectTranscodingProfileType', popup).val(transcodingProfile.Type || 'Video').trigger('change'); $('#txtTranscodingContainer', popup).val(transcodingProfile.Container || ''); $('#txtTranscodingAudioCodec', popup).val(transcodingProfile.AudioCodec || ''); @@ -390,12 +398,12 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } function renderContainerProfiles(page, profiles) { - var html = ''; + let html = ''; html += '
    '; - var currentType; + let currentType; - for (var i = 0, length = profiles.length; i < length; i++) { - var profile = profiles[i]; + for (let i = 0, length = profiles.length; i < length; i++) { + let profile = profiles[i]; if (profile.Type !== currentType) { html += '
  • ' + profile.Type + '
  • '; @@ -420,13 +428,13 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } html += '
'; - var elem = $('.containerProfiles', page).html(html).trigger('create'); + const elem = $('.containerProfiles', page).html(html).trigger('create'); $('.btnDeleteProfile', elem).on('click', function () { - var index = this.getAttribute('data-profileindex'); + const index = this.getAttribute('data-profileindex'); deleteContainerProfile(page, index); }); $('.lnkEditSubProfile', elem).on('click', function () { - var index = parseInt(this.getAttribute('data-profileindex')); + const index = parseInt(this.getAttribute('data-profileindex')); editContainerProfile(page, currentProfile.ContainerProfiles[index]); }); } @@ -440,7 +448,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in isSubProfileNew = null == containerProfile; containerProfile = containerProfile || {}; currentSubProfile = containerProfile; - var popup = $('#containerProfilePopup', page); + const popup = $('#containerProfilePopup', page); $('#selectContainerProfileType', popup).val(containerProfile.Type || 'Video').trigger('change'); $('#txtContainerProfileContainer', popup).val(containerProfile.Container || ''); $('.radioTabButton:first', popup).trigger('click'); @@ -461,13 +469,13 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } function renderCodecProfiles(page, profiles) { - var html = ''; + let html = ''; html += '
    '; - var currentType; + let currentType; - for (var i = 0, length = profiles.length; i < length; i++) { - var profile = profiles[i]; - var type = profile.Type.replace('VideoAudio', 'Video Audio'); + for (let i = 0, length = profiles.length; i < length; i++) { + let profile = profiles[i]; + const type = profile.Type.replace('VideoAudio', 'Video Audio'); if (type !== currentType) { html += '
  • ' + type + '
  • '; @@ -492,13 +500,13 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } html += '
'; - var elem = $('.codecProfiles', page).html(html).trigger('create'); + const elem = $('.codecProfiles', page).html(html).trigger('create'); $('.btnDeleteProfile', elem).on('click', function () { - var index = this.getAttribute('data-profileindex'); + const index = this.getAttribute('data-profileindex'); deleteCodecProfile(page, index); }); $('.lnkEditSubProfile', elem).on('click', function () { - var index = parseInt(this.getAttribute('data-profileindex')); + const index = parseInt(this.getAttribute('data-profileindex')); editCodecProfile(page, currentProfile.CodecProfiles[index]); }); } @@ -512,7 +520,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in isSubProfileNew = null == codecProfile; codecProfile = codecProfile || {}; currentSubProfile = codecProfile; - var popup = $('#codecProfilePopup', page); + const popup = $('#codecProfilePopup', page); $('#selectCodecProfileType', popup).val(codecProfile.Type || 'Video').trigger('change'); $('#txtCodecProfileCodec', popup).val(codecProfile.Codec || ''); $('.radioTabButton:first', popup).trigger('click'); @@ -533,12 +541,12 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } function renderResponseProfiles(page, profiles) { - var html = ''; + let html = ''; html += '
    '; - var currentType; + let currentType; - for (var i = 0, length = profiles.length; i < length; i++) { - var profile = profiles[i]; + for (let i = 0, length = profiles.length; i < length; i++) { + const profile = profiles[i]; if (profile.Type !== currentType) { html += '
  • ' + profile.Type + '
  • '; @@ -572,13 +580,13 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in } html += '
'; - var elem = $('.mediaProfiles', page).html(html).trigger('create'); + const elem = $('.mediaProfiles', page).html(html).trigger('create'); $('.btnDeleteProfile', elem).on('click', function () { - var index = this.getAttribute('data-profileindex'); + const index = this.getAttribute('data-profileindex'); deleteResponseProfile(page, index); }); $('.lnkEditSubProfile', elem).on('click', function () { - var index = parseInt(this.getAttribute('data-profileindex')); + const index = parseInt(this.getAttribute('data-profileindex')); editResponseProfile(page, currentProfile.ResponseProfiles[index]); }); } @@ -592,7 +600,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in isSubProfileNew = null == responseProfile; responseProfile = responseProfile || {}; currentSubProfile = responseProfile; - var popup = $('#responseProfilePopup', page); + const popup = $('#responseProfilePopup', page); $('#selectResponseProfileType', popup).val(responseProfile.Type || 'Video').trigger('change'); $('#txtResponseProfileContainer', popup).val(responseProfile.Container || ''); $('#txtResponseProfileAudioCodec', popup).val(responseProfile.AudioCodec || ''); @@ -618,7 +626,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in function saveProfile(page, profile) { updateProfile(page, profile); - var id = getParameterByName('id'); + const id = getParameterByName('id'); if (id) { ApiClient.ajax({ @@ -627,7 +635,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in data: JSON.stringify(profile), contentType: 'application/json' }).then(function () { - require(['toast'], function (toast) { + import('toast').then(({default: toast}) => { toast('Settings saved.'); }); }, Dashboard.processErrorResponse); @@ -687,18 +695,18 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in profile.UserId = $('#selectUser', page).val(); } - var currentProfile; - var currentSubProfile; - var isSubProfileNew; - var allText = globalize.translate('LabelAll'); + let currentProfile; + let currentSubProfile; + let isSubProfileNew; + const allText = globalize.translate('LabelAll'); $(document).on('pageinit', '#dlnaProfilePage', function () { - var page = this; + const page = this; $('.radioTabButton', page).on('click', function () { $(this).siblings().removeClass('ui-btn-active'); $(this).addClass('ui-btn-active'); - var value = 'A' == this.tagName ? this.getAttribute('data-value') : this.value; - var elem = $('.' + value, page); + const value = 'A' == this.tagName ? this.getAttribute('data-value') : this.value; + const elem = $('.' + value, page); elem.siblings('.tabContent').hide(); elem.show(); }); @@ -783,7 +791,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in $('.xmlAttributeForm').off('submit', DlnaProfilePage.onXmlAttributeFormSubmit).on('submit', DlnaProfilePage.onXmlAttributeFormSubmit); $('.subtitleProfileForm').off('submit', DlnaProfilePage.onSubtitleProfileFormSubmit).on('submit', DlnaProfilePage.onSubtitleProfileFormSubmit); }).on('pageshow', '#dlnaProfilePage', function () { - var page = this; + const page = this; $('#radioInfo', page).trigger('click'); loadProfile(page); }); @@ -826,4 +834,5 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in return false; } }; -}); + +/* eslint-enable indent */ diff --git a/src/controllers/dashboard/dlna/profiles.js b/src/controllers/dashboard/dlna/profiles.js index fb4caadeb..510128be4 100644 --- a/src/controllers/dashboard/dlna/profiles.js +++ b/src/controllers/dashboard/dlna/profiles.js @@ -1,5 +1,11 @@ -define(['jQuery', 'globalize', 'loading', 'libraryMenu', 'listViewStyle', 'emby-button'], function ($, globalize, loading, libraryMenu) { - 'use strict'; +import $ from 'jQuery'; +import globalize from 'globalize'; +import loading from 'loading'; +import libraryMenu from 'libraryMenu'; +import 'listViewStyle'; +import 'emby-button'; + +/* eslint-disable indent */ function loadProfiles(page) { loading.show(); @@ -23,14 +29,14 @@ define(['jQuery', 'globalize', 'loading', 'libraryMenu', 'listViewStyle', 'emby- } function renderProfiles(page, element, profiles) { - var html = ''; + let html = ''; if (profiles.length) { html += '
'; } - for (var i = 0, length = profiles.length; i < length; i++) { - var profile = profiles[i]; + for (let i = 0, length = profiles.length; i < length; i++) { + let profile = profiles[i]; html += '
'; html += ''; html += '
'; @@ -52,13 +58,13 @@ define(['jQuery', 'globalize', 'loading', 'libraryMenu', 'listViewStyle', 'emby- element.innerHTML = html; $('.btnDeleteProfile', element).on('click', function () { - var id = this.getAttribute('data-profileid'); + const id = this.getAttribute('data-profileid'); deleteProfile(page, id); }); } function deleteProfile(page, id) { - require(['confirm'], function (confirm) { + import('confirm').then(({default: confirm}) => { confirm(globalize.translate('MessageConfirmProfileDeletion'), globalize.translate('HeaderConfirmProfileDeletion')).then(function () { loading.show(); ApiClient.ajax({ @@ -86,4 +92,5 @@ define(['jQuery', 'globalize', 'loading', 'libraryMenu', 'listViewStyle', 'emby- libraryMenu.setTabs('dlna', 1, getTabs); loadProfiles(this); }); -}); + +/* eslint-enable indent */ diff --git a/src/controllers/dashboard/dlna/settings.js b/src/controllers/dashboard/dlna/settings.js index 5bbfea5d4..9e7d78d79 100644 --- a/src/controllers/dashboard/dlna/settings.js +++ b/src/controllers/dashboard/dlna/settings.js @@ -1,5 +1,9 @@ -define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading, libraryMenu, globalize) { - 'use strict'; +import $ from 'jQuery'; +import loading from 'loading'; +import libraryMenu from 'libraryMenu'; +import globalize from 'globalize'; + +/* eslint-disable indent */ function loadPage(page, config, users) { page.querySelector('#chkEnablePlayTo').checked = config.EnablePlayTo; @@ -8,7 +12,7 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading, $('#chkEnableServer', page).prop('checked', config.EnableServer); $('#chkBlastAliveMessages', page).prop('checked', config.BlastAliveMessages); $('#txtBlastInterval', page).val(config.BlastAliveMessageIntervalSeconds); - var usersHtml = users.map(function (u) { + const usersHtml = users.map(function (u) { return ''; }).join(''); $('#selectUser', page).html(usersHtml).val(config.DefaultUserId || ''); @@ -17,7 +21,7 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading, function onSubmit() { loading.show(); - var form = this; + const form = this; ApiClient.getNamedConfiguration('dlna').then(function (config) { config.EnablePlayTo = form.querySelector('#chkEnablePlayTo').checked; config.EnableDebugLog = form.querySelector('#chkEnableDlnaDebugLogging').checked; @@ -46,11 +50,12 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading, }).on('pageshow', '#dlnaSettingsPage', function () { libraryMenu.setTabs('dlna', 0, getTabs); loading.show(); - var page = this; - var promise1 = ApiClient.getNamedConfiguration('dlna'); - var promise2 = ApiClient.getUsers(); + const page = this; + const promise1 = ApiClient.getNamedConfiguration('dlna'); + const promise2 = ApiClient.getUsers(); Promise.all([promise1, promise2]).then(function (responses) { loadPage(page, responses[0], responses[1]); }); }); -}); + +/* eslint-enable indent */ From 11e675de58082d77695911624112674a93f5da8c Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 12 Jul 2020 04:24:45 +0900 Subject: [PATCH 0216/1168] fix two minor issues --- src/controllers/auth/login.js | 12 ++---------- src/controllers/dashboard/dashboard.js | 8 +------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/controllers/auth/login.js b/src/controllers/auth/login.js index c0c37e27d..640cb26c2 100644 --- a/src/controllers/auth/login.js +++ b/src/controllers/auth/login.js @@ -7,18 +7,10 @@ define(['apphost', 'appSettings', 'dom', 'connectionManager', 'loading', 'layout loading.show(); apiClient.authenticateUserByName(username, password).then(function (result) { var user = result.User; - var serverId = getParameterByName('serverid'); - var newUrl; - - if (user.Policy.IsAdministrator && !serverId) { - newUrl = 'dashboard.html'; - } else { - newUrl = 'home.html'; - } - loading.hide(); + Dashboard.onServerChanged(user.Id, result.AccessToken, apiClient); - Dashboard.navigate(newUrl); + Dashboard.navigate('home.html'); }, function (response) { page.querySelector('#txtManualName').value = ''; page.querySelector('#txtManualPassword').value = ''; diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index 6a378903d..e6e01338b 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -169,13 +169,7 @@ define(['datetime', 'events', 'itemHelper', 'serverNotifications', 'dom', 'globa function reloadSystemInfo(view, apiClient) { apiClient.getSystemInfo().then(function (systemInfo) { view.querySelector('#serverName').innerHTML = globalize.translate('DashboardServerName', systemInfo.ServerName); - var localizedVersion = globalize.translate('DashboardVersionNumber', systemInfo.Version); - - if (systemInfo.SystemUpdateLevel !== 'Release') { - localizedVersion += ' ' + systemInfo.SystemUpdateLevel; - } - - view.querySelector('#versionNumber').innerHTML = localizedVersion; + view.querySelector('#versionNumber').innerHTML = globalize.translate('DashboardVersionNumber', systemInfo.Version); view.querySelector('#operatingSystem').innerHTML = globalize.translate('DashboardOperatingSystem', systemInfo.OperatingSystem); view.querySelector('#architecture').innerHTML = globalize.translate('DashboardArchitecture', systemInfo.SystemArchitecture); From 868dfff829cca2dd62c706c21003e243aa3dad8c Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 12 Jul 2020 04:48:38 +0900 Subject: [PATCH 0217/1168] hide play button for now --- src/components/cardbuilder/cardBuilder.js | 10 ++++------ src/controllers/itemDetails/index.js | 8 +++++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index e906e806e..d36dc4cbb 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -1483,6 +1483,7 @@ import 'programStyles'; * @returns {string} HTML markup of the card overlay. */ function getHoverMenuHtml(item, action, options) { + if (options.disableHoverMenu) return; let html = ''; html += '
'; @@ -1497,12 +1498,12 @@ import 'programStyles'; const userData = item.UserData || {}; - if (itemHelper.canMarkPlayed(item) && !options.disableHoverMenu) { + if (itemHelper.canMarkPlayed(item)) { require(['emby-playstatebutton']); html += ''; } - if (itemHelper.canRate(item) && !options.disableHoverMenu) { + if (itemHelper.canRate(item)) { const likes = userData.Likes == null ? '' : userData.Likes; @@ -1510,10 +1511,7 @@ import 'programStyles'; html += ''; } - if (!options.disableHoverMenu) { - html += ''; - } - + html += ''; html += '
'; html += '
'; diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index 45c43c19b..2f0c9cc03 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -53,11 +53,13 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti user: user, share: true }; + return options; } function getProgramScheduleHtml(items) { var html = ''; + html += '
'; html += listView.getListViewHtml({ items: items, @@ -71,6 +73,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti moreButton: false, recordButton: false }); + html += '
'; return html; @@ -143,7 +146,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti instance._currentPlaybackMediaSources = mediaSources; page.querySelector('.trackSelections').classList.remove('hide'); - select.setLabel(globalize.translate('LabelVersion')); var currentValue = select.value; @@ -165,7 +167,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti renderAudioSelections(page, mediaSources); renderSubtitleSelections(page, mediaSources); } - } function renderVideoSelections(page, mediaSources) { @@ -173,9 +174,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti var mediaSource = mediaSources.filter(function (m) { return m.Id === mediaSourceId; })[0]; + var tracks = mediaSource.MediaStreams.filter(function (m) { return m.Type === 'Video'; }); + var select = page.querySelector('.selectVideo'); select.setLabel(globalize.translate('LabelVideo')); var selectedId = tracks.length ? tracks[0].Index : -1; @@ -727,7 +730,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti }); elem.innerHTML = cardHtml; - imageLoader.lazyChildren(elem); } From aa9059d077d705eceae74ca2ed66b678b311bb89 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 12 Jul 2020 06:09:57 +0900 Subject: [PATCH 0218/1168] fix some css issues with now playing bar --- .../nowPlayingBar/nowPlayingBar.css | 2 -- src/components/nowPlayingBar/nowPlayingBar.js | 17 +++----------- src/components/remotecontrol/remotecontrol.js | 4 ++-- src/nowplaying.html | 22 +++++++++---------- src/themes/appletv/theme.css | 8 ++----- src/themes/blueradiance/theme.css | 8 ++----- src/themes/dark/theme.css | 8 ++----- src/themes/light/theme.css | 8 ++----- src/themes/purplehaze/theme.css | 6 +---- src/themes/wmc/theme.css | 8 ++----- 10 files changed, 27 insertions(+), 64 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.css b/src/components/nowPlayingBar/nowPlayingBar.css index e545d82d1..a884f6576 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.css +++ b/src/components/nowPlayingBar/nowPlayingBar.css @@ -114,8 +114,6 @@ .nowPlayingBarUserDataButtons { display: inline-block; - margin-left: 1em; - margin-right: 1em; } .nowPlayingBarPositionSlider::-webkit-slider-thumb { diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index a229fab4b..215f6336a 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -72,7 +72,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', if (layoutManager.mobile) { html += ''; } else { - html += ''; + html += ''; } html += '
'; @@ -355,7 +355,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', function updateRepeatModeDisplay(repeatMode) { toggleRepeatButtonIcon.classList.remove('repeat', 'repeat_one'); - const cssClass = 'repeatButton-active'; + const cssClass = 'buttonActive'; switch (repeatMode) { case 'RepeatAll': @@ -375,18 +375,14 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } function updateTimeDisplay(positionTicks, runtimeTicks, bufferedRanges) { - // See bindEvents for why this is necessary if (positionSlider && !positionSlider.dragging) { if (runtimeTicks) { - var pct = positionTicks / runtimeTicks; pct *= 100; positionSlider.value = pct; - } else { - positionSlider.value = 0; } } @@ -396,9 +392,7 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } if (currentTimeElement) { - var timeText = positionTicks == null ? '--:--' : datetime.getDisplayRunningTime(positionTicks); - if (runtimeTicks) { timeText += ' / ' + datetime.getDisplayRunningTime(runtimeTicks); } @@ -606,14 +600,11 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', function onPlaybackStart(e, state) { console.debug('nowplaying event: ' + e.type); - var player = this; - onStateChanged.call(player, e, state); } function onRepeatModeChange() { - if (!isEnabled) { return; } @@ -628,9 +619,8 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', let shuffleMode = playbackManager.getQueueShuffleMode(); let context = nowPlayingBarElement; - const cssClass = 'shuffleQueue-active'; + const cssClass = 'buttonActive'; let toggleShuffleButton = context.querySelector('.btnShuffleQueue'); - switch (shuffleMode) { case 'Shuffle': toggleShuffleButton.classList.add(cssClass); @@ -643,7 +633,6 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', } function showNowPlayingBar() { - if (!isVisibilityAllowed) { hideNowPlayingBar(); return; diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 33c44ab40..b283daaba 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -359,7 +359,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function updateRepeatModeDisplay(repeatMode) { var context = dlg; let toggleRepeatButtons = context.querySelectorAll('.repeatToggleButton'); - const cssClass = 'repeatButton-active'; + const cssClass = 'buttonActive'; let innHtml = ''; let repeatOn = true; @@ -528,7 +528,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function onShuffleQueueModeChange(updateView = true) { let shuffleMode = playbackManager.getQueueShuffleMode(this); let context = dlg; - const cssClass = 'shuffleQueue-active'; + const cssClass = 'buttonActive'; let shuffleButtons = context.querySelectorAll('.btnShuffleQueue'); for (let shuffleButton of shuffleButtons) { diff --git a/src/nowplaying.html b/src/nowplaying.html index 9460cb814..1f4d09312 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -5,7 +5,7 @@
- +
@@ -15,9 +15,9 @@
- +
- +
@@ -25,25 +25,25 @@
- +
- +
- + - + - @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@
- + @@ -74,7 +74,7 @@ - +
- From 1c2399c70e2aab9bae1365f3589cd2e8998f96f7 Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 14 Jul 2020 13:50:37 +0100 Subject: [PATCH 0233/1168] Migration of appFooter and homesections to ES6 modules --- package.json | 7 +- src/components/appFooter/appFooter.js | 30 +-- src/components/homesections/homesections.js | 192 +++++++++++--------- 3 files changed, 125 insertions(+), 104 deletions(-) diff --git a/package.json b/package.json index 81c627f08..629d7c732 100644 --- a/package.json +++ b/package.json @@ -93,16 +93,19 @@ "src/components/accessSchedule/accessSchedule.js", "src/components/actionSheet/actionSheet.js", "src/components/alphaPicker/alphaPicker.js", + "src/components/appFooter/appFooter.js", "src/components/autoFocuser.js", "src/components/cardbuilder/cardBuilder.js", "src/components/cardbuilder/chaptercardbuilder.js", "src/components/cardbuilder/peoplecardbuilder.js", - "src/components/directorybrowser/directorybrowser.js", + "src/components/channelMapper/channelMapper.js", "src/components/collectionEditor/collectionEditor.js", "src/components/dialog/dialog.js", + "src/components/directorybrowser/directorybrowser.js", "src/components/dialogHelper/dialogHelper.js", - "src/components/channelMapper/channelMapper.js", + "src/components/homesections/homesections.js", "src/components/images/imageLoader.js", + "", "src/components/imageUploader/imageUploader.js", "src/components/indicators/indicators.js", "src/components/itemidentifier/itemidentifier.js", diff --git a/src/components/appFooter/appFooter.js b/src/components/appFooter/appFooter.js index 033a0b008..427d3b801 100644 --- a/src/components/appFooter/appFooter.js +++ b/src/components/appFooter/appFooter.js @@ -1,17 +1,18 @@ -define(['browser', 'css!./appFooter'], function (browser) { - 'use strict'; +import browser from 'browser'; +import 'css!./appFooter'; - function render(options) { - var elem = document.createElement('div'); - elem.classList.add('appfooter'); +function render(options) { + const elem = document.createElement('div'); + elem.classList.add('appfooter'); - document.body.appendChild(elem); + document.body.appendChild(elem); - return elem; - } + return elem; +} - function appFooter(options) { - var self = this; +class appFooter { + constructor(options) { + const self = this; self.element = render(options); self.add = function (elem) { @@ -26,12 +27,11 @@ define(['browser', 'css!./appFooter'], function (browser) { } }; } - - appFooter.prototype.destroy = function () { + destroy() { var self = this; self.element = null; - }; + } +} - return appFooter; -}); +export default new appFooter; diff --git a/src/components/homesections/homesections.js b/src/components/homesections/homesections.js index bba4b9db1..bae24a0eb 100644 --- a/src/components/homesections/homesections.js +++ b/src/components/homesections/homesections.js @@ -1,7 +1,24 @@ -define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'layoutManager', 'imageLoader', 'globalize', 'itemShortcuts', 'itemHelper', 'appRouter', 'scripts/imagehelper', 'paper-icon-button-light', 'emby-itemscontainer', 'emby-scroller', 'emby-button', 'css!./homesections'], function (connectionManager, cardBuilder, appSettings, dom, appHost, layoutManager, imageLoader, globalize, itemShortcuts, itemHelper, appRouter, imageHelper) { - 'use strict'; +import connectionManager from 'connectionManager'; +import cardBuilder from 'cardBuilder'; +import appSettings from 'appSettings'; +import dom from 'dom'; +import appHost from 'apphost'; +import layoutManager from 'layoutManager'; +import imageLoader from 'imageLoader'; +import globalize from 'globalize'; +import itemShortcuts from 'itemShortcuts'; +import itemHelper from 'itemHelper'; +import appRouter from 'appRouter'; +import imageHelper from 'scripts/imagehelper'; +import 'paper-icon-button-light'; +import 'emby-itemscontainer'; +import 'emby-scroller'; +import 'emby-button'; +import 'css!./homesections'; - function getDefaultSection(index) { +/* eslint-disable indent */ + + export function getDefaultSection(index) { switch (index) { case 0: return 'smalllibrarytiles'; @@ -23,9 +40,9 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } function getAllSectionsToShow(userSettings, sectionCount) { - var sections = []; - for (var i = 0, length = sectionCount; i < length; i++) { - var section = userSettings.get('homesection' + i) || getDefaultSection(i); + const sections = []; + for (let i = 0, length = sectionCount; i < length; i++) { + let section = userSettings.get('homesection' + i) || getDefaultSection(i); if (section === 'folders') { section = getDefaultSection(0); } @@ -36,22 +53,22 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la return sections; } - function loadSections(elem, apiClient, user, userSettings) { + export function loadSections(elem, apiClient, user, userSettings) { return getUserViews(apiClient, user.Id).then(function (userViews) { - var html = ''; + let html = ''; if (userViews.length) { - var sectionCount = 7; - for (var i = 0; i < sectionCount; i++) { + const sectionCount = 7; + for (let i = 0; i < sectionCount; i++) { html += '
'; } elem.innerHTML = html; elem.classList.add('homeSectionsContainer'); - var promises = []; - var sections = getAllSectionsToShow(userSettings, sectionCount); - for (var i = 0; i < sections.length; i++) { + const promises = []; + const sections = getAllSectionsToShow(userSettings, sectionCount); + for (let i = 0; i < sections.length; i++) { promises.push(loadSection(elem, apiClient, user, userSettings, userViews, sections, i)); } @@ -62,7 +79,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la }); }); } else { - var noLibDescription; + let noLibDescription; if (user['Policy'] && user['Policy']['IsAdministrator']) { noLibDescription = globalize.translate('NoCreatedLibraries', '
', ''); } else { @@ -75,7 +92,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la html += '
'; elem.innerHTML = html; - var createNowLink = elem.querySelector('#button-createLibrary'); + const createNowLink = elem.querySelector('#button-createLibrary'); if (createNowLink) { createNowLink.addEventListener('click', function () { Dashboard.navigate('library.html'); @@ -85,9 +102,9 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la }); } - function destroySections(elem) { - var elems = elem.querySelectorAll('.itemsContainer'); - for (var i = 0; i < elems.length; i++) { + export function destroySections(elem) { + const elems = elem.querySelectorAll('.itemsContainer'); + for (let i = 0; i < elems.length; i++) { elems[i].fetchData = null; elems[i].parentContainer = null; elems[i].getItemsHtml = null; @@ -96,24 +113,22 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la elem.innerHTML = ''; } - function pause(elem) { - var elems = elem.querySelectorAll('.itemsContainer'); - for (var i = 0; i < elems.length; i++) { + export function pause(elem) { + const elems = elem.querySelectorAll('.itemsContainer'); + for (let i = 0; i < elems.length; i++) { elems[i].pause(); } } - function resume(elem, options) { - var elems = elem.querySelectorAll('.itemsContainer'); - var i; - var length; - var promises = []; + export function resume(elem, options) { + const elems = elem.querySelectorAll('.itemsContainer'); + const promises = []; - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { promises.push(elems[i].resume(options)); } - var promise = Promise.all(promises); + const promise = Promise.all(promises); if (!options || options.returnPromise !== false) { return promise; } @@ -121,10 +136,10 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function loadSection(page, apiClient, user, userSettings, userViews, allSections, index) { - var section = allSections[index]; - var userId = user.Id; + const section = allSections[index]; + const userId = user.Id; - var elem = page.querySelector('.section' + index); + const elem = page.querySelector('.section' + index); if (section === 'latestmedia') { loadRecentlyAdded(elem, apiClient, user, userViews); @@ -172,7 +187,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } function getLibraryButtonsHtml(items) { - var html = ''; + let html = ''; html += '
'; html += '

' + globalize.translate('HeaderMyMedia') + '

'; @@ -180,9 +195,9 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la html += '
'; // library card background images - for (var i = 0, length = items.length; i < length; i++) { - var item = items[i]; - var icon = imageHelper.getLibraryIcon(item.CollectionType); + for (let i = 0, length = items.length; i < length; i++) { + const item = items[i]; + const icon = imageHelper.getLibraryIcon(item.CollectionType); html += '' + item.Name + ''; } @@ -194,7 +209,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function loadlibraryButtons(elem, apiClient, user, userSettings, userViews) { elem.classList.remove('verticalSection'); - var html = getLibraryButtonsHtml(userViews); + const html = getLibraryButtonsHtml(userViews); elem.innerHTML = html; imageLoader.lazyChildren(elem); @@ -210,8 +225,8 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function getFetchLatestItemsFn(serverId, parentId, collectionType) { return function () { - var apiClient = connectionManager.getApiClient(serverId); - var limit = 16; + const apiClient = connectionManager.getApiClient(serverId); + let limit = 16; if (enableScrollX()) { if (collectionType === 'music') { @@ -227,7 +242,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } } - var options = { + const options = { Limit: limit, Fields: 'PrimaryImageAspectRatio,BasicSyncInfo,Path', ImageTypeLimit: 1, @@ -241,8 +256,8 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function getLatestItemsHtmlFn(itemType, viewType) { return function (items) { - var cardLayout = false; - var shape; + const cardLayout = false; + let shape; if (itemType === 'Channel' || viewType === 'movies' || viewType === 'books' || viewType === 'tvshows') { shape = getPortraitShape(); } else if (viewType === 'music' || viewType === 'homevideos') { @@ -272,7 +287,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } function renderLatestSection(elem, apiClient, user, parent) { - var html = ''; + let html = ''; html += '
'; if (!layoutManager.tv) { @@ -303,7 +318,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la elem.innerHTML = html; - var itemsContainer = elem.querySelector('.itemsContainer'); + const itemsContainer = elem.querySelector('.itemsContainer'); itemsContainer.fetchData = getFetchLatestItemsFn(apiClient.serverId(), parent.Id, parent.CollectionType); itemsContainer.getItemsHtml = getLatestItemsHtmlFn(parent.Type, parent.CollectionType); itemsContainer.parentContainer = elem; @@ -311,10 +326,10 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function loadRecentlyAdded(elem, apiClient, user, userViews) { elem.classList.remove('verticalSection'); - var excludeViewTypes = ['playlists', 'livetv', 'boxsets', 'channels']; + const excludeViewTypes = ['playlists', 'livetv', 'boxsets', 'channels']; - for (var i = 0, length = userViews.length; i < length; i++) { - var item = userViews[i]; + for (let i = 0, length = userViews.length; i < length; i++) { + const item = userViews[i]; if (user.Configuration.LatestItemsExcludes.indexOf(item.Id) !== -1) { continue; } @@ -323,7 +338,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la continue; } - var frag = document.createElement('div'); + const frag = document.createElement('div'); frag.classList.add('verticalSection'); frag.classList.add('hide'); elem.appendChild(frag); @@ -334,12 +349,14 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function getRequirePromise(deps) { return new Promise(function (resolve, reject) { - require(deps, resolve); + import(deps).then(() => { + return resolve; + }); }); } - function loadLibraryTiles(elem, apiClient, user, userSettings, shape, userViews, allSections) { - var html = ''; + export function loadLibraryTiles(elem, apiCdflient, user, userSettings, shape, userViews, allSections) { + let html = ''; if (userViews.length) { html += '

' + globalize.translate('HeaderMyMedia') + '

'; if (enableScrollX()) { @@ -372,10 +389,10 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function getContinueWatchingFetchFn(serverId) { return function () { - var apiClient = connectionManager.getApiClient(serverId); - var screenWidth = dom.getWindowSize().innerWidth; + const apiClient = connectionManager.getApiClient(serverId); + const screenWidth = dom.getWindowSize().innerWidth; - var limit; + let limit; if (enableScrollX()) { limit = 12; } else { @@ -383,7 +400,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la limit = Math.min(limit, 5); } - var options = { + const options = { Limit: limit, Recursive: true, Fields: 'PrimaryImageAspectRatio,BasicSyncInfo', @@ -398,7 +415,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } function getContinueWatchingItemsHtml(items) { - var cardLayout = false; + const cardLayout = false; return cardBuilder.getCardsHtml({ items: items, preferThumb: true, @@ -419,7 +436,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } function loadResumeVideo(elem, apiClient, userId) { - var html = ''; + let html = ''; html += '

' + globalize.translate('HeaderContinueWatching') + '

'; if (enableScrollX()) { @@ -437,7 +454,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la elem.classList.add('hide'); elem.innerHTML = html; - var itemsContainer = elem.querySelector('.itemsContainer'); + const itemsContainer = elem.querySelector('.itemsContainer'); itemsContainer.fetchData = getContinueWatchingFetchFn(apiClient.serverId()); itemsContainer.getItemsHtml = getContinueWatchingItemsHtml; itemsContainer.parentContainer = elem; @@ -445,10 +462,10 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function getContinueListeningFetchFn(serverId) { return function () { - var apiClient = connectionManager.getApiClient(serverId); - var screenWidth = dom.getWindowSize().innerWidth; + const apiClient = connectionManager.getApiClient(serverId); + const screenWidth = dom.getWindowSize().innerWidth; - var limit; + let limit; if (enableScrollX()) { limit = 12; } else { @@ -456,7 +473,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la limit = Math.min(limit, 5); } - var options = { + const options = { Limit: limit, Recursive: true, Fields: 'PrimaryImageAspectRatio,BasicSyncInfo', @@ -471,7 +488,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } function getContinueListeningItemsHtml(items) { - var cardLayout = false; + const cardLayout = false; return cardBuilder.getCardsHtml({ items: items, preferThumb: true, @@ -492,7 +509,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } function loadResumeAudio(elem, apiClient, userId) { - var html = ''; + let html = ''; html += '

' + globalize.translate('HeaderContinueWatching') + '

'; if (enableScrollX()) { @@ -510,7 +527,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la elem.classList.add('hide'); elem.innerHTML = html; - var itemsContainer = elem.querySelector('.itemsContainer'); + const itemsContainer = elem.querySelector('.itemsContainer'); itemsContainer.fetchData = getContinueListeningFetchFn(apiClient.serverId()); itemsContainer.getItemsHtml = getContinueListeningItemsHtml; itemsContainer.parentContainer = elem; @@ -518,7 +535,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function getOnNowFetchFn(serverId) { return function () { - var apiClient = connectionManager.getApiClient(serverId); + const apiClient = connectionManager.getApiClient(serverId); return apiClient.getLiveTvRecommendedPrograms({ userId: apiClient.getCurrentUserId(), IsAiring: true, @@ -532,7 +549,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } function getOnNowItemsHtml(items) { - var cardLayout = false; + const cardLayout = false; return cardBuilder.getCardsHtml({ items: items, preferThumb: 'auto', @@ -559,7 +576,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la return Promise.resolve(); } - var userId = user.Id; + const userId = user.Id; return apiClient.getLiveTvRecommendedPrograms({ userId: apiClient.getCurrentUserId(), IsAiring: true, @@ -569,7 +586,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la EnableTotalRecordCount: false, Fields: 'ChannelInfo,PrimaryImageAspectRatio' }).then(function (result) { - var html = ''; + let html = ''; if (result.Items.length) { elem.classList.remove('padded-left'); elem.classList.remove('padded-right'); @@ -654,7 +671,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la elem.innerHTML = html; - var itemsContainer = elem.querySelector('.itemsContainer'); + const itemsContainer = elem.querySelector('.itemsContainer'); itemsContainer.parentContainer = elem; itemsContainer.fetchData = getOnNowFetchFn(apiClient.serverId()); itemsContainer.getItemsHtml = getOnNowItemsHtml; @@ -664,7 +681,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function getNextUpFetchFn(serverId) { return function () { - var apiClient = connectionManager.getApiClient(serverId); + const apiClient = connectionManager.getApiClient(serverId); return apiClient.getNextUpEpisodes({ Limit: enableScrollX() ? 24 : 15, Fields: 'PrimaryImageAspectRatio,SeriesInfo,DateCreated,BasicSyncInfo,Path', @@ -677,7 +694,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } function getNextUpItemsHtml(items) { - var cardLayout = false; + const cardLayout = false; return cardBuilder.getCardsHtml({ items: items, preferThumb: true, @@ -695,7 +712,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } function loadNextUp(elem, apiClient, userId) { - var html = ''; + let html = ''; html += '
'; if (!layoutManager.tv) { @@ -727,7 +744,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la elem.classList.add('hide'); elem.innerHTML = html; - var itemsContainer = elem.querySelector('.itemsContainer'); + const itemsContainer = elem.querySelector('.itemsContainer'); itemsContainer.fetchData = getNextUpFetchFn(apiClient.serverId()); itemsContainer.getItemsHtml = getNextUpItemsHtml; itemsContainer.parentContainer = elem; @@ -735,7 +752,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function getLatestRecordingsFetchFn(serverId, activeRecordingsOnly) { return function () { - var apiClient = connectionManager.getApiClient(serverId); + const apiClient = connectionManager.getApiClient(serverId); return apiClient.getLiveTvRecordings({ userId: apiClient.getCurrentUserId(), Limit: enableScrollX() ? 12 : 5, @@ -749,7 +766,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la function getLatestRecordingItemsHtml(activeRecordingsOnly) { return function (items) { - var cardLayout = false; + const cardLayout = false; return cardBuilder.getCardsHtml({ items: items, shape: enableScrollX() ? 'autooverflow' : 'auto', @@ -774,11 +791,11 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la } function loadLatestLiveTvRecordings(elem, activeRecordingsOnly, apiClient, userId) { - var title = activeRecordingsOnly ? + const title = activeRecordingsOnly ? globalize.translate('HeaderActiveRecordings') : globalize.translate('HeaderLatestRecordings'); - var html = ''; + let html = ''; html += '
'; html += '

' + title + '

'; @@ -799,18 +816,19 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la elem.classList.add('hide'); elem.innerHTML = html; - var itemsContainer = elem.querySelector('.itemsContainer'); + const itemsContainer = elem.querySelector('.itemsContainer'); itemsContainer.fetchData = getLatestRecordingsFetchFn(apiClient.serverId(), activeRecordingsOnly); itemsContainer.getItemsHtml = getLatestRecordingItemsHtml(activeRecordingsOnly); itemsContainer.parentContainer = elem; } - return { - loadLibraryTiles: loadLibraryTiles, - getDefaultSection: getDefaultSection, - loadSections: loadSections, - destroySections: destroySections, - pause: pause, - resume: resume - }; -}); +export default { + loadLibraryTiles: loadLibraryTiles, + getDefaultSection: getDefaultSection, + loadSections: loadSections, + destroySections: destroySections, + pause: pause, + resume: resume +}; + +/* eslint-enable indent */ From ef74521028bef3d2d000c5c1b14b560c7a6a02b1 Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 14 Jul 2020 13:57:56 +0100 Subject: [PATCH 0234/1168] fix lint --- src/components/itemContextMenu.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index b66e8a070..96a5cb71d 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -356,7 +356,7 @@ import actionsheet from 'actionsheet'; getResolveFunction(getResolveFunction(resolve, id), id)(); }); break; - case 'copy-stream': + case 'copy-stream': { const downloadHref = apiClient.getItemDownloadUrl(itemId); const textAreaCopy = function () { let textArea = document.createElement('textarea'); @@ -390,6 +390,7 @@ import actionsheet from 'actionsheet'; } getResolveFunction(resolve, id)(); break; + } case 'editsubtitles': import('subtitleEditor').then(({default: subtitleEditor}) => { subtitleEditor.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); From 9e61810bb10d44fb7aed3b77f20506842c610292 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 12 Jul 2020 15:28:02 +0100 Subject: [PATCH 0235/1168] remove console log --- src/controllers/shows/tvlatest.js | 1 - src/controllers/shows/tvrecommended.js | 1 - 2 files changed, 2 deletions(-) diff --git a/src/controllers/shows/tvlatest.js b/src/controllers/shows/tvlatest.js index c9860e17d..c08f3d5a1 100644 --- a/src/controllers/shows/tvlatest.js +++ b/src/controllers/shows/tvlatest.js @@ -53,7 +53,6 @@ import imageLoader from 'imageLoader'; } export default function (view, params, tabContent) { - console.log(tabContent) const self = this; let latestPromise; diff --git a/src/controllers/shows/tvrecommended.js b/src/controllers/shows/tvrecommended.js index d32b47840..6853f11d6 100644 --- a/src/controllers/shows/tvrecommended.js +++ b/src/controllers/shows/tvrecommended.js @@ -223,7 +223,6 @@ import 'emby-button'; } import(depends).then(({default: controllerFactory}) => { - console.log('using controller factory from ' + depends) let tabContent; if (index === 1) { From a8a85df303c88aa5d07ca06734ecf9d2404960f7 Mon Sep 17 00:00:00 2001 From: dkanada Date: Wed, 15 Jul 2020 06:23:36 +0900 Subject: [PATCH 0236/1168] fix some minor console issues --- src/components/playback/playbackmanager.js | 1 - src/components/syncPlay/groupSelectionMenu.js | 2 +- src/components/syncPlay/syncPlayManager.js | 4 ++++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 797fc39bd..cb1a91fb7 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -72,7 +72,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla const now = (new Date).getTime(); if (method !== reportPlaybackLastMethod || now - (reportPlaybackLastTime || 0) >= reportPlaybackLogDelay) { - console.debug(method + '-' + JSON.stringify(info)); reportPlaybackLastMethod = method; reportPlaybackLastTime = now; } diff --git a/src/components/syncPlay/groupSelectionMenu.js b/src/components/syncPlay/groupSelectionMenu.js index 3c77a67ea..360aa0b0c 100644 --- a/src/components/syncPlay/groupSelectionMenu.js +++ b/src/components/syncPlay/groupSelectionMenu.js @@ -84,7 +84,7 @@ function showNewJoinGroupSelection (button, user, apiClient) { actionsheet.show(menuOptions).then(function (id) { if (id == 'new-group') { apiClient.createSyncPlayGroup(); - } else { + } else if (id) { apiClient.joinSyncPlayGroup({ GroupId: id, PlayingItemId: playingItemId diff --git a/src/components/syncPlay/syncPlayManager.js b/src/components/syncPlay/syncPlayManager.js index c847fbaed..c8660b2bc 100644 --- a/src/components/syncPlay/syncPlayManager.js +++ b/src/components/syncPlay/syncPlayManager.js @@ -212,6 +212,7 @@ class SyncPlayManager { if (!this.lastPlaybackWaiting) { this.lastPlaybackWaiting = new Date(); } + events.trigger(this, 'waiting'); } @@ -288,6 +289,7 @@ class SyncPlayManager { player.setPlaybackRate(this.localPlayerPlaybackRate); this.localPlayerPlaybackRate = 1.0; } + this.currentPlayer = null; this.playbackRateSupported = false; } @@ -433,6 +435,7 @@ class SyncPlayManager { }); return; } + // Get playing item id let playingItemId; try { @@ -619,6 +622,7 @@ class SyncPlayManager { if (this.currentPlayer) { this.currentPlayer.setPlaybackRate(1); } + this.clearSyncIcon(); } From 0bdd88b958d0c083edd317aea801196134595c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Fern=C3=A1ndez?= Date: Wed, 15 Jul 2020 00:33:18 +0200 Subject: [PATCH 0237/1168] Address review comments --- src/components/maintabsmanager.js | 2 +- src/elements/emby-tabs/emby-tabs.css | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/maintabsmanager.js b/src/components/maintabsmanager.js index a852129aa..e1c543436 100644 --- a/src/components/maintabsmanager.js +++ b/src/components/maintabsmanager.js @@ -140,7 +140,7 @@ define(['dom', 'browser', 'events', 'emby-tabs', 'emby-button'], function (dom, var index = 0; var indexAttribute = selectedIndex == null ? '' : (' data-index="' + selectedIndex + '"'); - var tabsHtml = '
' + getTabsFn().map(function (t) { + var tabsHtml = '
' + getTabsFn().map(function (t) { var tabClass = 'emby-tab-button'; diff --git a/src/elements/emby-tabs/emby-tabs.css b/src/elements/emby-tabs/emby-tabs.css index f4f191f93..fe29f4614 100644 --- a/src/elements/emby-tabs/emby-tabs.css +++ b/src/elements/emby-tabs/emby-tabs.css @@ -31,8 +31,6 @@ .emby-tabs-slider { position: relative; - overflow: auto; - overflow-y: hidden; } .tabContent:not(.is-active) { From 5a950d36b86ae8be5b59fe69bcfd0a947f2fc19d Mon Sep 17 00:00:00 2001 From: Martim Pinheiro Date: Wed, 15 Jul 2020 00:42:28 +0000 Subject: [PATCH 0238/1168] Translated using Weblate (Portuguese (Portugal)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/ --- src/strings/pt-pt.json | 71 +++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/src/strings/pt-pt.json b/src/strings/pt-pt.json index abd2c08a9..aae1b1e4a 100644 --- a/src/strings/pt-pt.json +++ b/src/strings/pt-pt.json @@ -320,7 +320,7 @@ "LabelEmbedAlbumArtDidl": "Incorporar a capa do álbum no DIDL", "LabelEmbedAlbumArtDidlHelp": "Alguns dispositivos preferem este método para obter a capa do álbum. Noutros pode falhar a reprodução com esta opção ativada.", "LabelEnableAutomaticPortMap": "Ativar mapeamento automático de portas", - "LabelEnableAutomaticPortMapHelp": "Tenta mapear automaticamente o porto público para o porto local através de UPnP. Isto poderá não funcionar em alguns modelos de routers.", + "LabelEnableAutomaticPortMapHelp": "Automaticamente encaminha o porto público para o porto local através de UPnP. Isto poderá não funcionar em alguns modelos de routers ou devido às configurações da rede. As alterações só serão aplicadas após o reiniciar do servidor", "LabelEnableBlastAliveMessages": "Enviar mensagens de reconhecimento", "LabelEnableBlastAliveMessagesHelp": "Ativar esta opção se o servidor não for convenientemente detetado por outros dispositivos UPnP na rede.", "LabelEnableDlnaClientDiscoveryInterval": "Intervalo para descoberta de clientes (segundos)", @@ -768,13 +768,13 @@ "AllowMediaConversion": "Permitir conversão multimédia", "AllowMediaConversionHelp": "Permitir ou negar acesso à funcionalidade de conversão multimédia.", "AllowOnTheFlySubtitleExtraction": "Permitir a extração de legendas em tempo real", - "AllowOnTheFlySubtitleExtractionHelp": "Legendas integradas podem ser extraídas do vídeo e enviadas como texto simples para os clientes para evitar transcodificação. Em certos dispositivos, esta poderá ser uma operação demorada e pode causar paragens de reprodução durante o processo de extração. Desative esta opção para que as legendas sejam integradas no vídeo durante a conversão para um formato suportado pelo dispositivo de destino.", + "AllowOnTheFlySubtitleExtractionHelp": "Legendas integradas podem ser extraídas do vídeo e enviadas como texto simples para os clientes para evitar transcodificação. Em certos dispositivos, esta poderá ser uma operação demorada e pode causar interrupções de reprodução durante o processo de extração. Desative esta opção para que as legendas sejam integradas no vídeo durante a conversão para um formato suportado pelo dispositivo de destino.", "AllowRemoteAccess": "Permitir ligações remotas a este Jellyfin Server.", "AllowRemoteAccessHelp": "Se inativo, todas as ligações remotas serão bloqueadas.", "AllowedRemoteAddressesHelp": "Lista de IP ou IP/Máscara, separados por vírgulas, com permissão para se ligar remotamente. Se deixado em branco, todos os endereços remotos serão permitidos.", - "AlwaysPlaySubtitles": "Mostrar sempre legendas", + "AlwaysPlaySubtitles": "Reproduzir Sempre", "AlwaysPlaySubtitlesHelp": "Legendas correspondentes à língua preferencial vão ser sempre carregadas, independentemente do idioma do áudio.", - "AnyLanguage": "Qualquer idioma", + "AnyLanguage": "Qualquer linguagem", "Artists": "Artistas", "Ascending": "Crescente", "AspectRatio": "Proporção", @@ -785,7 +785,7 @@ "BirthPlaceValue": "Local de nascimento: {0}", "Blacklist": "Lista Negra", "Books": "Livros", - "BurnSubtitlesHelp": "Determina se o servidor deve integrar as legendas durante a conversão de vídeo, dependendo do formato da legenda. Evitar integração de legendas melhora o desempenho do servidor. Selecione Auto para que legendas baseadas em imagem (VOBSUB, PGS, SUB/IDX), e certos formatos ASS/SSA sejam integrados.", + "BurnSubtitlesHelp": "Determina se o servidor deve integrar as legendas durante a conversão de vídeo. Evitar a integração de legendas melhora o desempenho do servidor. Selecione Auto para que legendas baseadas em imagem (VOBSUB, PGS, SUB/IDX), e certos formatos ASS/SSA sejam integrados.", "Channels": "Canais", "Collections": "Coleções", "Favorites": "Favoritos", @@ -831,7 +831,7 @@ "Browse": "Procurar", "BoxRear": "Caixa (verso)", "Box": "Caixa", - "BookLibraryHelp": "Livros de texto e áudio são suportados. Consulte o guia de nomenclatura de livros{1}.", + "BookLibraryHelp": "Livros digitais e áudio livros são suportados. Consulte o guia de nomenclatura de livros{1}.", "BirthLocation": "Local de nascimento", "AsManyAsPossible": "Tantos quanto possível", "Art": "Capa", @@ -963,7 +963,7 @@ "LabelAbortedByServerShutdown": "(Abortado - Servidor encerrado)", "Kids": "Crianças", "Items": "Itens", - "InstallingPackage": "A instalar {0}", + "InstallingPackage": "A instalar {0} (version {1})", "HttpsRequiresCert": "Para activar ligações seguras, é necessário fornecer um certificado SSL confiável. Forneça um certificado SSL ou desactive as ligações seguras.", "DirectStreamHelp1": "O tipo de multimédia (H.264, AC3, etc.) e a sua resolução são compatíveis com o dispositivo, no entanto, o formato (mkv, avi, wmv, etc.) não é. O conteúdo é reempacotado em tempo real antes de ser enviado para o dispositivo.", "DirectPlaying": "Reprodução direta", @@ -1041,7 +1041,7 @@ "HeaderPlayOn": "Reproduzir Em", "HeaderNextVideoPlayingInValue": "Reprodução do próximo vídeo a iniciar em {0}", "HeaderNextEpisodePlayingInValue": "Reprodução do próximo episódio a iniciar em {0}", - "HardwareAccelerationWarning": "Ativar a aceleração por hardware pode causar instabilidade em alguns ambientes. Garanta que o sistema operativo e os controladores da placa gráfica estão completamente atualizados. Se tiver dificuldades em reproduzir vídeo depois de alterar esta opção, pode ser necessário repôr em \\\"Auto\\\".", + "HardwareAccelerationWarning": "Ativar a aceleração por hardware pode causar instabilidade em alguns ambientes. Garanta que o sistema operativo e os controladores da placa gráfica estão completamente atualizados. Se tiver dificuldades em reproduzir vídeo depois de alterar esta opção, pode ser necessário repôr as definições para o parâmetro \\\"Nenhum\\\".", "Display": "Visualização", "ManageLibrary": "Gerir biblioteca", "HeaderLibraryOrder": "Ordenação da Biblioteca", @@ -1102,7 +1102,7 @@ "HeaderNewDevices": "Novos Dispositivos", "HeaderRecordingOptions": "Opções de Gravação", "HeaderSortOrder": "Direção de Ordenação", - "LabelBaseUrlHelp": "Pode adicionar uma sub-pasta personalizada aqui para aceder ao servidor através de um URL mais direto.", + "LabelBaseUrlHelp": "Adiciona uma sub-pasta personalizada ao URL do servidor. Por exemplo: http://exemplo.com/<baseurl>", "LabelMoviePrefixHelp": "Se aplicar um prefixo aos títulos dos filmes, introduza-o aqui para que o servidor consiga tratá-los corretamente.", "LabelPleaseRestart": "As alterações produzirão efeito depois de recarregar a página web.", "LabelRecordingPathHelp": "Especifique a localização por defeito para guardar as gravações. Se for deixado em branco, será utilizada a pasta base do servidor.", @@ -1112,7 +1112,7 @@ "HeaderMusicQuality": "Qualidade da Música", "HeaderMyDevice": "O Meu Dispositivo", "HeaderSortBy": "Ordenar Por", - "LabelOptionalNetworkPathHelp": "Se esta pasta estiver partilhada na rede, fornecer o caminho de rede pode permitir aos clientes aceder diretamente aos ficheiros multimédia.", + "LabelOptionalNetworkPathHelp": "Se esta pasta estiver partilhada na rede, fornecer o caminho de rede pode permitir aos clientes aceder diretamente aos ficheiros multimédia. For example, {0} or {1}.", "LabelPersonRoleHelp": "Exemplo: motorista da carrinha de gelados", "LabelPlayer": "Reprodutor:", "LabelServerName": "Nome do servidor:", @@ -1453,5 +1453,54 @@ "AllowFfmpegThrottling": "Reduzir Taxa de Transcodificação", "PreferEmbeddedTitlesOverFileNamesHelp": "Determina o título a apresentar por defeito quando não é possível carregar metadados locais nem da Internet.", "OptionSaveMetadataAsHiddenHelp": "Alterar esta definição apenas afetará metadados guardados futuramente. Ficheiros existentes serão atualizados assim que forem alterados pelo Servidor Jellyfin.", - "ButtonSyncPlay": "SyncPlay" + "ButtonSyncPlay": "SyncPlay", + "LabelRepositoryUrl": "URL do Repositório", + "HeaderNewRepository": "Novo Repositório", + "MessageNoRepositories": "Sem repositórios.", + "MessageUnauthorizedUser": "Não está autorizado a aceder ao servidor neste momento. Por favor contacte o administador deste servidor para informação mais detalhada.", + "LabelSyncPlayAccess": "Acesso \"SyncPlay\"", + "LabelSyncPlayAccessNone": "Desativar para este utilizador", + "LabelSyncPlayAccessJoinGroups": "Permitir utilizador a aderir a grupos", + "LabelSyncPlayAccessCreateAndJoinGroups": "Autorizar utilizadores a criar e aderir a grupos", + "LabelSyncPlayLeaveGroupDescription": "Desativar \"SyncPlay\"", + "LabelSyncPlayLeaveGroup": "Abandonar grupo", + "LabelSyncPlayNewGroupDescription": "Criar novo grupo", + "LabelSyncPlayNewGroup": "Novo grupo", + "LabelSyncPlaySyncMethod": "Método de Sincronização:", + "LabelSyncPlayPlaybackDiff": "Diferença no tempo de Reprodução:", + "MillisecondsUnit": "ms", + "LabelSyncPlayTimeOffset": "Diferença de tempo com o servidor:", + "EnableFasterAnimationsHelp": "Utilizar animações e transições mais rápidas", + "EnableFasterAnimations": "Animações Rápidas", + "LabelRequireHttpsHelp": "Se selecionado, o servidor irá automaticamente redirecionar todos os pedidos em HTTP para HTTPS. Isto não surte efeito caso o servidor não esteja configurado em HTTPS.", + "LabelRequireHttps": "Exigir HTTPS", + "LabelNightly": "\"Nightly\"", + "LabelStable": "Estável", + "LabelChromecastVersion": "Versão do \"Chromecast\"", + "LabelLibraryPageSizeHelp": "Define a quantidade de items a apresentar na página de uma Biblioteca. Para desativar a existência de paginação, introduza o valor 0.", + "LabelLibraryPageSize": "Tamanho da página da Biblioteca:", + "LabelEnableHttpsHelp": "Permite que o servidor escute na porta HTTPS configurada. Um certificado válido também deve ser configurado para que isso entre em vigor.", + "LabelEnableHttps": "Ativar HTTPS", + "LabelDeinterlaceMethod": "Método de desentrelaçamento:", + "HeaderSyncPlayEnabled": "SyncPlay ativado", + "HeaderSyncPlaySelectGroup": "Aderir a um grupo", + "HeaderServerAddressSettings": "Definições da Localização do Servidor", + "HeaderRemoteAccessSettings": "Definições do Acesso Remoto", + "HeaderHttpsSettings": "Definições de HTTPS", + "HeaderFavoritePlaylists": "Listas de Reprodução Favoritas", + "HeaderDVR": "Gravações (DVR)", + "ApiKeysCaption": "Lista das chaves de API atualmente ativadas", + "Episode": "Episódio", + "EnableDetailsBannerHelp": "Mostra uma imagem no topo da página dos detalhes do item.", + "EnableDetailsBanner": "Cartaz de Detalhes", + "EnableDecodingColorDepth10Vp9": "Ativar descodificação de hardware de 10-Bits para VP9", + "EnableDecodingColorDepth10Hevc": "Ativar descodificação de hardware de 10-Bits para HEVC", + "DeinterlaceMethodHelp": "Selecionar um método de desentrelaçamento para converter conteúdo entrelaçado.", + "ClientSettings": "Definições do Cliente", + "ButtonTogglePlaylist": "Lista de Reprodução", + "ButtonToggleContextMenu": "Mais", + "BoxSet": "Coleção", + "Artist": "Artista", + "AlbumArtist": "Artista do Álbum", + "Album": "Álbum" } From 57ba9a8233ed56692e58f797c937aa4b9a9fea9a Mon Sep 17 00:00:00 2001 From: Nyanmisaka <799610810@qq.com> Date: Tue, 14 Jul 2020 18:24:39 +0000 Subject: [PATCH 0239/1168] Translated using Weblate (Chinese (Simplified)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/ --- src/strings/zh-cn.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index bd99a6155..4ab15420c 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -1134,7 +1134,7 @@ "RunAtStartup": "开机时启动", "Runtime": "播放时长", "Saturday": "星期六", - "Save": "储存", + "Save": "保存", "SaveSubtitlesIntoMediaFolders": "保存字幕到媒体所在文件夹", "SaveSubtitlesIntoMediaFoldersHelp": "将字幕存储在视频文件旁边可以跟方便的管理他们。", "ScanForNewAndUpdatedFiles": "扫描新的和有修改的文件", From 4bde73b96eb0674562868086804bc9ce454e26de Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 15 Jul 2020 09:29:15 +0100 Subject: [PATCH 0240/1168] Update variable Declerations --- src/controllers/auth/addserver.js | 9 ++-- src/controllers/auth/forgotpassword.js | 4 +- src/controllers/auth/forgotpasswordpin.js | 6 +-- src/controllers/auth/login.js | 54 +++++++++++------------ src/controllers/auth/selectserver.js | 34 +++++++------- 5 files changed, 54 insertions(+), 53 deletions(-) diff --git a/src/controllers/auth/addserver.js b/src/controllers/auth/addserver.js index 3c0fb3be0..112928324 100644 --- a/src/controllers/auth/addserver.js +++ b/src/controllers/auth/addserver.js @@ -9,11 +9,12 @@ import 'emby-button'; function handleConnectionResult(page, result) { loading.hide(); switch (result.State) { - case 'SignedIn': - var apiClient = result.ApiClient; + case 'SignedIn': { + const apiClient = result.ApiClient; Dashboard.onServerChanged(apiClient.getCurrentUserId(), apiClient.accessToken(), apiClient); Dashboard.navigate('home.html'); break; + } case 'ServerSignIn': Dashboard.navigate('login.html?serverid=' + result.Servers[0].Id, false, 'none'); break; @@ -35,7 +36,7 @@ import 'emby-button'; function submitServer(page) { loading.show(); - var host = page.querySelector('#txtServerHost').value; + const host = page.querySelector('#txtServerHost').value; ConnectionManager.connectToAddress(host, { enableAutoLogin: appSettings.enableAutoLogin() }).then(function(result) { @@ -66,6 +67,6 @@ import 'emby-button'; appRouter.back(); }); } - }; + } /* eslint-enable indent */ diff --git a/src/controllers/auth/forgotpassword.js b/src/controllers/auth/forgotpassword.js index f9fd1c2bc..ace5a3ec1 100644 --- a/src/controllers/auth/forgotpassword.js +++ b/src/controllers/auth/forgotpassword.js @@ -18,7 +18,7 @@ import globalize from 'globalize'; } if ('PinCode' == result.Action) { - var msg = globalize.translate('MessageForgotPasswordFileCreated'); + let msg = globalize.translate('MessageForgotPasswordFileCreated'); msg += '
'; msg += '
'; msg += 'Enter PIN here to finish Password Reset
'; @@ -50,6 +50,6 @@ import globalize from 'globalize'; } view.querySelector('form').addEventListener('submit', onSubmit); - }; + } /* eslint-enable indent */ diff --git a/src/controllers/auth/forgotpasswordpin.js b/src/controllers/auth/forgotpasswordpin.js index d0b20f688..a88e131ee 100644 --- a/src/controllers/auth/forgotpasswordpin.js +++ b/src/controllers/auth/forgotpasswordpin.js @@ -4,7 +4,7 @@ import globalize from 'globalize'; function processForgotPasswordResult(result) { if (result.Success) { - var msg = globalize.translate('MessagePasswordResetForUsers'); + let msg = globalize.translate('MessagePasswordResetForUsers'); msg += '
'; msg += '
'; msg += result.UsersReset.join('
'); @@ -38,6 +38,6 @@ import globalize from 'globalize'; } view.querySelector('form').addEventListener('submit', onSubmit); - }; + } -/* eslint-disable indent */ +/* eslint-enable indent */ diff --git a/src/controllers/auth/login.js b/src/controllers/auth/login.js index ead35d052..fb16413ae 100644 --- a/src/controllers/auth/login.js +++ b/src/controllers/auth/login.js @@ -11,14 +11,14 @@ import 'emby-checkbox'; /* eslint-disable indent */ - var enableFocusTransform = !browser.slow && !browser.edge; + const enableFocusTransform = !browser.slow && !browser.edge; function authenticateUserByName(page, apiClient, username, password) { loading.show(); apiClient.authenticateUserByName(username, password).then(function (result) { - var user = result.User; - var serverId = getParameterByName('serverid'); - var newUrl; + const user = result.User; + const serverId = getParameterByName('serverid'); + let newUrl; if (user.Policy.IsAdministrator && !serverId) { newUrl = 'dashboard.html'; @@ -68,23 +68,23 @@ import 'emby-checkbox'; } } - var metroColors = ['#6FBD45', '#4BB3DD', '#4164A5', '#E12026', '#800080', '#E1B222', '#008040', '#0094FF', '#FF00C7', '#FF870F', '#7F0037']; + const metroColors = ['#6FBD45', '#4BB3DD', '#4164A5', '#E12026', '#800080', '#E1B222', '#008040', '#0094FF', '#FF00C7', '#FF870F', '#7F0037']; function getRandomMetroColor() { - var index = Math.floor(Math.random() * (metroColors.length - 1)); + const index = Math.floor(Math.random() * (metroColors.length - 1)); return metroColors[index]; } function getMetroColor(str) { if (str) { - var character = String(str.substr(0, 1).charCodeAt()); - var sum = 0; + const character = String(str.substr(0, 1).charCodeAt()); + let sum = 0; - for (var i = 0; i < character.length; i++) { + for (let i = 0; i < character.length; i++) { sum += parseInt(character.charAt(i)); } - var index = String(sum).substr(-1); + const index = String(sum).substr(-1); return metroColors[index]; } @@ -92,13 +92,13 @@ import 'emby-checkbox'; } function loadUserList(context, apiClient, users) { - var html = ''; + let html = ''; - for (var i = 0; i < users.length; i++) { - var user = users[i]; + for (let i = 0; i < users.length; i++) { + const user = users[i]; // TODO move card creation code to Card component - var cssClass = 'card squareCard scalableCard squareCard-scalable'; + let cssClass = 'card squareCard scalableCard squareCard-scalable'; if (layoutManager.tv) { cssClass += ' show-focus'; @@ -108,13 +108,13 @@ import 'emby-checkbox'; } } - var cardBoxCssClass = 'cardBox cardBox-bottompadded'; + const cardBoxCssClass = 'cardBox cardBox-bottompadded'; html += '
'; return cardContainer; }).join(''); - var itemsContainer = view.querySelector('.servers'); + const itemsContainer = view.querySelector('.servers'); if (!items.length) { html = '

' + globalize.translate('MessageNoServersAvailable') + '

'; @@ -122,7 +122,7 @@ import 'emby-button'; enableAutoLogin: appSettings.enableAutoLogin() }).then(function (result) { loading.hide(); - var apiClient = result.ApiClient; + const apiClient = result.ApiClient; switch (result.State) { case 'SignedIn': @@ -157,7 +157,7 @@ import 'emby-button'; } function onServerClick(server) { - var menuItems = []; + const menuItems = []; menuItems.push({ name: globalize.translate('Connect'), id: 'connect' @@ -195,10 +195,10 @@ import 'emby-button'; connectionManager.getAvailableServers().then(onServersRetrieved); } - var servers; + let servers; updatePageStyle(view, params); view.addEventListener('viewshow', function (e) { - var isRestored = e.detail.isRestored; + const isRestored = e.detail.isRestored; appRouter.setTitle(null); if (!isRestored) { @@ -206,21 +206,21 @@ import 'emby-button'; } }); view.querySelector('.servers').addEventListener('click', function (e) { - var card = dom.parentWithClass(e.target, 'card'); + const card = dom.parentWithClass(e.target, 'card'); if (card) { - var url = card.getAttribute('data-url'); + const url = card.getAttribute('data-url'); if (url) { appRouter.show(url); } else { - var id = card.getAttribute('data-id'); + const id = card.getAttribute('data-id'); onServerClick(servers.filter(function (s) { return s.Id === id; })[0]); } } }); - }; + } /* eslint-enable indent */ From 9e2d2892654f2f019131533bcb8f0f2c96271b5e Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 15 Jul 2020 11:41:59 +0100 Subject: [PATCH 0241/1168] Migration of emby-buttton, paper-icon-button-light, emby-collapse, emby-imput to ES6 modules --- package.json | 4 +++ src/elements/emby-button/emby-button.js | 23 ++++++++---- .../emby-button/paper-icon-button-light.js | 12 ++++--- src/elements/emby-collapse/emby-collapse.js | 35 +++++++++++-------- src/elements/emby-input/emby-input.js | 32 ++++++++++------- 5 files changed, 67 insertions(+), 39 deletions(-) diff --git a/package.json b/package.json index 51f1ae10d..bc3847441 100644 --- a/package.json +++ b/package.json @@ -147,6 +147,10 @@ "src/elements/emby-checkbox/emby-checkbox.js", "src/elements/emby-textarea/emby-textarea.js", "src/elements/emby-toggle/emby-toggle.js", + "src/elements/emby-button/emby-button.js", + "src/elements/emby-button/paper-icon-button-light.js", + "src/elements/emby-collapse/emby-collapse.js", + "src/elements/emby-input/emby-input.js", "src/plugins/bookPlayer/plugin.js", "src/plugins/bookPlayer/tableOfContents.js", "src/plugins/photoPlayer/plugin.js", diff --git a/src/elements/emby-button/emby-button.js b/src/elements/emby-button/emby-button.js index be52b1d51..4848f4751 100644 --- a/src/elements/emby-button/emby-button.js +++ b/src/elements/emby-button/emby-button.js @@ -1,11 +1,19 @@ -define(['browser', 'dom', 'layoutManager', 'shell', 'appRouter', 'apphost', 'css!./emby-button', 'registerElement'], function (browser, dom, layoutManager, shell, appRouter, appHost) { - 'use strict'; +import browser from 'browser'; +import dom from 'dom'; +import layoutManager from 'layoutManager'; +import shell from 'shell'; +import appRouter from 'appRouter'; +import appHost from 'apphost'; +import 'css!./emby-button'; +import 'registerElement'; - var EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype); - var EmbyLinkButtonPrototype = Object.create(HTMLAnchorElement.prototype); +/* eslint-disable indent */ + + const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype); + const EmbyLinkButtonPrototype = Object.create(HTMLAnchorElement.prototype); function onAnchorClick(e) { - var href = this.getAttribute('href') || ''; + const href = this.getAttribute('href') || ''; if (href !== '#') { if (this.getAttribute('target')) { if (!appHost.supports('targetblank')) { @@ -66,5 +74,6 @@ define(['browser', 'dom', 'layoutManager', 'shell', 'appRouter', 'apphost', 'css extends: 'a' }); - return EmbyButtonPrototype; -}); + export default EmbyButtonPrototype; + +/* eslint-enable indent */ diff --git a/src/elements/emby-button/paper-icon-button-light.js b/src/elements/emby-button/paper-icon-button-light.js index 7eda76bae..5226f13db 100644 --- a/src/elements/emby-button/paper-icon-button-light.js +++ b/src/elements/emby-button/paper-icon-button-light.js @@ -1,7 +1,10 @@ -define(['layoutManager', 'css!./emby-button', 'registerElement'], function (layoutManager) { - 'use strict'; +import layoutManager from 'layoutManager'; +import 'css!./emby-button'; +import 'registerElement'; - var EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype); +/* eslint-disable indent */ + + const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype); EmbyButtonPrototype.createdCallback = function () { this.classList.add('paper-icon-button-light'); @@ -15,4 +18,5 @@ define(['layoutManager', 'css!./emby-button', 'registerElement'], function (layo prototype: EmbyButtonPrototype, extends: 'button' }); -}); + +/* eslint-enable indent */ diff --git a/src/elements/emby-collapse/emby-collapse.js b/src/elements/emby-collapse/emby-collapse.js index 707e81a78..805e40afd 100644 --- a/src/elements/emby-collapse/emby-collapse.js +++ b/src/elements/emby-collapse/emby-collapse.js @@ -1,18 +1,22 @@ -define(['browser', 'css!./emby-collapse', 'registerElement', 'emby-button'], function (browser) { - 'use strict'; +import browser from 'browser'; +import 'css!./emby-collapse'; +import 'registerElement'; +import 'emby-button'; - var EmbyButtonPrototype = Object.create(HTMLDivElement.prototype); +/* eslint-disable indent */ + + const EmbyButtonPrototype = Object.create(HTMLDivElement.prototype); function slideDownToShow(button, elem) { elem.classList.remove('hide'); elem.classList.add('expanded'); elem.style.height = 'auto'; - var height = elem.offsetHeight + 'px'; + const height = elem.offsetHeight + 'px'; elem.style.height = '0'; // trigger reflow - var newHeight = elem.offsetHeight; + const newHeight = elem.offsetHeight; elem.style.height = height; setTimeout(function () { @@ -24,7 +28,7 @@ define(['browser', 'css!./emby-collapse', 'registerElement', 'emby-button'], fun elem.style.height = 'auto'; }, 300); - var icon = button.querySelector('.material-icons'); + const icon = button.querySelector('.material-icons'); //icon.innerHTML = 'expand_less'; icon.classList.add('emby-collapse-expandIconExpanded'); } @@ -33,7 +37,7 @@ define(['browser', 'css!./emby-collapse', 'registerElement', 'emby-button'], fun elem.style.height = elem.offsetHeight + 'px'; // trigger reflow - var newHeight = elem.offsetHeight; + const newHeight = elem.offsetHeight; elem.classList.remove('expanded'); elem.style.height = '0'; @@ -46,15 +50,15 @@ define(['browser', 'css!./emby-collapse', 'registerElement', 'emby-button'], fun } }, 300); - var icon = button.querySelector('.material-icons'); + const icon = button.querySelector('.material-icons'); //icon.innerHTML = 'expand_more'; icon.classList.remove('emby-collapse-expandIconExpanded'); } function onButtonClick(e) { - var button = this; - var collapseContent = button.parentNode.querySelector('.collapseContent'); + const button = this; + const collapseContent = button.parentNode.querySelector('.collapseContent'); if (collapseContent.expanded) { collapseContent.expanded = false; @@ -73,18 +77,18 @@ define(['browser', 'css!./emby-collapse', 'registerElement', 'emby-button'], fun this.classList.add('emby-collapse'); - var collapseContent = this.querySelector('.collapseContent'); + const collapseContent = this.querySelector('.collapseContent'); if (collapseContent) { collapseContent.classList.add('hide'); } - var title = this.getAttribute('title'); + const title = this.getAttribute('title'); - var html = ''; + const html = ''; this.insertAdjacentHTML('afterbegin', html); - var button = this.querySelector('.emby-collapsible-button'); + const button = this.querySelector('.emby-collapsible-button'); button.addEventListener('click', onButtonClick); @@ -97,4 +101,5 @@ define(['browser', 'css!./emby-collapse', 'registerElement', 'emby-button'], fun prototype: EmbyButtonPrototype, extends: 'div' }); -}); + +/* eslint-enable indent */ diff --git a/src/elements/emby-input/emby-input.js b/src/elements/emby-input/emby-input.js index 1cef349bf..f5c60ca92 100644 --- a/src/elements/emby-input/emby-input.js +++ b/src/elements/emby-input/emby-input.js @@ -1,18 +1,23 @@ -define(['layoutManager', 'browser', 'dom', 'css!./emby-input', 'registerElement'], function (layoutManager, browser, dom) { - 'use strict'; +import layoutManager from 'layoutManager'; +import browser from 'browser'; +import dom from 'dom'; +import 'css!./emby-input'; +import 'registerElement'; - var EmbyInputPrototype = Object.create(HTMLInputElement.prototype); +/* eslint-disable indent */ - var inputId = 0; - var supportsFloatingLabel = false; + const EmbyInputPrototype = Object.create(HTMLInputElement.prototype); + + let inputId = 0; + let supportsFloatingLabel = false; if (Object.getOwnPropertyDescriptor && Object.defineProperty) { - var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value'); + const descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value'); // descriptor returning null in webos if (descriptor && descriptor.configurable) { - var baseSetMethod = descriptor.set; + const baseSetMethod = descriptor.set; descriptor.set = function (value) { baseSetMethod.call(this, value); @@ -39,9 +44,9 @@ define(['layoutManager', 'browser', 'dom', 'css!./emby-input', 'registerElement' this.classList.add('emby-input'); - var parentNode = this.parentNode; - var document = this.ownerDocument; - var label = document.createElement('label'); + const parentNode = this.parentNode; + const document = this.ownerDocument; + const label = document.createElement('label'); label.innerHTML = this.getAttribute('label') || ''; label.classList.add('inputLabel'); label.classList.add('inputLabelUnfocused'); @@ -95,12 +100,12 @@ define(['layoutManager', 'browser', 'dom', 'css!./emby-input', 'registerElement' function onChange() { - var label = this.labelElement; + const label = this.labelElement; if (this.value) { label.classList.remove('inputLabel-float'); } else { - var instanceSupportsFloat = supportsFloatingLabel && this.type !== 'date' && this.type !== 'time'; + const instanceSupportsFloat = supportsFloatingLabel && this.type !== 'date' && this.type !== 'time'; if (instanceSupportsFloat) { label.classList.add('inputLabel-float'); @@ -121,4 +126,5 @@ define(['layoutManager', 'browser', 'dom', 'css!./emby-input', 'registerElement' prototype: EmbyInputPrototype, extends: 'input' }); -}); + +/* eslint-enable indent */ From aca4c162724f4b7304f0dbda3ddb81313864e500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Fern=C3=A1ndez?= Date: Wed, 15 Jul 2020 13:38:51 +0200 Subject: [PATCH 0242/1168] Remove scrollbar on Firefox and mobile --- src/assets/css/scrollstyles.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/assets/css/scrollstyles.css b/src/assets/css/scrollstyles.css index 1cb3207e0..67c620225 100644 --- a/src/assets/css/scrollstyles.css +++ b/src/assets/css/scrollstyles.css @@ -12,6 +12,7 @@ .hiddenScrollX, .layout-tv .scrollX { -ms-overflow-style: none; + scrollbar-width: none; } .hiddenScrollX-forced { @@ -40,6 +41,7 @@ .hiddenScrollY, .layout-tv .smoothScrollY { -ms-overflow-style: none; + scrollbar-width: none; /* Can't do this because it not only hides the scrollbar, but also prevents scrolling */ From 1200617639db7aac537ba514b8d5fcc0437efd84 Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 15 Jul 2020 14:34:57 +0100 Subject: [PATCH 0243/1168] Migration of activitylog and datetime to ES6 modules --- package.json | 2 ++ src/components/activitylog.js | 29 +++++++++++++++------ src/controllers/dashboard/serveractivity.js | 2 +- src/scripts/datetime.js | 24 +++++++++-------- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 51f1ae10d..81d8b5f95 100644 --- a/package.json +++ b/package.json @@ -92,6 +92,7 @@ "test": [ "src/components/accessSchedule/accessSchedule.js", "src/components/actionSheet/actionSheet.js", + "src/components/activitylog.js", "src/components/alphaPicker/alphaPicker.js", "src/components/autoFocuser.js", "src/components/cardbuilder/cardBuilder.js", @@ -150,6 +151,7 @@ "src/plugins/bookPlayer/plugin.js", "src/plugins/bookPlayer/tableOfContents.js", "src/plugins/photoPlayer/plugin.js", + "src/scripts/datetime.js", "src/scripts/deleteHelper.js", "src/scripts/dfnshelper.js", "src/scripts/dom.js", diff --git a/src/components/activitylog.js b/src/components/activitylog.js index bbb099506..b51fc6787 100644 --- a/src/components/activitylog.js +++ b/src/components/activitylog.js @@ -1,5 +1,15 @@ -define(['events', 'globalize', 'dom', 'date-fns', 'dfnshelper', 'userSettings', 'serverNotifications', 'connectionManager', 'emby-button', 'listViewStyle'], function (events, globalize, dom, datefns, dfnshelper, userSettings, serverNotifications, connectionManager) { - 'use strict'; +import events from 'events'; +import globalize from 'globalize'; +import dom from 'dom'; +import * as datefns from 'date-fns'; +import dfnshelper from 'dfnshelper'; +import userSettings from 'userSettings'; +import serverNotifications from 'serverNotifications'; +import connectionManager from 'connectionManager'; +import 'emby-button'; +import 'listViewStyle'; + +/*eslint-disable indent */ function getEntryHtml(entry, apiClient) { var html = ''; @@ -125,7 +135,9 @@ define(['events', 'globalize', 'dom', 'date-fns', 'dfnshelper', 'userSettings', }); } - function ActivityLog(options) { +class ActivityLog { + constructor(options) { + console.log(options) this.options = options; var element = options.element; element.classList.add('activityLogListWidget'); @@ -137,8 +149,7 @@ define(['events', 'globalize', 'dom', 'date-fns', 'dfnshelper', 'userSettings', events.on(serverNotifications, 'ActivityLogEntry', onUpdate); apiClient.sendMessage('ActivityLogEntryStart', '0,1500'); } - - ActivityLog.prototype.destroy = function () { + destroy() { var options = this.options; if (options) { @@ -154,7 +165,9 @@ define(['events', 'globalize', 'dom', 'date-fns', 'dfnshelper', 'userSettings', this.items = null; this.options = null; - }; + } +} - return ActivityLog; -}); +export default ActivityLog; + +/*eslint-enable indent */ diff --git a/src/controllers/dashboard/serveractivity.js b/src/controllers/dashboard/serveractivity.js index c48a2903a..a3ce91592 100644 --- a/src/controllers/dashboard/serveractivity.js +++ b/src/controllers/dashboard/serveractivity.js @@ -14,7 +14,7 @@ define(['components/activitylog', 'globalize'], function (ActivityLog, globalize view.addEventListener('viewshow', function () { if (!activityLog) { - activityLog = new ActivityLog({ + activityLog = new ActivityLog.default({ serverId: ApiClient.serverId(), element: view.querySelector('.activityItems') }); diff --git a/src/scripts/datetime.js b/src/scripts/datetime.js index 34ff23fe6..6b7aa6999 100644 --- a/src/scripts/datetime.js +++ b/src/scripts/datetime.js @@ -1,7 +1,8 @@ -define(['globalize'], function (globalize) { - 'use strict'; +import globalize from 'globalize'; - function parseISO8601Date(s, toLocal) { +/*eslint-disable indent */ + + export function parseISO8601Date(s, toLocal) { // parenthese matches: // year month day hours minutes seconds @@ -58,7 +59,7 @@ define(['globalize'], function (globalize) { return new Date(ms); } - function getDisplayRunningTime(ticks) { + export function getDisplayRunningTime(ticks) { var ticksPerHour = 36000000000; var ticksPerMinute = 600000000; var ticksPerSecond = 10000000; @@ -118,7 +119,7 @@ define(['globalize'], function (globalize) { return list; } - function toLocaleString(date, options) { + export function toLocaleString(date, options) { if (!date) { throw new Error('date cannot be null'); @@ -138,7 +139,7 @@ define(['globalize'], function (globalize) { return date.toLocaleString(); } - function toLocaleDateString(date, options) { + export function toLocaleDateString(date, options) { if (!date) { throw new Error('date cannot be null'); @@ -172,7 +173,7 @@ define(['globalize'], function (globalize) { return date.toLocaleDateString(); } - function toLocaleTimeString(date, options) { + export function toLocaleTimeString(date, options) { if (!date) { throw new Error('date cannot be null'); @@ -192,7 +193,7 @@ define(['globalize'], function (globalize) { return date.toLocaleTimeString(); } - function getDisplayTime(date) { + export function getDisplayTime(date) { if (!date) { throw new Error('date cannot be null'); @@ -253,7 +254,7 @@ define(['globalize'], function (globalize) { return time; } - function isRelativeDay(date, offsetInDays) { + export function isRelativeDay(date, offsetInDays) { if (!date) { throw new Error('date cannot be null'); @@ -267,7 +268,7 @@ define(['globalize'], function (globalize) { return date.getFullYear() === yesterday.getFullYear() && date.getMonth() === yesterday.getMonth() && date.getDate() === day; } - return { + export default { parseISO8601Date: parseISO8601Date, getDisplayRunningTime: getDisplayRunningTime, toLocaleDateString: toLocaleDateString, @@ -279,4 +280,5 @@ define(['globalize'], function (globalize) { return toLocaleTimeStringSupportsLocales; } }; -}); + +/*eslint-enable indent */ From 45df6ef764bd469abab449d7966ab5136170bfe2 Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 15 Jul 2020 14:46:56 +0100 Subject: [PATCH 0244/1168] Migration of alert to ES6 module --- package.json | 1 + src/components/activitylog.js | 3 +-- src/components/alert.js | 14 +++++++++----- src/components/appRouter.js | 2 +- src/components/multiSelect/multiSelect.js | 2 +- src/components/playback/playbackmanager.js | 2 +- src/controllers/dashboard/encodingsettings.js | 2 +- src/controllers/dashboard/metadatanfo.js | 2 +- src/controllers/itemDetails.js | 2 +- src/plugins/chromecastPlayer/plugin.js | 2 +- src/scripts/serverNotifications.js | 2 +- src/scripts/site.js | 2 +- 12 files changed, 20 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 81d8b5f95..1707f0620 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,7 @@ "src/components/accessSchedule/accessSchedule.js", "src/components/actionSheet/actionSheet.js", "src/components/activitylog.js", + "src/components/alert.js", "src/components/alphaPicker/alphaPicker.js", "src/components/autoFocuser.js", "src/components/cardbuilder/cardBuilder.js", diff --git a/src/components/activitylog.js b/src/components/activitylog.js index b51fc6787..75b07a4cc 100644 --- a/src/components/activitylog.js +++ b/src/components/activitylog.js @@ -128,7 +128,7 @@ import 'listViewStyle'; } function showItemOverview(item) { - require(['alert'], function (alert) { + import('alert').then(({default: alert})=> { alert({ text: item.Overview }); @@ -137,7 +137,6 @@ import 'listViewStyle'; class ActivityLog { constructor(options) { - console.log(options) this.options = options; var element = options.element; element.classList.add('activityLogListWidget'); diff --git a/src/components/alert.js b/src/components/alert.js index 97b580f8f..80bfbc48e 100644 --- a/src/components/alert.js +++ b/src/components/alert.js @@ -1,12 +1,15 @@ -define(['browser', 'dialog', 'globalize'], function (browser, dialog, globalize) { - 'use strict'; +import browser from 'browser'; +import dialog from 'dialog'; +import globalize from 'globalize'; + +/*eslint-disable indent*/ function replaceAll(originalString, strReplace, strWith) { var reg = new RegExp(strReplace, 'ig'); return originalString.replace(reg, strWith); } - return function (text, title) { + export default function (text, title) { var options; if (typeof text === 'string') { @@ -41,5 +44,6 @@ define(['browser', 'dialog', 'globalize'], function (browser, dialog, globalize) } return Promise.resolve(); - }; -}); + } + +/*eslint-enable indent*/ diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 0861cf7e0..c2bec1769 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -53,7 +53,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro break; case 'ServerUpdateNeeded': require(['alert'], function (alert) { - alert({ + alert.default({ text: globalize.translate('ServerUpdateNeeded', 'https://github.com/jellyfin/jellyfin'), html: globalize.translate('ServerUpdateNeeded', 'https://github.com/jellyfin/jellyfin') }).then(function () { diff --git a/src/components/multiSelect/multiSelect.js b/src/components/multiSelect/multiSelect.js index 05a2b68f4..922a1fcc1 100644 --- a/src/components/multiSelect/multiSelect.js +++ b/src/components/multiSelect/multiSelect.js @@ -338,7 +338,7 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo if (selection.length < 2) { require(['alert'], function (alert) { - alert({ + alert.default({ text: globalize.translate('PleaseSelectTwoItems') }); }); diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 73f07a05f..b74ca5fb3 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -709,7 +709,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla function showPlaybackInfoErrorMessage(instance, errorCode, playNextTrack) { require(['alert'], function (alert) { - alert({ + alert.default({ text: globalize.translate('PlaybackError' + errorCode), title: globalize.translate('HeaderPlaybackError') }).then(function () { diff --git a/src/controllers/dashboard/encodingsettings.js b/src/controllers/dashboard/encodingsettings.js index b8cdd6665..098a8d6f6 100644 --- a/src/controllers/dashboard/encodingsettings.js +++ b/src/controllers/dashboard/encodingsettings.js @@ -86,7 +86,7 @@ define(['jQuery', 'loading', 'globalize', 'dom', 'libraryMenu'], function ($, lo if ($('#selectVideoDecoder', form).val()) { require(['alert'], function (alert) { - alert({ + alert.default({ title: globalize.translate('TitleHardwareAcceleration'), text: globalize.translate('HardwareAccelerationWarning') }).then(onDecoderConfirmed); diff --git a/src/controllers/dashboard/metadatanfo.js b/src/controllers/dashboard/metadatanfo.js index a93619261..3ef1a7cbf 100644 --- a/src/controllers/dashboard/metadatanfo.js +++ b/src/controllers/dashboard/metadatanfo.js @@ -36,7 +36,7 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading, msg.push(globalize.translate('MetadataSettingChangeHelp')); require(['alert'], function (alert) { - alert({ + alert.default({ text: msg.join('

') }); }); diff --git a/src/controllers/itemDetails.js b/src/controllers/itemDetails.js index c9b6b7fc1..cfaa5ab97 100644 --- a/src/controllers/itemDetails.js +++ b/src/controllers/itemDetails.js @@ -1787,7 +1787,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti imageLoader.lazyChildren(collectionItems); collectionItems.querySelector('.btnAddToCollection').addEventListener('click', function () { require(['alert'], function (alert) { - alert({ + alert.default({ text: globalize.translate('AddItemToCollectionHelp'), html: globalize.translate('AddItemToCollectionHelp') + '

' + globalize.translate('ButtonLearnMore') + '' }); diff --git a/src/plugins/chromecastPlayer/plugin.js b/src/plugins/chromecastPlayer/plugin.js index b3f75f7a6..dad95691f 100644 --- a/src/plugins/chromecastPlayer/plugin.js +++ b/src/plugins/chromecastPlayer/plugin.js @@ -150,7 +150,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' function alertText(text, title) { require(['alert'], function (alert) { - alert({ + alert.default({ text: text, title: title }); diff --git a/src/scripts/serverNotifications.js b/src/scripts/serverNotifications.js index 2553c284f..8e212ab71 100644 --- a/src/scripts/serverNotifications.js +++ b/src/scripts/serverNotifications.js @@ -15,7 +15,7 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in }); } else { require(['alert'], function (alert) { - alert({ title: args.Header, text: args.Text }); + alert.default({ title: args.Header, text: args.Text }); }); } } diff --git a/src/scripts/site.js b/src/scripts/site.js index c3f93d954..17bff0dec 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -187,7 +187,7 @@ var Dashboard = { } require(['alert'], function (alert) { - alert({ + alert.default({ title: options.title || Globalize.translate('HeaderAlert'), text: options.message }).then(options.callback || function () {}); From 3e148183740615bd447b98aa1bd7b9213f0a862d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Fern=C3=A1ndez?= Date: Wed, 15 Jul 2020 17:16:43 +0200 Subject: [PATCH 0245/1168] Remove repeated fav icon in remotecontrol in desktop layout --- src/components/remotecontrol/remotecontrol.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index d4511a9dd..c26079958 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -278,6 +278,10 @@ flex-direction: column; } + .layout-desktop .nowPlayingPageUserDataButtons { + display: none; + } + .nowPlayingInfoContainer { -webkit-box-orient: vertical !important; -webkit-box-direction: normal !important; From 1aeedf0fd0a30c023d903acd86ac3646ac93003f Mon Sep 17 00:00:00 2001 From: Viperinius Date: Wed, 15 Jul 2020 18:10:31 +0000 Subject: [PATCH 0246/1168] Translated using Weblate (German) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/ --- src/strings/de.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/strings/de.json b/src/strings/de.json index 6e3bd00f4..c9b126a08 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -1588,5 +1588,8 @@ "HeaderNewRepository": "Neues Repository", "MessageNoRepositories": "Keine Repositories.", "ButtonPlayer": "Player", - "Writers": "Autoren" + "Writers": "Autoren", + "ClearQueue": "Wiedergabeliste leeren", + "StopPlayback": "Wiedergabe anhalten", + "ViewAlbumArtist": "Zeige Albumkünstler" } From 0989b5222c66aa5a87a9273b2ae794f43e185a48 Mon Sep 17 00:00:00 2001 From: dumais1112 Date: Thu, 16 Jul 2020 02:53:33 +0000 Subject: [PATCH 0247/1168] Translated using Weblate (French (Canada)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr_CA/ --- src/strings/fr-ca.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/fr-ca.json b/src/strings/fr-ca.json index 67dd189a1..5f03a9d43 100644 --- a/src/strings/fr-ca.json +++ b/src/strings/fr-ca.json @@ -139,7 +139,7 @@ "BoxRear": "Dos de boîtier", "Browse": "Parcourir", "BrowsePluginCatalogMessage": "Explorer notre catalogue des plugins pour voir les plugins disponibles.", - "AllowHWTranscodingHelp": "Permet au récepteur TV de transcoder les flux à la volée. Cela peut aider à réduire le transcodage requis par le serveur.", + "AllowHWTranscodingHelp": "Permets au syntonisateur de transcoder les flux à la volée. Cela peut aider à réduire le transcodage requis par le serveur.", "BurnSubtitlesHelp": "Détermine si le serveur doit graver les sous-titres lors du transcodage vidéo. Éviter ceci améliorera les performances du serveur. Sélectionnez Auto pour graver les formats basés sur l'image (par exemple, VOBSUB, PGS, SUB/IDX etc) ainsi que certains sous-titres ASS/SSA.", "ButtonAccept": "Accepter", "ButtonAdd": "Ajouter", From 89fcda5f058d525294184d08dedca33df9bf32d9 Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 16 Jul 2020 10:28:08 +0100 Subject: [PATCH 0248/1168] Migration of searchfields, searchresults and searchpage to ES6 modules --- package.json | 3 ++ src/components/search/searchfields.js | 61 +++++++++++++---------- src/components/search/searchresults.js | 61 +++++++++++++---------- src/controllers/searchpage.js | 67 +++++++++++++------------- 4 files changed, 109 insertions(+), 83 deletions(-) diff --git a/package.json b/package.json index 51f1ae10d..b7c08fd28 100644 --- a/package.json +++ b/package.json @@ -126,6 +126,8 @@ "src/components/playmenu.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", + "src/components/search/searchfields.js", + "src/components/search/searchresults.js", "src/components/settingshelper.js", "src/components/subtitlesettings/subtitlesettings.js", "src/components/subtitlesettings/subtitleappearancehelper.js", @@ -137,6 +139,7 @@ "src/controllers/dashboard/logs.js", "src/controllers/user/subtitles.js", "src/controllers/dashboard/plugins/repositories.js", + "src/controllers/searchpage.js", "src/elements/emby-tabs/emby-tabs.js", "src/elements/emby-scroller/emby-scroller.js", "src/elements/emby-radio/emby-radio.js", diff --git a/src/components/search/searchfields.js b/src/components/search/searchfields.js index 7e7781477..99915e40b 100644 --- a/src/components/search/searchfields.js +++ b/src/components/search/searchfields.js @@ -1,10 +1,20 @@ -define(['layoutManager', 'globalize', 'require', 'events', 'browser', 'alphaPicker', 'emby-input', 'flexStyles', 'material-icons', 'css!./searchfields'], function (layoutManager, globalize, require, events, browser, AlphaPicker) { - 'use strict'; +import layoutManager from 'layoutManager'; +import globalize from 'globalize'; +import require from 'require'; +import events from 'events'; +import browser from 'browser'; +import AlphaPicker from 'alphaPicker'; +import 'emby-input'; +import 'flexStyles'; +import 'material-icons'; +import 'css!./searchfields'; + +/* eslint-disable indent*/ function onSearchTimeout() { - var instance = this; - var value = instance.nextSearchValue; + const instance = this; + let value = instance.nextSearchValue; value = (value || '').trim(); events.trigger(instance, 'search', [value]); @@ -22,14 +32,14 @@ define(['layoutManager', 'globalize', 'require', 'events', 'browser', 'alphaPick function onAlphaValueClicked(e) { - var value = e.detail.value; - var searchFieldsInstance = this; + const value = e.detail.value; + const searchFieldsInstance = this; - var txtSearch = searchFieldsInstance.options.element.querySelector('.searchfields-txtSearch'); + const txtSearch = searchFieldsInstance.options.element.querySelector('.searchfields-txtSearch'); if (value === 'backspace') { - var val = txtSearch.value; + const val = txtSearch.value; txtSearch.value = val.length ? val.substring(0, val.length - 1) : ''; } else { @@ -53,8 +63,8 @@ define(['layoutManager', 'globalize', 'require', 'events', 'browser', 'alphaPick function onSearchInput(e) { - var value = e.target.value; - var searchFieldsInstance = this; + const value = e.target.value; + const searchFieldsInstance = this; triggerSearch(searchFieldsInstance, value); } @@ -62,7 +72,7 @@ define(['layoutManager', 'globalize', 'require', 'events', 'browser', 'alphaPick require(['text!./searchfields.template.html'], function (template) { - var html = globalize.translateDocument(template, 'core'); + let html = globalize.translateDocument(template, 'core'); if (browser.tizen || browser.orsay) { html = html.replace(''; + let itemHtml = ''; return itemHtml; }).join(''); - var searchSuggestions = context.querySelector('.searchSuggestions'); + const searchSuggestions = context.querySelector('.searchSuggestions'); searchSuggestions.querySelector('.searchSuggestionsList').innerHTML = html; if (result.Items.length) { @@ -49,9 +59,9 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }); } - var allowSearch = true; + let allowSearch = true; - var queryIncludeItemTypes = query.IncludeItemTypes; + const queryIncludeItemTypes = query.IncludeItemTypes; if (instance.options.collectionType === 'tvshows') { if (query.IncludeArtists) { @@ -127,7 +137,7 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', query.EnableTotalRecordCount = false; query.ImageTypeLimit = 1; - var methodName = 'getItems'; + let methodName = 'getItems'; if (!query.IncludeMedia) { if (query.IncludePeople) { @@ -566,9 +576,9 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', section = context.querySelector(section); - var items = result.Items || result.SearchHints; + const items = result.Items || result.SearchHints; - var itemsContainer = section.querySelector('.itemsContainer'); + const itemsContainer = section.querySelector('.itemsContainer'); cardBuilder.buildCards(items, Object.assign({ @@ -588,7 +598,7 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', } function replaceAll(originalString, strReplace, strWith) { - var reg = new RegExp(strReplace, 'ig'); + const reg = new RegExp(strReplace, 'ig'); return originalString.replace(reg, strWith); } @@ -601,7 +611,7 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', template = replaceAll(template, 'itemsContainer scrollSlider', 'itemsContainer scrollSlider vertical-wrap'); } - var html = globalize.translateDocument(template, 'core'); + const html = globalize.translateDocument(template, 'core'); elem.innerHTML = html; @@ -610,28 +620,29 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', }); } - function SearchResults(options) { +class SearchResults { + constructor(options) { this.options = options; embed(options.element, this, options); } + search(value) { - SearchResults.prototype.search = function (value) { - - var apiClient = connectionManager.getApiClient(this.options.serverId); + const apiClient = connectionManager.getApiClient(this.options.serverId); search(this, apiClient, this.options.element, value); - }; + } + destroy() { - SearchResults.prototype.destroy = function () { - - var options = this.options; + const options = this.options; if (options) { options.element.classList.remove('searchFields'); } this.options = null; - }; + } +} - return SearchResults; -}); +export default SearchResults; + +/*eslint-enable indent*/ diff --git a/src/controllers/searchpage.js b/src/controllers/searchpage.js index 8a138b751..8ce3e8afe 100644 --- a/src/controllers/searchpage.js +++ b/src/controllers/searchpage.js @@ -1,36 +1,37 @@ -define(['focusManager', 'searchFields', 'searchResults', 'events'], function (focusManager, SearchFields, SearchResults, events) { - 'use strict'; +import focusManager from 'focusManager'; +import SearchFields from 'searchFields'; +import SearchResults from 'searchResults'; +import events from 'events'; - return function (view, params) { - function onSearch(e, value) { - self.searchResults.search(value); +export default function (view, params) { + function onSearch(e, value) { + self.searchResults.search(value); + } + + const self = this; + view.addEventListener('viewshow', function () { + if (!self.searchFields) { + self.searchFields = new SearchFields({ + element: view.querySelector('.searchFields') + }); + self.searchResults = new SearchResults({ + element: view.querySelector('.searchResults'), + serverId: params.serverId || ApiClient.serverId(), + parentId: params.parentId, + collectionType: params.collectionType + }); + events.on(self.searchFields, 'search', onSearch); + } + }); + view.addEventListener('viewdestroy', function () { + if (self.searchFields) { + self.searchFields.destroy(); + self.searchFields = null; } - var self = this; - view.addEventListener('viewshow', function () { - if (!self.searchFields) { - self.searchFields = new SearchFields({ - element: view.querySelector('.searchFields') - }); - self.searchResults = new SearchResults({ - element: view.querySelector('.searchResults'), - serverId: params.serverId || ApiClient.serverId(), - parentId: params.parentId, - collectionType: params.collectionType - }); - events.on(self.searchFields, 'search', onSearch); - } - }); - view.addEventListener('viewdestroy', function () { - if (self.searchFields) { - self.searchFields.destroy(); - self.searchFields = null; - } - - if (self.searchResults) { - self.searchResults.destroy(); - self.searchResults = null; - } - }); - }; -}); + if (self.searchResults) { + self.searchResults.destroy(); + self.searchResults = null; + } + }); +} From dfcf0d5d6b034943b43becf42b56a6ace14fbf3c Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 16 Jul 2020 11:25:17 +0100 Subject: [PATCH 0249/1168] update variable declerations --- src/controllers/dashboard/general.js | 22 ++++++++++----------- src/controllers/dashboard/librarydisplay.js | 5 ++--- src/controllers/dashboard/metadataImages.js | 18 ++++++++--------- src/controllers/dashboard/metadatanfo.js | 14 ++++++------- src/controllers/dashboard/streaming.js | 4 ++-- 5 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/controllers/dashboard/general.js b/src/controllers/dashboard/general.js index 2defc6d44..8e30749ab 100644 --- a/src/controllers/dashboard/general.js +++ b/src/controllers/dashboard/general.js @@ -24,7 +24,7 @@ import 'emby-button'; function onSubmit() { loading.show(); - var form = this; + const form = this; $(form).parents('.page'); ApiClient.getServerConfiguration().then(function (config) { config.ServerName = $('#txtServerName', form).val(); @@ -32,7 +32,7 @@ import 'emby-button'; config.CachePath = form.querySelector('#txtCachePath').value; config.MetadataPath = $('#txtMetadataPath', form).val(); config.MetadataNetworkPath = $('#txtMetadataNetworkPath', form).val(); - var requiresReload = config.UICulture !== currentLanguage; + let requiresReload = config.UICulture !== currentLanguage; ApiClient.updateServerConfiguration(config).then(function() { ApiClient.getNamedConfiguration(brandingConfigKey).then(function(brandingConfig) { brandingConfig.LoginDisclaimer = form.querySelector('#txtLoginDisclaimer').value; @@ -61,13 +61,13 @@ import 'emby-button'; return false; } - var currentBrandingOptions; - var currentLanguage; - var brandingConfigKey = 'branding'; + let currentBrandingOptions; + let currentLanguage; + const brandingConfigKey = 'branding'; export default function (view, params) { $('#btnSelectCachePath', view).on('click.selectDirectory', function () { import('directorybrowser').then(({default: directoryBrowser}) => { - var picker = new directoryBrowser(); + const picker = new directoryBrowser(); picker.show({ callback: function (path) { if (path) { @@ -84,7 +84,7 @@ import 'emby-button'; }); $('#btnSelectMetadataPath', view).on('click.selectDirectory', function () { import('directorybrowser').then(({default: directoryBrowser}) => { - var picker = new directoryBrowser(); + const picker = new directoryBrowser(); picker.show({ path: $('#txtMetadataPath', view).val(), networkSharePath: $('#txtMetadataNetworkPath', view).val(), @@ -108,9 +108,9 @@ import 'emby-button'; }); $('.dashboardGeneralForm', view).off('submit', onSubmit).on('submit', onSubmit); view.addEventListener('viewshow', function () { - var promiseConfig = ApiClient.getServerConfiguration(); - var promiseLanguageOptions = ApiClient.getJSON(ApiClient.getUrl('Localization/Options')); - var promiseSystemInfo = ApiClient.getSystemInfo(); + const promiseConfig = ApiClient.getServerConfiguration(); + const promiseLanguageOptions = ApiClient.getJSON(ApiClient.getUrl('Localization/Options')); + const promiseSystemInfo = ApiClient.getSystemInfo(); Promise.all([promiseConfig, promiseLanguageOptions, promiseSystemInfo]).then(function (responses) { loadPage(view, responses[0], responses[1], responses[2]); }); @@ -120,6 +120,6 @@ import 'emby-button'; view.querySelector('#txtCustomCss').value = config.CustomCss || ''; }); }); - }; + } /* eslint-enable indent */ diff --git a/src/controllers/dashboard/librarydisplay.js b/src/controllers/dashboard/librarydisplay.js index 95475cfb9..54ed028a3 100644 --- a/src/controllers/dashboard/librarydisplay.js +++ b/src/controllers/dashboard/librarydisplay.js @@ -3,7 +3,6 @@ import loading from 'loading'; import libraryMenu from 'libraryMenu'; import 'emby-checkbox'; import 'emby-button'; -import 'emby-button'; /* eslint-disable indent */ @@ -39,7 +38,7 @@ import 'emby-button'; view.querySelector('form').addEventListener('submit', function(e) { loading.show(); - var form = this; + const form = this; ApiClient.getServerConfiguration().then(function(config) { config.EnableFolderView = form.querySelector('.chkFolderView').checked; config.EnableGroupingIntoCollections = form.querySelector('.chkGroupMoviesIntoCollections').checked; @@ -69,6 +68,6 @@ import 'emby-button'; } }); }); - }; + } /* eslint-enable indent */ diff --git a/src/controllers/dashboard/metadataImages.js b/src/controllers/dashboard/metadataImages.js index 6573d9858..cbfe05419 100644 --- a/src/controllers/dashboard/metadataImages.js +++ b/src/controllers/dashboard/metadataImages.js @@ -9,10 +9,10 @@ import 'listViewStyle'; function populateLanguages(select) { return ApiClient.getCultures().then(function(languages) { - var html = ''; + let html = ''; html += ""; - for (var i = 0, length = languages.length; i < length; i++) { - var culture = languages[i]; + for (let i = 0, length = languages.length; i < length; i++) { + const culture = languages[i]; html += "'; } select.innerHTML = html; @@ -21,10 +21,10 @@ import 'listViewStyle'; function populateCountries(select) { return ApiClient.getCountries().then(function(allCountries) { - var html = ''; + let html = ''; html += ""; - for (var i = 0, length = allCountries.length; i < length; i++) { - var culture = allCountries[i]; + for (let i = 0, length = allCountries.length; i < length; i++) { + const culture = allCountries[i]; html += "'; } select.innerHTML = html; @@ -32,9 +32,9 @@ import 'listViewStyle'; } function loadPage(page) { - var promises = [ApiClient.getServerConfiguration(), populateLanguages(page.querySelector('#selectLanguage')), populateCountries(page.querySelector('#selectCountry'))]; + const promises = [ApiClient.getServerConfiguration(), populateLanguages(page.querySelector('#selectLanguage')), populateCountries(page.querySelector('#selectCountry'))]; Promise.all(promises).then(function(responses) { - var config = responses[0]; + const config = responses[0]; page.querySelector('#selectLanguage').value = config.PreferredMetadataLanguage || ''; page.querySelector('#selectCountry').value = config.MetadataCountryCode || ''; loading.hide(); @@ -42,7 +42,7 @@ import 'listViewStyle'; } function onSubmit() { - var form = this; + const form = this; return loading.show(), ApiClient.getServerConfiguration().then(function(config) { config.PreferredMetadataLanguage = form.querySelector('#selectLanguage').value; config.MetadataCountryCode = form.querySelector('#selectCountry').value; diff --git a/src/controllers/dashboard/metadatanfo.js b/src/controllers/dashboard/metadatanfo.js index 0659d477c..f1b768d18 100644 --- a/src/controllers/dashboard/metadatanfo.js +++ b/src/controllers/dashboard/metadatanfo.js @@ -6,7 +6,7 @@ import globalize from 'globalize'; /* eslint-disable indent */ function loadPage(page, config, users) { - var html = ''; + let html = ''; html += users.map(function (user) { return ''; }).join(''); @@ -20,7 +20,7 @@ import globalize from 'globalize'; function onSubmit() { loading.show(); - var form = this; + const form = this; ApiClient.getNamedConfiguration(metadataKey).then(function (config) { config.UserId = $('#selectUser', form).val() || null; config.ReleaseDateFormat = $('#selectReleaseDateFormat', form).val(); @@ -36,7 +36,7 @@ import globalize from 'globalize'; } function showConfirmMessage(config) { - var msg = []; + const msg = []; msg.push(globalize.translate('MetadataSettingChangeHelp')); import('alert').then(({default: alert}) => { @@ -62,15 +62,15 @@ import globalize from 'globalize'; }]; } - var metadataKey = 'xbmcmetadata'; + const metadataKey = 'xbmcmetadata'; $(document).on('pageinit', '#metadataNfoPage', function () { $('.metadataNfoForm').off('submit', onSubmit).on('submit', onSubmit); }).on('pageshow', '#metadataNfoPage', function () { libraryMenu.setTabs('metadata', 3, getTabs); loading.show(); - var page = this; - var promise1 = ApiClient.getUsers(); - var promise2 = ApiClient.getNamedConfiguration(metadataKey); + const page = this; + const promise1 = ApiClient.getUsers(); + const promise2 = ApiClient.getNamedConfiguration(metadataKey); Promise.all([promise1, promise2]).then(function (responses) { loadPage(page, responses[1], responses[0]); }); diff --git a/src/controllers/dashboard/streaming.js b/src/controllers/dashboard/streaming.js index 15d6c8920..c54fbea47 100644 --- a/src/controllers/dashboard/streaming.js +++ b/src/controllers/dashboard/streaming.js @@ -12,7 +12,7 @@ import globalize from 'globalize'; function onSubmit() { loading.show(); - var form = this; + const form = this; ApiClient.getServerConfiguration().then(function (config) { config.RemoteClientBitrateLimit = parseInt(1e6 * parseFloat($('#txtRemoteClientBitrateLimit', form).val() || '0')); ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult); @@ -39,7 +39,7 @@ import globalize from 'globalize'; }).on('pageshow', '#streamingSettingsPage', function () { loading.show(); libraryMenu.setTabs('playback', 2, getTabs); - var page = this; + const page = this; ApiClient.getServerConfiguration().then(function (config) { loadPage(page, config); }); From c4a1677523ed4b637cabb52bcb04e59a1a93fb9a Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 16 Jul 2020 15:26:02 +0200 Subject: [PATCH 0250/1168] Fix image size used on main item card --- src/controllers/itemDetails/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index 2f0c9cc03..823a837b7 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -726,7 +726,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti disableIndicators: true, disableHoverMenu: true, overlayPlayButton: true, - width: dom.getWindowSize().innerWidth * 0.25 + width: dom.getWindowSize().innerWidth * 0.5 }); elem.innerHTML = cardHtml; From 8c406176fb90be8fe517695de9c1f25c68309f32 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 16 Jul 2020 15:26:34 +0200 Subject: [PATCH 0251/1168] Change image action from resume to link --- src/components/listview/listview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/listview/listview.js b/src/components/listview/listview.js index dda0d3490..60340e2a0 100644 --- a/src/components/listview/listview.js +++ b/src/components/listview/listview.js @@ -273,7 +273,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan imageClass += ' itemAction'; } - var imageAction = playOnImageClick ? 'resume' : action; + var imageAction = playOnImageClick ? 'link' : action; if (imgUrl) { html += '
'; From 4c95485835a5f76633b0abec35ff92dae6d8b00a Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 16 Jul 2020 15:26:59 +0200 Subject: [PATCH 0252/1168] Don't play songs unless clicking on play in search results --- src/components/search/searchresults.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/search/searchresults.js b/src/components/search/searchresults.js index d4de2349a..5c9a8d05d 100644 --- a/src/components/search/searchresults.js +++ b/src/components/search/searchresults.js @@ -464,7 +464,6 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', showTitle: true, overlayText: false, centerText: true, - action: 'play' }); From af11f8b3b7f81fb1f00961e9c6508af4d890f60f Mon Sep 17 00:00:00 2001 From: ADRI IDZWAN MANSOR Date: Thu, 16 Jul 2020 11:38:27 +0000 Subject: [PATCH 0253/1168] Translated using Weblate (Malay) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ms/ --- src/strings/ms.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/strings/ms.json b/src/strings/ms.json index 0c8363392..d5f9259c2 100644 --- a/src/strings/ms.json +++ b/src/strings/ms.json @@ -103,5 +103,16 @@ "Genres": "Genre-genre", "Collections": "Koleksi", "Channels": "Saluran", - "ButtonSyncPlay": "SyncPlay" + "ButtonSyncPlay": "SyncPlay", + "Movies": "Filem", + "HeaderNextUp": "Seterusnya", + "HeaderLiveTV": "TV Siaran Langsung", + "HeaderFavoriteSongs": "Lagu-lagu Kegemaran", + "HeaderFavoriteShows": "Rancangan-rancangan Kegemaran", + "HeaderFavoriteEpisodes": "Episod-episod Kegemaran", + "HeaderFavoriteArtists": "Artis-artis Kegemaran", + "HeaderFavoriteAlbums": "Album-album Kegemaran", + "HeaderAlbumArtists": "Album Artis-artis", + "Folders": "Fail-fail", + "Favorites": "Kegemaran" } From fe91b4a695a5bf2d8ad40be84aaf132cec5e625a Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 16 Jul 2020 15:43:41 +0200 Subject: [PATCH 0254/1168] Fix play button on search results on mobile --- src/components/search/searchresults.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/search/searchresults.js b/src/components/search/searchresults.js index 5c9a8d05d..88c68fded 100644 --- a/src/components/search/searchresults.js +++ b/src/components/search/searchresults.js @@ -464,6 +464,7 @@ define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', showTitle: true, overlayText: false, centerText: true, + overlayPlayButton: true }); From eafb851c4031e3dc591be0b422c55808588f6552 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 16 Jul 2020 16:03:36 +0200 Subject: [PATCH 0255/1168] Fix quality settings for images --- src/components/appRouter.js | 39 +++---------------------------------- 1 file changed, 3 insertions(+), 36 deletions(-) diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 0861cf7e0..56af4cf03 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -222,46 +222,13 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } function normalizeImageOptions(options) { - var scaleFactor = browser.tv ? 0.8 : 1; - var setQuality; - if (options.maxWidth) { - options.maxWidth = Math.round(options.maxWidth * scaleFactor); + if (options.maxWidth || options.width || options.maxHeight || options.height) { setQuality = true; } - if (options.width) { - options.width = Math.round(options.width * scaleFactor); - setQuality = true; - } - - if (options.maxHeight) { - options.maxHeight = Math.round(options.maxHeight * scaleFactor); - setQuality = true; - } - - if (options.height) { - options.height = Math.round(options.height * scaleFactor); - setQuality = true; - } - - if (setQuality) { - var quality; - var type = options.type || 'Primary'; - - if (browser.tv || browser.slow) { - // TODO: wtf - if (browser.chrome) { - // webp support - quality = type === 'Primary' ? 40 : 50; - } else { - quality = type === 'Backdrop' ? 60 : 50; - } - } else { - quality = type === 'Backdrop' ? 70 : 90; - } - - options.quality = quality; + if (setQuality || !options.quality) { + options.quality = 90; } } From d662134cfbaee883839c618a6cca3940cba6f3e8 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 16 Jul 2020 10:51:41 -0400 Subject: [PATCH 0256/1168] Fix lighter header/footer background color --- src/themes/dark/theme.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/themes/dark/theme.css b/src/themes/dark/theme.css index 2fdc44e60..2732a3fc6 100644 --- a/src/themes/dark/theme.css +++ b/src/themes/dark/theme.css @@ -109,7 +109,7 @@ html { .formDialogHeader:not(.formDialogHeader-clear), .paperList, .visualCardBox { - background-color: #242424; + background-color: #202020; } .defaultCardBackground1 { From 94f1a5aad5657d3851f1d425e0d9ef5b9f001efe Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Thu, 16 Jul 2020 11:24:30 -0400 Subject: [PATCH 0257/1168] Remove iOS footer hack --- src/assets/css/ios.css | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/assets/css/ios.css b/src/assets/css/ios.css index 57de0c5fd..2b61f49a4 100644 --- a/src/assets/css/ios.css +++ b/src/assets/css/ios.css @@ -1,8 +1,3 @@ html { font-size: 82% !important; } - -.formDialogFooter { - position: static !important; - margin: 0 -1em !important; -} From 3c37a57866a02ab3a7887f225ea0e79d51db9bf2 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 16 Jul 2020 17:25:36 +0200 Subject: [PATCH 0258/1168] Fix suggestions --- src/components/appRouter.js | 2 +- src/controllers/itemDetails/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 56af4cf03..58c64e7d4 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -227,7 +227,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro setQuality = true; } - if (setQuality || !options.quality) { + if (setQuality && !options.quality) { options.quality = 90; } } diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index 823a837b7..a6ae8e271 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -1361,7 +1361,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti imageSize: 'large', enableSideMediaInfo: false, highlight: false, - action: layoutManager.tv ? 'resume' : 'none', + action: layoutManager.tv ? 'link' : 'none', imagePlayButton: true, includeParentInfoInTitle: false }); From dbb02275afdede6fb45a6c28db0b561082f98397 Mon Sep 17 00:00:00 2001 From: Julien Machiels Date: Thu, 16 Jul 2020 19:00:27 +0200 Subject: [PATCH 0259/1168] Update src/controllers/itemDetails/index.js Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com> --- src/controllers/itemDetails/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index a6ae8e271..cf5549f70 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -1361,7 +1361,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti imageSize: 'large', enableSideMediaInfo: false, highlight: false, - action: layoutManager.tv ? 'link' : 'none', + action: !layoutManager.desktop ? 'link' : 'none', imagePlayButton: true, includeParentInfoInTitle: false }); From 157bc178f59446f15e1f7663bf89cfb2abf2d293 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Thu, 16 Jul 2020 20:00:33 +0200 Subject: [PATCH 0260/1168] Fix selector error in remotecontrol --- src/components/remotecontrol/remotecontrol.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index b283daaba..b73584246 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -494,7 +494,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL itemsContainer.innerHTML = html; if (focusedItemPlaylistId !== null) { focusedItemPlaylistId = focusedItemPlaylistId.getAttribute('data-playlistitemid'); - const newFocusedItem = itemsContainer.querySelector(`button[data-playlistitemid=${focusedItemPlaylistId}]`); + const newFocusedItem = itemsContainer.querySelector(`button[data-playlistitemid="${focusedItemPlaylistId}"]`); if (newFocusedItem !== null) { newFocusedItem.focus(); } @@ -503,7 +503,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var playlistItemId = playbackManager.getCurrentPlaylistItemId(player); if (playlistItemId) { - var img = itemsContainer.querySelector('.listItem[data-playlistItemId="' + playlistItemId + '"] .listItemImage'); + var img = itemsContainer.querySelector(`.listItem[data-playlistItemId="${playlistItemId}"] .listItemImage`); if (img) { img.classList.remove('lazy'); From 5519d11d4d6e63c352c79db2fe933678c50cb867 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Thu, 16 Jul 2020 19:43:19 +0300 Subject: [PATCH 0261/1168] Change volume slider event --- src/components/nowPlayingBar/nowPlayingBar.js | 10 +++------- src/components/remotecontrol/remotecontrol.js | 9 +++------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 215f6336a..95c4372f2 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -204,15 +204,11 @@ define(['require', 'datetime', 'itemHelper', 'events', 'browser', 'imageLoader', volumeSliderContainer.classList.toggle('hide', appHost.supports('physicalvolumecontrol')); - function setVolume() { + volumeSlider.addEventListener('input', (e) => { if (currentPlayer) { - currentPlayer.setVolume(this.value); + currentPlayer.setVolume(e.target.value); } - } - - volumeSlider.addEventListener('change', setVolume); - volumeSlider.addEventListener('mousemove', setVolume); - volumeSlider.addEventListener('touchmove', setVolume); + }); positionSlider.addEventListener('change', function () { diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index b283daaba..7914ecb5b 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -788,13 +788,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL return datetime.getDisplayRunningTime(ticks); }; - function setVolume() { - playbackManager.setVolume(this.value, currentPlayer); - } + context.querySelector('.nowPlayingVolumeSlider').addEventListener('input', (e) => { + playbackManager.setVolume(e.target.value, currentPlayer); + }); - context.querySelector('.nowPlayingVolumeSlider').addEventListener('change', setVolume); - context.querySelector('.nowPlayingVolumeSlider').addEventListener('mousemove', setVolume); - context.querySelector('.nowPlayingVolumeSlider').addEventListener('touchmove', setVolume); context.querySelector('.buttonMute').addEventListener('click', function () { playbackManager.toggleMute(currentPlayer); }); From 73f88b840c50ea3eebf30971ad3d3329fedd3d09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2020 00:54:14 +0000 Subject: [PATCH 0262/1168] Bump lodash from 4.17.15 to 4.17.19 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19) Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3bc14cfe0..a8ae763df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6793,9 +6793,9 @@ lodash.uniq@^4.5.0: integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= lodash@^4.0.0, lodash@^4.1.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@~4.17.12: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + version "4.17.19" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" + integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== log-symbols@^1.0.2: version "1.0.2" From c3349dfe2438d0becc9267bb8d0b96a847bf76a4 Mon Sep 17 00:00:00 2001 From: Daisuke Inoue Date: Fri, 17 Jul 2020 06:46:32 +0000 Subject: [PATCH 0263/1168] Translated using Weblate (Japanese) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ja/ --- src/strings/ja.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/ja.json b/src/strings/ja.json index a3cf6380d..6cc05c63b 100644 --- a/src/strings/ja.json +++ b/src/strings/ja.json @@ -22,7 +22,7 @@ "AllowMediaConversion": "メディアの変換を許可する", "AllowMediaConversionHelp": "メディア変換機能へのアクセスを許可もしくは、拒否します。", "AllowOnTheFlySubtitleExtraction": "字幕の抽出の許可/拒否", - "AllowOnTheFlySubtitleExtractionHelp": "埋め込まれた字幕は、ビデオのトランスコーディングを防ぐために、ビデオから抽出してプレーンテキストでクライアントに配信できます。 システムによっては、これに時間がかかり、抽出中にビデオの再生が止まることがあります。 これを無効にし、埋め込み字幕がクライアントデバイスでネイティブにサポートされていない場合、ビデオのトランスコーディングが強制されます。", + "AllowOnTheFlySubtitleExtractionHelp": "埋め込まれた字幕は、ビデオのトランスコードを防ぐために、ビデオから抽出してプレーンテキストでクライアントに配信できます。 システムによっては、これに時間がかかり、抽出中にビデオの再生が止まることがあります。 これを無効にし、埋め込み字幕がクライアントデバイスでネイティブにサポートされていない場合、ビデオのトランスコードが強制されます。", "AllowRemoteAccess": "Jellyfin Serverへのリモート接続の許可。", "AllowRemoteAccessHelp": "チェックが入っていない場合すべてのリモート接続をブロックします。", "AllowedRemoteAddressesHelp": "リモート接続を許可するネットワークのIPアドレスまたはIPアドレス/マスク長 空白のままにすると、すべてのリモートアドレスが許可されます。", From 1f3bc874099383aade35d99fe8d535e6b0f33bb6 Mon Sep 17 00:00:00 2001 From: Daisuke Inoue Date: Fri, 17 Jul 2020 06:48:16 +0000 Subject: [PATCH 0264/1168] Translated using Weblate (Japanese) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ja/ --- src/strings/ja.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/strings/ja.json b/src/strings/ja.json index 6cc05c63b..e94a1388a 100644 --- a/src/strings/ja.json +++ b/src/strings/ja.json @@ -47,7 +47,7 @@ "BirthLocation": "生まれた場所", "BirthPlaceValue": "生まれた場所: {0}", "Blacklist": "ブラックリスト", - "BookLibraryHelp": "オーディオブックとテキストブックに対応しています。{0}Jellyfinブック命名ガイド{1}.", + "BookLibraryHelp": "オーディオブックとテキストブックに対応しています。{0} の資料、ブック命名ガイド {1} を参照。", "Books": "ブック", "Box": "ボックス", "BoxRear": "ボックス(後)", @@ -1176,5 +1176,10 @@ "LabelEnableBlastAliveMessagesHelp": "ネットワーク上の他の UPnP デバイスによってサーバーが確実に検出されない場合、この設定を有効にします。", "LabelEnableAutomaticPortMapHelp": "ルーター上のパブリックポートを、UPnP 経由でサーバーのローカルポートに自動的に転送します。これはルータのモデルやネットワーク構成によっては動作しない場合があります。変更はサーバーを再起動するまで適用されません。", "LabelEmbedAlbumArtDidlHelp": "一部のデバイスでは、アルバムアートを取得するためにこの方法が好まれています。その他のデバイスでは、このオプションを有効にしても再生できない場合があります。", - "LabelDownMixAudioScaleHelp": "ダウンミックス時にオーディオの音量を増幅します。値が 1 の場合、元の音量を維持します。" + "LabelDownMixAudioScaleHelp": "ダウンミックス時にオーディオの音量を増幅します。値が 1 の場合、元の音量を維持します。", + "LabelEnableHttps": "HTTPS を有効にする", + "LabelEnableDlnaPlayToHelp": "ネットワーク内のデバイスを検出し、それらをリモートコントロールできるようにします。", + "LabelEnableDlnaPlayTo": "DLNA 再生を有効にする", + "LabelEnableDlnaDebugLoggingHelp": "巨大なログファイルを作成します。トラブルシューティングでの必要な際にだけ使用してください。", + "LabelEnableDlnaClientDiscoveryIntervalHelp": "Jellyfin が実行する SSDP 検索の間隔を決めます(秒単位)。" } From ef09c661c34b85ab6d93a1265b4a452d6a4333e1 Mon Sep 17 00:00:00 2001 From: Daisuke Inoue Date: Fri, 17 Jul 2020 06:55:47 +0000 Subject: [PATCH 0265/1168] Translated using Weblate (Japanese) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ja/ --- src/strings/ja.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/strings/ja.json b/src/strings/ja.json index e94a1388a..60c814843 100644 --- a/src/strings/ja.json +++ b/src/strings/ja.json @@ -1181,5 +1181,13 @@ "LabelEnableDlnaPlayToHelp": "ネットワーク内のデバイスを検出し、それらをリモートコントロールできるようにします。", "LabelEnableDlnaPlayTo": "DLNA 再生を有効にする", "LabelEnableDlnaDebugLoggingHelp": "巨大なログファイルを作成します。トラブルシューティングでの必要な際にだけ使用してください。", - "LabelEnableDlnaClientDiscoveryIntervalHelp": "Jellyfin が実行する SSDP 検索の間隔を決めます(秒単位)。" + "LabelEnableDlnaClientDiscoveryIntervalHelp": "Jellyfin が実行する SSDP 検索の間隔を決めます(秒単位)。", + "LabelGroupMoviesIntoCollectionsHelp": "ムービーリストを表示する際、コレクションに属するムービーを1つのグループとして表示します。", + "LabelServerNameHelp": "この名前はサーバーを識別するために使用します。デフォルトではサーバーのコンピュータ名です。", + "LabelExtractChaptersDuringLibraryScanHelp": "ライブラリー スキャン中に動画を取り込んだときに、チャプター画像を生成します。もしくは、スケジュールタスクの中でチャプター画像を抽出することで、通常のライブラリー スキャンをより速く完了させることができます。", + "LabelExtractChaptersDuringLibraryScan": "ライブラリーをスキャンしながら、チャプター画像を生成する", + "LabelBaseUrlHelp": "サーバーの URL にカスタム サブディレクトリを加えます。例 : http://example.com/<baseurl>", + "LabelEnableSingleImageInDidlLimitHelp": "Didl 内に複数の画像が埋め込まれている場合、一部のデバイスでは正しくレンダリングされません。", + "LabelEnableRealtimeMonitorHelp": "ファイルへの変更は、サポートされているファイルシステム上ですぐに処理されます。", + "LabelEnableHttpsHelp": "構成された HTTPS ポートからサーバーがリッスンするのを有効にします。この機能を有効にするには、適切な証明書を設定する必要があります。" } From 8f88db5c2a3cf6b7c37122465c529fadbd6f6dfd Mon Sep 17 00:00:00 2001 From: DeathGambit Date: Fri, 17 Jul 2020 09:31:18 +0000 Subject: [PATCH 0266/1168] Translated using Weblate (Hindi) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/hi/ --- src/strings/hi-in.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/strings/hi-in.json b/src/strings/hi-in.json index 698269c3b..a8cdd1c99 100644 --- a/src/strings/hi-in.json +++ b/src/strings/hi-in.json @@ -113,5 +113,7 @@ "AllowOnTheFlySubtitleExtraction": "मक्खी पर उपशीर्षक निष्कर्षण की अनुमति दें", "Album": "एल्बम", "AddItemToCollectionHelp": "उनके लिए खोज करके संग्रह में आइटम जोड़ें और उन्हें संग्रह में जोड़ने के लिए उनके राइट-क्लिक या टैप मेनू का उपयोग करें।", - "ButtonSyncPlay": "SyncPlay" + "ButtonSyncPlay": "SyncPlay", + "BrowsePluginCatalogMessage": "उपलब्ध प्लगिन्स देखने के लिए हमारे कैटलॉग को ब्राउज़ करें.", + "Browse": "ब्राउज़" } From f296eb34750a38d0f185c49fdbe4efe425ef284e Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 17 Jul 2020 11:30:39 +0100 Subject: [PATCH 0267/1168] Migration of taskbutton and touchHelper to ES6 modules --- package.json | 14 +- src/components/maintabsmanager.js | 2 +- src/controllers/dashboard/mediaLibrary.js | 4 +- src/controllers/livetvstatus.js | 4 +- src/controllers/playback/videoosd.js | 2 +- src/scripts/taskbutton.js | 227 +++++++++++----------- src/scripts/touchHelper.js | 23 ++- 7 files changed, 140 insertions(+), 136 deletions(-) diff --git a/package.json b/package.json index b911778bc..ecf54d2ca 100644 --- a/package.json +++ b/package.json @@ -154,6 +154,9 @@ "src/plugins/bookPlayer/plugin.js", "src/plugins/bookPlayer/tableOfContents.js", "src/plugins/photoPlayer/plugin.js", + "src/scripts/settings/appSettings.js", + "src/scripts/settings/userSettings.js", + "src/scripts/settings/webSettings.js", "src/scripts/deleteHelper.js", "src/scripts/dfnshelper.js", "src/scripts/dom.js", @@ -161,14 +164,13 @@ "src/scripts/filesystem.js", "src/scripts/imagehelper.js", "src/scripts/inputManager.js", + "src/scripts/keyboardNavigation.js", + "src/scripts/taskbutton.js", + "src/scripts/touchHelper.js", + "src/scripts/themeLoader.js", "src/plugins/backdropScreensaver/plugin.js", "src/components/filterdialog/filterdialog.js", - "src/components/fetchhelper.js", - "src/scripts/keyboardNavigation.js", - "src/scripts/settings/appSettings.js", - "src/scripts/settings/userSettings.js", - "src/scripts/themeLoader.js", - "src/scripts/settings/webSettings.js" + "src/components/fetchhelper.js" ], "plugins": [ "@babel/plugin-transform-modules-amd", diff --git a/src/components/maintabsmanager.js b/src/components/maintabsmanager.js index e1c543436..e50d75bc0 100644 --- a/src/components/maintabsmanager.js +++ b/src/components/maintabsmanager.js @@ -85,7 +85,7 @@ define(['dom', 'browser', 'events', 'emby-tabs', 'emby-button'], function (dom, require(['touchHelper'], function (TouchHelper) { - var touchHelper = new TouchHelper(view.parentNode.parentNode); + var touchHelper = new TouchHelper.default(view.parentNode.parentNode); events.on(touchHelper, 'swipeleft', onSwipeLeft); events.on(touchHelper, 'swiperight', onSwipeRight); diff --git a/src/controllers/dashboard/mediaLibrary.js b/src/controllers/dashboard/mediaLibrary.js index d9b288c62..8e0020f62 100644 --- a/src/controllers/dashboard/mediaLibrary.js +++ b/src/controllers/dashboard/mediaLibrary.js @@ -372,7 +372,7 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl pageIdOn('pageshow', 'mediaLibraryPage', function () { libraryMenu.setTabs('librarysetup', 0, getTabs); var page = this; - taskButton({ + taskButton.default({ mode: 'on', progressElem: page.querySelector('.refreshProgress'), taskKey: 'RefreshLibrary', @@ -381,7 +381,7 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl }); pageIdOn('pagebeforehide', 'mediaLibraryPage', function () { var page = this; - taskButton({ + taskButton.default({ mode: 'off', progressElem: page.querySelector('.refreshProgress'), taskKey: 'RefreshLibrary', diff --git a/src/controllers/livetvstatus.js b/src/controllers/livetvstatus.js index c6daf53a4..efafd5087 100644 --- a/src/controllers/livetvstatus.js +++ b/src/controllers/livetvstatus.js @@ -303,7 +303,7 @@ define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layo }).on('pageshow', '#liveTvStatusPage', function () { var page = this; reload(page); - taskButton({ + taskButton.default({ mode: 'on', progressElem: page.querySelector('.refreshGuideProgress'), taskKey: 'RefreshGuide', @@ -311,7 +311,7 @@ define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layo }); }).on('pagehide', '#liveTvStatusPage', function () { var page = this; - taskButton({ + taskButton.default({ mode: 'off', progressElem: page.querySelector('.refreshGuideProgress'), taskKey: 'RefreshGuide', diff --git a/src/controllers/playback/videoosd.js b/src/controllers/playback/videoosd.js index d6caf24e8..0907a700b 100644 --- a/src/controllers/playback/videoosd.js +++ b/src/controllers/playback/videoosd.js @@ -1533,7 +1533,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med if (browser.touch) { (function () { require(['touchHelper'], function (TouchHelper) { - self.touchHelper = new TouchHelper(view, { + self.touchHelper = new TouchHelper.default(view, { swipeYThreshold: 30, triggerOnMove: true, preventDefaultOnMove: true, diff --git a/src/scripts/taskbutton.js b/src/scripts/taskbutton.js index 8facaf890..d2c9d6c91 100644 --- a/src/scripts/taskbutton.js +++ b/src/scripts/taskbutton.js @@ -1,119 +1,122 @@ -define(['events', 'userSettings', 'serverNotifications', 'connectionManager', 'globalize', 'emby-button'], function (events, userSettings, serverNotifications, connectionManager, globalize) { - 'use strict'; +import events from 'events'; +import * as userSettings from 'userSettings'; +import serverNotifications from 'serverNotifications'; +import connectionManager from 'connectionManager'; +import globalize from 'globalize'; +import 'emby-button'; - return function (options) { - function pollTasks() { - connectionManager.getApiClient(serverId).getScheduledTasks({ - IsEnabled: true - }).then(updateTasks); - } +export default function (options) { + function pollTasks() { + connectionManager.getApiClient(serverId).getScheduledTasks({ + IsEnabled: true + }).then(updateTasks); + } - function updateTasks(tasks) { - var task = tasks.filter(function (t) { - return t.Key == options.taskKey; - })[0]; - - if (options.panel) { - if (task) { - options.panel.classList.remove('hide'); - } else { - options.panel.classList.add('hide'); - } - } - - if (!task) { - return; - } - - if (task.State == 'Idle') { - button.removeAttribute('disabled'); - } else { - button.setAttribute('disabled', 'disabled'); - } - - button.setAttribute('data-taskid', task.Id); - var progress = (task.CurrentProgressPercentage || 0).toFixed(1); - - if (options.progressElem) { - options.progressElem.value = progress; - - if (task.State == 'Running') { - options.progressElem.classList.remove('hide'); - } else { - options.progressElem.classList.add('hide'); - } - } - - if (options.lastResultElem) { - var lastResult = task.LastExecutionResult ? task.LastExecutionResult.Status : ''; - - if (lastResult == 'Failed') { - options.lastResultElem.html('(' + globalize.translate('LabelFailed') + ')'); - } else if (lastResult == 'Cancelled') { - options.lastResultElem.html('(' + globalize.translate('LabelCancelled') + ')'); - } else if (lastResult == 'Aborted') { - options.lastResultElem.html('' + globalize.translate('LabelAbortedByServerShutdown') + ''); - } else { - options.lastResultElem.html(lastResult); - } - } - } - - function onScheduledTaskMessageConfirmed(id) { - connectionManager.getApiClient(serverId).startScheduledTask(id).then(pollTasks); - } - - function onButtonClick() { - onScheduledTaskMessageConfirmed(this.getAttribute('data-taskid')); - } - - function onScheduledTasksUpdate(e, apiClient, info) { - if (apiClient.serverId() === serverId) { - updateTasks(info); - } - } - - var pollInterval; - var button = options.button; - var serverId = ApiClient.serverId(); - - function onPollIntervalFired() { - if (!connectionManager.getApiClient(serverId).isMessageChannelOpen()) { - pollTasks(); - } - } - - function startInterval() { - var apiClient = connectionManager.getApiClient(serverId); - - if (pollInterval) { - clearInterval(pollInterval); - } - apiClient.sendMessage('ScheduledTasksInfoStart', '1000,1000'); - pollInterval = setInterval(onPollIntervalFired, 5000); - } - - function stopInterval() { - connectionManager.getApiClient(serverId).sendMessage('ScheduledTasksInfoStop'); - - if (pollInterval) { - clearInterval(pollInterval); - } - } + function updateTasks(tasks) { + var task = tasks.filter(function (t) { + return t.Key == options.taskKey; + })[0]; if (options.panel) { - options.panel.classList.add('hide'); + if (task) { + options.panel.classList.remove('hide'); + } else { + options.panel.classList.add('hide'); + } } - if (options.mode == 'off') { - button.removeEventListener('click', onButtonClick); - events.off(serverNotifications, 'ScheduledTasksInfo', onScheduledTasksUpdate); - stopInterval(); - } else { - button.addEventListener('click', onButtonClick); - pollTasks(); - startInterval(); - events.on(serverNotifications, 'ScheduledTasksInfo', onScheduledTasksUpdate); + if (!task) { + return; } - }; -}); + + if (task.State == 'Idle') { + button.removeAttribute('disabled'); + } else { + button.setAttribute('disabled', 'disabled'); + } + + button.setAttribute('data-taskid', task.Id); + var progress = (task.CurrentProgressPercentage || 0).toFixed(1); + + if (options.progressElem) { + options.progressElem.value = progress; + + if (task.State == 'Running') { + options.progressElem.classList.remove('hide'); + } else { + options.progressElem.classList.add('hide'); + } + } + + if (options.lastResultElem) { + var lastResult = task.LastExecutionResult ? task.LastExecutionResult.Status : ''; + + if (lastResult == 'Failed') { + options.lastResultElem.html('(' + globalize.translate('LabelFailed') + ')'); + } else if (lastResult == 'Cancelled') { + options.lastResultElem.html('(' + globalize.translate('LabelCancelled') + ')'); + } else if (lastResult == 'Aborted') { + options.lastResultElem.html('' + globalize.translate('LabelAbortedByServerShutdown') + ''); + } else { + options.lastResultElem.html(lastResult); + } + } + } + + function onScheduledTaskMessageConfirmed(id) { + connectionManager.getApiClient(serverId).startScheduledTask(id).then(pollTasks); + } + + function onButtonClick() { + onScheduledTaskMessageConfirmed(this.getAttribute('data-taskid')); + } + + function onScheduledTasksUpdate(e, apiClient, info) { + if (apiClient.serverId() === serverId) { + updateTasks(info); + } + } + + var pollInterval; + var button = options.button; + var serverId = ApiClient.serverId(); + + function onPollIntervalFired() { + if (!connectionManager.getApiClient(serverId).isMessageChannelOpen()) { + pollTasks(); + } + } + + function startInterval() { + var apiClient = connectionManager.getApiClient(serverId); + + if (pollInterval) { + clearInterval(pollInterval); + } + apiClient.sendMessage('ScheduledTasksInfoStart', '1000,1000'); + pollInterval = setInterval(onPollIntervalFired, 5000); + } + + function stopInterval() { + connectionManager.getApiClient(serverId).sendMessage('ScheduledTasksInfoStop'); + + if (pollInterval) { + clearInterval(pollInterval); + } + } + + if (options.panel) { + options.panel.classList.add('hide'); + } + + if (options.mode == 'off') { + button.removeEventListener('click', onButtonClick); + events.off(serverNotifications, 'ScheduledTasksInfo', onScheduledTasksUpdate); + stopInterval(); + } else { + button.addEventListener('click', onButtonClick); + pollTasks(); + startInterval(); + events.on(serverNotifications, 'ScheduledTasksInfo', onScheduledTasksUpdate); + } +} diff --git a/src/scripts/touchHelper.js b/src/scripts/touchHelper.js index 97455fc96..c3e3b01a1 100644 --- a/src/scripts/touchHelper.js +++ b/src/scripts/touchHelper.js @@ -1,12 +1,12 @@ -define(['dom', 'events'], function (dom, events) { - 'use strict'; +import dom from 'dom'; +import events from 'events'; - function getTouches(e) { +function getTouches(e) { + return e.changedTouches || e.targetTouches || e.touches; +} - return e.changedTouches || e.targetTouches || e.touches; - } - - function TouchHelper(elem, options) { +class TouchHelper { + constructor(elem, options) { options = options || {}; var touchTarget; @@ -138,8 +138,7 @@ define(['dom', 'events'], function (dom, events) { passive: true }); } - - TouchHelper.prototype.destroy = function () { + destroy() { var elem = this.elem; @@ -165,7 +164,7 @@ define(['dom', 'events'], function (dom, events) { this.touchEnd = null; this.elem = null; - }; + } +} - return TouchHelper; -}); +export default TouchHelper; From 0473e549abca7ce5aa449ff9f240f3e3b9cf7fbb Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 17 Jul 2020 11:30:56 +0100 Subject: [PATCH 0268/1168] update variable declerations for appSettings and userSettings --- src/scripts/settings/appSettings.js | 8 ++++---- src/scripts/settings/userSettings.js | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/scripts/settings/appSettings.js b/src/scripts/settings/appSettings.js index 6f0975e98..ffd63b956 100644 --- a/src/scripts/settings/appSettings.js +++ b/src/scripts/settings/appSettings.js @@ -28,7 +28,7 @@ import events from 'events'; } export function enableAutomaticBitrateDetection(isInNetwork, mediaType, val) { - var key = 'enableautobitratebitrate-' + mediaType + '-' + isInNetwork; + const key = 'enableautobitratebitrate-' + mediaType + '-' + isInNetwork; if (val !== undefined) { if (isInNetwork && mediaType === 'Audio') { val = true; @@ -45,7 +45,7 @@ import events from 'events'; } export function maxStreamingBitrate(isInNetwork, mediaType, val) { - var key = 'maxbitrate-' + mediaType + '-' + isInNetwork; + const key = 'maxbitrate-' + mediaType + '-' + isInNetwork; if (val !== undefined) { if (isInNetwork && mediaType === 'Audio') { // nothing to do, this is always a max value @@ -67,7 +67,7 @@ import events from 'events'; this.set('maxStaticMusicBitrate', val); } - var defaultValue = 320000; + const defaultValue = 320000; return parseInt(this.get('maxStaticMusicBitrate') || defaultValue.toString()) || defaultValue; } @@ -118,7 +118,7 @@ import events from 'events'; } export function set(name, value, userId) { - var currentValue = this.get(name, userId); + const currentValue = this.get(name, userId); appStorage.setItem(getKey(name, userId), value); if (currentValue !== value) { diff --git a/src/scripts/settings/userSettings.js b/src/scripts/settings/userSettings.js index 1b5283fa4..bd6050b5f 100644 --- a/src/scripts/settings/userSettings.js +++ b/src/scripts/settings/userSettings.js @@ -2,7 +2,7 @@ import appSettings from 'appSettings'; import events from 'events'; function onSaveTimeout() { - var self = this; + const self = this; self.saveTimeout = null; self.currentApiClient.updateDisplayPreferences('usersettings', self.displayPrefs, self.currentUserId, 'emby'); } @@ -37,7 +37,7 @@ export class UserSettings { return Promise.resolve(); } - var self = this; + const self = this; return apiClient.getDisplayPreferences('usersettings', userId, 'emby').then(function (result) { result.CustomPrefs = result.CustomPrefs || {}; @@ -63,9 +63,9 @@ export class UserSettings { * @param {boolean} enableOnServer - Flag to save preferences on server. */ set(name, value, enableOnServer) { - var userId = this.currentUserId; - var currentValue = this.get(name, enableOnServer); - var result = appSettings.set(name, value, userId); + const userId = this.currentUserId; + const currentValue = this.get(name, enableOnServer); + const result = appSettings.set(name, value, userId); if (enableOnServer !== false && this.displayPrefs) { this.displayPrefs.CustomPrefs[name] = value == null ? value : value.toString(); @@ -86,7 +86,7 @@ export class UserSettings { * @return {string} Value of setting. */ get(name, enableOnServer) { - var userId = this.currentUserId; + const userId = this.currentUserId; if (enableOnServer !== false && this.displayPrefs) { return this.displayPrefs.CustomPrefs[name]; } @@ -100,7 +100,7 @@ export class UserSettings { * @return {Object|Promise} Configuration or Promise. */ serverConfig(config) { - var apiClient = this.currentApiClient; + const apiClient = this.currentApiClient; if (config) { return apiClient.updateUserConfiguration(this.currentUserId, config); } @@ -349,7 +349,7 @@ export class UserSettings { return this.set('libraryPageSize', parseInt(val, 10), false); } - var libraryPageSize = parseInt(this.get('libraryPageSize', false), 10); + const libraryPageSize = parseInt(this.get('libraryPageSize', false), 10); if (libraryPageSize === 0) { // Explicitly return 0 to avoid returning 100 because 0 is falsy. return 0; @@ -378,7 +378,7 @@ export class UserSettings { * @return {Object} Query. */ loadQuerySettings(key, query) { - var values = this.get(key); + let values = this.get(key); if (values) { values = JSON.parse(values); return Object.assign(query, values); @@ -393,7 +393,7 @@ export class UserSettings { * @param {Object} query - Query. */ saveQuerySettings(key, query) { - var values = {}; + const values = {}; if (query.SortBy) { values.SortBy = query.SortBy; } From 46638fb9a9f94b70ad6dea378a22fededf26b5de Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 17 Jul 2020 11:32:23 +0100 Subject: [PATCH 0269/1168] update Variable declerations for taskbutton and touchHelper --- src/scripts/taskbutton.js | 14 +++++----- src/scripts/touchHelper.js | 52 +++++++++++++++++++------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/scripts/taskbutton.js b/src/scripts/taskbutton.js index d2c9d6c91..85062fdaa 100644 --- a/src/scripts/taskbutton.js +++ b/src/scripts/taskbutton.js @@ -13,7 +13,7 @@ export default function (options) { } function updateTasks(tasks) { - var task = tasks.filter(function (t) { + const task = tasks.filter(function (t) { return t.Key == options.taskKey; })[0]; @@ -36,7 +36,7 @@ export default function (options) { } button.setAttribute('data-taskid', task.Id); - var progress = (task.CurrentProgressPercentage || 0).toFixed(1); + const progress = (task.CurrentProgressPercentage || 0).toFixed(1); if (options.progressElem) { options.progressElem.value = progress; @@ -49,7 +49,7 @@ export default function (options) { } if (options.lastResultElem) { - var lastResult = task.LastExecutionResult ? task.LastExecutionResult.Status : ''; + const lastResult = task.LastExecutionResult ? task.LastExecutionResult.Status : ''; if (lastResult == 'Failed') { options.lastResultElem.html('(' + globalize.translate('LabelFailed') + ')'); @@ -77,9 +77,9 @@ export default function (options) { } } - var pollInterval; - var button = options.button; - var serverId = ApiClient.serverId(); + let pollInterval; + const button = options.button; + const serverId = ApiClient.serverId(); function onPollIntervalFired() { if (!connectionManager.getApiClient(serverId).isMessageChannelOpen()) { @@ -88,7 +88,7 @@ export default function (options) { } function startInterval() { - var apiClient = connectionManager.getApiClient(serverId); + const apiClient = connectionManager.getApiClient(serverId); if (pollInterval) { clearInterval(pollInterval); diff --git a/src/scripts/touchHelper.js b/src/scripts/touchHelper.js index c3e3b01a1..c12cf7951 100644 --- a/src/scripts/touchHelper.js +++ b/src/scripts/touchHelper.js @@ -9,23 +9,23 @@ class TouchHelper { constructor(elem, options) { options = options || {}; - var touchTarget; - var touchStartX; - var touchStartY; - var lastDeltaX; - var lastDeltaY; - var thresholdYMet; - var self = this; + let touchTarget; + let touchStartX; + let touchStartY; + let lastDeltaX; + let lastDeltaY; + let thresholdYMet; + const self = this; - var swipeXThreshold = options.swipeXThreshold || 50; - var swipeYThreshold = options.swipeYThreshold || 50; - var swipeXMaxY = 30; + const swipeXThreshold = options.swipeXThreshold || 50; + const swipeYThreshold = options.swipeYThreshold || 50; + const swipeXMaxY = 30; - var excludeTagNames = options.ignoreTagNames || []; + const excludeTagNames = options.ignoreTagNames || []; - var touchStart = function (e) { + const touchStart = function (e) { - var touch = getTouches(e)[0]; + const touch = getTouches(e)[0]; touchTarget = null; touchStartX = 0; touchStartY = 0; @@ -35,7 +35,7 @@ class TouchHelper { if (touch) { - var currentTouchTarget = touch.target; + const currentTouchTarget = touch.target; if (dom.parentWithTag(currentTouchTarget, excludeTagNames)) { return; @@ -47,18 +47,18 @@ class TouchHelper { } }; - var touchEnd = function (e) { + const touchEnd = function (e) { - var isTouchMove = e.type === 'touchmove'; + const isTouchMove = e.type === 'touchmove'; if (touchTarget) { - var touch = getTouches(e)[0]; + const touch = getTouches(e)[0]; - var deltaX; - var deltaY; + let deltaX; + let deltaY; - var clientX; - var clientY; + let clientX; + let clientY; if (touch) { clientX = touch.clientX || 0; @@ -70,8 +70,8 @@ class TouchHelper { deltaY = 0; } - var currentDeltaX = lastDeltaX == null ? deltaX : (deltaX - lastDeltaX); - var currentDeltaY = lastDeltaY == null ? deltaY : (deltaY - lastDeltaY); + const currentDeltaX = lastDeltaX == null ? deltaX : (deltaX - lastDeltaX); + const currentDeltaY = lastDeltaY == null ? deltaY : (deltaY - lastDeltaY); lastDeltaX = deltaX; lastDeltaY = deltaY; @@ -140,11 +140,11 @@ class TouchHelper { } destroy() { - var elem = this.elem; + const elem = this.elem; if (elem) { - var touchStart = this.touchStart; - var touchEnd = this.touchEnd; + const touchStart = this.touchStart; + const touchEnd = this.touchEnd; dom.removeEventListener(elem, 'touchstart', touchStart, { passive: true From cd2cab99ef247be5fc3ff48835c71b164ea41184 Mon Sep 17 00:00:00 2001 From: Moritz Date: Fri, 17 Jul 2020 11:21:48 +0000 Subject: [PATCH 0270/1168] Translated using Weblate (German) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/ --- src/strings/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/de.json b/src/strings/de.json index c9b126a08..7c3edac6b 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -1396,7 +1396,7 @@ "Thumb": "Miniaturansicht", "TitleSupport": "Hilfe", "Whitelist": "Erlaubt", - "AuthProviderHelp": "Wähle einen Authentifizierungsanbieter aus, der zur Authentifizierung des Passworts dieses Benutzers verwendet werden soll.", + "AuthProviderHelp": "Auswahl eines Authentifizierungsanbieters, der zur Authentifizierung des Passworts dieses Benutzes verwendet werden soll.", "Features": "Funktionen", "HeaderFavoriteBooks": "Lieblingsbücher", "HeaderFavoriteMovies": "Lieblingsfilme", From 09d072a4ceb7f02d4ad22cba4b614d9a8c1e827f Mon Sep 17 00:00:00 2001 From: David Date: Fri, 17 Jul 2020 11:24:59 +0000 Subject: [PATCH 0271/1168] Translated using Weblate (German) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/ --- src/strings/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/de.json b/src/strings/de.json index 7c3edac6b..d5864a95b 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -10,7 +10,7 @@ "AddToPlaylist": "Zur Wiedergabeliste hinzufügen", "AddUser": "Benutzer anlegen", "AddedOnValue": "{0} hinzugefügt", - "AdditionalNotificationServices": "Durchsuche den Pluginkatalog, um weitere Benachrichtigungsdienste zu installieren.", + "AdditionalNotificationServices": "Schau im Erweiterungskatalog, um weitere Benachrichtigungsdienste zu installieren.", "AirDate": "Erstausstrahlung", "Aired": "Ausgestrahlt", "Albums": "Alben", From 026d94d251da38d29ae4888cbaf26d288bfae855 Mon Sep 17 00:00:00 2001 From: David Date: Fri, 17 Jul 2020 11:25:21 +0000 Subject: [PATCH 0272/1168] Translated using Weblate (German) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/ --- src/strings/de.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/strings/de.json b/src/strings/de.json index d5864a95b..b26b3ec80 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -10,7 +10,7 @@ "AddToPlaylist": "Zur Wiedergabeliste hinzufügen", "AddUser": "Benutzer anlegen", "AddedOnValue": "{0} hinzugefügt", - "AdditionalNotificationServices": "Schau im Erweiterungskatalog, um weitere Benachrichtigungsdienste zu installieren.", + "AdditionalNotificationServices": "Durchsuchen sie den Pluginkatalog um weitere Benachrichtigungsdienste zu installieren.", "AirDate": "Erstausstrahlung", "Aired": "Ausgestrahlt", "Albums": "Alben", @@ -446,7 +446,7 @@ "HeaderTunerDevices": "Tuner", "HeaderTuners": "Tuner", "HeaderTypeText": "Texteingabe", - "HeaderUpcomingOnTV": "Bald im TV", + "HeaderUpcomingOnTV": "Demnächst im Fernsehen", "HeaderUploadImage": "Bild hochladen", "HeaderUser": "Benutzer", "HeaderUsers": "Benutzer", @@ -461,7 +461,7 @@ "Help": "Hilfe", "Hide": "Verstecke", "HideWatchedContentFromLatestMedia": "Verberge gesehene Inhalte von neuesten Medien", - "HttpsRequiresCert": "Um sichere Verbindungen zu ermöglichen, musst du ein vertrauenswürdiges SSL-Zertifikat, wie beispielsweise eines von Let's Encrypt, bereitstellen. Stelle bitte entweder ein Zertifikat zur Verfügung oder deaktiviere sichere Verbindungen.", + "HttpsRequiresCert": "Um https für externe Verbindungen zu erzwingen, benötigst du ein vertrauenswürdiges SSL-Zertifikat, z.B. von Let's Encrypt. Bitte stelle entweder ein Zertifikat bereit, oder deaktiviere sichere Verbindungen.", "Identify": "Identifizieren", "Images": "Bilder", "ImportFavoriteChannelsHelp": "Wenn aktiviert, werden nur auf dem Tuner favorisierte Kanäle importiert.", @@ -509,7 +509,7 @@ "LabelBlockContentWithTags": "Blockiere Inhalte mit Tags:", "LabelBurnSubtitles": "Untertitel einbrennen:", "LabelCachePath": "Cache Pfad:", - "LabelCachePathHelp": "Legen Sie ein eigenes Verzeichnis für den Server Zwischenspeicher fest (z.B. für Bilder). Lassen Sie dieses Feld leer um die Standardeinstellung zu verwenden.", + "LabelCachePathHelp": "Gib einen benutzerdefinierten Speicherort für Server-Cache-Dateien wie beispielsweise Bilder an. Lasse das Feld leer, um den Server-Standard zu verwenden.", "LabelCancelled": "Abgebrochen", "LabelCertificatePassword": "Zertifikat Passwort:", "LabelCertificatePasswordHelp": "Wenn Dein Zertifikat ein Passwort benötigt, gib es hier ein.", @@ -548,7 +548,7 @@ "LabelDisplayOrder": "Anzeigereihenfolge:", "LabelDisplaySpecialsWithinSeasons": "Zeige Sonderinhalt innerhalb der Staffel in der er ausgestrahlt wurde", "LabelDownMixAudioScale": "Audio Verstärkung bei Downmixing:", - "LabelDownMixAudioScaleHelp": "Erhöhe die Audiolautstärke beim Heruntermischen. Setze auf 1, um die ursprüngliche Lautstärke beizubehalten.", + "LabelDownMixAudioScaleHelp": "Erhöhe die Audiolautstärke beim Zusammenmischen zu Stereo. Setze den Wert auf 1 um die Originallautstärke zu erhalten.", "LabelDownloadLanguages": "Herunterzuladende Sprachen:", "LabelDropImageHere": "Fotos hierher ziehen oder klicken im zu browsen.", "LabelDropShadow": "Schlagschatten:", @@ -562,9 +562,9 @@ "LabelEnableDlnaClientDiscoveryInterval": "Client-Entdeckungs Intervall (Sekunden)", "LabelEnableDlnaClientDiscoveryIntervalHelp": "Ermittelt die Zeit in Sekunden zwischen SSDP Suchanfragen die durch Jellyfin ausgeführt wurden.", "LabelEnableDlnaDebugLogging": "Aktiviere DLNA Debug Logging", - "LabelEnableDlnaDebugLoggingHelp": "Erstellt große Logdateien und sollte nur bei Bedarf zur Fehlersuche verwendet werden.", + "LabelEnableDlnaDebugLoggingHelp": "Erzeugt große Logdateien und sollte nur zur Fehlerbehebung benutzt werden.", "LabelEnableDlnaPlayTo": "Aktiviere DLNA Play To", - "LabelEnableDlnaPlayToHelp": "Geräte in deinem Netzwerk erkennen und deren Fernsteuerung ermöglichen.", + "LabelEnableDlnaPlayToHelp": "Jellyfin kann Geräte in Ihrem Netzwerk erkennen und bietet die Möglichkeit, diese fernzusteuern.", "LabelEnableDlnaServer": "DLNA-Server aktivieren", "LabelEnableDlnaServerHelp": "Erlaubt UPnP Geräten in Ihrem Netzwerk den Zugriff und die Wiedergabe von Inhalten.", "LabelEnableHardwareDecodingFor": "Aktiviere Hardware-Decoding für:", @@ -1396,7 +1396,7 @@ "Thumb": "Miniaturansicht", "TitleSupport": "Hilfe", "Whitelist": "Erlaubt", - "AuthProviderHelp": "Auswahl eines Authentifizierungsanbieters, der zur Authentifizierung des Passworts dieses Benutzes verwendet werden soll.", + "AuthProviderHelp": "Wähle einen Authentifizierungsanbieter, der zur Authentifizierung des Passworts dieses Benutzes verwendet werden soll.", "Features": "Funktionen", "HeaderFavoriteBooks": "Lieblingsbücher", "HeaderFavoriteMovies": "Lieblingsfilme", @@ -1469,7 +1469,7 @@ "OptionRandom": "Zufällig", "TabNetworking": "Netzwerk", "VideoRange": "Videobereich", - "ButtonSplit": "Aufteilen", + "ButtonSplit": "Trennen", "SelectAdminUsername": "Bitte einen Benutzernamen für das Administrator-Konto auswählen.", "HeaderNavigation": "Navigation", "CopyStreamURLError": "Beim Kopieren der URL ist ein Fehler aufgetreten.", From ba118a6974433afeae5d81dff9ee9b264f999003 Mon Sep 17 00:00:00 2001 From: DeathGambit Date: Fri, 17 Jul 2020 09:39:40 +0000 Subject: [PATCH 0273/1168] Translated using Weblate (Hindi) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/hi/ --- src/strings/hi-in.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/strings/hi-in.json b/src/strings/hi-in.json index a8cdd1c99..48b82c601 100644 --- a/src/strings/hi-in.json +++ b/src/strings/hi-in.json @@ -73,10 +73,10 @@ "ButtonAddScheduledTaskTrigger": "ट्रिगर जोड़ें", "ButtonAddMediaLibrary": "मीडिया लाइब्रेरी जोड़ें", "ButtonAddImage": "छवि जोड़ें", - "ButtonAdd": "जोड़ना", + "ButtonAdd": "जोड़ें", "UnsupportedPlayback": "Jellyfin DRM द्वारा संरक्षित सामग्री को डिक्रिप्ट नहीं कर सकता है, लेकिन सभी सामग्री की परवाह किए बिना, संरक्षित शीर्षकों सहित प्रयास किया जाएगा। एन्क्रिप्शन या अन्य असमर्थित सुविधाओं जैसे इंटरेक्टिव शीर्षक के कारण कुछ फाइलें पूरी तरह से काली दिखाई दे सकती हैं।", "BoxRear": "बॉक्स (पीछे)", - "Box": "डिब्बा", + "Box": "बॉक्स", "Books": "पुस्तकें", "BookLibraryHelp": "ऑडियो और पाठ्य पुस्तकें समर्थित हैं। {0} पुस्तक नामकरण गाइड {1} की समीक्षा करें।", "Blacklist": "काला सूची में डालना", @@ -114,6 +114,8 @@ "Album": "एल्बम", "AddItemToCollectionHelp": "उनके लिए खोज करके संग्रह में आइटम जोड़ें और उन्हें संग्रह में जोड़ने के लिए उनके राइट-क्लिक या टैप मेनू का उपयोग करें।", "ButtonSyncPlay": "SyncPlay", - "BrowsePluginCatalogMessage": "उपलब्ध प्लगिन्स देखने के लिए हमारे कैटलॉग को ब्राउज़ करें.", - "Browse": "ब्राउज़" + "BrowsePluginCatalogMessage": "उपलब्ध प्लगिन्स देखने के लिए हमारे कैटलॉग को ब्राउज़ करें।", + "Browse": "ब्राउज़", + "BoxSet": "बॉक्स सेट", + "BurnSubtitlesHelp": "निर्धारित करता है कि वीडियो ट्रांसकोडिंग करते समय सर्वर को उपशीर्षक बर्न-इन करना चाहिए। इससे बचने से प्रदर्शन में बहुत सुधार होगा। छवि आधारित उपशीर्षक (VOBSUB, PGS, SUB, IDX, …) एवं ASS अथवा SSA जैसे उपशीर्षक बर्न-इन करने के लिए ऑटो का चयन करें।" } From 61a5ffcf8aa16290f92401ac3412283f406470eb Mon Sep 17 00:00:00 2001 From: David Date: Fri, 17 Jul 2020 11:41:59 +0000 Subject: [PATCH 0274/1168] Translated using Weblate (German) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/ --- src/strings/de.json | 54 ++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/strings/de.json b/src/strings/de.json index b26b3ec80..121e58537 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -577,14 +577,14 @@ "LabelEvent": "Ereignis:", "LabelEveryXMinutes": "Alle:", "LabelExtractChaptersDuringLibraryScan": "Erzeuge Kapitelbilder während des Bibliothekscans", - "LabelExtractChaptersDuringLibraryScanHelp": "Generiert Kapitelbilder während des Imports von Videos beim Bibliothekenscan erzeugt. Anderenfalls werden die Kapitelbilder während einer eigens dafür geplanten Aufgabe erstellt, was den regelmäßig Bibliothekenscan beschleunigt.", + "LabelExtractChaptersDuringLibraryScanHelp": "Falls aktiviert, werden die Kapitelbilder während des Imports von Videos beim Bibliothekenscan erzeugt. Falls deaktiviert, werden die Kapitelbilder während einer eigens dafür geplanten Aufgabe erstellt, was den regelmäßig Bibliothekenscan beschleunigt.", "LabelFailed": "Fehlgeschlagen", "LabelFileOrUrl": "Datei oder URL:", "LabelFinish": "Fertig", "LabelFont": "Schriftart:", "LabelForgotPasswordUsernameHelp": "Bitte gib deinen Benutzernamen ein, falls du dich daran erinnerst.", "LabelFriendlyName": "Benutzerfreundlicher Name:", - "LabelServerNameHelp": "Dieser Name wird benutzt um den Server zu identifizieren, normalerweise wird der Server-/Computername verwendet.", + "LabelServerNameHelp": "Dieser Name wird benutzt um den Server zu identifizieren, standardmäßig wird der Server-/Computername verwendet.", "LabelGroupMoviesIntoCollections": "Gruppiere Filme in Collections", "LabelGroupMoviesIntoCollectionsHelp": "Wenn Filmlisten angezeigt werden, dann werden Filme, die zu einer Collection gehören, als ein gruppiertes Element angezeigt.", "LabelEncoderPreset": "H264 Encoding Voreinstellung:", @@ -597,42 +597,42 @@ "LabelIconMaxHeight": "Maximale Iconhöhe:", "LabelIconMaxHeightHelp": "Maximale Auflösung für durch UPnP übermittelte Icons:icon.", "LabelIconMaxWidth": "Maximale Iconbreite:", - "LabelIconMaxWidthHelp": "Maximale Auflösung für durch UPnP übermittelte Icons:icon.", + "LabelIconMaxWidthHelp": "Maximale Auflösung der Icons, die über upnp:icon angezeigt werden.", "LabelIdentificationFieldHelp": "Ein Teilstring oder Regex Ausdruck, der keine Groß- und Kleinschreibung berücksichtigt.", "LabelImageFetchersHelp": "Aktiviere und ordne deine bevorzugten Bildquellen nach Präferenzen.", "LabelImageType": "Bildtyp:", "LabelImportOnlyFavoriteChannels": "Beschränke auf favorisierte Kanäle", "LabelInNetworkSignInWithEasyPassword": "Schalte Login mit einfachen Passwort für das eigene Netzwerk ein", - "LabelInNetworkSignInWithEasyPasswordHelp": "Wenn aktiviert, können Sie sich in ihrem eigenen Netzwerk mit dem vereinfachten PIN bei Jellyfin Apps anmelden. Ihr reguläres Kennwort wird nur benötigt, wenn Sie unterwegs sind. Wenn Sie den PIN frei lassen, so benötigen Sie in Ihrem Netzwerk keinen PIN.", + "LabelInNetworkSignInWithEasyPasswordHelp": "Einfachen Pin verwenden, um sich bei Jellyfin Apps im lokalen Netzwerk anzumelden. Ihr reguläres Kennwort wird nur benötigt, wenn Sie unterwegs sind. Wenn Sie den PIN frei lassen, so benötigen Sie in Ihrem Netzwerk keinen PIN.", "LabelInternetQuality": "Internetqualität:", "LabelKeepUpTo": "Fortführen:", "LabelKidsCategories": "Kinderkategorien:", "LabelKodiMetadataDateFormat": "Veröffentlichungsdatum Format:", - "LabelKodiMetadataDateFormatHelp": "Alle Daten innerhalb von NFO-Dateien werden in diesem Format analysiert.", - "LabelKodiMetadataEnableExtraThumbs": "Kopiere Extrafanart in Extrathumbs", + "LabelKodiMetadataDateFormatHelp": "Alle Daten innerhalb von NFO-Dateien werden in diesem Format gelesen.", + "LabelKodiMetadataEnableExtraThumbs": "Kopiere Extra-Fanart- nach Extra-Vorschau-Feld", "LabelKodiMetadataEnableExtraThumbsHelp": "Beim downloaden von Bildern können diese sowohl als Extrafanart als auch als Extrathumb gespeichert werden, um maximale Kodi Kompatibilität zu erzielen.", "LabelKodiMetadataEnablePathSubstitution": "Aktiviere Pfadersetzung", "LabelKodiMetadataEnablePathSubstitutionHelp": "Aktiviert die Pfadersetzung für Bildpfade durch Benutzung der Server Pfadersetzung Einstellungen.", "LabelKodiMetadataSaveImagePaths": "Speicher Bildpfade innerhalb der NFO Dateien", "LabelKodiMetadataSaveImagePathsHelp": "Dies ist empfehlenswert wenn du Dateinamen hast, die nicht den Kodi Richtlinien entsprechen.", - "LabelKodiMetadataUser": "Speichere den \"Gesehen\" Status von Benutzern in NFO's für:", - "LabelKodiMetadataUserHelp": "Aktivieren, um den \"Gesehen\" Status in NFO-Dateien zu speichern, damit diese von anderen Anwendungen verwendet werden können.", + "LabelKodiMetadataUser": "Speichere den \"Gesehen\" Status von Benutzern in NFO-Dateien für:", + "LabelKodiMetadataUserHelp": "\"Gesehen\" Status in NFO-Dateien speichern, damit diese von anderen Anwendungen verwendet werden können.", "LabelLanNetworks": "Lokale Netzwerke:", "LabelLanguage": "Sprache:", "LabelLineup": "TV Programm:", "LabelLocalHttpServerPortNumber": "Lokale HTTP Portnummer:", - "LabelLocalHttpServerPortNumberHelp": "Die TCP Port Nummer, auf die der Jellyfin http Server hört.", + "LabelLocalHttpServerPortNumberHelp": "Die TCP-Portnummer, die der HTTP-Server von Jellyfin verwenden soll.", "LabelLockItemToPreventChanges": "Sperre diesen Eintrag um zukünftige Änderungen zu verhindern", "LabelLoginDisclaimer": "Anmeldung Haftungsausschluss:", - "LabelLoginDisclaimerHelp": "Dies wird am Boden des Anmeldebildschirms angezeigt.", + "LabelLoginDisclaimerHelp": "Diese Nachricht wird am unteren Ende des Anmeldebildschirms angezeigt.", "LabelManufacturer": "Hersteller:", - "LabelManufacturerUrl": "Hersteller URL", + "LabelManufacturerUrl": "Hersteller-URL", "LabelMatchType": "Übereinstimmungstyp:", "LabelMaxBackdropsPerItem": "Maximale Anzahl von Hintergründen pro Element:", "LabelMaxChromecastBitrate": "Max Chromcast Datenrate:", "LabelMaxParentalRating": "Höchste erlaubte elterlich Bewertung:", "LabelMaxResumePercentage": "Maximale Prozent für Wiederaufnahme:", - "LabelMaxResumePercentageHelp": "Titel werden als \"vollständig gesehen\" markiert, wenn sie nach dieser Zeitmarke gestoppt werden.", + "LabelMaxResumePercentageHelp": "Titel werden als vollständig gesehen markiert, wenn sie nach dieser Zeit gestoppt werden", "LabelMaxScreenshotsPerItem": "Maximale Anzahl von Screenshots pro Element:", "LabelMaxStreamingBitrate": "Maximale Streaming-Qualität:", "LabelMaxStreamingBitrateHelp": "Wähle die maximale Bitrate während des streamens.", @@ -645,12 +645,12 @@ "LabelMetadataPathHelp": "Wähle ein Verzeichnis, für die heruntergeladenen Artworks und Metadaten.", "LabelMetadataReaders": "Metadatenleser:", "LabelMetadataReadersHelp": "Lege deine bevorzugte lokale Metadatenquelle fest und ordne sie nach Prioritäten. Die erste Datei die gefunden wird, wird verwendet.", - "LabelMetadataSavers": "Metadatenspeicherer:", - "LabelMetadataSaversHelp": "Wähle das Dateiformat in dem deine Metadaten gespeichert werden sollen.", + "LabelMetadataSavers": "Metadaten-Speicherer:", + "LabelMetadataSaversHelp": "Wähle das Dateiformat, in dem deine Metadaten gespeichert werden sollen.", "LabelMethod": "Methode:", "LabelMinBackdropDownloadWidth": "Minimale Breite für zu herunterladende Hintergründe:", "LabelMinResumeDuration": "Minimale Dauer für Wiederaufnahme:", - "LabelMinResumeDurationHelp": "Die Videolänge in Sekunden, ab der die Wiedergabeposition gespeichert wird und dich fortsetzen lässt.", + "LabelMinResumeDurationHelp": "Die kürzeste Videolänge in Sekunden, die den Wiedergabeposition speichert und dich fortsetzen lässt.", "LabelMinResumePercentage": "Minimale Prozent für Wiederaufnahme:", "LabelMinResumePercentageHelp": "Titel werden als \"Ungesehen\" eingetragen, wenn sie vor dieser Zeit gestoppt werden.", "LabelMinScreenshotDownloadWidth": "Minimale Breite für zu herunterladende Screenshot:", @@ -661,7 +661,7 @@ "LabelMonitorUsers": "Überwache Aktivität von:", "LabelMovieCategories": "Filmkategorien:", "LabelMoviePrefix": "Filmpräfix:", - "LabelMoviePrefixHelp": "Wenn ein Präfix in Filmtiteln angewendet wird, gib es hier ein damit Jellyfin es korrekt behandeln kann.", + "LabelMoviePrefixHelp": "Wenn ein Präfix in Filmtiteln angewendet wird, gib es hier ein damit der Server es korrekt behandeln kann.", "LabelMovieRecordingPath": "Film Aufnahmepfad (Optional):", "LabelMusicStreamingTranscodingBitrate": "Musik-Transkodierung Bitrate:", "LabelMusicStreamingTranscodingBitrateHelp": "Wähle die maximale Bitrate für das streamen von Musik.", @@ -767,7 +767,7 @@ "LabelTitle": "Titel:", "LabelTrackNumber": "Stück Nummer:", "LabelTranscodingAudioCodec": "Audio Codec:", - "LabelTranscodingTempPathHelp": "Dieses Verzeichnis beinhaltet Dateien die für den Betrieb des Transcoders benutzt werden. Wähle einen eigenen Pfad oder lasse das Feld frei, um den Standardspeicherort im Server Datenverzeichnis zu nutzen.", + "LabelTranscodingTempPathHelp": "Wähle einen eigenen Pfad für transkodierte Dateien. Lasse das Feld frei, um den Standardspeicherort zu nutzen.", "LabelTranscodingThreadCount": "Anzahl Transkodierungs-Threads:", "LabelTranscodingThreadCountHelp": "Legen Sie die maximale Anzahl von Transkodierungs-Threads fest. Das Reduzieren der Thread-Anzahl verringert die CPU Auslastung, wird aber möglicherweise die Transkodierung nicht schnell genug für eine störungsfrei Wiedergabe ermöglichen.", "LabelTranscodingVideoCodec": "Video Codec:", @@ -801,7 +801,7 @@ "Large": "Groß", "LatestFromLibrary": "Neueste {0}", "LearnHowYouCanContribute": "Erfahre, wie du unterstützen kannst.", - "LibraryAccessHelp": "Wähle die Medienverzeichnisse die du mit diesem Benutzer teilen möchtest. Administratoren können den Metadaten-Manager verwenden um alle Ordner zu bearbeiten.", + "LibraryAccessHelp": "Wähle die Bibliotheken aus, die du mit diesem Benutzer teilen möchtest. Administratoren können den Metadaten-Manager verwenden um alle Ordner zu bearbeiten.", "Like": "Mag ich", "List": "Liste", "LiveBroadcasts": "Liveübertragungen", @@ -841,7 +841,7 @@ "MessageConfirmRemoveMediaLocation": "Bist du dir sicher diese Medienquelle entfernen zu wollen?", "MessageConfirmRestart": "Möchten Sie Jellyfin Server wirklich neu starten?", "MessageConfirmRevokeApiKey": "Möchten Sie diesen API Schlüssel wirklich löschen? Die Verbindung der Anwendung zum Jellyfin Server wird sofort unterbrochen.", - "MessageConfirmShutdown": "Möchsten Sie Jellyfin Server wirklich beenden?", + "MessageConfirmShutdown": "Möchten Sie den Server wirklich herunterfahren?", "MessageContactAdminToResetPassword": "Bitte kontaktiere deinen Systemadministrator, um dein Passwort zurücksetzen zu lassen.", "MessageCreateAccountAt": "Erstellen Sie ein Konto bei {0}", "MessageDeleteTaskTrigger": "Bist du dir sicher, dass du diesen Aufgabenauslöser entfernen möchtest?", @@ -887,7 +887,7 @@ "MoreUsersCanBeAddedLater": "Weitere Benutzer können später über das Dashboard hinzugefügt werden.", "MoveLeft": "Nach links bewegen", "MoveRight": "Nach rechts bewegen", - "MovieLibraryHelp": "Überprüfe den {0}Filmbenennungsguide{1}.", + "MovieLibraryHelp": "Überprüfe den {0}Filmbenennungsleitfaden{1}.", "Movies": "Filme", "Mute": "Stumm", "MySubtitles": "Meine Untertitel", @@ -1122,7 +1122,7 @@ "SearchForMissingMetadata": "Suche nach fehlenden Metadaten", "SearchForSubtitles": "Suche nach Untertiteln", "SearchResults": "Suchergebnisse", - "SendMessage": "Sende Nachricht", + "SendMessage": "Nachricht senden", "Series": "Serien", "SeriesCancelled": "Serie abgebrochen.", "SeriesDisplayOrderHelp": "Sortiere Episoden nach Ausstrahlungsdatum, DVD Reihenfolge oder absoluter Nummerierung.", @@ -1222,7 +1222,7 @@ "TrackCount": "{0} Titel", "Trailers": "Trailer", "Tuesday": "Dienstag", - "TvLibraryHelp": "Überprüfe den {0}Serienbenennungsguide{1}.", + "TvLibraryHelp": "Überprüfe den {0}Serienbenennungsleitfaden{1}.", "Uniform": "Einheitlich", "UninstallPluginConfirmation": "Möchtest du {0} wirklich deinstallieren?", "UninstallPluginHeader": "Plugin deinstallieren", @@ -1232,7 +1232,7 @@ "Up": "Hoch", "Upload": "Hochladen", "UserAgentHelp": "Stelle einen benutzerdefinierten User-Agent HTTP header zur Verfügung.", - "UserProfilesIntro": "Jellyfin bietet die Unterstützung von Benutzerprofilen, mit eigenen Ansichten, Altersfreigaben und Spielstände von Medien.", + "UserProfilesIntro": "Jellyfin bietet Unterstützung für Benutzerprofile mit eigenen Ansichtseinstellungen, Wiedergabepositionen und Altersfreigaben.", "ValueAlbumCount": "{0} Alben", "ValueConditions": "Bedingungen: {0}", "ValueEpisodeCount": "{0} Episoden", @@ -1321,7 +1321,7 @@ "LabelVersion": "Version:", "LabelVersionNumber": "Version {0}", "LabelVideo": "Video", - "LeaveBlankToNotSetAPassword": "Du kannst dieses Feld frei lassen um kein Passwort zu setzen.", + "LeaveBlankToNotSetAPassword": "Dieses Feld frei lassen, um kein Passwort zu setzen.", "LinksValue": "Links: {0}", "MessageImageFileTypeAllowed": "Nur JPEG- und PNG-Dateien werden unterstützt.", "MessageImageTypeNotSelected": "Bitte wähle einen Bildtyp aus dem Drop-Down Menü aus.", @@ -1433,7 +1433,7 @@ "LabelAudioBitrate": "Tonbitrate:", "ButtonAddImage": "Bild hinzufügen", "LabelSize": "Größe:", - "LabelTranscodes": "Transkoder:", + "LabelTranscodes": "Transcodiert:", "LabelTranscodingProgress": "Transcodierungsfortschritt:", "LabelAudioBitDepth": "Audio-Bittiefe:", "LabelPleaseRestart": "Die Änderungen werden nach dem manuellen Neuladen des Webclients wirksam.", @@ -1456,7 +1456,7 @@ "MessageNoServersAvailable": "Die automatische Serversuche konnte keinen Server finden.", "LabelPlayer": "Schauspieler:", "MediaInfoCodecTag": "Codec Tag", - "SubtitleOffset": "Untertitelvorlauf", + "SubtitleOffset": "Untertitel-Synchronisierung", "PlaybackData": "Wiedergabeinformationen", "OptionThumbCard": "Vorschaukarte", "OptionPosterCard": "Posterkarte", @@ -1470,7 +1470,7 @@ "TabNetworking": "Netzwerk", "VideoRange": "Videobereich", "ButtonSplit": "Trennen", - "SelectAdminUsername": "Bitte einen Benutzernamen für das Administrator-Konto auswählen.", + "SelectAdminUsername": "Bitte wählen Sie einen Benutzernamen für den Administrator-Account.", "HeaderNavigation": "Navigation", "CopyStreamURLError": "Beim Kopieren der URL ist ein Fehler aufgetreten.", "MessageConfirmAppExit": "Wirklich verlassen?", From 93fcca6965d99c017cd8389c68cce105970663d6 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 17 Jul 2020 17:02:49 +0100 Subject: [PATCH 0275/1168] update paper button and button --- src/elements/emby-button/emby-button.js | 106 +++++++++--------- .../emby-button/paper-icon-button-light.js | 26 ++--- 2 files changed, 62 insertions(+), 70 deletions(-) diff --git a/src/elements/emby-button/emby-button.js b/src/elements/emby-button/emby-button.js index 4848f4751..683c59cca 100644 --- a/src/elements/emby-button/emby-button.js +++ b/src/elements/emby-button/emby-button.js @@ -7,73 +7,69 @@ import appHost from 'apphost'; import 'css!./emby-button'; import 'registerElement'; -/* eslint-disable indent */ +const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype); +const EmbyLinkButtonPrototype = Object.create(HTMLAnchorElement.prototype); - const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype); - const EmbyLinkButtonPrototype = Object.create(HTMLAnchorElement.prototype); - - function onAnchorClick(e) { - const href = this.getAttribute('href') || ''; - if (href !== '#') { - if (this.getAttribute('target')) { - if (!appHost.supports('targetblank')) { - e.preventDefault(); - shell.openUrl(href); - } - } else { - appRouter.handleAnchorClick(e); +function onAnchorClick(e) { + const href = this.getAttribute('href') || ''; + if (href !== '#') { + if (this.getAttribute('target')) { + if (!appHost.supports('targetblank')) { + e.preventDefault(); + shell.openUrl(href); } } else { - e.preventDefault(); + appRouter.handleAnchorClick(e); } + } else { + e.preventDefault(); + } +} + +EmbyButtonPrototype.createdCallback = function () { + if (this.classList.contains('emby-button')) { + return; } - EmbyButtonPrototype.createdCallback = function () { - if (this.classList.contains('emby-button')) { - return; - } + this.classList.add('emby-button'); + // TODO replace all instances of element-showfocus with this method + if (layoutManager.tv) { + // handles all special css for tv layout + // this method utilizes class chaining + this.classList.add('show-focus'); + } +}; - this.classList.add('emby-button'); - // TODO replace all instances of element-showfocus with this method - if (layoutManager.tv) { - // handles all special css for tv layout - // this method utilizes class chaining - this.classList.add('show-focus'); - } - }; +EmbyButtonPrototype.attachedCallback = function () { + if (this.tagName === 'A') { + dom.removeEventListener(this, 'click', onAnchorClick, {}); + dom.addEventListener(this, 'click', onAnchorClick, {}); - EmbyButtonPrototype.attachedCallback = function () { - if (this.tagName === 'A') { - dom.removeEventListener(this, 'click', onAnchorClick, {}); - dom.addEventListener(this, 'click', onAnchorClick, {}); - - if (this.getAttribute('data-autohide') === 'true') { - if (appHost.supports('externallinks')) { - this.classList.remove('hide'); - } else { - this.classList.add('hide'); - } + if (this.getAttribute('data-autohide') === 'true') { + if (appHost.supports('externallinks')) { + this.classList.remove('hide'); + } else { + this.classList.add('hide'); } } - }; + } +}; - EmbyButtonPrototype.detachedCallback = function () { - dom.removeEventListener(this, 'click', onAnchorClick, {}); - }; +EmbyButtonPrototype.detachedCallback = function () { + dom.removeEventListener(this, 'click', onAnchorClick, {}); +}; - EmbyLinkButtonPrototype.createdCallback = EmbyButtonPrototype.createdCallback; - EmbyLinkButtonPrototype.attachedCallback = EmbyButtonPrototype.attachedCallback; +EmbyLinkButtonPrototype.createdCallback = EmbyButtonPrototype.createdCallback; +EmbyLinkButtonPrototype.attachedCallback = EmbyButtonPrototype.attachedCallback; - document.registerElement('emby-button', { - prototype: EmbyButtonPrototype, - extends: 'button' - }); +document.registerElement('emby-button', { + prototype: EmbyButtonPrototype, + extends: 'button' +}); - document.registerElement('emby-linkbutton', { - prototype: EmbyLinkButtonPrototype, - extends: 'a' - }); +document.registerElement('emby-linkbutton', { + prototype: EmbyLinkButtonPrototype, + extends: 'a' +}); - export default EmbyButtonPrototype; - -/* eslint-enable indent */ +export default EmbyButtonPrototype; diff --git a/src/elements/emby-button/paper-icon-button-light.js b/src/elements/emby-button/paper-icon-button-light.js index 5226f13db..609dec296 100644 --- a/src/elements/emby-button/paper-icon-button-light.js +++ b/src/elements/emby-button/paper-icon-button-light.js @@ -2,21 +2,17 @@ import layoutManager from 'layoutManager'; import 'css!./emby-button'; import 'registerElement'; -/* eslint-disable indent */ +const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype); - const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype); +EmbyButtonPrototype.createdCallback = function () { + this.classList.add('paper-icon-button-light'); - EmbyButtonPrototype.createdCallback = function () { - this.classList.add('paper-icon-button-light'); + if (layoutManager.tv) { + this.classList.add('show-focus'); + } +}; - if (layoutManager.tv) { - this.classList.add('show-focus'); - } - }; - - document.registerElement('paper-icon-button-light', { - prototype: EmbyButtonPrototype, - extends: 'button' - }); - -/* eslint-enable indent */ +document.registerElement('paper-icon-button-light', { + prototype: EmbyButtonPrototype, + extends: 'button' +}); From 523231fcd1a474d189a061e7e6914ab4e201468a Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 17 Jul 2020 17:43:39 +0100 Subject: [PATCH 0276/1168] Migration of metadataeditor and personeditor to ES6 modules This reverts commit e75ff1fb9a12dbfe4a99a9dad4a0ea31a6343894. --- package.json | 2 + src/components/itemContextMenu.js | 2 +- .../metadataEditor/metadataEditor.js | 212 ++++++++++-------- src/components/metadataEditor/personEditor.js | 31 ++- 4 files changed, 139 insertions(+), 108 deletions(-) diff --git a/package.json b/package.json index b911778bc..32ae3a2c0 100644 --- a/package.json +++ b/package.json @@ -111,6 +111,8 @@ "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", "src/components/mediaLibraryCreator/mediaLibraryCreator.js", "src/components/mediaLibraryEditor/mediaLibraryEditor.js", + "src/components/metadataEditor/metadataEditor.js", + "src/components/metadataEditor/personEditor.js", "src/components/listview/listview.js", "src/components/playback/brightnessosd.js", "src/components/playback/mediasession.js", diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index 584b25f0e..68fbbb74c 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -554,7 +554,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', }); } else { require(['metadataEditor'], function (metadataEditor) { - metadataEditor.show(item.Id, serverId).then(resolve, reject); + metadataEditor.default.show(item.Id, serverId).then(resolve, reject); }); } }); diff --git a/src/components/metadataEditor/metadataEditor.js b/src/components/metadataEditor/metadataEditor.js index 61a4ba7f2..9977ae1ea 100644 --- a/src/components/metadataEditor/metadataEditor.js +++ b/src/components/metadataEditor/metadataEditor.js @@ -1,9 +1,30 @@ -define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loading', 'focusManager', 'connectionManager', 'globalize', 'require', 'shell', 'emby-checkbox', 'emby-input', 'emby-select', 'listViewStyle', 'emby-textarea', 'emby-button', 'paper-icon-button-light', 'css!./../formdialog', 'clearButtonStyle', 'flexStyles'], function (itemHelper, dom, layoutManager, dialogHelper, datetime, loading, focusManager, connectionManager, globalize, require, shell) { - 'use strict'; +import itemHelper from 'itemHelper'; +import dom from 'dom'; +import layoutManager from 'layoutManager'; +import dialogHelper from 'dialogHelper'; +import datetime from 'datetime'; +import loading from 'loading'; +import focusManager from 'focusManager'; +import connectionManager from 'connectionManager'; +import globalize from 'globalize'; +import require from 'require'; +import shell from 'shell'; +import 'emby-checkbox'; +import 'emby-input'; +import 'emby-select'; +import 'listViewStyle'; +import 'emby-textarea'; +import 'emby-button'; +import 'paper-icon-button-light'; +import 'css!./../formdialog'; +import 'clearButtonStyle'; +import 'flexStyles'; - var currentContext; - var metadataEditorInfo; - var currentItem; +/* eslint-disable indent */ + + let currentContext; + let metadataEditorInfo; + let currentItem; function isDialog() { return currentContext.classList.contains('dialog'); @@ -28,11 +49,11 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi closeDialog(true); } - var apiClient = getApiClient(); + const apiClient = getApiClient(); apiClient.updateItem(item).then(function () { - var newContentType = form.querySelector('#selectContentType').value || ''; + const newContentType = form.querySelector('#selectContentType').value || ''; if ((metadataEditorInfo.ContentType || '') !== newContentType) { @@ -56,7 +77,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi } function getSelectedAirDays(form) { - var checkedItems = form.querySelectorAll('.chkAirDay:checked') || []; + const checkedItems = form.querySelectorAll('.chkAirDay:checked') || []; return Array.prototype.map.call(checkedItems, function (c) { return c.getAttribute('data-day'); }); @@ -92,7 +113,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function getDateValue(form, element, property) { - var val = form.querySelector(element).value; + let val = form.querySelector(element).value; if (!val) { return null; @@ -100,14 +121,14 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi if (currentItem[property]) { - var date = datetime.parseISO8601Date(currentItem[property], true); + const date = datetime.parseISO8601Date(currentItem[property], true); - var parts = date.toISOString().split('T'); + const parts = date.toISOString().split('T'); // If the date is the same, preserve the time if (parts[0].indexOf(val) === 0) { - var iso = parts[1]; + const iso = parts[1]; val += 'T' + iso; } @@ -120,9 +141,9 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi loading.show(); - var form = this; + const form = this; - var item = { + const item = { Id: currentItem.Id, Name: form.querySelector('#txtName').value, OriginalTitle: form.querySelector('#txtOriginalName').value, @@ -168,9 +189,9 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi item.ProviderIds = Object.assign({}, currentItem.ProviderIds); - var idElements = form.querySelectorAll('.txtExternalId'); + const idElements = form.querySelectorAll('.txtExternalId'); Array.prototype.map.call(idElements, function (idElem) { - var providerKey = idElem.getAttribute('data-providerkey'); + const providerKey = idElem.getAttribute('data-providerkey'); item.ProviderIds[providerKey] = idElem.value; }); @@ -179,7 +200,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi if (currentItem.Type === 'Person') { - var placeOfBirth = form.querySelector('#txtPlaceOfBirth').value; + const placeOfBirth = form.querySelector('#txtPlaceOfBirth').value; item.ProductionLocations = placeOfBirth ? [placeOfBirth] : []; } @@ -187,11 +208,11 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi if (currentItem.Type === 'Series') { // 600000000 - var seriesRuntime = form.querySelector('#txtSeriesRuntime').value; + const seriesRuntime = form.querySelector('#txtSeriesRuntime').value; item.RunTimeTicks = seriesRuntime ? (seriesRuntime * 600000000) : null; } - var tagline = form.querySelector('#txtTagline').value; + const tagline = form.querySelector('#txtTagline').value; item.Taglines = tagline ? [tagline] : []; submitUpdatedItem(form, item); @@ -215,8 +236,8 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi prompt({ label: 'Value:' }).then(function (text) { - var list = dom.parentWithClass(source, 'editableListviewContainer').querySelector('.paperList'); - var items = getListValues(list); + const list = dom.parentWithClass(source, 'editableListviewContainer').querySelector('.paperList'); + const items = getListValues(list); items.push(text); populateListView(list, items, sortCallback); }); @@ -224,7 +245,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi } function removeElementFromList(source) { - var el = dom.parentWithClass(source, 'listItem'); + const el = dom.parentWithClass(source, 'listItem'); el.parentNode.removeChild(el); } @@ -234,7 +255,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi personEditor.show(person).then(function (updatedPerson) { - var isNew = index === -1; + const isNew = index === -1; if (isNew) { currentItem.People.push(updatedPerson); @@ -247,13 +268,13 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function onEditorClick(e) { - var btnRemoveFromEditorList = dom.parentWithClass(e.target, 'btnRemoveFromEditorList'); + const btnRemoveFromEditorList = dom.parentWithClass(e.target, 'btnRemoveFromEditorList'); if (btnRemoveFromEditorList) { removeElementFromList(btnRemoveFromEditorList); return; } - var btnAddTextItem = dom.parentWithClass(e.target, 'btnAddTextItem'); + const btnAddTextItem = dom.parentWithClass(e.target, 'btnAddTextItem'); if (btnAddTextItem) { addElementToList(btnAddTextItem); } @@ -264,7 +285,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi } 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); } } @@ -272,11 +293,11 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function init(context, apiClient) { context.querySelector('.externalIds').addEventListener('click', function (e) { - var btnOpenExternalId = dom.parentWithClass(e.target, 'btnOpenExternalId'); + const btnOpenExternalId = dom.parentWithClass(e.target, 'btnOpenExternalId'); if (btnOpenExternalId) { - var field = context.querySelector('#' + btnOpenExternalId.getAttribute('data-fieldid')); + const field = context.querySelector('#' + btnOpenExternalId.getAttribute('data-fieldid')); - var formatString = field.getAttribute('data-formatstring'); + const formatString = field.getAttribute('data-formatstring'); if (field.value) { shell.openUrl(formatString.replace('{0}', field.value)); @@ -311,7 +332,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi context.removeEventListener('click', onEditorClick); context.addEventListener('click', onEditorClick); - var form = context.querySelector('form'); + const form = context.querySelector('form'); form.removeEventListener('submit', onSubmit); form.addEventListener('submit', onSubmit); @@ -322,15 +343,15 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi context.querySelector('#peopleList').addEventListener('click', function (e) { - var index; - var btnDeletePerson = dom.parentWithClass(e.target, 'btnDeletePerson'); + let index; + const btnDeletePerson = dom.parentWithClass(e.target, 'btnDeletePerson'); if (btnDeletePerson) { index = parseInt(btnDeletePerson.getAttribute('data-index')); currentItem.People.splice(index, 1); populatePeople(context, currentItem.People); } - var btnEditPerson = dom.parentWithClass(e.target, 'btnEditPerson'); + const btnEditPerson = dom.parentWithClass(e.target, 'btnEditPerson'); if (btnEditPerson) { index = parseInt(btnEditPerson.getAttribute('data-index')); editPerson(context, currentItem.People[index], index); @@ -340,7 +361,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function getItem(itemId, serverId) { - var apiClient = connectionManager.getApiClient(serverId); + const apiClient = connectionManager.getApiClient(serverId); if (itemId) { return apiClient.getItem(apiClient.getCurrentUserId(), itemId); @@ -351,7 +372,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function getEditorConfig(itemId, serverId) { - var apiClient = connectionManager.getApiClient(serverId); + const apiClient = connectionManager.getApiClient(serverId); if (itemId) { return apiClient.getJSON(apiClient.getUrl('Items/' + itemId + '/MetadataEditor')); @@ -362,13 +383,13 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function populateCountries(select, allCountries) { - var html = ''; + let html = ''; html += ""; - for (var i = 0, length = allCountries.length; i < length; i++) { + for (let i = 0, length = allCountries.length; i < length; i++) { - var culture = allCountries[i]; + const culture = allCountries[i]; html += "'; } @@ -378,13 +399,13 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function populateLanguages(select, languages) { - var html = ''; + let html = ''; html += ""; - for (var i = 0, length = languages.length; i < length; i++) { + for (let i = 0, length = languages.length; i < length; i++) { - var culture = languages[i]; + const culture = languages[i]; html += "'; } @@ -400,41 +421,41 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi showElement('#fldContentType', context); } - var html = metadataInfo.ContentTypeOptions.map(function (i) { + const html = metadataInfo.ContentTypeOptions.map(function (i) { return ''; }).join(''); - var selectEl = context.querySelector('#selectContentType'); + const selectEl = context.querySelector('#selectContentType'); selectEl.innerHTML = html; selectEl.value = metadataInfo.ContentType || ''; } function loadExternalIds(context, item, externalIds) { - var html = ''; + let html = ''; - var providerIds = item.ProviderIds || {}; + const providerIds = item.ProviderIds || {}; - for (var i = 0, length = externalIds.length; i < length; i++) { + for (let i = 0, length = externalIds.length; i < length; i++) { - var idInfo = externalIds[i]; + const idInfo = externalIds[i]; - var id = 'txt1' + idInfo.Key; - var formatString = idInfo.UrlFormatString || ''; + const id = 'txt1' + idInfo.Key; + const formatString = idInfo.UrlFormatString || ''; - var fullName = idInfo.Name; + let fullName = idInfo.Name; if (idInfo.Type) { fullName = idInfo.Name + ' ' + globalize.translate(idInfo.Type); } - var labelText = globalize.translate('LabelDynamicExternalId', fullName); + const labelText = globalize.translate('LabelDynamicExternalId', fullName); html += '
'; html += '
'; - var value = providerIds[idInfo.Key] || ''; + const value = providerIds[idInfo.Key] || ''; html += '
'; html += ''; @@ -448,7 +469,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi html += '
'; } - var elem = context.querySelector('.externalIds', context); + const elem = context.querySelector('.externalIds', context); elem.innerHTML = html; if (externalIds.length) { @@ -465,7 +486,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi context = context || document; if (typeof selector === 'string') { - var elements = multiple ? context.querySelectorAll(selector) : [context.querySelector(selector)]; + const elements = multiple ? context.querySelectorAll(selector) : [context.querySelector(selector)]; Array.prototype.forEach.call(elements, function (el) { if (el) { @@ -484,7 +505,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi context = context || document; if (typeof selector === 'string') { - var elements = multiple ? context.querySelectorAll(selector) : [context.querySelector(selector)]; + const elements = multiple ? context.querySelectorAll(selector) : [context.querySelector(selector)]; Array.prototype.forEach.call(elements, function (el) { if (el) { @@ -686,7 +707,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function fillItemInfo(context, item, parentalRatingOptions) { - var select = context.querySelector('#selectOfficialRating'); + let select = context.querySelector('#selectOfficialRating'); populateRatings(parentalRatingOptions, select, item.OfficialRating); @@ -698,7 +719,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi select.value = item.CustomRating || ''; - var selectStatus = context.querySelector('#selectStatus'); + const selectStatus = context.querySelector('#selectStatus'); populateStatus(selectStatus); selectStatus.value = item.Status || ''; @@ -717,8 +738,8 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi populateListView(context.querySelector('#listTags'), item.Tags); - var lockData = (item.LockData || false); - var chkLockData = context.querySelector('#chkLockData'); + const lockData = (item.LockData || false); + const chkLockData = context.querySelector('#chkLockData'); chkLockData.checked = lockData; if (chkLockData.checked) { hideElement('.providerSettingsContainer', context); @@ -756,7 +777,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi return a.Name; }).join(';'); - var date; + let date; if (item.DateCreated) { try { @@ -798,7 +819,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi context.querySelector('#txtAirTime').value = item.AirTime || ''; - var placeofBirth = item.ProductionLocations && item.ProductionLocations.length ? item.ProductionLocations[0] : ''; + const placeofBirth = item.ProductionLocations && item.ProductionLocations.length ? item.ProductionLocations[0] : ''; context.querySelector('#txtPlaceOfBirth').value = placeofBirth; context.querySelector('#txtOriginalAspectRatio').value = item.AspectRatio || ''; @@ -808,7 +829,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi if (item.RunTimeTicks) { - var minutes = item.RunTimeTicks / 600000000; + const minutes = item.RunTimeTicks / 600000000; context.querySelector('#txtSeriesRuntime').value = Math.round(minutes); } else { @@ -818,18 +839,16 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function populateRatings(allParentalRatings, select, currentValue) { - var html = ''; + let html = ''; html += ""; - var ratings = []; - var i; - var length; - var rating; + const ratings = []; + let rating; - var currentValueFound = false; + let currentValueFound = false; - for (i = 0, length = allParentalRatings.length; i < length; i++) { + for (let i = 0, length = allParentalRatings.length; i < length; i++) { rating = allParentalRatings[i]; @@ -844,7 +863,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi ratings.push({ Name: currentValue, Value: currentValue }); } - for (i = 0, length = ratings.length; i < length; i++) { + for (let i = 0, length = ratings.length; i < length; i++) { rating = ratings[i]; @@ -855,7 +874,7 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi } function populateStatus(select) { - var html = ''; + let html = ''; html += ""; html += "'; @@ -873,8 +892,8 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi } else { items = sortCallback(items); } - var html = ''; - for (var i = 0; i < items.length; i++) { + let html = ''; + for (let i = 0; i < items.length; i++) { html += '
'; html += ''; @@ -897,14 +916,14 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function populatePeople(context, people) { - var lastType = ''; - var html = ''; + let lastType = ''; + let html = ''; - var elem = context.querySelector('#peopleList'); + const elem = context.querySelector('#peopleList'); - for (var i = 0, length = people.length; i < length; i++) { + for (let i = 0, length = people.length; i < length; i++) { - var person = people[i]; + const person = people[i]; html += '
'; @@ -934,13 +953,13 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi function getLockedFieldsHtml(fields, currentFields) { - var html = ''; - for (var i = 0; i < fields.length; i++) { + let html = ''; + for (let i = 0; i < fields.length; i++) { - var field = fields[i]; - var name = field.name; - var value = field.value || field.name; - var checkedHtml = currentFields.indexOf(value) === -1 ? ' checked' : ''; + const field = fields[i]; + const name = field.name; + const value = field.value || field.name; + const checkedHtml = currentFields.indexOf(value) === -1 ? ' checked' : ''; html += '