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

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

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

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

'; + if (showHelp) { + showHelp = false; + itemHtml += '
'; + itemHtml += globalize.translate('Help'); + itemHtml += ''; } - itemHtml += '
'; - itemHtml += '
' + notification.Name + '
'; itemHtml += '
'; - itemHtml += ''; - itemHtml += ''; - return itemHtml; - }).join(''); - - if (list.length) { - html += '
'; - html += '
'; + itemHtml += '
'; } - page.querySelector('.notificationList').innerHTML = html; - loading.hide(); - }); - } + itemHtml += ''; + if (notification.Enabled) { + itemHtml += ''; + } else { + itemHtml += ''; + } + itemHtml += '
'; + itemHtml += '
' + notification.Name + '
'; + itemHtml += '
'; + itemHtml += ''; + itemHtml += '
'; + return itemHtml; + }).join(''); - return function(view, params) { - view.addEventListener('viewshow', function() { - reload(view); - }); - }; -}); + if (list.length) { + html += '
'; + html += '
'; + } + page.querySelector('.notificationList').innerHTML = html; + loading.hide(); + }); +} + +export default function (view, params) { + view.addEventListener('viewshow', function () { + reload(view); + }); +} From 287cc06963b5935e1a7979c763d26a1cc7d3d17f Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 26 Jul 2020 11:29:02 +0100 Subject: [PATCH 006/226] Migration of edititemmetadata to ES6 module --- package.json | 1 + src/controllers/edititemmetadata.js | 51 ++++++++++++++--------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index dbedd2922e..ecb33b77c8 100644 --- a/package.json +++ b/package.json @@ -189,6 +189,7 @@ "src/controllers/dashboard/users/userparentalcontrol.js", "src/controllers/dashboard/users/userpasswordpage.js", "src/controllers/dashboard/users/userprofilespage.js", + "src/controllers/edititemmetadata.js", "src/controllers/playback/nowplaying.js", "src/controllers/playback/videoosd.js", "src/controllers/searchpage.js", diff --git a/src/controllers/edititemmetadata.js b/src/controllers/edititemmetadata.js index 1a3647a758..57c72dda28 100644 --- a/src/controllers/edititemmetadata.js +++ b/src/controllers/edititemmetadata.js @@ -1,31 +1,30 @@ -define(['loading', 'scripts/editorsidebar'], function (loading) { - 'use strict'; +import loading from 'loading'; +import 'scripts/editorsidebar'; - function reload(context, itemId) { - loading.show(); +function reload(context, itemId) { + loading.show(); - if (itemId) { - require(['metadataEditor'], function ({default: metadataEditor}) { - metadataEditor.embed(context.querySelector('.editPageInnerContent'), itemId, ApiClient.serverInfo().Id); - }); - } else { - context.querySelector('.editPageInnerContent').innerHTML = ''; - loading.hide(); - } + if (itemId) { + import('metadataEditor').then(({ default: metadataEditor }) => { + metadataEditor.embed(context.querySelector('.editPageInnerContent'), itemId, ApiClient.serverInfo().Id); + }); + } else { + context.querySelector('.editPageInnerContent').innerHTML = ''; + loading.hide(); } +} - return function (view, params) { - view.addEventListener('viewshow', function () { - reload(this, MetadataEditor.getCurrentItemId()); - }); - MetadataEditor.setCurrentItemId(null); - view.querySelector('.libraryTree').addEventListener('itemclicked', function (event) { - var data = event.detail; +export default function (view, params) { + view.addEventListener('viewshow', function () { + reload(this, MetadataEditor.getCurrentItemId()); + }); + MetadataEditor.setCurrentItemId(null); + view.querySelector('.libraryTree').addEventListener('itemclicked', function (event) { + var data = event.detail; - if (data.id != MetadataEditor.getCurrentItemId()) { - MetadataEditor.setCurrentItemId(data.id); - reload(view, data.id); - } - }); - }; -}); + if (data.id != MetadataEditor.getCurrentItemId()) { + MetadataEditor.setCurrentItemId(data.id); + reload(view, data.id); + } + }); +} From 3658b4471a1314d32bb84eb0cb83f6149fc5da1a Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 26 Jul 2020 11:29:26 +0100 Subject: [PATCH 007/226] Migration of Favorites and Hometab to ES6 modules --- package.json | 2 + src/controllers/favorites.js | 108 +++++++++++++++++++---------------- src/controllers/home.js | 2 +- src/controllers/hometab.js | 67 +++++++++++----------- 4 files changed, 97 insertions(+), 82 deletions(-) diff --git a/package.json b/package.json index ecb33b77c8..de3fe62adc 100644 --- a/package.json +++ b/package.json @@ -190,6 +190,8 @@ "src/controllers/dashboard/users/userpasswordpage.js", "src/controllers/dashboard/users/userprofilespage.js", "src/controllers/edititemmetadata.js", + "src/controllers/favorites.js", + "src/controllers/hometab.js", "src/controllers/playback/nowplaying.js", "src/controllers/playback/videoosd.js", "src/controllers/searchpage.js", diff --git a/src/controllers/favorites.js b/src/controllers/favorites.js index b4c7936239..532801bfaf 100644 --- a/src/controllers/favorites.js +++ b/src/controllers/favorites.js @@ -1,5 +1,15 @@ -define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'apphost', 'layoutManager', 'focusManager', 'emby-itemscontainer', 'emby-scroller'], function (appRouter, cardBuilder, dom, globalize, connectionManager, appHost, layoutManager, focusManager) { - 'use strict'; +import appRouter from 'appRouter'; +import cardBuilder from 'cardBuilder'; +import dom from 'dom'; +import globalize from 'globalize'; +import connectionManager from 'connectionManager'; +import appHost from 'apphost'; +import layoutManager from 'layoutManager'; +import focusManager from 'focusManager'; +import 'emby-itemscontainer'; +import 'emby-scroller'; + +/* eslint-disable indent */ function enableScrollX() { return true; @@ -133,8 +143,8 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap function getFetchDataFn(section) { return function () { - var apiClient = this.apiClient; - var options = { + const apiClient = this.apiClient; + const options = { SortBy: (section.types, 'SeriesName,SortName'), SortOrder: 'Ascending', Filters: 'IsFavorite', @@ -145,7 +155,7 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap EnableTotalRecordCount: false }; options.Limit = 20; - var userId = apiClient.getCurrentUserId(); + const userId = apiClient.getCurrentUserId(); if ('MusicArtist' === section.types) { return apiClient.getArtists(userId, options); @@ -170,17 +180,17 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap function getItemsHtmlFn(section) { return function (items) { - var supportsImageAnalysis = appHost.supports('imageanalysis'); - var cardLayout = (appHost.preferVisualCards || supportsImageAnalysis) && section.autoCardLayout && section.showTitle; + const supportsImageAnalysis = appHost.supports('imageanalysis'); + let cardLayout = (appHost.preferVisualCards || supportsImageAnalysis) && section.autoCardLayout && section.showTitle; cardLayout = false; - var serverId = this.apiClient.serverId(); - var leadingButtons = layoutManager.tv ? [{ + const serverId = this.apiClient.serverId(); + const leadingButtons = layoutManager.tv ? [{ name: globalize.translate('All'), id: 'more', icon: 'favorite', routeUrl: getRouteUrl(section, serverId) }] : null; - var lines = 0; + let lines = 0; if (section.showTitle) { lines++; @@ -216,23 +226,12 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap }; } - function FavoritesTab(view, params) { - this.view = view; - this.params = params; - this.apiClient = connectionManager.currentApiClient(); - this.sectionsContainer = view.querySelector('.sections'); - createSections(this, this.sectionsContainer, this.apiClient); - } - function createSections(instance, elem, apiClient) { - var i; - var length; - var sections = getSections(); - var html = ''; + const sections = getSections(); + let html = ''; - for (i = 0, length = sections.length; i < length; i++) { - var section = sections[i]; - var sectionClass = 'verticalSection'; + for (const section of sections) { + let sectionClass = 'verticalSection'; if (!section.showTitle) { sectionClass += ' verticalSection-extrabottompadding'; @@ -258,23 +257,32 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap } elem.innerHTML = html; - var elems = elem.querySelectorAll('.itemsContainer'); + const elems = elem.querySelectorAll('.itemsContainer'); - for (i = 0, length = elems.length; i < length; i++) { - var itemsContainer = elems[i]; + for (let i = 0, length = elems.length; i < length; i++) { + const itemsContainer = elems[i]; itemsContainer.fetchData = getFetchDataFn(sections[i]).bind(instance); itemsContainer.getItemsHtml = getItemsHtmlFn(sections[i]).bind(instance); itemsContainer.parentContainer = dom.parentWithClass(itemsContainer, 'verticalSection'); } } - FavoritesTab.prototype.onResume = function (options) { - var promises = (this.apiClient, []); - var view = this.view; - var elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); +class FavoritesTab { + constructor(view, params) { + this.view = view; + this.params = params; + this.apiClient = connectionManager.currentApiClient(); + this.sectionsContainer = view.querySelector('.sections'); + createSections(this, this.sectionsContainer, this.apiClient); + } - for (var i = 0, length = elems.length; i < length; i++) { - promises.push(elems[i].resume(options)); + onResume(options) { + const promises = (this.apiClient, []); + const view = this.view; + const elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); + + for (const elem of elems) { + promises.push(elem.resume(options)); } Promise.all(promises).then(function () { @@ -282,30 +290,32 @@ define(['appRouter', 'cardBuilder', 'dom', 'globalize', 'connectionManager', 'ap focusManager.autoFocus(view); } }); - }; + } - FavoritesTab.prototype.onPause = function () { - var elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); + onPause() { + const elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); - for (var i = 0, length = elems.length; i < length; i++) { - elems[i].pause(); + for (const elem of elems) { + elem.pause(); } - }; + } - FavoritesTab.prototype.destroy = function () { + destroy() { this.view = null; this.params = null; this.apiClient = null; - var elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); + const elems = this.sectionsContainer.querySelectorAll('.itemsContainer'); - for (var i = 0, length = elems.length; i < length; i++) { - elems[i].fetchData = null; - elems[i].getItemsHtml = null; - elems[i].parentContainer = null; + for (const elem of elems) { + elem.fetchData = null; + elem.getItemsHtml = null; + elem.parentContainer = null; } this.sectionsContainer = null; - }; + } +} - return FavoritesTab; -}); +export default FavoritesTab; + +/* eslint-enable indent */ diff --git a/src/controllers/home.js b/src/controllers/home.js index 9a4cea2227..ea3fef3ce2 100644 --- a/src/controllers/home.js +++ b/src/controllers/home.js @@ -40,7 +40,7 @@ define(['tabbedView', 'globalize', 'require', 'emby-tabs', 'emby-button', 'emby- var controller = instance.tabControllers[index]; if (!controller) { - controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params); + controller = new controllerFactory.default(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params); instance.tabControllers[index] = controller; } diff --git a/src/controllers/hometab.js b/src/controllers/hometab.js index 8e2a1f92e7..4b7ddee057 100644 --- a/src/controllers/hometab.js +++ b/src/controllers/hometab.js @@ -1,27 +1,23 @@ -define(['userSettings', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'focusManager', 'homeSections', 'emby-itemscontainer'], function (userSettings, loading, connectionManager, appHost, layoutManager, focusManager, homeSections) { - 'use strict'; +import * as userSettings from 'userSettings'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; +import appHost from 'apphost'; +import layoutManager from 'layoutManager'; +import focusManager from 'focusManager'; +import homeSections from 'homeSections'; +import 'emby-itemscontainer'; - function HomeTab(view, params) { +class HomeTab { + constructor(view, params) { this.view = view; this.params = params; this.apiClient = connectionManager.currentApiClient(); this.sectionsContainer = view.querySelector('.sections'); view.querySelector('.sections').addEventListener('settingschange', onHomeScreenSettingsChanged.bind(this)); } - - function onHomeScreenSettingsChanged() { - this.sectionsRendered = false; - - if (!this.paused) { - this.onResume({ - refresh: true - }); - } - } - - HomeTab.prototype.onResume = function (options) { + onResume(options) { if (this.sectionsRendered) { - var sectionsContainer = this.sectionsContainer; + const sectionsContainer = this.sectionsContainer; if (sectionsContainer) { return homeSections.resume(sectionsContainer, options); @@ -31,8 +27,8 @@ define(['userSettings', 'loading', 'connectionManager', 'apphost', 'layoutManage } loading.show(); - var view = this.view; - var apiClient = this.apiClient; + const view = this.view; + const apiClient = this.apiClient; this.destroyHomeSections(); this.sectionsRendered = true; return apiClient.getCurrentUser().then(function (user) { @@ -44,31 +40,38 @@ define(['userSettings', 'loading', 'connectionManager', 'apphost', 'layoutManage loading.hide(); }); }); - }; - - HomeTab.prototype.onPause = function () { - var sectionsContainer = this.sectionsContainer; + } + onPause() { + const sectionsContainer = this.sectionsContainer; if (sectionsContainer) { homeSections.pause(sectionsContainer); } - }; - - HomeTab.prototype.destroy = function () { + } + destroy() { this.view = null; this.params = null; this.apiClient = null; this.destroyHomeSections(); this.sectionsContainer = null; - }; - - HomeTab.prototype.destroyHomeSections = function () { - var sectionsContainer = this.sectionsContainer; + } + destroyHomeSections() { + const sectionsContainer = this.sectionsContainer; if (sectionsContainer) { homeSections.destroySections(sectionsContainer); } - }; + } +} - return HomeTab; -}); +function onHomeScreenSettingsChanged() { + this.sectionsRendered = false; + + if (!this.paused) { + this.onResume({ + refresh: true + }); + } +} + +export default HomeTab; From 0bf23576ee9b95176390ea1b3ba3f6d4c36715c7 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Sun, 26 Jul 2020 15:00:09 +0300 Subject: [PATCH 008/226] Extract styles --- .../subtitlesettings/subtitlesettings.css | 26 +++++++++++++++++ .../subtitlesettings/subtitlesettings.js | 1 + .../subtitlesettings.template.html | 29 ------------------- 3 files changed, 27 insertions(+), 29 deletions(-) create mode 100644 src/components/subtitlesettings/subtitlesettings.css diff --git a/src/components/subtitlesettings/subtitlesettings.css b/src/components/subtitlesettings/subtitlesettings.css new file mode 100644 index 0000000000..e8cb9a50b5 --- /dev/null +++ b/src/components/subtitlesettings/subtitlesettings.css @@ -0,0 +1,26 @@ +.subtitleappearance-fullpreview { + position: fixed; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 1000; + pointer-events: none; + transition: 0.2s +} + +.subtitleappearance-fullpreview-hide { + opacity: 0; +} + +.subtitleappearance-fullpreview-window { + position: absolute; + width: 100%; + font-size: 170%; + text-align: center; +} + +.subtitleappearance-fullpreview-text { + display: inline-block; + max-width: 70%; +} diff --git a/src/components/subtitlesettings/subtitlesettings.js b/src/components/subtitlesettings/subtitlesettings.js index 07d83d86ea..f7e37c8212 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -16,6 +16,7 @@ import 'emby-slider'; import 'emby-input'; import 'emby-checkbox'; import 'flexStyles'; +import 'css!./subtitlesettings' /** * Subtitle settings. diff --git a/src/components/subtitlesettings/subtitlesettings.template.html b/src/components/subtitlesettings/subtitlesettings.template.html index 2f49fa4c3e..af9139188c 100644 --- a/src/components/subtitlesettings/subtitlesettings.template.html +++ b/src/components/subtitlesettings/subtitlesettings.template.html @@ -38,35 +38,6 @@ ${HeaderSubtitleAppearance} - -
From 3339315b9cbdca0cd19a37c345d4e5de6f9a84e0 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Sun, 26 Jul 2020 18:12:10 +0300 Subject: [PATCH 009/226] Add missing semicolon (Lint) --- src/components/subtitlesettings/subtitlesettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/subtitlesettings/subtitlesettings.js b/src/components/subtitlesettings/subtitlesettings.js index f7e37c8212..68defc656a 100644 --- a/src/components/subtitlesettings/subtitlesettings.js +++ b/src/components/subtitlesettings/subtitlesettings.js @@ -16,7 +16,7 @@ import 'emby-slider'; import 'emby-input'; import 'emby-checkbox'; import 'flexStyles'; -import 'css!./subtitlesettings' +import 'css!./subtitlesettings'; /** * Subtitle settings. From 270b717cd032e0d6ca4700d45813cba7479841d0 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Sun, 26 Jul 2020 19:25:58 +0300 Subject: [PATCH 010/226] Add missing semicolon (Lint) --- src/components/subtitlesettings/subtitlesettings.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/subtitlesettings/subtitlesettings.css b/src/components/subtitlesettings/subtitlesettings.css index e8cb9a50b5..204757f10f 100644 --- a/src/components/subtitlesettings/subtitlesettings.css +++ b/src/components/subtitlesettings/subtitlesettings.css @@ -6,7 +6,7 @@ left: 0; z-index: 1000; pointer-events: none; - transition: 0.2s + transition: 0.2s; } .subtitleappearance-fullpreview-hide { From 8fb8dacdf1bca533c4021dc9adff35cfd98b9aea Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 26 Jul 2020 22:45:00 +0200 Subject: [PATCH 011/226] Migrate shell, serverNotifications to ES6 + remove searchtab --- package.json | 2 + src/assets/css/librarybrowser.css | 6 - src/components/guide/guide.js | 2 + src/components/itemsrefresher.js | 2 + src/components/notifications/notifications.js | 2 + src/components/playback/playbackmanager.js | 1 + .../recordingcreator/recordingfields.js | 2 + src/controllers/livetv/livetvsuggested.js | 6 - src/controllers/movies/moviesrecommended.js | 6 - src/controllers/music/musicrecommended.js | 6 - src/controllers/shows/tvrecommended.js | 7 - src/plugins/sessionPlayer/plugin.js | 2 + src/scripts/searchtab.js | 57 --- src/scripts/serverNotifications.js | 407 +++++++++--------- src/scripts/shell.js | 43 +- 15 files changed, 239 insertions(+), 312 deletions(-) delete mode 100644 src/scripts/searchtab.js diff --git a/package.json b/package.json index d1831b13ee..12ed63929a 100644 --- a/package.json +++ b/package.json @@ -250,9 +250,11 @@ "src/scripts/inputManager.js", "src/scripts/keyboardNavigation.js", "src/scripts/playlists.js", + "src/scripts/serverNotifications.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", "src/scripts/settings/webSettings.js", + "src/scripts/shell.js", "src/scripts/taskbutton.js", "src/scripts/themeLoader.js", "src/scripts/touchHelper.js" diff --git a/src/assets/css/librarybrowser.css b/src/assets/css/librarybrowser.css index 61815a590f..644dba9371 100644 --- a/src/assets/css/librarybrowser.css +++ b/src/assets/css/librarybrowser.css @@ -236,12 +236,6 @@ text-align: center; } -.layout-desktop .searchTabButton, -.layout-mobile .searchTabButton, -.layout-tv .headerSearchButton { - display: none !important; -} - .mainDrawer-scrollContainer { padding-bottom: 10vh; } diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index bb4a36497c..e18f053a5a 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -1,6 +1,8 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'webcomponents'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) { 'use strict'; + serverNotifications = serverNotifications.default || serverNotifications; + function showViewSettings(instance) { require(['guide-settings-dialog'], function (guideSettingsDialog) { diff --git a/src/components/itemsrefresher.js b/src/components/itemsrefresher.js index 6da74eef80..f50813a7e0 100644 --- a/src/components/itemsrefresher.js +++ b/src/components/itemsrefresher.js @@ -1,6 +1,8 @@ define(['playbackManager', 'serverNotifications', 'events'], function (playbackManager, serverNotifications, events) { 'use strict'; + serverNotifications = serverNotifications.default || serverNotifications; + function onUserDataChanged(e, apiClient, userData) { var instance = this; diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index c8480e4f15..d12b14cc01 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -1,6 +1,8 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'require'], function (serverNotifications, playbackManager, events, globalize, require) { 'use strict'; + serverNotifications = serverNotifications.default || serverNotifications; + function onOneDocumentClick() { document.removeEventListener('click', onOneDocumentClick); document.removeEventListener('keydown', onOneDocumentClick); diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index fe3ff11250..a6fc3942be 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3455,6 +3455,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (apphost.supports('remotecontrol')) { require(['serverNotifications'], function (serverNotifications) { + serverNotifications = serverNotifications.default || serverNotifications; events.on(serverNotifications, 'ServerShuttingDown', self.setDefaultPlayerActive.bind(self)); events.on(serverNotifications, 'ServerRestarting', self.setDefaultPlayerActive.bind(self)); }); diff --git a/src/components/recordingcreator/recordingfields.js b/src/components/recordingcreator/recordingfields.js index 84348fcfbc..5fc0f24af4 100644 --- a/src/components/recordingcreator/recordingfields.js +++ b/src/components/recordingcreator/recordingfields.js @@ -1,6 +1,8 @@ define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loading', 'apphost', 'dom', 'recordingHelper', 'events', 'paper-icon-button-light', 'emby-button', 'css!./recordingfields', 'flexStyles'], function (globalize, connectionManager, serverNotifications, require, loading, appHost, dom, recordingHelper, events) { 'use strict'; + serverNotifications = serverNotifications.default || serverNotifications; + function loadData(parent, program, apiClient) { if (program.IsSeries) { parent.querySelector('.recordSeriesContainer').classList.remove('hide'); diff --git a/src/controllers/livetv/livetvsuggested.js b/src/controllers/livetv/livetvsuggested.js index 036eee9fc6..16cee8a496 100644 --- a/src/controllers/livetv/livetvsuggested.js +++ b/src/controllers/livetv/livetvsuggested.js @@ -167,9 +167,6 @@ define(['layoutManager', 'userSettings', 'inputManager', 'loading', 'globalize', name: globalize.translate('HeaderSchedule') }, { name: globalize.translate('TabSeries') - }, { - name: globalize.translate('ButtonSearch'), - cssClass: 'searchTabButton' }]; } @@ -253,9 +250,6 @@ define(['layoutManager', 'userSettings', 'inputManager', 'loading', 'globalize', case 5: depends.push('controllers/livetv/livetvseriestimers'); break; - - case 6: - depends.push('scripts/searchtab'); } require(depends, function (controllerFactory) { diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js index d948c1cef7..11aa6e3fec 100644 --- a/src/controllers/movies/moviesrecommended.js +++ b/src/controllers/movies/moviesrecommended.js @@ -222,9 +222,6 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu' name: globalize.translate('TabCollections') }, { name: globalize.translate('TabGenres') - }, { - name: globalize.translate('ButtonSearch'), - cssClass: 'searchTabButton' }]; } @@ -291,9 +288,6 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu' case 5: depends.push('controllers/movies/moviegenres'); break; - - case 6: - depends.push('scripts/searchtab'); } require(depends, function (controllerFactory) { diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js index 3f025799f6..1409d6de3f 100644 --- a/src/controllers/music/musicrecommended.js +++ b/src/controllers/music/musicrecommended.js @@ -180,9 +180,6 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' name: globalize.translate('TabSongs') }, { name: globalize.translate('TabGenres') - }, { - name: globalize.translate('ButtonSearch'), - cssClass: 'searchTabButton' }]; } @@ -283,9 +280,6 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' case 6: depends.push('controllers/music/musicgenres'); break; - - case 7: - depends.push('scripts/searchtab'); } require(depends, function (controllerFactory) { diff --git a/src/controllers/shows/tvrecommended.js b/src/controllers/shows/tvrecommended.js index 7edd2ab501..25459b7b6a 100644 --- a/src/controllers/shows/tvrecommended.js +++ b/src/controllers/shows/tvrecommended.js @@ -30,9 +30,6 @@ import 'emby-button'; name: globalize.translate('TabNetworks') }, { name: globalize.translate('TabEpisodes') - }, { - name: globalize.translate('ButtonSearch'), - cssClass: 'searchTabButton' }]; } @@ -217,10 +214,6 @@ import 'emby-button'; case 6: depends = 'controllers/shows/episodes'; break; - - case 7: - depends = 'scripts/searchtab'; - break; } import(depends).then(({default: controllerFactory}) => { diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index 084aa027cf..a8cb1e3579 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -1,6 +1,8 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'], function (playbackManager, events, serverNotifications, connectionManager) { 'use strict'; + serverNotifications = serverNotifications.default || serverNotifications; + function getActivePlayerId() { var info = playbackManager.getPlayerInfo(); return info ? info.id : null; diff --git a/src/scripts/searchtab.js b/src/scripts/searchtab.js deleted file mode 100644 index e012b8a4b2..0000000000 --- a/src/scripts/searchtab.js +++ /dev/null @@ -1,57 +0,0 @@ -define(['searchFields', 'searchResults', 'events'], function (SearchFields, SearchResults, events) { - 'use strict'; - - SearchFields = SearchFields.default || SearchFields; - SearchResults = SearchResults.default || SearchResults; - - function init(instance, tabContent, options) { - tabContent.innerHTML = '
'; - instance.searchFields = new SearchFields({ - element: tabContent.querySelector('.searchFields') - }); - instance.searchResults = new SearchResults({ - element: tabContent.querySelector('.searchResults'), - serverId: ApiClient.serverId(), - parentId: options.parentId, - collectionType: options.collectionType - }); - events.on(instance.searchFields, 'search', function (e, value) { - instance.searchResults.search(value); - }); - } - - function SearchTab(view, tabContent, options) { - var self = this; - options = options || {}; - init(this, tabContent, options); - - self.preRender = function () {}; - - self.renderTab = function () { - var searchFields = this.searchFields; - - if (searchFields) { - searchFields.focus(); - } - }; - } - - SearchTab.prototype.destroy = function () { - var searchFields = this.searchFields; - - if (searchFields) { - searchFields.destroy(); - } - - this.searchFields = null; - var searchResults = this.searchResults; - - if (searchResults) { - searchResults.destroy(); - } - - this.searchResults = null; - }; - - return SearchTab; -}); diff --git a/src/scripts/serverNotifications.js b/src/scripts/serverNotifications.js index 331a75329c..83af40c4e6 100644 --- a/src/scripts/serverNotifications.js +++ b/src/scripts/serverNotifications.js @@ -1,211 +1,216 @@ -define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'inputManager', 'focusManager', 'appRouter'], function (connectionManager, playbackManager, syncPlayManager, events, inputManager, focusManager, appRouter) { - 'use strict'; +import connectionManager from 'connectionManager'; +import playbackManager from 'playbackManager'; +import syncPlayManager from 'syncPlayManager'; +import events from 'events'; +import inputManager from 'inputManager'; +import focusManager from 'focusManager'; +import appRouter from 'appRouter'; - var serverNotifications = {}; +const serverNotifications = {}; - function notifyApp() { - inputManager.notify(); - } +function notifyApp() { + inputManager.notify(); +} - function displayMessage(cmd) { - var args = cmd.Arguments; - if (args.TimeoutMs) { - require(['toast'], function (toast) { - toast({ title: args.Header, text: args.Text }); - }); - } else { - require(['alert'], function (alert) { - alert.default({ title: args.Header, text: args.Text }); - }); - } - } - - function displayContent(cmd, apiClient) { - if (!playbackManager.isPlayingLocally(['Video', 'Book'])) { - appRouter.showItem(cmd.Arguments.ItemId, apiClient.serverId()); - } - } - - function playTrailers(apiClient, itemId) { - apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) { - playbackManager.playTrailers(item); +function displayMessage(cmd) { + const args = cmd.Arguments; + if (args.TimeoutMs) { + require(['toast'], function (toast) { + toast({ title: args.Header, text: args.Text }); + }); + } else { + require(['alert'], function (alert) { + alert.default({ title: args.Header, text: args.Text }); }); } +} - function processGeneralCommand(cmd, apiClient) { - console.debug('Received command: ' + cmd.Name); - switch (cmd.Name) { - case 'Select': - inputManager.handleCommand('select'); - return; - case 'Back': - inputManager.handleCommand('back'); - return; - case 'MoveUp': - inputManager.handleCommand('up'); - return; - case 'MoveDown': - inputManager.handleCommand('down'); - return; - case 'MoveLeft': - inputManager.handleCommand('left'); - return; - case 'MoveRight': - inputManager.handleCommand('right'); - return; - case 'PageUp': - inputManager.handleCommand('pageup'); - return; - case 'PageDown': - inputManager.handleCommand('pagedown'); - return; - case 'PlayTrailers': - playTrailers(apiClient, cmd.Arguments.ItemId); - break; - case 'SetRepeatMode': - playbackManager.setRepeatMode(cmd.Arguments.RepeatMode); - break; - case 'SetShuffleQueue': - playbackManager.setQueueShuffleMode(cmd.Arguments.ShuffleMode); - break; - case 'VolumeUp': - inputManager.handleCommand('volumeup'); - return; - case 'VolumeDown': - inputManager.handleCommand('volumedown'); - return; - case 'ChannelUp': - inputManager.handleCommand('channelup'); - return; - case 'ChannelDown': - inputManager.handleCommand('channeldown'); - return; - case 'Mute': - inputManager.handleCommand('mute'); - return; - case 'Unmute': - inputManager.handleCommand('unmute'); - return; - case 'ToggleMute': - inputManager.handleCommand('togglemute'); - return; - case 'SetVolume': - notifyApp(); - playbackManager.setVolume(cmd.Arguments.Volume); - break; - case 'SetAudioStreamIndex': - notifyApp(); - playbackManager.setAudioStreamIndex(parseInt(cmd.Arguments.Index)); - break; - case 'SetSubtitleStreamIndex': - notifyApp(); - playbackManager.setSubtitleStreamIndex(parseInt(cmd.Arguments.Index)); - break; - case 'ToggleFullscreen': - inputManager.handleCommand('togglefullscreen'); - return; - case 'GoHome': - inputManager.handleCommand('home'); - return; - case 'GoToSettings': - inputManager.handleCommand('settings'); - return; - case 'DisplayContent': - displayContent(cmd, apiClient); - break; - case 'GoToSearch': - inputManager.handleCommand('search'); - return; - case 'DisplayMessage': - displayMessage(cmd); - break; - case 'ToggleOsd': - // todo - break; - case 'ToggleContextMenu': - // todo - break; - case 'TakeScreenShot': - // todo - break; - case 'SendKey': - // todo - break; - case 'SendString': - // todo - focusManager.sendText(cmd.Arguments.String); - break; - default: - console.debug('processGeneralCommand does not recognize: ' + cmd.Name); - break; - } - - notifyApp(); +function displayContent(cmd, apiClient) { + if (!playbackManager.isPlayingLocally(['Video', 'Book'])) { + appRouter.showItem(cmd.Arguments.ItemId, apiClient.serverId()); } +} - function onMessageReceived(e, msg) { - var apiClient = this; - if (msg.MessageType === 'Play') { - notifyApp(); - var serverId = apiClient.serverInfo().Id; - if (msg.Data.PlayCommand === 'PlayNext') { - playbackManager.queueNext({ ids: msg.Data.ItemIds, serverId: serverId }); - } else if (msg.Data.PlayCommand === 'PlayLast') { - playbackManager.queue({ ids: msg.Data.ItemIds, serverId: serverId }); - } else { - playbackManager.play({ - ids: msg.Data.ItemIds, - startPositionTicks: msg.Data.StartPositionTicks, - mediaSourceId: msg.Data.MediaSourceId, - audioStreamIndex: msg.Data.AudioStreamIndex, - subtitleStreamIndex: msg.Data.SubtitleStreamIndex, - startIndex: msg.Data.StartIndex, - serverId: serverId - }); - } - } else if (msg.MessageType === 'Playstate') { - if (msg.Data.Command === 'Stop') { - inputManager.handleCommand('stop'); - } else if (msg.Data.Command === 'Pause') { - inputManager.handleCommand('pause'); - } else if (msg.Data.Command === 'Unpause') { - inputManager.handleCommand('play'); - } else if (msg.Data.Command === 'PlayPause') { - inputManager.handleCommand('playpause'); - } else if (msg.Data.Command === 'Seek') { - playbackManager.seek(msg.Data.SeekPositionTicks); - } else if (msg.Data.Command === 'NextTrack') { - inputManager.handleCommand('next'); - } else if (msg.Data.Command === 'PreviousTrack') { - inputManager.handleCommand('previous'); - } else { - notifyApp(); - } - } else if (msg.MessageType === 'GeneralCommand') { - var cmd = msg.Data; - processGeneralCommand(cmd, apiClient); - } else if (msg.MessageType === 'UserDataChanged') { - if (msg.Data.UserId === apiClient.getCurrentUserId()) { - for (var i = 0, length = msg.Data.UserDataList.length; i < length; i++) { - events.trigger(serverNotifications, 'UserDataChanged', [apiClient, msg.Data.UserDataList[i]]); - } - } - } else if (msg.MessageType === 'SyncPlayCommand') { - syncPlayManager.processCommand(msg.Data, apiClient); - } else if (msg.MessageType === 'SyncPlayGroupUpdate') { - syncPlayManager.processGroupUpdate(msg.Data, apiClient); - } else { - events.trigger(serverNotifications, msg.MessageType, [apiClient, msg.Data]); - } - } - function bindEvents(apiClient) { - events.off(apiClient, 'message', onMessageReceived); - events.on(apiClient, 'message', onMessageReceived); - } - - connectionManager.getApiClients().forEach(bindEvents); - events.on(connectionManager, 'apiclientcreated', function (e, newApiClient) { - bindEvents(newApiClient); +function playTrailers(apiClient, itemId) { + apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) { + playbackManager.playTrailers(item); }); - return serverNotifications; +} + +function processGeneralCommand(cmd, apiClient) { + console.debug('Received command: ' + cmd.Name); + switch (cmd.Name) { + case 'Select': + inputManager.handleCommand('select'); + return; + case 'Back': + inputManager.handleCommand('back'); + return; + case 'MoveUp': + inputManager.handleCommand('up'); + return; + case 'MoveDown': + inputManager.handleCommand('down'); + return; + case 'MoveLeft': + inputManager.handleCommand('left'); + return; + case 'MoveRight': + inputManager.handleCommand('right'); + return; + case 'PageUp': + inputManager.handleCommand('pageup'); + return; + case 'PageDown': + inputManager.handleCommand('pagedown'); + return; + case 'PlayTrailers': + playTrailers(apiClient, cmd.Arguments.ItemId); + break; + case 'SetRepeatMode': + playbackManager.setRepeatMode(cmd.Arguments.RepeatMode); + break; + case 'SetShuffleQueue': + playbackManager.setQueueShuffleMode(cmd.Arguments.ShuffleMode); + break; + case 'VolumeUp': + inputManager.handleCommand('volumeup'); + return; + case 'VolumeDown': + inputManager.handleCommand('volumedown'); + return; + case 'ChannelUp': + inputManager.handleCommand('channelup'); + return; + case 'ChannelDown': + inputManager.handleCommand('channeldown'); + return; + case 'Mute': + inputManager.handleCommand('mute'); + return; + case 'Unmute': + inputManager.handleCommand('unmute'); + return; + case 'ToggleMute': + inputManager.handleCommand('togglemute'); + return; + case 'SetVolume': + notifyApp(); + playbackManager.setVolume(cmd.Arguments.Volume); + break; + case 'SetAudioStreamIndex': + notifyApp(); + playbackManager.setAudioStreamIndex(parseInt(cmd.Arguments.Index)); + break; + case 'SetSubtitleStreamIndex': + notifyApp(); + playbackManager.setSubtitleStreamIndex(parseInt(cmd.Arguments.Index)); + break; + case 'ToggleFullscreen': + inputManager.handleCommand('togglefullscreen'); + return; + case 'GoHome': + inputManager.handleCommand('home'); + return; + case 'GoToSettings': + inputManager.handleCommand('settings'); + return; + case 'DisplayContent': + displayContent(cmd, apiClient); + break; + case 'GoToSearch': + inputManager.handleCommand('search'); + return; + case 'DisplayMessage': + displayMessage(cmd); + break; + case 'ToggleOsd': + // todo + break; + case 'ToggleContextMenu': + // todo + break; + case 'TakeScreenShot': + // todo + break; + case 'SendKey': + // todo + break; + case 'SendString': + // todo + focusManager.sendText(cmd.Arguments.String); + break; + default: + console.debug('processGeneralCommand does not recognize: ' + cmd.Name); + break; + } + + notifyApp(); +} + +function onMessageReceived(e, msg) { + const apiClient = this; + if (msg.MessageType === 'Play') { + notifyApp(); + const serverId = apiClient.serverInfo().Id; + if (msg.Data.PlayCommand === 'PlayNext') { + playbackManager.queueNext({ ids: msg.Data.ItemIds, serverId: serverId }); + } else if (msg.Data.PlayCommand === 'PlayLast') { + playbackManager.queue({ ids: msg.Data.ItemIds, serverId: serverId }); + } else { + playbackManager.play({ + ids: msg.Data.ItemIds, + startPositionTicks: msg.Data.StartPositionTicks, + mediaSourceId: msg.Data.MediaSourceId, + audioStreamIndex: msg.Data.AudioStreamIndex, + subtitleStreamIndex: msg.Data.SubtitleStreamIndex, + startIndex: msg.Data.StartIndex, + serverId: serverId + }); + } + } else if (msg.MessageType === 'Playstate') { + if (msg.Data.Command === 'Stop') { + inputManager.handleCommand('stop'); + } else if (msg.Data.Command === 'Pause') { + inputManager.handleCommand('pause'); + } else if (msg.Data.Command === 'Unpause') { + inputManager.handleCommand('play'); + } else if (msg.Data.Command === 'PlayPause') { + inputManager.handleCommand('playpause'); + } else if (msg.Data.Command === 'Seek') { + playbackManager.seek(msg.Data.SeekPositionTicks); + } else if (msg.Data.Command === 'NextTrack') { + inputManager.handleCommand('next'); + } else if (msg.Data.Command === 'PreviousTrack') { + inputManager.handleCommand('previous'); + } else { + notifyApp(); + } + } else if (msg.MessageType === 'GeneralCommand') { + const cmd = msg.Data; + processGeneralCommand(cmd, apiClient); + } else if (msg.MessageType === 'UserDataChanged') { + if (msg.Data.UserId === apiClient.getCurrentUserId()) { + for (let i = 0, length = msg.Data.UserDataList.length; i < length; i++) { + events.trigger(serverNotifications, 'UserDataChanged', [apiClient, msg.Data.UserDataList[i]]); + } + } + } else if (msg.MessageType === 'SyncPlayCommand') { + syncPlayManager.processCommand(msg.Data, apiClient); + } else if (msg.MessageType === 'SyncPlayGroupUpdate') { + syncPlayManager.processGroupUpdate(msg.Data, apiClient); + } else { + events.trigger(serverNotifications, msg.MessageType, [apiClient, msg.Data]); + } +} +function bindEvents(apiClient) { + events.off(apiClient, 'message', onMessageReceived); + events.on(apiClient, 'message', onMessageReceived); +} + +connectionManager.getApiClients().forEach(bindEvents); +events.on(connectionManager, 'apiclientcreated', function (e, newApiClient) { + bindEvents(newApiClient); }); + +export default serverNotifications; diff --git a/src/scripts/shell.js b/src/scripts/shell.js index 4f1aa0c8de..390ddae82c 100644 --- a/src/scripts/shell.js +++ b/src/scripts/shell.js @@ -1,24 +1,21 @@ -define([], function () { - 'use strict'; - - return { - openUrl: function (url, target) { - if (window.NativeShell) { - window.NativeShell.openUrl(url, target); - } else { - window.open(url, target || '_blank'); - } - - }, - enableFullscreen: function () { - if (window.NativeShell) { - window.NativeShell.enableFullscreen(); - } - }, - disableFullscreen: function () { - if (window.NativeShell) { - window.NativeShell.disableFullscreen(); - } +// TODO: This seems like a good candidate for deprecation +export default { + openUrl: function (url, target) { + if (window.NativeShell) { + window.NativeShell.openUrl(url, target); + } else { + window.open(url, target || '_blank'); } - }; -}); + + }, + enableFullscreen: function () { + if (window.NativeShell) { + window.NativeShell.enableFullscreen(); + } + }, + disableFullscreen: function () { + if (window.NativeShell) { + window.NativeShell.disableFullscreen(); + } + } +}; From 4fce7f8be5076cb8cc05546c6ef0b33ebee6f14e Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sun, 26 Jul 2020 22:52:55 +0200 Subject: [PATCH 012/226] Migrate scrollHelper to ES6 --- package.json | 1 + .../collectionEditor/collectionEditor.js | 2 +- src/components/dialogHelper/dialogHelper.js | 2 +- src/components/filtermenu/filtermenu.js | 1 + src/components/guide/guide-settings.js | 2 + src/components/guide/guide.js | 2 + .../imageDownloader/imageDownloader.js | 2 + src/components/imageeditor/imageeditor.js | 2 + .../playlisteditor/playlisteditor.js | 2 +- .../recordingcreator/recordingcreator.js | 2 + .../recordingcreator/recordingeditor.js | 2 + .../recordingcreator/seriesrecordingeditor.js | 2 + src/components/refreshdialog/refreshdialog.js | 1 + src/components/sortmenu/sortmenu.js | 1 + .../subtitleeditor/subtitleeditor.js | 1 + src/components/tunerPicker.js | 2 + src/components/viewSettings/viewSettings.js | 1 + src/scripts/scrollHelper.js | 250 +++++++++--------- 18 files changed, 150 insertions(+), 128 deletions(-) diff --git a/package.json b/package.json index 12ed63929a..7a80b89140 100644 --- a/package.json +++ b/package.json @@ -250,6 +250,7 @@ "src/scripts/inputManager.js", "src/scripts/keyboardNavigation.js", "src/scripts/playlists.js", + "src/scripts/scrollHelper.js", "src/scripts/serverNotifications.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", diff --git a/src/components/collectionEditor/collectionEditor.js b/src/components/collectionEditor/collectionEditor.js index 18cc0d311f..67daad9f2e 100644 --- a/src/components/collectionEditor/collectionEditor.js +++ b/src/components/collectionEditor/collectionEditor.js @@ -212,7 +212,7 @@ import 'flexStyles'; } function centerFocus(elem, horiz, on) { - import('scrollHelper').then(scrollHelper => { + import('scrollHelper').then((scrollHelper) => { const fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/dialogHelper/dialogHelper.js b/src/components/dialogHelper/dialogHelper.js index ca7c94a416..af1a278cb4 100644 --- a/src/components/dialogHelper/dialogHelper.js +++ b/src/components/dialogHelper/dialogHelper.js @@ -376,7 +376,7 @@ import 'scrollStyles'; } function centerFocus(elem, horiz, on) { - import('scrollHelper').then(scrollHelper => { + import('scrollHelper').then((scrollHelper) => { const fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/filtermenu/filtermenu.js b/src/components/filtermenu/filtermenu.js index 936e2b0407..075af143d2 100644 --- a/src/components/filtermenu/filtermenu.js +++ b/src/components/filtermenu/filtermenu.js @@ -194,6 +194,7 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', function centerFocus(elem, horiz, on) { require(['scrollHelper'], function (scrollHelper) { + scrollHelper = scrollHelper.default || scrollHelper; var fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/guide/guide-settings.js b/src/components/guide/guide-settings.js index 77a3637251..aded7ac5dd 100644 --- a/src/components/guide/guide-settings.js +++ b/src/components/guide/guide-settings.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'globalize', 'userSettings', 'layoutManager', 'connectionManager', 'require', 'loading', 'scrollHelper', 'emby-checkbox', 'emby-radio', 'css!./../formdialog', 'material-icons'], function (dialogHelper, globalize, userSettings, layoutManager, connectionManager, require, loading, scrollHelper) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + function saveCategories(context, options) { var categories = []; diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index e18f053a5a..0d3c721e2d 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -1,6 +1,8 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'webcomponents'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + serverNotifications = serverNotifications.default || serverNotifications; function showViewSettings(instance) { diff --git a/src/components/imageDownloader/imageDownloader.js b/src/components/imageDownloader/imageDownloader.js index fbe98c532f..9ad65dd157 100644 --- a/src/components/imageDownloader/imageDownloader.js +++ b/src/components/imageDownloader/imageDownloader.js @@ -1,6 +1,8 @@ define(['dom', 'loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader', 'browser', 'layoutManager', 'scrollHelper', 'globalize', 'require', 'emby-checkbox', 'paper-icon-button-light', 'emby-button', 'formDialogStyle', 'cardStyle'], function (dom, loading, appHost, dialogHelper, connectionManager, imageLoader, browser, layoutManager, scrollHelper, globalize, require) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var enableFocusTransform = !browser.slow && !browser.edge; var currentItemId; diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index 0a873fa4c7..766304f9aa 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', 'focusManager', 'globalize', 'scrollHelper', 'imageLoader', 'require', 'browser', 'apphost', 'cardStyle', 'formDialogStyle', 'emby-button', 'paper-icon-button-light', 'css!./imageeditor'], function (dialogHelper, connectionManager, loading, dom, layoutManager, focusManager, globalize, scrollHelper, imageLoader, require, browser, appHost) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var enableFocusTransform = !browser.slow && !browser.edge; var currentItem; diff --git a/src/components/playlisteditor/playlisteditor.js b/src/components/playlisteditor/playlisteditor.js index 7b1e915e1f..78f0cf3dec 100644 --- a/src/components/playlisteditor/playlisteditor.js +++ b/src/components/playlisteditor/playlisteditor.js @@ -210,7 +210,7 @@ import 'emby-button'; } function centerFocus(elem, horiz, on) { - import('scrollHelper').then(scrollHelper => { + import('scrollHelper').then((scrollHelper) => { const fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/recordingcreator/recordingcreator.js b/src/components/recordingcreator/recordingcreator.js index d18d5fcb6c..3b7cbe49aa 100644 --- a/src/components/recordingcreator/recordingcreator.js +++ b/src/components/recordingcreator/recordingcreator.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'datetime', 'imageLoader', 'recordingFields', 'events', 'emby-checkbox', 'emby-button', 'emby-collapse', 'emby-input', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper, datetime, imageLoader, recordingFields, events) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var currentDialog; var closeAction; var currentRecordingFields; diff --git a/src/components/recordingcreator/recordingeditor.js b/src/components/recordingcreator/recordingeditor.js index c3f40fcddb..2fde735404 100644 --- a/src/components/recordingcreator/recordingeditor.js +++ b/src/components/recordingcreator/recordingeditor.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'imageLoader', 'scrollStyles', 'emby-button', 'emby-collapse', 'emby-input', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons', 'flexStyles'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper, imageLoader) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var currentDialog; var recordingDeleted = false; var currentItemId; diff --git a/src/components/recordingcreator/seriesrecordingeditor.js b/src/components/recordingcreator/seriesrecordingeditor.js index a101ce53ec..053dd1a12c 100644 --- a/src/components/recordingcreator/seriesrecordingeditor.js +++ b/src/components/recordingcreator/seriesrecordingeditor.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'imageLoader', 'datetime', 'scrollStyles', 'emby-button', 'emby-checkbox', 'emby-input', 'emby-select', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons', 'flexStyles'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper, imageLoader, datetime) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var currentDialog; var recordingUpdated = false; var recordingDeleted = false; diff --git a/src/components/refreshdialog/refreshdialog.js b/src/components/refreshdialog/refreshdialog.js index 3edb725c4a..593cc0dc2d 100644 --- a/src/components/refreshdialog/refreshdialog.js +++ b/src/components/refreshdialog/refreshdialog.js @@ -42,6 +42,7 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionM function centerFocus(elem, horiz, on) { require(['scrollHelper'], function (scrollHelper) { + scrollHelper = scrollHelper.default || scrollHelper; var fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/sortmenu/sortmenu.js b/src/components/sortmenu/sortmenu.js index dbf7ef1a7f..abe55a6092 100644 --- a/src/components/sortmenu/sortmenu.js +++ b/src/components/sortmenu/sortmenu.js @@ -17,6 +17,7 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana function centerFocus(elem, horiz, on) { require(['scrollHelper'], function (scrollHelper) { + scrollHelper = scrollHelper.default || scrollHelper; var fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js index 9c0992c53c..4c33252574 100644 --- a/src/components/subtitleeditor/subtitleeditor.js +++ b/src/components/subtitleeditor/subtitleeditor.js @@ -420,6 +420,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', function centerFocus(elem, horiz, on) { require(['scrollHelper'], function (scrollHelper) { + scrollHelper = scrollHelper.default || scrollHelper; var fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/components/tunerPicker.js b/src/components/tunerPicker.js index e7c92851a4..f064f95152 100644 --- a/src/components/tunerPicker.js +++ b/src/components/tunerPicker.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'dom', 'layoutManager', 'connectionManager', 'globalize', 'loading', 'browser', 'focusManager', 'scrollHelper', 'material-icons', 'formDialogStyle', 'emby-button', 'emby-itemscontainer', 'cardStyle'], function (dialogHelper, dom, layoutManager, connectionManager, globalize, loading, browser, focusManager, scrollHelper) { 'use strict'; + scrollHelper = scrollHelper.default || scrollHelper; + var enableFocusTransform = !browser.slow && !browser.edge; function getEditorHtml() { diff --git a/src/components/viewSettings/viewSettings.js b/src/components/viewSettings/viewSettings.js index 28a9854c34..198c0a541c 100644 --- a/src/components/viewSettings/viewSettings.js +++ b/src/components/viewSettings/viewSettings.js @@ -33,6 +33,7 @@ define(['require', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'conne function centerFocus(elem, horiz, on) { require(['scrollHelper'], function (scrollHelper) { + scrollHelper = scrollHelper.default || scrollHelper; var fn = on ? 'on' : 'off'; scrollHelper.centerFocus[fn](elem, horiz); }); diff --git a/src/scripts/scrollHelper.js b/src/scripts/scrollHelper.js index 1a36594026..020888a2e3 100644 --- a/src/scripts/scrollHelper.js +++ b/src/scripts/scrollHelper.js @@ -1,137 +1,137 @@ -define(['focusManager', 'dom', 'scrollStyles'], function (focusManager, dom) { - 'use strict'; +import focusManager from 'focusManager'; +import dom from 'dom'; +import 'scrollStyles'; - function getBoundingClientRect(elem) { +function getBoundingClientRect(elem) { - // Support: BlackBerry 5, iOS 3 (original iPhone) - // If we don't have gBCR, just use 0,0 rather than error - if (elem.getBoundingClientRect) { - return elem.getBoundingClientRect(); - } else { - return { top: 0, left: 0 }; - } + // Support: BlackBerry 5, iOS 3 (original iPhone) + // If we don't have gBCR, just use 0,0 rather than error + if (elem.getBoundingClientRect) { + return elem.getBoundingClientRect(); + } else { + return { top: 0, left: 0 }; + } +} + +export function getPosition(scrollContainer, item, horizontal) { + + const slideeOffset = getBoundingClientRect(scrollContainer); + const itemOffset = getBoundingClientRect(item); + + let offset = horizontal ? itemOffset.left - slideeOffset.left : itemOffset.top - slideeOffset.top; + let size = horizontal ? itemOffset.width : itemOffset.height; + if (!size && size !== 0) { + size = item[horizontal ? 'offsetWidth' : 'offsetHeight']; } - function getPosition(scrollContainer, item, horizontal) { + const currentStart = horizontal ? scrollContainer.scrollLeft : scrollContainer.scrollTop; - var slideeOffset = getBoundingClientRect(scrollContainer); - var itemOffset = getBoundingClientRect(item); + offset += currentStart; - var offset = horizontal ? itemOffset.left - slideeOffset.left : itemOffset.top - slideeOffset.top; - var size = horizontal ? itemOffset.width : itemOffset.height; - if (!size && size !== 0) { - size = item[horizontal ? 'offsetWidth' : 'offsetHeight']; - } + const frameSize = horizontal ? scrollContainer.offsetWidth : scrollContainer.offsetHeight; - var currentStart = horizontal ? scrollContainer.scrollLeft : scrollContainer.scrollTop; + const currentEnd = currentStart + frameSize; - offset += currentStart; - - var frameSize = horizontal ? scrollContainer.offsetWidth : scrollContainer.offsetHeight; - - var currentEnd = currentStart + frameSize; - - var isVisible = offset >= currentStart && (offset + size) <= currentEnd; - - return { - start: offset, - center: (offset - (frameSize / 2) + (size / 2)), - end: offset - frameSize + size, - size: size, - isVisible: isVisible - }; - } - - function toCenter(container, elem, horizontal, skipWhenVisible) { - var pos = getPosition(container, elem, horizontal); - - if (skipWhenVisible && pos.isVisible) { - return; - } - - if (container.scrollTo) { - if (horizontal) { - container.scrollTo(pos.center, 0); - } else { - container.scrollTo(0, pos.center); - } - } else { - if (horizontal) { - container.scrollLeft = Math.round(pos.center); - } else { - container.scrollTop = Math.round(pos.center); - } - } - } - - function toStart(container, elem, horizontal, skipWhenVisible) { - var pos = getPosition(container, elem, horizontal); - - if (skipWhenVisible && pos.isVisible) { - return; - } - - if (container.scrollTo) { - if (horizontal) { - container.scrollTo(pos.start, 0); - } else { - container.scrollTo(0, pos.start); - } - } else { - if (horizontal) { - container.scrollLeft = Math.round(pos.start); - } else { - container.scrollTop = Math.round(pos.start); - } - } - } - - function centerOnFocus(e, scrollSlider, horizontal) { - var focused = focusManager.focusableParent(e.target); - - if (focused) { - toCenter(scrollSlider, focused, horizontal); - } - } - - function centerOnFocusHorizontal(e) { - centerOnFocus(e, this, true); - } - function centerOnFocusVertical(e) { - centerOnFocus(e, this, false); - } + const isVisible = offset >= currentStart && (offset + size) <= currentEnd; return { - getPosition: getPosition, - centerFocus: { - on: function (element, horizontal) { - if (horizontal) { - dom.addEventListener(element, 'focus', centerOnFocusHorizontal, { - capture: true, - passive: true - }); - } else { - dom.addEventListener(element, 'focus', centerOnFocusVertical, { - capture: true, - passive: true - }); - } - }, - off: function (element, horizontal) { - if (horizontal) { - dom.removeEventListener(element, 'focus', centerOnFocusHorizontal, { - capture: true, - passive: true - }); - } else { - dom.removeEventListener(element, 'focus', centerOnFocusVertical, { - capture: true, - passive: true - }); - } + start: offset, + center: (offset - (frameSize / 2) + (size / 2)), + end: offset - frameSize + size, + size: size, + isVisible: isVisible + }; +} + +export function toCenter(container, elem, horizontal, skipWhenVisible) { + const pos = getPosition(container, elem, horizontal); + + if (skipWhenVisible && pos.isVisible) { + return; + } + + if (container.scrollTo) { + if (horizontal) { + container.scrollTo(pos.center, 0); + } else { + container.scrollTo(0, pos.center); + } + } else { + if (horizontal) { + container.scrollLeft = Math.round(pos.center); + } else { + container.scrollTop = Math.round(pos.center); + } + } +} + +export function toStart(container, elem, horizontal, skipWhenVisible) { + const pos = getPosition(container, elem, horizontal); + + if (skipWhenVisible && pos.isVisible) { + return; + } + + if (container.scrollTo) { + if (horizontal) { + container.scrollTo(pos.start, 0); + } else { + container.scrollTo(0, pos.start); + } + } else { + if (horizontal) { + container.scrollLeft = Math.round(pos.start); + } else { + container.scrollTop = Math.round(pos.start); + } + } +} + +function centerOnFocus(e, scrollSlider, horizontal) { + const focused = focusManager.focusableParent(e.target); + + if (focused) { + toCenter(scrollSlider, focused, horizontal); + } +} + +function centerOnFocusHorizontal(e) { + centerOnFocus(e, this, true); +} +function centerOnFocusVertical(e) { + centerOnFocus(e, this, false); +} + +export default { + getPosition: getPosition, + centerFocus: { + on: function (element, horizontal) { + if (horizontal) { + dom.addEventListener(element, 'focus', centerOnFocusHorizontal, { + capture: true, + passive: true + }); + } else { + dom.addEventListener(element, 'focus', centerOnFocusVertical, { + capture: true, + passive: true + }); } }, - toCenter: toCenter, - toStart: toStart - }; -}); + off: function (element, horizontal) { + if (horizontal) { + dom.removeEventListener(element, 'focus', centerOnFocusHorizontal, { + capture: true, + passive: true + }); + } else { + dom.removeEventListener(element, 'focus', centerOnFocusVertical, { + capture: true, + passive: true + }); + } + } + }, + toCenter: toCenter, + toStart: toStart +}; From b6dfeb59fca3dffae15eaa0bdfcedbff94f6e7bb Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 27 Jul 2020 10:26:09 +0100 Subject: [PATCH 013/226] Migration of toast and upnextdialog to ES6 modules --- package.json | 2 + src/components/toast/toast.js | 66 ++++++++++----------- src/components/upnextdialog/upnextdialog.js | 40 ++++++++----- 3 files changed, 60 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index da8c87aedd..e88a68efbd 100644 --- a/package.json +++ b/package.json @@ -156,6 +156,8 @@ "src/components/syncPlay/playbackPermissionManager.js", "src/components/syncPlay/syncPlayManager.js", "src/components/syncPlay/timeSyncManager.js", + "src/components/toast/toast.js", + "src/components/upnextdialog/upnextdialog.js", "src/controllers/session/addServer/index.js", "src/controllers/session/forgotPassword/index.js", "src/controllers/session/redeemPassword/index.js", diff --git a/src/components/toast/toast.js b/src/components/toast/toast.js index 7b8e49e4d2..36226ab8e3 100644 --- a/src/components/toast/toast.js +++ b/src/components/toast/toast.js @@ -1,42 +1,40 @@ -define(['css!./toast'], function () { - 'use strict'; +import 'css!./toast'; - function remove(elem) { +function remove(elem) { - setTimeout(function () { - elem.parentNode.removeChild(elem); - }, 300); + setTimeout(function () { + elem.parentNode.removeChild(elem); + }, 300); +} + +function animateRemove(elem) { + + setTimeout(function () { + + elem.classList.remove('toastVisible'); + remove(elem); + + }, 3300); +} + +export default function (options) { + + if (typeof options === 'string') { + options = { + text: options + }; } - function animateRemove(elem) { + var elem = document.createElement('div'); + elem.classList.add('toast'); + elem.innerHTML = options.text; - setTimeout(function () { + document.body.appendChild(elem); - elem.classList.remove('toastVisible'); - remove(elem); + setTimeout(function () { + elem.classList.add('toastVisible'); - }, 3300); - } + animateRemove(elem); - return function (options) { - - if (typeof options === 'string') { - options = { - text: options - }; - } - - var elem = document.createElement('div'); - elem.classList.add('toast'); - elem.innerHTML = options.text; - - document.body.appendChild(elem); - - setTimeout(function () { - elem.classList.add('toastVisible'); - - animateRemove(elem); - - }, 300); - }; -}); + }, 300); +} diff --git a/src/components/upnextdialog/upnextdialog.js b/src/components/upnextdialog/upnextdialog.js index 3e9c9f9c5e..e45b3d5951 100644 --- a/src/components/upnextdialog/upnextdialog.js +++ b/src/components/upnextdialog/upnextdialog.js @@ -1,5 +1,17 @@ -define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'layoutManager', 'focusManager', 'globalize', 'itemHelper', 'css!./upnextdialog', 'emby-button', 'flexStyles'], function (dom, playbackManager, connectionManager, events, mediaInfo, layoutManager, focusManager, globalize, itemHelper) { - 'use strict'; +import dom from 'dom'; +import playbackManager from 'playbackManager'; +import connectionManager from 'connectionManager'; +import events from 'events'; +import mediaInfo from 'mediaInfo'; +import layoutManager from 'layoutManager'; +import focusManager from 'focusManager'; +import globalize from 'globalize'; +import itemHelper from 'itemHelper'; +import 'css!./upnextdialog'; +import 'emby-button'; +import 'flexStyles'; + +/* eslint-disable indent */ var transitionEndEventName = dom.whichTransitionEvent(); @@ -289,14 +301,14 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l instance._countdownTextTimeout = setInterval(setNextVideoText.bind(instance), 400); } - function UpNextDialog(options) { +class UpNextDialog { + constructor(options) { this.options = options; init(this, options); } - - UpNextDialog.prototype.show = function () { + show() { var elem = this.options.parent; @@ -316,20 +328,20 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l } startComingUpNextHideTimer(this); - }; - - UpNextDialog.prototype.hide = function () { + } + hide() { hideComingUpNext.call(this); - }; - - UpNextDialog.prototype.destroy = function () { + } + destroy() { hideComingUpNext.call(this); this.options = null; this.itemType = null; - }; + } +} - return UpNextDialog; -}); +export default UpNextDialog; + +/* eslint-enable indent */ From 1d74c5c85a57263a051c5bcc6e63dd609f0fa525 Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 27 Jul 2020 10:30:24 +0100 Subject: [PATCH 014/226] Update variables --- src/components/toast/toast.js | 2 +- src/components/upnextdialog/upnextdialog.js | 48 ++++++++++----------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/components/toast/toast.js b/src/components/toast/toast.js index 36226ab8e3..5eacc2787b 100644 --- a/src/components/toast/toast.js +++ b/src/components/toast/toast.js @@ -25,7 +25,7 @@ export default function (options) { }; } - var elem = document.createElement('div'); + const elem = document.createElement('div'); elem.classList.add('toast'); elem.innerHTML = options.text; diff --git a/src/components/upnextdialog/upnextdialog.js b/src/components/upnextdialog/upnextdialog.js index e45b3d5951..9879f0ed47 100644 --- a/src/components/upnextdialog/upnextdialog.js +++ b/src/components/upnextdialog/upnextdialog.js @@ -13,7 +13,7 @@ import 'flexStyles'; /* eslint-disable indent */ - var transitionEndEventName = dom.whichTransitionEvent(); + const transitionEndEventName = dom.whichTransitionEvent(); function seriesImageUrl(item, options) { @@ -79,7 +79,7 @@ import 'flexStyles'; if (item) { - var imgUrl = seriesImageUrl(item, { type: 'Primary' }) || + let imgUrl = seriesImageUrl(item, { type: 'Primary' }) || seriesImageUrl(item, { type: 'Thumb' }) || imageUrl(item, { type: 'Primary' }); @@ -100,7 +100,7 @@ import 'flexStyles'; function getHtml() { - var html = ''; + let html = ''; html += '
'; html += '
'; @@ -137,17 +137,17 @@ import 'flexStyles'; function setNextVideoText() { - var instance = this; + const instance = this; - var elem = instance.options.parent; + const elem = instance.options.parent; - var secondsRemaining = Math.max(Math.round(getTimeRemainingMs(instance) / 1000), 0); + const secondsRemaining = Math.max(Math.round(getTimeRemainingMs(instance) / 1000), 0); console.debug('up next seconds remaining: ' + secondsRemaining); - var timeText = '' + globalize.translate('HeaderSecondsValue', secondsRemaining) + ''; + const timeText = '' + globalize.translate('HeaderSecondsValue', secondsRemaining) + ''; - var nextVideoText = instance.itemType === 'Episode' ? + const nextVideoText = instance.itemType === 'Episode' ? globalize.translate('HeaderNextEpisodePlayingInValue', timeText) : globalize.translate('HeaderNextVideoPlayingInValue', timeText); @@ -156,9 +156,9 @@ import 'flexStyles'; function fillItem(item) { - var instance = this; + const instance = this; - var elem = instance.options.parent; + const elem = instance.options.parent; setPoster(elem.querySelector('.upNextDialog-poster'), item); @@ -167,7 +167,7 @@ import 'flexStyles'; elem.querySelector('.upNextDialog-mediainfo').innerHTML = mediaInfo.getPrimaryMediaInfoHtml(item, { }); - var title = itemHelper.getDisplayName(item); + let title = itemHelper.getDisplayName(item); if (item.SeriesName) { title = item.SeriesName + ' - ' + title; } @@ -188,11 +188,11 @@ import 'flexStyles'; function onStartNowClick() { - var options = this.options; + const options = this.options; if (options) { - var player = options.player; + const player = options.player; this.hide(); @@ -216,7 +216,7 @@ import 'flexStyles'; function clearHideAnimationEventListeners(instance, elem) { - var fn = instance._onHideAnimationComplete; + const fn = instance._onHideAnimationComplete; if (fn) { dom.removeEventListener(elem, transitionEndEventName, fn, { @@ -227,8 +227,8 @@ import 'flexStyles'; function onHideAnimationComplete(e) { - var instance = this; - var elem = e.target; + const instance = this; + const elem = e.target; elem.classList.add('hide'); @@ -238,14 +238,14 @@ import 'flexStyles'; function hideComingUpNext() { - var instance = this; + const instance = this; clearCountdownTextTimeout(this); if (!instance.options) { return; } - var elem = instance.options.parent; + const elem = instance.options.parent; if (!elem) { return; @@ -262,7 +262,7 @@ import 'flexStyles'; elem.classList.add('upNextDialog-hidden'); - var fn = onHideAnimationComplete.bind(instance); + const fn = onHideAnimationComplete.bind(instance); instance._onHideAnimationComplete = fn; dom.addEventListener(elem, transitionEndEventName, fn, { @@ -272,13 +272,13 @@ import 'flexStyles'; function getTimeRemainingMs(instance) { - var options = instance.options; + const options = instance.options; if (options) { - var runtimeTicks = playbackManager.duration(options.player); + const runtimeTicks = playbackManager.duration(options.player); if (runtimeTicks) { - var timeRemainingTicks = runtimeTicks - playbackManager.currentTime(options.player); + const timeRemainingTicks = runtimeTicks - playbackManager.currentTime(options.player); return Math.round(timeRemainingTicks / 10000); } @@ -289,7 +289,7 @@ import 'flexStyles'; function startComingUpNextHideTimer(instance) { - var timeRemainingMs = getTimeRemainingMs(instance); + const timeRemainingMs = getTimeRemainingMs(instance); if (timeRemainingMs <= 0) { return; @@ -310,7 +310,7 @@ class UpNextDialog { } show() { - var elem = this.options.parent; + const elem = this.options.parent; clearHideAnimationEventListeners(this, elem); From 951d3ffc498f1f22735a04b5cdde643fb8f92313 Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 27 Jul 2020 10:32:48 +0100 Subject: [PATCH 015/226] Update site.js --- src/scripts/site.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index cddf2506a0..85e8c427d0 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -152,13 +152,13 @@ var Dashboard = { processPluginConfigurationUpdateResult: function () { require(['loading', 'toast'], function (loading, toast) { loading.hide(); - toast(Globalize.translate('MessageSettingsSaved')); + toast.default(Globalize.translate('MessageSettingsSaved')); }); }, processServerConfigurationUpdateResult: function (result) { require(['loading', 'toast'], function (loading, toast) { loading.hide(); - toast(Globalize.translate('MessageSettingsSaved')); + toast.default(Globalize.translate('MessageSettingsSaved')); }); }, processErrorResponse: function (response) { @@ -180,7 +180,7 @@ var Dashboard = { alert: function (options) { if ('string' == typeof options) { return void require(['toast'], function (toast) { - toast({ + toast.default({ text: options }); }); From e2b7daf4b70e982a49cd672d9ff0788e419d4368 Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 27 Jul 2020 13:08:16 +0100 Subject: [PATCH 016/226] fix lint --- src/components/imageeditor/imageeditor.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index 0a873fa4c7..96c179404a 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -51,7 +51,6 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', var btnBrowseAllImages = page.querySelectorAll('.btnBrowseAllImages'); for (var i = 0, length = btnBrowseAllImages.length; i < length; i++) { - if (providers.length) { btnBrowseAllImages[i].classList.remove('hide'); } else { @@ -60,7 +59,6 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', } apiClient.getItemImageInfos(currentItem.Id).then(function (imageInfos) { - renderStandardImages(page, apiClient, item, imageInfos, providers); renderBackdrops(page, apiClient, item, imageInfos, providers); renderScreenshots(page, apiClient, item, imageInfos, providers); From f9e79c0a4eda2b6aca51244eb59d7541c47a7fdb Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 28 Jul 2020 21:28:16 +0100 Subject: [PATCH 017/226] Migration of list.js and screensavermanager to ES6 modules --- .eslintignore | 1 - package.json | 2 + src/controllers/list.js | 270 ++++++++++++++-------------- src/libraries/screensavermanager.js | 256 +++++++++++++------------- 4 files changed, 264 insertions(+), 265 deletions(-) diff --git a/.eslintignore b/.eslintignore index 8e3aee83fb..74b18ddcf6 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,4 +2,3 @@ node_modules dist .idea .vscode -src/libraries diff --git a/package.json b/package.json index 30c0c481e6..f412c0671a 100644 --- a/package.json +++ b/package.json @@ -188,6 +188,7 @@ "src/controllers/dashboard/users/userparentalcontrol.js", "src/controllers/dashboard/users/userpasswordpage.js", "src/controllers/dashboard/users/userprofilespage.js", + "src/controllers/list.js", "src/controllers/playback/queue/index.js", "src/controllers/playback/video/index.js", "src/controllers/searchpage.js", @@ -230,6 +231,7 @@ "src/elements/emby-tabs/emby-tabs.js", "src/elements/emby-textarea/emby-textarea.js", "src/elements/emby-toggle/emby-toggle.js", + "src/libraries/screensavermanager.js", "src/plugins/backdropScreensaver/plugin.js", "src/plugins/bookPlayer/plugin.js", "src/plugins/bookPlayer/tableOfContents.js", diff --git a/src/controllers/list.js b/src/controllers/list.js index e550b535f4..c7c4b2a31d 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -1,8 +1,21 @@ -define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager', 'cardBuilder', 'loading', 'connectionManager', 'alphaNumericShortcuts', 'scroller', 'playbackManager', 'alphaPicker', 'emby-itemscontainer', 'emby-scroller'], function (globalize, listView, layoutManager, userSettings, focusManager, cardBuilder, loading, connectionManager, AlphaNumericShortcuts, scroller, playbackManager, AlphaPicker) { - 'use strict'; +import globalize from 'globalize'; +import listView from 'listView'; +import layoutManager from 'layoutManager'; +import * as userSettings from 'userSettings'; +import focusManager from 'focusManager'; +import cardBuilder from 'cardBuilder'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; +import AlphaNumericShortcuts from 'alphaNumericShortcuts'; +import playbackManager from 'playbackManager'; +import AlphaPicker from 'alphaPicker'; +import 'emby-itemscontainer'; +import 'emby-scroller'; + +/* eslint-disable indent */ function getInitialLiveTvQuery(instance, params) { - var query = { + const query = { UserId: connectionManager.getApiClient(params.serverId).getCurrentUserId(), StartIndex: 0, Fields: 'ChannelInfo,PrimaryImageAspectRatio', @@ -59,7 +72,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function modifyQueryWithFilters(instance, query) { - var sortValues = instance.getSortValues(); + const sortValues = instance.getSortValues(); if (!query.SortBy) { query.SortBy = sortValues.sortBy; @@ -68,9 +81,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' query.Fields = query.Fields ? query.Fields + ',PrimaryImageAspectRatio' : 'PrimaryImageAspectRatio'; query.ImageTypeLimit = 1; - var hasFilters; - var queryFilters = []; - var filters = instance.getFilters(); + let hasFilters; + const queryFilters = []; + const filters = instance.getFilters(); if (filters.IsPlayed) { queryFilters.push('IsPlayed'); @@ -164,21 +177,21 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function updateSortText(instance) { - var btnSortText = instance.btnSortText; + const btnSortText = instance.btnSortText; if (btnSortText) { - var options = instance.getSortMenuOptions(); - var values = instance.getSortValues(); - var sortBy = values.sortBy; + const options = instance.getSortMenuOptions(); + const values = instance.getSortValues(); + const sortBy = values.sortBy; - for (var i = 0, length = options.length; i < length; i++) { + for (let i = 0, length = options.length; i < length; i++) { if (sortBy === options[i].value) { btnSortText.innerHTML = globalize.translate('SortByValue', options[i].name); break; } } - var btnSortIcon = instance.btnSortIcon; + const btnSortIcon = instance.btnSortIcon; if (btnSortIcon) { setSortButtonIcon(btnSortIcon, 'Descending' === values.sortOrder ? 'arrow_downward' : 'arrow_upward'); @@ -198,10 +211,10 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' function updateAlphaPickerState(instance, numItems) { if (instance.alphaPicker) { - var alphaPicker = instance.alphaPickerElement; + const alphaPicker = instance.alphaPickerElement; if (alphaPicker) { - var values = instance.getSortValues(); + const values = instance.getSortValues(); if (null == numItems) { numItems = 100; @@ -219,7 +232,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function getItems(instance, params, item, sortBy, startIndex, limit) { - var apiClient = connectionManager.getApiClient(params.serverId); + const apiClient = connectionManager.getApiClient(params.serverId); instance.queryRecursive = false; if ('Recordings' === params.type) { @@ -248,7 +261,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' if (!item) { instance.queryRecursive = true; - var method = 'getItems'; + let method = 'getItems'; if ('MusicArtist' === params.type) { method = 'getArtists'; @@ -271,7 +284,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' if ('Genre' === item.Type || 'MusicGenre' === item.Type || 'Studio' === item.Type || 'Person' === item.Type) { instance.queryRecursive = true; - var query = { + const query = { StartIndex: startIndex, Limit: limit, Fields: 'PrimaryImageAspectRatio,SortName', @@ -320,8 +333,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' return Promise.resolve(null); } - var apiClient = connectionManager.getApiClient(params.serverId); - var itemId = params.genreId || params.musicGenreId || params.studioId || params.personId || params.parentId; + const apiClient = connectionManager.getApiClient(params.serverId); + const itemId = params.genreId || params.musicGenreId || params.studioId || params.personId || params.parentId; if (itemId) { return apiClient.getItem(apiClient.getCurrentUserId(), itemId); @@ -331,9 +344,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function showViewSettingsMenu() { - var instance = this; + const instance = this; - require(['viewSettings'], function (ViewSettings) { + import('viewSettings').then(({default: ViewSettings}) => { new ViewSettings().show({ settingsKey: instance.getSettingsKey(), settings: instance.getViewSettings(), @@ -346,9 +359,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function showFilterMenu() { - var instance = this; + const instance = this; - require(['filterMenu'], function (FilterMenu) { + import('filterMenu').then(({default: FilterMenu}) => { new FilterMenu().show({ settingsKey: instance.getSettingsKey(), settings: instance.getFilters(), @@ -365,9 +378,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function showSortMenu() { - var instance = this; + const instance = this; - require(['sortMenu'], function (SortMenu) { + import('sortMenu').then(({default: SortMenu}) => { new SortMenu().show({ settingsKey: instance.getSettingsKey(), settings: instance.getSortValues(), @@ -383,9 +396,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function onNewItemClick() { - var instance = this; + const instance = this; - require(['playlistEditor'], function (playlistEditor) { + import('playlistEditor').then(({default: playlistEditor}) => { new playlistEditor.showEditor({ items: [], serverId: instance.params.serverId @@ -394,7 +407,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function hideOrShowAll(elems, hide) { - for (var i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { if (hide) { elems[i].classList.add('hide'); } else { @@ -404,12 +417,13 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function bindAll(elems, eventName, fn) { - for (var i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener(eventName, fn); } } - function ItemsView(view, params) { +class ItemsView { + constructor(view, params) { function fetchData() { return getItems(self, params, self.currentItem).then(function (result) { if (null == self.totalItemCount) { @@ -422,7 +436,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function getItemsHtml(items) { - var settings = self.getViewSettings(); + const settings = self.getViewSettings(); if ('list' === settings.imageType) { return listView.getListViewHtml({ @@ -430,13 +444,13 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' }); } - var shape; - var preferThumb; - var preferDisc; - var preferLogo; - var defaultShape; - var item = self.currentItem; - var lines = settings.showTitle ? 2 : 0; + let shape; + let preferThumb; + let preferDisc; + let preferLogo; + let defaultShape; + const item = self.currentItem; + let lines = settings.showTitle ? 2 : 0; if ('banner' === settings.imageType) { shape = 'banner'; @@ -460,7 +474,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' shape = 'autoVertical'; } - var posterOptions = { + let posterOptions = { shape: shape, showTitle: settings.showTitle, showYear: settings.showTitle, @@ -493,19 +507,19 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' lines = 1; } else if ('Programs' === params.type) { lines = settings.showTitle ? 1 : 0; - var showParentTitle = settings.showTitle && 'true' !== params.IsMovie; + const showParentTitle = settings.showTitle && 'true' !== params.IsMovie; if (showParentTitle) { lines++; } - var showAirTime = settings.showTitle && 'Recordings' !== params.type; + const showAirTime = settings.showTitle && 'Recordings' !== params.type; if (showAirTime) { lines++; } - var showYear = settings.showTitle && 'true' === params.IsMovie && 'Recordings' === params.type; + const showYear = settings.showTitle && 'true' === params.IsMovie && 'Recordings' === params.type; if (showYear) { lines++; @@ -538,7 +552,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' function initAlphaPicker() { self.scroller = view.querySelector('.scrollFrameY'); - var alphaPickerElement = self.alphaPickerElement; + const alphaPickerElement = self.alphaPickerElement; alphaPickerElement.classList.add('alphaPicker-fixed-right'); alphaPickerElement.classList.add('focuscontainer-right'); @@ -649,7 +663,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function play() { - var currentItem = self.currentItem; + const currentItem = self.currentItem; if (currentItem && !self.hasFilters) { playbackManager.play({ @@ -665,7 +679,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function queue() { - var currentItem = self.currentItem; + const currentItem = self.currentItem; if (currentItem && !self.hasFilters) { playbackManager.queue({ @@ -681,7 +695,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } function shuffle() { - var currentItem = self.currentItem; + const currentItem = self.currentItem; if (currentItem && !self.hasFilters) { playbackManager.shuffle(currentItem); @@ -694,7 +708,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } } - var self = this; + const self = this; self.params = params; this.itemsContainer = view.querySelector('.itemsContainer'); @@ -708,20 +722,20 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' this.itemsContainer.setAttribute('data-refreshinterval', '300000'); } - var i; - var length; - var btnViewSettings = view.querySelectorAll('.btnViewSettings'); + let i; + let length; + const btnViewSettings = view.querySelectorAll('.btnViewSettings'); for (i = 0, length = btnViewSettings.length; i < length; i++) { btnViewSettings[i].addEventListener('click', showViewSettingsMenu.bind(this)); } - var filterButtons = view.querySelectorAll('.btnFilter'); + const filterButtons = view.querySelectorAll('.btnFilter'); this.filterButtons = filterButtons; - var hasVisibleFilters = this.getVisibleFilters().length; + const hasVisibleFilters = this.getVisibleFilters().length; for (i = 0, length = filterButtons.length; i < length; i++) { - var btnFilter = filterButtons[i]; + const btnFilter = filterButtons[i]; btnFilter.addEventListener('click', showFilterMenu.bind(this)); if (hasVisibleFilters) { @@ -731,10 +745,10 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } } - var sortButtons = view.querySelectorAll('.btnSort'); + const sortButtons = view.querySelectorAll('.btnSort'); for (this.sortButtons = sortButtons, i = 0, length = sortButtons.length; i < length; i++) { - var sortButton = sortButtons[i]; + const sortButton = sortButtons[i]; sortButton.addEventListener('click', showSortMenu.bind(this)); if ('nextup' !== params.type) { @@ -749,7 +763,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' self.itemsContainer.fetchData = fetchData; self.itemsContainer.getItemsHtml = getItemsHtml; view.addEventListener('viewshow', function (e) { - var isRestored = e.detail.isRestored; + const isRestored = e.detail.isRestored; if (!isRestored) { loading.show(); @@ -761,7 +775,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' getItem(params).then(function (item) { setTitle(item); self.currentItem = item; - var refresh = !isRestored; + const refresh = !isRestored; self.itemsContainer.resume({ refresh: refresh }).then(function () { @@ -776,7 +790,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' initAlphaPicker(); } - var itemType = item ? item.Type : null; + const itemType = item ? item.Type : null; if ('MusicGenre' === itemType || 'Programs' !== params.type && 'Channel' !== itemType) { hideOrShowAll(view.querySelectorAll('.btnPlay'), false); @@ -808,13 +822,13 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' }); }); view.addEventListener('viewhide', function (e) { - var itemsContainer = self.itemsContainer; + const itemsContainer = self.itemsContainer; if (itemsContainer) { itemsContainer.pause(); } - var alphaNumericShortcuts = self.alphaNumericShortcuts; + const alphaNumericShortcuts = self.alphaNumericShortcuts; if (alphaNumericShortcuts) { alphaNumericShortcuts.destroy(); @@ -841,9 +855,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' self.alphaPickerElement = null; }); } - - ItemsView.prototype.getFilters = function () { - var basekey = this.getSettingsKey(); + getFilters() { + const basekey = this.getSettingsKey(); return { IsPlayed: 'true' === userSettings.getFilter(basekey + '-filter-IsPlayed'), IsUnplayed: 'true' === userSettings.getFilter(basekey + '-filter-IsUnplayed'), @@ -862,30 +875,27 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' HasThemeVideo: userSettings.getFilter(basekey + '-filter-HasThemeVideo'), GenreIds: userSettings.getFilter(basekey + '-filter-GenreIds') }; - }; - - ItemsView.prototype.getSortValues = function () { - var basekey = this.getSettingsKey(); + } + getSortValues() { + const basekey = this.getSettingsKey(); return { sortBy: userSettings.getFilter(basekey + '-sortby') || this.getDefaultSortBy(), sortOrder: 'Descending' === userSettings.getFilter(basekey + '-sortorder') ? 'Descending' : 'Ascending' }; - }; - - ItemsView.prototype.getDefaultSortBy = function () { - var params = this.params; - var sortNameOption = this.getNameSortOption(params); + } + getDefaultSortBy() { + const params = this.params; + const sortNameOption = this.getNameSortOption(params); if (params.type) { return sortNameOption.value; } return 'IsFolder,' + sortNameOption.value; - }; - - ItemsView.prototype.getSortMenuOptions = function () { - var sortBy = []; - var params = this.params; + } + getSortMenuOptions() { + const sortBy = []; + const params = this.params; if ('Programs' === params.type) { sortBy.push({ @@ -894,7 +904,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' }); } - var option = this.getNameSortOption(params); + let option = this.getNameSortOption(params); if (option) { sortBy.push(option); @@ -952,9 +962,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' value: 'Runtime,SortName' }); return sortBy; - }; - - ItemsView.prototype.getNameSortOption = function (params) { + } + getNameSortOption(params) { if ('Episode' === params.type) { return { name: globalize.translate('Name'), @@ -966,9 +975,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' name: globalize.translate('Name'), value: 'SortName' }; - }; - - ItemsView.prototype.getPlayCountSortOption = function () { + } + getPlayCountSortOption() { if ('Programs' === this.params.type) { return null; } @@ -977,9 +985,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' name: globalize.translate('PlayCount'), value: 'PlayCount,SortName' }; - }; - - ItemsView.prototype.getDatePlayedSortOption = function () { + } + getDatePlayedSortOption() { if ('Programs' === this.params.type) { return null; } @@ -988,9 +995,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' name: globalize.translate('DatePlayed'), value: 'DatePlayed,SortName' }; - }; - - ItemsView.prototype.getCriticRatingSortOption = function () { + } + getCriticRatingSortOption() { if ('Programs' === this.params.type) { return null; } @@ -999,18 +1005,16 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' name: globalize.translate('CriticRating'), value: 'CriticRating,SortName' }; - }; - - ItemsView.prototype.getCommunityRatingSortOption = function () { + } + getCommunityRatingSortOption() { return { name: globalize.translate('CommunityRating'), value: 'CommunityRating,SortName' }; - }; - - ItemsView.prototype.getVisibleFilters = function () { - var filters = []; - var params = this.params; + } + getVisibleFilters() { + const filters = []; + const params = this.params; if (!('nextup' === params.type)) { if ('Programs' === params.type) { @@ -1034,16 +1038,15 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } return filters; - }; - - ItemsView.prototype.setFilterStatus = function (hasFilters) { + } + setFilterStatus(hasFilters) { this.hasFilters = hasFilters; - var filterButtons = this.filterButtons; + const filterButtons = this.filterButtons; if (filterButtons.length) { - for (var i = 0, length = filterButtons.length; i < length; i++) { - var btnFilter = filterButtons[i]; - var bubble = btnFilter.querySelector('.filterButtonBubble'); + for (let i = 0, length = filterButtons.length; i < length; i++) { + const btnFilter = filterButtons[i]; + let bubble = btnFilter.querySelector('.filterButtonBubble'); if (!bubble) { if (!hasFilters) { @@ -1062,10 +1065,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } } } - }; - - ItemsView.prototype.getFilterMenuOptions = function () { - var params = this.params; + } + getFilterMenuOptions() { + const params = this.params; return { IsAiring: params.IsAiring, IsMovie: params.IsMovie, @@ -1075,11 +1077,10 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' IsSeries: params.IsSeries, Recursive: this.queryRecursive }; - }; - - ItemsView.prototype.getVisibleViewSettings = function () { - var item = (this.params, this.currentItem); - var fields = ['showTitle']; + } + getVisibleViewSettings() { + const item = (this.params, this.currentItem); + const fields = ['showTitle']; if (!item || 'PhotoAlbum' !== item.Type && 'ChannelFolderItem' !== item.Type) { fields.push('imageType'); @@ -1087,13 +1088,12 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' fields.push('viewType'); return fields; - }; - - ItemsView.prototype.getViewSettings = function () { - var basekey = this.getSettingsKey(); - var params = this.params; - var item = this.currentItem; - var showTitle = userSettings.get(basekey + '-showTitle'); + } + getViewSettings() { + const basekey = this.getSettingsKey(); + const params = this.params; + const item = this.currentItem; + let showTitle = userSettings.get(basekey + '-showTitle'); if ('true' === showTitle) { showTitle = true; @@ -1105,7 +1105,7 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' showTitle = true; } - var imageType = userSettings.get(basekey + '-imageType'); + let imageType = userSettings.get(basekey + '-imageType'); if (!imageType && 'nextup' === params.type) { imageType = 'thumb'; @@ -1117,10 +1117,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' imageType: imageType || 'primary', viewType: userSettings.get(basekey + '-viewType') || 'images' }; - }; - - ItemsView.prototype.getItemTypes = function () { - var params = this.params; + } + getItemTypes() { + const params = this.params; if ('nextup' === params.type) { return ['Episode']; @@ -1131,12 +1130,11 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } return []; - }; - - ItemsView.prototype.getSettingsKey = function () { - var values = []; + } + getSettingsKey() { + const values = []; values.push('items'); - var params = this.params; + const params = this.params; if (params.type) { values.push(params.type); @@ -1193,7 +1191,9 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager' } return values.join('-'); - }; + } +} - return ItemsView; -}); +export default ItemsView; + +/* eslint-enable indent */ diff --git a/src/libraries/screensavermanager.js b/src/libraries/screensavermanager.js index b9d7082850..61d128ff14 100644 --- a/src/libraries/screensavermanager.js +++ b/src/libraries/screensavermanager.js @@ -1,132 +1,130 @@ -define(["events", "playbackManager", "pluginManager", "inputManager", "connectionManager", "userSettings"], function (events, playbackManager, pluginManager, inputManager, connectionManager, userSettings) { - "use strict"; +import events from 'events'; +import playbackManager from 'playbackManager'; +import pluginManager from 'pluginManager'; +import inputManager from 'inputManager'; +import connectionManager from 'connectionManager'; +import * as userSettings from 'userSettings'; - function getMinIdleTime() { - // Returns the minimum amount of idle time required before the screen saver can be displayed - //time units used Millisecond - return 180000; +function getMinIdleTime() { + // Returns the minimum amount of idle time required before the screen saver can be displayed + //time units used Millisecond + return 180000; +} + +let lastFunctionalEvent = 0; + +function getFunctionalEventIdleTime() { + return new Date().getTime() - lastFunctionalEvent; +} + +events.on(playbackManager, 'playbackstop', function (e, stopInfo) { + const state = stopInfo.state; + if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') { + lastFunctionalEvent = new Date().getTime(); } - - var lastFunctionalEvent = 0; - - function getFunctionalEventIdleTime() { - return new Date().getTime() - lastFunctionalEvent; - } - - events.on(playbackManager, "playbackstop", function (e, stopInfo) { - var state = stopInfo.state; - if (state.NowPlayingItem && state.NowPlayingItem.MediaType == "Video") { - lastFunctionalEvent = new Date().getTime(); - } - }); - - function getScreensaverPlugin(isLoggedIn) { - - var option; - try { - option = userSettings.get("screensaver", false); - } catch (err) { - option = isLoggedIn ? "backdropscreensaver" : "logoscreensaver"; - } - - var plugins = pluginManager.ofType("screensaver"); - - for (var i = 0, length = plugins.length; i < length; i++) { - var plugin = plugins[i]; - - if (plugin.id === option) { - return plugin; - } - } - - return null; - } - - function ScreenSaverManager() { - - var self = this; - var activeScreenSaver; - - function showScreenSaver(screensaver) { - - if (activeScreenSaver) { - throw new Error("An existing screensaver is already active."); - } - - console.debug("Showing screensaver " + screensaver.name); - - screensaver.show(); - activeScreenSaver = screensaver; - - if (screensaver.hideOnClick !== false) { - window.addEventListener("click", hide, true); - } - if (screensaver.hideOnMouse !== false) { - window.addEventListener("mousemove", hide, true); - } - if (screensaver.hideOnKey !== false) { - window.addEventListener("keydown", hide, true); - } - } - - function hide() { - if (activeScreenSaver) { - console.debug("Hiding screensaver"); - activeScreenSaver.hide(); - activeScreenSaver = null; - } - - window.removeEventListener("click", hide, true); - window.removeEventListener("mousemove", hide, true); - window.removeEventListener("keydown", hide, true); - } - - self.isShowing = function () { - return activeScreenSaver != null; - }; - - self.show = function () { - var isLoggedIn; - var apiClient = connectionManager.currentApiClient(); - - if (apiClient && apiClient.isLoggedIn()) { - isLoggedIn = true; - } - - var screensaver = getScreensaverPlugin(isLoggedIn); - - if (screensaver) { - showScreenSaver(screensaver); - } - }; - - self.hide = function () { - hide(); - }; - - function onInterval() { - - if (self.isShowing()) { - return; - } - - if (inputManager.idleTime() < getMinIdleTime()) { - return; - } - - if (getFunctionalEventIdleTime < getMinIdleTime()) { - return; - } - - if (playbackManager.isPlayingVideo()) { - return; - } - - self.show(); - } - - setInterval(onInterval, 10000); - } - - return new ScreenSaverManager(); }); + +function getScreensaverPlugin(isLoggedIn) { + let option; + try { + option = userSettings.get('screensaver', false); + } catch (err) { + option = isLoggedIn ? 'backdropscreensaver' : 'logoscreensaver'; + } + + const plugins = pluginManager.ofType('screensaver'); + + for (let i = 0, length = plugins.length; i < length; i++) { + const plugin = plugins[i]; + + if (plugin.id === option) { + return plugin; + } + } + + return null; +} + +function ScreenSaverManager() { + let activeScreenSaver; + + function showScreenSaver(screensaver) { + if (activeScreenSaver) { + throw new Error('An existing screensaver is already active.'); + } + + console.debug('Showing screensaver ' + screensaver.name); + + screensaver.show(); + activeScreenSaver = screensaver; + + if (screensaver.hideOnClick !== false) { + window.addEventListener('click', hide, true); + } + if (screensaver.hideOnMouse !== false) { + window.addEventListener('mousemove', hide, true); + } + if (screensaver.hideOnKey !== false) { + window.addEventListener('keydown', hide, true); + } + } + + function hide() { + if (activeScreenSaver) { + console.debug('Hiding screensaver'); + activeScreenSaver.hide(); + activeScreenSaver = null; + } + + window.removeEventListener('click', hide, true); + window.removeEventListener('mousemove', hide, true); + window.removeEventListener('keydown', hide, true); + } + + this.isShowing = () => { + return activeScreenSaver != null; + }; + + this.show = function () { + let isLoggedIn; + const apiClient = connectionManager.currentApiClient(); + + if (apiClient && apiClient.isLoggedIn()) { + isLoggedIn = true; + } + + const screensaver = getScreensaverPlugin(isLoggedIn); + + if (screensaver) { + showScreenSaver(screensaver); + } + }; + + this.hide = function () { + hide(); + }; + + const onInterval = () => { + if (this.isShowing()) { + return; + } + + if (inputManager.idleTime() < getMinIdleTime()) { + return; + } + + if (getFunctionalEventIdleTime < getMinIdleTime()) { + return; + } + + if (playbackManager.isPlayingVideo()) { + return; + } + + this.show(); + }; + + setInterval(onInterval, 10000); +} + +export default new ScreenSaverManager; From d63a229e0ef0573af125e29d8981faf2a89a040f Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 28 Jul 2020 21:43:46 +0100 Subject: [PATCH 018/226] fix lint --- src/libraries/navdrawer/navdrawer.js | 86 ++++++++++++++-------------- src/libraries/scroller.js | 39 ------------- 2 files changed, 43 insertions(+), 82 deletions(-) diff --git a/src/libraries/navdrawer/navdrawer.js b/src/libraries/navdrawer/navdrawer.js index d9c246b406..750dd510b8 100644 --- a/src/libraries/navdrawer/navdrawer.js +++ b/src/libraries/navdrawer/navdrawer.js @@ -1,5 +1,5 @@ -define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, dom) { - "use strict"; +define(['browser', 'dom', 'css!./navdrawer', 'scrollStyles'], function (browser, dom) { + 'use strict'; return function (options) { function getTouches(e) { @@ -7,7 +7,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, } function onMenuTouchStart(e) { - options.target.classList.remove("transition"); + options.target.classList.remove('transition'); var touches = getTouches(e); var touch = touches[0] || {}; menuTouchStartX = touch.clientX; @@ -36,7 +36,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, if (0 === dragMode && (!isOpen || Math.abs(deltaX) >= 10) && Math.abs(deltaY) < 5) { dragMode = 1; - scrollContainer.addEventListener("scroll", disableEvent); + scrollContainer.addEventListener('scroll', disableEvent); self.showMask(); } else if (0 === dragMode && Math.abs(deltaY) >= 5) { dragMode = 2; @@ -49,8 +49,8 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, } function onMenuTouchEnd(e) { - options.target.classList.add("transition"); - scrollContainer.removeEventListener("scroll", disableEvent); + options.target.classList.add('transition'); + scrollContainer.removeEventListener('scroll', disableEvent); dragMode = 0; var touches = getTouches(e); var touch = touches[0] || {}; @@ -69,9 +69,9 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, if (((getTouches(e)[0] || {}).clientX || 0) <= options.handleSize) { isPeeking = true; - if (e.type === "touchstart") { - dom.removeEventListener(edgeContainer, "touchmove", onEdgeTouchMove, {}); - dom.addEventListener(edgeContainer, "touchmove", onEdgeTouchMove, {}); + if (e.type === 'touchstart') { + dom.removeEventListener(edgeContainer, 'touchmove', onEdgeTouchMove, {}); + dom.addEventListener(edgeContainer, 'touchmove', onEdgeTouchMove, {}); } onMenuTouchStart(e); @@ -88,7 +88,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, function onEdgeTouchEnd(e) { if (isPeeking) { isPeeking = false; - dom.removeEventListener(edgeContainer, "touchmove", onEdgeTouchMove, {}); + dom.removeEventListener(edgeContainer, 'touchmove', onEdgeTouchMove, {}); onMenuTouchEnd(e); } } @@ -142,8 +142,8 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, function onMaskTransitionEnd() { var classList = mask.classList; - if (!classList.contains("backdrop")) { - classList.add("hide"); + if (!classList.contains('backdrop')) { + classList.add('hide'); } } @@ -155,10 +155,10 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, var startPoint = 0; var countStart = 0; var velocity = 0; - options.target.classList.add("transition"); + options.target.classList.add('transition'); var dragMode = 0; - var scrollContainer = options.target.querySelector(".mainDrawer-scrollContainer"); - scrollContainer.classList.add("scrollY"); + var scrollContainer = options.target.querySelector('.mainDrawer-scrollContainer'); + scrollContainer.classList.add('scrollY'); var TouchMenuLA = function () { self = this; @@ -173,13 +173,13 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, }; TouchMenuLA.prototype.initElements = function () { - options.target.classList.add("touch-menu-la"); - options.target.style.width = options.width + "px"; - options.target.style.left = -options.width + "px"; + options.target.classList.add('touch-menu-la'); + options.target.style.width = options.width + 'px'; + options.target.style.left = -options.width + 'px'; if (!options.disableMask) { - mask = document.createElement("div"); - mask.className = "tmla-mask hide"; + mask = document.createElement('div'); + mask.className = 'tmla-mask hide'; document.body.appendChild(mask); dom.addEventListener(mask, dom.whichTransitionEvent(), onMaskTransitionEnd, { passive: true @@ -190,12 +190,12 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, var menuTouchStartX; var menuTouchStartY; var menuTouchStartTime; - var edgeContainer = document.querySelector(".mainDrawerHandle"); + var edgeContainer = document.querySelector('.mainDrawerHandle'); var isPeeking = false; TouchMenuLA.prototype.animateToPosition = function (pos) { requestAnimationFrame(function () { - options.target.style.transform = pos ? "translateX(" + pos + "px)" : "none"; + options.target.style.transform = pos ? 'translateX(' + pos + 'px)' : 'none'; }); }; @@ -206,7 +206,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, }; TouchMenuLA.prototype.clickMaskClose = function () { - mask.addEventListener("click", function () { + mask.addEventListener('click', function () { self.close(); }); }; @@ -233,7 +233,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, this.animateToPosition(options.width); currentPos = options.width; this.isVisible = true; - options.target.classList.add("drawer-open"); + options.target.classList.add('drawer-open'); self.showMask(); self.invoke(options.onChange); }; @@ -242,7 +242,7 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, this.animateToPosition(0); currentPos = 0; self.isVisible = false; - options.target.classList.remove("drawer-open"); + options.target.classList.remove('drawer-open'); self.hideMask(); self.invoke(options.onChange); }; @@ -259,13 +259,13 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, var backgroundTouchStartTime; TouchMenuLA.prototype.showMask = function () { - mask.classList.remove("hide"); - mask.classList.add("backdrop"); + mask.classList.remove('hide'); + mask.classList.add('backdrop'); }; TouchMenuLA.prototype.hideMask = function () { - mask.classList.add("hide"); - mask.classList.remove("backdrop"); + mask.classList.add('hide'); + mask.classList.remove('backdrop'); }; TouchMenuLA.prototype.invoke = function (fn) { @@ -282,26 +282,26 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, if (enabled) { if (!_edgeSwipeEnabled) { _edgeSwipeEnabled = true; - dom.addEventListener(edgeContainer, "touchstart", onEdgeTouchStart, { + dom.addEventListener(edgeContainer, 'touchstart', onEdgeTouchStart, { passive: true }); - dom.addEventListener(edgeContainer, "touchend", onEdgeTouchEnd, { + dom.addEventListener(edgeContainer, 'touchend', onEdgeTouchEnd, { passive: true }); - dom.addEventListener(edgeContainer, "touchcancel", onEdgeTouchEnd, { + dom.addEventListener(edgeContainer, 'touchcancel', onEdgeTouchEnd, { passive: true }); } } else { if (_edgeSwipeEnabled) { _edgeSwipeEnabled = false; - dom.removeEventListener(edgeContainer, "touchstart", onEdgeTouchStart, { + dom.removeEventListener(edgeContainer, 'touchstart', onEdgeTouchStart, { passive: true }); - dom.removeEventListener(edgeContainer, "touchend", onEdgeTouchEnd, { + dom.removeEventListener(edgeContainer, 'touchend', onEdgeTouchEnd, { passive: true }); - dom.removeEventListener(edgeContainer, "touchcancel", onEdgeTouchEnd, { + dom.removeEventListener(edgeContainer, 'touchcancel', onEdgeTouchEnd, { passive: true }); } @@ -320,26 +320,26 @@ define(["browser", "dom", "css!./navdrawer", "scrollStyles"], function (browser, self.initElements(); if (browser.touch) { - dom.addEventListener(options.target, "touchstart", onMenuTouchStart, { + dom.addEventListener(options.target, 'touchstart', onMenuTouchStart, { passive: true }); - dom.addEventListener(options.target, "touchmove", onMenuTouchMove, { + dom.addEventListener(options.target, 'touchmove', onMenuTouchMove, { passive: true }); - dom.addEventListener(options.target, "touchend", onMenuTouchEnd, { + dom.addEventListener(options.target, 'touchend', onMenuTouchEnd, { passive: true }); - dom.addEventListener(options.target, "touchcancel", onMenuTouchEnd, { + dom.addEventListener(options.target, 'touchcancel', onMenuTouchEnd, { passive: true }); - dom.addEventListener(mask, "touchstart", onBackgroundTouchStart, { + dom.addEventListener(mask, 'touchstart', onBackgroundTouchStart, { passive: true }); - dom.addEventListener(mask, "touchmove", onBackgroundTouchMove, {}); - dom.addEventListener(mask, "touchend", onBackgroundTouchEnd, { + dom.addEventListener(mask, 'touchmove', onBackgroundTouchMove, {}); + dom.addEventListener(mask, 'touchend', onBackgroundTouchEnd, { passive: true }); - dom.addEventListener(mask, "touchcancel", onBackgroundTouchEnd, { + dom.addEventListener(mask, 'touchcancel', onBackgroundTouchEnd, { passive: true }); } diff --git a/src/libraries/scroller.js b/src/libraries/scroller.js index 645a8ea85c..464b31059d 100644 --- a/src/libraries/scroller.js +++ b/src/libraries/scroller.js @@ -52,8 +52,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc var dragTouchEvents = ['touchmove', 'touchend']; var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel' : 'mousewheel'); var interactiveElements = ['INPUT', 'SELECT', 'TEXTAREA']; - var tmpArray = []; - var time; // Math shorthands var abs = Math.abs; @@ -61,10 +59,8 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc var pow = Math.pow; var round = Math.round; var max = Math.max; - var min = Math.min; var scrollerFactory = function (frame, options) { - // Extend options var o = Object.assign({}, { slidee: null, // Selector, DOM element, or jQuery object with DOM element representing SLIDEE. @@ -97,11 +93,9 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc // native smooth scroll options.enableNativeScroll = true; } else if (options.requireAnimation && (browser.animate || browser.supportsCssAnimation())) { - // transform is the only way to guarantee animation options.enableNativeScroll = false; } else if (!layoutManager.tv || !browser.animate) { - options.enableNativeScroll = true; } @@ -162,9 +156,7 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc var frameSize = 0; var slideeSize = 0; function ensureSizeInfo() { - if (requiresReflow) { - requiresReflow = false; // Reset global variables @@ -186,11 +178,9 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @return {Void} */ function load(isInit) { - requiresReflow = true; if (!isInit) { - ensureSizeInfo(); // Fix possible overflowing @@ -200,7 +190,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } function initFrameResizeObserver() { - var observerOptions = {}; self.frameResizeObserver = new ResizeObserver(onResize, observerOptions); @@ -225,16 +214,13 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc }; function nativeScrollTo(container, pos, immediate) { - if (container.scroll) { if (o.horizontal) { - container.scroll({ left: pos, behavior: immediate ? 'instant' : 'smooth' }); } else { - container.scroll({ top: pos, behavior: immediate ? 'instant' : 'smooth' @@ -266,14 +252,12 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @return {Void} */ self.slideTo = function (newPos, immediate, fullItemPos) { - ensureSizeInfo(); var pos = self._pos; newPos = within(newPos, pos.start, pos.end); if (!transform) { - nativeScrollTo(nativeScrollElement, newPos, immediate); return; } @@ -291,7 +275,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } if (!immediate && o.skipSlideToWhenVisible && fullItemPos && fullItemPos.isVisible) { - return; } @@ -303,7 +286,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc }; function setStyleProperty(elem, name, value, speed, resetTransition) { - var style = elem.style; if (resetTransition || browser.edge) { @@ -325,7 +307,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } function renderAnimateWithTransform(fromPosition, toPosition, immediate) { - var speed = o.speed; if (immediate) { @@ -343,7 +324,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } function getBoundingClientRect(elem) { - // Support: BlackBerry 5, iOS 3 (original iPhone) // If we don't have gBCR, just use 0,0 rather than error if (elem.getBoundingClientRect) { @@ -361,14 +341,10 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @return {Object} */ self.getPos = function (item) { - var scrollElement = transform ? slideeElement : nativeScrollElement; var slideeOffset = getBoundingClientRect(scrollElement); var itemOffset = getBoundingClientRect(item); - var slideeStartPos = o.horizontal ? slideeOffset.left : slideeOffset.top; - var slideeEndPos = o.horizontal ? slideeOffset.right : slideeOffset.bottom; - var offset = o.horizontal ? itemOffset.left - slideeOffset.left : itemOffset.top - slideeOffset.top; var size = o.horizontal ? itemOffset.width : itemOffset.height; @@ -405,7 +381,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc }; self.getCenterPosition = function (item) { - ensureSizeInfo(); var pos = self.getPos(item); @@ -450,7 +425,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc // Bind dragging events if (transform) { - if (isTouch) { dragTouchEvents.forEach(function (eventName) { dom.addEventListener(document, eventName, dragHandler, { @@ -554,9 +528,7 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @return {Boolean} */ function isInteractive(element) { - while (element) { - if (interactiveElements.indexOf(element.tagName) !== -1) { return true; } @@ -592,7 +564,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @return {Void} */ function scrollHandler(event) { - ensureSizeInfo(); var pos = self._pos; // Ignore if there is no scrolling to be done @@ -609,7 +580,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc self.slideBy(o.scrollBy * delta); } else { - if (isSmoothScrollSupported) { delta *= 12; } @@ -628,7 +598,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc * @return {Void} */ self.destroy = function () { - if (self.frameResizeObserver) { self.frameResizeObserver.disconnect(); self.frameResizeObserver = null; @@ -664,11 +633,9 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc var contentRect = {}; function onResize(entries) { - var entry = entries[0]; if (entry) { - var newRect = entry.contentRect; // handle element being hidden @@ -677,7 +644,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } if (newRect.width !== contentRect.width || newRect.height !== contentRect.height) { - contentRect = newRect; load(false); @@ -703,7 +669,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc } self.getScrollPosition = function () { - if (transform) { return self._pos.cur; } @@ -716,7 +681,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc }; self.getScrollSize = function () { - if (transform) { return slideeSize; } @@ -792,7 +756,6 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc initFrameResizeObserver(); if (transform) { - dom.addEventListener(dragSourceElement, 'touchstart', dragInitSlidee, { passive: true }); @@ -809,9 +772,7 @@ define(['browser', 'layoutManager', 'dom', 'focusManager', 'ResizeObserver', 'sc passive: true }); } - } else if (o.horizontal) { - // Don't bind to mouse events with vertical scroll since the mouse wheel can handle this natively if (o.mouseWheel) { From 612d74fd2c2054c17f96549238935ebab4c2d4ab Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 28 Jul 2020 22:04:01 +0100 Subject: [PATCH 019/226] Migration of home and librarymenu to ES6 modules --- package.json | 2 + .../dashboard/plugins/available/index.js | 2 + .../dashboard/plugins/installed/index.js | 2 + src/controllers/home.js | 118 +++++----- src/controllers/itemDetails/index.js | 2 + src/controllers/movies/moviesrecommended.js | 2 + src/controllers/music/musicrecommended.js | 2 + src/scripts/libraryMenu.js | 216 ++++++++++-------- 8 files changed, 190 insertions(+), 156 deletions(-) diff --git a/package.json b/package.json index edda337f2c..6276da0e43 100644 --- a/package.json +++ b/package.json @@ -188,6 +188,7 @@ "src/controllers/dashboard/users/userparentalcontrol.js", "src/controllers/dashboard/users/userpasswordpage.js", "src/controllers/dashboard/users/userprofilespage.js", + "src/controllers/home.js", "src/controllers/playback/queue/index.js", "src/controllers/playback/video/index.js", "src/controllers/searchpage.js", @@ -248,6 +249,7 @@ "src/scripts/imagehelper.js", "src/scripts/inputManager.js", "src/scripts/keyboardNavigation.js", + "src/scripts/libraryMenu.js", "src/scripts/playlists.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", diff --git a/src/controllers/dashboard/plugins/available/index.js b/src/controllers/dashboard/plugins/available/index.js index 1f202d6ff6..473b1b8961 100644 --- a/src/controllers/dashboard/plugins/available/index.js +++ b/src/controllers/dashboard/plugins/available/index.js @@ -1,6 +1,8 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby-checkbox', 'emby-select'], function (loading, libraryMenu, globalize) { 'use strict'; + libraryMenu = LibraryMenu.default || libraryMenu; + function reloadList(page) { loading.show(); var promise1 = ApiClient.getAvailablePlugins(); diff --git a/src/controllers/dashboard/plugins/installed/index.js b/src/controllers/dashboard/plugins/installed/index.js index d28a04cb2b..014fbf16c2 100644 --- a/src/controllers/dashboard/plugins/installed/index.js +++ b/src/controllers/dashboard/plugins/installed/index.js @@ -1,6 +1,8 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'], function (loading, libraryMenu, dom, globalize) { 'use strict'; + libraryMenu = LibraryMenu.default || libraryMenu; + function deletePlugin(page, uniqueid, name) { var msg = globalize.translate('UninstallPluginConfirmation', name); diff --git a/src/controllers/home.js b/src/controllers/home.js index 9a4cea2227..f3e9e8e22b 100644 --- a/src/controllers/home.js +++ b/src/controllers/home.js @@ -1,75 +1,77 @@ -define(['tabbedView', 'globalize', 'require', 'emby-tabs', 'emby-button', 'emby-scroller'], function (TabbedView, globalize, require) { - 'use strict'; +import TabbedView from 'tabbedView'; +import globalize from 'globalize'; +import require from 'require'; +import 'emby-tabs'; +import 'emby-button'; +import 'emby-scroller'; - function getTabs() { - return [{ - name: globalize.translate('Home') - }, { - name: globalize.translate('Favorites') - }]; +function getTabs() { + return [{ + name: globalize.translate('Home') + }, { + name: globalize.translate('Favorites') + }]; +} + +function getDefaultTabIndex() { + return 0; +} + +function getRequirePromise(deps) { + return new Promise(function (resolve, reject) { + require(deps, resolve); + }); +} + +function getTabController(index) { + if (null == index) { + throw new Error('index cannot be null'); } - function getDefaultTabIndex() { - return 0; + const depends = []; + + switch (index) { + case 0: + depends.push('controllers/hometab'); + break; + + case 1: + depends.push('controllers/favorites'); } - function getRequirePromise(deps) { - return new Promise(function (resolve, reject) { - require(deps, resolve); - }); - } + const instance = this; + return getRequirePromise(depends).then(function (controllerFactory) { + let controller = instance.tabControllers[index]; - function getTabController(index) { - if (null == index) { - throw new Error('index cannot be null'); + if (!controller) { + controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params); + instance.tabControllers[index] = controller; } - var depends = []; + return controller; + }); +} - switch (index) { - case 0: - depends.push('controllers/hometab'); - break; - - case 1: - depends.push('controllers/favorites'); - } - - var instance = this; - return getRequirePromise(depends).then(function (controllerFactory) { - var controller = instance.tabControllers[index]; - - if (!controller) { - controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params); - instance.tabControllers[index] = controller; - } - - return controller; - }); - } - - function HomeView(view, params) { +class HomeView { + constructor(view, params) { TabbedView.call(this, view, params); } - - Object.assign(HomeView.prototype, TabbedView.prototype); - HomeView.prototype.getTabs = getTabs; - HomeView.prototype.getDefaultTabIndex = getDefaultTabIndex; - HomeView.prototype.getTabController = getTabController; - - HomeView.prototype.setTitle = function () { + setTitle() { Emby.Page.setTitle(null); - }; - - HomeView.prototype.onPause = function () { + } + onPause() { TabbedView.prototype.onPause.call(this); document.querySelector('.skinHeader').classList.remove('noHomeButtonHeader'); - }; - - HomeView.prototype.onResume = function (options) { + } + onResume(options) { TabbedView.prototype.onResume.call(this, options); document.querySelector('.skinHeader').classList.add('noHomeButtonHeader'); - }; + } +} - return HomeView; -}); +Object.assign(HomeView.prototype, TabbedView.prototype); +HomeView.prototype.getTabs = getTabs; +HomeView.prototype.getDefaultTabIndex = getDefaultTabIndex; +HomeView.prototype.getTabController = getTabController; + +export default HomeView; diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index 29aa8ad1e1..49412c4ac4 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -1,6 +1,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSettings', 'cardBuilder', 'datetime', 'mediaInfo', 'backdrop', 'listView', 'itemContextMenu', 'itemHelper', 'dom', 'indicators', 'imageLoader', 'libraryMenu', 'globalize', 'browser', 'events', 'playbackManager', 'scrollStyles', 'emby-itemscontainer', 'emby-checkbox', 'emby-button', 'emby-playstatebutton', 'emby-ratingbutton', 'emby-scroller', 'emby-select'], function (loading, appRouter, layoutManager, connectionManager, userSettings, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, dom, indicators, imageLoader, libraryMenu, globalize, browser, events, playbackManager) { 'use strict'; + libraryMenu = LibraryMenu.default || libraryMenu; + function getPromise(apiClient, params) { var id = params.id; diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js index 4ffe7888cf..96e98452db 100644 --- a/src/controllers/movies/moviesrecommended.js +++ b/src/controllers/movies/moviesrecommended.js @@ -1,6 +1,8 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu', 'mainTabsManager', 'cardBuilder', 'dom', 'imageLoader', 'playbackManager', 'globalize', 'emby-scroller', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager, globalize) { 'use strict'; + libraryMenu = LibraryMenu.default || libraryMenu; + function enableScrollX() { return !layoutManager.desktop; } diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js index 0eecef0bfb..01b907a893 100644 --- a/src/controllers/music/musicrecommended.js +++ b/src/controllers/music/musicrecommended.js @@ -1,6 +1,8 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', 'cardBuilder', 'dom', 'apphost', 'imageLoader', 'libraryMenu', 'playbackManager', 'mainTabsManager', 'globalize', 'scrollStyles', 'emby-itemscontainer', 'emby-tabs', 'emby-button', 'flexStyles'], function (browser, layoutManager, userSettings, inputManager, loading, cardBuilder, dom, appHost, imageLoader, libraryMenu, playbackManager, mainTabsManager, globalize) { 'use strict'; + libraryMenu = LibraryMenu.default || libraryMenu; + function itemsPerRow() { var screenWidth = dom.getWindowSize().innerWidth; diff --git a/src/scripts/libraryMenu.js b/src/scripts/libraryMenu.js index 961d89dc05..86a8d38079 100644 --- a/src/scripts/libraryMenu.js +++ b/src/scripts/libraryMenu.js @@ -1,8 +1,26 @@ -define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', 'viewManager', 'libraryBrowser', 'appRouter', 'apphost', 'playbackManager', 'syncPlayManager', 'groupSelectionMenu', 'browser', 'globalize', 'scripts/imagehelper', 'paper-icon-button-light', 'material-icons', 'scrollStyles', 'flexStyles'], function (dom, layoutManager, inputManager, connectionManager, events, viewManager, libraryBrowser, appRouter, appHost, playbackManager, syncPlayManager, groupSelectionMenu, browser, globalize, imageHelper) { - 'use strict'; +import dom from 'dom'; +import layoutManager from 'layoutManager'; +import inputManager from 'inputManager'; +import connectionManager from 'connectionManager'; +import events from 'events'; +import viewManager from 'viewManager'; +import appRouter from 'appRouter'; +import appHost from 'apphost'; +import playbackManager from 'playbackManager'; +import syncPlayManager from 'syncPlayManager'; +import groupSelectionMenu from 'groupSelectionMenu'; +import browser from 'browser'; +import globalize from 'globalize'; +import imageHelper from 'scripts/imagehelper'; +import 'paper-icon-button-light'; +import 'material-icons'; +import 'scrollStyles'; +import 'flexStyles'; + +/* eslint-disable indent */ function renderHeader() { - var html = ''; + let html = ''; html += '
'; html += '
'; html += ''; @@ -56,11 +74,11 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function updateUserInHeader(user) { - var hasImage; + let hasImage; if (user && user.name) { if (user.imageUrl) { - var url = user.imageUrl; + const url = user.imageUrl; updateHeaderUserButton(url); hasImage = true; } @@ -87,9 +105,9 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' headerCastButton.classList.remove('hide'); } - var policy = user.Policy ? user.Policy : user.localUser.Policy; + const policy = user.Policy ? user.Policy : user.localUser.Policy; - var apiClient = getCurrentApiClient(); + const apiClient = getCurrentApiClient(); if (headerSyncButton && policy && policy.SyncPlayAccess !== 'None' && apiClient.isMinServerVersion('10.6.0')) { headerSyncButton.classList.remove('hide'); } @@ -139,7 +157,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' mainDrawerButton.addEventListener('click', toggleMainDrawer); } - var headerBackButton = skinHeader.querySelector('.headerBackButton'); + const headerBackButton = skinHeader.querySelector('.headerBackButton'); if (headerBackButton) { headerBackButton.addEventListener('click', onBackClick); @@ -181,7 +199,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function onCastButtonClicked() { - var btn = this; + const btn = this; require(['playerSelectionMenu'], function (playerSelectionMenu) { playerSelectionMenu.show(btn); @@ -189,12 +207,12 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function onSyncButtonClicked() { - var btn = this; + const btn = this; groupSelectionMenu.show(btn); } function onSyncPlayEnabled(event, enabled) { - var icon = headerSyncButton.querySelector('span'); + const icon = headerSyncButton.querySelector('span'); icon.classList.remove('sync', 'sync_disabled', 'sync_problem'); if (enabled) { icon.classList.add('sync'); @@ -204,7 +222,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function onSyncPlaySyncing(event, is_syncing, syncMethod) { - var icon = headerSyncButton.querySelector('span'); + const icon = headerSyncButton.querySelector('span'); icon.classList.remove('sync', 'sync_disabled', 'sync_problem'); if (is_syncing) { icon.classList.add('sync_problem'); @@ -250,7 +268,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function refreshLibraryInfoInDrawer(user, drawer) { - var html = ''; + let html = ''; html += '
'; html += '' + globalize.translate('ButtonHome') + ''; @@ -286,12 +304,12 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' // add buttons to navigation drawer navDrawerScrollContainer.innerHTML = html; - var btnSettings = navDrawerScrollContainer.querySelector('.btnSettings'); + const btnSettings = navDrawerScrollContainer.querySelector('.btnSettings'); if (btnSettings) { btnSettings.addEventListener('click', onSettingsClick); } - var btnLogout = navDrawerScrollContainer.querySelector('.btnLogout'); + const btnLogout = navDrawerScrollContainer.querySelector('.btnLogout'); if (btnLogout) { btnLogout.addEventListener('click', onLogoutClick); } @@ -313,20 +331,20 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function updateDashboardMenuSelectedItem() { - var links = navDrawerScrollContainer.querySelectorAll('.navMenuOption'); - var currentViewId = viewManager.currentView().id; + const links = navDrawerScrollContainer.querySelectorAll('.navMenuOption'); + const currentViewId = viewManager.currentView().id; - for (var i = 0, length = links.length; i < length; i++) { - var link = links[i]; - var selected = false; - var pageIds = link.getAttribute('data-pageids'); + for (let i = 0, length = links.length; i < length; i++) { + let link = links[i]; + let selected = false; + let pageIds = link.getAttribute('data-pageids'); if (pageIds) { pageIds = pageIds.split('|'); selected = -1 != pageIds.indexOf(currentViewId); } - var pageUrls = link.getAttribute('data-pageurls'); + let pageUrls = link.getAttribute('data-pageurls'); if (pageUrls) { pageUrls = pageUrls.split('|'); @@ -335,7 +353,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' if (selected) { link.classList.add('navMenuOption-selected'); - var title = ''; + let title = ''; link = link.querySelector('.navMenuOptionText') || link; title += (link.innerText || link.textContent).trim(); LibraryMenu.setTitle(title); @@ -346,7 +364,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function createToolsMenuList(pluginItems) { - var links = [{ + const links = [{ name: globalize.translate('TabServer') }, { name: globalize.translate('TabDashboard'), @@ -458,8 +476,8 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function addPluginPagesToMainMenu(links, pluginItems, section) { - for (var i = 0, length = pluginItems.length; i < length; i++) { - var pluginItem = pluginItems[i]; + for (let i = 0, length = pluginItems.length; i < length; i++) { + const pluginItem = pluginItems[i]; if (pluginItem.EnableInMainMenu && pluginItem.MenuSection === section) { links.push({ @@ -479,10 +497,10 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function getToolsLinkHtml(item) { - var menuHtml = ''; - var pageIds = item.pageIds ? item.pageIds.join('|') : ''; + let menuHtml = ''; + let pageIds = item.pageIds ? item.pageIds.join('|') : ''; pageIds = pageIds ? ' data-pageids="' + pageIds + '"' : ''; - var pageUrls = item.pageUrls ? item.pageUrls.join('|') : ''; + let pageUrls = item.pageUrls ? item.pageUrls.join('|') : ''; pageUrls = pageUrls ? ' data-pageurls="' + pageUrls + '"' : ''; menuHtml += ''; @@ -498,11 +516,11 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' function getToolsMenuHtml(apiClient) { return getToolsMenuLinks(apiClient).then(function (items) { - var item; - var menuHtml = ''; + let item; + let menuHtml = ''; menuHtml += '
'; - for (var i = 0; i < items.length; i++) { + for (let i = 0; i < items.length; i++) { item = items[i]; if (item.href) { @@ -520,7 +538,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' function createDashboardMenu(apiClient) { return getToolsMenuHtml(apiClient).then(function (toolsMenuHtml) { - var html = ''; + let html = ''; html += ''; @@ -531,24 +549,24 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function onSidebarLinkClick() { - var section = this.getElementsByClassName('sectionName')[0]; - var text = section ? section.innerHTML : this.innerHTML; + const section = this.getElementsByClassName('sectionName')[0]; + const text = section ? section.innerHTML : this.innerHTML; LibraryMenu.setTitle(text); } function getUserViews(apiClient, userId) { return apiClient.getUserViews({}, userId).then(function (result) { - var items = result.Items; - var list = []; + const items = result.Items; + const list = []; - for (var i = 0, length = items.length; i < length; i++) { - var view = items[i]; + for (let i = 0, length = items.length; i < length; i++) { + const view = items[i]; list.push(view); if ('livetv' == view.CollectionType) { view.ImageTags = {}; view.icon = 'live_tv'; - var guideView = Object.assign({}, view); + const guideView = Object.assign({}, view); guideView.Name = globalize.translate('ButtonGuide'); guideView.ImageTags = {}; guideView.icon = 'dvr'; @@ -562,7 +580,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function showBySelector(selector, show) { - var elem = document.querySelector(selector); + const elem = document.querySelector(selector); if (elem) { if (show) { @@ -592,17 +610,17 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' showBySelector('.libraryMenuDownloads', false); } - var userId = Dashboard.getCurrentUserId(); - var apiClient = getCurrentApiClient(); - var libraryMenuOptions = document.querySelector('.libraryMenuOptions'); + const userId = Dashboard.getCurrentUserId(); + const apiClient = getCurrentApiClient(); + const libraryMenuOptions = document.querySelector('.libraryMenuOptions'); if (libraryMenuOptions) { getUserViews(apiClient, userId).then(function (result) { - var items = result; - var html = `

${globalize.translate('HeaderMedia')}

`; + const items = result; + let html = `

${globalize.translate('HeaderMedia')}

`; html += items.map(function (i) { - var icon = i.icon || imageHelper.getLibraryIcon(i.CollectionType); - var itemId = i.Id; + const icon = i.icon || imageHelper.getLibraryIcon(i.CollectionType); + const itemId = i.Id; const linkHtml = ` @@ -612,8 +630,8 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' return linkHtml; }).join(''); libraryMenuOptions.innerHTML = html; - var elem = libraryMenuOptions; - var sidebarLinks = elem.querySelectorAll('.navMenuOption'); + const elem = libraryMenuOptions; + const sidebarLinks = elem.querySelectorAll('.navMenuOption'); for (const sidebarLink of sidebarLinks) { sidebarLink.removeEventListener('click', onSidebarLinkClick); @@ -642,9 +660,9 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function updateCastIcon() { - var context = document; - var info = playbackManager.getPlayerInfo(); - var icon = headerCastButton.querySelector('.material-icons'); + const context = document; + const info = playbackManager.getPlayerInfo(); + const icon = headerCastButton.querySelector('.material-icons'); icon.classList.remove('cast_connected', 'cast'); @@ -660,18 +678,16 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function updateLibraryNavLinks(page) { - var i; - var length; - var isLiveTvPage = page.classList.contains('liveTvPage'); - var isChannelsPage = page.classList.contains('channelsPage'); - var isEditorPage = page.classList.contains('metadataEditorPage'); - var isMySyncPage = page.classList.contains('mySyncPage'); - var id = isLiveTvPage || isChannelsPage || isEditorPage || isMySyncPage || page.classList.contains('allLibraryPage') ? '' : getTopParentId() || ''; - var elems = document.getElementsByClassName('lnkMediaFolder'); + const isLiveTvPage = page.classList.contains('liveTvPage'); + const isChannelsPage = page.classList.contains('channelsPage'); + const isEditorPage = page.classList.contains('metadataEditorPage'); + const isMySyncPage = page.classList.contains('mySyncPage'); + const id = isLiveTvPage || isChannelsPage || isEditorPage || isMySyncPage || page.classList.contains('allLibraryPage') ? '' : getTopParentId() || ''; + const elems = document.getElementsByClassName('lnkMediaFolder'); - for (var i = 0, length = elems.length; i < length; i++) { - var lnkMediaFolder = elems[i]; - var itemId = lnkMediaFolder.getAttribute('data-itemid'); + for (let i = 0, length = elems.length; i < length; i++) { + const lnkMediaFolder = elems[i]; + const itemId = lnkMediaFolder.getAttribute('data-itemid'); if (isChannelsPage && 'channels' === itemId) { lnkMediaFolder.classList.add('navMenuOption-selected'); @@ -692,7 +708,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function updateMenuForPageType(isDashboardPage, isLibraryPage) { - var newPageType = isDashboardPage ? 2 : isLibraryPage ? 1 : 3; + const newPageType = isDashboardPage ? 2 : isLibraryPage ? 1 : 3; if (currentPageType !== newPageType) { currentPageType = newPageType; @@ -703,7 +719,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' skinHeader.classList.remove('headroomDisabled'); } - var bodyClassList = document.body.classList; + const bodyClassList = document.body.classList; if (isLibraryPage) { bodyClassList.add('libraryDocument'); @@ -740,7 +756,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function updateTitle(page) { - var title = page.getAttribute('data-title'); + const title = page.getAttribute('data-title'); if (title) { LibraryMenu.setTitle(title); @@ -765,7 +781,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' function initHeadRoom(elem) { require(['headroom'], function (Headroom) { - var headroom = new Headroom(elem); + const headroom = new Headroom(elem); headroom.init(); }); } @@ -785,7 +801,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function getNavDrawerOptions() { - var drawerWidth = screen.availWidth - 50; + let drawerWidth = screen.availWidth - 50; drawerWidth = Math.max(drawerWidth, 240); drawerWidth = Math.min(drawerWidth, 320); return { @@ -816,25 +832,25 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' }); } - var navDrawerElement; - var navDrawerScrollContainer; - var navDrawerInstance; - var mainDrawerButton; - var headerHomeButton; - var currentDrawerType; - var pageTitleElement; - var headerBackButton; - var headerUserButton; - var currentUser; - var headerCastButton; - var headerSearchButton; - var headerAudioPlayerButton; - var headerSyncButton; - var enableLibraryNavDrawer = layoutManager.desktop; - var enableLibraryNavDrawerHome = !layoutManager.tv; - var skinHeader = document.querySelector('.skinHeader'); - var requiresUserRefresh = true; - window.LibraryMenu = { + let navDrawerElement; + let navDrawerScrollContainer; + let navDrawerInstance; + let mainDrawerButton; + let headerHomeButton; + let currentDrawerType; + let pageTitleElement; + let headerBackButton; + let headerUserButton; + let currentUser; + let headerCastButton; + let headerSearchButton; + let headerAudioPlayerButton; + let headerSyncButton; + const enableLibraryNavDrawer = layoutManager.desktop; + const enableLibraryNavDrawerHome = !layoutManager.tv; + const skinHeader = document.querySelector('.skinHeader'); + let requiresUserRefresh = true; + const LibraryMenu = { getTopParentId: getTopParentId, onHardwareMenuButtonClick: function () { toggleMainDrawer(); @@ -873,7 +889,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' title = ''; } - var html = title; + const html = title; if (!pageTitleElement) { pageTitleElement = document.querySelector('.pageTitle'); @@ -896,18 +912,18 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } } }; - var currentPageType; + let currentPageType; pageClassOn('pagebeforeshow', 'page', function (e) { if (!this.classList.contains('withTabs')) { LibraryMenu.setTabs(null); } }); pageClassOn('pageshow', 'page', function (e) { - var page = this; - var isDashboardPage = page.classList.contains('type-interior'); - var isHomePage = page.classList.contains('homePage'); - var isLibraryPage = !isDashboardPage && page.classList.contains('libraryPage'); - var apiClient = getCurrentApiClient(); + const page = this; + const isDashboardPage = page.classList.contains('type-interior'); + const isHomePage = page.classList.contains('homePage'); + const isLibraryPage = !isDashboardPage && page.classList.contains('libraryPage'); + const apiClient = getCurrentApiClient(); if (isDashboardPage) { if (mainDrawerButton) { @@ -944,7 +960,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' renderHeader(); events.on(connectionManager, 'localusersignedin', function (e, user) { - var currentApiClient = connectionManager.getApiClient(user.ServerId); + const currentApiClient = connectionManager.getApiClient(user.ServerId); currentDrawerType = null; currentUser = { @@ -968,5 +984,9 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' events.on(syncPlayManager, 'syncing', onSyncPlaySyncing); loadNavDrawer(); - return LibraryMenu; -}); + + window.LibraryMenu = LibraryMenu; + +export default LibraryMenu; + +/* eslint-enable indent */ From 00a545dae350daf20b671ee184ebb9f7e5430534 Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 28 Jul 2020 22:09:56 +0100 Subject: [PATCH 020/226] extraction of functions --- src/scripts/libraryMenu.js | 129 ++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 58 deletions(-) diff --git a/src/scripts/libraryMenu.js b/src/scripts/libraryMenu.js index 86a8d38079..594bb79f20 100644 --- a/src/scripts/libraryMenu.js +++ b/src/scripts/libraryMenu.js @@ -850,74 +850,74 @@ import 'flexStyles'; const enableLibraryNavDrawerHome = !layoutManager.tv; const skinHeader = document.querySelector('.skinHeader'); let requiresUserRefresh = true; - const LibraryMenu = { - getTopParentId: getTopParentId, - onHardwareMenuButtonClick: function () { - toggleMainDrawer(); - }, - setTabs: function (type, selectedIndex, builder) { - require(['mainTabsManager'], function (mainTabsManager) { - if (type) { - mainTabsManager.setTabs(viewManager.currentView(), selectedIndex, builder, function () { - return []; - }); - } else { - mainTabsManager.setTabs(null); - } - }); - }, - setDefaultTitle: function () { - if (!pageTitleElement) { - pageTitleElement = document.querySelector('.pageTitle'); - } - if (pageTitleElement) { - pageTitleElement.classList.add('pageTitleWithLogo'); - pageTitleElement.classList.add('pageTitleWithDefaultLogo'); - pageTitleElement.style.backgroundImage = null; - pageTitleElement.innerHTML = ''; - } - - document.title = 'Jellyfin'; - }, - setTitle: function (title) { - if (null == title) { - return void LibraryMenu.setDefaultTitle(); - } - - if ('-' === title) { - title = ''; - } - - const html = title; - - if (!pageTitleElement) { - pageTitleElement = document.querySelector('.pageTitle'); - } - - if (pageTitleElement) { - pageTitleElement.classList.remove('pageTitleWithLogo'); - pageTitleElement.classList.remove('pageTitleWithDefaultLogo'); - pageTitleElement.style.backgroundImage = null; - pageTitleElement.innerHTML = html || ''; - } - - document.title = title || 'Jellyfin'; - }, - setTransparentMenu: function (transparent) { - if (transparent) { - skinHeader.classList.add('semiTransparent'); + function setTabs (type, selectedIndex, builder) { + require(['mainTabsManager'], function (mainTabsManager) { + if (type) { + mainTabsManager.setTabs(viewManager.currentView(), selectedIndex, builder, function () { + return []; + }); } else { - skinHeader.classList.remove('semiTransparent'); + mainTabsManager.setTabs(null); } + }); + } + + function setDefaultTitle () { + if (!pageTitleElement) { + pageTitleElement = document.querySelector('.pageTitle'); } - }; + + if (pageTitleElement) { + pageTitleElement.classList.add('pageTitleWithLogo'); + pageTitleElement.classList.add('pageTitleWithDefaultLogo'); + pageTitleElement.style.backgroundImage = null; + pageTitleElement.innerHTML = ''; + } + + document.title = 'Jellyfin'; + } + + function setTitle (title) { + if (null == title) { + return void LibraryMenu.setDefaultTitle(); + } + + if ('-' === title) { + title = ''; + } + + const html = title; + + if (!pageTitleElement) { + pageTitleElement = document.querySelector('.pageTitle'); + } + + if (pageTitleElement) { + pageTitleElement.classList.remove('pageTitleWithLogo'); + pageTitleElement.classList.remove('pageTitleWithDefaultLogo'); + pageTitleElement.style.backgroundImage = null; + pageTitleElement.innerHTML = html || ''; + } + + document.title = title || 'Jellyfin'; + } + + function setTransparentMenu (transparent) { + if (transparent) { + skinHeader.classList.add('semiTransparent'); + } else { + skinHeader.classList.remove('semiTransparent'); + } + } + let currentPageType; pageClassOn('pagebeforeshow', 'page', function (e) { if (!this.classList.contains('withTabs')) { LibraryMenu.setTabs(null); } }); + pageClassOn('pageshow', 'page', function (e) { const page = this; const isDashboardPage = page.classList.contains('type-interior'); @@ -974,10 +974,12 @@ import 'flexStyles'; updateUserInHeader(user); }); }); + events.on(connectionManager, 'localusersignedout', function () { currentUser = {}; updateUserInHeader(); }); + events.on(playbackManager, 'playerchange', updateCastIcon); events.on(syncPlayManager, 'enabled', onSyncPlayEnabled); @@ -985,6 +987,17 @@ import 'flexStyles'; loadNavDrawer(); + const LibraryMenu = { + getTopParentId: getTopParentId, + onHardwareMenuButtonClick: function () { + toggleMainDrawer(); + }, + setTabs: setTabs, + setDefaultTitle: setDefaultTitle, + setTitle: setTitle, + setTransparentMenu: setTransparentMenu + }; + window.LibraryMenu = LibraryMenu; export default LibraryMenu; From 215a623a18cf859414cadb4051fefbce7051812e Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 28 Jul 2020 22:13:49 +0100 Subject: [PATCH 021/226] remove require --- src/scripts/libraryMenu.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/scripts/libraryMenu.js b/src/scripts/libraryMenu.js index 594bb79f20..f010fa15e3 100644 --- a/src/scripts/libraryMenu.js +++ b/src/scripts/libraryMenu.js @@ -64,7 +64,7 @@ import 'flexStyles'; } function lazyLoadViewMenuBarImages() { - require(['imageLoader'], function (imageLoader) { + import('imageLoader').then(({default: imageLoader}) => { imageLoader.lazyChildren(skinHeader); }); } @@ -201,7 +201,7 @@ import 'flexStyles'; function onCastButtonClicked() { const btn = this; - require(['playerSelectionMenu'], function (playerSelectionMenu) { + import('playerSelectionMenu').then(({default: playerSelectionMenu}) => { playerSelectionMenu.show(btn); }); } @@ -780,7 +780,7 @@ import 'flexStyles'; } function initHeadRoom(elem) { - require(['headroom'], function (Headroom) { + import('headroom').then(({default: Headroom}) => { const headroom = new Headroom(elem); headroom.init(); }); @@ -820,7 +820,7 @@ import 'flexStyles'; navDrawerScrollContainer = navDrawerElement.querySelector('.scrollContainer'); navDrawerScrollContainer.addEventListener('click', onMainDrawerClick); return new Promise(function (resolve, reject) { - require(['navdrawer'], function (navdrawer) { + import('navdrawer').then(({default: navdrawer}) => { navDrawerInstance = new navdrawer(getNavDrawerOptions()); if (!layoutManager.tv) { @@ -852,7 +852,7 @@ import 'flexStyles'; let requiresUserRefresh = true; function setTabs (type, selectedIndex, builder) { - require(['mainTabsManager'], function (mainTabsManager) { + import('mainTabsManager').then(({default: mainTabsManager}) => { if (type) { mainTabsManager.setTabs(viewManager.currentView(), selectedIndex, builder, function () { return []; From 675cad71d845cf0faaacbc82b01dd3f25812eea4 Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 28 Jul 2020 23:08:27 +0100 Subject: [PATCH 022/226] Migration of loading to ES6 module --- package.json | 1 + src/components/appRouter.js | 10 +- src/components/guide/guide.js | 2 + .../imageDownloader/imageDownloader.js | 2 + src/components/imageeditor/imageeditor.js | 2 + src/components/loading/loading.js | 118 +++++++++--------- src/components/playback/playbackmanager.js | 2 + .../recordingcreator/recordingeditor.js | 2 + .../recordingcreator/recordingfields.js | 2 + .../recordingcreator/recordinghelper.js | 2 + .../recordingcreator/seriesrecordingeditor.js | 2 + src/components/refreshdialog/refreshdialog.js | 2 + .../subtitleeditor/subtitleeditor.js | 2 + src/components/tunerPicker.js | 2 + src/components/tvproviders/schedulesdirect.js | 2 + src/components/tvproviders/xmltv.js | 2 + .../notifications/notifications/index.js | 2 + .../dashboard/plugins/add/index.js | 2 + .../dashboard/plugins/available/index.js | 2 + .../dashboard/plugins/installed/index.js | 2 + src/controllers/edititemmetadata.js | 2 + src/controllers/hometab.js | 2 + src/controllers/itemDetails/index.js | 2 + src/controllers/list.js | 2 + src/controllers/livetv/livetvchannels.js | 2 + src/controllers/livetv/livetvrecordings.js | 2 + src/controllers/livetv/livetvschedule.js | 2 + src/controllers/livetv/livetvseriestimers.js | 2 + src/controllers/livetv/livetvsuggested.js | 2 + src/controllers/livetvguideprovider.js | 2 + src/controllers/livetvsettings.js | 2 + src/controllers/livetvstatus.js | 2 + src/controllers/livetvtuner.js | 2 + src/controllers/movies/moviecollections.js | 2 + src/controllers/movies/moviegenres.js | 2 + src/controllers/movies/movies.js | 2 + src/controllers/movies/movietrailers.js | 2 + src/controllers/music/musicalbums.js | 2 + src/controllers/music/musicartists.js | 2 + src/controllers/music/musicgenres.js | 2 + src/controllers/music/musicplaylists.js | 2 + src/controllers/music/musicrecommended.js | 2 + src/controllers/music/songs.js | 2 + src/plugins/htmlVideoPlayer/plugin.js | 2 + src/scripts/site.js | 2 +- 45 files changed, 146 insertions(+), 67 deletions(-) diff --git a/package.json b/package.json index edda337f2c..f2ae59522b 100644 --- a/package.json +++ b/package.json @@ -122,6 +122,7 @@ "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", "src/components/libraryoptionseditor/libraryoptionseditor.js", "src/components/listview/listview.js", + "src/components/loading/loading.js", "src/components/maintabsmanager.js", "src/components/mediainfo/mediainfo.js", "src/components/mediaLibraryCreator/mediaLibraryCreator.js", diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 138d58e5c0..e4c53fbbb8 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -22,7 +22,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro function beginConnectionWizard() { backdrop.clearBackdrop(); - loading.show(); + loading.default.show(); connectionManager.connect({ enableAutoLogin: appSettings.enableAutoLogin() }).then(function (result) { @@ -33,7 +33,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro function handleConnectionResult(result) { switch (result.State) { case 'SignedIn': - loading.hide(); + loading.default.hide(); skinManager.loadUserSkin(); break; case 'ServerSignIn': @@ -277,7 +277,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro var firstConnectionResult; function start(options) { - loading.show(); + loading.default.show(); initApiClients(); @@ -297,7 +297,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro hashbang: options.hashbang !== false }); }).catch().then(function() { - loading.hide(); + loading.default.hide(); }); } @@ -512,7 +512,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro if (currentRouteInfo && currentRouteInfo.path === path) { // can't use this with home right now due to the back menu if (currentRouteInfo.route.type !== 'home') { - loading.hide(); + loading.default.hide(); return Promise.resolve(); } } diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index bd3ad89aaa..abc7d81fee 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -1,6 +1,8 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'webcomponents'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) { 'use strict'; + loading = loading.default || loading; + function showViewSettings(instance) { require(['guide-settings-dialog'], function (guideSettingsDialog) { guideSettingsDialog.show(instance.categoryOptions).then(function () { diff --git a/src/components/imageDownloader/imageDownloader.js b/src/components/imageDownloader/imageDownloader.js index 8c278a62b6..d615b912fd 100644 --- a/src/components/imageDownloader/imageDownloader.js +++ b/src/components/imageDownloader/imageDownloader.js @@ -1,6 +1,8 @@ define(['dom', 'loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader', 'browser', 'layoutManager', 'scrollHelper', 'globalize', 'require', 'emby-checkbox', 'paper-icon-button-light', 'emby-button', 'formDialogStyle', 'cardStyle'], function (dom, loading, appHost, dialogHelper, connectionManager, imageLoader, browser, layoutManager, scrollHelper, globalize, require) { 'use strict'; + loading = loading.default || loading; + var enableFocusTransform = !browser.slow && !browser.edge; var currentItemId; diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index 125a2dc062..9a7b563d0f 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', 'focusManager', 'globalize', 'scrollHelper', 'imageLoader', 'require', 'browser', 'apphost', 'cardStyle', 'formDialogStyle', 'emby-button', 'paper-icon-button-light', 'css!./imageeditor'], function (dialogHelper, connectionManager, loading, dom, layoutManager, focusManager, globalize, scrollHelper, imageLoader, require, browser, appHost) { 'use strict'; + loading = loading.default || loading; + var enableFocusTransform = !browser.slow && !browser.edge; var currentItem; diff --git a/src/components/loading/loading.js b/src/components/loading/loading.js index 9f86ba452f..08271d4635 100644 --- a/src/components/loading/loading.js +++ b/src/components/loading/loading.js @@ -1,78 +1,74 @@ -define(['css!./loading'], function () { - 'use strict'; +import 'css!./loading'; - var loadingElem; - var layer1; - var layer2; - var layer3; - var layer4; - var circleLefts; - var circleRights; +let loadingElem; +let layer1; +let layer2; +let layer3; +let layer4; +let circleLefts; +let circleRights; - return { - show: function () { - var elem = loadingElem; +function show() { + let elem = loadingElem; - if (!elem) { - elem = document.createElement('div'); - loadingElem = elem; + if (!elem) { + elem = document.createElement('div'); + loadingElem = elem; - elem.classList.add('docspinner'); - elem.classList.add('mdl-spinner'); + elem.classList.add('docspinner'); + elem.classList.add('mdl-spinner'); - elem.innerHTML = '
'; + elem.innerHTML = '
'; - document.body.appendChild(elem); + document.body.appendChild(elem); - layer1 = elem.querySelector('.mdl-spinner__layer-1'); - layer2 = elem.querySelector('.mdl-spinner__layer-2'); - layer3 = elem.querySelector('.mdl-spinner__layer-3'); - layer4 = elem.querySelector('.mdl-spinner__layer-4'); + layer1 = elem.querySelector('.mdl-spinner__layer-1'); + layer2 = elem.querySelector('.mdl-spinner__layer-2'); + layer3 = elem.querySelector('.mdl-spinner__layer-3'); + layer4 = elem.querySelector('.mdl-spinner__layer-4'); - circleLefts = elem.querySelectorAll('.mdl-spinner__circleLeft'); - circleRights = elem.querySelectorAll('.mdl-spinner__circleRight'); - } + circleLefts = elem.querySelectorAll('.mdl-spinner__circleLeft'); + circleRights = elem.querySelectorAll('.mdl-spinner__circleRight'); + } - elem.classList.add('mdlSpinnerActive'); + elem.classList.add('mdlSpinnerActive'); - layer1.classList.add('mdl-spinner__layer-1-active'); - layer2.classList.add('mdl-spinner__layer-2-active'); - layer3.classList.add('mdl-spinner__layer-3-active'); - layer4.classList.add('mdl-spinner__layer-4-active'); + layer1.classList.add('mdl-spinner__layer-1-active'); + layer2.classList.add('mdl-spinner__layer-2-active'); + layer3.classList.add('mdl-spinner__layer-3-active'); + layer4.classList.add('mdl-spinner__layer-4-active'); - var i; - var length; + for (let i = 0, length = circleLefts.length; i < length; i++) { + circleLefts[i].classList.add('mdl-spinner__circleLeft-active'); + } - for (i = 0, length = circleLefts.length; i < length; i++) { - circleLefts[i].classList.add('mdl-spinner__circleLeft-active'); - } + for (let i = 0, length = circleRights.length; i < length; i++) { + circleRights[i].classList.add('mdl-spinner__circleRight-active'); + } +} - for (i = 0, length = circleRights.length; i < length; i++) { - circleRights[i].classList.add('mdl-spinner__circleRight-active'); - } - }, - hide: function () { - var elem = loadingElem; +function hide() { + const elem = loadingElem; - if (elem) { - elem.classList.remove('mdlSpinnerActive'); + if (elem) { + elem.classList.remove('mdlSpinnerActive'); - elem.classList.remove('mdl-spinner__layer-1-active'); - elem.classList.remove('mdl-spinner__layer-2-active'); - elem.classList.remove('mdl-spinner__layer-3-active'); - elem.classList.remove('mdl-spinner__layer-4-active'); + elem.classList.remove('mdl-spinner__layer-1-active'); + elem.classList.remove('mdl-spinner__layer-2-active'); + elem.classList.remove('mdl-spinner__layer-3-active'); + elem.classList.remove('mdl-spinner__layer-4-active'); - var i; - var length; - - for (i = 0, length = circleLefts.length; i < length; i++) { - circleLefts[i].classList.remove('mdl-spinner__circleLeft-active'); - } - - for (i = 0, length = circleRights.length; i < length; i++) { - circleRights[i].classList.remove('mdl-spinner__circleRight-active'); - } - } + for (let i = 0, length = circleLefts.length; i < length; i++) { + circleLefts[i].classList.remove('mdl-spinner__circleLeft-active'); } - }; -}); + + for (let i = 0, length = circleRights.length; i < length; i++) { + circleRights[i].classList.remove('mdl-spinner__circleRight-active'); + } + } +} + +export default { + show: show, + hide: hide +}; diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 829cd38f2c..85d5954d18 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -1,6 +1,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'playQueueManager', 'userSettings', 'globalize', 'connectionManager', 'loading', 'apphost', 'screenfull'], function (events, datetime, appSettings, itemHelper, pluginManager, PlayQueueManager, userSettings, globalize, connectionManager, loading, apphost, screenfull) { 'use strict'; + loading = loading.default || loading; + function enableLocalPlaylistManagement(player) { if (player.getPlaylist) { return false; diff --git a/src/components/recordingcreator/recordingeditor.js b/src/components/recordingcreator/recordingeditor.js index 3797cde370..2086129a9e 100644 --- a/src/components/recordingcreator/recordingeditor.js +++ b/src/components/recordingcreator/recordingeditor.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'imageLoader', 'scrollStyles', 'emby-button', 'emby-collapse', 'emby-input', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons', 'flexStyles'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper, imageLoader) { 'use strict'; + loading = loading.default || loading; + var currentDialog; var recordingDeleted = false; var currentItemId; diff --git a/src/components/recordingcreator/recordingfields.js b/src/components/recordingcreator/recordingfields.js index 2534eafe6a..e3739f1cfe 100644 --- a/src/components/recordingcreator/recordingfields.js +++ b/src/components/recordingcreator/recordingfields.js @@ -1,6 +1,8 @@ define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loading', 'apphost', 'dom', 'recordingHelper', 'events', 'paper-icon-button-light', 'emby-button', 'css!./recordingfields', 'flexStyles'], function (globalize, connectionManager, serverNotifications, require, loading, appHost, dom, recordingHelper, events) { 'use strict'; + loading = loading.default || loading; + function loadData(parent, program, apiClient) { if (program.IsSeries) { parent.querySelector('.recordSeriesContainer').classList.remove('hide'); diff --git a/src/components/recordingcreator/recordinghelper.js b/src/components/recordingcreator/recordinghelper.js index 4a0bdd9b01..5d72394282 100644 --- a/src/components/recordingcreator/recordinghelper.js +++ b/src/components/recordingcreator/recordinghelper.js @@ -1,6 +1,8 @@ define(['globalize', 'loading', 'connectionManager'], function (globalize, loading, connectionManager) { 'use strict'; + loading = loading.default || loading; + function changeRecordingToSeries(apiClient, timerId, programId, confirmTimerCancellation) { loading.show(); diff --git a/src/components/recordingcreator/seriesrecordingeditor.js b/src/components/recordingcreator/seriesrecordingeditor.js index ea20c7267d..b115e273e6 100644 --- a/src/components/recordingcreator/seriesrecordingeditor.js +++ b/src/components/recordingcreator/seriesrecordingeditor.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'imageLoader', 'datetime', 'scrollStyles', 'emby-button', 'emby-checkbox', 'emby-input', 'emby-select', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons', 'flexStyles'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper, imageLoader, datetime) { 'use strict'; + loading = loading.default || loading; + var currentDialog; var recordingUpdated = false; var recordingDeleted = false; diff --git a/src/components/refreshdialog/refreshdialog.js b/src/components/refreshdialog/refreshdialog.js index 40e1183502..57b2ee3189 100644 --- a/src/components/refreshdialog/refreshdialog.js +++ b/src/components/refreshdialog/refreshdialog.js @@ -1,6 +1,8 @@ define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionManager', 'appRouter', 'globalize', 'emby-input', 'emby-checkbox', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button'], function (dom, shell, dialogHelper, loading, layoutManager, connectionManager, appRouter, globalize) { 'use strict'; + loading = loading.default || loading; + function getEditorHtml() { var html = ''; diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js index 37f767524e..7df24b5da8 100644 --- a/src/components/subtitleeditor/subtitleeditor.js +++ b/src/components/subtitleeditor/subtitleeditor.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', 'connectionManager', 'loading', 'focusManager', 'dom', 'apphost', 'emby-select', 'listViewStyle', 'paper-icon-button-light', 'css!./../formdialog', 'material-icons', 'css!./subtitleeditor', 'emby-button', 'flexStyles'], function (dialogHelper, require, layoutManager, globalize, userSettings, connectionManager, loading, focusManager, dom, appHost) { 'use strict'; + loading = loading.default || loading; + var currentItem; var hasChanges; diff --git a/src/components/tunerPicker.js b/src/components/tunerPicker.js index e7c92851a4..de5c4cf186 100644 --- a/src/components/tunerPicker.js +++ b/src/components/tunerPicker.js @@ -1,6 +1,8 @@ define(['dialogHelper', 'dom', 'layoutManager', 'connectionManager', 'globalize', 'loading', 'browser', 'focusManager', 'scrollHelper', 'material-icons', 'formDialogStyle', 'emby-button', 'emby-itemscontainer', 'cardStyle'], function (dialogHelper, dom, layoutManager, connectionManager, globalize, loading, browser, focusManager, scrollHelper) { 'use strict'; + loading = loading.default || loading; + var enableFocusTransform = !browser.slow && !browser.edge; function getEditorHtml() { diff --git a/src/components/tvproviders/schedulesdirect.js b/src/components/tvproviders/schedulesdirect.js index be1cdf575b..e9bb6c4080 100644 --- a/src/components/tvproviders/schedulesdirect.js +++ b/src/components/tvproviders/schedulesdirect.js @@ -1,6 +1,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'listViewStyle', 'emby-input', 'emby-select', 'emby-button', 'flexStyles'], function ($, loading, globalize) { 'use strict'; + loading = loading.default || loading; + return function (page, providerId, options) { function reload() { loading.show(); diff --git a/src/components/tvproviders/xmltv.js b/src/components/tvproviders/xmltv.js index 054c5b640d..339451e1ab 100644 --- a/src/components/tvproviders/xmltv.js +++ b/src/components/tvproviders/xmltv.js @@ -1,6 +1,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'emby-input', 'listViewStyle', 'paper-icon-button-light'], function ($, loading, globalize) { 'use strict'; + loading = loading.default || loading; + return function (page, providerId, options) { function getListingProvider(config, id) { if (config && id) { diff --git a/src/controllers/dashboard/notifications/notifications/index.js b/src/controllers/dashboard/notifications/notifications/index.js index 4e049bc106..c2cf9d83c3 100644 --- a/src/controllers/dashboard/notifications/notifications/index.js +++ b/src/controllers/dashboard/notifications/notifications/index.js @@ -1,6 +1,8 @@ define(['loading', 'libraryMenu', 'globalize', 'listViewStyle', 'emby-button'], function(loading, libraryMenu, globalize) { 'use strict'; + loading = loading.default || loading; + function reload(page) { loading.show(); ApiClient.getJSON(ApiClient.getUrl('Notifications/Types')).then(function(list) { diff --git a/src/controllers/dashboard/plugins/add/index.js b/src/controllers/dashboard/plugins/add/index.js index a3c450dd79..c20b7832cd 100644 --- a/src/controllers/dashboard/plugins/add/index.js +++ b/src/controllers/dashboard/plugins/add/index.js @@ -1,6 +1,8 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'emby-button'], function ($, loading, libraryMenu, globalize, connectionManager) { 'use strict'; + loading = loading.default || loading; + function populateHistory(packageInfo, page) { var html = ''; var length = Math.min(packageInfo.versions.length, 10); diff --git a/src/controllers/dashboard/plugins/available/index.js b/src/controllers/dashboard/plugins/available/index.js index 1f202d6ff6..c4f18b6de9 100644 --- a/src/controllers/dashboard/plugins/available/index.js +++ b/src/controllers/dashboard/plugins/available/index.js @@ -1,6 +1,8 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby-checkbox', 'emby-select'], function (loading, libraryMenu, globalize) { 'use strict'; + loading = loading.default || loading; + function reloadList(page) { loading.show(); var promise1 = ApiClient.getAvailablePlugins(); diff --git a/src/controllers/dashboard/plugins/installed/index.js b/src/controllers/dashboard/plugins/installed/index.js index d28a04cb2b..3131386b2b 100644 --- a/src/controllers/dashboard/plugins/installed/index.js +++ b/src/controllers/dashboard/plugins/installed/index.js @@ -1,6 +1,8 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'], function (loading, libraryMenu, dom, globalize) { 'use strict'; + loading = loading.default || loading; + function deletePlugin(page, uniqueid, name) { var msg = globalize.translate('UninstallPluginConfirmation', name); diff --git a/src/controllers/edititemmetadata.js b/src/controllers/edititemmetadata.js index 1a3647a758..b0f1f4a142 100644 --- a/src/controllers/edititemmetadata.js +++ b/src/controllers/edititemmetadata.js @@ -1,6 +1,8 @@ define(['loading', 'scripts/editorsidebar'], function (loading) { 'use strict'; + loading = loading.default || loading; + function reload(context, itemId) { loading.show(); diff --git a/src/controllers/hometab.js b/src/controllers/hometab.js index 8e2a1f92e7..97034d4505 100644 --- a/src/controllers/hometab.js +++ b/src/controllers/hometab.js @@ -1,6 +1,8 @@ define(['userSettings', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'focusManager', 'homeSections', 'emby-itemscontainer'], function (userSettings, loading, connectionManager, appHost, layoutManager, focusManager, homeSections) { 'use strict'; + loading = loading.default || loading; + function HomeTab(view, params) { this.view = view; this.params = params; diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index 29aa8ad1e1..02dc66d35a 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -1,6 +1,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSettings', 'cardBuilder', 'datetime', 'mediaInfo', 'backdrop', 'listView', 'itemContextMenu', 'itemHelper', 'dom', 'indicators', 'imageLoader', 'libraryMenu', 'globalize', 'browser', 'events', 'playbackManager', 'scrollStyles', 'emby-itemscontainer', 'emby-checkbox', 'emby-button', 'emby-playstatebutton', 'emby-ratingbutton', 'emby-scroller', 'emby-select'], function (loading, appRouter, layoutManager, connectionManager, userSettings, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, dom, indicators, imageLoader, libraryMenu, globalize, browser, events, playbackManager) { 'use strict'; + loading = loading.default || loading; + function getPromise(apiClient, params) { var id = params.id; diff --git a/src/controllers/list.js b/src/controllers/list.js index e550b535f4..2a26f81a39 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -1,6 +1,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager', 'cardBuilder', 'loading', 'connectionManager', 'alphaNumericShortcuts', 'scroller', 'playbackManager', 'alphaPicker', 'emby-itemscontainer', 'emby-scroller'], function (globalize, listView, layoutManager, userSettings, focusManager, cardBuilder, loading, connectionManager, AlphaNumericShortcuts, scroller, playbackManager, AlphaPicker) { 'use strict'; + loading = loading.default || loading; + function getInitialLiveTvQuery(instance, params) { var query = { UserId: connectionManager.getApiClient(params.serverId).getCurrentUserId(), diff --git a/src/controllers/livetv/livetvchannels.js b/src/controllers/livetv/livetvchannels.js index 62906d9d21..c0061c1f52 100644 --- a/src/controllers/livetv/livetvchannels.js +++ b/src/controllers/livetv/livetvchannels.js @@ -1,6 +1,8 @@ define(['cardBuilder', 'imageLoader', 'libraryBrowser', 'loading', 'events', 'userSettings', 'emby-itemscontainer'], function (cardBuilder, imageLoader, libraryBrowser, loading, events, userSettings) { 'use strict'; + loading = loading.default || loading; + return function (view, params, tabContent) { function getPageData() { if (!pageData) { diff --git a/src/controllers/livetv/livetvrecordings.js b/src/controllers/livetv/livetvrecordings.js index d832ca1339..b0259bc89b 100644 --- a/src/controllers/livetv/livetvrecordings.js +++ b/src/controllers/livetv/livetvrecordings.js @@ -1,6 +1,8 @@ define(['layoutManager', 'loading', 'cardBuilder', 'apphost', 'imageLoader', 'scripts/livetvcomponents', 'listViewStyle', 'emby-itemscontainer'], function (layoutManager, loading, cardBuilder, appHost, imageLoader) { 'use strict'; + loading = loading.default || loading; + function renderRecordings(elem, recordings, cardOptions, scrollX) { if (!elem) { return; diff --git a/src/controllers/livetv/livetvschedule.js b/src/controllers/livetv/livetvschedule.js index 2f451e50fb..4427bef5d1 100644 --- a/src/controllers/livetv/livetvschedule.js +++ b/src/controllers/livetv/livetvschedule.js @@ -1,6 +1,8 @@ define(['layoutManager', 'cardBuilder', 'apphost', 'imageLoader', 'loading', 'scripts/livetvcomponents', 'emby-button', 'emby-itemscontainer'], function (layoutManager, cardBuilder, appHost, imageLoader, loading) { 'use strict'; + loading = loading.default || loading; + function enableScrollX() { return !layoutManager.desktop; } diff --git a/src/controllers/livetv/livetvseriestimers.js b/src/controllers/livetv/livetvseriestimers.js index c5d0da60d7..62f36a1006 100644 --- a/src/controllers/livetv/livetvseriestimers.js +++ b/src/controllers/livetv/livetvseriestimers.js @@ -1,6 +1,8 @@ define(['datetime', 'cardBuilder', 'imageLoader', 'apphost', 'loading', 'paper-icon-button-light', 'emby-button'], function (datetime, cardBuilder, imageLoader, appHost, loading) { 'use strict'; + loading = loading.default || loading; + function renderTimers(context, timers) { var html = ''; html += cardBuilder.getCardsHtml({ diff --git a/src/controllers/livetv/livetvsuggested.js b/src/controllers/livetv/livetvsuggested.js index 036eee9fc6..5f0d4d5657 100644 --- a/src/controllers/livetv/livetvsuggested.js +++ b/src/controllers/livetv/livetvsuggested.js @@ -1,6 +1,8 @@ define(['layoutManager', 'userSettings', 'inputManager', 'loading', 'globalize', 'libraryBrowser', 'mainTabsManager', 'cardBuilder', 'apphost', 'imageLoader', 'scrollStyles', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (layoutManager, userSettings, inputManager, loading, globalize, libraryBrowser, mainTabsManager, cardBuilder, appHost, imageLoader) { 'use strict'; + loading = loading.default || loading; + function enableScrollX() { return !layoutManager.desktop; } diff --git a/src/controllers/livetvguideprovider.js b/src/controllers/livetvguideprovider.js index 8f8b9f91c7..3ec04fd2af 100644 --- a/src/controllers/livetvguideprovider.js +++ b/src/controllers/livetvguideprovider.js @@ -1,6 +1,8 @@ define(['events', 'loading', 'globalize'], function (events, loading, globalize) { 'use strict'; + loading = loading.default || loading; + function onListingsSubmitted() { Dashboard.navigate('livetvstatus.html'); } diff --git a/src/controllers/livetvsettings.js b/src/controllers/livetvsettings.js index 715eb06214..33034295b5 100644 --- a/src/controllers/livetvsettings.js +++ b/src/controllers/livetvsettings.js @@ -1,6 +1,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, globalize) { 'use strict'; + loading = loading.default || loading; + function loadPage(page, config) { $('.liveTvSettingsForm', page).show(); $('.noLiveTvServices', page).hide(); diff --git a/src/controllers/livetvstatus.js b/src/controllers/livetvstatus.js index 84ea006fd9..216594160f 100644 --- a/src/controllers/livetvstatus.js +++ b/src/controllers/livetvstatus.js @@ -1,6 +1,8 @@ define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layoutManager', 'loading', 'browser', 'listViewStyle', 'flexStyles', 'emby-itemscontainer', 'cardStyle', 'material-icons', 'emby-button'], function ($, globalize, taskButton, dom, libraryMenu, layoutManager, loading, browser) { 'use strict'; + loading = loading.default || loading; + var enableFocusTransform = !browser.slow && !browser.edge; function getDeviceHtml(device) { diff --git a/src/controllers/livetvtuner.js b/src/controllers/livetvtuner.js index 92f705c02f..7f5b70483d 100644 --- a/src/controllers/livetvtuner.js +++ b/src/controllers/livetvtuner.js @@ -1,6 +1,8 @@ define(['globalize', 'loading', 'libraryMenu', 'dom', 'emby-input', 'emby-button', 'emby-checkbox', 'emby-select'], function (globalize, loading, libraryMenu, dom) { 'use strict'; + loading = loading.default || loading; + function isM3uVariant(type) { return ['nextpvr'].indexOf(type || '') !== -1; } diff --git a/src/controllers/movies/moviecollections.js b/src/controllers/movies/moviecollections.js index 65abca46e0..f69b53b77e 100644 --- a/src/controllers/movies/moviecollections.js +++ b/src/controllers/movies/moviecollections.js @@ -1,6 +1,8 @@ define(['loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, userSettings, globalize) { 'use strict'; + loading = loading.default || loading; + return function (view, params, tabContent) { function getPageData(context) { var key = getSavedQueryKey(context); diff --git a/src/controllers/movies/moviegenres.js b/src/controllers/movies/moviegenres.js index 43f73bfa76..93370a8ce5 100644 --- a/src/controllers/movies/moviegenres.js +++ b/src/controllers/movies/moviegenres.js @@ -1,6 +1,8 @@ define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader', 'apphost', 'globalize', 'appRouter', 'dom', 'emby-button'], function (layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) { 'use strict'; + loading = loading.default || loading; + return function (view, params, tabContent) { function getPageData() { var key = getSavedQueryKey(); diff --git a/src/controllers/movies/movies.js b/src/controllers/movies/movies.js index 82b162e2ad..5bc582ad29 100644 --- a/src/controllers/movies/movies.js +++ b/src/controllers/movies/movies.js @@ -1,6 +1,8 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser', 'alphaPicker', 'listView', 'cardBuilder', 'globalize', 'emby-itemscontainer'], function (loading, layoutManager, userSettings, events, libraryBrowser, AlphaPicker, listView, cardBuilder, globalize) { 'use strict'; + loading = loading.default || loading; + return function (view, params, tabContent, options) { function onViewStyleChange() { if (self.getCurrentViewStyle() == 'List') { diff --git a/src/controllers/movies/movietrailers.js b/src/controllers/movies/movietrailers.js index a9db0abf49..51ed03ce81 100644 --- a/src/controllers/movies/movietrailers.js +++ b/src/controllers/movies/movietrailers.js @@ -1,6 +1,8 @@ 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'; + loading = loading.default || loading; + return function (view, params, tabContent) { function getPageData(context) { var key = getSavedQueryKey(context); diff --git a/src/controllers/music/musicalbums.js b/src/controllers/music/musicalbums.js index 3630e0b9f9..81dc3d8bb0 100644 --- a/src/controllers/music/musicalbums.js +++ b/src/controllers/music/musicalbums.js @@ -1,6 +1,8 @@ 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'; + loading = loading.default || loading; + return function (view, params, tabContent) { function playAll() { ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) { diff --git a/src/controllers/music/musicartists.js b/src/controllers/music/musicartists.js index c9a0b06b77..ab73c30db3 100644 --- a/src/controllers/music/musicartists.js +++ b/src/controllers/music/musicartists.js @@ -1,6 +1,8 @@ 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'; + loading = loading.default || loading; + return function (view, params, tabContent) { function getPageData(context) { var key = getSavedQueryKey(context); diff --git a/src/controllers/music/musicgenres.js b/src/controllers/music/musicgenres.js index 82f2eba574..39ca5a44bf 100644 --- a/src/controllers/music/musicgenres.js +++ b/src/controllers/music/musicgenres.js @@ -1,6 +1,8 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], function (libraryBrowser, cardBuilder, appHost, imageLoader, loading) { 'use strict'; + loading = loading.default || loading; + return function (view, params, tabContent) { function getPageData() { var key = getSavedQueryKey(); diff --git a/src/controllers/music/musicplaylists.js b/src/controllers/music/musicplaylists.js index f508489216..464d418229 100644 --- a/src/controllers/music/musicplaylists.js +++ b/src/controllers/music/musicplaylists.js @@ -1,6 +1,8 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], function (libraryBrowser, cardBuilder, appHost, imageLoader, loading) { 'use strict'; + loading = loading.default || loading; + return function (view, params, tabContent) { function getPageData() { var key = getSavedQueryKey(); diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js index 0eecef0bfb..f1809623d4 100644 --- a/src/controllers/music/musicrecommended.js +++ b/src/controllers/music/musicrecommended.js @@ -1,6 +1,8 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', 'cardBuilder', 'dom', 'apphost', 'imageLoader', 'libraryMenu', 'playbackManager', 'mainTabsManager', 'globalize', 'scrollStyles', 'emby-itemscontainer', 'emby-tabs', 'emby-button', 'flexStyles'], function (browser, layoutManager, userSettings, inputManager, loading, cardBuilder, dom, appHost, imageLoader, libraryMenu, playbackManager, mainTabsManager, globalize) { 'use strict'; + loading = loading.default || loading; + function itemsPerRow() { var screenWidth = dom.getWindowSize().innerWidth; diff --git a/src/controllers/music/songs.js b/src/controllers/music/songs.js index aa63ec51fe..e82b81a5c7 100644 --- a/src/controllers/music/songs.js +++ b/src/controllers/music/songs.js @@ -1,6 +1,8 @@ define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userSettings', 'globalize', 'emby-itemscontainer'], function (events, libraryBrowser, imageLoader, listView, loading, userSettings, globalize) { 'use strict'; + loading = loading.default || loading; + return function (view, params, tabContent) { function getPageData(context) { var key = getSavedQueryKey(context); diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index b3b2402c26..9e91723449 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -2,6 +2,8 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackManager', 'appRouter', 'appSettings', 'connectionManager', 'htmlMediaHelper', 'itemHelper', 'screenfull', 'globalize'], function (browser, require, events, appHost, loading, dom, playbackManager, appRouter, appSettings, connectionManager, htmlMediaHelper, itemHelper, screenfull, globalize) { 'use strict'; + loading = loading.default || loading; + function tryRemoveElement(elem) { var parentNode = elem.parentNode; if (parentNode) { diff --git a/src/scripts/site.js b/src/scripts/site.js index 2beb45959a..c53ed7e713 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -880,7 +880,7 @@ function initClient() { }); } } - + console.log(appRouter) appRouter.showLocalLogin = function (serverId, manualLogin) { Dashboard.navigate('login.html?serverid=' + serverId); }; From e3ca0a3d994f8cd4ce05ab10ae8b50ec1e56bd1f Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 29 Jul 2020 09:06:06 +0100 Subject: [PATCH 023/226] Migration of favoriteitems to ES6 module --- package.json | 1 + src/components/favoriteitems.js | 54 +++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index f2ae59522b..9b3ee84d10 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "src/components/dialogHelper/dialogHelper.js", "src/components/directorybrowser/directorybrowser.js", "src/components/displaySettings/displaySettings.js", + "src/components/favoriteitems.js", "src/components/fetchhelper.js", "src/components/filterdialog/filterdialog.js", "src/components/groupedcards.js", diff --git a/src/components/favoriteitems.js b/src/components/favoriteitems.js index 358bf04112..056022fa88 100644 --- a/src/components/favoriteitems.js +++ b/src/components/favoriteitems.js @@ -1,5 +1,14 @@ -define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoader', 'globalize', 'layoutManager', 'scrollStyles', 'emby-itemscontainer'], function (loading, libraryBrowser, cardBuilder, dom, appHost, imageLoader, globalize, layoutManager) { - 'use strict'; +import loading from 'loading'; +import cardBuilder from 'cardBuilder'; +import dom from 'dom'; +import appHost from 'apphost'; +import imageLoader from 'imageLoader'; +import globalize from 'globalize'; +import layoutManager from 'layoutManager'; +import 'scrollStyles'; +import 'emby-itemscontainer'; + +/* eslint-disable indent */ function enableScrollX() { return !layoutManager.desktop; @@ -94,8 +103,8 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad } function loadSection(elem, userId, topParentId, section, isSingleSection) { - var screenWidth = dom.getWindowSize().innerWidth; - var options = { + const screenWidth = dom.getWindowSize().innerWidth; + const options = { SortBy: 'SortName', SortOrder: 'Ascending', Filters: 'IsFavorite', @@ -118,7 +127,7 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad } } - var promise; + let promise; if ('MusicArtist' === section.types) { promise = ApiClient.getArtists(userId, options); @@ -128,7 +137,7 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad } return promise.then(function (result) { - var html = ''; + let html = ''; if (result.Items.length) { if (html += '
', !layoutManager.tv && options.Limit && result.Items.length >= options.Limit) { @@ -144,7 +153,7 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad html += '
'; if (enableScrollX()) { - var scrollXClass = 'scrollX hiddenScrollX'; + let scrollXClass = 'scrollX hiddenScrollX'; if (layoutManager.tv) { scrollXClass += ' smoothScrollX'; } @@ -154,7 +163,7 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad html += '
'; } - var cardLayout = appHost.preferVisualCards && section.autoCardLayout && section.showTitle; + let cardLayout = appHost.preferVisualCards && section.autoCardLayout && section.showTitle; cardLayout = false; html += cardBuilder.getCardsHtml(result.Items, { preferThumb: section.preferThumb, @@ -179,10 +188,10 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad }); } - function loadSections(page, userId, topParentId, types) { + export function loadSections(page, userId, topParentId, types) { loading.show(); - var sections = getSections(); - var sectionid = getParameterByName('sectionid'); + let sections = getSections(); + const sectionid = getParameterByName('sectionid'); if (sectionid) { sections = sections.filter(function (s) { @@ -196,24 +205,22 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad }); } - var i; - var length; - var elem = page.querySelector('.favoriteSections'); + let elem = page.querySelector('.favoriteSections'); if (!elem.innerHTML) { - var html = ''; + let html = ''; - for (i = 0, length = sections.length; i < length; i++) { + for (let i = 0, length = sections.length; i < length; i++) { html += '
'; } elem.innerHTML = html; } - var promises = []; + const promises = []; - for (i = 0, length = sections.length; i < length; i++) { - var section = sections[i]; + for (let i = 0, length = sections.length; i < length; i++) { + const section = sections[i]; elem = page.querySelector('.section' + section.id); promises.push(loadSection(elem, userId, topParentId, section, 1 === sections.length)); } @@ -223,7 +230,8 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad }); } - return { - render: loadSections - }; -}); +export default { + render: loadSection +}; + +/* eslint-enable indent */ From 8985ba2a958c4c41c8050e998db6b7845d0006c7 Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 29 Jul 2020 09:08:26 +0100 Subject: [PATCH 024/226] remove log --- src/scripts/site.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts/site.js b/src/scripts/site.js index c53ed7e713..2beb45959a 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -880,7 +880,7 @@ function initClient() { }); } } - console.log(appRouter) + appRouter.showLocalLogin = function (serverId, manualLogin) { Dashboard.navigate('login.html?serverid=' + serverId); }; From ddf65f31e03be9e9246c29a5972644c120456a7d Mon Sep 17 00:00:00 2001 From: Cameron Date: Wed, 29 Jul 2020 10:09:05 +0100 Subject: [PATCH 025/226] fix lint --- src/components/imageeditor/imageeditor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index 9fbd34090d..c0394ed2ad 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -18,7 +18,7 @@ import 'css!./imageeditor'; /* eslint-disable indent */ const enableFocusTransform = !browser.slow && !browser.edge; - + loading = loading.default || loading; let currentItem; From c76f550b915c57d575700c78550805e24997ea80 Mon Sep 17 00:00:00 2001 From: dkanada Date: Wed, 29 Jul 2020 19:36:44 +0900 Subject: [PATCH 026/226] add paging in book player with touch events --- src/plugins/bookPlayer/plugin.js | 47 ++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/plugins/bookPlayer/plugin.js b/src/plugins/bookPlayer/plugin.js index db6c344dad..8fdab182cf 100644 --- a/src/plugins/bookPlayer/plugin.js +++ b/src/plugins/bookPlayer/plugin.js @@ -2,6 +2,7 @@ import connectionManager from 'connectionManager'; import loading from 'loading'; import keyboardnavigation from 'keyboardnavigation'; import dialogHelper from 'dialogHelper'; +import dom from 'dom'; import events from 'events'; import 'css!./style'; import 'material-icons'; @@ -93,23 +94,22 @@ export class BookPlayer { onWindowKeyUp(e) { let key = keyboardnavigation.getKeyName(e); - let rendition = this._rendition; + + // TODO: depending on the event this can be the document or the rendition itself + let rendition = this._rendition || this; let book = rendition.book; + if (this._loaded === false) return; switch (key) { case 'l': case 'ArrowRight': case 'Right': - if (this._loaded) { - book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next(); - } + book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next(); break; case 'j': case 'ArrowLeft': case 'Left': - if (this._loaded) { - book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev(); - } + book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev(); break; case 'Escape': if (this._tocElement) { @@ -123,6 +123,25 @@ export class BookPlayer { } } + onTouchStart(e) { + // TODO: depending on the event this can be the document or the rendition itself + let rendition = this._rendition || this; + let book = rendition.book; + + // check that the event is from the book or the document + if (!book || this._loaded === false) return; + + // epubjs stores pages off the screen or something for preloading + // get the modulus of the touch event to account for the increased width + if (!e.touches || e.touches.length === 0) return; + let touch = e.touches[0].clientX % dom.getWindowSize().innerWidth; + if (touch < dom.getWindowSize().innerWidth / 2) { + book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev(); + } else { + book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next(); + } + } + onDialogClosed() { this.stop(); } @@ -139,8 +158,11 @@ export class BookPlayer { this.bindMediaElementEvents(); document.addEventListener('keyup', this.onWindowKeyUp); + document.addEventListener('touchstart', this.onTouchStart); + // FIXME: I don't really get why document keyup event is not triggered when epub is in focus this._rendition.on('keyup', this.onWindowKeyUp); + this._rendition.on('touchstart', this.onTouchStart); } unbindMediaElementEvents() { @@ -155,9 +177,13 @@ export class BookPlayer { if (this._mediaElement) { this.unbindMediaElementEvents(); } + document.removeEventListener('keyup', this.onWindowKeyUp); + document.removeEventListener('touchstart', this.onTouchStart); + if (this._rendition) { this._rendition.off('keyup', this.onWindowKeyUp); + this._rendition.off('touchstart', this.onTouchStart); } } @@ -169,13 +195,11 @@ export class BookPlayer { createMediaElement() { let elem = this._mediaElement; - if (elem) { return elem; } elem = document.getElementById('bookPlayer'); - if (!elem) { elem = dialogHelper.createDialog({ exitAnimationDuration: 400, @@ -185,6 +209,7 @@ export class BookPlayer { exitAnimation: 'fadeout', removeOnClose: true }); + elem.id = 'bookPlayer'; let html = ''; @@ -230,6 +255,7 @@ export class BookPlayer { let cancellationToken = { shouldCancel: false }; + this._cancellationToken = cancellationToken; return rendition.display().then(() => { @@ -253,7 +279,6 @@ export class BookPlayer { epubElem.style.display = 'block'; rendition.on('relocated', (locations) => { this._progress = book.locations.percentageFromCfi(locations.start.cfi); - events.trigger(this, 'timeupdate'); }); @@ -262,7 +287,7 @@ export class BookPlayer { return resolve(); }); }, () => { - console.error('Failed to display epub'); + console.error('failed to display epub'); return reject(); }); }); From fd55eb99ac960d248f1dce32684719b2b790e8f7 Mon Sep 17 00:00:00 2001 From: Mariusz Chryc Date: Wed, 29 Jul 2020 17:49:07 +0200 Subject: [PATCH 027/226] Fix updateNowPlayingInfo when artist or album are empty --- src/components/remotecontrol/remotecontrol.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index db2bed36a7..24e58404d8 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -119,9 +119,9 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var nowPlayingServerId = (item.ServerId || serverId); 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; + var artistsSeries = ''; + var albumName = ''; + if (item.Artists != null) { if (item.ArtistItems != null) { for (const artist of item.ArtistItems) { let artistName = artist.Name; @@ -142,9 +142,12 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } } } - context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries; - context.querySelector('.nowPlayingAlbum').innerHTML = '
${albumName}`; } + if (item.Album != null){ + albumName = '` + item.Album + ``; + } + context.querySelector('.nowPlayingAlbum').innerHTML = albumName + context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries; context.querySelector('.nowPlayingSongName').innerHTML = songName; } else if (item.Type == 'Episode') { if (item.SeasonName != null) { From 260668f501b7018c93b9bdf4aa302455f4362484 Mon Sep 17 00:00:00 2001 From: Mariusz Chryc Date: Wed, 29 Jul 2020 18:05:45 +0200 Subject: [PATCH 028/226] Fix lintint errors --- src/components/remotecontrol/remotecontrol.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 24e58404d8..c0d594f123 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -143,10 +143,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } } } - if (item.Album != null){ - albumName = '` + item.Album + ``; + if (item.Album != null) { + albumName = '' + item.Album + ''; } - context.querySelector('.nowPlayingAlbum').innerHTML = albumName + context.querySelector('.nowPlayingAlbum').innerHTML = albumName; context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries; context.querySelector('.nowPlayingSongName').innerHTML = songName; } else if (item.Type == 'Episode') { From 56aaed9f816acfc1ec0dac69ae02484562026205 Mon Sep 17 00:00:00 2001 From: Mariusz Chryc Date: Wed, 29 Jul 2020 18:11:27 +0200 Subject: [PATCH 029/226] Fix string --- 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 c0d594f123..13fa8c0887 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -144,7 +144,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } } if (item.Album != null) { - albumName = '' + item.Album + ''; + albumName = '` + item.Album + ''; } context.querySelector('.nowPlayingAlbum').innerHTML = albumName; context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries; From 6ef3be136a1e2f98e0d292cfdc108b94eb3eb470 Mon Sep 17 00:00:00 2001 From: Dmitry Lyzo Date: Thu, 30 Jul 2020 23:36:52 +0300 Subject: [PATCH 030/226] Add parseInt radix --- src/components/subtitlesettings/subtitleappearancehelper.js | 4 ++-- src/plugins/htmlVideoPlayer/plugin.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/subtitlesettings/subtitleappearancehelper.js b/src/components/subtitlesettings/subtitleappearancehelper.js index 4b8b7aed2a..904c018bfc 100644 --- a/src/components/subtitlesettings/subtitleappearancehelper.js +++ b/src/components/subtitlesettings/subtitleappearancehelper.js @@ -89,7 +89,7 @@ function getTextStyles(settings, preview) { } if (!preview) { - const pos = parseInt(settings.verticalPosition); + const pos = parseInt(settings.verticalPosition, 10); const lineHeight = 1.35; // FIXME: It is better to read this value from element const line = Math.abs(pos * lineHeight); if (pos < 0) { @@ -108,7 +108,7 @@ function getWindowStyles(settings, preview) { const list = []; if (!preview) { - const pos = parseInt(settings.verticalPosition); + const pos = parseInt(settings.verticalPosition, 10); if (pos < 0) { list.push({ name: 'top', value: '' }); list.push({ name: 'bottom', value: '0' }); diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 77e3253641..7ef35adf41 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -1200,7 +1200,7 @@ function tryRemoveElement(elem) { console.debug(`downloaded ${data.TrackEvents.length} track events`); const subtitleAppearance = userSettings.getSubtitleAppearanceSettings(); - const cueLine = parseInt(subtitleAppearance.verticalPosition); + const cueLine = parseInt(subtitleAppearance.verticalPosition, 10); // add some cues to show the text // in safari, the cues need to be added before setting the track mode to showing From b3bfbe640e17c5ec05427883b856001fef3f1a6d Mon Sep 17 00:00:00 2001 From: matjaz321 Date: Thu, 30 Jul 2020 23:25:35 +0200 Subject: [PATCH 031/226] Migrated livestatus.js to es6 module --- package.json | 1 + src/controllers/livetvstatus.js | 545 ++++++++++++++++---------------- 2 files changed, 280 insertions(+), 266 deletions(-) diff --git a/package.json b/package.json index 38b7580ed9..965d676b5b 100644 --- a/package.json +++ b/package.json @@ -201,6 +201,7 @@ "src/controllers/playback/video/index.js", "src/controllers/searchpage.js", "src/controllers/livetvtuner.js", + "src/controllers/livetvstatus.js", "src/controllers/shows/episodes.js", "src/controllers/shows/tvgenres.js", "src/controllers/shows/tvlatest.js", diff --git a/src/controllers/livetvstatus.js b/src/controllers/livetvstatus.js index 84ea006fd9..1c04990634 100644 --- a/src/controllers/livetvstatus.js +++ b/src/controllers/livetvstatus.js @@ -1,294 +1,307 @@ -define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layoutManager', 'loading', 'browser', 'listViewStyle', 'flexStyles', 'emby-itemscontainer', 'cardStyle', 'material-icons', 'emby-button'], function ($, globalize, taskButton, dom, libraryMenu, layoutManager, loading, browser) { - 'use strict'; +'use strict'; - var enableFocusTransform = !browser.slow && !browser.edge; +import $ from 'jQuery'; +import globalize from 'globalize'; +import taskButton from 'scripts/taskbutton'; +import dom from 'dom'; +import layoutManager from 'layoutManager'; +import loading from 'loading'; +import browser from 'browser'; +import 'listViewStyle'; +import 'flexStyles'; +import 'emby-itemscontainer'; +import 'cardStyle'; +import 'material-icons'; +import 'emby-button'; - function getDeviceHtml(device) { - var padderClass; - var html = ''; - var cssClass = 'card scalableCard'; - var cardBoxCssClass = 'cardBox visualCardBox'; - cssClass += ' backdropCard backdropCard-scalable'; - padderClass = 'cardPadder-backdrop'; +const enableFocusTransform = !browser.slow && !browser.edge; - // TODO move card creation code to Card component +function getDeviceHtml(device) { + let padderClass; + let html = ''; + let cssClass = 'card scalableCard'; + let cardBoxCssClass = 'cardBox visualCardBox'; + cssClass += ' backdropCard backdropCard-scalable'; + padderClass = 'cardPadder-backdrop'; - if (layoutManager.tv) { - cssClass += ' show-focus'; + // TODO move card creation code to Card component - if (enableFocusTransform) { - cssClass += ' show-animation'; - } + if (layoutManager.tv) { + cssClass += ' show-focus'; + + if (enableFocusTransform) { + cssClass += ' show-animation'; } - - html += '
'; - html += '
'; - html += '
'; - html += '
'; - html += '
'; - html += '
'; - html += '
'; - html += '
'; - html += '
'; - html += ''; - html += '
' + (device.FriendlyName || getTunerName(device.Type)) + '
'; - html += '
'; - html += device.Url || ' '; - html += '
'; - html += '
'; - html += '
'; - return html += '
'; } - function renderDevices(page, devices) { - var html = devices.map(getDeviceHtml).join(''); - page.querySelector('.devicesList').innerHTML = html; - } + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += '
'; + html += ''; + html += '
' + (device.FriendlyName || getTunerName(device.Type)) + '
'; + html += '
'; + html += device.Url || ' '; + html += '
'; + html += '
'; + html += '
'; + return html += '
'; +} - function deleteDevice(page, id) { - var message = globalize.translate('MessageConfirmDeleteTunerDevice'); +function renderDevices(page, devices) { + page.querySelector('.devicesList').innerHTML = devices.map(getDeviceHtml).join(''); +} - require(['confirm'], function (confirm) { - confirm.default(message, globalize.translate('HeaderDeleteDevice')).then(function () { - loading.show(); - ApiClient.ajax({ - type: 'DELETE', - url: ApiClient.getUrl('LiveTv/TunerHosts', { - Id: id - }) - }).then(function () { - reload(page); - }); +function deleteDevice(page, id) { + const message = globalize.translate('MessageConfirmDeleteTunerDevice'); + + import('confirm').then(({default: confirm}) => { + confirm(message, globalize.translate('HeaderDeleteDevice')).then(function () { + loading.show(); + ApiClient.ajax({ + type: 'DELETE', + url: ApiClient.getUrl('LiveTv/TunerHosts', { + Id: id + }) + }).then(function () { + reload(page); }); }); - } + }); +} - function reload(page) { - loading.show(); - ApiClient.getNamedConfiguration('livetv').then(function (config) { - renderDevices(page, config.TunerHosts); - renderProviders(page, config.ListingProviders); +function reload(page) { + loading.show(); + ApiClient.getNamedConfiguration('livetv').then(function (config) { + renderDevices(page, config.TunerHosts); + renderProviders(page, config.ListingProviders); + }); + loading.hide(); +} + +function submitAddDeviceForm(page) { + page.querySelector('.dlgAddDevice').close(); + loading.show(); + ApiClient.ajax({ + type: 'POST', + url: ApiClient.getUrl('LiveTv/TunerHosts'), + data: JSON.stringify({ + Type: $('#selectTunerDeviceType', page).val(), + Url: $('#txtDevicePath', page).val() + }), + contentType: 'application/json' + }).then(function () { + reload(page); + }, function () { + Dashboard.alert({ + message: globalize.translate('ErrorAddingTunerDevice') }); - loading.hide(); - } + }); +} - function submitAddDeviceForm(page) { - page.querySelector('.dlgAddDevice').close(); - loading.show(); - ApiClient.ajax({ - type: 'POST', - url: ApiClient.getUrl('LiveTv/TunerHosts'), - data: JSON.stringify({ - Type: $('#selectTunerDeviceType', page).val(), - Url: $('#txtDevicePath', page).val() - }), - contentType: 'application/json' - }).then(function () { - reload(page); - }, function () { - Dashboard.alert({ - message: globalize.translate('ErrorAddingTunerDevice') - }); - }); - } +function renderProviders(page, providers) { + let html = ''; - function renderProviders(page, providers) { - var html = ''; - - if (providers.length) { - html += '
'; - - for (var i = 0, length = providers.length; i < length; i++) { - var provider = providers[i]; - html += ''; - } + if (providers.length) { + html += '
'; + for (let i = 0, length = providers.length; i < length; i++) { + const provider = providers[i]; + html += ''; } - var elem = $('.providerList', page).html(html); - $('.btnOptions', elem).on('click', function () { - var id = this.getAttribute('data-id'); - showProviderOptions(page, id, this); - }); + html += '
'; } - function showProviderOptions(page, providerId, button) { - var items = []; - items.push({ - name: globalize.translate('ButtonDelete'), - id: 'delete' - }); - items.push({ - name: globalize.translate('MapChannels'), - id: 'map' - }); + const elem = $('.providerList', page).html(html); + $('.btnOptions', elem).on('click', function () { + var id = this.getAttribute('data-id'); + showProviderOptions(page, id, this); + }); +} - require(['actionsheet'], function (actionsheet) { - actionsheet.show({ - items: items, - positionTo: button - }).then(function (id) { - switch (id) { - case 'delete': - deleteProvider(page, providerId); - break; +function showProviderOptions(page, providerId, button) { + const items = []; + items.push({ + name: globalize.translate('ButtonDelete'), + id: 'delete' + }); + items.push({ + name: globalize.translate('MapChannels'), + id: 'map' + }); - case 'map': - mapChannels(page, providerId); - } - }); - }); - } + import('actionsheet').then(({default: actionsheet}) => { + actionsheet.show({ + items: items, + positionTo: button + }).then(function (id) { + switch (id) { + case 'delete': + deleteProvider(page, providerId); + break; - function mapChannels(page, providerId) { - require(['components/channelMapper/channelMapper'], function (channelMapper) { - new channelMapper.default({ - serverId: ApiClient.serverInfo().Id, - providerId: providerId - }).show(); - }); - } - - function deleteProvider(page, id) { - var message = globalize.translate('MessageConfirmDeleteGuideProvider'); - - require(['confirm'], function (confirm) { - confirm.default(message, globalize.translate('HeaderDeleteProvider')).then(function () { - loading.show(); - ApiClient.ajax({ - type: 'DELETE', - url: ApiClient.getUrl('LiveTv/ListingProviders', { - Id: id - }) - }).then(function () { - reload(page); - }, function () { - reload(page); - }); - }); - }); - } - - function getTunerName(providerId) { - switch (providerId = providerId.toLowerCase()) { - case 'm3u': - return 'M3U'; - case 'hdhomerun': - return 'HDHomeRun'; - case 'hauppauge': - return 'Hauppauge'; - case 'satip': - return 'DVB'; - default: - return 'Unknown'; - } - } - - function getProviderName(providerId) { - switch (providerId = providerId.toLowerCase()) { - case 'schedulesdirect': - return 'Schedules Direct'; - case 'xmltv': - return 'XMLTV'; - default: - return 'Unknown'; - } - } - - function getProviderConfigurationUrl(providerId) { - switch (providerId = providerId.toLowerCase()) { - case 'xmltv': - return 'livetvguideprovider.html?type=xmltv'; - case 'schedulesdirect': - return 'livetvguideprovider.html?type=schedulesdirect'; - } - } - - function addProvider(button) { - var menuItems = []; - menuItems.push({ - name: 'Schedules Direct', - id: 'SchedulesDirect' - }); - menuItems.push({ - name: 'XMLTV', - id: 'xmltv' - }); - - require(['actionsheet'], function (actionsheet) { - actionsheet.show({ - items: menuItems, - positionTo: button, - callback: function (id) { - Dashboard.navigate(getProviderConfigurationUrl(id)); - } - }); - }); - } - - function addDevice(button) { - Dashboard.navigate('livetvtuner.html'); - } - - function showDeviceMenu(button, tunerDeviceId) { - var items = []; - items.push({ - name: globalize.translate('ButtonDelete'), - id: 'delete' - }); - items.push({ - name: globalize.translate('ButtonEdit'), - id: 'edit' - }); - - require(['actionsheet'], function (actionsheet) { - actionsheet.show({ - items: items, - positionTo: button - }).then(function (id) { - switch (id) { - case 'delete': - deleteDevice(dom.parentWithClass(button, 'page'), tunerDeviceId); - break; - - case 'edit': - Dashboard.navigate('livetvtuner.html?id=' + tunerDeviceId); - } - }); - }); - } - - function onDevicesListClick(e) { - var card = dom.parentWithClass(e.target, 'card'); - - if (card) { - var id = card.getAttribute('data-id'); - var btnCardOptions = dom.parentWithClass(e.target, 'btnCardOptions'); - - if (btnCardOptions) { - showDeviceMenu(btnCardOptions, id); - } else { - Dashboard.navigate('livetvtuner.html?id=' + id); + case 'map': + mapChannels(page, providerId); } + }); + }); +} + +function mapChannels(page, providerId) { + import('components/channelMapper/channelMapper').then(({default: channelMapper}) => { + new channelMapper({ + serverId: ApiClient.serverInfo().Id, + providerId: providerId + }).show(); + }); +} + +function deleteProvider(page, id) { + const message = globalize.translate('MessageConfirmDeleteGuideProvider'); + + import('confirm').then(({default: confirm}) => { + confirm(message, globalize.translate('HeaderDeleteProvider')).then(function () { + loading.show(); + ApiClient.ajax({ + type: 'DELETE', + url: ApiClient.getUrl('LiveTv/ListingProviders', { + Id: id + }) + }).then(function () { + reload(page); + }, function () { + reload(page); + }); + }); + }); +} + +function getTunerName(providerId) { + switch (providerId = providerId.toLowerCase()) { + case 'm3u': + return 'M3U'; + case 'hdhomerun': + return 'HDHomeRun'; + case 'hauppauge': + return 'Hauppauge'; + case 'satip': + return 'DVB'; + default: + return 'Unknown'; + } +} + +function getProviderName(providerId) { + switch (providerId = providerId.toLowerCase()) { + case 'schedulesdirect': + return 'Schedules Direct'; + case 'xmltv': + return 'XMLTV'; + default: + return 'Unknown'; + } +} + +function getProviderConfigurationUrl(providerId) { + switch (providerId = providerId.toLowerCase()) { + case 'xmltv': + return 'livetvguideprovider.html?type=xmltv'; + case 'schedulesdirect': + return 'livetvguideprovider.html?type=schedulesdirect'; + } +} + +function addProvider(button) { + const menuItems = []; + menuItems.push({ + name: 'Schedules Direct', + id: 'SchedulesDirect' + }); + menuItems.push({ + name: 'XMLTV', + id: 'xmltv' + }); + + import('actionsheet').then(({default: actionsheet}) => { + actionsheet.show({ + items: menuItems, + positionTo: button, + callback: function (id) { + Dashboard.navigate(getProviderConfigurationUrl(id)); + } + }); + }); +} + +function addDevice(button) { + Dashboard.navigate('livetvtuner.html'); +} + +function showDeviceMenu(button, tunerDeviceId) { + var items = []; + items.push({ + name: globalize.translate('ButtonDelete'), + id: 'delete' + }); + items.push({ + name: globalize.translate('ButtonEdit'), + id: 'edit' + }); + + require(['actionsheet'], function (actionsheet) { + actionsheet.show({ + items: items, + positionTo: button + }).then(function (id) { + switch (id) { + case 'delete': + deleteDevice(dom.parentWithClass(button, 'page'), tunerDeviceId); + break; + + case 'edit': + Dashboard.navigate('livetvtuner.html?id=' + tunerDeviceId); + } + }); + }); +} + +function onDevicesListClick(e) { + const card = dom.parentWithClass(e.target, 'card'); + + if (card) { + const id = card.getAttribute('data-id'); + const btnCardOptions = dom.parentWithClass(e.target, 'btnCardOptions'); + + if (btnCardOptions) { + showDeviceMenu(btnCardOptions, id); + } else { + Dashboard.navigate('livetvtuner.html?id=' + id); } } +} +export default function () { $(document).on('pageinit', '#liveTvStatusPage', function () { - var page = this; + const page = this; $('.btnAddDevice', page).on('click', function () { addDevice(this); }); @@ -301,21 +314,21 @@ define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layo }); page.querySelector('.devicesList').addEventListener('click', onDevicesListClick); }).on('pageshow', '#liveTvStatusPage', function () { - var page = this; + const page = this; reload(page); - taskButton.default({ + taskButton({ mode: 'on', progressElem: page.querySelector('.refreshGuideProgress'), taskKey: 'RefreshGuide', button: page.querySelector('.btnRefresh') }); }).on('pagehide', '#liveTvStatusPage', function () { - var page = this; - taskButton.default({ + const page = this; + taskButton({ mode: 'off', progressElem: page.querySelector('.refreshGuideProgress'), taskKey: 'RefreshGuide', button: page.querySelector('.btnRefresh') }); }); -}); +} From e44534140599aef02139145d8a36f847950cdbf5 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 09:47:58 +0100 Subject: [PATCH 032/226] Update src/components/favoriteitems.js Co-authored-by: dkanada --- src/components/favoriteitems.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/favoriteitems.js b/src/components/favoriteitems.js index 056022fa88..dde2e5f1c5 100644 --- a/src/components/favoriteitems.js +++ b/src/components/favoriteitems.js @@ -231,7 +231,7 @@ import 'emby-itemscontainer'; } export default { - render: loadSection + render: loadSections }; /* eslint-enable indent */ From 116e73e5606a47da15c2cacb74f829f02c24924d Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 11:30:02 +0100 Subject: [PATCH 033/226] Remove unused vars --- src/controllers/hometab.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/controllers/hometab.js b/src/controllers/hometab.js index 4b7ddee057..d834e3e233 100644 --- a/src/controllers/hometab.js +++ b/src/controllers/hometab.js @@ -1,8 +1,6 @@ import * as userSettings from 'userSettings'; import loading from 'loading'; import connectionManager from 'connectionManager'; -import appHost from 'apphost'; -import layoutManager from 'layoutManager'; import focusManager from 'focusManager'; import homeSections from 'homeSections'; import 'emby-itemscontainer'; From d14ac4b2e1f656832ae384269c234da9ea8d33a7 Mon Sep 17 00:00:00 2001 From: matjaz321 Date: Fri, 31 Jul 2020 16:58:53 +0200 Subject: [PATCH 034/226] removed --- src/controllers/livetvstatus.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/controllers/livetvstatus.js b/src/controllers/livetvstatus.js index 1c04990634..be6cb1c738 100644 --- a/src/controllers/livetvstatus.js +++ b/src/controllers/livetvstatus.js @@ -1,5 +1,3 @@ -'use strict'; - import $ from 'jQuery'; import globalize from 'globalize'; import taskButton from 'scripts/taskbutton'; From 997054ab12572c52000cc1ec0186bfbf4f609679 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 15:54:47 +0100 Subject: [PATCH 035/226] remove require This reverts commit bef8a4509d0b151e7a2e85f549bfca49ce952341. --- src/controllers/home.js | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/controllers/home.js b/src/controllers/home.js index f3e9e8e22b..392da0e2d2 100644 --- a/src/controllers/home.js +++ b/src/controllers/home.js @@ -1,6 +1,5 @@ import TabbedView from 'tabbedView'; import globalize from 'globalize'; -import require from 'require'; import 'emby-tabs'; import 'emby-button'; import 'emby-scroller'; @@ -17,30 +16,24 @@ function getDefaultTabIndex() { return 0; } -function getRequirePromise(deps) { - return new Promise(function (resolve, reject) { - require(deps, resolve); - }); -} - function getTabController(index) { if (null == index) { throw new Error('index cannot be null'); } - const depends = []; + let depends = ''; switch (index) { case 0: - depends.push('controllers/hometab'); + depends = 'controllers/hometab'; break; case 1: - depends.push('controllers/favorites'); + depends = 'controllers/favorites'; } const instance = this; - return getRequirePromise(depends).then(function (controllerFactory) { + return import(depends).then(({ default: controllerFactory }) => { let controller = instance.tabControllers[index]; if (!controller) { From 37740083432c1bb24fbaf75d35bf4f96a45c4987 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 1 Aug 2020 00:18:24 +0900 Subject: [PATCH 036/226] standardize key prefixes for translations --- .../accessSchedule/accessSchedule.js | 2 +- src/components/imageeditor/imageeditor.js | 2 +- .../mediaLibraryEditor/mediaLibraryEditor.js | 2 +- src/controllers/dashboard/encodingsettings.js | 2 +- src/controllers/dashboard/general.js | 2 +- .../dashboard/plugins/add/index.js | 2 +- .../dashboard/plugins/installed/index.js | 8 ++--- src/controllers/dashboard/users/usernew.js | 2 +- .../dashboard/users/userpasswordpage.js | 4 +-- src/controllers/livetvsettings.js | 2 +- src/strings/af.json | 2 +- src/strings/ar.json | 16 +++++----- src/strings/bg-bg.json | 18 +++++------ src/strings/ca.json | 10 +++---- src/strings/cs.json | 18 +++++------ src/strings/da.json | 18 +++++------ src/strings/de.json | 18 +++++------ src/strings/el.json | 16 +++++----- src/strings/en-gb.json | 18 +++++------ src/strings/en-us.json | 30 +++++++++---------- src/strings/es-ar.json | 18 +++++------ src/strings/es-mx.json | 18 +++++------ src/strings/es.json | 18 +++++------ src/strings/es_419.json | 18 +++++------ src/strings/fa.json | 18 +++++------ src/strings/fi.json | 12 ++++---- src/strings/fr-ca.json | 2 +- src/strings/fr.json | 18 +++++------ src/strings/gsw.json | 2 +- src/strings/he.json | 10 +++---- src/strings/hi-in.json | 2 +- src/strings/hr.json | 16 +++++----- src/strings/hu.json | 18 +++++------ src/strings/id.json | 4 +-- src/strings/is-is.json | 8 ++--- src/strings/it.json | 18 +++++------ src/strings/ja.json | 10 +++---- src/strings/kk.json | 18 +++++------ src/strings/ko.json | 16 +++++----- src/strings/lt-lt.json | 8 ++--- src/strings/lv.json | 12 ++++---- src/strings/ms.json | 2 +- src/strings/nb.json | 18 +++++------ src/strings/nl.json | 18 +++++------ src/strings/pl.json | 18 +++++------ src/strings/pt-br.json | 18 +++++------ src/strings/pt-pt.json | 18 +++++------ src/strings/pt.json | 16 +++++----- src/strings/ro.json | 18 +++++------ src/strings/ru.json | 18 +++++------ src/strings/sk.json | 18 +++++------ src/strings/sl-si.json | 14 ++++----- src/strings/sr.json | 2 +- src/strings/sv.json | 18 +++++------ src/strings/tr.json | 8 ++--- src/strings/vi.json | 8 ++--- src/strings/zh-cn.json | 18 +++++------ src/strings/zh-hk.json | 6 ++-- src/strings/zh-tw.json | 18 +++++------ src/tv.html | 2 +- 60 files changed, 356 insertions(+), 356 deletions(-) diff --git a/src/components/accessSchedule/accessSchedule.js b/src/components/accessSchedule/accessSchedule.js index 6b96aad1d4..b513766d0b 100644 --- a/src/components/accessSchedule/accessSchedule.js +++ b/src/components/accessSchedule/accessSchedule.js @@ -49,7 +49,7 @@ import 'formDialogStyle'; }; if (parseFloat(updatedSchedule.StartHour) >= parseFloat(updatedSchedule.EndHour)) { - return void alert(globalize.translate('ErrorMessageStartHourGreaterThanEnd')); + return void alert(globalize.translate('ErrorStartHourGreaterThanEnd')); } context.submitted = true; diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index 78c35bb15f..bb8bce269e 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -217,7 +217,7 @@ import 'css!./imageeditor'; reload(context, null, focusContext); }, function () { import('alert').then(({default: alert}) => { - alert(globalize.translate('DefaultErrorMessage')); + alert(globalize.translate('MessageDefaultError')); }); }); } diff --git a/src/components/mediaLibraryEditor/mediaLibraryEditor.js b/src/components/mediaLibraryEditor/mediaLibraryEditor.js index b04f632055..66e7253401 100644 --- a/src/components/mediaLibraryEditor/mediaLibraryEditor.js +++ b/src/components/mediaLibraryEditor/mediaLibraryEditor.js @@ -85,7 +85,7 @@ import 'flexStyles'; refreshLibraryFromServer(dom.parentWithClass(button, 'dlg-libraryeditor')); }, () => { import('toast').then(({default: toast}) => { - toast(globalize.translate('DefaultErrorMessage')); + toast(globalize.translate('MessageDefaultError')); }); }); }); diff --git a/src/controllers/dashboard/encodingsettings.js b/src/controllers/dashboard/encodingsettings.js index 9995577ba8..2c133526bc 100644 --- a/src/controllers/dashboard/encodingsettings.js +++ b/src/controllers/dashboard/encodingsettings.js @@ -81,7 +81,7 @@ import libraryMenu from 'libraryMenu'; updateEncoder(form); }, function () { import('alert').then(({default: alert}) => { - alert(globalize.translate('DefaultErrorMessage')); + alert(globalize.translate('MessageDefaultError')); }); Dashboard.processServerConfigurationUpdateResult(); diff --git a/src/controllers/dashboard/general.js b/src/controllers/dashboard/general.js index 8e30749aba..9cf4092b5c 100644 --- a/src/controllers/dashboard/general.js +++ b/src/controllers/dashboard/general.js @@ -52,7 +52,7 @@ import 'emby-button'; }); }, function () { import('alert').then(({default: alert}) => { - alert(globalize.translate('DefaultErrorMessage')); + alert(globalize.translate('MessageDefaultError')); }); Dashboard.processServerConfigurationUpdateResult(); diff --git a/src/controllers/dashboard/plugins/add/index.js b/src/controllers/dashboard/plugins/add/index.js index a3c450dd79..89984ec397 100644 --- a/src/controllers/dashboard/plugins/add/index.js +++ b/src/controllers/dashboard/plugins/add/index.js @@ -79,7 +79,7 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'e page.querySelector('#btnInstall').disabled = true; ApiClient.installPlugin(name, guid, version).then(function () { loading.hide(); - alertText(globalize.translate('PluginInstalledMessage')); + alertText(globalize.translate('MessagePluginInstalled')); }); }; diff --git a/src/controllers/dashboard/plugins/installed/index.js b/src/controllers/dashboard/plugins/installed/index.js index d28a04cb2b..9c411538ed 100644 --- a/src/controllers/dashboard/plugins/installed/index.js +++ b/src/controllers/dashboard/plugins/installed/index.js @@ -6,10 +6,10 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button' require(['confirm'], function (confirm) { confirm.default({ - title: globalize.translate('UninstallPluginHeader'), + title: globalize.translate('HeaderUninstallPlugin'), text: msg, primary: 'delete', - confirmText: globalize.translate('UninstallPluginHeader') + confirmText: globalize.translate('HeaderUninstallPlugin') }).then(function () { loading.show(); ApiClient.uninstallPlugin(uniqueid).then(function () { @@ -21,7 +21,7 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button' function showNoConfigurationMessage() { Dashboard.alert({ - message: globalize.translate('NoPluginConfigurationMessage') + message: globalize.translate('MessageNoPluginConfiguration') }); } @@ -95,7 +95,7 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button' html += '
'; html += '

' + globalize.translate('MessageNoPluginsInstalled') + '

'; html += '

'; - html += globalize.translate('BrowsePluginCatalogMessage'); + html += globalize.translate('MessageBrowsePluginCatalog'); html += '

'; html += '
'; } diff --git a/src/controllers/dashboard/users/usernew.js b/src/controllers/dashboard/users/usernew.js index f45cbf8ca8..ae3ac0baa9 100644 --- a/src/controllers/dashboard/users/usernew.js +++ b/src/controllers/dashboard/users/usernew.js @@ -89,7 +89,7 @@ import 'emby-checkbox'; }); }, function (response) { import('toast').then(({default: toast}) => { - toast(globalize.translate('DefaultErrorMessage')); + toast(globalize.translate('MessageDefaultError')); }); loading.hide(); diff --git a/src/controllers/dashboard/users/userpasswordpage.js b/src/controllers/dashboard/users/userpasswordpage.js index db91c7bce7..d399804d3e 100644 --- a/src/controllers/dashboard/users/userpasswordpage.js +++ b/src/controllers/dashboard/users/userpasswordpage.js @@ -145,14 +145,14 @@ import 'emby-button'; function resetPassword() { const msg = globalize.translate('PasswordResetConfirmation'); import('confirm').then(({default: confirm}) => { - confirm(msg, globalize.translate('PasswordResetHeader')).then(function () { + confirm(msg, globalize.translate('HeaderResetPassword')).then(function () { const userId = params.userId; loading.show(); ApiClient.resetUserPassword(userId).then(function () { loading.hide(); Dashboard.alert({ message: globalize.translate('PasswordResetComplete'), - title: globalize.translate('PasswordResetHeader') + title: globalize.translate('HeaderResetPassword') }); loadUser(view, params); }); diff --git a/src/controllers/livetvsettings.js b/src/controllers/livetvsettings.js index 715eb06214..129d99311f 100644 --- a/src/controllers/livetvsettings.js +++ b/src/controllers/livetvsettings.js @@ -44,7 +44,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, var msg = ''; if (recordingPathChanged) { - msg += globalize.translate('RecordingPathChangeMessage'); + msg += globalize.translate('MessageChangeRecordingPath'); } if (msg) { diff --git a/src/strings/af.json b/src/strings/af.json index bab716af49..a0df4fc037 100644 --- a/src/strings/af.json +++ b/src/strings/af.json @@ -112,7 +112,7 @@ "Up": "Op", "Unplayed": "Ongespeel", "Unmute": "Ontstom", - "UninstallPluginHeader": "Oninstalleer Plugin", + "HeaderUninstallPlugin": "Oninstalleer Plugin", "UninstallPluginConfirmation": "Is jy seker jy wil voortgaan met die oninstallasie {0}?", "Uniform": "Uniform", "TvLibraryHelp": "Hersien die {0}TV benamings gids{1}.", diff --git a/src/strings/ar.json b/src/strings/ar.json index 216cbf7074..744ac928f0 100644 --- a/src/strings/ar.json +++ b/src/strings/ar.json @@ -11,7 +11,7 @@ "BirthDateValue": "وُلد: {0}", "BirthPlaceValue": "مكان الميلاد: {0}", "Browse": "تصفح", - "BrowsePluginCatalogMessage": "تصفح قائمتنا للملحق لترى المتوفر من الملاحق.", + "MessageBrowsePluginCatalog": "تصفح قائمتنا للملحق لترى المتوفر من الملاحق.", "ButtonAdd": "إضافة", "ButtonAddMediaLibrary": "إضافة مكتبة وسائط", "ButtonAddScheduledTaskTrigger": "إضافة زناد", @@ -92,7 +92,7 @@ "CinemaModeConfigurationHelp": "الطور السينمائي يوفر أجواء سينمائية إلى قلب صالتك مع إمكانية تشغيل عروض إعلانية لأفلام أخرى وعرض مقدمات أخرى من انتقاءاتك قبل تشغيل الفيلم الرئيسي.", "CustomDlnaProfilesHelp": "إنشاء عرائض مخصوصه تستهدف جهازاً جديداً أو يمتطي حساباً نظامياً.", "DeathDateValue": "توفي: {0}", - "DefaultErrorMessage": "كان هناك خطأ في معالجة الطلب. الرجاء المحاولة لاحقاً.", + "MessageDefaultError": "كان هناك خطأ في معالجة الطلب. الرجاء المحاولة لاحقاً.", "Delete": "حذف", "DeleteDeviceConfirmation": "هل أنت متأكد أنك تريد حذف هذا الجهاز؟ سيظهر الجهاز من جديد في المرة القادمة التي يسجل فها مستخدم دخوله عبره.", "DeleteImage": "حذف صورة", @@ -110,7 +110,7 @@ "ErrorAddingTunerDevice": "كان هناك خطأ في إضافة جهاز المولف. الرجاء التأكد من صلاحية الوصول إليه ثم عاود المحاولة.", "ErrorAddingXmlTvFile": "كان هناك خطأ في محاولة الوصول إلى ملف XMLTV. الرجاء التأكد من وجود الملف ثم حاول مرة أخرى.", "ErrorGettingTvLineups": "كان هناك خطأ في إنزال اصطفافات التلفاز. الرجاء التأكد من أن بياناتك صحيحة ثم عاود المحاولة.", - "ErrorMessageStartHourGreaterThanEnd": "وقت النهاية يجب أن يكون أكبر من وقت البداية.", + "ErrorStartHourGreaterThanEnd": "وقت النهاية يجب أن يكون أكبر من وقت البداية.", "ErrorPleaseSelectLineup": "الرجاء اختيار اصطفاف ثم المحاولة مرة أخرى. إن لم تتوفر أية اصطفافات، فالرجاء التأكد من اسم المستخدم وكلمة المرور الخاصة بك، وتأكد من صحة رمزك البريدي.", "ErrorSavingTvProvider": "كان هناك خطأ في حفظ مزود التلفزة. الرجاء التأكد من صلاحية الوصول إليه ثم عاود المحاولة.", "ExitFullscreen": "الخروج من الشاشة الكاملة", @@ -632,8 +632,8 @@ "MoreUsersCanBeAddedLater": "يمكن اضافة المستخدمين لاحقا من لوحة العدادات.", "Mute": "صامت", "NextUp": "التالي", - "NoNextUpItemsMessage": "لم يتم ايجاد شيء، إبدأ بمشاهدة برامجك!", - "NoPluginConfigurationMessage": "هذا الملحق ليس له إعدادات تضبط.", + "MessageNoNextUpItems": "لم يتم ايجاد شيء، إبدأ بمشاهدة برامجك!", + "MessageNoPluginConfiguration": "هذا الملحق ليس له إعدادات تضبط.", "NumLocationsValue": "{0} مجلد(ات)", "Option3D": "ثلاثي أبعاد", "OptionAdminUsers": "المدراء", @@ -772,7 +772,7 @@ "PasswordMatchError": "كلمة السر وتاكيدها يجب ان يتطابقان.", "PasswordResetComplete": "لقد تم اعادة تعيين كلمة السر.", "PasswordResetConfirmation": "هل انت متاكد من انك تريد اعادة تعيين كلمة السر؟", - "PasswordResetHeader": "إعادة تهيئة كلمة السر", + "HeaderResetPassword": "إعادة تهيئة كلمة السر", "PasswordSaved": "تم حفظ كلمة السر.", "PictureInPicture": "صورة داخل صورة", "PinCodeResetComplete": "تمت إعادة تهيئة الرمز الشخصي", @@ -783,7 +783,7 @@ "RecommendationBecauseYouWatched": "لأنك شاهدت {0}", "RecommendationDirectedBy": "إخراج {0}", "RecommendationStarring": "بطولة {0}", - "RecordingPathChangeMessage": "إن تغيير مجلد التسجيل لم يهجّر التسجيلات الموجودة من الموقع القديم إلى الموقع الجديد. سيتعين عليك أن تنقلهم بنفسك لو شئت.", + "MessageChangeRecordingPath": "إن تغيير مجلد التسجيل لم يهجّر التسجيلات الموجودة من الموقع القديم إلى الموقع الجديد. سيتعين عليك أن تنقلهم بنفسك لو شئت.", "RememberMe": "تذكرني", "Rewind": "الترجيع", "Saturday": "السبت", @@ -862,7 +862,7 @@ "TitlePlayback": "تشغيل", "Tuesday": "الثلاثاء", "UninstallPluginConfirmation": "هل انت متاكد انك تريد إزالة تثبيت {0}؟", - "UninstallPluginHeader": "الغاء الملحق", + "HeaderUninstallPlugin": "الغاء الملحق", "Unmute": "غير صامت", "UserProfilesIntro": "إمبي يتضمن الدعم التلقائي حسابات المستخدمين، ما يتيح لكل مستخدم أن يحفظ إعدادات العرض الخاصة وحالات تشغيل الوسائط وخواص الرقابة الأبوية.", "ValueAlbumCount": "{0} ألبومـ(ات)", diff --git a/src/strings/bg-bg.json b/src/strings/bg-bg.json index 9af8c54435..3afd904af3 100644 --- a/src/strings/bg-bg.json +++ b/src/strings/bg-bg.json @@ -508,7 +508,7 @@ "NewEpisodes": "Нови епизоди", "NewEpisodesOnly": "Само нови епизоди", "News": "Новини", - "NoNextUpItemsMessage": "Нищо не е намерено. Започнете да гледате вашите предавания!", + "MessageNoNextUpItems": "Нищо не е намерено. Започнете да гледате вашите предавания!", "NoSubtitleSearchResultsFound": "Няма намерени резултати.", "NoSubtitles": "Без", "None": "Нищо", @@ -613,7 +613,7 @@ "OriginalAirDateValue": "Дата на първоначално излъчване: {0}", "Overview": "Обобщение", "ParentalRating": "Родителска оценка", - "PasswordResetHeader": "Зануляване на паролата", + "HeaderResetPassword": "Зануляване на паролата", "People": "Хора", "Photos": "Снимки", "PictureInPicture": "Картина в картина", @@ -748,7 +748,7 @@ "TrackCount": "{0} песни", "Trailers": "Трейлъри", "Tuesday": "Вторник", - "UninstallPluginHeader": "Деинсталиране на приставката", + "HeaderUninstallPlugin": "Деинсталиране на приставката", "Unmute": "Без заглушаване", "Unplayed": "Непускано", "Upload": "Качване", @@ -841,7 +841,7 @@ "OptionResElement": "рес. елемент", "ButtonChangeServer": "Смяна на сървър", "ButtonAddImage": "Добавяне на изображение", - "BrowsePluginCatalogMessage": "За да видите наличните добавки, прегледайте каталога с добавките.", + "MessageBrowsePluginCatalog": "За да видите наличните добавки, прегледайте каталога с добавките.", "Box": "Кутия", "AlwaysPlaySubtitlesHelp": "Поднадписите, съвпадащи с езика от настройките, ще се зареждат, независимо от езика на аудио то.", "BookLibraryHelp": "Поддържат се аудио книги такива съдържащи текст. Проверете ръководството за наименуване {1} на книги {0}.", @@ -882,7 +882,7 @@ "CinemaModeConfigurationHelp": "Режимът на кино носи театрално изживяване направо във вашата всекидневна с възможност за пускане на трейлъри и персонализирани интродукции преди основния филм.", "ChangingMetadataImageSettingsNewContent": "Промените в настройките за изтегляне на метаданни или изображения ще се прилагат само за ново съдържание, добавено към вашата библиотека. За да приложите промените към съществуващите заглавия, ще трябва да обновите метаданните им ръчно.", "DefaultMetadataLangaugeDescription": "Това са настройки по подразбиране и могат да се променят на база библиотека.", - "DefaultErrorMessage": "Възникна грешка при изпълнение на заявката. Моля опитайте по-късно.", + "MessageDefaultError": "Възникна грешка при изпълнение на заявката. Моля опитайте по-късно.", "CustomDlnaProfilesHelp": "Създаване на персонализиран профил за целево устройство или заменяне на системния профил.", "CopyStreamURL": "Копиране URL на стрийма", "CopyStreamURLError": "Възникна грешка при копиране на URL.", @@ -903,7 +903,7 @@ "ButtonToggleContextMenu": "Повече", "ErrorSavingTvProvider": "Има проблем със запазването на ТВ доставчика.Убедете се ,че е достъпен и опитайте отново.", "ErrorPleaseSelectLineup": "Моля изберете списък и опитайте отново.Ако няма налични списъци се убедете ,че името,паролата и пощенския код са точни.", - "ErrorMessageStartHourGreaterThanEnd": "Времето за край трябва да бъде по-голямо от началното време.", + "ErrorStartHourGreaterThanEnd": "Времето за край трябва да бъде по-голямо от началното време.", "ErrorGettingTvLineups": "Има проблем при опита да бъдат свалени списъци с ТВ.Убедете се ,че информацията е правилна и опитайте отново.", "ErrorDeletingItem": "Има проблем при опита да бъде изтрит файла от сървъра.Убедете се ,че сървъра има право да трие папки и опитайте отново.", "ErrorAddingXmlTvFile": "Има проблем при достъпа на XMLTV файла.Уверете се ,че е наличен и пробвайте отново.", @@ -1423,7 +1423,7 @@ "RefreshDialogHelp": "Метаданните се обновяват въз основа на настройките и интернет услугите, които са активирани от таблото за управление на сървъра.", "Recordings": "Записи", "RecordingScheduled": "Записът е насрочен.", - "RecordingPathChangeMessage": "Промяната на вашата папка за запис няма да мигрира съществуващите записи от старото местоположение към новото.Необходимо е да направите това ръчно.", + "MessageChangeRecordingPath": "Промяната на вашата папка за запис няма да мигрира съществуващите записи от старото местоположение към новото.Необходимо е да направите това ръчно.", "RecordSeries": "Запиши сериал", "RecommendationStarring": "В главните роли {0}", "RecommendationDirectedBy": "Режисьор {0}", @@ -1434,7 +1434,7 @@ "PreferEmbeddedEpisodeInfosOverFileNames": "Предпочитай \"вградената\" информация за епизода вместо името на файла", "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Това използва информацията за епизода от вградените метаданни, ако е налична.", "PreferEmbeddedTitlesOverFileNamesHelp": "Това определя заглавието по подразбиране, когато няма интернет метаданни или локални метаданни.", - "PluginInstalledMessage": "Добавката е успешно инсталирана. Джелифин ще трябва да бъде рестартиран, за да влязат в сила промените.", + "MessagePluginInstalled": "Добавката е успешно инсталирана. Джелифин ще трябва да бъде рестартиран, за да влязат в сила промените.", "PleaseSelectTwoItems": "Моля, изберете поне два елемента.", "PleaseEnterNameOrId": "Моля, въведете име или външен идентификатор.", "PleaseConfirmPluginInstallation": "Моля, щракнете върху OK, за да потвърдите, че сте прочели горното и искате да продължите с инсталирането на добавката.", @@ -1519,7 +1519,7 @@ "OnlyForcedSubtitles": "Само принудително", "OneChannel": "Един канал", "NoSubtitlesHelp": "Субтитрите няма да бъдат заредени по подразбиране. Те все още могат да бъдат включени ръчно по време на възпроизвеждане.", - "NoPluginConfigurationMessage": "Тази добавка няма настройки за конфигуриране.", + "MessageNoPluginConfiguration": "Тази добавка няма настройки за конфигуриране.", "NoNewDevicesFound": "Не са намерени нови устройства. За да добавите нов тунер, затворете този диалогов прозорец и въведете ръчно информацията за устройството.", "NoCreatedLibraries": "Изглежда, че все още не сте създали библиотеки. {0} Искате ли да ги създадете сега? {1}", "NextUp": "Следващ по ред", diff --git a/src/strings/ca.json b/src/strings/ca.json index 2324c31e4c..90f5ce8930 100644 --- a/src/strings/ca.json +++ b/src/strings/ca.json @@ -14,7 +14,7 @@ "AspectRatio": "Relació d'aspecte", "AttributeNew": "Nou", "Audio": "Àudio", - "BrowsePluginCatalogMessage": "Consulta el nostre catàleg per veure els complements disponibles.", + "MessageBrowsePluginCatalog": "Consulta el nostre catàleg per veure els complements disponibles.", "ButtonAdd": "Afegeix", "ButtonAddMediaLibrary": "Afegir Biblioteca Multimèdia", "ButtonAddScheduledTaskTrigger": "Afegir Disparador", @@ -84,7 +84,7 @@ "ConfirmDeletion": "Confirma supressió", "Connect": "Connecta", "Continuing": "Continuant", - "DefaultErrorMessage": "Hi ha hagut un error processant la petició. Intenta-ho més tard si et plau.", + "MessageDefaultError": "Hi ha hagut un error processant la petició. Intenta-ho més tard si et plau.", "Delete": "Esborra", "DeleteImage": "Esborra Imatge", "DeleteImageConfirmation": "Esteu segur que voleu suprimir aquesta imatge?", @@ -490,8 +490,8 @@ "NewCollectionNameExample": "Exemple: Col·leció Star Wars", "NewEpisodes": "Nous episodis", "NewEpisodesOnly": "Només nous episodis", - "NoNextUpItemsMessage": "Cap trobat. Comença a mirar els teus programes!", - "NoPluginConfigurationMessage": "Aquest complement no té opcions de configuració.", + "MessageNoNextUpItems": "Cap trobat. Comença a mirar els teus programes!", + "MessageNoPluginConfiguration": "Aquest complement no té opcions de configuració.", "NoSubtitleSearchResultsFound": "No s'han trobat resultats.", "NoSubtitles": "Sense subtítols", "None": "Cap", @@ -708,7 +708,7 @@ "TrackCount": "{0} pistes", "Tuesday": "Dimarts", "UninstallPluginConfirmation": "Estàs segur que vols desinstal·lar {0}?", - "UninstallPluginHeader": "Desinstal·lar Complement.", + "HeaderUninstallPlugin": "Desinstal·lar Complement.", "Unmute": "De-silencia", "Unrated": "Sense valorar", "Up": "Amunt", diff --git a/src/strings/cs.json b/src/strings/cs.json index fcabe3f3b3..c00b177548 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -34,7 +34,7 @@ "Books": "Knihy", "Box": "Pouzdro", "BoxRear": "Zadní část pouzdra", - "BrowsePluginCatalogMessage": "Prohlédněte si náš katalog, kde najdete dostupné zásuvné moduly.", + "MessageBrowsePluginCatalog": "Prohlédněte si náš katalog, kde najdete dostupné zásuvné moduly.", "ButtonAdd": "Přidat", "ButtonAddMediaLibrary": "Přidat knihovnu médií", "ButtonAddScheduledTaskTrigger": "Přidat Spouštěč", @@ -131,7 +131,7 @@ "DatePlayed": "Datum přehrání", "DeathDateValue": "Zemřel: {0}", "Default": "Výchozí", - "DefaultErrorMessage": "Došlo k chybě při zpracování požadavku. Prosím zkuste to znovu později.", + "MessageDefaultError": "Došlo k chybě při zpracování požadavku. Prosím zkuste to znovu později.", "DefaultMetadataLangaugeDescription": "Toto jsou vaše výchozí hodnoty a lze je přizpůsobit na základě jednotlivých knihoven.", "DefaultSubtitlesHelp": "Titulky jsou načteny na základě výchozích a vynucených nastavení ve vložených metadatech. Jazykové preference jsou vzaty v úvahu, pokud je k dispozici více možností.", "Delete": "Odstranit", @@ -185,7 +185,7 @@ "ErrorAddingXmlTvFile": "Nastala chyba při přístupu k XMLTV souboru. Ujistěte se, že soubor existuje a zkuste jej znovu otevřít.", "ErrorDeletingItem": "Při odstranění položky ze serveru Jellyfin došlo k chybě. Zkontrolujte prosím, zda má server Jellyfin oprávnění k zápisu do složky médií, a zkuste to prosím znovu.", "ErrorGettingTvLineups": "Došlo k chybě při stahování TV sestav. Ujistěte se prosím, že zadané informace jsou správné a zkuste to znovu.", - "ErrorMessageStartHourGreaterThanEnd": "Čas ukončení musí být větší než čas startu.", + "ErrorStartHourGreaterThanEnd": "Čas ukončení musí být větší než čas startu.", "ErrorPleaseSelectLineup": "Vyberte prosím sestavu a zkuste to znovu. Pokud nejsou k dispozici žádné sestavy, zkontrolujte, zda je vaše uživatelské jméno, heslo a poštovní směrovací číslo správné.", "ErrorSavingTvProvider": "Při ukládání poskytovatele TV došlo k chybě. Prosím, ujistěte se, že je přístupný a zkuste to znovu.", "ExitFullscreen": "Opustit celou obrazovku", @@ -819,8 +819,8 @@ "News": "Zpravodajství", "Next": "Další", "No": "Ne", - "NoNextUpItemsMessage": "Nic nenalezeno. Začněte sledovat Vaše oblíbené seriály!", - "NoPluginConfigurationMessage": "Tento zásuvný modul nemá žádné nastavení.", + "MessageNoNextUpItems": "Nic nenalezeno. Začněte sledovat Vaše oblíbené seriály!", + "MessageNoPluginConfiguration": "Tento zásuvný modul nemá žádné nastavení.", "NoSubtitleSearchResultsFound": "Žádné výsledky.", "NoSubtitles": "Žádné", "NoSubtitlesHelp": "Ve výchozím nastavení nebudou titulky načteny. Během přehrávání však mohou být manuálně zapnuty.", @@ -964,7 +964,7 @@ "PasswordMatchError": "Heslo a potvrzení hesla musí souhlasit.", "PasswordResetComplete": "Heslo bylo obnoveno.", "PasswordResetConfirmation": "Jste si jisti, že chcete obnovit heslo?", - "PasswordResetHeader": "Obnovit heslo", + "HeaderResetPassword": "Obnovit heslo", "PasswordSaved": "Heslo uloženo.", "People": "Lidé", "PerfectMatch": "Přesná shoda", @@ -1004,7 +1004,7 @@ "Record": "Nahrávat", "RecordSeries": "Nahrát série", "RecordingCancelled": "Nahrávání zrušeno.", - "RecordingPathChangeMessage": "Změna záznamové složky automaticky nepřesune stávající záznamy ze starého umístění do nového. Budete muset přesunout ručně, pokud je to žádoucí.", + "MessageChangeRecordingPath": "Změna záznamové složky automaticky nepřesune stávající záznamy ze starého umístění do nového. Budete muset přesunout ručně, pokud je to žádoucí.", "RecordingScheduled": "Plán nahrávání.", "Recordings": "Nahrávky", "Refresh": "Obnovit", @@ -1131,7 +1131,7 @@ "Transcoding": "Překódování", "Tuesday": "Úterý", "UninstallPluginConfirmation": "Jste si jisti, že chcete odinstalovat {0}?", - "UninstallPluginHeader": "Odinstalovat zásuvný modul", + "HeaderUninstallPlugin": "Odinstalovat zásuvný modul", "Unmute": "Povolit zvuk", "Unrated": "Nehodnoceno", "Up": "Nahoru", @@ -1358,7 +1358,7 @@ "OptionProtocolHttp": "HTTP", "OptionRequirePerfectSubtitleMatchHelp": "Vyžadování dokonalé shody filtruje titulky tak, aby obsahovaly pouze ty, které byly testovány a ověřeny s vaším přesným videosouborem. Zrušení zaškrtnutí tohoto políčka zvýší pravděpodobnost stahování titulků, ale zvýší pravděpodobnost chybného nebo nesprávného textu titulků.", "PasswordResetProviderHelp": "Zvolte poskytovatele resetování hesla, který bude použit, když tento uživatel o něj požádá", - "PluginInstalledMessage": "Zásuvný modul byl úspěšně nainstalován. Server Jellyfin bude nutné restartovat, aby se změny projevily.", + "MessagePluginInstalled": "Zásuvný modul byl úspěšně nainstalován. Server Jellyfin bude nutné restartovat, aby se změny projevily.", "PreferEmbeddedTitlesOverFileNames": "Preferovat vložené názvy nad názvy souborů", "PreferEmbeddedTitlesOverFileNamesHelp": "Toto určuje výchozí název zobrazení, pokud nejsou k dispozici žádná metadata z internetu nebo místní metadata.", "Raised": "Vystupující", diff --git a/src/strings/da.json b/src/strings/da.json index 9965294f4c..265d322fc5 100644 --- a/src/strings/da.json +++ b/src/strings/da.json @@ -31,7 +31,7 @@ "BirthPlaceValue": "Fødselssted: {0}", "BookLibraryHelp": "Lyd- og tekstbøger er understøttet. Se {0}guiden til navngivning af bøger{1}.", "Browse": "Gennemse", - "BrowsePluginCatalogMessage": "Gennemse vores plugin-katalog for at se tilgængelige plugins.", + "MessageBrowsePluginCatalog": "Gennemse vores plugin-katalog for at se tilgængelige plugins.", "ButtonAdd": "Tilføj", "ButtonAddMediaLibrary": "Tilføj Mediebibliotek", "ButtonAddScheduledTaskTrigger": "Tilføj udløser", @@ -119,7 +119,7 @@ "Continuing": "Forsættes", "CustomDlnaProfilesHelp": "Lav brugerdefinerede profiler til nye enheder eller for at overstyre en systemprofil.", "DeathDateValue": "Dødsdato: {0}", - "DefaultErrorMessage": "Det opstod en fejl ved behandlingen af forespørgslen. Prøv igen senere.", + "MessageDefaultError": "Det opstod en fejl ved behandlingen af forespørgslen. Prøv igen senere.", "DefaultMetadataLangaugeDescription": "Dette er dine standarder og kan brugerdefineres på per-biblioteks basis.", "Delete": "Slet", "DeleteDeviceConfirmation": "Er du sikker på du ønsker at slette denne enhed? Den vil dukke op igen næste gang en bruger logger ind med den.", @@ -154,7 +154,7 @@ "ErrorAddingTunerDevice": "Der opstod en fejl under tilføjelse af tuner-enhed. Kontroller venligst at den er tilgængelig og prøv igen.", "ErrorAddingXmlTvFile": "Der opstod en fejl under tilgang til XMLTV-filen. Kontroller venligst at filen findes og prøv igen.", "ErrorGettingTvLineups": "Der opstod en fejl under download af TV-opstillinger. Kontroller venligst at dine informationer er korrekte og prøv igen.", - "ErrorMessageStartHourGreaterThanEnd": "Slut tid skal være større end start tid.", + "ErrorStartHourGreaterThanEnd": "Slut tid skal være større end start tid.", "ErrorPleaseSelectLineup": "Vælg venligst en opstilling og prøv igen. Hvis ingen opstillinger er tilgængelige, så kontroller venligst at dit brugernavn, adgangskode og postnummer er korrekt.", "ErrorSavingTvProvider": "Der opstod en fejl i forsøget på at gemme udbyder. Kontroller venligst at den er tilgængelig og prøv igen.", "EveryNDays": "Hver {0} dage", @@ -754,8 +754,8 @@ "News": "Nyheder", "NextUp": "Næste", "NoNewDevicesFound": "Ingen nye enheder fundet. For at tilføje en ny tuner, luk denne dialog og skriv enhedens informationer manuelt.", - "NoNextUpItemsMessage": "Ingen fundet. Se dine serier!", - "NoPluginConfigurationMessage": "Dette plugin har ingen indstillinger at konfigurere.", + "MessageNoNextUpItems": "Ingen fundet. Se dine serier!", + "MessageNoPluginConfiguration": "Dette plugin har ingen indstillinger at konfigurere.", "NoSubtitleSearchResultsFound": "Ingen resultater fundet.", "NumLocationsValue": "{0} mapper", "OneChannel": "En kanal", @@ -890,7 +890,7 @@ "PasswordMatchError": "Adgangskode og bekræft adgangskode skal være ens.", "PasswordResetComplete": "Adgangskoden er blevet nulstillet.", "PasswordResetConfirmation": "Er du sikker på at adgangskoden skal nulstilles?", - "PasswordResetHeader": "Nulstil adgangskode", + "HeaderResetPassword": "Nulstil adgangskode", "PasswordSaved": "Adgangskoden er gemt.", "People": "Personer", "PictureInPicture": "Billede i billede", @@ -906,7 +906,7 @@ "PleaseEnterNameOrId": "Indtast venligst et navn eller eksternt ID.", "PleaseRestartServerName": "Genstart venligst Jellyfin Server - {0}.", "PleaseSelectTwoItems": "Vælg venligst mindst to elementer.", - "PluginInstalledMessage": "Plugin blev installeret med success. Jellyfin serveren skal genstartes for at aktivere det.", + "MessagePluginInstalled": "Plugin blev installeret med success. Jellyfin serveren skal genstartes for at aktivere det.", "PreferEmbeddedTitlesOverFileNames": "Foretræk indlejrede titler over filnavne", "PreferEmbeddedTitlesOverFileNamesHelp": "Dette bestemmer standard visnings titel når ingen internet metadata eller lokal metadata er tilgængelig.", "Premieres": "Premiere", @@ -923,7 +923,7 @@ "Record": "Optag", "RecordSeries": "Optag serie", "RecordingCancelled": "Optagelse annulleret.", - "RecordingPathChangeMessage": "Ændring af optagelsesmappe migrerer ikke eksisterende optagelser fra den gamle lokation til den nye. Du bliver nød til at flytte dem manuelt, hvis det ønskes.", + "MessageChangeRecordingPath": "Ændring af optagelsesmappe migrerer ikke eksisterende optagelser fra den gamle lokation til den nye. Du bliver nød til at flytte dem manuelt, hvis det ønskes.", "RecordingScheduled": "Optagelse planlagt.", "Refresh": "Opdater", "RefreshDialogHelp": "Metadata opdateres alt efter hvilke indstillinger og internet-servicer der er aktiveret i Jellyfin Server-kontrolpanelet.", @@ -1034,7 +1034,7 @@ "Tuesday": "Tirsdag", "TvLibraryHelp": "Gennemgå {0} TV-navneguiden {1}.", "UninstallPluginConfirmation": "Er du sikker på du vil afinstallere {0}?", - "UninstallPluginHeader": "Afinstaller plugin", + "HeaderUninstallPlugin": "Afinstaller plugin", "Unmute": "Genoptag lyd", "Unrated": "Ingen bedømmelse", "UserAgentHelp": "Angiv en brugerdefineret bruger-agent HTTP-header.", diff --git a/src/strings/de.json b/src/strings/de.json index 837feb42b9..0c25bb9c29 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -46,7 +46,7 @@ "Books": "Bücher", "BoxRear": "Box (Rückseite)", "Browse": "Blättern", - "BrowsePluginCatalogMessage": "Durchsuche unsere Bibliothek, um alle verfügbaren Plugins anzuzeigen.", + "MessageBrowsePluginCatalog": "Durchsuche unsere Bibliothek, um alle verfügbaren Plugins anzuzeigen.", "BurnSubtitlesHelp": "Legt fest, ob der Server die Untertitel während der Videotranskodierung einbrennen soll. Deaktivieren verbessert die Serverperformance immens. Wähle Auto, um bildbasierte Formate (z.B. VOBSUB, PGS, SUB, IDX, ...) sowie bestimmte ASS- oder SSA-Untertitel einbrennen zu lassen.", "ButtonAdd": "Hinzufügen", "ButtonAddMediaLibrary": "Füge Medienbibliothek hinzu", @@ -143,7 +143,7 @@ "DatePlayed": "Abgespielt am", "DeathDateValue": "Gestorben: {0}", "Default": "Standard", - "DefaultErrorMessage": "Es gab einen Fehler beim verarbeiten der Anfrage. Bitte versuche es später erneut.", + "MessageDefaultError": "Es gab einen Fehler beim verarbeiten der Anfrage. Bitte versuche es später erneut.", "DefaultMetadataLangaugeDescription": "Das sind deine Default-Werte, die bibliotheksspezifisch verändert werden können.", "DefaultSubtitlesHelp": "Untertitel werden gemäß der Standard- und Erzwungen-Ansicht aus den eingebetteten Metadaten geladen. Spracheinstellungen werden zur Verfügung gestellt, wenn mehrere Sprachen verfügbar sind.", "Delete": "Löschen", @@ -210,7 +210,7 @@ "ErrorAddingXmlTvFile": "Fehler beim Zugriff auf die XMLTV Datei. Stelle bitte sicher, dass die Datei existiert und versuche es nochmal.", "ErrorDeletingItem": "Fehler beim Löschen des Mediums vom Jellyfin Server. Bitte stelle sicher dass der Jellyfin Server Schreibzugriff auf den Dateiordner hat und versuche es erneut.", "ErrorGettingTvLineups": "Ein Fehler trat beim Herunterladen des Fernsehprogramms auf. Bitte stellen Sie sicher, dass Ihre Informationen korrekt sind und versuchen Sie es erneut.", - "ErrorMessageStartHourGreaterThanEnd": "Die Endzeit muss größer als die Startzeit sein.", + "ErrorStartHourGreaterThanEnd": "Die Endzeit muss größer als die Startzeit sein.", "ErrorPleaseSelectLineup": "Bitte wählen Sie ein TV Programm und versuchen Sie es erneut. Wenn keine Programme verfügbar sind prüfen Sie bitte Benutzername, Passwort und Ihre Postleitzahl.", "ErrorSavingTvProvider": "Ein Fehler beim speichern des TV Verzeichnisses trat auf. Bitte stellen Sie sicher das dieser erreichbar ist und versuchen Sie es erneut.", "EveryNDays": "Alle {0} Tage", @@ -888,8 +888,8 @@ "NextUp": "Es folgt", "No": "Nein", "NoNewDevicesFound": "Keine neuen Geräte gefunden. Um einen neuen Tuner hinzuzufügen, schließe diesen Dialog und gebe die Geräteinformationen manuell ein.", - "NoNextUpItemsMessage": "Es wurde nichts gefunden. Schau dir deine Shows an!", - "NoPluginConfigurationMessage": "Dieses Plugin hat keine konfigurierbaren Einstellungen.", + "MessageNoNextUpItems": "Es wurde nichts gefunden. Schau dir deine Shows an!", + "MessageNoPluginConfiguration": "Dieses Plugin hat keine konfigurierbaren Einstellungen.", "NoSubtitleSearchResultsFound": "Keine Ergebnisse gefunden.", "NoSubtitles": "Keine", "NoSubtitlesHelp": "Untertitel werden standardmäßig nicht geladen. Sie können aber während der Wiedergabe manuell aktiviert werden.", @@ -1026,7 +1026,7 @@ "PasswordMatchError": "Die Passwörter müssen übereinstimmen.", "PasswordResetComplete": "Das Passwort wurde zurückgesetzt.", "PasswordResetConfirmation": "Möchtest du das Passwort wirklich zurücksetzen?", - "PasswordResetHeader": "Passwort zurücksetzen", + "HeaderResetPassword": "Passwort zurücksetzen", "PasswordSaved": "Passwort gespeichert.", "People": "Personen", "PerfectMatch": "Perfektes Ergbnis", @@ -1048,7 +1048,7 @@ "PleaseEnterNameOrId": "Bitte gib einen Namen oder eine externe ID an.", "PleaseRestartServerName": "Bitte starte Jellyfin Server - {0} neu.", "PleaseSelectTwoItems": "Bitte wähle mindestens zwei Optionen aus.", - "PluginInstalledMessage": "Das Plugin wurde erfolgreich installiert. Der Jellyfin-Server muss neu gestartet werden, um die Änderungen zu übernehmen.", + "MessagePluginInstalled": "Das Plugin wurde erfolgreich installiert. Der Jellyfin-Server muss neu gestartet werden, um die Änderungen zu übernehmen.", "PreferEmbeddedTitlesOverFileNames": "Bevorzuge eingebettete Titel vor Dateinamen", "PreferEmbeddedTitlesOverFileNamesHelp": "Das bestimmt den Standard Displaytitel wenn keine lokale oder Internetmetadaten verfügbar sind.", "PreferEmbeddedEpisodeInfosOverFileNames": "Bevorzuge eingebettete Episodeninformationen vor Dateinamen", @@ -1071,7 +1071,7 @@ "Record": "Aufnehmen", "RecordSeries": "Serie aufnehmen", "RecordingCancelled": "Aufnahme abgebrochen.", - "RecordingPathChangeMessage": "Das Ändern des Aufnahmeverzeichnisses wird alte Aufnahmen nicht automatisch verschieben. Wenn Du das möchtest, musst Du das selber machen.", + "MessageChangeRecordingPath": "Das Ändern des Aufnahmeverzeichnisses wird alte Aufnahmen nicht automatisch verschieben. Wenn Du das möchtest, musst Du das selber machen.", "RecordingScheduled": "Aufnahme geplant.", "Recordings": "Aufnahmen", "Refresh": "Aktualisieren", @@ -1209,7 +1209,7 @@ "TvLibraryHelp": "Überprüfe den {0}Serienbenennungsleitfaden{1}.", "Uniform": "Einheitlich", "UninstallPluginConfirmation": "Möchtest du {0} wirklich deinstallieren?", - "UninstallPluginHeader": "Plugin deinstallieren", + "HeaderUninstallPlugin": "Plugin deinstallieren", "Unmute": "Ton ein", "Unplayed": "Ungesehen", "Unrated": "Nicht bewertet", diff --git a/src/strings/el.json b/src/strings/el.json index a1fbf85613..5b3f1afc22 100644 --- a/src/strings/el.json +++ b/src/strings/el.json @@ -43,7 +43,7 @@ "Books": "Βιβλία", "Box": "Κουτί", "Browse": "Αναζήτηση", - "BrowsePluginCatalogMessage": "Πλοηγηθείτε στον κατάλογο plugin μας για να δείτε τα διαθέσιμα plugins.", + "MessageBrowsePluginCatalog": "Πλοηγηθείτε στον κατάλογο plugin μας για να δείτε τα διαθέσιμα plugins.", "BurnSubtitlesHelp": "Καθορίζει αν ο διακομιστής πρέπει να εγγράψει τους υπότιτλους κατά τη μετατροπή βίντεο ανάλογα με τη μορφή των υπότιτλων. Η αποφυγή της εγγραφής στους υπότιτλους θα βελτιώσει την απόδοση του διακομιστή. Επιλέξτε Αυτόματα για να εγγράψετε μορφές βασισμένες σε εικόνες (VOBSUB, PGS, SUB / IDX κ.λπ.) και ορισμένους υπότιτλους ASS / SSA.", "ButtonAdd": "Πρόσθεσε", "ButtonAddMediaLibrary": "Προσθήκη βιβλιοθήκης πολυμέσων", @@ -146,7 +146,7 @@ "DatePlayed": "Ημερομηνία Αναπαραγωγής", "DeathDateValue": "Πέθανε: {0}", "Default": "Προεπιλογή", - "DefaultErrorMessage": "Παρουσιάστηκε σφάλμα κατά την επεξεργασία του αιτήματός σας. Παρακαλώ δοκιμάστε ξανά αργότερα.", + "MessageDefaultError": "Παρουσιάστηκε σφάλμα κατά την επεξεργασία του αιτήματός σας. Παρακαλώ δοκιμάστε ξανά αργότερα.", "DefaultMetadataLangaugeDescription": "Αυτές είναι οι προεπιλογές σας και μπορούν να προσαρμοστούν σε βάση ανά βιβλιοθήκη.", "DefaultSubtitlesHelp": "Οι υπότιτλοι φορτώνονται με βάση τις προεπιλεγμένες και αναγκασμένες σημαίες στα ενσωματωμένα μεταδεδομένα. Οι προτιμήσεις γλώσσας εξετάζονται όταν υπάρχουν πολλές επιλογές.", "Delete": "Διαγραφή", @@ -206,7 +206,7 @@ "Episodes": "Επεισόδια", "ErrorAddingMediaPathToVirtualFolder": "Παρουσιάστηκε σφάλμα κατά την προσθήκη της διαδρομής πολυμέσων. Βεβαιωθείτε ότι η διαδρομή είναι έγκυρη και ότι η διαδικασία του διακομιστή Jellyfin έχει πρόσβαση σε αυτήν τη θέση.", "ErrorDeletingItem": "Παρουσιάστηκε σφάλμα κατά τη διαγραφή του στοιχείου από τον διακομιστή Jellyfin. Βεβαιωθείτε ότι ο διακομιστής Jellyfin έχει πρόσβαση εγγραφής στο φάκελο πολυμέσων και προσπαθήστε ξανά.", - "ErrorMessageStartHourGreaterThanEnd": "Η ώρα λήξης πρέπει να είναι μεγαλύτερη από την ώρα έναρξης.", + "ErrorStartHourGreaterThanEnd": "Η ώρα λήξης πρέπει να είναι μεγαλύτερη από την ώρα έναρξης.", "EveryNDays": "Κάθε {0} μέρες", "ExitFullscreen": "Έξοδος από τη πλήρη οθόνη", "ExtraLarge": "Πολύ Μεγάλο", @@ -794,8 +794,8 @@ "Next": "Επόμενο", "NextUp": "Επόμενο", "No": "Οχι", - "NoNextUpItemsMessage": "Δεν βρέθηκε κανένα. Ξεκινήστε παρακολουθώντας τις εκπομπές σας!", - "NoPluginConfigurationMessage": "Αυτό το plugin δεν απαιτεί ρυθμίσεις.", + "MessageNoNextUpItems": "Δεν βρέθηκε κανένα. Ξεκινήστε παρακολουθώντας τις εκπομπές σας!", + "MessageNoPluginConfiguration": "Αυτό το plugin δεν απαιτεί ρυθμίσεις.", "NoSubtitleSearchResultsFound": "Δεν βρέθηκαν αποτελέσματα.", "NoSubtitles": "Χωρίς Υπότιτλους", "NoSubtitlesHelp": "Οι υπότιτλοι δεν θα φορτωθούν από προεπιλογή.Μπορούν ακόμα να ενεργοποιούνται χειροκίνητα κατά την αναπαραγωγή.", @@ -925,7 +925,7 @@ "PasswordMatchError": "Ο κωδικός πρόσβασης και ο κωδικός επιβεβαίωσης πρέπει να είναι ίδιοι.", "PasswordResetComplete": "Ο κωδικός πρόσβασης επαναφέρθηκε.", "PasswordResetConfirmation": "Είστε σίγουροι ότι θέλετε να επαναφέρετε τον κωδικό πρόσβασης;", - "PasswordResetHeader": "Επαναφορά του κωδικού πρόσβασης", + "HeaderResetPassword": "Επαναφορά του κωδικού πρόσβασης", "PasswordSaved": "Ο κωδικός πρόσβασης αποθηκεύτηκε.", "People": "Πρόσωπα", "PerfectMatch": "Τέλεια αντιστοίχιση", @@ -946,7 +946,7 @@ "PleaseEnterNameOrId": "Εισαγάγετε ένα όνομα ή ένα εξωτερικό αναγνωριστικό.", "PleaseRestartServerName": "Κάντε επανεκκίνηση του Jellyfin Server - {0}.", "PleaseSelectTwoItems": "Επιλέξτε τουλάχιστον δύο στοιχεία.", - "PluginInstalledMessage": "Η προσθήκη έχει εγκατασταθεί με επιτυχία. Θα πρέπει να γίνει επανεκκίνηση του διακομιστή Jellyfin για να εφαρμοστούν οι αλλαγές.", + "MessagePluginInstalled": "Η προσθήκη έχει εγκατασταθεί με επιτυχία. Θα πρέπει να γίνει επανεκκίνηση του διακομιστή Jellyfin για να εφαρμοστούν οι αλλαγές.", "Premiere": "Πρεμιέρα", "Premieres": "Πρεμιέρες", "Previous": "Προηγούμενο", @@ -1103,7 +1103,7 @@ "Tuesday": "Τρίτη", "Uniform": "ομοειδής", "UninstallPluginConfirmation": "Είστε σίγουροι ότι θέλετε να απεγκαταστήσετε;", - "UninstallPluginHeader": "απεγκατάστησετε το plugin", + "HeaderUninstallPlugin": "απεγκατάστησετε το plugin", "Unmute": "Με ήχο", "Unplayed": "Δεν παίχθηκε", "Unrated": "Χωρίς Βαθμολογία", diff --git a/src/strings/en-gb.json b/src/strings/en-gb.json index 1947dc0c37..43269a507f 100644 --- a/src/strings/en-gb.json +++ b/src/strings/en-gb.json @@ -1,6 +1,6 @@ { "AdditionalNotificationServices": "Browse the plugin catalogue to install additional notification services.", - "BrowsePluginCatalogMessage": "Browse our plugin catalogue to view available plugins.", + "MessageBrowsePluginCatalog": "Browse our plugin catalogue to view available plugins.", "CinemaModeConfigurationHelp": "Cinema mode brings the theatre experience straight to your living room with the ability to play trailers and custom intros before the main feature.", "ColorPrimaries": "Colour primaries", "ColorSpace": "Colour space", @@ -202,7 +202,7 @@ "DatePlayed": "Date played", "DeathDateValue": "Died: {0}", "Default": "Default", - "DefaultErrorMessage": "There was an error processing the request. Please try again later.", + "MessageDefaultError": "There was an error processing the request. Please try again later.", "DefaultSubtitlesHelp": "Subtitles are loaded based on the default and forced flags in the embedded metadata. Language preferences are considered when multiple options are available.", "Delete": "Delete", "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.", @@ -269,7 +269,7 @@ "ErrorAddingXmlTvFile": "There was an error accessing the XMLTV file. Please ensure the file exists and try again.", "ErrorDeletingItem": "There was an error deleting the item from Jellyfin Server. Please check that Jellyfin Server has write access to the media folder and try again.", "ErrorGettingTvLineups": "There was an error downloading TV lineups. Please ensure your information is correct and try again.", - "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time.", + "ErrorStartHourGreaterThanEnd": "End time must be greater than the start time.", "ErrorPleaseSelectLineup": "Please select a lineup and try again. If no lineups are available, then please check that your username, password, and postal code is correct.", "ErrorSavingTvProvider": "There was an error saving the TV provider. Please ensure it is accessible and try again.", "EveryNDays": "Every {0} days", @@ -466,7 +466,7 @@ "Unrated": "Unrated", "Unplayed": "Unplayed", "Unmute": "Unmute", - "UninstallPluginHeader": "Uninstall Plugin", + "HeaderUninstallPlugin": "Uninstall Plugin", "Trailers": "Trailers", "TrackCount": "{0} tracks", "TitlePlayback": "Playback", @@ -567,7 +567,7 @@ "Refresh": "Refresh", "Recordings": "Recordings", "RecordingScheduled": "Recording scheduled.", - "RecordingPathChangeMessage": "Changing your recording folder will not migrate existing recordings from the old location to the new. You'll need to move them manually if desired.", + "MessageChangeRecordingPath": "Changing your recording folder will not migrate existing recordings from the old location to the new. You'll need to move them manually if desired.", "RecordingCancelled": "Recording cancelled.", "RecordSeries": "Record series", "Record": "Record", @@ -585,7 +585,7 @@ "Premiere": "Premiere", "PreferEmbeddedTitlesOverFileNamesHelp": "This determines the default display title when no internet metadata or local metadata is available.", "PreferEmbeddedTitlesOverFileNames": "Prefer embedded titles over filenames", - "PluginInstalledMessage": "The plugin has been successfully installed. Jellyfin Server will need to be restarted for changes to take effect.", + "MessagePluginInstalled": "The plugin has been successfully installed. Jellyfin Server will need to be restarted for changes to take effect.", "PleaseSelectTwoItems": "Please select at least two items.", "PleaseRestartServerName": "Please restart Jellyfin Server - {0}.", "PleaseConfirmPluginInstallation": "Please click OK to confirm you've read the above and wish to proceed with the plugin installation.", @@ -602,7 +602,7 @@ "PictureInPicture": "Picture in picture", "PerfectMatch": "Perfect match", "PasswordSaved": "Password saved.", - "PasswordResetHeader": "Reset Password", + "HeaderResetPassword": "Reset Password", "PasswordResetConfirmation": "Are you sure you wish to reset the password?", "PasswordResetComplete": "The password has been reset.", "PasswordMatchError": "Password and password confirmation must match.", @@ -686,8 +686,8 @@ "None": "None", "NoSubtitlesHelp": "Subtitles will not be loaded by default. They can still be turned on manually during playback.", "NoSubtitles": "None", - "NoPluginConfigurationMessage": "This plugin has no settings to configure.", - "NoNextUpItemsMessage": "None found. Start watching your shows!", + "MessageNoPluginConfiguration": "This plugin has no settings to configure.", + "MessageNoNextUpItems": "None found. Start watching your shows!", "No": "No", "NextUp": "Next Up", "NewEpisodesOnly": "New episodes only", diff --git a/src/strings/en-us.json b/src/strings/en-us.json index a148ef061f..ea190351ce 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -61,7 +61,7 @@ "BoxSet": "Box Set", "BoxRear": "Box (rear)", "Browse": "Browse", - "BrowsePluginCatalogMessage": "Browse our plugin catalog to view available plugins.", + "MessageBrowsePluginCatalog": "Browse our plugin catalog to view available plugins.", "BurnSubtitlesHelp": "Determines if the server should burn in subtitles when transcoding videos. Avoiding this will greatly improve performance. Select Auto to burn image based formats (VOBSUB, PGS, SUB, IDX, …) and certain ASS or SSA subtitles.", "ButtonAdd": "Add", "ButtonAddImage": "Add Image", @@ -178,7 +178,7 @@ "DatePlayed": "Date played", "DeathDateValue": "Died: {0}", "Default": "Default", - "DefaultErrorMessage": "There was an error processing the request. Please try again later.", + "MessageDefaultError": "There was an error processing the request. Please try again later.", "DefaultMetadataLangaugeDescription": "These are your defaults and can be customized on a per-library basis.", "DefaultSubtitlesHelp": "Subtitles are loaded based on the default and forced flags in the embedded metadata. Language preferences are considered when multiple options are available.", "DeinterlaceMethodHelp": "Select the deinterlacing method to use when transcoding interlaced content.", @@ -253,7 +253,7 @@ "ErrorAddingXmlTvFile": "There was an error accessing the XMLTV file. Please ensure the file exists and try again.", "ErrorDeletingItem": "There was an error deleting the item from Jellyfin Server. Please check that Jellyfin Server has write access to the media folder and try again.", "ErrorGettingTvLineups": "There was an error downloading TV lineups. Please ensure your information is correct and try again.", - "ErrorMessageStartHourGreaterThanEnd": "End time must be greater than the start time.", + "ErrorStartHourGreaterThanEnd": "End time must be greater than the start time.", "ErrorPleaseSelectLineup": "Please select a lineup and try again. If no lineups are available, then please check that your username, password, and postal code is correct.", "ErrorSavingTvProvider": "There was an error saving the TV provider. Please ensure it is accessible and try again.", "EveryNDays": "Every {0} days", @@ -576,11 +576,11 @@ "LabelAuthProvider": "Authentication Provider:", "LabelAutomaticallyRefreshInternetMetadataEvery": "Automatically refresh metadata from the internet:", "LabelBindToLocalNetworkAddress": "Bind to local network address:", - "LabelBindToLocalNetworkAddressHelp": "Optional. Override the local IP address to bind the http server to. If left empty, the server will bind to all availabile addresses. Changing this value requires restarting Jellyfin Server.", + "LabelBindToLocalNetworkAddressHelp": "Override the local IP address to bind the http server to. If left empty, the server will bind to all availabile addresses. Changing this value requires restarting Jellyfin Server.", "LabelBirthDate": "Birth date:", "LabelBirthYear": "Birth year:", "LabelBitrate": "Bitrate:", - "LabelBlastMessageInterval": "Alive message interval (seconds)", + "LabelBlastMessageInterval": "Alive message interval", "LabelBlastMessageIntervalHelp": "Determines the duration in seconds between blast alive messages.", "LabelBlockContentWithTags": "Block items with tags:", "LabelBurnSubtitles": "Burn subtitles:", @@ -753,7 +753,7 @@ "LabelMovieCategories": "Movie categories:", "LabelMoviePrefix": "Movie prefix:", "LabelMoviePrefixHelp": "If a prefix is applied to movie titles, enter it here so the server can handle it properly.", - "LabelMovieRecordingPath": "Movie recording path (optional):", + "LabelMovieRecordingPath": "Movie recording path:", "LabelMusicStreamingTranscodingBitrate": "Music transcoding bitrate:", "LabelMusicStreamingTranscodingBitrateHelp": "Specify a max bitrate when streaming music.", "LabelName": "Name:", @@ -770,7 +770,7 @@ "LabelNumber": "Number:", "LabelNumberOfGuideDays": "Number of days of guide data to download:", "LabelNumberOfGuideDaysHelp": "Downloading more days worth of guide data provides the ability to schedule out further in advance and view more listings, but it will also take longer to download. Auto will choose based on the number of channels.", - "LabelOptionalNetworkPath": "(Optional) Shared network folder:", + "LabelOptionalNetworkPath": "Shared network folder:", "LabelOptionalNetworkPathHelp": "If this folder is shared on your network, supplying the network share path can allow Jellyfin apps on other devices to access media files directly. For example, {0} or {1}.", "LabelOriginalAspectRatio": "Original aspect ratio:", "LabelOriginalTitle": "Original title:", @@ -836,7 +836,7 @@ "LabelSelectVersionToInstall": "Select version to install:", "LabelSendNotificationToUsers": "Send the notification to:", "LabelSerialNumber": "Serial number", - "LabelSeriesRecordingPath": "Series recording path (optional):", + "LabelSeriesRecordingPath": "Series recording path:", "LabelServerHost": "Host:", "LabelServerHostHelp": "192.168.1.100:8096 or https://myserver.com", "LabelServerName": "Server name:", @@ -1100,8 +1100,8 @@ "No": "No", "NoCreatedLibraries": "Seems like you haven't created any libraries yet. {0}Would you like to create one now?{1}", "NoNewDevicesFound": "No new devices found. To add a new tuner, close this dialog and enter the device information manually.", - "NoNextUpItemsMessage": "None found. Start watching your shows!", - "NoPluginConfigurationMessage": "This plugin has no settings to configure.", + "MessageNoNextUpItems": "None found. Start watching your shows!", + "MessageNoPluginConfiguration": "This plugin has no settings to configure.", "NoSubtitleSearchResultsFound": "No results found.", "NoSubtitles": "None", "NoSubtitlesHelp": "Subtitles will not be loaded by default. They can still be turned on manually during playback.", @@ -1275,7 +1275,7 @@ "PasswordMatchError": "Password and password confirmation must match.", "PasswordResetComplete": "The password has been reset.", "PasswordResetConfirmation": "Are you sure you wish to reset the password?", - "PasswordResetHeader": "Reset Password", + "HeaderResetPassword": "Reset Password", "PasswordResetProviderHelp": "Choose a Password Reset Provider to be used when this user requests a password reset", "PasswordSaved": "Password saved.", "People": "People", @@ -1301,7 +1301,7 @@ "PleaseEnterNameOrId": "Please enter a name or an external ID.", "PleaseRestartServerName": "Please restart Jellyfin Server - {0}.", "PleaseSelectTwoItems": "Please select at least two items.", - "PluginInstalledMessage": "The plugin has been successfully installed. Jellyfin Server will need to be restarted for changes to take effect.", + "MessagePluginInstalled": "The plugin has been successfully installed. Jellyfin Server will need to be restarted for changes to take effect.", "PreferEmbeddedTitlesOverFileNames": "Prefer embedded titles over filenames", "PreferEmbeddedTitlesOverFileNamesHelp": "This determines the default display title when no internet metadata or local metadata is available.", "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "This uses the episode information from the embedded metadata if available.", @@ -1326,7 +1326,7 @@ "Record": "Record", "RecordSeries": "Record series", "RecordingCancelled": "Recording cancelled.", - "RecordingPathChangeMessage": "Changing your recording folder will not migrate existing recordings from the old location to the new. You'll need to move them manually if desired.", + "ChangeRecordingPath": "Changing your recording folder will not migrate existing recordings from the old location to the new. You'll need to move them manually if desired.", "RecordingScheduled": "Recording scheduled.", "Recordings": "Recordings", "Refresh": "Refresh", @@ -1366,7 +1366,7 @@ "SearchResults": "Search Results", "Season": "Season", "SelectAdminUsername": "Please select a username for the admin account.", - "SendMessage": "Send message", + "Send": "Send ", "Series": "Series", "SeriesCancelled": "Series cancelled.", "SeriesDisplayOrderHelp": "Order episodes by air date, DVD order, or absolute numbering.", @@ -1495,7 +1495,7 @@ "TvLibraryHelp": "Review the {0}TV naming guide{1}.", "Uniform": "Uniform", "UninstallPluginConfirmation": "Are you sure you wish to uninstall {0}?", - "UninstallPluginHeader": "Uninstall Plugin", + "HeaderUninstallPlugin": "Uninstall Plugin", "Unmute": "Unmute", "Unplayed": "Unplayed", "Unrated": "Unrated", diff --git a/src/strings/es-ar.json b/src/strings/es-ar.json index e64f1e7c6e..23ce44b56a 100644 --- a/src/strings/es-ar.json +++ b/src/strings/es-ar.json @@ -97,7 +97,7 @@ "Box": "Caja", "BoxRear": "Caja (lado opuesto)", "Browse": "Explorar", - "BrowsePluginCatalogMessage": "Explore nuestro catálogo de complementos para ver los complementos disponibles.", + "MessageBrowsePluginCatalog": "Explore nuestro catálogo de complementos para ver los complementos disponibles.", "BurnSubtitlesHelp": "Determina si el servidor debe grabarse en subtítulos al transcodificar videos. Evitar esto mejorará en gran medida el rendimiento. Seleccione Automático para grabar formatos basados en imágenes (VOBSUB, PGS, SUB, IDX, ...) y ciertos subtítulos ASS o SSA.", "ButtonAdd": "Agregar", "ButtonAddMediaLibrary": "Agregar biblioteca de medios", @@ -201,7 +201,7 @@ "DatePlayed": "Fecha de reproducción", "DeathDateValue": "Muerte: {0}", "Default": "Predeterminado", - "DefaultErrorMessage": "Hubo un error procesando la solicitud. Por favor intentalo nuevamente mas tarde.", + "MessageDefaultError": "Hubo un error procesando la solicitud. Por favor intentalo nuevamente mas tarde.", "DefaultMetadataLangaugeDescription": "Estos son tus predeterminados y pueden ser personalizados por librería únicamente.", "Delete": "Borrar", "DeleteDeviceConfirmation": "Estas seguro que quieres borrar este dispositivo? Este va a volver a aparecer cuando una persona se registre.", @@ -271,7 +271,7 @@ "ErrorAddingXmlTvFile": "Ocurrió un error al acceder al archivo de XmlTV. Por favor asegúrate de que el archivo existe e intenta de nuevo.", "ErrorDeletingItem": "Ocurrió un error al eliminar el ítem del servidor Jellyfin. Por favor verifica que el servidor Jellyfin tiene permiso de escritura a la carpeta de medios e intenta de nuevo.", "ErrorGettingTvLineups": "Ocurrió un error al descargar la guía de programación de TV. Por favor asegúrate que tu información es correcta e intenta de nuevo.", - "ErrorMessageStartHourGreaterThanEnd": "La hora de fin tiene que ser mayor que la de inicio.", + "ErrorStartHourGreaterThanEnd": "La hora de fin tiene que ser mayor que la de inicio.", "ErrorPleaseSelectLineup": "Por favor selecciona un alineamiento e intenta de nuevo. Si no existen alineamientos disponibles, asegúrate de que tu nombre de usuario, contraseña y código postal son correctos.", "ErrorSavingTvProvider": "Ocurrió un error al guardar el proveedor de TV. Por favor asegúrate de que está disponible e intenta de nuevo.", "EveryNDays": "Cada {0} días", @@ -918,8 +918,8 @@ "NoSubtitlesHelp": "Los subtítulos no se cargarán de manera predeterminada. Todavía se pueden activar manualmente durante la reproducción.", "NoSubtitles": "Ninguno", "NoSubtitleSearchResultsFound": "No se han encontrado resultados.", - "NoPluginConfigurationMessage": "Este complemento no tiene opciones para configurar.", - "NoNextUpItemsMessage": "Nada encontrado. ¡Comienza a ver tus shows!", + "MessageNoPluginConfiguration": "Este complemento no tiene opciones para configurar.", + "MessageNoNextUpItems": "Nada encontrado. ¡Comienza a ver tus shows!", "NoNewDevicesFound": "No se encontraron nuevos dispositivos. Para agregar un nuevo sintonizador, cierre este cuadro de diálogo e ingrese la información del dispositivo manualmente.", "NoCreatedLibraries": "Parece que todavía no has creado ninguna biblioteca. {0}¿Te gustaría crear una ahora?{1}", "No": "No", @@ -1208,7 +1208,7 @@ "Refresh": "Actualizar", "Recordings": "Grabaciones", "RecordingScheduled": "Grabación programada.", - "RecordingPathChangeMessage": "Cambiar su carpeta de grabación no migrará las grabaciones existentes de la ubicación anterior a la nueva. Tendrá que moverlos manualmente si lo desea.", + "MessageChangeRecordingPath": "Cambiar su carpeta de grabación no migrará las grabaciones existentes de la ubicación anterior a la nueva. Tendrá que moverlos manualmente si lo desea.", "RecordingCancelled": "Grabación cancelada.", "RecordSeries": "Grabar series", "Record": "Grabar", @@ -1232,7 +1232,7 @@ "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Esto usa la información de los metadatos incrustados del capítulo si está disponible.", "PreferEmbeddedTitlesOverFileNamesHelp": "Esto determina el título de visualización predeterminado cuando no hay metadatos de Internet o metadatos locales disponibles.", "PreferEmbeddedTitlesOverFileNames": "Preferir títulos incrustados sobre nombres de archivo", - "PluginInstalledMessage": "El complemento se ha instalado correctamente. El servidor Jellyfin deberá reiniciarse para que los cambios surtan efecto.", + "MessagePluginInstalled": "El complemento se ha instalado correctamente. El servidor Jellyfin deberá reiniciarse para que los cambios surtan efecto.", "PleaseSelectTwoItems": "Seleccione al menos dos elementos.", "PleaseRestartServerName": "Reinicie el servidor Jellyfin - {0}.", "PleaseEnterNameOrId": "Por favor, introduzca un nombre o una ID externa.", @@ -1256,7 +1256,7 @@ "People": "Personas", "PasswordSaved": "Contraseña guardada.", "PasswordResetProviderHelp": "Elija un proveedor de restablecimiento de contraseña para usar cuando este usuario solicite un restablecimiento de contraseña", - "PasswordResetHeader": "Restablecer contraseña", + "HeaderResetPassword": "Restablecer contraseña", "PasswordResetConfirmation": "¿Estás seguro de que deseas restablecer la contraseña?", "PasswordResetComplete": "La contraseña ha sido restablecida.", "PasswordMatchError": "La contraseña y la confirmación de la contraseña deben coincidir.", @@ -1412,7 +1412,7 @@ "Unrated": "Sin calificación", "Unplayed": "No reproducido", "Unmute": "Dejar de silenciar", - "UninstallPluginHeader": "Desinstalar complemento", + "HeaderUninstallPlugin": "Desinstalar complemento", "UninstallPluginConfirmation": "¿Estás seguro de que deseas desinstalar {0}?", "Uniform": "Uniforme", "TvLibraryHelp": "Revise la {0}guía de nombres de TV{1}.", diff --git a/src/strings/es-mx.json b/src/strings/es-mx.json index 5500a26ce6..af2e2b5d4b 100644 --- a/src/strings/es-mx.json +++ b/src/strings/es-mx.json @@ -50,7 +50,7 @@ "Box": "Caja", "BoxRear": "Caja (parte trasera)", "Browse": "Explorar", - "BrowsePluginCatalogMessage": "Explora nuestro catálogo de complementos para ver los complementos disponibles.", + "MessageBrowsePluginCatalog": "Explora nuestro catálogo de complementos para ver los complementos disponibles.", "BurnSubtitlesHelp": "Determina si el servidor debería quemar los subtítulos al transcodificar videos. Evitar esto mejorará altamente el rendimiento del servidor. Seleccione Auto para grabar formatos basados en imágenes (VOBSUB, PGS, SUB, IDX...) y ciertos subtítulos ASS o SSA.", "ButtonAdd": "Agregar", "ButtonAddMediaLibrary": "Agregar biblioteca de medios", @@ -156,7 +156,7 @@ "DatePlayed": "Fecha de reproducción", "DeathDateValue": "Falleció: {0}", "Default": "Por defecto", - "DefaultErrorMessage": "Ha ocurrido un error al procesar la solicitud. Por favor, inténtalo de nuevo más tarde.", + "MessageDefaultError": "Ha ocurrido un error al procesar la solicitud. Por favor, inténtalo de nuevo más tarde.", "DefaultMetadataLangaugeDescription": "Estos son sus valores por defecto y pueden ser personalizados en cada biblioteca.", "DefaultSubtitlesHelp": "Los subtítulos se cargan basados en los indicadores «por defecto» y «forzado» incluidos en los metadatos. Las preferencias de idioma son consideradas cuando hay múltiples opciones disponibles.", "Delete": "Eliminar", @@ -224,7 +224,7 @@ "ErrorAddingXmlTvFile": "Hubo un error accediendo al archivo XMLTV. Por favor, asegúrate de que el archivo existe e inténtalo de nuevo.", "ErrorDeletingItem": "Hubo un error eliminando el elemento del servidor Jellyfin. Por favor, verifica que el servidor Jellyfin tiene permisos de escritura en la carpeta del medio e inténtalo de nuevo.", "ErrorGettingTvLineups": "Hubo un error al descargar la programación de TV. Por favor, asegúrate de que tu información sea correcta e inténtalo de nuevo.", - "ErrorMessageStartHourGreaterThanEnd": "La hora de finalización debe ser mayor que la hora de inicio.", + "ErrorStartHourGreaterThanEnd": "La hora de finalización debe ser mayor que la hora de inicio.", "ErrorPleaseSelectLineup": "Por favor, selecciona una programación e inténtalo de nuevo. Si no hay disponible ninguna, entonces, por favor, verifica que tu nombre de usuario, contraseña, y código postal sean correctos.", "ErrorSavingTvProvider": "Hubo un error al guardar el proveedor de TV. Por favor, asegúrate de que sea accesible e inténtalo de nuevo.", "EveryNDays": "Cada {0} días", @@ -934,8 +934,8 @@ "Next": "Siguiente", "NextUp": "A continuación", "NoNewDevicesFound": "No se encontraron nuevos dispositivos. Para agregar un sintonizador nuevo, cierra este diálogo e introduce la información del dispositivo manualmente.", - "NoNextUpItemsMessage": "No se encontró nada. ¡Comienza a ver tus programas!", - "NoPluginConfigurationMessage": "Este complemento no tiene configuraciones disponibles.", + "MessageNoNextUpItems": "No se encontró nada. ¡Comienza a ver tus programas!", + "MessageNoPluginConfiguration": "Este complemento no tiene configuraciones disponibles.", "NoSubtitleSearchResultsFound": "No se encontraron resultados.", "NoSubtitles": "Ninguno", "NoSubtitlesHelp": "Los subtítulos no serán cargados por defecto. Pueden ser activados manualmente durante la reproducción.", @@ -1087,7 +1087,7 @@ "PasswordMatchError": "La contraseña y la confirmación de la contraseña deben coincidir.", "PasswordResetComplete": "La contraseña ha sido restablecida.", "PasswordResetConfirmation": "¿Estás seguro de querer restablecer la contraseña?", - "PasswordResetHeader": "Restablecer contraseña", + "HeaderResetPassword": "Restablecer contraseña", "PasswordSaved": "Contraseña guardada.", "People": "Personas", "PerfectMatch": "Coincidencia perfecta", @@ -1109,7 +1109,7 @@ "PleaseEnterNameOrId": "Por favor, introduce un nombre o ID externo.", "PleaseRestartServerName": "Por favor, reinicia el servidor Jellyfin - {0}.", "PleaseSelectTwoItems": "Por favor, selecciona al menos dos elementos.", - "PluginInstalledMessage": "El complemento ha sido instalado con éxito. El servidor Jellyfin necesitará ser reiniciado para que los cambios surtan efecto.", + "MessagePluginInstalled": "El complemento ha sido instalado con éxito. El servidor Jellyfin necesitará ser reiniciado para que los cambios surtan efecto.", "PreferEmbeddedTitlesOverFileNames": "Preferir títulos incrustados a los nombres de archivo", "PreferEmbeddedTitlesOverFileNamesHelp": "Esto determina el título mostrado por defecto cuando no hay disponibles metadatos en Internet o localmente.", "Premiere": "Estreno", @@ -1131,7 +1131,7 @@ "Record": "Grabar", "RecordSeries": "Grabar series", "RecordingCancelled": "Grabación cancelada.", - "RecordingPathChangeMessage": "Cambiar la carpeta de grabaciones no moverá las grabaciones existentes de la antigua ubicación a la nueva. Necesitan moverse manualmente si se desea.", + "MessageChangeRecordingPath": "Cambiar la carpeta de grabaciones no moverá las grabaciones existentes de la antigua ubicación a la nueva. Necesitan moverse manualmente si se desea.", "RecordingScheduled": "Grabación programada.", "Recordings": "Grabaciones", "Refresh": "Actualizar", @@ -1281,7 +1281,7 @@ "TvLibraryHelp": "Revisa la {0}guía de nombrado de series de TV{1}.", "Uniform": "Uniforme", "UninstallPluginConfirmation": "¿Estás seguro de querer desinstalar {0}?", - "UninstallPluginHeader": "Desinstalar complemento", + "HeaderUninstallPlugin": "Desinstalar complemento", "Unmute": "Activar sonido", "Unplayed": "No reproducido", "Unrated": "Sin clasificar", diff --git a/src/strings/es.json b/src/strings/es.json index 23bc5c9330..45c9b1f452 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -40,7 +40,7 @@ "Box": "Caja", "BoxRear": "Caja (trasera)", "Browse": "Explorar", - "BrowsePluginCatalogMessage": "Explore el catálogo de extensiones para ver las extensiones disponibles.", + "MessageBrowsePluginCatalog": "Explore el catálogo de extensiones para ver las extensiones disponibles.", "ButtonAdd": "Añadir", "ButtonAddMediaLibrary": "Añadir biblioteca de medios", "ButtonAddScheduledTaskTrigger": "Agregar Activador", @@ -138,7 +138,7 @@ "CustomDlnaProfilesHelp": "Crear un perfil personalizado para un nuevo dispositivo o reemplazar un perfil del sistema.", "DeathDateValue": "Murió: {0}", "Default": "Por defecto", - "DefaultErrorMessage": "Ha habido un error procesando la solicitud. Por favor inténtalo más tarde.", + "MessageDefaultError": "Ha habido un error procesando la solicitud. Por favor inténtalo más tarde.", "DefaultMetadataLangaugeDescription": "Estos son tus ajustes y se pueden personalizar para cada biblioteca.", "DefaultSubtitlesHelp": "Los subtítulos que se utilizarán dependerán de como estén etiquetadas las pistas de los archivos (si \"por defecto\" o \"forzado\"). Los ajustes de idioma se tienen en cuenta cuando hay varias opciones disponibles.", "Delete": "Borrar", @@ -185,7 +185,7 @@ "ErrorAddingTunerDevice": "Ha habido un error añadiendo el dispositivo sintonizador. Por favor, asegúrate de que es accesible e inténtalo otra vez.", "ErrorAddingXmlTvFile": "Ha sucedido un error accediendo al archivo XML. Por favor, asegúrate que el archivo existe e inténtalo de nuevo.", "ErrorGettingTvLineups": "Ha habido un error descargando la programación de TV. Por favor, asegúrese que la información es correcta e inténtalo de nuevo.", - "ErrorMessageStartHourGreaterThanEnd": "La hora de finalización tiene que ser mayor que la de inicio.", + "ErrorStartHourGreaterThanEnd": "La hora de finalización tiene que ser mayor que la de inicio.", "ErrorPleaseSelectLineup": "Por favor selecciona una alineación e inténtalo otra vez. Si no hay alineaciones disponibles, revisa que tu nombre de usuario, contraseña y código postal son correctos.", "ErrorSavingTvProvider": "Ha habido un error guardando el proveedor de TV. Por favor, asegúrate de que es accesible e inténtalo otra vez.", "EveryNDays": "Cada {0} días", @@ -854,8 +854,8 @@ "Next": "Siguiente", "NextUp": "Seguidamente", "NoNewDevicesFound": "No se han encontrado nuevos dispositivos. Para añadir un sintonizador cierra este diálogo e introduce la información del dispositivo manualmente.", - "NoNextUpItemsMessage": "Nada encontrado. ¡Comienza a ver tus programas!", - "NoPluginConfigurationMessage": "Este complemento no tiene opciones que configurar.", + "MessageNoNextUpItems": "Nada encontrado. ¡Comienza a ver tus programas!", + "MessageNoPluginConfiguration": "Este complemento no tiene opciones que configurar.", "NoSubtitleSearchResultsFound": "No se han encontrado resultados.", "NoSubtitles": "Sin subtítulos", "NoSubtitlesHelp": "Los subtítulos no se cargarán de forma predeterminada. Tienen que ser activados manualmente durante la reproducción.", @@ -1000,7 +1000,7 @@ "PasswordMatchError": "La contraseña y la confirmación de la contraseña deben de ser iguales.", "PasswordResetComplete": "La contraseña se ha restablecido.", "PasswordResetConfirmation": "¿Esta seguro de que desea restablecer la contraseña?", - "PasswordResetHeader": "Restablecer contraseña", + "HeaderResetPassword": "Restablecer contraseña", "PasswordSaved": "Contraseña guardada.", "People": "Gente", "PinCodeResetComplete": "El código PIN se ha restablecido.", @@ -1017,7 +1017,7 @@ "PleaseEnterNameOrId": "Introduzca un nombre o un identificador externo.", "PleaseRestartServerName": "Por favor, reinicie el Servidor de Jellyfin - {0}.", "PleaseSelectTwoItems": "Seleccione al menos dos elementos.", - "PluginInstalledMessage": "El complemento se ha instalado correctamente. El servidor Jellyfin deberá reiniciarse para que los cambios surjan efecto.", + "MessagePluginInstalled": "El complemento se ha instalado correctamente. El servidor Jellyfin deberá reiniciarse para que los cambios surjan efecto.", "PreferEmbeddedTitlesOverFileNames": "Preferir títulos incrustados sobre los nombres de archivo", "PreferEmbeddedTitlesOverFileNamesHelp": "Esto determina el título que se utilizará cuando un elemento no tenga etiquetas ni estas se hayan podido descargar de Internet.", "Premieres": "Estrenos", @@ -1037,7 +1037,7 @@ "Record": "Grabar", "RecordSeries": "Grabar serie", "RecordingCancelled": "Grabación cancelada.", - "RecordingPathChangeMessage": "Cambiar la carpeta de grabación no migrará las grabaciones existentes de la ubicación antigua a la nueva. Tendrá que moverlos manualmente si lo desea.", + "MessageChangeRecordingPath": "Cambiar la carpeta de grabación no migrará las grabaciones existentes de la ubicación antigua a la nueva. Tendrá que moverlos manualmente si lo desea.", "RecordingScheduled": "Grabación programada.", "Recordings": "Grabaciones", "Refresh": "Refrescar", @@ -1169,7 +1169,7 @@ "Tuesday": "Martes", "TvLibraryHelp": "Revisar la {0}guía de nombres de los programas de TV{1}.", "UninstallPluginConfirmation": "¿Esta seguro que desea desinstalar {0}?", - "UninstallPluginHeader": "Desinstalar complemento", + "HeaderUninstallPlugin": "Desinstalar complemento", "Unmute": "Activar audio", "Unrated": "Sin clasificar", "Up": "Arriba", diff --git a/src/strings/es_419.json b/src/strings/es_419.json index 2e02dd6b3d..71ae83d24f 100644 --- a/src/strings/es_419.json +++ b/src/strings/es_419.json @@ -114,7 +114,7 @@ "Unrated": "Sin clasificar", "Unplayed": "No reproducido", "Unmute": "Activar sonido", - "UninstallPluginHeader": "Desinstalar complemento", + "HeaderUninstallPlugin": "Desinstalar complemento", "UninstallPluginConfirmation": "¿Estás seguro de querer desinstalar {0}?", "Uniform": "Uniforme", "TvLibraryHelp": "Revisa la {0}guía de nombrado de series de TV{1}.", @@ -306,8 +306,8 @@ "NoSubtitlesHelp": "Los subtítulos no serán cargados por defecto. Pueden ser activados manualmente durante la reproducción.", "NoSubtitles": "Ninguno", "NoSubtitleSearchResultsFound": "No se encontraron resultados.", - "NoPluginConfigurationMessage": "Este complemento no tiene configuraciones disponibles.", - "NoNextUpItemsMessage": "No se encontró nada. ¡Comienza a ver tus programas!", + "MessageNoPluginConfiguration": "Este complemento no tiene configuraciones disponibles.", + "MessageNoNextUpItems": "No se encontró nada. ¡Comienza a ver tus programas!", "NoNewDevicesFound": "No se encontraron nuevos dispositivos. Para agregar un sintonizador nuevo, cierra este diálogo e introduce la información del dispositivo manualmente.", "NoCreatedLibraries": "Parece que no has creado ninguna biblioteca todavía. {0}¿Quisieras crear una ahora?{1}", "No": "No", @@ -580,7 +580,7 @@ "Refresh": "Actualizar", "Recordings": "Grabaciones", "RecordingScheduled": "Grabación programada.", - "RecordingPathChangeMessage": "Cambiar la carpeta de grabaciones no moverá las grabaciones existentes de la antigua ubicación a la nueva. Necesitan moverse manualmente si se desea.", + "MessageChangeRecordingPath": "Cambiar la carpeta de grabaciones no moverá las grabaciones existentes de la antigua ubicación a la nueva. Necesitan moverse manualmente si se desea.", "RecordingCancelled": "Grabación cancelada.", "RecordSeries": "Grabar series", "Record": "Grabar", @@ -604,7 +604,7 @@ "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Esto utiliza la información del episodio desde los metadatos incrustados si están disponibles.", "PreferEmbeddedTitlesOverFileNamesHelp": "Esto determina el título mostrado por defecto cuando no hay disponibles metadatos en Internet o localmente.", "PreferEmbeddedTitlesOverFileNames": "Preferir títulos incrustados a los nombres de archivo", - "PluginInstalledMessage": "El complemento ha sido instalado con éxito. El servidor Jellyfin necesitará ser reiniciado para que los cambios surtan efecto.", + "MessagePluginInstalled": "El complemento ha sido instalado con éxito. El servidor Jellyfin necesitará ser reiniciado para que los cambios surtan efecto.", "PleaseSelectTwoItems": "Por favor, selecciona al menos dos elementos.", "PleaseRestartServerName": "Por favor, reinicia el servidor Jellyfin - {0}.", "PleaseEnterNameOrId": "Por favor, introduce un nombre o ID externo.", @@ -628,7 +628,7 @@ "People": "Personas", "PasswordSaved": "Contraseña guardada.", "PasswordResetProviderHelp": "Elige un proveedor de restablecimiento de contraseña para usar cuando este usuario solicite un restablecimiento de contraseña", - "PasswordResetHeader": "Restablecer contraseña", + "HeaderResetPassword": "Restablecer contraseña", "PasswordResetConfirmation": "¿Estás seguro de querer restablecer la contraseña?", "PasswordResetComplete": "La contraseña ha sido restablecida.", "PasswordMatchError": "La contraseña y la confirmación de la contraseña deben coincidir.", @@ -1303,7 +1303,7 @@ "EveryNDays": "Cada {0} días", "ErrorSavingTvProvider": "Hubo un error al guardar el proveedor de TV. Por favor, asegúrate de que sea accesible e inténtalo de nuevo.", "ErrorPleaseSelectLineup": "Por favor, selecciona una programación e inténtalo de nuevo. Si no hay disponible ninguna, entonces, por favor, verifica que tu nombre de usuario, contraseña, y código postal sean correctos.", - "ErrorMessageStartHourGreaterThanEnd": "La hora de finalización debe ser mayor que la hora de inicio.", + "ErrorStartHourGreaterThanEnd": "La hora de finalización debe ser mayor que la hora de inicio.", "ErrorGettingTvLineups": "Hubo un error al descargar la programación de TV. Por favor, asegúrate de que tu información sea correcta e inténtalo de nuevo.", "ErrorDeletingItem": "Hubo un error eliminando el elemento del servidor Jellyfin. Por favor, verifica que el servidor Jellyfin tiene permisos de escritura en la carpeta del medio e inténtalo de nuevo.", "ErrorAddingXmlTvFile": "Hubo un error accediendo al archivo XMLTV. Por favor, asegúrate de que el archivo existe e inténtalo de nuevo.", @@ -1374,7 +1374,7 @@ "DeinterlaceMethodHelp": "Seleccione el método de desentrelazado que se usará al transcodificar contenido entrelazado.", "DefaultSubtitlesHelp": "Los subtítulos se cargan basados en los indicadores «por defecto» y «forzado» incluidos en los metadatos. Las preferencias de idioma son consideradas cuando hay múltiples opciones disponibles.", "DefaultMetadataLangaugeDescription": "Estos son sus valores por defecto y pueden ser personalizados en cada biblioteca.", - "DefaultErrorMessage": "Ha ocurrido un error al procesar la solicitud. Por favor, inténtalo de nuevo más tarde.", + "MessageDefaultError": "Ha ocurrido un error al procesar la solicitud. Por favor, inténtalo de nuevo más tarde.", "Default": "Por defecto", "DeathDateValue": "Falleció: {0}", "DatePlayed": "Fecha de reproducción", @@ -1496,7 +1496,7 @@ "ButtonAddImage": "Agregar imagen", "ButtonAdd": "Agregar", "BurnSubtitlesHelp": "Determina si el servidor debería quemar los subtítulos al transcodificar videos. Evitar esto mejorará altamente el rendimiento del servidor. Seleccione Auto para grabar formatos basados en imágenes (VOBSUB, PGS, SUB, IDX...) y ciertos subtítulos ASS o SSA.", - "BrowsePluginCatalogMessage": "Explora nuestro catálogo de complementos para ver los complementos disponibles.", + "MessageBrowsePluginCatalog": "Explora nuestro catálogo de complementos para ver los complementos disponibles.", "Browse": "Explorar", "BoxRear": "Caja (parte trasera)", "Box": "Caja", diff --git a/src/strings/fa.json b/src/strings/fa.json index 3b3cb07e00..32e083685f 100644 --- a/src/strings/fa.json +++ b/src/strings/fa.json @@ -73,7 +73,7 @@ "MessagePleaseEnsureInternetMetadata": "لطفا مطمئن شوید دانلود متاداده از اینترنت فعال است.", "MoreUsersCanBeAddedLater": "بعدا میتوانید کاربران بیشتری را در داشبورد اضافه کنید.", "NextUp": "بعدی چیه", - "NoNextUpItemsMessage": "چیزی یافت نشد. دیدن سریال ها یتان را شروع کنید!", + "MessageNoNextUpItems": "چیزی یافت نشد. دیدن سریال ها یتان را شروع کنید!", "OptionAscending": "صعودی", "OptionDescending": "نزولی", "OptionDislikes": "پسندیده نشده ها", @@ -225,7 +225,7 @@ "AddToCollection": "افزودن به مجموعه", "ExitFullscreen": "خروج از تمام صفحه", "EveryNDays": "هر {0} روز", - "ErrorMessageStartHourGreaterThanEnd": "زمان پایان باید پس از زمان شروع باشد.", + "ErrorStartHourGreaterThanEnd": "زمان پایان باید پس از زمان شروع باشد.", "Episodes": "قسمت‌ها", "EndsAtValue": "تمام شده در {0}", "Ended": "تمام شده", @@ -272,7 +272,7 @@ "DeleteDeviceConfirmation": "آیا از حذف این دستگاه اطمینان دارید؟ هنگامی که یک کاربر دوباره با آن دستگاه وارد شود، دوباره نمایش داده می‌شود.", "Delete": "حذف", "DefaultMetadataLangaugeDescription": "این موارد پیشفرض‌های شماست و می‌توانید برای هر کتابخانه آن را شخصی سازی کنید.", - "DefaultErrorMessage": "خطایی در پردازش درخواست رخ داد. لطفا اندکی بعد دوباره تلاش کنید.", + "MessageDefaultError": "خطایی در پردازش درخواست رخ داد. لطفا اندکی بعد دوباره تلاش کنید.", "Default": "پیشفرض", "DeathDateValue": "تلف شد: {0}", "DatePlayed": "تاریخ پخش شده", @@ -312,7 +312,7 @@ "ButtonShutdown": "خاموش", "ButtonSelectDirectory": "انتخاب مسیر", "ButtonEditOtherUserPreferences": "نمایه، تصویر و ترجیحات شخصی این کاربر را ویرایش کنید.", - "BrowsePluginCatalogMessage": "برای مرور کردن افزونه‌های موجود، به فروشگاه افزونه‌های ما سر بزنید.", + "MessageBrowsePluginCatalog": "برای مرور کردن افزونه‌های موجود، به فروشگاه افزونه‌های ما سر بزنید.", "AuthProviderHelp": "ارائه دهنده تأیید اعتبار را انتخاب کنید تا برای تأیید اعتبار گذرواژه این کاربر استفاده شود.", "HeaderRecordingPostProcessing": "در حال ضبط پس پردازش", "HeaderRecordingOptions": "گزینه‌های ضبط", @@ -520,7 +520,7 @@ "Unrated": "بدون امتیاز", "Unplayed": "پخش نشده", "Unmute": "صدادار", - "UninstallPluginHeader": "حذف نصب افزونه", + "HeaderUninstallPlugin": "حذف نصب افزونه", "UninstallPluginConfirmation": "آیا اطمینان دارید که می‌خواهید {0} را حذف نصب کنید؟", "Uniform": "یکپارچه", "Tuesday": "سه‌شنبه", @@ -698,7 +698,7 @@ "MessageInvalidUser": "نام کاربری یا گذرواژه نامعتبر است. لطفا دوباره تلاش کنید.", "MessageInvalidForgotPasswordPin": "کد پین نامعتبر یا منقضی شده وارد شد. لطفا دوباره تلاش کنید.", "MessageInstallPluginFromApp": "این افزونه باید از داخل برنامه‌ای که قصد استفاده از آن را دارید نصب شود.", - "PasswordResetHeader": "بازنشانی گذرواژه", + "HeaderResetPassword": "بازنشانی گذرواژه", "PasswordResetConfirmation": "آیا واقعا تمایل به بازنشانی گذرواژه دارید؟", "PasswordResetComplete": "گذرواژه بازنشانی شد.", "PasswordMatchError": "گذرواژه و تکرار گذرواژه باید یکسان باشند.", @@ -743,7 +743,7 @@ "Refresh": "به‌روز‌رسانی", "Recordings": "ضبط شده ها", "RecordingScheduled": "ضبط برنامه ریزی شد.", - "RecordingPathChangeMessage": "با تغییر محل ذخیره فایل های ضبط شده، فایل های موجود به صورت خودکار منتقل نمی شوند. در صورت نیاز، شما باید خودتان این کار را انجام دهید.", + "MessageChangeRecordingPath": "با تغییر محل ذخیره فایل های ضبط شده، فایل های موجود به صورت خودکار منتقل نمی شوند. در صورت نیاز، شما باید خودتان این کار را انجام دهید.", "RecordingCancelled": "ضبط شدن لغو شد.", "RecordSeries": "ضبط کردن سریال ها", "Record": "ضبط کردن", @@ -767,7 +767,7 @@ "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "این از اطلاعات قسمت در فراداده های تعبیه شده در صورت موجود استفاده می کند.", "PreferEmbeddedTitlesOverFileNamesHelp": "این عنوان نمایش را به صورت پیش فرض تعیین می کند، زمانی که فراداده اینترنتی یا محلی موجود نباشند.", "PreferEmbeddedTitlesOverFileNames": "عنوان های تعبیه شده را به نام فایل ترجیح بده", - "PluginInstalledMessage": "افزونه با موفقیت نصب شد. برای اعمال تغییرات سرور جلیفین نیاز به بارگذاری مجدد دارد.", + "MessagePluginInstalled": "افزونه با موفقیت نصب شد. برای اعمال تغییرات سرور جلیفین نیاز به بارگذاری مجدد دارد.", "PleaseSelectTwoItems": "لطفا حداقل دو مورد را انتخاب کنید.", "PleaseRestartServerName": "لطفا سرور جلیفین را دوباره بارگذاری کنید - {0}.", "PleaseEnterNameOrId": "لطفا یک نام یا شناسه خارجی را وارد کنید.", @@ -797,7 +797,7 @@ "LaunchWebAppOnStartup": "نمای وب هنگامی که سرور آغاز به کار می‌کند باز بشود", "NoSubtitles": "خالی", "NoSubtitleSearchResultsFound": "نتیجه‌ای یافت نشد.", - "NoPluginConfigurationMessage": "این افزونه هیچ تنظیماتی برای پیکربندی ندارد.", + "MessageNoPluginConfiguration": "این افزونه هیچ تنظیماتی برای پیکربندی ندارد.", "No": "خیر", "Next": "بعدی", "News": "اخبار", diff --git a/src/strings/fi.json b/src/strings/fi.json index 657f1a4c32..147d501f46 100644 --- a/src/strings/fi.json +++ b/src/strings/fi.json @@ -1,5 +1,5 @@ { - "BrowsePluginCatalogMessage": "Selaa lisäosakuvastoamme katsoaksesi saatavilla olevia lisäosia.", + "MessageBrowsePluginCatalog": "Selaa lisäosakuvastoamme katsoaksesi saatavilla olevia lisäosia.", "ButtonAddUser": "Lisää Käyttäjä", "ButtonCancel": "Peruuta", "ButtonDeleteImage": "Poista Kuva", @@ -47,7 +47,7 @@ "TellUsAboutYourself": "Kerro meille itsestäsi", "ThisWizardWillGuideYou": "Tämä työkalu auttaa sinua asennusprosessin aikana. Valitse kieli aloittaaksesi.", "UninstallPluginConfirmation": "Oletko varma, että haluat poistaa {0}?", - "UninstallPluginHeader": "Poista Lisäosa", + "HeaderUninstallPlugin": "Poista Lisäosa", "Absolute": "Ehdoton", "Actor": "Näyttelijä", "Add": "Lisää", @@ -201,7 +201,7 @@ "DateAdded": "Lisäyspäivämäärä", "DatePlayed": "Toistopäivämäärä", "Default": "Oletus", - "DefaultErrorMessage": "Pyynnön käsittelyssä tapahtui virhe. Yritä myöhemmin uudelleen.", + "MessageDefaultError": "Pyynnön käsittelyssä tapahtui virhe. Yritä myöhemmin uudelleen.", "DefaultMetadataLangaugeDescription": "Nämä ovat sinun oletuksetasetukset ja niitä voidaan muokata kirjastokohtaisesti.", "DefaultSubtitlesHelp": "Tekstitykset ladataan pakotettu- ja oletusmäärityksien upotetun metadatan mukaan. Kieliasetukset otetaan huomioon, kun on enemmän kuin yksi tekstitys josta valita.", "DeleteDeviceConfirmation": "Oletko varma, että haluat positaa tämän laitteen? Se ilmaantuu uudelleen seuraavan kerran, kun jokin käyttäjä kirjautuu sillä.", @@ -303,7 +303,7 @@ "Play": "Toista", "PinCodeResetConfirmation": "Haluatko varmasti nollata PIN-koodin?", "People": "Ihmiset", - "PasswordResetHeader": "Nollaa salasana", + "HeaderResetPassword": "Nollaa salasana", "OriginalAirDateValue": "Alkuperäinen esityspäivä: {0}", "OptionWeekly": "Viikottainen", "OptionWeekends": "Viikonloput", @@ -831,7 +831,7 @@ "OnApplicationStartup": "Käynnistyksen yhteydessä", "NumLocationsValue": "{0} kansiota", "NoSubtitleSearchResultsFound": "Ei tuloksia.", - "NoPluginConfigurationMessage": "Tällä liitännäisellä ei ole asetuksia muokattavaksi.", + "MessageNoPluginConfiguration": "Tällä liitännäisellä ei ole asetuksia muokattavaksi.", "NoCreatedLibraries": "Vaikuttaa siltä, ettet ole luonut vielä yhtään kirjastoa. {0} Haluaisitko luoda sellaisen nyt?{1}", "No": "Ei", "NextUp": "Seuraavana", @@ -1216,7 +1216,7 @@ "FolderTypeUnset": "Sekalainen sisältö", "FetchingData": "Noudetaan lisätietoja", "Features": "Ominaisuudet", - "ErrorMessageStartHourGreaterThanEnd": "Loppumisajan on oltava myöhemmin kuin aloitusaika.", + "ErrorStartHourGreaterThanEnd": "Loppumisajan on oltava myöhemmin kuin aloitusaika.", "MediaInfoAnamorphic": "Anamorfinen", "ErrorGettingTvLineups": "TV esiintyjälistan lataamisessa tapahtui virhe. Varmista, että tiedot on oikein ja yritä uudelleen.", "EnableDetailsBannerHelp": "Näyttää julistekuvan yksityiskohdat -sivun ylälaidassa.", diff --git a/src/strings/fr-ca.json b/src/strings/fr-ca.json index 00bc7320cd..2e3b99b946 100644 --- a/src/strings/fr-ca.json +++ b/src/strings/fr-ca.json @@ -138,7 +138,7 @@ "Box": "Boîtier", "BoxRear": "Dos de boîtier", "Browse": "Parcourir", - "BrowsePluginCatalogMessage": "Explorer notre catalogue des plugins pour voir les plugins disponibles.", + "MessageBrowsePluginCatalog": "Explorer notre catalogue des plugins pour voir les plugins disponibles.", "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.", "ButtonAdd": "Ajouter", diff --git a/src/strings/fr.json b/src/strings/fr.json index 6d56752211..c5ef0d5615 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -49,7 +49,7 @@ "Box": "Boîtier", "BoxRear": "Dos de boîtier", "Browse": "Parcourir", - "BrowsePluginCatalogMessage": "Explorer notre catalogue des plugins pour voir les plugins disponibles.", + "MessageBrowsePluginCatalog": "Explorer notre catalogue des plugins pour voir les plugins disponibles.", "BurnSubtitlesHelp": "Détermine si le serveur doit incruster les sous-titres lors du transcodage de la vidéo. Les performances seront grandement améliorées sans incrustation. Sélectionnez Auto pour incruster par image les formats (VOBSUB, PGS, SUB, IDX etc) et certains sous-titres ASS ou SSA.", "ButtonAdd": "Ajouter", "ButtonAddMediaLibrary": "Ajouter une médiathèque", @@ -155,7 +155,7 @@ "DatePlayed": "Date de lecture", "DeathDateValue": "Décédé(e) le {0}", "Default": "Par défaut", - "DefaultErrorMessage": "Il y a eu une erreur lors de l'exécution de la requête. Veuillez réessayer plus tard.", + "MessageDefaultError": "Il y a eu une erreur lors de l'exécution de la requête. Veuillez réessayer plus tard.", "DefaultMetadataLangaugeDescription": "Ce sont vos réglages par défaut. Ils peuvent être personnalisés pour chaque médiathèque.", "DefaultSubtitlesHelp": "Les sous-titres seront chargés selon les marqueurs par défaut et forcé dans les métadonnées intégrées. Les langues préférées seront utilisées quand plusieurs options seront disponibles.", "Delete": "Supprimer", @@ -224,7 +224,7 @@ "ErrorAddingXmlTvFile": "Une erreur est survenue lors de l'accès au fichier XMLTV. Assurez-vous que le fichier existe et réessayez.", "ErrorDeletingItem": "Une erreur s'est produite lors de la suppression de l'élément du serveur Jellyfin. Vérifiez que le serveur Jellyfin a un accès en écriture au dossier multimédia et réessayez.", "ErrorGettingTvLineups": "Une erreur est survenue pendant le téléchargement des programmes TV. Assurez-vous que vos informations sont correctes et réessayez.", - "ErrorMessageStartHourGreaterThanEnd": "La date de fin doit être postérieure à la date de début.", + "ErrorStartHourGreaterThanEnd": "La date de fin doit être postérieure à la date de début.", "ErrorPleaseSelectLineup": "Veuillez sélectionner une programmation et réessayer. Si aucune programmation n'est disponible, veuillez vérifier que vos identifiant, mot de passe et code postal sont corrects.", "ErrorSavingTvProvider": "Une erreur est survenue lors de la sauvegarde du fournisseur TV. Assurez-vous qu'il est accessible et réessayez.", "EveryNDays": "Tous les {0} jours", @@ -932,8 +932,8 @@ "NextUp": "A Suivre", "No": "Non", "NoNewDevicesFound": "Aucun nouvel appareil détecté. Pour en ajouter un, fermez cette fenêtre et saisissez les informations de l'appareil manuellement.", - "NoNextUpItemsMessage": "Aucun élément trouvé. Commencez à regarder vos émissions !", - "NoPluginConfigurationMessage": "Cette extension n'a aucun paramètre à configurer.", + "MessageNoNextUpItems": "Aucun élément trouvé. Commencez à regarder vos émissions !", + "MessageNoPluginConfiguration": "Cette extension n'a aucun paramètre à configurer.", "NoSubtitleSearchResultsFound": "Aucun résultat trouvé.", "NoSubtitles": "Pas de sous-titres", "NoSubtitlesHelp": "Les sous-titres ne seront pas chargés par défaut. Ils peuvent toujours être activés manuellement pendant la lecture.", @@ -1082,7 +1082,7 @@ "PasswordMatchError": "Le mot de passe et sa confirmation doivent correspondre.", "PasswordResetComplete": "Le mot de passe a été réinitialisé.", "PasswordResetConfirmation": "Êtes-vous sûr de vouloir réinitialiser le mot de passe ?", - "PasswordResetHeader": "Réinitialiser le mot de passe", + "HeaderResetPassword": "Réinitialiser le mot de passe", "PasswordSaved": "Mot de passe sauvegardé.", "People": "Personnes", "PerfectMatch": "Correspondance parfaite", @@ -1103,7 +1103,7 @@ "PleaseEnterNameOrId": "Veuillez saisir un nom ou un identifiant externe.", "PleaseRestartServerName": "Veuillez redémarrer le serveur Jellyfin - {0}.", "PleaseSelectTwoItems": "Veuillez sélectionner au moins deux éléments.", - "PluginInstalledMessage": "Cette extension a été installée avec succès. Le serveur Jellyfin doit être redémarré afin que les modifications soient prises en compte.", + "MessagePluginInstalled": "Cette extension a été installée avec succès. Le serveur Jellyfin doit être redémarré afin que les modifications soient prises en compte.", "PreferEmbeddedTitlesOverFileNames": "Préférer les titres intégrés aux médias aux noms des fichiers", "PreferEmbeddedTitlesOverFileNamesHelp": "Cela détermine le titre affiché par défaut quand il n'y a pas de métadonnées en ligne ou locales disponibles.", "Premieres": "Inédits", @@ -1124,7 +1124,7 @@ "Record": "Enregistrer", "RecordSeries": "Enregistrer la série", "RecordingCancelled": "Enregistrement annulé.", - "RecordingPathChangeMessage": "Modifier votre dossier d'enregistrement ne déplacera pas les enregistrements existants de l'ancien emplacement vers le nouveau. Vous devrez les déplacer manuellement si vous le souhaitez.", + "MessageChangeRecordingPath": "Modifier votre dossier d'enregistrement ne déplacera pas les enregistrements existants de l'ancien emplacement vers le nouveau. Vous devrez les déplacer manuellement si vous le souhaitez.", "RecordingScheduled": "Enregistrement planifié.", "Recordings": "Enregistrements", "Refresh": "Actualiser", @@ -1265,7 +1265,7 @@ "TvLibraryHelp": "Consultez le {0}guide de nommage des émissions{1}.", "Uniform": "Uniforme", "UninstallPluginConfirmation": "Êtes-vous sûr de vouloir désinstaller {0} ?", - "UninstallPluginHeader": "Désinstaller Plug-in", + "HeaderUninstallPlugin": "Désinstaller Plug-in", "Unmute": "Rétablir le son", "Unplayed": "Non lu", "Unrated": "Non noté", diff --git a/src/strings/gsw.json b/src/strings/gsw.json index dad75ae57d..231cb131e5 100644 --- a/src/strings/gsw.json +++ b/src/strings/gsw.json @@ -58,7 +58,7 @@ "Monday": "Mäntig", "MoreUsersCanBeAddedLater": "Meh User chönt spöter im Dashboard hinzuegfüegt werde.", "NewCollectionNameExample": "Biispell: Star Wars Sammlig", - "NoNextUpItemsMessage": "Nix da. Fang mal a Serie luege!", + "MessageNoNextUpItems": "Nix da. Fang mal a Serie luege!", "OptionAlbumArtist": "Album-Artist", "OptionAscending": "Ufstiigend", "OptionBluray": "BluRay", diff --git a/src/strings/he.json b/src/strings/he.json index 4288b04762..7624080423 100644 --- a/src/strings/he.json +++ b/src/strings/he.json @@ -15,7 +15,7 @@ "AttributeNew": "חדש", "Backdrops": "תמונות רקע", "BirthLocation": "מיקום לידה", - "BrowsePluginCatalogMessage": "עבור לקטלוג התוספים לראות אילו זמינים.", + "MessageBrowsePluginCatalog": "עבור לקטלוג התוספים לראות אילו זמינים.", "ButtonAdd": "הוסף", "ButtonAddUser": "הוסף משתמש", "ButtonCancel": "בטל", @@ -53,7 +53,7 @@ "ConfirmDeletion": "אשר מחיקה", "Continuing": "ממשיך", "CustomDlnaProfilesHelp": "צור פרופיל מותאם אישית למכשיר חדש או לעקיפת פרופיל מערכת.", - "DefaultErrorMessage": "אירעה שגיאה בעיבוד הבקשה. בבקשה נסה שוב מאוחר יותר.", + "MessageDefaultError": "אירעה שגיאה בעיבוד הבקשה. בבקשה נסה שוב מאוחר יותר.", "Delete": "מחק", "DeleteImage": "מחק תמונה", "DeleteImageConfirmation": "האם אתה בטוח שברצונך למחוק תמונה זו?", @@ -298,7 +298,7 @@ "NewEpisodes": "פרקים חדשים", "NewEpisodesOnly": "פרקים חדשים בלבד", "News": "חדשות", - "NoNextUpItemsMessage": "לא נמצא כלום. התחלת לצפות בסדרות שלך!", + "MessageNoNextUpItems": "לא נמצא כלום. התחלת לצפות בסדרות שלך!", "NoSubtitleSearchResultsFound": "לא נמצאו תוצאות.", "Option3D": "תלת מימד", "OptionAdminUsers": "מנהלים", @@ -484,7 +484,7 @@ "TrackCount": "שירים {0}", "Tuesday": "שלישי", "UninstallPluginConfirmation": "האם אתה בטוח שברצונך להסיר {0}?", - "UninstallPluginHeader": "הסר תוסף", + "HeaderUninstallPlugin": "הסר תוסף", "Unrated": "אין דירוג", "ValueAlbumCount": "{0} אלבומים", "ValueDiscNumber": "דיסק {0}", @@ -675,7 +675,7 @@ "ExtraLarge": "גדול מאוד", "ExitFullscreen": "צא ממסך מלא", "EveryNDays": "כל {0} ימים", - "ErrorMessageStartHourGreaterThanEnd": "שעת הסיום חייבת להיות לאחר שעת ההתחלה.", + "ErrorStartHourGreaterThanEnd": "שעת הסיום חייבת להיות לאחר שעת ההתחלה.", "Episodes": "פרקים", "EnableThemeSongsHelp": "נגן שירי פתיח ברגע בעת העיון בספרייה.", "ThemeSongs": "שירי פתיח", diff --git a/src/strings/hi-in.json b/src/strings/hi-in.json index 48b82c601f..7e9bb01563 100644 --- a/src/strings/hi-in.json +++ b/src/strings/hi-in.json @@ -114,7 +114,7 @@ "Album": "एल्बम", "AddItemToCollectionHelp": "उनके लिए खोज करके संग्रह में आइटम जोड़ें और उन्हें संग्रह में जोड़ने के लिए उनके राइट-क्लिक या टैप मेनू का उपयोग करें।", "ButtonSyncPlay": "SyncPlay", - "BrowsePluginCatalogMessage": "उपलब्ध प्लगिन्स देखने के लिए हमारे कैटलॉग को ब्राउज़ करें।", + "MessageBrowsePluginCatalog": "उपलब्ध प्लगिन्स देखने के लिए हमारे कैटलॉग को ब्राउज़ करें।", "Browse": "ब्राउज़", "BoxSet": "बॉक्स सेट", "BurnSubtitlesHelp": "निर्धारित करता है कि वीडियो ट्रांसकोडिंग करते समय सर्वर को उपशीर्षक बर्न-इन करना चाहिए। इससे बचने से प्रदर्शन में बहुत सुधार होगा। छवि आधारित उपशीर्षक (VOBSUB, PGS, SUB, IDX, …) एवं ASS अथवा SSA जैसे उपशीर्षक बर्न-इन करने के लिए ऑटो का चयन करें।" diff --git a/src/strings/hr.json b/src/strings/hr.json index db5c5499d2..50e8f7ffaa 100644 --- a/src/strings/hr.json +++ b/src/strings/hr.json @@ -16,7 +16,7 @@ "BirthDateValue": "Rođen: {0}", "BirthLocation": "Lokacija rođenja", "BirthPlaceValue": "Mjesto rođenja: {0}", - "BrowsePluginCatalogMessage": "Pregledajte dostupne dodatke u našem katalogu.", + "MessageBrowsePluginCatalog": "Pregledajte dostupne dodatke u našem katalogu.", "ButtonAdd": "Dodaj", "ButtonAddMediaLibrary": "Dodaj medijsku bibilioteku", "ButtonAddScheduledTaskTrigger": "Dodaj okidač", @@ -106,7 +106,7 @@ "Continuing": "Nastavlja se", "CustomDlnaProfilesHelp": "Kreiraj prilagođeni profili za novi uređaj ili doradi neki od sistemskih profila.", "DeathDateValue": "Umro: {0}", - "DefaultErrorMessage": "Došlo je do pogreške prilikom obrade zahtjeva. Molimo pokušajte ponovo kasnije.", + "MessageDefaultError": "Došlo je do pogreške prilikom obrade zahtjeva. Molimo pokušajte ponovo kasnije.", "Delete": "Izbriši", "DeleteDeviceConfirmation": "Jeste li sigurni da želite izbrisati ovaj uređaj? Pojavit će se sljedeći put kad se korisnik prijavi s njim.", "DeleteImage": "Izbriši sliku", @@ -133,7 +133,7 @@ "ErrorAddingMediaPathToVirtualFolder": "Došlo je do pogreške prilikom dodavanja putanje medija. Provjerite dali je putanja valjana i da proces Jellyfin Server-a ima pristup tom mjestu.", "ErrorAddingTunerDevice": "Došlo je do pogreške prilikom dodavanja uređaja TV/radio pretraživača. Provjerite da je dostupan i pokušajte ponovno.", "ErrorGettingTvLineups": "Došlo je do pogreške prilikom preuzimanja TV postave. Provjerite dali su vaše informacije točne i pokušajte ponovno.", - "ErrorMessageStartHourGreaterThanEnd": "Vrijeme završetka mora biti veće od početka.", + "ErrorStartHourGreaterThanEnd": "Vrijeme završetka mora biti veće od početka.", "ErrorPleaseSelectLineup": "Odaberite postavu i pokušajte ponovno. Ako niti jedna postava nije dostupna provjerite dali su korisničko ime, lozinka i poštanski broj točni.", "ErrorSavingTvProvider": "Došlo je do pogreške prilikom snimanja TV pružatelja. Provjerite da je dostupan i pokušajte ponovno.", "ExtractChapterImagesHelp": "Izdvajanje slika poglavlja omogućiti će klijentima prikaz grafičkih izbornika za odabir scena. Proces može biti spor, resursi intenzivno korišteni i može zahtijevati nekoliko gigabajta prostora. Ono se pokreće kad je otkriven video, a također i kao noćni zadatak. Raspored je podesiv u području rasporeda zadataka. Ne preporučuje se za pokretanje ovog zadatka tijekom sati čestog korištenja.", @@ -692,8 +692,8 @@ "NewEpisodes": "Nove epizode", "NewEpisodesOnly": "Samo nove epizode", "News": "Vijesti", - "NoNextUpItemsMessage": "Nije pronađeno. Krenite sa gledanjem vaše emisije!", - "NoPluginConfigurationMessage": "Ovaj dodatak nema postavke za podesiti.", + "MessageNoNextUpItems": "Nije pronađeno. Krenite sa gledanjem vaše emisije!", + "MessageNoPluginConfiguration": "Ovaj dodatak nema postavke za podesiti.", "NoSubtitleSearchResultsFound": "Nije ništa pronađeno.", "NumLocationsValue": "{0} mape", "OptionAdminUsers": "Administratori", @@ -828,7 +828,7 @@ "PasswordMatchError": "Lozinka i lozinka potvrde moraju biti identične.", "PasswordResetComplete": "Lozinka je resetirana.", "PasswordResetConfirmation": "Da li ste sigurni da želite resetirati lozinku?", - "PasswordResetHeader": "Poništi lozinku", + "HeaderResetPassword": "Poništi lozinku", "PasswordSaved": "Lozinka snimljena.", "People": "Ljudi", "PinCodeResetComplete": "PIN je resetiran.", @@ -855,7 +855,7 @@ "Record": "Snimi", "RecordSeries": "Snimi serije", "RecordingCancelled": "Snimka je otkazana.", - "RecordingPathChangeMessage": "Promjena mape za snimanje neće migrirati postojeće snimke iz stare lokacije na novu. Morat ćete ih pomicati ručno, ako to želite.", + "MessageChangeRecordingPath": "Promjena mape za snimanje neće migrirati postojeće snimke iz stare lokacije na novu. Morat ćete ih pomicati ručno, ako to želite.", "RecordingScheduled": "Snimka je zakazana.", "Refresh": "Osviježi", "RefreshDialogHelp": "Meta-podaci se osvježavaju na temelju postavki i internet usluga koje su omogućene u nadzornoj ploči Jellyfin Server-a.", @@ -963,7 +963,7 @@ "TrackCount": "{0} pjesme", "Tuesday": "Utorak", "UninstallPluginConfirmation": "Da li ste sigurni da želite ukloniti {0}?", - "UninstallPluginHeader": "Ukloni dodatak", + "HeaderUninstallPlugin": "Ukloni dodatak", "Unrated": "Neocijenjeno", "UserProfilesIntro": "Jellyfin uključuje ugrađenu podršku za korisničke profile što omogućuje svakom korisniku da ima svoje vlastite postavke prikaza, PlayStation i roditeljski nadzor.", "ValueAlbumCount": "{0} albuma", diff --git a/src/strings/hu.json b/src/strings/hu.json index ddf4cd9fe9..8dd52462aa 100644 --- a/src/strings/hu.json +++ b/src/strings/hu.json @@ -554,7 +554,7 @@ "TitlePlayback": "Lejátszás", "Tuesday": "Kedd", "UninstallPluginConfirmation": "Biztosan el szeretnéd távolítani a következőt: {0} ?", - "UninstallPluginHeader": "Bővítmény Eltávolítása", + "HeaderUninstallPlugin": "Bővítmény Eltávolítása", "Unmute": "Hangosít", "Up": "Fel", "ValueAudioCodec": "Audió Kódek: {0}", @@ -604,7 +604,7 @@ "Artists": "Előadók", "Blacklist": "Feketelista", "BookLibraryHelp": "Lehetőség van audió és hangoskönyvek visszajátszására. Nézd meg a {0} könyvelnevezési útmutatót {1}.", - "BrowsePluginCatalogMessage": "Böngéssz a Bővítmény katalógusunkban a rendelkezésre álló bővítmények megtekintéséhez.", + "MessageBrowsePluginCatalog": "Böngéssz a Bővítmény katalógusunkban a rendelkezésre álló bővítmények megtekintéséhez.", "AddItemToCollectionHelp": "Adj elemeket a gyűjteményekhez, ehhez keresed meg őket, majd kattints jobb egérgombbal, vagy kattints a menüre és add hozzá a gyűjteményhez.", "AllowedRemoteAddressesHelp": "Vesszővel válaszd el az IP-címek vagy IP / netmask címek listáját annak a hálózatnak amelyből távolról csatlakozhatnak. Ha üresen marad, az összes távoli cím megengedett.", "BoxRear": "Box (hátsó)", @@ -645,7 +645,7 @@ "CustomDlnaProfilesHelp": "Hozz létre egyéni profilt az új eszközhöz, vagy módosítsd a rendszerprofilt.", "DeathDateValue": "Elhunyt: {0}", "Default": "Alapértelmezett", - "DefaultErrorMessage": "Hiba történt a kérés feldolgozása során. Kérlek próbáld újra később.", + "MessageDefaultError": "Hiba történt a kérés feldolgozása során. Kérlek próbáld újra később.", "DefaultMetadataLangaugeDescription": "Ezek az alapértelmezettek, és könyvtáranként testre szabhatók.", "DeleteDeviceConfirmation": "Biztosan törölni szeretnéd ezt az eszközt? Legközelebb akkor jelenik meg, amikor a felhasználó bejelentkezik róla.", "DeleteImage": "Kép törlése", @@ -682,7 +682,7 @@ "ErrorAddingTunerDevice": "Hiba történt a tuner eszköz hozzáadásakor. Kérlek győződj meg róla, hogy az eszköz elérhető és próbáld meg újra.", "ErrorAddingXmlTvFile": "Hiba történt az XMLTV fájl elérésekor. Győződj meg róla, hogy a fájl létezik és próbáld meg újra.", "ErrorDeletingItem": "Hiba történt az elem törlése során a Jellyfin Szerverről. Ellenőrizd, hogy a Jellyfin Szerver rendelkezik-e írási jogosultsággal a média mappához és próbálja újra.", - "ErrorMessageStartHourGreaterThanEnd": "A befejezési időnek nagyobbnak kell lennie mint a kezdési idő.", + "ErrorStartHourGreaterThanEnd": "A befejezési időnek nagyobbnak kell lennie mint a kezdési idő.", "ErrorSavingTvProvider": "Hiba történt a TV szolgáltató mentésekor. Kérlek győződj meg róla, hogy elérhető és próbálkozz meg újra.", "EveryNDays": "Minden {0} nap", "ExtraLarge": "Extra NAGY", @@ -1069,8 +1069,8 @@ "NextUp": "Következik", "No": "Nem", "NoNewDevicesFound": "Nem található új eszköz. Új tuner hozzáadásához zárd be ezt a párbeszédablakot és add meg kézzel az eszköz adatait.", - "NoNextUpItemsMessage": "Nem található. Kezdj el nézni műsorokat!", - "NoPluginConfigurationMessage": "Ez a bővítmény nem rendelkezik konfigurációs beállításokkal.", + "MessageNoNextUpItems": "Nem található. Kezdj el nézni műsorokat!", + "MessageNoPluginConfiguration": "Ez a bővítmény nem rendelkezik konfigurációs beállításokkal.", "NoSubtitles": "Nincs", "NoSubtitlesHelp": "A feliratok alapértelmezés szerint nem lesznek betöltve. Lejátszás közben kézzel is bekapcsolhatók.", "Off": "Ki", @@ -1154,7 +1154,7 @@ "PasswordMatchError": "A jelszónak és a jelszó megerősítésének meg kell egyeznie.", "PasswordResetComplete": "A jelszó visszaállítva.", "PasswordResetConfirmation": "Biztosan vissza szeretnéd állítani a jelszót?", - "PasswordResetHeader": "Jelszó visszaállítása", + "HeaderResetPassword": "Jelszó visszaállítása", "PasswordSaved": "Jelszó mentve.", "PerfectMatch": "Tökéletes párosítás", "PictureInPicture": "Kép a képen", @@ -1167,7 +1167,7 @@ "PleaseConfirmPluginInstallation": "Kérlek kattints az OK gombra, hogy megerősítsd, hogy elolvastad a fentieket és folytatni kívánod a bővítmény telepítését.", "PleaseEnterNameOrId": "Kérlek adj meg egy nevet vagy egy külső ID-t.", "PleaseSelectTwoItems": "Kérlek válassz legalább két elemet.", - "PluginInstalledMessage": "A bővítmény sikeresen telepítve lett. A módosítások életbelépéséhez újra kell indítani a Jellyfin Szerver programot.", + "MessagePluginInstalled": "A bővítmény sikeresen telepítve lett. A módosítások életbelépéséhez újra kell indítani a Jellyfin Szerver programot.", "PreferEmbeddedTitlesOverFileNames": "A fájlnevek helyett előnyben részesíti a beépített címeket", "PreferEmbeddedTitlesOverFileNamesHelp": "Ez határozza meg az alapértelmezett megjelenítési címet, ha nem áll rendelkezésre internetes metaadat vagy helyi metaadat.", "Premiere": "Premier", @@ -1182,7 +1182,7 @@ "RecentlyWatched": "Nemrég nézett", "RecordSeries": "Sorozatok rögzítése", "RecordingCancelled": "Felvétel törölve.", - "RecordingPathChangeMessage": "A felvételi mappa módosítása nem fogja áthelyezni a meglévő felvételeket a régi helyről az újra. Szükség esetén manuálisan kell mozgatni őket.", + "MessageChangeRecordingPath": "A felvételi mappa módosítása nem fogja áthelyezni a meglévő felvételeket a régi helyről az újra. Szükség esetén manuálisan kell mozgatni őket.", "RecordingScheduled": "A rögzítés ütemezett.", "Recordings": "Felvételek", "RefreshQueued": "Frissítés sorba állítva.", diff --git a/src/strings/id.json b/src/strings/id.json index 9d347b7dcc..71641a435a 100644 --- a/src/strings/id.json +++ b/src/strings/id.json @@ -56,7 +56,7 @@ "Actor": "Aktor", "Delete": "Hapus", "DefaultMetadataLangaugeDescription": "Berikut ini adalah standar Anda dan dapat dikustomisasi pada tiap pustakanya.", - "DefaultErrorMessage": "Terdapat galat dalam memproses permintaan. Silakan coba kembali nanti.", + "MessageDefaultError": "Terdapat galat dalam memproses permintaan. Silakan coba kembali nanti.", "Default": "Standar", "DeathDateValue": "Meninggal: {0}", "DatePlayed": "Tanggal dimainkan", @@ -150,7 +150,7 @@ "ButtonAddMediaLibrary": "Tambah Pustaka Media", "ButtonAddImage": "Tamba gambar", "ButtonAdd": "Tambah", - "BrowsePluginCatalogMessage": "Jelajahi katalog plugin kamu untuk melihat plugin yang tersedia.", + "MessageBrowsePluginCatalog": "Jelajahi katalog plugin kamu untuk melihat plugin yang tersedia.", "Browse": "Jelajah", "BoxRear": "Kotak (belakang)", "Box": "Kotak", diff --git a/src/strings/is-is.json b/src/strings/is-is.json index fac582bad4..21dfe6a472 100644 --- a/src/strings/is-is.json +++ b/src/strings/is-is.json @@ -53,7 +53,7 @@ "Add": "Bæta við", "AddToCollection": "Bæta í safn", "AutoBasedOnLanguageSetting": "Sjálfkrafa (byggt á tungumálastillingum)", - "BrowsePluginCatalogMessage": "Skoða viðbætur sem eru í boði í viðbóta safninu okkar.", + "MessageBrowsePluginCatalog": "Skoða viðbætur sem eru í boði í viðbóta safninu okkar.", "BurnSubtitlesHelp": "Ákveður hvort þjónninn eigi að brenna textann inn í myndaskránna þegar verið er að umbreyta skrársniðinu. Með því að forðast að brenna inn textann er hægt að minnka álag á þjóninn (tölvuna). Veljið sjálfkrafa til þess að brenna texta byggðan á myndum (VOBSUB, PGS, SUB/IDX, ofl) og ákveðna ASS/SSA texta.", "OptionSaveMetadataAsHidden": "Geyma gagnagögn (metadata) og myndir sem leynilegar skrár", "PasswordMatchError": "Lykilorð og ítrekun lykilorðs þarf að passa.", @@ -145,7 +145,7 @@ "Overview": "Yfirlit", "PackageInstallCompleted": "{0} lokið við uppsetningu.", "PasswordResetComplete": "Lykilorðið hefur verið endurstillt.", - "PasswordResetHeader": "Endurstilla lykilorð", + "HeaderResetPassword": "Endurstilla lykilorð", "PasswordResetProviderHelp": "Veldu þjónustu til þess að endurstilla lykilorð þegar notandi biður um það", "PictureInPicture": "Brot úr ramma", "PinCodeResetComplete": "Pinnið þitt hefur verið endursett.", @@ -380,7 +380,7 @@ "DirectStreamHelp2": "Beint streymi á skrá notar mjög litið vinnsluafl án þess að tapa myndgæðum.", "Descending": "Niður", "DeleteImageConfirmation": "Ertu viss um að þú viljir eyða þessari mynd?", - "DefaultErrorMessage": "Villa varð við vinnslu beiðninnar. Reyndu aftur síðar.", + "MessageDefaultError": "Villa varð við vinnslu beiðninnar. Reyndu aftur síðar.", "DeathDateValue": "Dó: {0}", "DatePlayed": "Dagsetning spilað", "DateAdded": "Dagsetning bætt við", @@ -433,7 +433,7 @@ "ValueOneEpisode": "1 þáttur", "Up": "Upp", "Unplayed": "Óspilað", - "UninstallPluginHeader": "Fjarlægja Viðbót", + "HeaderUninstallPlugin": "Fjarlægja Viðbót", "Tuesday": "Þriðjudagur", "Transcoding": "Umkóðun", "Trailers": "Sýnishorn", diff --git a/src/strings/it.json b/src/strings/it.json index 76d3971fa9..437e9d2ffc 100644 --- a/src/strings/it.json +++ b/src/strings/it.json @@ -44,7 +44,7 @@ "Books": "Libri", "BoxRear": "Box (retro)", "Browse": "Esplora", - "BrowsePluginCatalogMessage": "Sfoglia il catalogo dei Plugins.", + "MessageBrowsePluginCatalog": "Sfoglia il catalogo dei Plugins.", "BurnSubtitlesHelp": "Determina se il server deve imprimere i sottotitoli quando i video vengono convertiti. Evitare ciò migliorerà di molto le prestazioni. Selezionare Auto per imprimere formati basati sull'immagine (VOBSUB, PGS, SUB, IDX, ...) e alcuni sottotitoli ASS o SSA.", "ButtonAdd": "Aggiungi", "ButtonAddMediaLibrary": "Aggiungi raccolta multimediale", @@ -145,7 +145,7 @@ "DatePlayed": "Visto il", "DeathDateValue": "Morto: {0}", "Default": "Predefinito", - "DefaultErrorMessage": "Si è verificato un errore durante l'elaborazione della richiesta. Si prega di riprovare più tardi.", + "MessageDefaultError": "Si è verificato un errore durante l'elaborazione della richiesta. Si prega di riprovare più tardi.", "DefaultMetadataLangaugeDescription": "Queste sono le tue impostazioni predefinite e possono essere personalizzate per ogni libreria.", "DefaultSubtitlesHelp": "I sottotitoli vengono letti in base agli attributi predefiniti e forzati dai metadati integrati. Le preferenze di lingua sono prese in considerazione quando sono disponibili più opzioni.", "Delete": "Elimina", @@ -213,7 +213,7 @@ "ErrorAddingXmlTvFile": "Si è verificato un errore durante l'accesso al file XMLTV. Si prega di assicurarsi che il file esista e riprovare.", "ErrorDeletingItem": "Si è verificato un errore durante l'eliminazione dell'elemento da Jellyfin Server. Verifica che Jellyfin Server abbia accesso in scrittura sulla cartella multimediale e riprova.", "ErrorGettingTvLineups": "Si è verificato un errore durante il download delle formazioni TV. Assicurarsi che le vostre informazioni siano corrette e riprovare.", - "ErrorMessageStartHourGreaterThanEnd": "Il tempo della fine deve essere maggiore del tempo di avvio.", + "ErrorStartHourGreaterThanEnd": "Il tempo della fine deve essere maggiore del tempo di avvio.", "ErrorPleaseSelectLineup": "Si prega di selezionare una scaletta e riprovare. Se non ci sono formazioni disponibili, si prega allora di verificare che il vostro nome utente, password, e il codice postale siano corretti.", "ErrorSavingTvProvider": "Si è verificato un errore durante il salvataggio del fornitore di TV. Si prega di assicurarsi che sia accessibile e riprovare.", "EveryNDays": "Ogni {0} giorni", @@ -893,8 +893,8 @@ "News": "Notizie", "Next": "Prossimo", "NoNewDevicesFound": "Non sono stati trovati nuovi dispositivi. Per aggiungere un nuovo sintonizzatore, chiudere questa finestra di dialogo e immettere manualmente le informazioni sul dispositivo.", - "NoNextUpItemsMessage": "Trovato niente. Inizia a guardare i tuoi programmi!", - "NoPluginConfigurationMessage": "Questo Plugin non ha impostazioni da configurare.", + "MessageNoNextUpItems": "Trovato niente. Inizia a guardare i tuoi programmi!", + "MessageNoPluginConfiguration": "Questo Plugin non ha impostazioni da configurare.", "NoSubtitleSearchResultsFound": "Nessun risultato.", "NoSubtitles": "Nessuno", "NoSubtitlesHelp": "I sottotitoli non verranno caricati per impostazione predefinita.Possono essere ancora caricati manualmente durante la riproduzione.", @@ -1037,7 +1037,7 @@ "PasswordMatchError": "Le password non coincidono.", "PasswordResetComplete": "Reset della password eseguito.", "PasswordResetConfirmation": "Sicuro di voler eseguire il reset della password?", - "PasswordResetHeader": "Reset Password", + "HeaderResetPassword": "Reset Password", "PasswordSaved": "Password salvata.", "People": "Attori", "PerfectMatch": "Corrispondenza perfetta", @@ -1058,7 +1058,7 @@ "PleaseEnterNameOrId": "Per favore inserisci un nome o un ID esterno.", "PleaseRestartServerName": "Per favore riavvia Jellyfin Server - {0}.", "PleaseSelectTwoItems": "Seleziona almeno due elementi.", - "PluginInstalledMessage": "Il plugin è stato installato correttamente. Il server Jellyfin dovrà essere riavviato affinché le modifiche abbiano effetto.", + "MessagePluginInstalled": "Il plugin è stato installato correttamente. Il server Jellyfin dovrà essere riavviato affinché le modifiche abbiano effetto.", "PreferEmbeddedTitlesOverFileNames": "Preferisci titoli integrati ai nomi dei file", "PreferEmbeddedTitlesOverFileNamesHelp": "Determina il titolo predefinito usato quando non sono disponibili metadati locali o da Internet.", "Premiere": "Prima visione", @@ -1080,7 +1080,7 @@ "Record": "Registra", "RecordSeries": "Registra serie TV", "RecordingCancelled": "Registrazione annullata.", - "RecordingPathChangeMessage": "La modifica della cartella di registrazione non migrerà le registrazioni esistenti dalla vecchia posizione al nuovo. Sarà necessario spostarli manualmente, se lo si desidera.", + "MessageChangeRecordingPath": "La modifica della cartella di registrazione non migrerà le registrazioni esistenti dalla vecchia posizione al nuovo. Sarà necessario spostarli manualmente, se lo si desidera.", "RecordingScheduled": "Registrazione pianificata.", "Recordings": "Registrazioni", "Refresh": "Aggiorna", @@ -1223,7 +1223,7 @@ "TvLibraryHelp": "Rivedere la {0} guida di denominazione TV{1}.", "Uniform": "Uniforme", "UninstallPluginConfirmation": "Sei sicuro di voler Disinstallare {0}?", - "UninstallPluginHeader": "Disinstalla Plugin", + "HeaderUninstallPlugin": "Disinstalla Plugin", "Unmute": "Togli muto", "Unplayed": "Non visto", "Unrated": "Non votato", diff --git a/src/strings/ja.json b/src/strings/ja.json index d41bea60b5..0ea7eeb250 100644 --- a/src/strings/ja.json +++ b/src/strings/ja.json @@ -52,7 +52,7 @@ "Box": "ボックス", "BoxRear": "ボックス(後)", "Browse": "ブラウズ", - "BrowsePluginCatalogMessage": "利用可能なプラグインを表示するには、プラグインカタログを参照してください。", + "MessageBrowsePluginCatalog": "利用可能なプラグインを表示するには、プラグインカタログを参照してください。", "BurnSubtitlesHelp": "ビデオのトランスコード時にサーバーが字幕を焼付けるかどうかを決定します。 この字幕焼付けを避けると、サーバーのパフォーマンスが非常に向上します。 画像ベースの形式 (VOBSUB, PGS, SUB, IDX など) と特定の ASS または SSA 字幕でだけ焼付けを行うには、自動を選んでください。", "ButtonAdd": "追加", "ButtonAddMediaLibrary": "メディアライブラリを追加", @@ -157,7 +157,7 @@ "DateAdded": "追加日時", "DatePlayed": "再生日時", "Default": "デフォルト", - "DefaultErrorMessage": "要求の処理中にエラーが発生しました。 後でもう一度やり直してください。", + "MessageDefaultError": "要求の処理中にエラーが発生しました。 後でもう一度やり直してください。", "DefaultMetadataLangaugeDescription": "これらはデフォルトであり、ライブラリごとにカスタマイズすることができます。", "DefaultSubtitlesHelp": "字幕は、埋め込みメタデータのデフォルトフラグと強制フラグに基づいてロードされます。 複数のオプションが利用可能な場合は、言語設定が考慮されます。", "Delete": "削除", @@ -236,7 +236,7 @@ "ErrorAddingXmlTvFile": "XMLTV ファイルへのアクセス中にエラーが発生しました。 ファイルが存在することを確認して、やり直してください。", "ErrorDeletingItem": "Jellyfin サーバーからアイテムを削除中にエラーが発生しました。 Jellyfin サーバーがメディアフォルダーへの書き込みアクセス権を持っていることを確認して、もう一度やり直してください。", "ErrorGettingTvLineups": "TV ラインナップ のダウンロード中にエラーが発生しました。 あなたの情報が正しいことを確認してもう一度やり直してください。", - "ErrorMessageStartHourGreaterThanEnd": "終了時間は開始時間より長くなければなりません。", + "ErrorStartHourGreaterThanEnd": "終了時間は開始時間より長くなければなりません。", "ErrorPleaseSelectLineup": "ラインナップを選択してもう一度やり直してください。 ラインナップが利用できない場合は、あなたのユーザー名、パスワード、および郵便番号が正しいことを確認してください。", "ErrorSavingTvProvider": "TV プロバイダの保存中にエラーが発生しました。 アクセス可能であることを確認して、もう一度やり直してください。", "EveryNDays": "{0}日ごと", @@ -594,7 +594,7 @@ "OptionWeekdays": "平日", "ParentalRating": "個人評価", "PasswordResetConfirmation": "本当にパスワードを再設定しますか?", - "PasswordResetHeader": "パスワード再設定", + "HeaderResetPassword": "パスワード再設定", "PasswordSaved": "パスワードが保存されました。", "People": "ピープル", "PerfectMatch": "完全に一致", @@ -786,7 +786,7 @@ "TitlePlayback": "プレイバック", "TrackCount": "{0} トラック", "Transcoding": "トランスコーディング", - "UninstallPluginHeader": "プラグインをアンインストール", + "HeaderUninstallPlugin": "プラグインをアンインストール", "Unmute": "ミュート解除", "Unrated": "未評価", "Up": "上へ", diff --git a/src/strings/kk.json b/src/strings/kk.json index 1396bcff34..521dcfad5e 100644 --- a/src/strings/kk.json +++ b/src/strings/kk.json @@ -53,7 +53,7 @@ "Box": "Qorap", "BoxRear": "Qorap arty", "Browse": "Sharlaý", - "BrowsePluginCatalogMessage": "Qoljetimdi plagındermen tanysý úshin plagın tizimdemesin sholyńyz.", + "MessageBrowsePluginCatalog": "Qoljetimdi plagındermen tanysý úshin plagın tizimdemesin sholyńyz.", "BurnSubtitlesHelp": "Beıneni qaıta kodtaǵan kezde server sýbtıtrlerdi jazyýyn anyqtaıdy. Onan qashqaqtaý serverdiń ónimdiligin biraz jaqsartady. Sýretke negizdelgen pishimderdi (VOBSUB, PGS, SUB, IDX, j.t.b.) jáne keıbir ASS nemese SSA sýbtıtrlerin jazý úshin Avtomattyny tańdańyz.", "ButtonAdd": "Ústeý", "ButtonAddMediaLibrary": "Tasyǵyshhana ústeý", @@ -161,7 +161,7 @@ "DatePlayed": "Oınatylǵan kúni", "DeathDateValue": "Ólgeni: {0}", "Default": "Ádepki", - "DefaultErrorMessage": "Saýal óńdelý kezinde qate oryn aldy. Áreketti keıin qaıtalańyz.", + "MessageDefaultError": "Saýal óńdelý kezinde qate oryn aldy. Áreketti keıin qaıtalańyz.", "DefaultMetadataLangaugeDescription": "Bular sizdiń ádepki maǵynalaryńyz jáne ár tasyǵyshhana negizinde teńsheýge bolady.", "DefaultSubtitlesHelp": "Sýbtıtrler engizilgen metaderekterdegi ádepki jáne májbúrli jalaýshalary negizinde júktelip alynady. Birneshe opsıa qoljetimdi bolǵanda til teńshelimi qarastyrylady.", "Delete": "Joıý", @@ -230,7 +230,7 @@ "ErrorAddingXmlTvFile": "XMLTV-faılyna qatynaý kezinde qate oryn aldy. Faıl bar bolýyna kóz jetkizińiz de áreketti qaıtalańyz.", "ErrorDeletingItem": "Jellyfin Server elementin joıý kezinde qate oryn aldy. Jellyfin Server tasyǵysh qaltasyna jazýǵa ruqsaty bar ekenin tekserip, qaıtalap kórińiz.", "ErrorGettingTvLineups": "TD kezekterin júktep alý kezinde qate oryn aldy. Málimetterińiz durys ekenine kóz jetkizińiz de áreketti qaıtalańyz.", - "ErrorMessageStartHourGreaterThanEnd": "Aıaqtalý ýaqyty bastaý ýaqytynan keıinrek bolýy qajet etedi.", + "ErrorStartHourGreaterThanEnd": "Aıaqtalý ýaqyty bastaý ýaqytynan keıinrek bolýy qajet etedi.", "ErrorPleaseSelectLineup": "Tizbekti tańdańyz jáne áreketti qaıtalańyz. Eger eshqandaı tizbek qoljetimdi bolmasa, onda paıdalanýshy atyńyzdy, parólińizdi jáne poshta kodyn durys ekenin tekserińiz.", "ErrorSavingTvProvider": "TD jetkizýshisin saqtaý kezinde qate oryn aldy. Bul qatynaýly ekenine kóz jetkizińiz de áreketti qaıtalańyz.", "EveryNDays": "{0} kún saıyn", @@ -952,8 +952,8 @@ "NextUp": "Kezekti", "No": "Joq", "NoNewDevicesFound": "Jańa qurylǵylar tabylmady. Jańa túner ústeý úshin, osy tilqatysý terezesin jaýyp, qurylǵy aqparatyn qolmen engizińiz.", - "NoNextUpItemsMessage": "Eshteńe tabylmady. Kórsetimderińizdi qaraı bastańyz!", - "NoPluginConfigurationMessage": "Osy plagınde teńsheletin parametrler joq.", + "MessageNoNextUpItems": "Eshteńe tabylmady. Kórsetimderińizdi qaraı bastańyz!", + "MessageNoPluginConfiguration": "Osy plagınde teńsheletin parametrler joq.", "NoSubtitleSearchResultsFound": "Eshqandaı nátıjeler tabylmady.", "NoSubtitles": "Eshqandaı", "NoSubtitlesHelp": "Ádepkide sýbtıtrler júktelmeıdi. Olardy oınatý kezinde áli de qolmen qosýǵa bolady.", @@ -1111,7 +1111,7 @@ "PasswordMatchError": "Paróli men Paróldi rastaý óristeri sáıkes bolý kerek.", "PasswordResetComplete": "Paról ysyryldy.", "PasswordResetConfirmation": "Shynymen paróldi ysyrý qajet pe?", - "PasswordResetHeader": "Paróldi ysyrý", + "HeaderResetPassword": "Paróldi ysyrý", "PasswordSaved": "Paról saqtaldy.", "People": "Adamdar", "PerfectMatch": "Úzdik teń", @@ -1133,7 +1133,7 @@ "PleaseEnterNameOrId": "Atyn nemese syrtqy ID engizińiz.", "PleaseRestartServerName": "Jellyfin Server úshin qaıta iske qosyńyz - {0}.", "PleaseSelectTwoItems": "Eń keminde eki tarmaqty tańdańyz.", - "PluginInstalledMessage": "Plagın sátti ornatyldy. Ózgertýler kúshine enýi úshin Jellyfin Server qaıta iske qosylý qajet.", + "MessagePluginInstalled": "Plagın sátti ornatyldy. Ózgertýler kúshine enýi úshin Jellyfin Server qaıta iske qosylý qajet.", "PreferEmbeddedTitlesOverFileNames": "Faıl ataýlary ornyna endirilgen ataýlardy qalaý", "PreferEmbeddedTitlesOverFileNamesHelp": "Internettegi metaderekter nemese jergilikti metaderekter qol jetimdi bolmaǵanda bul ádepki beıneletin ataýdy anyqtaıdy.", "Premiere": "Tusaýkeseri", @@ -1155,7 +1155,7 @@ "Record": "Jazý", "RecordSeries": "Telehıkaıany jazý", "RecordingCancelled": "Jazba boldyrylmady.", - "RecordingPathChangeMessage": "Jazý qaltasyn ózgertkende, bar jazbalar eski ornynan jańasyna tasymaldanbaıdy. Talap etseńiz, olardy qolmen jyljytýyńyzǵa qajet bolady.", + "MessageChangeRecordingPath": "Jazý qaltasyn ózgertkende, bar jazbalar eski ornynan jańasyna tasymaldanbaıdy. Talap etseńiz, olardy qolmen jyljytýyńyzǵa qajet bolady.", "RecordingScheduled": "Jazý josparlaǵan.", "Recordings": "Jazbalar", "Refresh": "Jańǵyrtý", @@ -1310,7 +1310,7 @@ "TvLibraryHelp": "{0}TD-kórsetimdi ataý nusqaýlyǵyn{1} qarap shyǵý.", "Uniform": "Biryńǵaı", "UninstallPluginConfirmation": "Shynymen {0} ornatýyn boldyrmaý qajet pe?", - "UninstallPluginHeader": "Plagın ornatýyn boldyrmaý", + "HeaderUninstallPlugin": "Plagın ornatýyn boldyrmaý", "Unmute": "Dybysty qosý", "Unplayed": "Oınatylmaǵan", "Unrated": "Baǵalanbaǵan", diff --git a/src/strings/ko.json b/src/strings/ko.json index e587031bb5..68f963dea7 100644 --- a/src/strings/ko.json +++ b/src/strings/ko.json @@ -13,7 +13,7 @@ "Backdrops": "배경", "BirthDateValue": "출생: {0}", "BirthPlaceValue": "출생지: {0}", - "BrowsePluginCatalogMessage": "사용 가능한 플러그인을 보려면 플러그인 카탈로그를 참고하십시오.", + "MessageBrowsePluginCatalog": "사용 가능한 플러그인을 보려면 플러그인 카탈로그를 참고하십시오.", "ButtonAdd": "추가", "ButtonAddScheduledTaskTrigger": "트리거 추가", "ButtonAddServer": "서버 추가", @@ -86,7 +86,7 @@ "Connect": "접속", "CustomDlnaProfilesHelp": "새 장치를 대상으로 하거나 시스템 프로필을 재정의 할 사용자 지정 프로필을 만듭니다.", "DeathDateValue": "사망: {0}", - "DefaultErrorMessage": "요청을 처리하는 중에 오류가 발생했습니다. 나중에 다시 시도하십시오.", + "MessageDefaultError": "요청을 처리하는 중에 오류가 발생했습니다. 나중에 다시 시도하십시오.", "DefaultMetadataLangaugeDescription": "이는 기본값이며 라이브러리별로 사용자 정의될 수 있습니다.", "Delete": "제거", "DeleteImage": "이미지 제거", @@ -525,7 +525,7 @@ "MoreUsersCanBeAddedLater": "나중에 대시보드에서 사용자를 더 추가할 수 있습니다.", "Mute": "음소거", "NewCollection": "새 컬렉션", - "NoNextUpItemsMessage": "아무도 찾지 못했어요. 여러분의 쇼를 보기 시작하세요!", + "MessageNoNextUpItems": "아무도 찾지 못했어요. 여러분의 쇼를 보기 시작하세요!", "OptionAdminUsers": "관리자", "OptionAlbum": "앨범", "OptionAlbumArtist": "앨범 아티스트", @@ -648,7 +648,7 @@ "PasswordMatchError": "비밀번호와 비밀번호 확인이 일치해야 합니다.", "PasswordResetComplete": "비밀번호가 재설정되었습니다.", "PasswordResetConfirmation": "비밀번호를 재설정하겠습니까?", - "PasswordResetHeader": "비밀번호 재설정", + "HeaderResetPassword": "비밀번호 재설정", "PasswordSaved": "비밀번호가 저장되었습니다.", "PictureInPicture": "Picture in picture", "PinCodeResetComplete": "PIN 코드가 초기화되었습니다.", @@ -749,7 +749,7 @@ "TrackCount": "{0} 트랙", "Tuesday": "화요일", "UninstallPluginConfirmation": "{0} 을(를) 설치 제거하겠습니까?", - "UninstallPluginHeader": "플러그인 제거", + "HeaderUninstallPlugin": "플러그인 제거", "Unmute": "음소거 취소", "UserProfilesIntro": "Jellyfin은 세분화된 디스플레이 설정, 재생 상태, 자녀 보호 기능을 갖춘 사용자 프로필을 지원합니다.", "ValueAlbumCount": "{0} 앨범", @@ -953,7 +953,7 @@ "Programs": "프로그램", "Previous": "이전", "PreferEmbeddedTitlesOverFileNames": "파일 이름보다 내장된 제목 선호", - "PluginInstalledMessage": "플러그인이 성공적으로 설치되었습니다. 변경사항을 적용하려면 Jellyfin 서버를 재시작하십시오.", + "MessagePluginInstalled": "플러그인이 성공적으로 설치되었습니다. 변경사항을 적용하려면 Jellyfin 서버를 재시작하십시오.", "PleaseRestartServerName": "Jellyfin 서버를 재시작하십시오 - {0}.", "PleaseEnterNameOrId": "이름 또는 외부 ID를 입력하십시오.", "PlayNextEpisodeAutomatically": "자동으로 다음 에피소드 재생", @@ -1143,7 +1143,7 @@ "FileReadCancelled": "파일 읽기 작업이 취소되었습니다.", "FetchingData": "추가 데이터를 가져오는 중", "ExtraLarge": "매우 큼", - "ErrorMessageStartHourGreaterThanEnd": "종료 시간은 시작 시간보다 커야 합니다.", + "ErrorStartHourGreaterThanEnd": "종료 시간은 시작 시간보다 커야 합니다.", "Display": "디스플레이", "DirectStreamHelp1": "이 미디어는 해상도 및 미디어 유형(H.264, AC3 등)과 관련하여 장치와 호환되지만, 파일 컨테이너(mkv, avi, wmv 등)와는 호환되지 않습니다. 비디오는 장치로 스트리밍 되기 전에 즉각 재포장됩니다.", "Descending": "내림차순", @@ -1258,7 +1258,7 @@ "MediaInfoBitDepth": "비트뎁스", "LabelPostProcessor": "후처리 애플리케이션:", "RefreshQueued": "새로 고침 대기 중", - "NoPluginConfigurationMessage": "이 플러그인은 설정할 것이 없습니다.", + "MessageNoPluginConfiguration": "이 플러그인은 설정할 것이 없습니다.", "OptionExtractChapterImage": "챕터 이미지 추출 활성화", "Up": "위", "EasyPasswordHelp": "쉬운 핀 코드는 지원되는 기기에서 오프라인 접근을 할 때나 내부 내트워크 로그인에서 사용됩니다.", diff --git a/src/strings/lt-lt.json b/src/strings/lt-lt.json index c0b254251a..6726c85291 100644 --- a/src/strings/lt-lt.json +++ b/src/strings/lt-lt.json @@ -65,7 +65,7 @@ "ConfirmDeletion": "Patvirtinti trynimą", "Continuing": "Tęsiamas", "CustomDlnaProfilesHelp": "Sukurti kitą profilį naujam įrenginiui ar pakeisti sistemos profilį.", - "DefaultErrorMessage": "Įvyko klaida vykdant užklausą. Pabandykite vėliau.", + "MessageDefaultError": "Įvyko klaida vykdant užklausą. Pabandykite vėliau.", "Delete": "Ištrinti", "DeleteMedia": "Trinti mediją", "DeviceAccessHelp": "Tai taikoma tik įrenginiams, kurie gali būti identifikuojami, ir neuždraus prieigos per naršyklę. Vartotojo įrenginio prieigos filtravimas neleis jiems naudotis naujais įrenginiais kol jie nepatvirtinti čia.", @@ -322,7 +322,7 @@ "NewEpisodes": "Naujoms serijoms", "NewEpisodesOnly": "Tik naujas serijas", "News": "Naujienos", - "NoNextUpItemsMessage": "Nieko neradau. Pradėkite žiūrėti laidas!", + "MessageNoNextUpItems": "Nieko neradau. Pradėkite žiūrėti laidas!", "NoSubtitleSearchResultsFound": "Nieko neradau.", "OptionAdminUsers": "Administratoriai", "OptionAlbum": "Albumas", @@ -655,7 +655,7 @@ "AllowRemoteAccessHelp": "Jei nepažymėta, visi nuotoliniai prisijungimai bus blokuojami.", "Banner": "Juosta", "HeaderDeleteDevice": "Ištrinti prietaisą", - "BrowsePluginCatalogMessage": "Peržiūrėti įskiepių katalogą.", + "MessageBrowsePluginCatalog": "Peržiūrėti įskiepių katalogą.", "EnableBackdrops": "Fonai", "EnableCinemaMode": "Kino režimas", "EnableDisplayMirroring": "Ekrano dubliavimas", @@ -831,7 +831,7 @@ "HeaderAccessSchedule": "Prieigos tvarkaraštis", "HeaderAccessScheduleHelp": "Sukurkite prieigos tvarkaraštį, kad apribotumėte prieigą tam tikromis valandomis.", "HeaderContainerProfile": "Konteinerio profilis", - "ErrorMessageStartHourGreaterThanEnd": "Pabaigos laikas turi būti didesnis nei pradžios laikas.", + "ErrorStartHourGreaterThanEnd": "Pabaigos laikas turi būti didesnis nei pradžios laikas.", "HeaderFeatures": "Medžiagos", "ErrorSavingTvProvider": "Išsaugant TV teikėją įvyko klaida. Įsitikinkite, kad jis prieinamas, ir bandykite dar kartą.", "HeaderKodiMetadataHelp": "Norėdami įjungti arba išjungti NFO metaduomenis, redaguokite biblioteką Jellyfin bibliotekos nustatymuose, metaduomenų išsaugojimo skyriuje.", diff --git a/src/strings/lv.json b/src/strings/lv.json index fd2d2d821e..329354d93b 100644 --- a/src/strings/lv.json +++ b/src/strings/lv.json @@ -556,7 +556,7 @@ "ButtonAddMediaLibrary": "Pievienot Multimēdiju Bibliotēku", "ButtonAddImage": "Pievienot attēlu", "ButtonAdd": "Pievienot", - "BrowsePluginCatalogMessage": "Pārlūko mūsu paplašinājumu katalogu, lai redzētu pieejamos paplašinājumus.", + "MessageBrowsePluginCatalog": "Pārlūko mūsu paplašinājumu katalogu, lai redzētu pieejamos paplašinājumus.", "Browse": "Pārlūkot", "BoxRear": "Kaste (aizmugure)", "Box": "Kaste", @@ -692,7 +692,7 @@ "Unrated": "Nevērtēts", "Unplayed": "Neatskaņots", "Unmute": "Ieslēgt skaņu", - "UninstallPluginHeader": "Noņemt Paplašinājumu", + "HeaderUninstallPlugin": "Noņemt Paplašinājumu", "UninstallPluginConfirmation": "Vai tu tiešām vēlies noņemt {0}?", "Tuesday": "Otrdiena", "Transcoding": "Trans-kodēšana", @@ -830,7 +830,7 @@ "OptionAutomatic": "Auto", "OptionAuto": "Auto", "OptionArtist": "Izpildītājs", - "NoPluginConfigurationMessage": "Šim paplašinājumam nav konfigurējamu iestatījumu.", + "MessageNoPluginConfiguration": "Šim paplašinājumam nav konfigurējamu iestatījumu.", "NoCreatedLibraries": "Izskatās ka tu vēl neesi izveidojis nevienu bibliotēku. {0}Vai tu vēlies izveidot vienu tagad?{1}", "NextUp": "Nākamais", "Mute": "Apklusināt", @@ -881,7 +881,7 @@ "LabelCustomCertificatePathHelp": "Ceļš uz PKCS #12 datni, kas satur sertifikātu un privāto atslēgu lai iespējotu TLS atbalstu uz sava domēna.", "FolderTypeUnset": "Jaukts Saturs", "ErrorSavingTvProvider": "Kļūda saglabājot TV sniedzēju. Pārliecinies ka tas ir pieejams un mēģini vēlreiz.", - "ErrorMessageStartHourGreaterThanEnd": "Beigu laikam jābūt vēlākam par sākuma laiku.", + "ErrorStartHourGreaterThanEnd": "Beigu laikam jābūt vēlākam par sākuma laiku.", "ErrorAddingXmlTvFile": "Kļūda atverot XMLTV datni. Lūdzu pārliecinies ka datne eksistē un mēģini vēlreiz.", "LabelCustomCssHelp": "Izmanto pats savu pielāgoto silu web interfeisam.", "LabelCustomCss": "Pielāgots CSS:", @@ -975,7 +975,7 @@ "DeleteMedia": "Dzēst mediju", "DeleteImageConfirmation": "Vai tu tiešām vēlies izdzēst šo attēlu?", "DeleteDeviceConfirmation": "Vai tu tiešām vēlies noņemt šo ierīci? Tā parādīsies atkārtoti nākamo reizi, kad lietotājs ieiet ar to.", - "DefaultErrorMessage": "Apstrādājot pieprasījumu notika kļūda. Pēc brītiņa lūdzu mēģini vēlreiz.", + "MessageDefaultError": "Apstrādājot pieprasījumu notika kļūda. Pēc brītiņa lūdzu mēģini vēlreiz.", "DeathDateValue": "Miris: {0}", "ConfirmEndPlayerSession": "Vai jūs gribat izslēgt Jellyfin uz {0}?", "ConfirmDeleteItems": "Dzēšot šos vienumus, tie tiks izdzēsti gan no jūsu failu sistēmas, gan mediju bibliotēkas. Vai tiešām turpināt?", @@ -1137,7 +1137,7 @@ "PlaybackData": "Atskaņošanas Dati", "Person": "Persona", "PerfectMatch": "Ideāla saderība", - "PasswordResetHeader": "Atiestatīt Paroli", + "HeaderResetPassword": "Atiestatīt Paroli", "PasswordResetConfirmation": "Vai tu tiešām gribi atiestatīt paroli?", "PasswordResetComplete": "Parole ir atiestatīta.", "PasswordMatchError": "Parolei un paroles pārbaudei ir jāsakrīt.", diff --git a/src/strings/ms.json b/src/strings/ms.json index d5f9259c21..db01453815 100644 --- a/src/strings/ms.json +++ b/src/strings/ms.json @@ -92,7 +92,7 @@ "ButtonAddScheduledTaskTrigger": "Tambah Pencetus", "ButtonAddImage": "Tambah gambar", "BurnSubtitlesHelp": "Menentukan sama ada pelayan perlu membakar subtitle ke skrin apabila menukar video bergantung kepada format sarikata. Menghindari pembakaran sari kata ke skrin akan meningkatkan prestasi pelayan. Pilih Auto untuk membakar format berasaskan imej (VOBSUB, PGS, SUB / IDX, dll) dan subtitle ASS / SSA tertentu.", - "BrowsePluginCatalogMessage": "Semak imbas katalog plugin kami untuk melihat plugin yang tersedia.", + "MessageBrowsePluginCatalog": "Semak imbas katalog plugin kami untuk melihat plugin yang tersedia.", "BoxRear": "Kotak (belakang)", "BookLibraryHelp": "Buku audio dan teks disokong. Semak {0}panduan penamaan buku{1}.", "Banner": "Sepanduk", diff --git a/src/strings/nb.json b/src/strings/nb.json index bba97f9da2..dbd94366ad 100644 --- a/src/strings/nb.json +++ b/src/strings/nb.json @@ -33,7 +33,7 @@ "BirthPlaceValue": "Fødested: {0}", "BookLibraryHelp": "Lyd- og tekstbøker støttes. Se igjennom {0} navneguiden for bøker {1}.", "Books": "Bøker", - "BrowsePluginCatalogMessage": "Bla i tilleggskatalogen vår for å se tilgjengelige applikasjonstillegg.", + "MessageBrowsePluginCatalog": "Bla i tilleggskatalogen vår for å se tilgjengelige applikasjonstillegg.", "ButtonAdd": "Legg til", "ButtonAddMediaLibrary": "Legg til bibliotek", "ButtonAddScheduledTaskTrigger": "Legg til utløser", @@ -126,7 +126,7 @@ "Continuing": "Fortsetter", "CustomDlnaProfilesHelp": "Lag en tilpasset profil til en ny enhet eller for å overstyre en system-profil.", "DeathDateValue": "Døde: {0}", - "DefaultErrorMessage": "Det oppstod en feil under behandling av forespørselen. Vennligst prøv igjen senere.", + "MessageDefaultError": "Det oppstod en feil under behandling av forespørselen. Vennligst prøv igjen senere.", "DefaultMetadataLangaugeDescription": "Dette er standardverdiene dine, de kan også tilpasses per biblioteksbasis.", "Delete": "Slett", "DeleteDeviceConfirmation": "Er du sikker på at du ønsker å slette denne enheten? Den vil gjenoppstå neste gang en bruker logger inn med den.", @@ -164,7 +164,7 @@ "ErrorAddingTunerDevice": "Det oppstod en feil når tuneren skulle legges til. Vennligst sørg for at den er tilgjengelig og prøv på nytt.", "ErrorAddingXmlTvFile": "Det oppstod en feil under lesing av XMLTV-filen. Vennligst sørg for at filen finnes og prøv igjen.", "ErrorGettingTvLineups": "Det oppstod en feil under nedlastning av TV-oversikten. Vennligst sørg for at informasjonen er korrekt og prøv igjen.", - "ErrorMessageStartHourGreaterThanEnd": "Sluttid må være senere enn starttid.", + "ErrorStartHourGreaterThanEnd": "Sluttid må være senere enn starttid.", "ErrorPleaseSelectLineup": "Velg et programoppsett og prøv igjen. Hvis ingen oppsett er tilgjengelig, sjekk at brukernavn, passord og postnummer er riktig.", "ErrorSavingTvProvider": "Det oppstod en feil ved lagring av TV-leverandør. Vennligst forsikre deg om at den er tilgjengelig, og prøv på nytt.", "EveryNDays": "Hver {0}. dag", @@ -763,7 +763,7 @@ "NextUp": "Neste", "No": "Nei", "NoNewDevicesFound": "Ingen nye enheter funnet. For å legge til en ny tuner, lukk denne dialogboksen og skriv inn enhetens informasjon manuelt.", - "NoNextUpItemsMessage": "Ingen funnet. Begynn å se det du har!", + "MessageNoNextUpItems": "Ingen funnet. Begynn å se det du har!", "NoSubtitleSearchResultsFound": "Ingen resultater funnet.", "None": "Ingen", "NumLocationsValue": "{0} mapper", @@ -895,7 +895,7 @@ "PasswordMatchError": "Passord og passordbekreftelsen må matche.", "PasswordResetComplete": "Passordet har blitt tilbakestilt.", "PasswordResetConfirmation": "Er du sikker på at du vil tilbakestille passordet?", - "PasswordResetHeader": "Tilbakestill passord", + "HeaderResetPassword": "Tilbakestill passord", "PasswordSaved": "Passord lagret.", "People": "Mennesker", "PictureInPicture": "Bilde i bilde", @@ -913,7 +913,7 @@ "PleaseEnterNameOrId": "Vennligst skriv et navn eller en ekstern ID.", "PleaseRestartServerName": "Vennligst start Jellyfin-serveren på nytt - {0}.", "PleaseSelectTwoItems": "Vennligst velg minst to elementer.", - "PluginInstalledMessage": "Programtillegget ble installert. Jellyfin-serveren må startes på nytt for at endringene skal tre i kraft.", + "MessagePluginInstalled": "Programtillegget ble installert. Jellyfin-serveren må startes på nytt for at endringene skal tre i kraft.", "PreferEmbeddedTitlesOverFileNames": "Foretrekk integrerte titler fremfor filnavn", "PreferEmbeddedTitlesOverFileNamesHelp": "Dette avgjør standard visningstittel når det ikke er noen metadata eller lokale metadata tilgjengelige.", "Premieres": "Premierer", @@ -931,7 +931,7 @@ "Record": "Ta opp", "RecordSeries": "Ta opp serien", "RecordingCancelled": "Opptak er avbrutt.", - "RecordingPathChangeMessage": "Endring av mappen for opptak vil ikke flytte eksisterende opptak fra den gamle plasseringen til den nye. Du må flytte dem manuelt hvis ønskelig.", + "MessageChangeRecordingPath": "Endring av mappen for opptak vil ikke flytte eksisterende opptak fra den gamle plasseringen til den nye. Du må flytte dem manuelt hvis ønskelig.", "RecordingScheduled": "Opptak planlagt.", "Recordings": "Opptak", "Refresh": "Oppdater", @@ -1050,7 +1050,7 @@ "Tuesday": "Tirsdag", "TvLibraryHelp": "Gå igjennom {0}veiledning for navngivelse av TV-programmer{1}.", "UninstallPluginConfirmation": "Er du sikker på at du ønsker å avinstallere {0}?", - "UninstallPluginHeader": "Avinstaller programtillegg", + "HeaderUninstallPlugin": "Avinstaller programtillegg", "Unrated": "Ikke vurdert", "Up": "Opp", "UserProfilesIntro": "Jellyfin har støtte for brukerprofiler med finjusterbare innstillinger, avspillingsstatus og foreldrekontroll.", @@ -1207,7 +1207,7 @@ "LabelLanNetworks": "Lokale nettverk:", "MediaInfoCodecTag": "Kodektagg", "Metadata": "Metadata", - "NoPluginConfigurationMessage": "Dette programtillegget har ingen innstillinger å konfigurere.", + "MessageNoPluginConfiguration": "Dette programtillegget har ingen innstillinger å konfigurere.", "TabGuide": "Guide", "Unmute": "Skru på lyd", "OptionIsHD": "HD", diff --git a/src/strings/nl.json b/src/strings/nl.json index e97578db4b..0ee710db7f 100644 --- a/src/strings/nl.json +++ b/src/strings/nl.json @@ -48,7 +48,7 @@ "Books": "Boeken", "BoxRear": "Hoes (achterkant)", "Browse": "Bladeren", - "BrowsePluginCatalogMessage": "Bekijk de Plugin catalogus voor beschikbare Plug-ins.", + "MessageBrowsePluginCatalog": "Bekijk de Plugin catalogus voor beschikbare Plug-ins.", "BurnSubtitlesHelp": "Bepaalt of de server ondertitels moet branden bij het transcoderen van video's. Als u dit vermijd, worden de prestaties aanzienlijk verbeterd. Selecteer Auto om op afbeeldingen gebaseerde formaten (VOBSUB, PGS, SUB/IDX etc.) en bepaalde ASS/SSA ondertitels te branden.", "ButtonAdd": "Toevoegen", "ButtonAddMediaLibrary": "Voeg Media Bibliotheek toe", @@ -149,7 +149,7 @@ "DatePlayed": "Datum afgespeeld", "DeathDateValue": "Overleden: {0}", "Default": "Standaard", - "DefaultErrorMessage": "Er is een fout opgetreden. Probeer later opnieuw.", + "MessageDefaultError": "Er is een fout opgetreden. Probeer later opnieuw.", "DefaultMetadataLangaugeDescription": "Dit zijn uw standaardinstellingen en kunnen per bibliotheek worden aangepast.", "DefaultSubtitlesHelp": "Ondertitels worden geladen op basis van de standaard en geforceerd markeringen in de ingesloten metadata. Indien meerdere opties aanwezig zijn zal rekening worden gehouden met de taalvoorkeuren.", "Delete": "Verwijderen", @@ -216,7 +216,7 @@ "ErrorAddingXmlTvFile": "Er is een fout opgetreden met de toegang tot XMLTV bestand. Zorg ervoor dat het bestand bestaat en probeer het opnieuw.", "ErrorDeletingItem": "Er was een probleem bij het verwijderen van het item in Jellyfin Server. Controleer dat Jellyfin Server schrijfrechten op de map heeft en probeer het opnieuw.", "ErrorGettingTvLineups": "Er was een fout bij het downloaden van de TV lineup. Controleer of uw gegevens correct zijn en probeer het opnieuw.", - "ErrorMessageStartHourGreaterThanEnd": "Eind tijd moet na de start tijd liggen.", + "ErrorStartHourGreaterThanEnd": "Eind tijd moet na de start tijd liggen.", "ErrorPleaseSelectLineup": "Selecteer een lineup en probeer het opnieuw. Als er geen lineups beschibaar zijn, controleer dan of uw gebruikersnaam, wachtwoord en postcode correct zijn.", "ErrorSavingTvProvider": "Er was een fout bij het opslaan van de TV aanbieder. Controleer of deze toegankelijk is en probeer het opnieuw.", "EveryNDays": "Elke {0} dagen", @@ -880,8 +880,8 @@ "NextUp": "Hierna", "No": "Nee", "NoNewDevicesFound": "Er zijn geen nieuwe apparaten gevonden. Sluit dit melding en voer handmatig de apparaat gegevens in om een nieuwe tuner toe te voegen.", - "NoNextUpItemsMessage": "Niets gevonden. Start met kijken!", - "NoPluginConfigurationMessage": "Deze plugin heeft geen instellingen te configureren.", + "MessageNoNextUpItems": "Niets gevonden. Start met kijken!", + "MessageNoPluginConfiguration": "Deze plugin heeft geen instellingen te configureren.", "NoSubtitleSearchResultsFound": "Geen resultaten gevonden.", "NoSubtitles": "Geen ondertiteling", "NoSubtitlesHelp": "Ondertitels worden niet standaard weergegeven. Deze kunnen tijdens het afspelen handmatig worden ingeschakeld.", @@ -1022,7 +1022,7 @@ "PasswordMatchError": "Wachtwoord en wachtwoord bevestiging moeten hetzelfde zijn.", "PasswordResetComplete": "Het wachtwoord is opnieuw ingesteld.", "PasswordResetConfirmation": "Weet u zeker dat u het wachtwoord opnieuw in wilt stellen?", - "PasswordResetHeader": "Reset Wachtwoord", + "HeaderResetPassword": "Reset Wachtwoord", "PasswordSaved": "Wachtwoord opgeslagen.", "People": "Personen", "PerfectMatch": "Perfecte match", @@ -1044,7 +1044,7 @@ "PleaseEnterNameOrId": "Voer een naam of een externe ID in.", "PleaseRestartServerName": "Herstart Jellyfin Server - {0} aub.", "PleaseSelectTwoItems": "Selecteer ten minste twee items.", - "PluginInstalledMessage": "Het installeren van de plugin is gelukt. Jellyfin Server zal heropgestart moeten worden om de wijzigingen door te voeren.", + "MessagePluginInstalled": "Het installeren van de plugin is gelukt. Jellyfin Server zal heropgestart moeten worden om de wijzigingen door te voeren.", "PreferEmbeddedTitlesOverFileNames": "Prefereer ingesloten titels boven bestandsnamen", "PreferEmbeddedTitlesOverFileNamesHelp": "Dit bepaalt de standaard weergavetitel wanneer er geen internet metagegevens of lokale metadata beschikbaar is.", "Premieres": "Premières", @@ -1065,7 +1065,7 @@ "Record": "Opnemen", "RecordSeries": "Series Opnemen", "RecordingCancelled": "Opname geannuleerd.", - "RecordingPathChangeMessage": "Bij het wijzigen van uw opnamemap zullen bestaande opnamen niet migreren van de oude locatie naar de nieuwe. U moet deze desgewenst handmatig verplaatsen.", + "MessageChangeRecordingPath": "Bij het wijzigen van uw opnamemap zullen bestaande opnamen niet migreren van de oude locatie naar de nieuwe. U moet deze desgewenst handmatig verplaatsen.", "RecordingScheduled": "Opname schema.", "Recordings": "Opnames", "Refresh": "Vernieuwen", @@ -1204,7 +1204,7 @@ "Tuesday": "Dinsdag", "TvLibraryHelp": "Bekijk de {0}TV naamgeving gids {1}.", "UninstallPluginConfirmation": "Weet u zeker dat u {0} wilt deïnstalleren?", - "UninstallPluginHeader": "Plug-in deïnstalleren", + "HeaderUninstallPlugin": "Plug-in deïnstalleren", "Unmute": "Dempen opheffen", "Unplayed": "Niet afgespeeld", "Unrated": "Geen rating", diff --git a/src/strings/pl.json b/src/strings/pl.json index a141b975cb..9d3ec0b2f3 100644 --- a/src/strings/pl.json +++ b/src/strings/pl.json @@ -53,7 +53,7 @@ "Box": "Pudełko", "BoxRear": "Pudełko (tył)", "Browse": "Przeglądaj", - "BrowsePluginCatalogMessage": "Przejrzyj nasz katalog wtyczek żeby zobaczyć dostępne wtyczki.", + "MessageBrowsePluginCatalog": "Przejrzyj nasz katalog wtyczek żeby zobaczyć dostępne wtyczki.", "BurnSubtitlesHelp": "Określa czy serwer powinien wypalać napisy podczas konwersji wideo, w zależności od formatu napisów. Unikanie wypalania napisów znacząco poprawia wydajność serwera. Wybierz Automatycznie, w celu wypalania zarówno napisów w formatach graficznych (np. VOBSUB, PGS, SUB, IDX, ...), jak i pewnych napisów ASS lub SSA.", "ButtonAdd": "Dodaj", "ButtonAddMediaLibrary": "Dodaj media do biblioteki", @@ -160,7 +160,7 @@ "DatePlayed": "Data odtwarzania", "DeathDateValue": "Zmarły: {0}", "Default": "Domyślny", - "DefaultErrorMessage": "Wystąpił błąd podczas przetwarzania żądania. Proszę spróbować ponownie później.", + "MessageDefaultError": "Wystąpił błąd podczas przetwarzania żądania. Proszę spróbować ponownie później.", "DefaultMetadataLangaugeDescription": "To są twoje ustawienia domyślne. Możesz je zmienić dla każdej biblioteki osobno.", "DefaultSubtitlesHelp": "Napisy będą wczytywane w oparciu o znaczniki metadanych ścieżek dźwiękowych. Preferencje językowe brane są pod uwagę, gdy dostępnych jest wiele możliwości.", "Delete": "Usuń", @@ -229,7 +229,7 @@ "ErrorAddingXmlTvFile": "Podczas próby dostępu do pliku XMLTV wystąpił błąd. Upewnij się, że plik istnieje i spróbuj ponownie.", "ErrorDeletingItem": "Podczas usuwania pozycji z serwera Jellyfin wystąpił błąd. Upewnij się, że serwer ma uprawnienia do zapisu w folderze mediów i spróbuj ponownie.", "ErrorGettingTvLineups": "Podczas pobierania programu telewizyjnego wystąpił błąd. Upewnij się, że informacje są poprawne i spróbuj ponownie.", - "ErrorMessageStartHourGreaterThanEnd": "Czas końcowy musi być większy niż czas początkowy.", + "ErrorStartHourGreaterThanEnd": "Czas końcowy musi być większy niż czas początkowy.", "ErrorPleaseSelectLineup": "Wybierz program i spróbuj ponownie, jeśli żadne programy nie są dostępne, sprawdź czy twój login, hasło i kod pocztowy jest poprawny.", "ErrorSavingTvProvider": "Wystąpił błąd podczas dodawania dostawcy telewizji. Upewnij się, że jest on dostępny i spróbuj ponownie.", "EveryNDays": "Co {0} dni", @@ -945,8 +945,8 @@ "NextUp": "Do obejrzenia", "No": "Nie", "NoNewDevicesFound": "Nie znaleziono żadnych nowych urządzeń. Aby dodać tuner, zamknij ten dialog i wprowadź informacje o urządzeniu ręcznie.", - "NoNextUpItemsMessage": "Nie znaleziono niczego. Zacznij oglądać swoje seriale!", - "NoPluginConfigurationMessage": "Ta wtyczka nie ma żadnych ustawień.", + "MessageNoNextUpItems": "Nie znaleziono niczego. Zacznij oglądać swoje seriale!", + "MessageNoPluginConfiguration": "Ta wtyczka nie ma żadnych ustawień.", "NoSubtitleSearchResultsFound": "Brak wyników wyszukiwania.", "NoSubtitles": "Brak", "NoSubtitlesHelp": "Domyślnie napisy nie będą wczytywane. Można je ciągle włączyć ręcznie podczas odtwarzania.", @@ -1102,7 +1102,7 @@ "PasswordMatchError": "Hasło i potwierdzenie hasła muszą się zgadzać.", "PasswordResetComplete": "Hasło zostało zresetowane.", "PasswordResetConfirmation": "Czy na pewno chcesz wyczyścić hasło?", - "PasswordResetHeader": "Wyczyść hasło", + "HeaderResetPassword": "Wyczyść hasło", "PasswordSaved": "Hasło zapisane.", "People": "Osoby", "PerfectMatch": "Perfekcyjne dopasowanie", @@ -1124,7 +1124,7 @@ "PleaseEnterNameOrId": "Proszę wprowadź nazwę lub zewnętrzne ID.", "PleaseRestartServerName": "Uruchom ponownie serwer Jellyfin - {0}.", "PleaseSelectTwoItems": "Proszę wybierz przynajmniej dwie pozycje.", - "PluginInstalledMessage": "Wtyczka została poprawnie zainstalowana. Serwer Jellyfin będzie wymagała ponownego uruchomienia w celu zastosowania zmian.", + "MessagePluginInstalled": "Wtyczka została poprawnie zainstalowana. Serwer Jellyfin będzie wymagała ponownego uruchomienia w celu zastosowania zmian.", "PreferEmbeddedTitlesOverFileNames": "Preferuj wbudowane tytuły zamiast nazw plików", "PreferEmbeddedTitlesOverFileNamesHelp": "Określa domyślnie wyświetlany tytuł, gdy brak dostępnych metadanych lokalnych i od dostawców internetowych.", "Premiere": "Premiera", @@ -1146,7 +1146,7 @@ "Record": "Nagrywaj", "RecordSeries": "Nagraj seryjnie", "RecordingCancelled": "Anulowano nagranie.", - "RecordingPathChangeMessage": "Zmiana folderu z nagraniami nie spowoduje przeniesienia już istniejących nagrań, ze starej lokalizacji do nowej. Jeśli jest to wymagane, należy to zrobić manualnie.", + "MessageChangeRecordingPath": "Zmiana folderu z nagraniami nie spowoduje przeniesienia już istniejących nagrań, ze starej lokalizacji do nowej. Jeśli jest to wymagane, należy to zrobić manualnie.", "RecordingScheduled": "Zaplanowano nagranie.", "Recordings": "Nagrania", "Refresh": "Odśwież", @@ -1301,7 +1301,7 @@ "TvLibraryHelp": "Zapoznaj się z instrukcją{1} nazewnictwa seriali {0}.", "Uniform": "Jednolity", "UninstallPluginConfirmation": "Czy na pewno chcesz usunąć {0}?", - "UninstallPluginHeader": "Usuń wtyczkę", + "HeaderUninstallPlugin": "Usuń wtyczkę", "Unmute": "Dezaktywuj wyciszenie", "Unplayed": "Nieodtwarzane", "Unrated": "Nieokreślone", diff --git a/src/strings/pt-br.json b/src/strings/pt-br.json index 413abeea73..6c7c49718a 100644 --- a/src/strings/pt-br.json +++ b/src/strings/pt-br.json @@ -49,7 +49,7 @@ "Box": "Caixa", "BoxRear": "Caixa (traseira)", "Browse": "Navegar", - "BrowsePluginCatalogMessage": "Navegue pelo nosso catálogo de plugins para ver os plugins disponíveis.", + "MessageBrowsePluginCatalog": "Navegue pelo nosso catálogo de plugins para ver os plugins disponíveis.", "BurnSubtitlesHelp": "Determina se o servidor deveria gravar as legendas no vídeo ao convertê-lo, dependendo do formato da legenda. Evitar a gravação da legenda irá melhorar a performance do servidor. Selecione Auto para gravar legendas baseados em imagem dos tipos (ex. VOBSUB, PGS, SUB/IDX, etc.) e algumas legendas ASS/SSA.", "ButtonAdd": "Adicionar", "ButtonAddMediaLibrary": "Adicionar Biblioteca de Mídia", @@ -153,7 +153,7 @@ "DatePlayed": "Data de reprodução", "DeathDateValue": "Morte: {0}", "Default": "Padrão", - "DefaultErrorMessage": "Ocorreu um erro ao processar o pedido. Por favor, tente novamente mais tarde.", + "MessageDefaultError": "Ocorreu um erro ao processar o pedido. Por favor, tente novamente mais tarde.", "DefaultMetadataLangaugeDescription": "Estas são suas configurações padrão e podem ser personalizadas por biblioteca.", "DefaultSubtitlesHelp": "Legendas são carregadas com base nas configurações padrão e de legendas forçadas nos metadados incorporados. As preferências de idioma são consideradas quando existem múltiplas opções disponíveis.", "Delete": "Excluir", @@ -219,7 +219,7 @@ "ErrorAddingXmlTvFile": "Ocorreu um erro ao acessar o arquivo XmlTV. Por favor, verifique se o arquivo existe e tente novamente.", "ErrorDeletingItem": "Ocorreu um erro ao excluir o item do Servidor Jellyfin. Por favor, verifique se o Servidor Jellyfin possui acesso de gravação na pasta de mídia e tente novamente.", "ErrorGettingTvLineups": "Ocorreu um erro ao fazer download da programação de TV. Por favor, certifique-se que sua informação esteja correta e tente novamente.", - "ErrorMessageStartHourGreaterThanEnd": "A hora final deve ser maior que a hora inicial.", + "ErrorStartHourGreaterThanEnd": "A hora final deve ser maior que a hora inicial.", "ErrorPleaseSelectLineup": "Por favor, selecione a programação e tente novamente. Se não houver programações disponíveis, verifique se o seu nome de usuário, senha e código postal estão corretos.", "ErrorSavingTvProvider": "Um erro ocorreu ao salvar o provedor de TV. Por favor, verifique se está acessível e tente novamente.", "EveryNDays": "A cada {0} dias", @@ -918,8 +918,8 @@ "NextUp": "A Seguir", "No": "Não", "NoNewDevicesFound": "Nenhum novo dispositivo encontrado. Para adicionar um novo sintonizador, feche esta mensagem e digite as informações do dispositivo manualmente.", - "NoNextUpItemsMessage": "Nada encontrado. Comece a assistir suas séries!", - "NoPluginConfigurationMessage": "Este plugin não permite alterar configurações.", + "MessageNoNextUpItems": "Nada encontrado. Comece a assistir suas séries!", + "MessageNoPluginConfiguration": "Este plugin não permite alterar configurações.", "NoSubtitleSearchResultsFound": "Nenhum resultado encontrado.", "NoSubtitles": "Não há legendas", "NoSubtitlesHelp": "Legendas não serão carregadas por padrão. Elas podem ser carregadas manualmente durante a reprodução.", @@ -1065,7 +1065,7 @@ "PasswordMatchError": "A senha e a confirmação da senha devem ser iguais.", "PasswordResetComplete": "A senha foi redefinida.", "PasswordResetConfirmation": "Deseja realmente redefinir a senha?", - "PasswordResetHeader": "Redefinir Senha", + "HeaderResetPassword": "Redefinir Senha", "PasswordSaved": "Senha salva.", "People": "Pessoas", "PerfectMatch": "Combinação perfeita", @@ -1086,7 +1086,7 @@ "PleaseEnterNameOrId": "Por favor, digite um nome ou ID externa.", "PleaseRestartServerName": "Por favor, reinicie o Servidor Jellyfin - {0}.", "PleaseSelectTwoItems": "Por favor, selecione pelo menos dois itens.", - "PluginInstalledMessage": "O plugin foi instalado com sucesso. O Servidor Jellyfin precisa ser reiniciado para que as alterações sejam aplicadas.", + "MessagePluginInstalled": "O plugin foi instalado com sucesso. O Servidor Jellyfin precisa ser reiniciado para que as alterações sejam aplicadas.", "PreferEmbeddedTitlesOverFileNames": "Preferir títulos incorporados ao invés de nomes de arquivos", "PreferEmbeddedTitlesOverFileNamesHelp": "Isto determina a exibição padrão do título quando não houverem metadados da internet ou locais disponíveis.", "Premieres": "Estreias", @@ -1107,7 +1107,7 @@ "Record": "Gravar", "RecordSeries": "Gravar série", "RecordingCancelled": "Gravação cancelada.", - "RecordingPathChangeMessage": "Alterar a sua pasta de gravações não migrará as gravações existentes do local anterior para o novo. Se desejar, você necessitará movê-los manualmente.", + "MessageChangeRecordingPath": "Alterar a sua pasta de gravações não migrará as gravações existentes do local anterior para o novo. Se desejar, você necessitará movê-los manualmente.", "RecordingScheduled": "Gravação agendada.", "Recordings": "Gravações", "Refresh": "Atualizar", @@ -1250,7 +1250,7 @@ "TvLibraryHelp": "Verifique o {0}guia de nomes de séries{1}.", "Uniform": "Uniforme", "UninstallPluginConfirmation": "Deseja realmente desinstalar {0}?", - "UninstallPluginHeader": "Desinstalar Plugin", + "HeaderUninstallPlugin": "Desinstalar Plugin", "Unmute": "Sair do Mudo", "Unplayed": "Não reproduzido", "Unrated": "Não avaliado", diff --git a/src/strings/pt-pt.json b/src/strings/pt-pt.json index 4243a4869c..5f51f56763 100644 --- a/src/strings/pt-pt.json +++ b/src/strings/pt-pt.json @@ -7,7 +7,7 @@ "AttributeNew": "Novo", "Audio": "Áudio", "Backdrops": "Imagens de Fundo", - "BrowsePluginCatalogMessage": "Procure extensões disponíveis no nosso catálogo.", + "MessageBrowsePluginCatalog": "Procure extensões disponíveis no nosso catálogo.", "ButtonAdd": "Adicionar", "ButtonAddMediaLibrary": "Adicionar Biblioteca de Multimédia", "ButtonAddScheduledTaskTrigger": "Adicionar tarefa agendada", @@ -527,7 +527,7 @@ "Mute": "Desativar Som", "NewCollection": "Nova Coleção", "NewCollectionNameExample": "Exemplo: Coleção Guerra das Estrelas", - "NoNextUpItemsMessage": "Nenhum encontrado. Comece a ver os seus programas!", + "MessageNoNextUpItems": "Nenhum encontrado. Comece a ver os seus programas!", "OptionAdminUsers": "Administradores", "OptionAlbum": "Álbum", "OptionAlbumArtist": "Artista do Álbum", @@ -643,7 +643,7 @@ "PasswordMatchError": "A palavra-passe e a confirmação devem coincidir.", "PasswordResetComplete": "A palavra-passe foi redefinida.", "PasswordResetConfirmation": "Tem a certeza de que deseja redefinir a palavra-passe?", - "PasswordResetHeader": "Redefinir Palavra-Passe", + "HeaderResetPassword": "Redefinir Palavra-Passe", "PasswordSaved": "Palavra-passe guardada.", "PinCodeResetComplete": "O código PIN foi redefinido.", "PinCodeResetConfirmation": "Tem a certeza de que devia repôr o código PIN?", @@ -734,7 +734,7 @@ "TrackCount": "{0} faixas", "Tuesday": "Terça", "UninstallPluginConfirmation": "Tem a certeza de que deseja desinstalar {0}?", - "UninstallPluginHeader": "Desinstalar Extensão", + "HeaderUninstallPlugin": "Desinstalar Extensão", "Unmute": "Ativar som", "UserProfilesIntro": "O Jellyfin suporta perfis de utilizadores, permitindo que cada utilizador tenha as suas configurações de visualização, estado da reprodução e controlos parentais.", "ValueAudioCodec": "Codec de Áudio: {0}", @@ -881,7 +881,7 @@ "ExtraLarge": "Extra Grande", "EveryNDays": "A cada {0} dias", "ErrorSavingTvProvider": "Ocorreu um erro ao guardar o provedor do serviços de TV. Por favor, garanta que está acessível e tente de novo.", - "ErrorMessageStartHourGreaterThanEnd": "A hora de fim deve ser superior à hora de início.", + "ErrorStartHourGreaterThanEnd": "A hora de fim deve ser superior à hora de início.", "ErrorDeletingItem": "Ocorreu um erro ao apagar o item do Servidor Jellyfin. Por favor, verifique o acesso de escrita do Servidor Jellyfin à pasta e tente de novo.", "ErrorAddingTunerDevice": "Ocorreu um erro ao adicionar o dispositivo de sintonização. Por favor, garanta que está acessível e tente de novo.", "ErrorAddingXmlTvFile": "Ocorreu um erro ao aceder ao ficheiro XMLTV. Por favor, certifique-se que o ficheiro está acessível e tente de novo.", @@ -915,7 +915,7 @@ "DirectStreamHelp2": "Reprodução direta de um ficheiro requer pouco processamento e não implica perda de qualidade num vídeo.", "DefaultSubtitlesHelp": "As legendas são carregadas com base nas definições por defeito ou forçado nos metadados. As preferências de idioma são consideradas quando existem múltiplas opções disponíveis.", "DefaultMetadataLangaugeDescription": "Estes são os valores por defeito que podem ser customizados para cada uma das bibliotecas.", - "DefaultErrorMessage": "Ocorreu um erro a processar o pedido. Por favor, tente novamente mais tarde.", + "MessageDefaultError": "Ocorreu um erro a processar o pedido. Por favor, tente novamente mais tarde.", "Default": "Por defeito", "DeathDateValue": "Faleceu: {0}", "DatePlayed": "Reproduzido a", @@ -997,12 +997,12 @@ "RepeatOne": "Repetir este", "RepeatMode": "Modo de Repetição", "ServerRestartNeededAfterPluginInstall": "O Servidor Jellyfin necessitará de reiniciar depois de instalar uma extensão.", - "NoPluginConfigurationMessage": "Esta extensão não é configurável.", + "MessageNoPluginConfiguration": "Esta extensão não é configurável.", "MessagePluginInstallDisclaimer": "As extensões desenvolvidas pela comunidade Jellyfin são uma ótima forma de melhorar a experiência de utilização do Jellyfin, adicionando novas funcionalidades e benefícios. Antes de proceder à instalação, tenha em atenção que estas podem alterar determinados comportamentos no Servidor Jellyfin e provocar efeitos como tempos de atualização da Biblioteca mais longos, processamento adicional em segundo plano e estabilidade do sistema reduzida.", "MessagePluginConfigurationRequiresLocalAccess": "Para configurar esta extensão, inicie sessão localmente no servidor.", "MessageInstallPluginFromApp": "Esta extensão deverá ser instalada a partir da aplicação onde tem intenção de a utilizar.", "HeaderPluginInstallation": "Instalação de Extensão", - "PluginInstalledMessage": "A extensão foi instalada com sucesso. O Servidor Jellyfin necessitará de reiniciar para aplicar as alterações.", + "MessagePluginInstalled": "A extensão foi instalada com sucesso. O Servidor Jellyfin necessitará de reiniciar para aplicar as alterações.", "PleaseRestartServerName": "Por favor, reinicie o Servidor Jellyfin - {0}.", "PleaseConfirmPluginInstallation": "Por favor clique em OK para confirmar que leu o conteúdo acima, e que deseja prosseguir com a instalação da extensão.", "PleaseAddAtLeastOneFolder": "Por favor, adicione pelo menos uma pasta a esta Biblioteca, utilizando para isso o botão Adicionar.", @@ -1207,7 +1207,7 @@ "StopRecording": "Parar gravação", "SeriesRecordingScheduled": "Gravação da série agendada.", "Recordings": "Gravações", - "RecordingPathChangeMessage": "Alterar a localização das gravações não irá migrar as gravações existentes da localização atual para a nova. Os ficheiros deverão ser movidos manualmente, se necessário.", + "MessageChangeRecordingPath": "Alterar a localização das gravações não irá migrar as gravações existentes da localização atual para a nova. Os ficheiros deverão ser movidos manualmente, se necessário.", "ManageRecording": "Gerir gravação", "OptionLoginAttemptsBeforeLockout": "Determina quantas falhas de início de sessão são admitidas antes de a conta ser bloqueada.", "OptionList": "Lista", diff --git a/src/strings/pt.json b/src/strings/pt.json index e6d21f584d..0640f82870 100644 --- a/src/strings/pt.json +++ b/src/strings/pt.json @@ -24,7 +24,7 @@ "UserAgentHelp": "Forneça um user-agent HTTP personalizado.", "Unplayed": "Por reproduzir", "Unmute": "Activar som", - "UninstallPluginHeader": "Desinstalar Extensão", + "HeaderUninstallPlugin": "Desinstalar Extensão", "UninstallPluginConfirmation": "Tem a certeza que deseja desinstalar {0}?", "Uniform": "Uniforme", "Tuesday": "Terça", @@ -138,7 +138,7 @@ "Raised": "Alto relevo", "Programs": "Programas", "Producer": "Produtor", - "PluginInstalledMessage": "A extensão foi instalada com sucesso. O Servidor Jellyfin necessitará de reiniciar para aplicar as alterações.", + "MessagePluginInstalled": "A extensão foi instalada com sucesso. O Servidor Jellyfin necessitará de reiniciar para aplicar as alterações.", "PleaseSelectTwoItems": "Por favor seleccione pelo menos dois itens.", "PleaseRestartServerName": "Por favor, reinicie o Servidor Jellyfin - {0}.", "PleaseEnterNameOrId": "Por favor, digite um nome ou Id externo.", @@ -161,7 +161,7 @@ "People": "Pessoas", "PasswordSaved": "Palavra-passe guardada.", "PasswordResetProviderHelp": "Seleccione um provedor de reposição de palavra-passe a ser usado quando um utilizador requisitar uma reposição de palavra-passe", - "PasswordResetHeader": "Redefinir Palavra-Passe", + "HeaderResetPassword": "Redefinir Palavra-Passe", "PasswordResetConfirmation": "Tem a certeza que deseja redefinir a palavra-passe?", "PasswordResetComplete": "A palavra-passe foi redefinida.", "PasswordMatchError": "A palavra-passe e a confirmação devem coincidir.", @@ -678,8 +678,8 @@ "OptionAlbum": "Álbum", "OptionAdminUsers": "Administradores", "OneChannel": "Um canal", - "NoPluginConfigurationMessage": "Esta extensão não é configurável.", - "NoNextUpItemsMessage": "Nenhum encontrado. Comece a ver os seus programas!", + "MessageNoPluginConfiguration": "Esta extensão não é configurável.", + "MessageNoNextUpItems": "Nenhum encontrado. Comece a ver os seus programas!", "News": "Notícias", "NewCollectionNameExample": "Exemplo: Colecção Guerra das Estrelas", "NewCollection": "Nova Colecção", @@ -855,7 +855,7 @@ "EveryNDays": "A cada {0} dias", "ErrorSavingTvProvider": "Ocorreu um erro ao guardar o provedor do serviços de TV. Por favor, garanta que está acessível e tente de novo.", "ErrorPleaseSelectLineup": "Por favor selecione a programação e tente novamente. Se não houver programações disponíveis, verifique se o seu nome de utilizador, senha e código postal estão correctos.", - "ErrorMessageStartHourGreaterThanEnd": "A hora de fim deve ser superior à hora de início.", + "ErrorStartHourGreaterThanEnd": "A hora de fim deve ser superior à hora de início.", "ErrorGettingTvLineups": "Ocorreu um erro ao transferir a programação de TV. Por favor, certifique-se que a sua informação está correcta e tente novamente.", "ErrorDeletingItem": "Ocorreu um erro ao apagar o item do Servidor Jellyfin. Por favor, verifique o acesso de escrita do Servidor Jellyfin à pasta e tente de novo.", "ErrorAddingXmlTvFile": "Ocorreu um erro ao aceder ao ficheiro XmlTV. Por favor, garanta que o ficheiro está acessível e tente de novo.", @@ -919,7 +919,7 @@ "DeleteDeviceConfirmation": "Tem a certeza que deseja remover este dispositivo? Reaparecerá na próxima vez que o utilizador inicie sessão a partir dele.", "Delete": "Remover", "DefaultSubtitlesHelp": "As legendas são carregadas com base nas definições por omissão ou forçado nos metadados. As preferências de idioma são consideradas quando existem múltiplas opções disponíveis.", - "DefaultErrorMessage": "Ocorreu um erro ao processar o pedido. Por favor, tente novamente mais tarde.", + "MessageDefaultError": "Ocorreu um erro ao processar o pedido. Por favor, tente novamente mais tarde.", "Default": "Por omissão", "DeathDateValue": "Faleceu: {0}", "DatePlayed": "Reproduzido a", @@ -1068,7 +1068,7 @@ "ButtonAddImage": "Adicionar Imagem", "ButtonAdd": "Adicionar", "BurnSubtitlesHelp": "Determina se o servidor deve integrar as legendas durante a conversão de vídeo, dependendo do formato da legenda. Evitar a integração de legendas melhora o desempenho do servidor. Selecione Automático para que legendas baseadas em imagem (VOBSUB, PGS, SUB/IDX) e certos formatos ASS/SSA sejam integrados.", - "BrowsePluginCatalogMessage": "Explore as extensões disponíveis no nosso catálogo.", + "MessageBrowsePluginCatalog": "Explore as extensões disponíveis no nosso catálogo.", "Browse": "Explorar", "BoxRear": "Caixa (verso)", "Box": "Caixa", diff --git a/src/strings/ro.json b/src/strings/ro.json index ccb91f0a50..f341a1699d 100644 --- a/src/strings/ro.json +++ b/src/strings/ro.json @@ -117,7 +117,7 @@ "Monday": "Luni", "MoreUsersCanBeAddedLater": "Mai mulți utilizatori pot fi adăugați mai târziu din Tabloul de Bord.", "NewCollectionNameExample": "Exemplu: Star Wars Collection", - "NoNextUpItemsMessage": "Nu s-a gasit nimic. Începe să vizionezi seriale!", + "MessageNoNextUpItems": "Nu s-a gasit nimic. Începe să vizionezi seriale!", "OptionAllowBrowsingLiveTv": "Permite accessul la Live TV", "OptionAllowLinkSharing": "Permite partajarea pe rețelele de socializare", "OptionAllowLinkSharingHelp": "Doar paginile wev ce contin informații despre conținutul media va fi partajat. Fișierele media nu vor fi partajate niciodată pentru public. Partajările sunt limitate ca timp și vor expira după {0} zile.", @@ -275,7 +275,7 @@ "Audio": "Audio", "BoxRear": "Cutie (spate)", "Browse": "Răsfoire", - "BrowsePluginCatalogMessage": "Răsfoiți catalogul de pluginuri pentru a vedea ce este disponibil.", + "MessageBrowsePluginCatalog": "Răsfoiți catalogul de pluginuri pentru a vedea ce este disponibil.", "ButtonAddMediaLibrary": "Adaugă Librărie Media", "ButtonAddServer": "Adaugă Server", "ButtonArrowDown": "Jos", @@ -345,7 +345,7 @@ "DatePlayed": "Data redării", "DeathDateValue": "Mort: {0}", "Default": "Implicit", - "DefaultErrorMessage": "A fost o eroare în procesarea cererii. Vă rugam încercați din nou mai târziu.", + "MessageDefaultError": "A fost o eroare în procesarea cererii. Vă rugam încercați din nou mai târziu.", "DeleteImageConfirmation": "Sigur doriți să ștergeți această imagine?", "ButtonRename": "Redenumește", "ButtonRepeat": "Repetă", @@ -562,7 +562,7 @@ "EnableStreamLoopingHelp": "Activați acestă opțiune dacă fluxurile live conțin doar câteva secunde de date și trebuie solicitate în mod continuu. Activarea acestei opțiuni atunci când nu este necesar poate provoca probleme.", "ErrorAddingListingsToSchedulesDirect": "A apărut o eroare la adăugarea liniei în contul dvs. Schedules Direct. Schedules Direct permite doar un număr limitat de linii pentru fiecare cont. Este posibil să fie nevoie să vă conectați la site-ul web Schedules Direct și să eliminați alte înregistrări din cont înainte de a continua.", "ErrorAddingMediaPathToVirtualFolder": "A apărut o eroare la adăugarea căii de acces la fișierul media. Vă rugăm să vă asigurați că ruta este validă și procesul Jellyfin Server are acces la locația respectivă.", - "ErrorMessageStartHourGreaterThanEnd": "Timpul de oprire trebuie să fie mai mare decât cel de pornire.", + "ErrorStartHourGreaterThanEnd": "Timpul de oprire trebuie să fie mai mare decât cel de pornire.", "ErrorPleaseSelectLineup": "Selectați o linie și încercați din nou. Dacă nu sunt disponibile linii, atunci vă rugăm să verificați dacă numele dvs. de utilizator, parola și codul poștal sunt corecte.", "ExitFullscreen": "Ieșiți din modul ecran complet", "H264CrfHelp": "Factorul de Rată Constantă (CRF) este setarea implicită a calității pentru codificatorul x264. Puteți seta valorile între 0 și 51, unde valorile mai mici ar avea ca rezultat o calitate mai bună (în detrimentul dimensiunilor mai mari de fișiere). Valorile recomandate sunt cuprinse între 18 și 28. Valoarea implicită pentru x264 este 23, deci puteți utiliza acest lucru ca punct de plecare.", @@ -1007,7 +1007,7 @@ "NoSubtitlesHelp": "Subtitrările nu vor fi încărcate în mod implicit. Acestea pot fi însă activate manual în timpul redării.", "NoSubtitles": "Fără", "NoSubtitleSearchResultsFound": "Nici un rezultat găsit.", - "NoPluginConfigurationMessage": "Acest plugin nu are setări de configurat.", + "MessageNoPluginConfiguration": "Acest plugin nu are setări de configurat.", "NoNewDevicesFound": "Nu s-au găsit dispozitive noi. Pentru a adăuga un nou tuner, închideți acest dialog și introduceți informațiile dispozitivului manual.", "No": "Nu", "NextUp": "Urmează", @@ -1239,7 +1239,7 @@ "Refresh": "Reîmprospătează", "Recordings": "Înregistrări", "RecordingScheduled": "Înregistrare programată.", - "RecordingPathChangeMessage": "Modificarea dosarului dvs. de înregistrare nu va migra înregistrările existente din vechea locație la cea nouă. Dacă doriți, trebuie să le mutați manual.", + "MessageChangeRecordingPath": "Modificarea dosarului dvs. de înregistrare nu va migra înregistrările existente din vechea locație la cea nouă. Dacă doriți, trebuie să le mutați manual.", "RecordingCancelled": "Înregistrare anulată.", "RecordSeries": "Înregistrează serialele", "Record": "Înregistrează", @@ -1261,7 +1261,7 @@ "Premiere": "Premieră", "PreferEmbeddedTitlesOverFileNamesHelp": "Aceasta determină titlul afișat implicit atunci când nu sunt disponibile metadate din internet sau metadate locale.", "PreferEmbeddedTitlesOverFileNames": "Preferă titlurile incluse decât numele fișierelor", - "PluginInstalledMessage": "Pluginul a fost instalat cu succes. Jellyfin Server va trebui să fie repornit pentru ca modificările să intre în vigoare.", + "MessagePluginInstalled": "Pluginul a fost instalat cu succes. Jellyfin Server va trebui să fie repornit pentru ca modificările să intre în vigoare.", "PleaseSelectTwoItems": "Vă rugăm să selectați cel puțin două elemente.", "PleaseRestartServerName": "Vă rugăm să reporniți Jellyfin Server - {0}.", "PleaseEnterNameOrId": "Vă rugăm să introduceți un nume sau un ID extern.", @@ -1283,7 +1283,7 @@ "People": "Oameni", "PasswordSaved": "Parolă salvată.", "PasswordResetProviderHelp": "Alegeți un furnizor de resetare a parolei pentru a fi utilizat atunci când acest utilizator solicită o resetare a parolei", - "PasswordResetHeader": "Resetează parola", + "HeaderResetPassword": "Resetează parola", "PasswordResetConfirmation": "Sigur doriți să resetați parola?", "PasswordResetComplete": "Parola a fost resetată.", "PasswordMatchError": "Confirmarea parolei și parola trebuie să corespundă.", @@ -1401,7 +1401,7 @@ "Unrated": "Neevaluat", "Unplayed": "Nerulat", "Unmute": "Activați sunetul", - "UninstallPluginHeader": "Dezinstalați pluginul", + "HeaderUninstallPlugin": "Dezinstalați pluginul", "UninstallPluginConfirmation": "Sigur doriți să dezinstalați {0}?", "Uniform": "Constant", "TvLibraryHelp": "Examinați {0}ghidul de denumire TV{1}.", diff --git a/src/strings/ru.json b/src/strings/ru.json index 0a471bca0c..0ba5eeac27 100644 --- a/src/strings/ru.json +++ b/src/strings/ru.json @@ -53,7 +53,7 @@ "Box": "Коробка", "BoxRear": "Коробка (задняя часть)", "Browse": "Навигация", - "BrowsePluginCatalogMessage": "Просмотрите каталог плагинов, чтобы ознакомиться с имеющимися плагинами.", + "MessageBrowsePluginCatalog": "Просмотрите каталог плагинов, чтобы ознакомиться с имеющимися плагинами.", "BurnSubtitlesHelp": "Определяется, должен ли сервер внедрять субтитры при перекодировании. Избежание этого значительно улучшит производительность. Выберите «Авто» для записи основанных на графике форматов (VOBSUB, PGS, SUB, IDX и др.) и некоторых субтитров ASS или SSA.", "ButtonAdd": "Добавить", "ButtonAddMediaLibrary": "Добавить медиатеку", @@ -163,7 +163,7 @@ "DatePlayed": "Дата воспроизведения", "DeathDateValue": "Дата смерти: {0}", "Default": "По умолчанию", - "DefaultErrorMessage": "Произошла ошибка при обработке запроса. Повторите попытку позже.", + "MessageDefaultError": "Произошла ошибка при обработке запроса. Повторите попытку позже.", "DefaultMetadataLangaugeDescription": "Они являются значениями по умолчанию и могут быть подстроены индивидуально для каждой медиатеки.", "DefaultSubtitlesHelp": "Загрузки субтитров определяются флагами \"По умолчанию\" и \"Форсированные\" во внедрённых метаданных. Языковые настройки учитываются при наличии нескольких опций.", "Delete": "Удалить", @@ -232,7 +232,7 @@ "ErrorAddingXmlTvFile": "Произошла ошибка при доступе к XMLTV-файлу. Убедитесь, что файл существует и повторите попытку.", "ErrorDeletingItem": "Произошла ошибка при удалении элемента с Jellyfin Server. Проверьте, что у Jellyfin Server имеется доступ на запись в медиапапку и повторите попытку.", "ErrorGettingTvLineups": "Произошла ошибка при загрузке списков сопоставления. Убедитесь, что ваши данные правильны и повторите попытку.", - "ErrorMessageStartHourGreaterThanEnd": "Конечное время должно быть позже, чем начальное время.", + "ErrorStartHourGreaterThanEnd": "Конечное время должно быть позже, чем начальное время.", "ErrorPleaseSelectLineup": "Выделите список сопоставления и повторите попытку. Если списков сопоставления не имеется, то проверьте, что ваше имя пользователя, пароль и почтовый код являются верными.", "ErrorSavingTvProvider": "Произошла ошибка при сохранении поставщика ТВ. Убедитесь, что он доступен и повторите попытку.", "EveryNDays": "Каждые {0} дней", @@ -955,8 +955,8 @@ "NextUp": "Очередное", "No": "Нет", "NoNewDevicesFound": "Новых устройств не обнаружено. Чтобы добавить новый тюнер, закройте данный диалог и введите сведения об устройстве вручную.", - "NoNextUpItemsMessage": "Ничего не найдено. Начните смотреть свои ТВ-передачи!", - "NoPluginConfigurationMessage": "В данном плагине нет параметров конфигурирования.", + "MessageNoNextUpItems": "Ничего не найдено. Начните смотреть свои ТВ-передачи!", + "MessageNoPluginConfiguration": "В данном плагине нет параметров конфигурирования.", "NoSubtitleSearchResultsFound": "Результатов не найдено.", "NoSubtitles": "Ничего", "NoSubtitlesHelp": "По умолчанию, субтитры не будут загружаться. Они могут быть все ещё включены вручную во время воспроизведения.", @@ -1114,7 +1114,7 @@ "PasswordMatchError": "Пароль и подтверждение пароля должны совпадать.", "PasswordResetComplete": "Пароль был сброшен.", "PasswordResetConfirmation": "Вы действительно хотите сбросить пароль?", - "PasswordResetHeader": "Сброс пароля", + "HeaderResetPassword": "Сброс пароля", "PasswordSaved": "Пароль был сохранён.", "People": "Люди", "PerfectMatch": "Полное соответствие", @@ -1136,7 +1136,7 @@ "PleaseEnterNameOrId": "Введите название или внешний ID.", "PleaseRestartServerName": "Перезапустите Jellyfin Server - {0}.", "PleaseSelectTwoItems": "Выберите хотя бы два элемента.", - "PluginInstalledMessage": "Плагин установлен успешно. Чтобы изменения вступили в силу, будет необходимо перезапустить Jellyfin Server.", + "MessagePluginInstalled": "Плагин установлен успешно. Чтобы изменения вступили в силу, будет необходимо перезапустить Jellyfin Server.", "PreferEmbeddedTitlesOverFileNames": "Предпочитать внедрённые названия, чем имена файлов", "PreferEmbeddedTitlesOverFileNamesHelp": "Этим определяется отображаемое название по умолчанию, когда нет метаданных с интернета или локальные метаданные недоступны.", "Premiere": "Премьера", @@ -1158,7 +1158,7 @@ "Record": "Записать", "RecordSeries": "Записать сериал", "RecordingCancelled": "Запись отменена.", - "RecordingPathChangeMessage": "Изменение папки для записи не приведёт к переносу существующих записей со старого места на новое. Вам нужно переместить их вручную, если это необходимо.", + "MessageChangeRecordingPath": "Изменение папки для записи не приведёт к переносу существующих записей со старого места на новое. Вам нужно переместить их вручную, если это необходимо.", "RecordingScheduled": "Запись назначена.", "Recordings": "Записи", "Refresh": "Обновить", @@ -1315,7 +1315,7 @@ "TvLibraryHelp": "Просмотрите {0}руководство по именованию передач{1}.", "Uniform": "Однородная", "UninstallPluginConfirmation": "Вы действительно хотите удалить {0}?", - "UninstallPluginHeader": "Удаление плагина", + "HeaderUninstallPlugin": "Удаление плагина", "Unmute": "Вкл. звук", "Unplayed": "Невоспроизведённое", "Unrated": "Без категории", diff --git a/src/strings/sk.json b/src/strings/sk.json index dc754fdff2..760722a9d3 100644 --- a/src/strings/sk.json +++ b/src/strings/sk.json @@ -110,7 +110,7 @@ "DateAdded": "Dátum pridania", "DatePlayed": "Dátum prehrania", "DeathDateValue": "Zomrel/a: {0}", - "DefaultErrorMessage": "Pri spracovaní požiadavky došlo k chybe. Prosím, skúste to neskôr znova.", + "MessageDefaultError": "Pri spracovaní požiadavky došlo k chybe. Prosím, skúste to neskôr znova.", "Delete": "Zmazať", "DeleteDeviceConfirmation": "Ste si istý, že chcete odstrániť toto zariadenie? Objaví sa znovu, keď sa ním používateľ nabudúce prihlási.", "DeleteImage": "Zmazať obrázok", @@ -143,7 +143,7 @@ "EnablePhotos": "Zobraziť fotky", "EndsAtValue": "Končí o {0}", "Episodes": "Epizódy", - "ErrorMessageStartHourGreaterThanEnd": "Čas ukončenia musí byť väčší ako čas štartu.", + "ErrorStartHourGreaterThanEnd": "Čas ukončenia musí byť väčší ako čas štartu.", "EveryNDays": "Každých {0} dní", "ExitFullscreen": "Opustiť celú obrazovku", "ExtraLarge": "Veľmi veľké", @@ -573,8 +573,8 @@ "Next": "Ďalšie", "NextUp": "Nasleduje", "No": "Nie", - "NoNextUpItemsMessage": "Nič nenájdené. Začnite pozerať vaše seriály!", - "NoPluginConfigurationMessage": "Tento zásuvný modul nemá žiadne nastavenia.", + "MessageNoNextUpItems": "Nič nenájdené. Začnite pozerať vaše seriály!", + "MessageNoPluginConfiguration": "Tento zásuvný modul nemá žiadne nastavenia.", "NoSubtitleSearchResultsFound": "Žiadne výsledky.", "NoSubtitles": "Žiadne", "None": "Žiadne", @@ -682,7 +682,7 @@ "PasswordMatchError": "Heslo a potvrdenie hesla sa musia zhodovať.", "PasswordResetComplete": "Heslo bolo obnovené.", "PasswordResetConfirmation": "Naozaj chcete obnoviť heslo?", - "PasswordResetHeader": "Obnoviť heslo", + "HeaderResetPassword": "Obnoviť heslo", "PasswordSaved": "Heslo uložené.", "People": "Ľudia", "PerfectMatch": "Perfektná zhoda", @@ -701,7 +701,7 @@ "PleaseEnterNameOrId": "Prosím, zadajte meno alebo externé ID.", "PleaseRestartServerName": "Prosím reštartujte Jellyfin Server - {0}.", "PleaseSelectTwoItems": "Vyberte prosím aspoň dve položky.", - "PluginInstalledMessage": "Rozšírenie bolo úspešne nainštalované. Je potrebný reštart Jellyfin Server aby sa prejavili zmeny.", + "MessagePluginInstalled": "Rozšírenie bolo úspešne nainštalované. Je potrebný reštart Jellyfin Server aby sa prejavili zmeny.", "Premiere": "Premiéra", "Premieres": "Premiéry", "Previous": "Predchádzajúce", @@ -819,7 +819,7 @@ "Trailers": "Trailery", "Tuesday": "Utorok", "UninstallPluginConfirmation": "Ste si istý, že chcete odinštalovať {0}?", - "UninstallPluginHeader": "Odinštalovať rozšírenie", + "HeaderUninstallPlugin": "Odinštalovať rozšírenie", "Unmute": "Zapnúť zvuk", "Unplayed": "Neprehrané", "Unrated": "Nehodnotené", @@ -1172,7 +1172,7 @@ "ButtonSplit": "Rozdeliť", "ButtonAddImage": "Pridať obrázok", "BurnSubtitlesHelp": "Určuje, či má server vpáliť titulky počas transkódovania videa. Vynechanie tejto možnosti výrazne zvýši výkon. Vyberte možnosť Auto, pokiaľ chcete vpáliť do obrazu titulky v grafickom formáte (VOBSUB, PGS, SUB, IDX, …) a niektoré ASS alebo SSA titulky.", - "BrowsePluginCatalogMessage": "Prehliadnite si náš katalóg dostupných zásuvných modulov.", + "MessageBrowsePluginCatalog": "Prehliadnite si náš katalóg dostupných zásuvných modulov.", "Browse": "Prechádzať", "Blacklist": "Blacklist", "Banner": "Banner", @@ -1215,7 +1215,7 @@ "SelectAdminUsername": "Prosím, vyberte si používateľské meno pre účet administrátora.", "RefreshQueued": "Obnovenie zaradené do fronty.", "RefreshDialogHelp": "Metadáta sa obnovujú na základe nastavení a internetových služieb, ktoré sú povolené v dashboarde Jellyfin Serveru.", - "RecordingPathChangeMessage": "Zmenou priečinku pre nahrávanie sa existujúce nahrávky automaticky nepresunú zo starej lokácie na na novú. Budete ich musieť presunúť ručne, pokiaľ budete chcieť.", + "MessageChangeRecordingPath": "Zmenou priečinku pre nahrávanie sa existujúce nahrávky automaticky nepresunú zo starej lokácie na na novú. Budete ich musieť presunúť ručne, pokiaľ budete chcieť.", "RecordSeries": "Nahrať sériu", "Raised": "Vystupujúce", "QueueAllFromHere": "Všetko odtiaľto zaradiť do fronty", diff --git a/src/strings/sl-si.json b/src/strings/sl-si.json index 16d8472546..fd9dde8302 100644 --- a/src/strings/sl-si.json +++ b/src/strings/sl-si.json @@ -124,7 +124,7 @@ "Box": "Ovitek", "BoxRear": "Ovitek (zadnja stran)", "Browse": "Brskaj", - "BrowsePluginCatalogMessage": "Poiščite razpoložljive dodatke v našem katalogu.", + "MessageBrowsePluginCatalog": "Poiščite razpoložljive dodatke v našem katalogu.", "BurnSubtitlesHelp": "Določi ali naj strežnik vžge podnapise pri prekodiranju videa. Izogibanje temu lahko občutno izboljša delovanje strežnika. Izberite Samodejno za vžig slikovnih formatov podnapisov (VOBSUB, PGS, SUB, IDX, ...) in nekaterih ASS oziroma SSA podnapisov.", "ButtonAdd": "Dodaj", "Photos": "Fotografije", @@ -257,7 +257,7 @@ "DeleteImage": "Izbriši sliko", "Delete": "Izbiši", "DefaultMetadataLangaugeDescription": "To so vaše privzete nastavitve, ki jih lahko spreminjate za posamezno knjižnico.", - "DefaultErrorMessage": "Prišlo je do težave pri obdelavi zahteve. Poskusite ponovno kasneje.", + "MessageDefaultError": "Prišlo je do težave pri obdelavi zahteve. Poskusite ponovno kasneje.", "Default": "Privzeto", "DeathDateValue": "Smrt: {0}", "DatePlayed": "Predvajano", @@ -466,7 +466,7 @@ "EnableStreamLooping": "Samodejno ponavljaj prenose v živo", "DropShadow": "Senca", "EveryNDays": "Vsakih {0} dni", - "ErrorMessageStartHourGreaterThanEnd": "Čas konca mora biti večji od časa začetka.", + "ErrorStartHourGreaterThanEnd": "Čas konca mora biti večji od časa začetka.", "ErrorDeletingItem": "Prišlo je do težave pri brisanju predstavnosti s strežnika. Preverite ali ima Jellyfin strežnik dovoljenje za pisanje v mapi s predstavnostjo in poskusite znova.", "ErrorAddingXmlTvFile": "Prišlo je do težave pri dostopu do XMLTV datoteke. Preverite ali datoteka obstaja in poskusite znova.", "ErrorAddingMediaPathToVirtualFolder": "Prišlo je do težave pri dodajanju poti predstavnosti. Preverite ali je pot veljavna in da ima Jellyfin strežnik dovoljenja za dostop.", @@ -756,7 +756,7 @@ "Small": "Majhno", "SmartSubtitlesHelp": "Podnapisi, ki se ujemajo z želenim jezikom, bodo naloženi, ko je zvok v tujem jeziku.", "SubtitleAppearanceSettingsDisclaimer": "Te nastavitve ne vplivajo na grafične podnapise (PGS, DVD, itd.) ali ASS/SSA podnapise, ki imajo vdelan svoj lasten slog.", - "PluginInstalledMessage": "Dodatek je bil uspešno nameščen. Za uveljavitev sprememb je potreben ponovni zagon Jellyfin strežnika.", + "MessagePluginInstalled": "Dodatek je bil uspešno nameščen. Za uveljavitev sprememb je potreben ponovni zagon Jellyfin strežnika.", "MessageNoMovieSuggestionsAvailable": "Trenutno ni na voljo nobenih predlogov za filme. Začnite gledati in ocenjevati vaše filme, ter se nato vrnite sem in si oglejte predloge.", "LabelSelectFolderGroups": "Samodejno združi vsebine iz spodnjih map v poglede kot so Filmi, Glasba in TV:", "TabPlayback": "Predvajanje", @@ -864,7 +864,7 @@ "PasswordMatchError": "Geslo in potrditev gesla se moreta ujemati.", "PasswordResetComplete": "Geslo je bilo ponastavljeno.", "PasswordResetConfirmation": "Ali ste prepričani, da želite ponastaviti geslo?", - "PasswordResetHeader": "Ponastavi geslo", + "HeaderResetPassword": "Ponastavi geslo", "PasswordResetProviderHelp": "Izberite ponudnika ponastavitve gesla, ki bo uporabljen, ko bo ta uporabnik zahteval ponastavitev gesla", "PasswordSaved": "Geslo shranjeno.", "PerfectMatch": "Popolno ujemanje", @@ -1074,7 +1074,7 @@ "OptionAdminUsers": "Skrbniki", "Option3D": "3D", "NumLocationsValue": "{0} mape", - "NoPluginConfigurationMessage": "Ta dodatek nima nobenih nastavitev.", + "MessageNoPluginConfiguration": "Ta dodatek nima nobenih nastavitev.", "No": "Ne", "News": "Novice", "NewEpisodesOnly": "Samo nove epizode", @@ -1389,7 +1389,7 @@ "TabSeries": "Serije", "TabScheduledTasks": "Načrtovana opravila", "TabResumeSettings": "Nadaljuj", - "UninstallPluginHeader": "Odstrani dodatek", + "HeaderUninstallPlugin": "Odstrani dodatek", "UninstallPluginConfirmation": "Ali ste prepričan, da želite odstraniti {0}?", "ServerRestartNeededAfterPluginInstall": "Po namestitvi dodatka bo potreben ponoven zagon jellyfin strežnika.", "TabResponses": "Odzivi", diff --git a/src/strings/sr.json b/src/strings/sr.json index d1ed50e87b..df90a3c0f8 100644 --- a/src/strings/sr.json +++ b/src/strings/sr.json @@ -70,7 +70,7 @@ "ButtonAddMediaLibrary": "Додај каталог медија", "ButtonAddImage": "Додај слику", "ButtonAdd": "Додај", - "BrowsePluginCatalogMessage": "Претражуј наш каталог доступних додатака", + "MessageBrowsePluginCatalog": "Претражуј наш каталог доступних додатака", "Browse": "Изабери", "BoxRear": "Омот (позади)", "Box": "Омот", diff --git a/src/strings/sv.json b/src/strings/sv.json index dfc0fa6826..f12e7eff47 100644 --- a/src/strings/sv.json +++ b/src/strings/sv.json @@ -45,7 +45,7 @@ "Box": "Omslag", "BoxRear": "Omslag (baksida)", "Browse": "Bläddra", - "BrowsePluginCatalogMessage": "Besök katalogen för att se tillgängliga tillägg.", + "MessageBrowsePluginCatalog": "Besök katalogen för att se tillgängliga tillägg.", "BurnSubtitlesHelp": "Avgör ifall servern ska \"bränna in\" undertexterna under transkodning. Att undvika detta förbättrar prestandan avsevärt. Välj \"Automatisk\" för att bränna bild-baserade format (ex. VOBSUB, PGS, SUB/IDX, ...) och vissa ASS/SSA-undertexter.", "ButtonAdd": "Lägg till", "ButtonAddMediaLibrary": "Lägg till mediabibliotek", @@ -145,7 +145,7 @@ "DatePlayed": "Senast visad", "DeathDateValue": "Död: {0}", "Default": "Standard", - "DefaultErrorMessage": "Ett fel uppstd vid begäran. Försök igen senare.", + "MessageDefaultError": "Ett fel uppstd vid begäran. Försök igen senare.", "DefaultSubtitlesHelp": "Undertexter visas baserat på standardspråk och tvingande undertexter i den inbäddade metadatan. Förvalsspråk kommer väljas när fler val är möjliga.", "Delete": "Ta bort", "DeleteDeviceConfirmation": "Är du säker på att du vill ta bort den här enheten? Den kommer att dyka upp igen nästa gång en användare kopplar upp sig med den.", @@ -208,7 +208,7 @@ "ErrorAddingTunerDevice": "Det gick inte att lågga till den här TV-mottagaren. Säkerställ att den går att nå och försök igen.", "ErrorDeletingItem": "Det gick inte att ta bort det här objektet från Jellyfin-servern. Kontrollera att Jellyfin-servern har skrivrättigheter till media-mappen och försök igen.", "ErrorGettingTvLineups": "Ett fel uppstod vid nedladdningen utav TV-sortimentet. Se till så att uppgifterna stämmer och försök igen.", - "ErrorMessageStartHourGreaterThanEnd": "Sluttiden måste vara senare än starttiden.", + "ErrorStartHourGreaterThanEnd": "Sluttiden måste vara senare än starttiden.", "ErrorPleaseSelectLineup": "Välj en lineup och försök igen. Om inga lineups finns tillgängliga, kolla så att användarnamn, lösenord och postnummer stämmer.", "ErrorSavingTvProvider": "Ett fel uppstod när TV-tjänsten skulle sparas. Se till att den går att nå och försök igen senare.", "EveryNDays": "Var {0}:e dag", @@ -886,8 +886,8 @@ "Next": "Nästa", "No": "Nej", "NoNewDevicesFound": "Inga nya enheter hittades. För att lägga tilll en ny tuner, stäng denna rutan och mata in enhetsinformation manuellt.", - "NoNextUpItemsMessage": "Hittade inget. Sätt igång och titta!", - "NoPluginConfigurationMessage": "Detta tillägg har inga inställningar att konfigurera.", + "MessageNoNextUpItems": "Hittade inget. Sätt igång och titta!", + "MessageNoPluginConfiguration": "Detta tillägg har inga inställningar att konfigurera.", "NoSubtitleSearchResultsFound": "Inga resultat hittades.", "NoSubtitles": "Inga", "NoSubtitlesHelp": "Undertexter kommer inte visas per standard. Det kan fortfarande sättas på manuellt under uppspelning.", @@ -1033,7 +1033,7 @@ "PasswordMatchError": "Lösenordet och bekräftelsen måste överensstämma.", "PasswordResetComplete": "Lösenordet har återställts.", "PasswordResetConfirmation": "Är du säker på att du vill återställa lösenordet?", - "PasswordResetHeader": "Återställ lösenord", + "HeaderResetPassword": "Återställ lösenord", "PasswordSaved": "Lösenordet har sparats.", "People": "Personer", "PerfectMatch": "Perfekt matchning", @@ -1055,7 +1055,7 @@ "PleaseEnterNameOrId": "Ange ett namn eller externt id.", "PleaseRestartServerName": "Vänligen starta om Jellyfin Server - {0}.", "PleaseSelectTwoItems": "Var god välj minst två objekt.", - "PluginInstalledMessage": "Tillägget har installerats. Jellyfin Server behöver startas om för att verkställa ändringarna.", + "MessagePluginInstalled": "Tillägget har installerats. Jellyfin Server behöver startas om för att verkställa ändringarna.", "PreferEmbeddedTitlesOverFileNames": "Föredra inbäddade titlar över filnamnen", "PreferEmbeddedTitlesOverFileNamesHelp": "Det här bestämmer visningstiteln när ingen internet metadata eller lokal metadata finns att tillgå.", "Premiere": "Premiär", @@ -1217,7 +1217,7 @@ "Tuesday": "Tisdag", "TvLibraryHelp": "Läs om {0} namngivningsguide för TV-serier{1}.", "UninstallPluginConfirmation": "Är du säker på att du vill avinstallera {0}?", - "UninstallPluginHeader": "Avinstallera tillägg", + "HeaderUninstallPlugin": "Avinstallera tillägg", "Unmute": "Muting av", "Unplayed": "Inte spelad", "Unrated": "Ej klassad", @@ -1375,7 +1375,7 @@ "SelectAdminUsername": "Vänligen välj ett användarnamn för admin kontot.", "SaveSubtitlesIntoMediaFoldersHelp": "Spara undertexter vid video filer kommer göra det mer enklare att hantera.", "Rewind": "Spola tillbaka", - "RecordingPathChangeMessage": "Ändring av din inspelnings mapp kommer inte migrera existerande inspelningar från gamla platsen till den nya. Du behöver flytta dom manuellt om så önskas.", + "MessageChangeRecordingPath": "Ändring av din inspelnings mapp kommer inte migrera existerande inspelningar från gamla platsen till den nya. Du behöver flytta dom manuellt om så önskas.", "PlaybackData": "Uppspelnings Data", "PasswordResetProviderHelp": "Välj en Lösenords Återställnings Provider att använda när denna användare begär att återställa lösenordet", "OptionThumbCard": "Miniatyr kort", diff --git a/src/strings/tr.json b/src/strings/tr.json index f6ea6c7188..eb89293759 100644 --- a/src/strings/tr.json +++ b/src/strings/tr.json @@ -5,7 +5,7 @@ "AllowRemoteAccess": "Bu Jellyfin sunucusuna uzaktan bağlanmaya izin ver.", "AllowRemoteAccessHelp": "Eğer işaretlenmemişse, bütün uzak bağlantılar bloke edilicek.", "AttributeNew": "Yeni", - "BrowsePluginCatalogMessage": "Mevcut eklentileri görebilmek için eklenti katologuna göz atın.", + "MessageBrowsePluginCatalog": "Mevcut eklentileri görebilmek için eklenti katologuna göz atın.", "ButtonAdd": "Ekle", "ButtonAddUser": "Kullanıcı Ekle", "ButtonArrowRight": "Sağ", @@ -245,7 +245,7 @@ "Thursday": "Perşembe", "Tuesday": "Salı", "UninstallPluginConfirmation": "Kaldırmak İstediginizden Eminmisiniz {0} ?", - "UninstallPluginHeader": "Eklenti Kaldır", + "HeaderUninstallPlugin": "Eklenti Kaldır", "Wednesday": "Çarşamba", "WelcomeToProject": "Jellyfin'ye Hoş Geldiniz!", "Absolute": "Mutlak", @@ -421,7 +421,7 @@ "DatePlayed": "Oynanan tarih", "DeathDateValue": "Öldü: {0}", "Default": "Varsayılan", - "DefaultErrorMessage": "İsteğin işlenmesi sırasında bir hata oluştu. Lütfen daha sonra tekrar deneyiniz.", + "MessageDefaultError": "İsteğin işlenmesi sırasında bir hata oluştu. Lütfen daha sonra tekrar deneyiniz.", "DefaultMetadataLangaugeDescription": "Bunlar varsayılan ayarlarınızdır ve kitaplık bazında özelleştirilebilir.", "DeleteUserConfirmation": "Bu kullanıcıyı silmek istediğinden emin misin?", "Depressed": "Bunalımlı", @@ -538,7 +538,7 @@ "EveryNDays": "Her {0} günde", "ErrorSavingTvProvider": "TV sağlayıcısını kaydederken bir hata oluştu. Lütfen erişilebilir olduğundan emin olun ve tekrar deneyin.", "ErrorPleaseSelectLineup": "Lütfen bir grup seçin ve tekrar deneyin. Hiç bir sıralama yoksa, lütfen kullanıcı adınızın, şifrenizin ve posta kodunuzun doğru olup olmadığını kontrol edin.", - "ErrorMessageStartHourGreaterThanEnd": "Bitiş saati, başlangıç saatinden büyük olmalıdır.", + "ErrorStartHourGreaterThanEnd": "Bitiş saati, başlangıç saatinden büyük olmalıdır.", "ErrorGettingTvLineups": "TV dizilimini indirirken bir hata oluştu. Lütfen bilgilerinizin doğru olduğundan emin olun ve tekrar deneyin.", "ErrorDeletingItem": "Öğe Jellyfin Sunucusundan silinirken bir hata oluştu. Lütfen Jellyfin Server'ın medya klasörüne yazma erişimi olup olmadığını kontrol edin ve tekrar deneyin.", "ErrorAddingXmlTvFile": "XmlTV dosyasına erişilirken bir hata oluştu. Lütfen dosyanın var olduğundan emin olun ve tekrar deneyin.", diff --git a/src/strings/vi.json b/src/strings/vi.json index 4481559761..d4b120c61c 100644 --- a/src/strings/vi.json +++ b/src/strings/vi.json @@ -1,7 +1,7 @@ { "Add": "Thêm", "All": "Tất cả", - "BrowsePluginCatalogMessage": "Duyệt qua các danh mục plugin của chúng tôi để xem các plugin có sẵn.", + "MessageBrowsePluginCatalog": "Duyệt qua các danh mục plugin của chúng tôi để xem các plugin có sẵn.", "ButtonAdd": "Thêm", "ButtonAddUser": "Thêm người dùng", "ButtonCancel": "Thoát", @@ -115,7 +115,7 @@ "TellUsAboutYourself": "Nói cho chúng tôi biết đôi điều về Bạn", "ThisWizardWillGuideYou": "Thủ thuật này sẽ hướng dẫn quá trình cài đặt cho bạn. Để bắt đầu, vui lòng lựa chọn ngôn ngữ bạn ưa thích.", "UninstallPluginConfirmation": "Bạn có chắc muốn gỡ bỏ{0}?", - "UninstallPluginHeader": "Gỡ bỏ Plugin", + "HeaderUninstallPlugin": "Gỡ bỏ Plugin", "AccessRestrictedTryAgainLater": "Truy cập hiện đang bị hạn chế. Hãy thử lại sau.", "AddToCollection": "Thêm vào bộ sưu tập", "Actor": "Diễn viên", @@ -237,7 +237,7 @@ "ButtonSignIn": "Đăng nhập", "ButtonShutdown": "Tắt", "ButtonSettings": "Cài đặt", - "DefaultErrorMessage": "Có lỗi xảy ra trong lúc xử lý yêu cầu của bạn. Xin hãy thử lại sau.", + "MessageDefaultError": "Có lỗi xảy ra trong lúc xử lý yêu cầu của bạn. Xin hãy thử lại sau.", "Default": "Mặc định", "DeathDateValue": "Không hoạt động: {0}", "DatePlayed": "Ngày phát", @@ -405,7 +405,7 @@ "EveryNDays": "Mỗi {0} ngày", "ErrorSavingTvProvider": "Có lỗi xảy ra khi lưu thông tin của nhà cung cấp TV này. Hãy thử lại khi chắc chắn rằng nó có thể truy cập.", "ErrorPleaseSelectLineup": "Hãy chọn một danh sách và thử lại. Nếu không có danh sách nào sẵn sàng, hãy chắc chắn rằng thông tin tài khoản, mật khẩu, và mã bưu điện đều chính xác.", - "ErrorMessageStartHourGreaterThanEnd": "Thời gian kết thúc phải lớn hơn thời gian bắt đầu.", + "ErrorStartHourGreaterThanEnd": "Thời gian kết thúc phải lớn hơn thời gian bắt đầu.", "ErrorGettingTvLineups": "Có lỗi xảy ra khi tải danh sách TV này. Hãy thử lại khi chắc chắn rằng thông tin của bạn chính xác.", "ErrorDeletingItem": "Có lỗi xảy ra khi xoá mục này khỏi máy chủ Jellyfin. Hãy thử lại sau khi kiểm tra chắc chắn rằng máy chủ Jellyfin có quyền ghi/xoá vào thư mục nội dung.", "ErrorAddingXmlTvFile": "Có lỗi xảy ra khi truy cập tài liệu XMLTV. Hãy thử lại khi chắc chắn rằng tài liệu này tồn tại.", diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index c496ab54d0..b593772f9a 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -47,7 +47,7 @@ "BookLibraryHelp": "现已支持音频和文本书籍。浏览{0}有声读物命名指南{1}。", "Books": "书籍", "Browse": "浏览", - "BrowsePluginCatalogMessage": "浏览我们的插件目录来查看现有插件。", + "MessageBrowsePluginCatalog": "浏览我们的插件目录来查看现有插件。", "BurnSubtitlesHelp": "服务器在转换视频时是否应压制字幕。避免压制字幕会提高服务器性能。选择“自动”以压制基于图像的字幕格式(如 VOBSUB, PGS, SUB, IDX 等)和一些复杂的 ASS/SSA 字幕。", "ButtonAdd": "添加", "ButtonAddMediaLibrary": "添加媒体库", @@ -148,7 +148,7 @@ "DatePlayed": "播放日期", "DeathDateValue": "去世:{0}", "Default": "默认", - "DefaultErrorMessage": "处理请求时发生错误。请稍后尝试。", + "MessageDefaultError": "处理请求时发生错误。请稍后尝试。", "DefaultMetadataLangaugeDescription": "这些是你的默认设置并且可以在你的每个媒体库中被单独自定义。", "DefaultSubtitlesHelp": "字幕将基于内嵌元数据中的“默认”标志和“强制”标志来载入。当多个选项可用时,将根据语言偏好决定。", "Delete": "删除", @@ -211,7 +211,7 @@ "ErrorAddingTunerDevice": "添加协调器设备时发生错误。请确认它是可访问的然后再试一次。", "ErrorAddingXmlTvFile": "访问 XmlTV 文件时发生错误。请确认该文件是否存在然后再试一次。", "ErrorGettingTvLineups": "下载 TV 节目表 时发生错误。请确认你的信息是否正确,然后再试。", - "ErrorMessageStartHourGreaterThanEnd": "结束时间必须在开始时间后。", + "ErrorStartHourGreaterThanEnd": "结束时间必须在开始时间后。", "ErrorPleaseSelectLineup": "请选择一个阵容, 然后再试一次。如果没有可用的阵容, 请检查您的用户名、密码和邮政编码是否正确。", "ErrorSavingTvProvider": "保存 TV 提供商时发生错误。请确认它是可访问的然后再试一次。", "EveryNDays": "每 {0} 天", @@ -907,8 +907,8 @@ "NextUp": "下一步", "No": "否", "NoNewDevicesFound": "找不到新设备。要添加新调谐器, 请关闭此对话框并手动输入设备信息。", - "NoNextUpItemsMessage": "没有发现。开始看你的节目!", - "NoPluginConfigurationMessage": "此插件没有配置选项。", + "MessageNoNextUpItems": "没有发现。开始看你的节目!", + "MessageNoPluginConfiguration": "此插件没有配置选项。", "NoSubtitleSearchResultsFound": "未找到结果。", "NoSubtitles": "无字幕", "NoSubtitlesHelp": "字幕将默认不被加载,但你仍然可以在播放时手动打开字幕。", @@ -1068,7 +1068,7 @@ "PasswordMatchError": "密码和确认密码必须匹配。", "PasswordResetComplete": "密码已重置。", "PasswordResetConfirmation": "你确定要重置密码?", - "PasswordResetHeader": "密码重置", + "HeaderResetPassword": "密码重置", "PasswordSaved": "密码已保存。", "People": "人物", "PerfectMatch": "最佳匹配", @@ -1087,7 +1087,7 @@ "PleaseEnterNameOrId": "请输入一个名称或一个外部ID。", "PleaseRestartServerName": "请重启 Jellyfin 服务器 - {0}。", "PleaseSelectTwoItems": "请至少选择2个项目。", - "PluginInstalledMessage": "这个插件已经被成功安装。Jellyfin 服务器需要重启以使该插件生效。", + "MessagePluginInstalled": "这个插件已经被成功安装。Jellyfin 服务器需要重启以使该插件生效。", "PreferEmbeddedTitlesOverFileNames": "优先使用内置的标题而不是文件名", "PreferEmbeddedTitlesOverFileNamesHelp": "这将在没有 internet 元数据或本地元数据可用时确定默认显示标题。", "Premiere": "首映", @@ -1107,7 +1107,7 @@ "Record": "录制", "RecordSeries": "录制电视剧", "RecordingCancelled": "录制已取消。", - "RecordingPathChangeMessage": "更改录制文件夹不会将现有录制从旧位置迁移到新的。您需要手动移动它们 (如果需要)。", + "MessageChangeRecordingPath": "更改录制文件夹不会将现有录制从旧位置迁移到新的。您需要手动移动它们 (如果需要)。", "RecordingScheduled": "录制预设。", "Refresh": "刷新", "RefreshMetadata": "刷新元数据", @@ -1248,7 +1248,7 @@ "Tuesday": "星期二", "TvLibraryHelp": "回顾{0}电视节目命名指南{1}。", "UninstallPluginConfirmation": "你确定要卸载 {0}?", - "UninstallPluginHeader": "卸载插件", + "HeaderUninstallPlugin": "卸载插件", "Unmute": "取消静音", "Unplayed": "未播放", "Unrated": "未分级", diff --git a/src/strings/zh-hk.json b/src/strings/zh-hk.json index b52dcbc1ef..da68975e7d 100644 --- a/src/strings/zh-hk.json +++ b/src/strings/zh-hk.json @@ -186,7 +186,7 @@ "MoreUsersCanBeAddedLater": "稍後在控制台可以添加更多用戶。", "NewCollection": "新收藏庫", "NewCollectionNameExample": "例如:星球大戰收藏庫", - "NoNextUpItemsMessage": "未有發現。開始欣賞您的節目!", + "MessageNoNextUpItems": "未有發現。開始欣賞您的節目!", "OptionAdminUsers": "管理員", "OptionAlbum": "唱片", "OptionAlbumArtist": "唱片歌手", @@ -419,7 +419,7 @@ "DeleteMedia": "刪除媒體", "DeleteImageConfirmation": "你確定要刪除此圖片嗎?", "DeleteImage": "刪除圖片", - "DefaultErrorMessage": "處理此請求時發生錯誤,請稍後再嘗試。", + "MessageDefaultError": "處理此請求時發生錯誤,請稍後再嘗試。", "Default": "預設", "DateAdded": "日期已新增", "CopyStreamURLError": "複製URL時發生錯誤。", @@ -499,7 +499,7 @@ "ButtonSyncPlay": "SyncPlay", "ButtonDown": "向下", "BurnSubtitlesHelp": "確定若服務器對視頻進行轉碼時是否嵌入字幕。 關閉這功能將使用更少時間。 選擇'自動'可嵌入基於圖像的格式字幕(VOBSUB,PGS,SUB,IDX等)和某些ASS或SSA字幕。", - "BrowsePluginCatalogMessage": "瀏覽我們的插件目錄以查看可用的插件。", + "MessageBrowsePluginCatalog": "瀏覽我們的插件目錄以查看可用的插件。", "BoxRear": "盒裝(背面)", "BoxSet": "套裝", "Box": "盒裝", diff --git a/src/strings/zh-tw.json b/src/strings/zh-tw.json index 22a40d3247..e8a05e081e 100644 --- a/src/strings/zh-tw.json +++ b/src/strings/zh-tw.json @@ -3,7 +3,7 @@ "All": "全部", "AllowRemoteAccessHelp": "如果未勾選,所有連線都將被阻擋。", "Browse": "瀏覽", - "BrowsePluginCatalogMessage": "瀏覽我們的模組目錄來查看可用的模組。", + "MessageBrowsePluginCatalog": "瀏覽我們的模組目錄來查看可用的模組。", "ButtonAdd": "新增", "ButtonAddServer": "新增伺服器", "ButtonAddUser": "新增使用者", @@ -160,7 +160,7 @@ "NewCollection": "新合集", "NewCollectionHelp": "收藏櫃讓您能夠建立個人化的影音及其他媒體的分類。", "NewCollectionNameExample": "例子:星球大戰合集", - "NoNextUpItemsMessage": "沒有找到。開始看你的節目!", + "MessageNoNextUpItems": "沒有找到。開始看你的節目!", "NoSubtitleSearchResultsFound": "無結果。", "OptionAlbum": "專輯", "OptionAlbumArtist": "專輯歌手", @@ -290,7 +290,7 @@ "TrackCount": "{0} 個曲目", "Tuesday": "星期二", "UninstallPluginConfirmation": "你確定要解除安裝 {0}?", - "UninstallPluginHeader": "解除安裝插件", + "HeaderUninstallPlugin": "解除安裝插件", "UserProfilesIntro": "Jellyfin 可單獨對使用者進行設定,所有使用者擁有自己的顯示設置,播放狀態和家長控制。", "Wednesday": "星期三", "WelcomeToProject": "歡迎使用 Jellyfin!", @@ -421,7 +421,7 @@ "ColorSpace": "色彩空間", "ColorTransfer": "色彩傳輸", "CommunityRating": "社群評分", - "DefaultErrorMessage": "處理請求時發生錯誤。請稍後再試。", + "MessageDefaultError": "處理請求時發生錯誤。請稍後再試。", "DefaultMetadataLangaugeDescription": "這些預設設定可以在你的媒體庫中單獨設定。", "DefaultSubtitlesHelp": "字幕將基於中繼資料中的「預設」標記和「強制」標記來載入,當有多個選項可用時,將根據語言偏好決定。", "DeleteDeviceConfirmation": "你確定你要刪除這個裝置嗎?當有使用者用這個裝置登入時,這個裝置會再次出現。", @@ -479,7 +479,7 @@ "ErrorAddingXmlTvFile": "存取 XMLTV 檔案時發生錯誤,請確認該檔案是否存在後再試一次。", "ErrorDeletingItem": "從 Jellyfin 伺服器刪除項目時發生錯誤,請確認伺服器對該磁碟有寫入權限並再試一次。", "ErrorGettingTvLineups": "下載電視節目表時發生錯誤,請確認你的資訊是否正確並重試。", - "ErrorMessageStartHourGreaterThanEnd": "結束時間必須在開始時間後。", + "ErrorStartHourGreaterThanEnd": "結束時間必須在開始時間後。", "ErrorPleaseSelectLineup": "請選擇節目表,然後再試一次。如果沒有可用的節目表,請檢查您的使用者名稱、密碼和郵遞區號是否正確。", "ErrorSavingTvProvider": "儲存電視供應商時發生錯誤,請確認是否可存取並重試。", "EveryNDays": "每 {0} 天", @@ -824,7 +824,7 @@ "ThemeSongs": "主題曲", "ThemeVideos": "主題曲影片", "Upload": "上傳", - "PasswordResetHeader": "重設密碼", + "HeaderResetPassword": "重設密碼", "ScanLibrary": "掃描媒體庫", "ValueAudioCodec": "音訊編碼:{0}", "ValueCodec": "編碼:{0}", @@ -993,7 +993,7 @@ "MediaInfoStreamTypeVideo": "影片", "Menu": "選單", "MetadataManager": "中繼資料管理器", - "NoPluginConfigurationMessage": "這個模組沒有設定選項可供更改。", + "MessageNoPluginConfiguration": "這個模組沒有設定選項可供更改。", "NoSubtitlesHelp": "字幕不會自動讀取,但可於播放時手動選取。", "Normal": "正常", "OptionAllowContentDownloading": "允許下載及同步媒體", @@ -1303,8 +1303,8 @@ "OptionIgnoreTranscodeByteRangeRequestsHelp": "如果啟用,這些請求會被兌現,但會忽略的位元組範圍標頭。", "OptionLoginAttemptsBeforeLockoutHelp": "若值為 0,則表示將允許普通使用者嘗試三次、管理員嘗試五次的預設值,設定為 -1 來停用此功能。", "OptionRequirePerfectSubtitleMatchHelp": "僅下載經過測試並確認跟此影片檔案完美匹配的字幕。取消勾選這個項目可以增加找到並下載字幕的可能性,但可能會下載時間軸、翻譯不正確的字幕。", - "PluginInstalledMessage": "這個模組安裝成功,但 Jellyfin 伺服器需要重啟以使模組生效。", - "RecordingPathChangeMessage": "更改錄製資料夾不會將現有錄製從舊位置遷移到新的,您需要手動移動它們。", + "MessagePluginInstalled": "這個模組安裝成功,但 Jellyfin 伺服器需要重啟以使模組生效。", + "MessageChangeRecordingPath": "更改錄製資料夾不會將現有錄製從舊位置遷移到新的,您需要手動移動它們。", "LabelEmbedAlbumArtDidl": "於 Didl 中嵌入專輯封面", "LabelEnableAutomaticPortMapHelp": "透過 UPnP 自動將路由器上的公共埠轉發到伺服器上的本地埠。這可能不適用於某些路由器型號或網路設定。在伺服器重新啟動後才會進行更改。", "LabelEmbedAlbumArtDidlHelp": "有些裝置使用這個方式來取得專輯封面,啟用這個選項可能導致其他設備播放失敗。", diff --git a/src/tv.html b/src/tv.html index ceb5c51b44..035f1db6a3 100644 --- a/src/tv.html +++ b/src/tv.html @@ -31,7 +31,7 @@
- +
From 1811c7d5f68ab68848144a96eede302dac2f4785 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 1 Aug 2020 00:21:25 +0900 Subject: [PATCH 037/226] revert accidental string change --- src/strings/en-us.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/en-us.json b/src/strings/en-us.json index ea190351ce..76e5fe22ee 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1366,7 +1366,7 @@ "SearchResults": "Search Results", "Season": "Season", "SelectAdminUsername": "Please select a username for the admin account.", - "Send": "Send ", + "SendMessage": "Send message", "Series": "Series", "SeriesCancelled": "Series cancelled.", "SeriesDisplayOrderHelp": "Order episodes by air date, DVD order, or absolute numbering.", From f163f83dae6fa7e3153d61fb41684ea183385918 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 1 Aug 2020 00:24:53 +0900 Subject: [PATCH 038/226] fix another minor string issue --- src/strings/en-us.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 76e5fe22ee..aa07591079 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1326,7 +1326,7 @@ "Record": "Record", "RecordSeries": "Record series", "RecordingCancelled": "Recording cancelled.", - "ChangeRecordingPath": "Changing your recording folder will not migrate existing recordings from the old location to the new. You'll need to move them manually if desired.", + "MessageChangeRecordingPath": "Changing your recording folder will not migrate existing recordings from the old location to the new. You'll need to move them manually if desired.", "RecordingScheduled": "Recording scheduled.", "Recordings": "Recordings", "Refresh": "Refresh", From 39627f364a52bd1103ca72496a3a3a4e1fd0340e Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 16:12:49 +0100 Subject: [PATCH 039/226] Migration of tabbedview to ES6 module --- package.json | 1 + src/components/tabbedview/tabbedview.js | 60 +++++++++++++------------ 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index 2fd4b90ce5..07ac3f4b54 100644 --- a/package.json +++ b/package.json @@ -158,6 +158,7 @@ "src/components/syncPlay/playbackPermissionManager.js", "src/components/syncPlay/syncPlayManager.js", "src/components/syncPlay/timeSyncManager.js", + "src/components/tabbedview/tabbedview.js", "src/controllers/session/addServer/index.js", "src/controllers/session/forgotPassword/index.js", "src/controllers/session/redeemPassword/index.js", diff --git a/src/components/tabbedview/tabbedview.js b/src/components/tabbedview/tabbedview.js index 8bd3afd372..710a0e3c40 100644 --- a/src/components/tabbedview/tabbedview.js +++ b/src/components/tabbedview/tabbedview.js @@ -1,30 +1,33 @@ -define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function (backdrop, mainTabsManager, layoutManager) { - 'use strict'; +import backdrop from 'backdrop'; +import * as mainTabsManager from 'mainTabsManager'; +import layoutManager from 'layoutManager'; +import 'emby-tabs'; - function onViewDestroy(e) { - var tabControllers = this.tabControllers; +function onViewDestroy(e) { + var tabControllers = this.tabControllers; - if (tabControllers) { - tabControllers.forEach(function (t) { - if (t.destroy) { - t.destroy(); - } - }); + if (tabControllers) { + tabControllers.forEach(function (t) { + if (t.destroy) { + t.destroy(); + } + }); - this.tabControllers = null; - } - - this.view = null; - this.params = null; - this.currentTabController = null; - this.initialTabIndex = null; + this.tabControllers = null; } - function onBeforeTabChange() { + this.view = null; + this.params = null; + this.currentTabController = null; + this.initialTabIndex = null; +} - } +function onBeforeTabChange() { - function TabbedView(view, params) { +} + +class TabbedView { + constructor(view, params) { this.tabControllers = []; this.view = view; this.params = params; @@ -85,7 +88,7 @@ define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function ( view.addEventListener('viewdestroy', onViewDestroy.bind(this)); } - TabbedView.prototype.onResume = function (options) { + onResume(options) { this.setTitle(); backdrop.clearBackdrop(); @@ -96,19 +99,18 @@ define(['backdrop', 'mainTabsManager', 'layoutManager', 'emby-tabs'], function ( } else if (currentTabController && currentTabController.onResume) { currentTabController.onResume({}); } - }; + } - TabbedView.prototype.onPause = function () { + onPause() { var currentTabController = this.currentTabController; if (currentTabController && currentTabController.onPause) { currentTabController.onPause(); } - }; - - TabbedView.prototype.setTitle = function () { + } + setTitle() { Emby.Page.setTitle(''); - }; + } +} - return TabbedView; -}); +export default TabbedView; From 38d25172d5def42c19de33153fed8e7accaee286 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 17:06:04 +0100 Subject: [PATCH 040/226] Fix type and applysuggestions to home.js --- .../dashboard/plugins/available/index.js | 2 +- .../dashboard/plugins/installed/index.js | 2 +- src/controllers/home.js | 98 +++++++++---------- src/controllers/itemDetails/index.js | 2 +- src/controllers/movies/moviesrecommended.js | 2 +- 5 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/controllers/dashboard/plugins/available/index.js b/src/controllers/dashboard/plugins/available/index.js index 473b1b8961..274cde8824 100644 --- a/src/controllers/dashboard/plugins/available/index.js +++ b/src/controllers/dashboard/plugins/available/index.js @@ -1,7 +1,7 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby-checkbox', 'emby-select'], function (loading, libraryMenu, globalize) { 'use strict'; - libraryMenu = LibraryMenu.default || libraryMenu; + libraryMenu = libraryMenu.default || libraryMenu; function reloadList(page) { loading.show(); diff --git a/src/controllers/dashboard/plugins/installed/index.js b/src/controllers/dashboard/plugins/installed/index.js index 014fbf16c2..02fd954620 100644 --- a/src/controllers/dashboard/plugins/installed/index.js +++ b/src/controllers/dashboard/plugins/installed/index.js @@ -1,7 +1,7 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'], function (loading, libraryMenu, dom, globalize) { 'use strict'; - libraryMenu = LibraryMenu.default || libraryMenu; + libraryMenu = libraryMenu.default || libraryMenu; function deletePlugin(page, uniqueid, name) { var msg = globalize.translate('UninstallPluginConfirmation', name); diff --git a/src/controllers/home.js b/src/controllers/home.js index 392da0e2d2..bfee2c50fb 100644 --- a/src/controllers/home.js +++ b/src/controllers/home.js @@ -4,67 +4,65 @@ import 'emby-tabs'; import 'emby-button'; import 'emby-scroller'; -function getTabs() { - return [{ - name: globalize.translate('Home') - }, { - name: globalize.translate('Favorites') - }]; -} - -function getDefaultTabIndex() { - return 0; -} - -function getTabController(index) { - if (null == index) { - throw new Error('index cannot be null'); - } - - let depends = ''; - - switch (index) { - case 0: - depends = 'controllers/hometab'; - break; - - case 1: - depends = 'controllers/favorites'; - } - - const instance = this; - return import(depends).then(({ default: controllerFactory }) => { - let controller = instance.tabControllers[index]; - - if (!controller) { - controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params); - instance.tabControllers[index] = controller; - } - - return controller; - }); -} - -class HomeView { +class HomeView extends TabbedView { constructor(view, params) { - TabbedView.call(this, view, params); + super(view, params); } + setTitle() { Emby.Page.setTitle(null); } + onPause() { - TabbedView.prototype.onPause.call(this); + super.onPause(this); document.querySelector('.skinHeader').classList.remove('noHomeButtonHeader'); } + onResume(options) { - TabbedView.prototype.onResume.call(this, options); + super.onResume(this, options); document.querySelector('.skinHeader').classList.add('noHomeButtonHeader'); } + + getDefaultTabIndex() { + return 0; + } + + getTabs() { + return [{ + name: globalize.translate('Home') + }, { + name: globalize.translate('Favorites') + }]; + } + + getTabController(index) { + if (null == index) { + throw new Error('index cannot be null'); + } + + let depends = ''; + + switch (index) { + case 0: + depends = 'controllers/hometab'; + break; + + case 1: + depends = 'controllers/favorites'; + } + + const instance = this; + return import(depends).then(({ default: controllerFactory }) => { + let controller = instance.tabControllers[index]; + + if (!controller) { + controller = new controllerFactory(instance.view.querySelector(".tabContent[data-index='" + index + "']"), instance.params); + instance.tabControllers[index] = controller; + } + + return controller; + }); + } } -Object.assign(HomeView.prototype, TabbedView.prototype); -HomeView.prototype.getTabs = getTabs; -HomeView.prototype.getDefaultTabIndex = getDefaultTabIndex; -HomeView.prototype.getTabController = getTabController; - export default HomeView; diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index 49412c4ac4..d02268b9d4 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -1,7 +1,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSettings', 'cardBuilder', 'datetime', 'mediaInfo', 'backdrop', 'listView', 'itemContextMenu', 'itemHelper', 'dom', 'indicators', 'imageLoader', 'libraryMenu', 'globalize', 'browser', 'events', 'playbackManager', 'scrollStyles', 'emby-itemscontainer', 'emby-checkbox', 'emby-button', 'emby-playstatebutton', 'emby-ratingbutton', 'emby-scroller', 'emby-select'], function (loading, appRouter, layoutManager, connectionManager, userSettings, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, dom, indicators, imageLoader, libraryMenu, globalize, browser, events, playbackManager) { 'use strict'; - libraryMenu = LibraryMenu.default || libraryMenu; + libraryMenu = libraryMenu.default || libraryMenu; function getPromise(apiClient, params) { var id = params.id; diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js index 96e98452db..09ecd3c034 100644 --- a/src/controllers/movies/moviesrecommended.js +++ b/src/controllers/movies/moviesrecommended.js @@ -1,7 +1,7 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu', 'mainTabsManager', 'cardBuilder', 'dom', 'imageLoader', 'playbackManager', 'globalize', 'emby-scroller', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager, globalize) { 'use strict'; - libraryMenu = LibraryMenu.default || libraryMenu; + libraryMenu = libraryMenu.default || libraryMenu; function enableScrollX() { return !layoutManager.desktop; From 889b9a3d738324cca79c6173f4957bd551d56e3b Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 1 Aug 2020 01:26:45 +0900 Subject: [PATCH 041/226] update a few more strings --- .../displaySettings.template.html | 4 +- src/strings/bg-bg.json | 4 +- src/strings/cs.json | 4 +- src/strings/de.json | 4 +- src/strings/en-gb.json | 4 +- src/strings/en-us.json | 78 +++++++++---------- src/strings/es-ar.json | 4 +- src/strings/es-mx.json | 4 +- src/strings/es.json | 4 +- src/strings/es_419.json | 4 +- src/strings/fa.json | 4 +- src/strings/fr.json | 4 +- src/strings/hu.json | 4 +- src/strings/it.json | 4 +- src/strings/nb.json | 4 +- src/strings/nl.json | 4 +- src/strings/pl.json | 4 +- src/strings/pt-br.json | 4 +- src/strings/ro.json | 4 +- src/strings/ru.json | 4 +- src/strings/sk.json | 4 +- src/strings/sv.json | 4 +- src/strings/zh-cn.json | 4 +- src/strings/zh-tw.json | 4 +- 24 files changed, 85 insertions(+), 85 deletions(-) diff --git a/src/components/displaySettings/displaySettings.template.html b/src/components/displaySettings/displaySettings.template.html index ab01b4b6ae..7258edf208 100644 --- a/src/components/displaySettings/displaySettings.template.html +++ b/src/components/displaySettings/displaySettings.template.html @@ -159,9 +159,9 @@
-
${EnableBlurhashHelp}
+
${EnableBlurHashHelp}
diff --git a/src/strings/bg-bg.json b/src/strings/bg-bg.json index 3afd904af3..ccdc906a9f 100644 --- a/src/strings/bg-bg.json +++ b/src/strings/bg-bg.json @@ -1197,8 +1197,8 @@ "LabelProtocolInfo": "Информация за протокола:", "LabelPostProcessorArgumentsHelp": "Използвай {path},като път за записване на файла.", "LabelPostProcessorArguments": "Аргументи на командния ред след обработка:", - "EnableBlurhashHelp": "Изображенията, които все още се зареждат, ще се показват чрез функцията\"размито запълване\"", - "EnableBlurhash": "Активиране на функцията \"размито запълване\" за изображения", + "EnableBlurHashHelp": "Изображенията, които все още се зареждат, ще се показват чрез функцията\"размито запълване\"", + "EnableBlurHash": "Активиране на функцията \"размито запълване\" за изображения", "UnsupportedPlayback": "Джелифин не може да дешифрира съдържание, защитено с DRM, но въпреки това цялото съдържание ще бъде обработено, включително защитените заглавия. Някои файлове могат да изглеждат напълно черни поради криптиране или други неподдържани функции, например интерактивни заглавия.", "OnApplicationStartup": "При стартиране на приложението", "EveryXHours": "На всеки {0} часа", diff --git a/src/strings/cs.json b/src/strings/cs.json index c00b177548..13ce07b62d 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -1543,8 +1543,8 @@ "EnableDetailsBanner": "Obrázek detailu", "ShowMore": "Zobrazit více", "ShowLess": "Zobrazit méně", - "EnableBlurhashHelp": "Nenačtené obrázky budou zobrazeny pomocí neurčitých zástupných obrázků", - "EnableBlurhash": "Povolit zástupné obrázky", + "EnableBlurHashHelp": "Nenačtené obrázky budou zobrazeny pomocí neurčitých zástupných obrázků", + "EnableBlurHash": "Povolit zástupné obrázky", "ButtonCast": "Přehrát v zařízení", "ButtonSyncPlay": "SyncPlay", "MessageNoGenresAvailable": "Povolit některým poskytovatelům metadat stahovat informace o žánrech z Internetu.", diff --git a/src/strings/de.json b/src/strings/de.json index 0c25bb9c29..f88361c1d2 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -1543,8 +1543,8 @@ "EnableDetailsBanner": "Detailbanner", "ShowMore": "Mehr anzeigen", "ShowLess": "Weniger anzeigen", - "EnableBlurhashHelp": "Bilder, die noch nicht fertig geladen wurden, werden mit einem verschwommenen Platzhalter dargestellt", - "EnableBlurhash": "Verschwommene Platzhalter für Bilder erlauben", + "EnableBlurHashHelp": "Bilder, die noch nicht fertig geladen wurden, werden mit einem verschwommenen Platzhalter dargestellt", + "EnableBlurHash": "Verschwommene Platzhalter für Bilder erlauben", "EnableFasterAnimations": "Schnellere Animationen", "EnableDecodingColorDepth10Vp9": "Aktiviere 10-Bit-Hardware-Dekodierung für VP9", "EnableDecodingColorDepth10Hevc": "Aktiviere 10-Bit-Hardware-Dekodierung für HEVC", diff --git a/src/strings/en-gb.json b/src/strings/en-gb.json index 43269a507f..58bd67426e 100644 --- a/src/strings/en-gb.json +++ b/src/strings/en-gb.json @@ -1501,8 +1501,8 @@ "ApiKeysCaption": "List of the currently enabled API keys", "ButtonCast": "Cast", "ButtonSyncPlay": "SyncPlay", - "EnableBlurhashHelp": "Images that are still being loaded will be displayed with a blurred placeholder", - "EnableBlurhash": "Enable blurred placeholders for images", + "EnableBlurHashHelp": "Images that are still being loaded will be displayed with a blurred placeholder", + "EnableBlurHash": "Enable blurred placeholders for images", "TabDVR": "DVR", "TabRepositories": "Repositories", "SyncPlayAccessHelp": "Select the level of access this user has to the SyncPlay feature. SyncPlay enables to sync playback with other devices.", diff --git a/src/strings/en-us.json b/src/strings/en-us.json index aa07591079..f0e24d63ab 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -45,7 +45,7 @@ "AspectRatio": "Aspect Ratio", "AttributeNew": "New", "Audio": "Audio", - "AuthProviderHelp": "Select an Authentication Provider to be used to authenticate this user's password.", + "AuthProviderHelp": "Select an authentication provider to be used to authenticate this user's password.", "Auto": "Auto", "AutoBasedOnLanguageSetting": "Auto (based on language setting)", "Backdrop": "Backdrop", @@ -195,8 +195,8 @@ "DetectingDevices": "Detecting devices", "DeviceAccessHelp": "This only applies to devices that can be uniquely identified and will not prevent browser access. Filtering user device access will prevent them from using new devices until they've been approved here.", "DirectPlaying": "Direct playing", - "DirectStreamHelp1": "The media is compatible with the device regarding resolution and media type (H.264, AC3, etc), but is in an incompatible file container (mkv, avi, wmv, etc). The video will be re-packaged on the fly before streaming it to the device.", - "DirectStreamHelp2": "Direct Streaming a file uses very little processing power without any loss in video quality.", + "DirectStreamHelp1": "The media is compatible with the device regarding resolution and media type (H.264, AC3, etc), but in an incompatible file container (mkv, avi, wmv, etc). The video will be re-packaged on the fly before being sent to the device.", + "DirectStreamHelp2": "Direct stream uses very little processing power with a minimal loss in video quality.", "DirectStreaming": "Direct streaming", "Director": "Director", "Directors": "Directors", @@ -313,7 +313,7 @@ "HeaderAllowMediaDeletionFrom": "Allow Media Deletion From", "HeaderApiKey": "API Key", "HeaderApiKeys": "API Keys", - "HeaderApiKeysHelp": "External applications are required to have an API key in order to communicate with Jellyfin Server. Keys are issued by logging in with a Jellyfin account, or by manually granting the application a key.", + "HeaderApiKeysHelp": "External applications are required to have an API key in order to communicate with the server. Keys are issued by logging in with a normal user account or manually granting the application a key.", "ApiKeysCaption": "List of the currently enabled API keys", "HeaderApp": "App", "HeaderAppearsOn": "Appears On", @@ -400,7 +400,7 @@ "HeaderItems": "Items", "HeaderKeepRecording": "Keep Recording", "HeaderKeepSeries": "Keep Series", - "HeaderKodiMetadataHelp": "To enable or disable NFO metadata, edit a library in Jellyfin library setup and locate the metadata savers section.", + "HeaderKodiMetadataHelp": "To enable or disable NFO metadata, edit a library and locate the metadata savers section.", "HeaderLatestEpisodes": "Latest Episodes", "HeaderLatestMedia": "Latest Media", "HeaderLatestMovies": "Latest Movies", @@ -450,7 +450,7 @@ "HeaderPreferredMetadataLanguage": "Preferred Metadata Language", "HeaderProfile": "Profile", "HeaderProfileInformation": "Profile Information", - "HeaderProfileServerSettingsHelp": "These values control how Jellyfin Server will present itself to the device.", + "HeaderProfileServerSettingsHelp": "These values control how the server will present itself to clients.", "HeaderRecentlyPlayed": "Recently Played", "HeaderRecordingOptions": "Recording Options", "HeaderRecordingPostProcessing": "Recording Post Processing", @@ -469,13 +469,13 @@ "HeaderSecondsValue": "{0} Seconds", "HeaderSelectCertificatePath": "Select Certificate Path", "HeaderSelectMetadataPath": "Select Metadata Path", - "HeaderSelectMetadataPathHelp": "Browse or enter the path you'd like to store metadata within. The folder must be writeable.", + "HeaderSelectMetadataPathHelp": "Browse or enter the path you'd like to use for metadata. The folder must be writeable.", "HeaderSelectPath": "Select Path", "HeaderSelectServer": "Select Server", "HeaderSelectServerCachePath": "Select Server Cache Path", "HeaderSelectServerCachePathHelp": "Browse or enter the path to use for server cache files. The folder must be writeable.", "HeaderSelectTranscodingPath": "Select Transcoding Temporary Path", - "HeaderSelectTranscodingPathHelp": "Browse or enter the path to use for transcoding temporary files. The folder must be writeable.", + "HeaderSelectTranscodingPathHelp": "Browse or enter the path to use for transcode files. The folder must be writeable.", "HeaderSendMessage": "Send Message", "HeaderSeries": "Series", "HeaderSeriesOptions": "Series Options", @@ -531,8 +531,8 @@ "HttpsRequiresCert": "To enable secure connections, you will need to supply a trusted SSL certificate, such as Let's Encrypt. Please either supply a certificate, or disable secure connections.", "Identify": "Identify", "Images": "Images", - "ImportFavoriteChannelsHelp": "If enabled, only channels that are marked as favorite on the tuner device will be imported.", - "ImportMissingEpisodesHelp": "If enabled, information about missing episodes will be imported into your Jellyfin database and displayed within seasons and series. This may cause significantly longer library scans.", + "ImportFavoriteChannelsHelp": "Only channels that are marked as favorite on the tuner device will be imported.", + "ImportMissingEpisodesHelp": "Information about missing episodes will be imported into your database and displayed within seasons and series. This may cause significantly longer library scans.", "InstallingPackage": "Installing {0} (version {1})", "InstantMix": "Instant mix", "ItemCount": "{0} items", @@ -565,7 +565,7 @@ "LabelAppName": "App name", "LabelAppNameExample": "Example: Sickbeard, Sonarr", "LabelArtists": "Artists:", - "LabelArtistsHelp": "Separate multiple using ;", + "LabelArtistsHelp": "Separate multiple artists with a semicolon.", "LabelAudio": "Audio", "LabelAudioBitDepth": "Audio bit depth:", "LabelAudioBitrate": "Audio bitrate:", @@ -576,7 +576,7 @@ "LabelAuthProvider": "Authentication Provider:", "LabelAutomaticallyRefreshInternetMetadataEvery": "Automatically refresh metadata from the internet:", "LabelBindToLocalNetworkAddress": "Bind to local network address:", - "LabelBindToLocalNetworkAddressHelp": "Override the local IP address to bind the http server to. If left empty, the server will bind to all availabile addresses. Changing this value requires restarting Jellyfin Server.", + "LabelBindToLocalNetworkAddressHelp": "Override the local IP address for the HTTP server. If left empty, the server will bind to all availabile addresses. Changing this value requires restarting Jellyfin Server.", "LabelBirthDate": "Birth date:", "LabelBirthYear": "Birth year:", "LabelBitrate": "Bitrate:", @@ -601,14 +601,14 @@ "LabelCustomCertificatePath": "Custom SSL certificate path:", "LabelCustomCertificatePathHelp": "Path to a PKCS #12 file containing a certificate and private key to enable TLS support on a custom domain.", "LabelCustomCss": "Custom CSS:", - "LabelCustomCssHelp": "Apply your own custom styling to the web interface.", + "LabelCustomCssHelp": "Apply your own custom styles on the web interface.", "LabelCustomDeviceDisplayName": "Display name:", "LabelCustomDeviceDisplayNameHelp": "Supply a custom display name or leave empty to use the name reported by the device.", "LabelCustomRating": "Custom rating:", "LabelDashboardTheme": "Server dashboard theme:", "LabelDateAdded": "Date added:", "LabelDateAddedBehavior": "Date added behavior for new content:", - "LabelDateAddedBehaviorHelp": "If a metadata value is present it will always be used before either of these options.", + "LabelDateAddedBehaviorHelp": "If a metadata value is present, it will always be used before either of these options.", "LabelDateTimeLocale": "Date time locale:", "LabelDay": "Day:", "LabelDeathDate": "Death date:", @@ -640,19 +640,19 @@ "LabelEnableAutomaticPortMapHelp": "Automatically forward public ports on your router to local ports on your server via UPnP. This may not work with some router models or network configurations. Changes will not apply until after a server restart.", "LabelEnableBlastAliveMessages": "Blast alive messages", "LabelEnableBlastAliveMessagesHelp": "Enable this if the server is not detected reliably by other UPnP devices on your network.", - "LabelEnableDlnaClientDiscoveryInterval": "Client discovery interval (seconds)", + "LabelEnableDlnaClientDiscoveryInterval": "Client discovery interval", "LabelEnableDlnaClientDiscoveryIntervalHelp": "Determines the duration in seconds between SSDP searches performed by Jellyfin.", "LabelEnableDlnaDebugLogging": "Enable DLNA debug logging", "LabelEnableDlnaDebugLoggingHelp": "Create large log files and should only be used as needed for troubleshooting purposes.", "LabelEnableDlnaPlayTo": "Enable DLNA Play To", - "LabelEnableDlnaPlayToHelp": "Detect devices within your network and offer the ability to remote control them.", + "LabelEnableDlnaPlayToHelp": "Detect devices within your network and offer the ability to control them remotely.", "LabelEnableDlnaServer": "Enable DLNA server", "LabelEnableDlnaServerHelp": "Allows UPnP devices on your network to browse and play content.", "LabelEnableHardwareDecodingFor": "Enable hardware decoding for:", "LabelEnableHttps": "Enable HTTPS", - "LabelEnableHttpsHelp": "Enables the server to listen on the configured HTTPS port. A valid certificate must also be configured in order for this to take effect.", + "LabelEnableHttpsHelp": "Listen on the configured HTTPS port. A valid certificate must also be supplied for this to take effect.", "LabelEnableRealtimeMonitor": "Enable real time monitoring", - "LabelEnableRealtimeMonitorHelp": "Changes to files will be processed immediately, on supported file systems.", + "LabelEnableRealtimeMonitorHelp": "Changes to files will be processed immediately on supported file systems.", "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image", "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.", "LabelEndDate": "End date:", @@ -660,7 +660,7 @@ "LabelEvent": "Event:", "LabelEveryXMinutes": "Every:", "LabelBaseUrl": "Base URL:", - "LabelBaseUrlHelp": "Adds a custom subdirectory to the server URL. For example: http://example.com/<baseurl>", + "LabelBaseUrlHelp": "Add a custom subdirectory to the server URL. For example: http://example.com/<baseurl>", "LabelExtractChaptersDuringLibraryScan": "Extract chapter images during the library scan", "LabelExtractChaptersDuringLibraryScanHelp": "Generate chapter images when videos are imported during the library scan. Otherwise, they will be extracted during the chapter images scheduled task, allowing the regular library scan to complete faster.", "LabelFailed": "Failed", @@ -671,9 +671,9 @@ "LabelForgotPasswordUsernameHelp": "Enter your username, if you remember it.", "LabelFormat": "Format:", "LabelFriendlyName": "Friendly name:", - "LabelServerNameHelp": "This name will be used to identify the server and will default to the server's computer name.", + "LabelServerNameHelp": "This name will be used to identify the server and will default to the server's hostname.", "LabelGroupMoviesIntoCollections": "Group movies into collections", - "LabelGroupMoviesIntoCollectionsHelp": "When displaying movie lists, movies belonging to a collection will be displayed as one grouped item.", + "LabelGroupMoviesIntoCollectionsHelp": "When displaying movie lists, movies in a collection will be displayed as one grouped item.", "LabelH264Crf": "H264 encoding CRF:", "LabelEncoderPreset": "H264 and H265 encoding preset:", "LabelHardwareAccelerationType": "Hardware acceleration:", @@ -681,7 +681,7 @@ "LabelHomeNetworkQuality": "Home network quality:", "LabelHomeScreenSectionValue": "Home screen section {0}:", "LabelHttpsPort": "Local HTTPS port number:", - "LabelHttpsPortHelp": "The TCP port number that Jellyfin's HTTPS server should bind to.", + "LabelHttpsPortHelp": "The TCP port number for the HTTPS server.", "LabelIconMaxHeight": "Icon maximum height:", "LabelIconMaxHeightHelp": "Maximum resolution of icons exposed via upnp:icon.", "LabelIconMaxWidth": "Icon maximum width:", @@ -711,7 +711,7 @@ "LabelLibraryPageSizeHelp": "Sets the amount of items to show on a library page. Set to 0 in order to disable paging.", "LabelLineup": "Lineup:", "LabelLocalHttpServerPortNumber": "Local HTTP port number:", - "LabelLocalHttpServerPortNumberHelp": "The TCP port number that Jellyfin's HTTP server should bind to.", + "LabelLocalHttpServerPortNumberHelp": "The TCP port number for the HTTP server.", "LabelLockItemToPreventChanges": "Lock this item to prevent future changes", "LabelLoginDisclaimer": "Login disclaimer:", "LabelLoginDisclaimerHelp": "A message that will be displayed at the bottom of the login page.", @@ -737,7 +737,7 @@ "LabelMetadataReaders": "Metadata readers:", "LabelMetadataReadersHelp": "Rank your preferred local metadata sources in order of priority. The first file found will be read.", "LabelMetadataSavers": "Metadata savers:", - "LabelMetadataSaversHelp": "Choose the file formats to save your metadata to.", + "LabelMetadataSaversHelp": "Choose the file formats to use when saving your metadata.", "LabelMethod": "Method:", "LabelMinBackdropDownloadWidth": "Minimum backdrop download width:", "LabelMinResumeDuration": "Minimum resume duration:", @@ -755,7 +755,7 @@ "LabelMoviePrefixHelp": "If a prefix is applied to movie titles, enter it here so the server can handle it properly.", "LabelMovieRecordingPath": "Movie recording path:", "LabelMusicStreamingTranscodingBitrate": "Music transcoding bitrate:", - "LabelMusicStreamingTranscodingBitrateHelp": "Specify a max bitrate when streaming music.", + "LabelMusicStreamingTranscodingBitrateHelp": "Specify a maximum bitrate when streaming music.", "LabelName": "Name:", "LabelChromecastVersion": "Chromecast Version", "LabelStable": "Stable", @@ -822,7 +822,7 @@ "LabelRemoteClientBitrateLimitHelp": "An optional per-stream bitrate limit for all out of network devices. This is useful to prevent devices from requesting a higher bitrate than your internet connection can handle. This may result in increased CPU load on your server in order to transcode videos on the fly to a lower bitrate.", "LabelRequireHttps": "Require HTTPS", "LabelRequireHttpsHelp": "If checked, the server will automatically redirect all requests over HTTP to HTTPS. This has no effect if the server is not listening on HTTPS.", - "LabelRuntimeMinutes": "Run time (minutes):", + "LabelRuntimeMinutes": "Runtime:", "LabelSaveLocalMetadata": "Save artwork into media folders", "LabelSaveLocalMetadataHelp": "Saving artwork into media folders will put them in a place where they can be easily edited.", "LabelScheduledTaskLastRan": "Last ran {0}, taking {1}.", @@ -938,7 +938,7 @@ "LabelYoureDone": "You're Done!", "LabelZipCode": "Zip Code:", "LabelffmpegPath": "FFmpeg path:", - "LabelffmpegPathHelp": "The path to the ffmpeg application file, or folder containing ffmpeg.", + "LabelffmpegPathHelp": "The path to the ffmpeg application file or folder containing ffmpeg.", "LanNetworksHelp": "Comma separated list of IP addresses or IP/netmask entries for networks that will be considered on local network when enforcing bandwidth restrictions. If set, all other IP addresses will be considered to be on the external network and will be subject to the external bandwidth restrictions. If left blank, only the server's subnet is considered to be on the local network.", "Large": "Large", "LatestFromLibrary": "Latest {0}", @@ -1067,7 +1067,7 @@ "MessageSyncPlayErrorMedia": "Failed to enable SyncPlay! Media error.", "Metadata": "Metadata", "MetadataManager": "Metadata Manager", - "MetadataSettingChangeHelp": "Changing metadata settings will affect new content that is added going forward. To refresh existing content, open the detail screen and click the refresh button, or perform bulk refreshes using the metadata manager.", + "MetadataSettingChangeHelp": "Changing metadata settings will affect new content added going forward. To refresh existing content, open the detail screen and click the refresh button, or perform bulk refreshes using the metadata manager.", "MinutesAfter": "minutes after", "MinutesBefore": "minutes before", "Mobile": "Mobile", @@ -1126,7 +1126,7 @@ "OptionAllowLinkSharingHelp": "Only web pages containing media information are shared. Media files are never shared publicly. Shares are time-limited and will expire after {0} days.", "OptionAllowManageLiveTv": "Allow Live TV recording management", "OptionAllowMediaPlayback": "Allow media playback", - "OptionAllowMediaPlaybackTranscodingHelp": "Restricting access to transcoding may cause playback failures in Jellyfin apps due to unsupported media formats.", + "OptionAllowMediaPlaybackTranscodingHelp": "Restricting access to transcoding may cause playback failures in clients due to unsupported media formats.", "OptionAllowRemoteControlOthers": "Allow remote control of other users", "OptionAllowRemoteSharedDevices": "Allow remote control of shared devices", "OptionAllowRemoteSharedDevicesHelp": "DLNA devices are considered shared until a user begins controlling them.", @@ -1139,7 +1139,7 @@ "OptionAuto": "Auto", "OptionAutomatic": "Auto", "OptionAutomaticallyGroupSeries": "Automatically merge series that are spread across multiple folders", - "OptionAutomaticallyGroupSeriesHelp": "If enabled, series that are spread across multiple folders within this library will be automatically merged into a single series.", + "OptionAutomaticallyGroupSeriesHelp": "Series that are spread across multiple folders within this library will be automatically merged into a single series.", "OptionBanner": "Banner", "OptionBlockBooks": "Books", "OptionBlockChannelContent": "Internet Channel Content", @@ -1161,7 +1161,7 @@ "OptionDatePlayed": "Date Played", "OptionDescending": "Descending", "OptionDisableUser": "Disable this user", - "OptionDisableUserHelp": "If disabled the server will not allow any connections from this user. Existing connections will be abruptly terminated.", + "OptionDisableUserHelp": "The server will not allow any connections from this user. Existing connections will be abruptly terminated.", "OptionDislikes": "Dislikes", "OptionDisplayFolderView": "Display a folder view to show plain media folders", "OptionDisplayFolderViewHelp": "Display folders alongside your other media libraries. This can be useful if you'd like to have a plain folder view.", @@ -1171,7 +1171,7 @@ "OptionDownloadBoxImage": "Box", "OptionDownloadDiscImage": "Disc", "OptionDownloadImagesInAdvance": "Download images in advance", - "OptionDownloadImagesInAdvanceHelp": "By default, most images are only downloaded when requested by a Jellyfin app. Enable this option to download all images in advance, as new media is imported. This may cause significantly longer library scans.", + "OptionDownloadImagesInAdvanceHelp": "By default, most images are only downloaded when requested by a client. Enable this option to download all images in advance, as new media is imported. This may cause significantly longer library scans.", "OptionDownloadLogoImage": "Logo", "OptionDownloadMenuImage": "Menu", "OptionDownloadPrimaryImage": "Primary", @@ -1204,7 +1204,7 @@ "OptionHlsSegmentedSubtitles": "HLS segmented subtitles", "OptionHomeVideos": "Photos", "OptionIgnoreTranscodeByteRangeRequests": "Ignore transcode byte range requests", - "OptionIgnoreTranscodeByteRangeRequestsHelp": "If enabled, these requests will be honored but will ignore the byte range header.", + "OptionIgnoreTranscodeByteRangeRequestsHelp": "These requests will be honored but will ignore the byte range header.", "OptionImdbRating": "IMDb Rating", "OptionIsHD": "HD", "OptionIsSD": "SD", @@ -1222,9 +1222,9 @@ "OptionOnInterval": "On an interval", "OptionParentalRating": "Parental Rating", "OptionPlainStorageFolders": "Display all folders as plain storage folders", - "OptionPlainStorageFoldersHelp": "If enabled, all folders are represented in DIDL as \"object.container.storageFolder\" instead of a more specific type, such as \"object.container.person.musicArtist\".", + "OptionPlainStorageFoldersHelp": "All folders are represented in DIDL as \"object.container.storageFolder\" instead of a more specific type, such as \"object.container.person.musicArtist\".", "OptionPlainVideoItems": "Display all videos as plain video items", - "OptionPlainVideoItemsHelp": "If enabled, all videos are represented in DIDL as \"object.item.videoItem\" instead of a more specific type, such as \"object.item.videoItem.movie\".", + "OptionPlainVideoItemsHelp": "All videos are represented in DIDL as \"object.item.videoItem\" instead of a more specific type, such as \"object.item.videoItem.movie\".", "OptionPlayCount": "Play Count", "OptionPlayed": "Played", "OptionPoster": "Poster", @@ -1276,7 +1276,7 @@ "PasswordResetComplete": "The password has been reset.", "PasswordResetConfirmation": "Are you sure you wish to reset the password?", "HeaderResetPassword": "Reset Password", - "PasswordResetProviderHelp": "Choose a Password Reset Provider to be used when this user requests a password reset", + "PasswordResetProviderHelp": "Choose a password reset provider to be used when this user requests a password reset.", "PasswordSaved": "Password saved.", "People": "People", "PerfectMatch": "Perfect match", @@ -1330,7 +1330,7 @@ "RecordingScheduled": "Recording scheduled.", "Recordings": "Recordings", "Refresh": "Refresh", - "RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Jellyfin Server dashboard.", + "RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the dashboard.", "RefreshMetadata": "Refresh metadata", "RefreshQueued": "Refresh queued.", "ReleaseDate": "Release date", @@ -1561,8 +1561,8 @@ "EveryXHours": "Every {0} hours", "OnApplicationStartup": "On application startup", "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", + "EnableBlurHash": "Enable blurred placeholders for images", + "EnableBlurHashHelp": "Images that are still being loaded will be displayed with a unique placeholder.", "ButtonSyncPlay": "SyncPlay", "ButtonCast": "Cast", "ButtonPlayer": "Player", diff --git a/src/strings/es-ar.json b/src/strings/es-ar.json index 23ce44b56a..c39e873be7 100644 --- a/src/strings/es-ar.json +++ b/src/strings/es-ar.json @@ -1357,8 +1357,8 @@ "ReleaseGroup": "Grupo de lanzamiento", "ButtonCast": "Transmitir", "ButtonSyncPlay": "SyncPlay", - "EnableBlurhashHelp": "Las imágenes que aún se están cargando se mostrarán con un marcador de posición borroso", - "EnableBlurhash": "Habilitar marcadores de posición borrosos para imágenes", + "EnableBlurHashHelp": "Las imágenes que aún se están cargando se mostrarán con un marcador de posición borroso", + "EnableBlurHash": "Habilitar marcadores de posición borrosos para imágenes", "OnApplicationStartup": "En el inicio de la aplicación", "EveryXHours": "Cada {0} horas", "EveryHour": "Cada hora", diff --git a/src/strings/es-mx.json b/src/strings/es-mx.json index af2e2b5d4b..ef23d21528 100644 --- a/src/strings/es-mx.json +++ b/src/strings/es-mx.json @@ -1544,8 +1544,8 @@ "ButtonSyncPlay": "SyncPlay", "ButtonPlayer": "Reproductor", "ButtonCast": "Elenco", - "EnableBlurhashHelp": "Imágenes que aún están siendo cargadas serán mostradas difuminadas", - "EnableBlurhash": "Habilitar imágenes de fondo difuminadas", + "EnableBlurHashHelp": "Imágenes que aún están siendo cargadas serán mostradas difuminadas", + "EnableBlurHash": "Habilitar imágenes de fondo difuminadas", "TabRepositories": "Repositorios", "ShowMore": "Mostrar más", "ShowLess": "Mostrar menos", diff --git a/src/strings/es.json b/src/strings/es.json index 45c9b1f452..1aebb394ab 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -1511,8 +1511,8 @@ "LabelEnableHttps": "Activar HTTPS", "TabDVR": "DVR", "SaveChanges": "Guardar cambios", - "EnableBlurhash": "Mostrar una representación de las imágenes mientras cargan", - "EnableBlurhashHelp": "Aparecerá una representación de los colores de las imágenes antes de que terminen de cargar", + "EnableBlurHash": "Mostrar una representación de las imágenes mientras cargan", + "EnableBlurHashHelp": "Aparecerá una representación de los colores de las imágenes antes de que terminen de cargar", "HeaderDVR": "DVR", "SyncPlayAccessHelp": "Selecciona el nivel de acceso de este usuario para utilizar SyncPlay. SyncPlay te permite sincronizar la reproducción entre varios dispositivos.", "MessageSyncPlayErrorMedia": "¡No se pudo activar SyncPlay! Error de medio.", diff --git a/src/strings/es_419.json b/src/strings/es_419.json index 71ae83d24f..3ce724f19b 100644 --- a/src/strings/es_419.json +++ b/src/strings/es_419.json @@ -1541,10 +1541,10 @@ "AllChannels": "Todos los canales", "All": "Todo", "Alerts": "Alertas", - "EnableBlurhash": "Habilitar marcadores de posición borrosos para imágenes", + "EnableBlurHash": "Habilitar marcadores de posición borrosos para imágenes", "ShowMore": "Mostrar más", "ShowLess": "Mostrar menos", - "EnableBlurhashHelp": "Las imágenes que aún se están cargando se mostrarán con un marcador de posición borroso", + "EnableBlurHashHelp": "Las imágenes que aún se están cargando se mostrarán con un marcador de posición borroso", "ButtonSyncPlay": "SyncPlay", "MessageNoGenresAvailable": "Permitir a algunos proveedores de metadatos obtener géneros desde Internet.", "MessageAddRepository": "Si desea agregar un repositorio, haga clic en el botón al lado del encabezado y complete la información solicitada.", diff --git a/src/strings/fa.json b/src/strings/fa.json index 32e083685f..3535a3693d 100644 --- a/src/strings/fa.json +++ b/src/strings/fa.json @@ -1543,7 +1543,7 @@ "TvLibraryHelp": "Review the {0}TV naming guide{1}.", "UserAgentHelp": "Supply a custom user-agent HTTP header.", "ValueContainer": "Container: {0}", - "EnableBlurhash": "Enable blurred placeholders for images", - "EnableBlurhashHelp": "Images that are still being loaded will be displayed with a blurred placeholder", + "EnableBlurHash": "Enable blurred placeholders for images", + "EnableBlurHashHelp": "Images that are still being loaded will be displayed with a blurred placeholder", "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/fr.json b/src/strings/fr.json index c5ef0d5615..8d9c0818bc 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -1543,8 +1543,8 @@ "MessageSyncPlayErrorAccessingGroups": "Une erreur s'est produite pendant l'accès à la liste de groupes.", "ShowMore": "Voir plus", "ShowLess": "Voir moins", - "EnableBlurhashHelp": "Les images qui sont encore en cours de chargement seront remplacées par une image générique floue", - "EnableBlurhash": "Utilise des images génériques floues à la place des images", + "EnableBlurHashHelp": "Les images qui sont encore en cours de chargement seront remplacées par une image générique floue", + "EnableBlurHash": "Utilise des images génériques floues à la place des images", "ButtonCast": "Diffuser", "ButtonSyncPlay": "SyncPlay", "TabRepositories": "Dépôts", diff --git a/src/strings/hu.json b/src/strings/hu.json index 8dd52462aa..f05472601f 100644 --- a/src/strings/hu.json +++ b/src/strings/hu.json @@ -1541,8 +1541,8 @@ "LabelSyncPlayTimeOffset": "Időeltolás a szerverhez képest:", "EnableDetailsBannerHelp": "Megjelenít egy banner képet a részletes információoldal tetején.", "EnableDetailsBanner": "Banner a részletes oldalon", - "EnableBlurhashHelp": "A még betöltés alatt álló képek helyén egy elmosódott helyettesítő képet jelenít meg", - "EnableBlurhash": "Elmosódott helyettesítőképek engedélyezése", + "EnableBlurHashHelp": "A még betöltés alatt álló képek helyén egy elmosódott helyettesítő képet jelenít meg", + "EnableBlurHash": "Elmosódott helyettesítőképek engedélyezése", "ShowMore": "Továbbiak megtekintése", "ShowLess": "Kevesebb mutatása", "ButtonCast": "Vetítés", diff --git a/src/strings/it.json b/src/strings/it.json index 437e9d2ffc..d3d5f93578 100644 --- a/src/strings/it.json +++ b/src/strings/it.json @@ -1541,8 +1541,8 @@ "HeaderSyncPlaySelectGroup": "Unisciti a un gruppo", "EnableDetailsBannerHelp": "Mostra il banner nella parte superiore della pagina di dettaglio dell'elemento.", "EnableDetailsBanner": "Banner Dettagli", - "EnableBlurhashHelp": "Le immagini ancora da caricare saranno mostrate inizialmente sfocate", - "EnableBlurhash": "Abilita i segnaposto sfocati per le immagini", + "EnableBlurHashHelp": "Le immagini ancora da caricare saranno mostrate inizialmente sfocate", + "EnableBlurHash": "Abilita i segnaposto sfocati per le immagini", "ShowMore": "Mostra di più", "ShowLess": "Mostra meno", "ButtonCast": "Cast", diff --git a/src/strings/nb.json b/src/strings/nb.json index dbd94366ad..ee1905b7e2 100644 --- a/src/strings/nb.json +++ b/src/strings/nb.json @@ -1469,8 +1469,8 @@ "DeinterlaceMethodHelp": "Velg deinterlacing metoden som skal bli brukt når man transkoder interlaced innhold.", "ButtonTogglePlaylist": "Spilleliste", "ButtonToggleContextMenu": "Mer", - "EnableBlurhashHelp": "Bilder som fortsatt lastes inn vil vises med en tåkete plassholder", - "EnableBlurhash": "Aktiver tåkete plassholdere for bilder", + "EnableBlurHashHelp": "Bilder som fortsatt lastes inn vil vises med en tåkete plassholder", + "EnableBlurHash": "Aktiver tåkete plassholdere for bilder", "UnsupportedPlayback": "Jellyfin kan ikke dekryptere innhold beskyttet med DRM, men alt innhold vil bli forsøkt uansett, inkludert beskyttede titler. Noen filer kan fremstå helt svarte grunnet kryptering eller andre ikke støttede funksjoner, som interaktive titler.", "OnApplicationStartup": "Ved oppstart av applikasjonen", "EveryXHours": "Hver {0}. time", diff --git a/src/strings/nl.json b/src/strings/nl.json index 0ee710db7f..c185c429b8 100644 --- a/src/strings/nl.json +++ b/src/strings/nl.json @@ -1552,8 +1552,8 @@ "ClearQueue": "Leeg wachtrij", "StopPlayback": "Stop afspelen", "ButtonPlayer": "Speler", - "EnableBlurhashHelp": "Afbeeldingen die nog laden worden getoond als een wazige placeholder", - "EnableBlurhash": "Schakel wazige placeholders voor plaatjes in", + "EnableBlurHashHelp": "Afbeeldingen die nog laden worden getoond als een wazige placeholder", + "EnableBlurHash": "Schakel wazige placeholders voor plaatjes in", "Writers": "Schrijvers", "ViewAlbumArtist": "Bekijk album artiest", "MessageAddRepository": "Om een repository toe te voegen klik je op de knop naast de kop, en vul je benodigde informatie in.", diff --git a/src/strings/pl.json b/src/strings/pl.json index 9d3ec0b2f3..cf82877cc4 100644 --- a/src/strings/pl.json +++ b/src/strings/pl.json @@ -1477,8 +1477,8 @@ "StopPlayback": "Zatrzymaj odtwarzanie", "ButtonPlayer": "Odtwarzacz", "ButtonCast": "Obsada", - "EnableBlurhashHelp": "Obrazy które wciąż się ładują zostaną zastąpione rozmazanym symbolem", - "EnableBlurhash": "Włącz rozmazane zamienniki dla obrazów", + "EnableBlurHashHelp": "Obrazy które wciąż się ładują zostaną zastąpione rozmazanym symbolem", + "EnableBlurHash": "Włącz rozmazane zamienniki dla obrazów", "UnsupportedPlayback": "Jellyfin nie może odszyfrować zawartości zabezpieczonej przy pomocy DRM, ale spróbuje pomimo tego. Niektóre pliki mogą pojawiać się jako zupełnie czarne z powodu szyfrowania lub innych nie wspieranych funkcji jak np. interaktywne tytuły.", "OnApplicationStartup": "Przy starcie aplikacji", "EveryXHours": "Co {0} godzin", diff --git a/src/strings/pt-br.json b/src/strings/pt-br.json index 6c7c49718a..b86508e9db 100644 --- a/src/strings/pt-br.json +++ b/src/strings/pt-br.json @@ -1541,8 +1541,8 @@ "HeaderSyncPlaySelectGroup": "Entrar em um grupo", "EnableDetailsBanner": "Banner de detalhes", "EnableDetailsBannerHelp": "Exibe um banner na parte superior da página de detalhes do item.", - "EnableBlurhashHelp": "Imagens que ainda estão carregando vão mostrar em seu lugar representações", - "EnableBlurhash": "Habilitar efeito borrado para imagens previas", + "EnableBlurHashHelp": "Imagens que ainda estão carregando vão mostrar em seu lugar representações", + "EnableBlurHash": "Habilitar efeito borrado para imagens previas", "ShowMore": "Mostrar mais", "ShowLess": "Mostrar menos", "ButtonSyncPlay": "SyncPlay", diff --git a/src/strings/ro.json b/src/strings/ro.json index f341a1699d..9996a8fe70 100644 --- a/src/strings/ro.json +++ b/src/strings/ro.json @@ -1541,8 +1541,8 @@ "HeaderSyncPlaySelectGroup": "Alăturați-vă unui grup", "EnableDetailsBannerHelp": "Afișați o imagine de bandou în partea de sus a paginii cu detalii ale articolului.", "EnableDetailsBanner": "Detalii Bandou", - "EnableBlurhashHelp": "Imaginile care sunt în curs de încărcare vor fi afișate cu un marcaj întinat", - "EnableBlurhash": "Activați marcatoarele întinate pentru imagini", + "EnableBlurHashHelp": "Imaginile care sunt în curs de încărcare vor fi afișate cu un marcaj întinat", + "EnableBlurHash": "Activați marcatoarele întinate pentru imagini", "ShowMore": "Arată mai mult", "ShowLess": "Arată mai puțin", "ButtonCast": "Proiectează", diff --git a/src/strings/ru.json b/src/strings/ru.json index 0ba5eeac27..edc7acdd4f 100644 --- a/src/strings/ru.json +++ b/src/strings/ru.json @@ -1543,8 +1543,8 @@ "MessageSyncPlayErrorNoActivePlayer": "Активный проигрыватель не найден. SyncPlay был отключен.", "ShowMore": "Показать больше", "ShowLess": "Показать меньше", - "EnableBlurhashHelp": "Рисунки, которые всё ещё загружаются, будут отображаться с размытым заполнением", - "EnableBlurhash": "Включить размытые заполнители для изображений", + "EnableBlurHashHelp": "Рисунки, которые всё ещё загружаются, будут отображаться с размытым заполнением", + "EnableBlurHash": "Включить размытые заполнители для изображений", "ButtonSyncPlay": "SyncPlay", "ButtonCast": "В ролях", "TabRepositories": "Репозитории", diff --git a/src/strings/sk.json b/src/strings/sk.json index 760722a9d3..579420920b 100644 --- a/src/strings/sk.json +++ b/src/strings/sk.json @@ -1541,8 +1541,8 @@ "SyncPlayAccessHelp": "Vyberte úroveň prístupu pre tohto používateľa k funkcií SyncPlay. SyncPlay umožňuje zosynchronizovať prehrávanie s ostatnými zariadeniami.", "EnableDetailsBannerHelp": "Zobrazí banner na vrchnej časti detailu položky.", "EnableDetailsBanner": "Detail banneru", - "EnableBlurhashHelp": "Obrázky, ktoré sa stále načítavajú budú zobrazené ako dočasný obrázok s rozmazaným pozadím", - "EnableBlurhash": "Povoliť obrázok s rozmazaným pozadím pre chýbajúce obrázky", + "EnableBlurHashHelp": "Obrázky, ktoré sa stále načítavajú budú zobrazené ako dočasný obrázok s rozmazaným pozadím", + "EnableBlurHash": "Povoliť obrázok s rozmazaným pozadím pre chýbajúce obrázky", "ShowMore": "Zobraziť viac", "ShowLess": "Zobraziť menej", "ButtonCast": "Prenášať", diff --git a/src/strings/sv.json b/src/strings/sv.json index f12e7eff47..7ab2afc867 100644 --- a/src/strings/sv.json +++ b/src/strings/sv.json @@ -1538,8 +1538,8 @@ "StopPlayback": "Stoppa uppspelning", "ButtonPlayer": "Spelare", "ButtonCast": "Roller", - "EnableBlurhashHelp": "Bilder som fortfarande laddas kommer visas med en suddig platshållare", - "EnableBlurhash": "Aktivera suddiga platshållare för bilder", + "EnableBlurHashHelp": "Bilder som fortfarande laddas kommer visas med en suddig platshållare", + "EnableBlurHash": "Aktivera suddiga platshållare för bilder", "Writers": "Skribenter", "ViewAlbumArtist": "Visa albums artist", "TabRepositories": "Förvaringsplatser", diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index b593772f9a..dd2ea6be7d 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -1533,8 +1533,8 @@ "EnableDetailsBanner": "详细信息页面的横幅", "ButtonCast": "投射", "ButtonSyncPlay": "SyncPlay", - "EnableBlurhashHelp": "仍在加载的图片将显示带有模糊的占位符", - "EnableBlurhash": "为图片启用模糊的占位符", + "EnableBlurHashHelp": "仍在加载的图片将显示带有模糊的占位符", + "EnableBlurHash": "为图片启用模糊的占位符", "SyncPlayAccessHelp": "为此用户选择对同步播放功能的访问级别。同步播放让你可以和其他设备同步播放进度。", "ShowMore": "显示更多", "ShowLess": "显示更少", diff --git a/src/strings/zh-tw.json b/src/strings/zh-tw.json index e8a05e081e..4a05bb9ee8 100644 --- a/src/strings/zh-tw.json +++ b/src/strings/zh-tw.json @@ -1525,8 +1525,8 @@ "ShowLess": "顯示更少", "ShowMore": "顯示更多", "SyncPlayAccessHelp": "選取該使用者對同步播放的存取權。此功能能讓你與其他裝置同步播放進度。", - "EnableBlurhash": "啟用模糊的占位圖片", - "EnableBlurhashHelp": "尚未讀取完畢的圖片會先顯示模糊的版本", + "EnableBlurHash": "啟用模糊的占位圖片", + "EnableBlurHashHelp": "尚未讀取完畢的圖片會先顯示模糊的版本", "ClearQueue": "清空佇列", "StopPlayback": "停止播放", "ButtonPlayer": "播放器", From 620f9cd30fb14f3cd5fd7a78b1732e1c4d926c5d Mon Sep 17 00:00:00 2001 From: Matjaz Zavski Date: Fri, 31 Jul 2020 18:41:31 +0200 Subject: [PATCH 042/226] Update src/controllers/livetvstatus.js Co-authored-by: Cameron --- src/controllers/livetvstatus.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/livetvstatus.js b/src/controllers/livetvstatus.js index be6cb1c738..2b7a1ee730 100644 --- a/src/controllers/livetvstatus.js +++ b/src/controllers/livetvstatus.js @@ -265,7 +265,7 @@ function showDeviceMenu(button, tunerDeviceId) { id: 'edit' }); - require(['actionsheet'], function (actionsheet) { + import('actionsheet').then(({default: actionsheet}) => { actionsheet.show({ items: items, positionTo: button From 8b1c80c4fb2c00dfd75478a45c3c6470347bd402 Mon Sep 17 00:00:00 2001 From: matjaz321 Date: Fri, 31 Jul 2020 18:44:37 +0200 Subject: [PATCH 043/226] more fixes --- src/controllers/livetvstatus.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/livetvstatus.js b/src/controllers/livetvstatus.js index 2b7a1ee730..f37760808a 100644 --- a/src/controllers/livetvstatus.js +++ b/src/controllers/livetvstatus.js @@ -131,7 +131,7 @@ function renderProviders(page, providers) { const elem = $('.providerList', page).html(html); $('.btnOptions', elem).on('click', function () { - var id = this.getAttribute('data-id'); + const id = this.getAttribute('data-id'); showProviderOptions(page, id, this); }); } @@ -255,7 +255,7 @@ function addDevice(button) { } function showDeviceMenu(button, tunerDeviceId) { - var items = []; + const items = []; items.push({ name: globalize.translate('ButtonDelete'), id: 'delete' From dd0e47a70efa89cd4f3f748cfc705575885546cb Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 21:35:01 +0100 Subject: [PATCH 044/226] Apply suggestions --- src/components/appRouter.js | 12 +++++++----- src/controllers/music/musicrecommended.js | 2 -- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 7f4976424c..8c9b953d39 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -1,6 +1,8 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdrop', 'browser', 'page', 'appSettings', 'apphost', 'connectionManager'], function (loading, globalize, events, viewManager, skinManager, backdrop, browser, page, appSettings, appHost, connectionManager) { 'use strict'; + loading = loading.default || loading; + var appRouter = { showLocalLogin: function (serverId, manualLogin) { var pageName = manualLogin ? 'manuallogin' : 'login'; @@ -22,7 +24,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro function beginConnectionWizard() { backdrop.clearBackdrop(); - loading.default.show(); + loading.show(); connectionManager.connect({ enableAutoLogin: appSettings.enableAutoLogin() }).then(function (result) { @@ -33,7 +35,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro function handleConnectionResult(result) { switch (result.State) { case 'SignedIn': - loading.default.hide(); + loading.hide(); skinManager.loadUserSkin(); break; case 'ServerSignIn': @@ -276,7 +278,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro var firstConnectionResult; function start(options) { - loading.default.show(); + loading.show(); initApiClients(); @@ -296,7 +298,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro hashbang: options.hashbang !== false }); }).catch().then(function() { - loading.default.hide(); + loading.hide(); }); } @@ -511,7 +513,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro if (currentRouteInfo && currentRouteInfo.path === path) { // can't use this with home right now due to the back menu if (currentRouteInfo.route.type !== 'home') { - loading.default.hide(); + loading.hide(); return Promise.resolve(); } } diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js index e06f865a27..82041c5a56 100644 --- a/src/controllers/music/musicrecommended.js +++ b/src/controllers/music/musicrecommended.js @@ -17,8 +17,6 @@ import 'flexStyles'; /* eslint-disable indent */ - loading = loading.default || loading; - function itemsPerRow() { const screenWidth = dom.getWindowSize().innerWidth; From 0acf8534bb94e987603c8497a6705418534389bb Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 21:39:31 +0100 Subject: [PATCH 045/226] Apply suggestions from code review Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com> --- src/components/loading/loading.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/loading/loading.js b/src/components/loading/loading.js index 08271d4635..8237611373 100644 --- a/src/components/loading/loading.js +++ b/src/components/loading/loading.js @@ -8,7 +8,7 @@ let layer4; let circleLefts; let circleRights; -function show() { +export function show() { let elem = loadingElem; if (!elem) { @@ -47,7 +47,7 @@ function show() { } } -function hide() { +export function hide() { const elem = loadingElem; if (elem) { From c5c11279b877152fdca2569953edae751b2d26f0 Mon Sep 17 00:00:00 2001 From: matjaz321 Date: Fri, 31 Jul 2020 23:27:51 +0200 Subject: [PATCH 046/226] Migrated to es6 module --- package.json | 1 + src/controllers/livetvsettings.js | 123 +++++++++++++++--------------- 2 files changed, 64 insertions(+), 60 deletions(-) diff --git a/package.json b/package.json index a9e269f5ef..c1b1ab5ae2 100644 --- a/package.json +++ b/package.json @@ -207,6 +207,7 @@ "src/controllers/searchpage.js", "src/controllers/livetvtuner.js", "src/controllers/livetvstatus.js", + "src/controllers/livetvsettings.js", "src/controllers/shows/episodes.js", "src/controllers/shows/tvgenres.js", "src/controllers/shows/tvlatest.js", diff --git a/src/controllers/livetvsettings.js b/src/controllers/livetvsettings.js index 715eb06214..0adf8f18b5 100644 --- a/src/controllers/livetvsettings.js +++ b/src/controllers/livetvsettings.js @@ -1,65 +1,68 @@ -define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, globalize) { - 'use strict'; +import $ from 'jQuery'; +import loading from 'loading'; +import globalize from 'globalize'; +import 'emby-button'; - function loadPage(page, config) { - $('.liveTvSettingsForm', page).show(); - $('.noLiveTvServices', page).hide(); - $('#selectGuideDays', page).val(config.GuideDays || ''); - $('#txtPrePaddingMinutes', page).val(config.PrePaddingSeconds / 60); - $('#txtPostPaddingMinutes', page).val(config.PostPaddingSeconds / 60); - page.querySelector('#txtRecordingPath').value = config.RecordingPath || ''; - page.querySelector('#txtMovieRecordingPath').value = config.MovieRecordingPath || ''; - page.querySelector('#txtSeriesRecordingPath').value = config.SeriesRecordingPath || ''; - page.querySelector('#txtPostProcessor').value = config.RecordingPostProcessor || ''; - page.querySelector('#txtPostProcessorArguments').value = config.RecordingPostProcessorArguments || ''; - loading.hide(); - } +function loadPage(page, config) { + $('.liveTvSettingsForm', page).show(); + $('.noLiveTvServices', page).hide(); + $('#selectGuideDays', page).val(config.GuideDays || ''); + $('#txtPrePaddingMinutes', page).val(config.PrePaddingSeconds / 60); + $('#txtPostPaddingMinutes', page).val(config.PostPaddingSeconds / 60); + page.querySelector('#txtRecordingPath').value = config.RecordingPath || ''; + page.querySelector('#txtMovieRecordingPath').value = config.MovieRecordingPath || ''; + page.querySelector('#txtSeriesRecordingPath').value = config.SeriesRecordingPath || ''; + page.querySelector('#txtPostProcessor').value = config.RecordingPostProcessor || ''; + page.querySelector('#txtPostProcessorArguments').value = config.RecordingPostProcessorArguments || ''; + loading.hide(); +} - function onSubmit() { - loading.show(); - var form = this; - ApiClient.getNamedConfiguration('livetv').then(function (config) { - config.GuideDays = $('#selectGuideDays', form).val() || null; - var recordingPath = form.querySelector('#txtRecordingPath').value || null; - var movieRecordingPath = form.querySelector('#txtMovieRecordingPath').value || null; - var seriesRecordingPath = form.querySelector('#txtSeriesRecordingPath').value || null; - var recordingPathChanged = recordingPath != config.RecordingPath || movieRecordingPath != config.MovieRecordingPath || seriesRecordingPath != config.SeriesRecordingPath; - config.RecordingPath = recordingPath; - config.MovieRecordingPath = movieRecordingPath; - config.SeriesRecordingPath = seriesRecordingPath; - config.RecordingEncodingFormat = 'mkv'; - config.PrePaddingSeconds = 60 * $('#txtPrePaddingMinutes', form).val(); - config.PostPaddingSeconds = 60 * $('#txtPostPaddingMinutes', form).val(); - config.RecordingPostProcessor = $('#txtPostProcessor', form).val(); - config.RecordingPostProcessorArguments = $('#txtPostProcessorArguments', form).val(); - ApiClient.updateNamedConfiguration('livetv', config).then(function () { - Dashboard.processServerConfigurationUpdateResult(); - showSaveMessage(recordingPathChanged); - }); +function onSubmit() { + loading.show(); + const form = this; + ApiClient.getNamedConfiguration('livetv').then(function (config) { + config.GuideDays = $('#selectGuideDays', form).val() || null; + const recordingPath = form.querySelector('#txtRecordingPath').value || null; + const movieRecordingPath = form.querySelector('#txtMovieRecordingPath').value || null; + const seriesRecordingPath = form.querySelector('#txtSeriesRecordingPath').value || null; + const recordingPathChanged = recordingPath != config.RecordingPath || movieRecordingPath != config.MovieRecordingPath || seriesRecordingPath != config.SeriesRecordingPath; + config.RecordingPath = recordingPath; + config.MovieRecordingPath = movieRecordingPath; + config.SeriesRecordingPath = seriesRecordingPath; + config.RecordingEncodingFormat = 'mkv'; + config.PrePaddingSeconds = 60 * $('#txtPrePaddingMinutes', form).val(); + config.PostPaddingSeconds = 60 * $('#txtPostPaddingMinutes', form).val(); + config.RecordingPostProcessor = $('#txtPostProcessor', form).val(); + config.RecordingPostProcessorArguments = $('#txtPostProcessorArguments', form).val(); + ApiClient.updateNamedConfiguration('livetv', config).then(function () { + Dashboard.processServerConfigurationUpdateResult(); + showSaveMessage(recordingPathChanged); }); - return false; + }); + return false; +} + +function showSaveMessage(recordingPathChanged) { + let msg = ''; + + if (recordingPathChanged) { + msg += globalize.translate('RecordingPathChangeMessage'); } - function showSaveMessage(recordingPathChanged) { - var msg = ''; - - if (recordingPathChanged) { - msg += globalize.translate('RecordingPathChangeMessage'); - } - - if (msg) { - require(['alert'], function (alert) { - alert(msg); - }); - } + if (msg) { } + import('alert').then(({default: alert}) => { + alert(msg); + }); +} +export default function () { $(document).on('pageinit', '#liveTvSettingsPage', function () { - var page = this; + const page = this; $('.liveTvSettingsForm').off('submit', onSubmit).on('submit', onSubmit); $('#btnSelectRecordingPath', page).on('click.selectDirectory', function () { - require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser.default(); + import('directorybrowser').then(({default: directoryBrowser}) => { + const picker = new directoryBrowser(); picker.show({ callback: function (path) { if (path) { @@ -73,8 +76,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, }); }); $('#btnSelectMovieRecordingPath', page).on('click.selectDirectory', function () { - require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser.default(); + import('directorybrowser').then(({default: directoryBrowser}) => { + const picker = new directoryBrowser(); picker.show({ callback: function (path) { if (path) { @@ -88,8 +91,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, }); }); $('#btnSelectSeriesRecordingPath', page).on('click.selectDirectory', function () { - require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser.default(); + import('directorybrowser').then(({default: directoryBrowser}) => { + const picker = new directoryBrowser(); picker.show({ callback: function (path) { if (path) { @@ -103,8 +106,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, }); }); $('#btnSelectPostProcessorPath', page).on('click.selectDirectory', function () { - require(['directorybrowser'], function (directoryBrowser) { - var picker = new directoryBrowser.default(); + import('directorybrowser').then(({default: directoryBrowser}) => { + const picker = new directoryBrowser(); picker.show({ includeFiles: true, callback: function (path) { @@ -119,9 +122,9 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, }); }).on('pageshow', '#liveTvSettingsPage', function () { loading.show(); - var page = this; + const page = this; ApiClient.getNamedConfiguration('livetv').then(function (config) { loadPage(page, config); }); }); -}); +} From caeba288aa91b05d1232197d82d848f1f81f97ba Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2020 21:30:52 +0000 Subject: [PATCH 047/226] Bump css-loader from 4.1.1 to 4.2.0 Bumps [css-loader](https://github.com/webpack-contrib/css-loader) from 4.1.1 to 4.2.0. - [Release notes](https://github.com/webpack-contrib/css-loader/releases) - [Changelog](https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/css-loader/compare/v4.1.1...v4.2.0) Signed-off-by: dependabot-preview[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a9e269f5ef..17d175b7e7 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "babel-loader": "^8.0.6", "browser-sync": "^2.26.12", "copy-webpack-plugin": "^5.1.1", - "css-loader": "^4.1.1", + "css-loader": "^4.2.0", "cssnano": "^4.1.10", "del": "^5.1.0", "eslint": "^6.8.0", diff --git a/yarn.lock b/yarn.lock index fdba5328dd..09181bfc78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3025,10 +3025,10 @@ css-has-pseudo@^0.10.0: postcss "^7.0.6" postcss-selector-parser "^5.0.0-rc.4" -css-loader@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-4.1.1.tgz#48342f098784e75bbfc0933dea2853314fb737d8" - integrity sha512-nZ4OC2g88+wOOdkVQ0yYy7T6uXSkb7I7UyMNnaevQQvVWskTSDRAz08ETl91et4ghVL6jfnzWUt0o2XaY0gyRg== +css-loader@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-4.2.0.tgz#b57efb92ac8f0cd85bf92d89df9634ef1f51b8bf" + integrity sha512-ko7a9b0iFpWtk9eSI/C8IICvZeGtYnjxYjw45rJprokXj/+kBd/siX4vAIBq9Uij8Jubc4jL1EvSnTjCEwaHSw== dependencies: camelcase "^6.0.0" cssesc "^3.0.0" From 7e5e429625d89b2187963b4b4a96ca744d3d79ed Mon Sep 17 00:00:00 2001 From: matjaz321 Date: Fri, 31 Jul 2020 23:31:32 +0200 Subject: [PATCH 048/226] small fix --- src/controllers/livetvsettings.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controllers/livetvsettings.js b/src/controllers/livetvsettings.js index 0adf8f18b5..a9c597a2be 100644 --- a/src/controllers/livetvsettings.js +++ b/src/controllers/livetvsettings.js @@ -50,10 +50,10 @@ function showSaveMessage(recordingPathChanged) { } if (msg) { + import('alert').then(({default: alert}) => { + alert(msg); + }); } - import('alert').then(({default: alert}) => { - alert(msg); - }); } export default function () { From af93c4a798376f89bb089bcf1226420767e31408 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 1 Aug 2020 05:36:36 +0200 Subject: [PATCH 049/226] Migrate routes.js to ES6 --- package.json | 2 + src/components/viewContainer.js | 104 +++++++++++++------------- src/scripts/routes.js | 126 ++++++++++++++++++++++---------- 3 files changed, 142 insertions(+), 90 deletions(-) diff --git a/package.json b/package.json index a9e269f5ef..74cf0ad5e9 100644 --- a/package.json +++ b/package.json @@ -163,6 +163,7 @@ "src/components/syncPlay/playbackPermissionManager.js", "src/components/syncPlay/syncPlayManager.js", "src/components/syncPlay/timeSyncManager.js", + "src/components/viewContainer.js", "src/controllers/session/addServer/index.js", "src/controllers/session/forgotPassword/index.js", "src/controllers/session/redeemPassword/index.js", @@ -267,6 +268,7 @@ "src/scripts/libraryBrowser.js", "src/scripts/multiDownload.js", "src/scripts/playlists.js", + "src/scripts/routes.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", "src/scripts/settings/webSettings.js", diff --git a/src/components/viewContainer.js b/src/components/viewContainer.js index d1b0df6fbb..766a12b9ce 100644 --- a/src/components/viewContainer.js +++ b/src/components/viewContainer.js @@ -1,12 +1,11 @@ -define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewContainer'], function (browser, dom, layoutManager) { - 'use strict'; +/* eslint-disable indent */ function setControllerClass(view, options) { if (options.controllerFactory) { return Promise.resolve(); } - var controllerUrl = view.getAttribute('data-controller'); + let controllerUrl = view.getAttribute('data-controller'); if (controllerUrl) { if (controllerUrl.indexOf('__plugin/') === 0) { @@ -14,7 +13,7 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta } controllerUrl = Dashboard.getConfigurationResourceUrl(controllerUrl); - return getRequirePromise([controllerUrl]).then(function (ControllerFactory) { + return getRequirePromise([controllerUrl]).then((ControllerFactory) => { options.controllerFactory = ControllerFactory; }); } @@ -23,35 +22,35 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta } function getRequirePromise(deps) { - return new Promise(function (resolve, reject) { + return new Promise((resolve, reject) => { require(deps, resolve); }); } - function loadView(options) { + export function loadView(options) { if (!options.cancel) { - var selected = selectedPageIndex; - var previousAnimatable = selected === -1 ? null : allPages[selected]; - var pageIndex = selected + 1; + const selected = selectedPageIndex; + const previousAnimatable = selected === -1 ? null : allPages[selected]; + let pageIndex = selected + 1; if (pageIndex >= pageContainerCount) { pageIndex = 0; } - var isPluginpage = options.url.toLowerCase().indexOf('/configurationpage') !== -1; - var newViewInfo = normalizeNewView(options, isPluginpage); - var newView = newViewInfo.elem; - var modulesToLoad = []; + const isPluginpage = options.url.toLowerCase().indexOf('/configurationpage') !== -1; + const newViewInfo = normalizeNewView(options, isPluginpage); + const newView = newViewInfo.elem; + const modulesToLoad = []; - return new Promise(function (resolve) { - require(modulesToLoad, function () { - var currentPage = allPages[pageIndex]; + return new Promise((resolve) => { + require(modulesToLoad, () => { + const currentPage = allPages[pageIndex]; if (currentPage) { triggerDestroy(currentPage); } - var view = newView; + let view = newView; if (typeof view == 'string') { view = document.createElement('div'); @@ -79,7 +78,7 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta view.setAttribute('data-type', options.type); } - var properties = []; + const properties = []; if (options.fullscreen) { properties.push('fullscreen'); @@ -90,7 +89,7 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta } allPages[pageIndex] = view; - setControllerClass(view, options).then(function () { + setControllerClass(view, options).then(() => { if (onBeforeChange) { onBeforeChange(view, false, options); } @@ -125,28 +124,28 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta html = replaceAll(html, '<\/script>--\x3e', '<\/script>'); } - var wrapper = document.createElement('div'); + const wrapper = document.createElement('div'); wrapper.innerHTML = html; return wrapper.querySelector('div[data-role="page"]'); } function normalizeNewView(options, isPluginpage) { - var viewHtml = options.view; + const viewHtml = options.view; if (viewHtml.indexOf('data-role="page"') === -1) { return viewHtml; } - var hasScript = viewHtml.indexOf(' { if (onBeforeChange) { onBeforeChange(view, true, options); } @@ -228,25 +227,28 @@ define(['browser', 'dom', 'layoutManager', 'css!components/viewManager/viewConta view.dispatchEvent(new CustomEvent('viewdestroy', {})); } - function reset() { + export function reset() { allPages = []; currentUrls = []; mainAnimatedPages.innerHTML = ''; selectedPageIndex = -1; } - var onBeforeChange; - var mainAnimatedPages = document.querySelector('.mainAnimatedPages'); - var allPages = []; - var currentUrls = []; - var pageContainerCount = 3; - var selectedPageIndex = -1; + let onBeforeChange; + const mainAnimatedPages = document.querySelector('.mainAnimatedPages'); + let allPages = []; + let currentUrls = []; + const pageContainerCount = 3; + let selectedPageIndex = -1; reset(); mainAnimatedPages.classList.remove('hide'); - return { - loadView: loadView, - tryRestoreView: tryRestoreView, - reset: reset, - setOnBeforeChange: setOnBeforeChange - }; -}); + +/* eslint-enable indent */ + +export default { + loadView: loadView, + tryRestoreView: tryRestoreView, + reset: reset, + setOnBeforeChange: setOnBeforeChange +}; + diff --git a/src/scripts/routes.js b/src/scripts/routes.js index 1d735e3018..4094a2552f 100644 --- a/src/scripts/routes.js +++ b/src/scripts/routes.js @@ -1,18 +1,21 @@ -define([ - 'jQuery', - 'emby-button', - 'emby-input', - 'scripts/livetvcomponents', - 'paper-icon-button-light', - 'emby-itemscontainer', - 'emby-collapse', - 'emby-select', - 'livetvcss', - 'emby-checkbox', - 'emby-slider', - 'listViewStyle', - 'dashboardcss', - 'detailtablecss'], function () { +import 'emby-button'; +import 'emby-input'; +import 'scripts/livetvcomponents'; +import 'paper-icon-button-light'; +import 'emby-itemscontainer'; +import 'emby-collapse'; +import 'emby-select'; +import 'livetvcss'; +import 'emby-checkbox'; +import 'emby-slider'; +import 'listViewStyle'; +import 'dashboardcss'; +import 'detailtablecss'; + +/* eslint-disable indent */ + + console.groupCollapsed('defining core routes'); + function defineRoute(newRoute) { var path = newRoute.alias ? newRoute.alias : newRoute.path; console.debug('defining route: ' + path); @@ -20,8 +23,6 @@ define([ Emby.Page.addRoute(path, newRoute); } - console.debug('defining core routes'); - defineRoute({ alias: '/addserver.html', path: '/controllers/session/addServer/index.html', @@ -30,6 +31,7 @@ define([ startup: true, controller: 'session/addServer/index' }); + defineRoute({ alias: '/selectserver.html', path: '/controllers/session/selectServer/index.html', @@ -39,6 +41,7 @@ define([ controller: 'session/selectServer/index', type: 'selectserver' }); + defineRoute({ alias: '/login.html', path: '/controllers/session/login/index.html', @@ -48,6 +51,7 @@ define([ controller: 'session/login/index', type: 'login' }); + defineRoute({ alias: '/forgotpassword.html', path: '/controllers/session/forgotPassword/index.html', @@ -55,6 +59,7 @@ define([ startup: true, controller: 'session/forgotPassword/index' }); + defineRoute({ alias: '/forgotpasswordpin.html', path: '/controllers/session/redeemPassword/index.html', @@ -68,42 +73,41 @@ define([ alias: '/mypreferencesmenu.html', path: '/controllers/user/menu/index.html', autoFocus: false, - transition: 'fade', controller: 'user/menu/index' }); + defineRoute({ alias: '/myprofile.html', path: '/controllers/user/profile/index.html', autoFocus: false, - transition: 'fade', controller: 'user/profile/index' }); + defineRoute({ alias: '/mypreferencesdisplay.html', path: '/controllers/user/display/index.html', autoFocus: false, - transition: 'fade', controller: 'user/display/index' }); + defineRoute({ alias: '/mypreferenceshome.html', path: '/controllers/user/home/index.html', autoFocus: false, - transition: 'fade', controller: 'user/home/index' }); + defineRoute({ alias: '/mypreferencesplayback.html', path: '/controllers/user/playback/index.html', autoFocus: false, - transition: 'fade', controller: 'user/playback/index' }); + defineRoute({ alias: '/mypreferencessubtitles.html', path: '/controllers/user/subtitles/index.html', autoFocus: false, - transition: 'fade', controller: 'user/subtitles/index' }); @@ -113,42 +117,49 @@ define([ roles: 'admin', controller: 'dashboard/dashboard' }); + defineRoute({ path: '/dashboardgeneral.html', controller: 'dashboard/general', autoFocus: false, roles: 'admin' }); + defineRoute({ path: '/networking.html', autoFocus: false, roles: 'admin', controller: 'dashboard/networking' }); + defineRoute({ path: '/devices.html', autoFocus: false, roles: 'admin', controller: 'dashboard/devices/devices' }); + defineRoute({ path: '/device.html', autoFocus: false, roles: 'admin', controller: 'dashboard/devices/device' }); + defineRoute({ path: '/dlnaprofile.html', autoFocus: false, roles: 'admin', controller: 'dashboard/dlna/profile' }); + defineRoute({ path: '/dlnaprofiles.html', autoFocus: false, roles: 'admin', controller: 'dashboard/dlna/profiles' }); + defineRoute({ alias: '/addplugin.html', path: '/controllers/dashboard/plugins/add/index.html', @@ -156,52 +167,61 @@ define([ roles: 'admin', controller: 'dashboard/plugins/add/index' }); + defineRoute({ path: '/library.html', autoFocus: false, roles: 'admin', controller: 'dashboard/mediaLibrary' }); + defineRoute({ path: '/librarydisplay.html', autoFocus: false, roles: 'admin', controller: 'dashboard/librarydisplay' }); + defineRoute({ path: '/dlnasettings.html', autoFocus: false, roles: 'admin', controller: 'dashboard/dlna/settings' }); + defineRoute({ path: '/edititemmetadata.html', controller: 'edititemmetadata', autoFocus: false }); + defineRoute({ path: '/encodingsettings.html', autoFocus: false, roles: 'admin', controller: 'dashboard/encodingsettings' }); + defineRoute({ path: '/log.html', roles: 'admin', controller: 'dashboard/logs' }); + defineRoute({ path: '/metadataimages.html', autoFocus: false, roles: 'admin', controller: 'dashboard/metadataImages' }); + defineRoute({ path: '/metadatanfo.html', autoFocus: false, roles: 'admin', controller: 'dashboard/metadatanfo' }); + defineRoute({ alias: '/notificationsetting.html', path: '/controllers/dashboard/notifications/notification/index.html', @@ -209,6 +229,7 @@ define([ roles: 'admin', controller: 'dashboard/notifications/notification/index' }); + defineRoute({ alias: '/notificationsettings.html', path: '/controllers/dashboard/notifications/notifications/index.html', @@ -216,12 +237,14 @@ define([ autoFocus: false, roles: 'admin' }); + defineRoute({ path: '/playbackconfiguration.html', autoFocus: false, roles: 'admin', controller: 'dashboard/playback' }); + defineRoute({ alias: '/availableplugins.html', path: '/controllers/dashboard/plugins/available/index.html', @@ -229,6 +252,7 @@ define([ roles: 'admin', controller: 'dashboard/plugins/available/index' }); + defineRoute({ alias: '/repositories.html', path: '/controllers/dashboard/plugins/repositories/index.html', @@ -241,67 +265,72 @@ define([ path: '/home.html', autoFocus: false, controller: 'home', - transition: 'fade', type: 'home' }); + defineRoute({ path: '/search.html', controller: 'searchpage' }); + defineRoute({ path: '/list.html', autoFocus: false, - controller: 'list', - transition: 'fade' + controller: 'list' }); + defineRoute({ alias: '/details', path: '/controllers/itemDetails/index.html', controller: 'itemDetails/index', - autoFocus: false, - transition: 'fade' + autoFocus: false }); + defineRoute({ path: '/livetv.html', controller: 'livetv/livetvsuggested', - autoFocus: false, - transition: 'fade' + autoFocus: false }); + defineRoute({ path: '/livetvguideprovider.html', autoFocus: false, roles: 'admin', controller: 'livetvguideprovider' }); + defineRoute({ path: '/livetvsettings.html', autoFocus: false, controller: 'livetvsettings' }); + defineRoute({ path: '/livetvstatus.html', autoFocus: false, roles: 'admin', controller: 'livetvstatus' }); + defineRoute({ path: '/livetvtuner.html', autoFocus: false, roles: 'admin', controller: 'livetvtuner' }); + defineRoute({ path: '/movies.html', autoFocus: false, - controller: 'movies/moviesrecommended', - transition: 'fade' + controller: 'movies/moviesrecommended' }); + defineRoute({ path: '/music.html', controller: 'music/musicrecommended', - autoFocus: false, - transition: 'fade' + autoFocus: false }); + defineRoute({ alias: '/installedplugins.html', path: '/controllers/dashboard/plugins/installed/index.html', @@ -309,41 +338,46 @@ define([ roles: 'admin', controller: 'dashboard/plugins/installed/index' }); + defineRoute({ path: '/scheduledtask.html', autoFocus: false, roles: 'admin', controller: 'dashboard/scheduledtasks/scheduledtask' }); + defineRoute({ path: '/scheduledtasks.html', autoFocus: false, roles: 'admin', controller: 'dashboard/scheduledtasks/scheduledtasks' }); + defineRoute({ path: '/serveractivity.html', autoFocus: false, roles: 'admin', controller: 'dashboard/serveractivity' }); + defineRoute({ path: '/apikeys.html', autoFocus: false, roles: 'admin', controller: 'dashboard/apikeys' }); + defineRoute({ path: '/streamingsettings.html', autoFocus: false, roles: 'admin', controller: 'dashboard/streaming' }); + defineRoute({ path: '/tv.html', autoFocus: false, - controller: 'shows/tvrecommended', - transition: 'fade' + controller: 'shows/tvrecommended' }); defineRoute({ @@ -352,29 +386,34 @@ define([ roles: 'admin', controller: 'dashboard/users/useredit' }); + defineRoute({ path: '/userlibraryaccess.html', autoFocus: false, roles: 'admin', controller: 'dashboard/users/userlibraryaccess' }); + defineRoute({ path: '/usernew.html', autoFocus: false, roles: 'admin', controller: 'dashboard/users/usernew' }); + defineRoute({ path: '/userparentalcontrol.html', autoFocus: false, roles: 'admin', controller: 'dashboard/users/userparentalcontrol' }); + defineRoute({ path: '/userpassword.html', autoFocus: false, controller: 'dashboard/users/userpasswordpage' }); + defineRoute({ path: '/userprofiles.html', autoFocus: false, @@ -389,6 +428,7 @@ define([ anonymous: true, controller: 'wizard/remote/index' }); + defineRoute({ alias: '/wizardfinish.html', path: '/controllers/wizard/finish/index.html', @@ -396,12 +436,14 @@ define([ anonymous: true, controller: 'wizard/finish/index' }); + defineRoute({ path: '/wizardlibrary.html', autoFocus: false, anonymous: true, controller: 'dashboard/mediaLibrary' }); + defineRoute({ alias: '/wizardsettings.html', path: '/controllers/wizard/settings/index.html', @@ -409,6 +451,7 @@ define([ anonymous: true, controller: 'wizard/settings/index' }); + defineRoute({ alias: '/wizardstart.html', path: '/controllers/wizard/start/index.html', @@ -416,6 +459,7 @@ define([ anonymous: true, controller: 'wizard/start/index' }); + defineRoute({ alias: '/wizarduser.html', path: '/controllers/wizard/user/index.html', @@ -427,7 +471,6 @@ define([ defineRoute({ alias: '/video', path: '/controllers/playback/video/index.html', - transition: 'fade', controller: 'playback/video/index', autoFocus: false, type: 'video-osd', @@ -435,16 +478,17 @@ define([ fullscreen: true, enableMediaControl: false }); + defineRoute({ alias: '/queue', path: '/controllers/playback/queue/index.html', controller: 'playback/queue/index', autoFocus: false, - transition: 'fade', fullscreen: true, supportsThemeMedia: true, enableMediaControl: false }); + defineRoute({ path: '/configurationpage', autoFocus: false, @@ -458,9 +502,13 @@ define([ isDefaultRoute: true, autoFocus: false }); + defineRoute({ path: '/index.html', autoFocus: false, isDefaultRoute: true }); -}); + + console.groupEnd('defining core routes'); + +/* eslint-enable indent */ From 5d2d8d2855d2b8173f9eb04c86a1f81724cc2b13 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 1 Aug 2020 05:37:07 +0200 Subject: [PATCH 050/226] Fix typo in imageLoader --- src/components/images/imageLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index c9d3e6fdb2..0effcc7a57 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -205,7 +205,7 @@ import 'css!./style'; /* eslint-enable indent */ export default { - serLazyImage: setLazyImage, + setLazyImage: setLazyImage, fillImages: fillImages, fillImage: fillImage, lazyImage: lazyImage, From 1f3bc8a4272df1d03af6dd4f3dee5aab1ed65df5 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 1 Aug 2020 05:46:31 +0200 Subject: [PATCH 051/226] Migrate mouseManager to es6 --- package.json | 1 + src/scripts/mouseManager.js | 49 +++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 74cf0ad5e9..4695eb155a 100644 --- a/package.json +++ b/package.json @@ -266,6 +266,7 @@ "src/scripts/inputManager.js", "src/scripts/keyboardNavigation.js", "src/scripts/libraryBrowser.js", + "src/scripts/mouseManager.js", "src/scripts/multiDownload.js", "src/scripts/playlists.js", "src/scripts/routes.js", diff --git a/src/scripts/mouseManager.js b/src/scripts/mouseManager.js index d801d82393..40253fb91c 100644 --- a/src/scripts/mouseManager.js +++ b/src/scripts/mouseManager.js @@ -1,10 +1,15 @@ -define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'dom'], function (inputManager, focusManager, browser, layoutManager, events, dom) { - 'use strict'; +import inputManager from 'inputManager'; +import focusManager from 'focusManager'; +import browser from 'browser'; +import layoutManager from 'layoutManager'; +import events from 'events'; +import dom from 'dom'; +/* eslint-disable indent */ - var self = {}; + const self = {}; - var lastMouseInputTime = new Date().getTime(); - var isMouseIdle; + let lastMouseInputTime = new Date().getTime(); + let isMouseIdle; function mouseIdleTime() { return new Date().getTime() - lastMouseInputTime; @@ -15,14 +20,14 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } function removeIdleClasses() { - var classList = document.body.classList; + const classList = document.body.classList; classList.remove('mouseIdle'); classList.remove('mouseIdle-tv'); } function addIdleClasses() { - var classList = document.body.classList; + const classList = document.body.classList; classList.add('mouseIdle'); @@ -31,7 +36,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } } - function showCursor() { + export function showCursor() { if (isMouseIdle) { isMouseIdle = false; removeIdleClasses(); @@ -39,7 +44,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } } - function hideCursor() { + export function hideCursor() { if (!isMouseIdle) { isMouseIdle = true; addIdleClasses(); @@ -47,17 +52,17 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } } - var lastPointerMoveData; + let lastPointerMoveData; function onPointerMove(e) { - var eventX = e.screenX; - var eventY = e.screenY; + const eventX = e.screenX; + const eventY = e.screenY; // if coord don't exist how could it move if (typeof eventX === 'undefined' && typeof eventY === 'undefined') { return; } - var obj = lastPointerMoveData; + const obj = lastPointerMoveData; if (!obj) { lastPointerMoveData = { x: eventX, @@ -81,11 +86,11 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } function onPointerEnter(e) { - var pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'); + const pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'); if (pointerType === 'mouse') { if (!isMouseIdle) { - var parent = focusManager.focusableParent(e.target); + const parent = focusManager.focusableParent(e.target); if (parent) { focusManager.focus(parent); } @@ -115,7 +120,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } } - var mouseInterval; + let mouseInterval; function startMouseInterval() { if (!mouseInterval) { mouseInterval = setInterval(onMouseInterval, 5000); @@ -123,7 +128,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd } function stopMouseInterval() { - var interval = mouseInterval; + const interval = mouseInterval; if (interval) { clearInterval(interval); @@ -167,8 +172,10 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd events.on(layoutManager, 'modechange', initMouse); - self.hideCursor = hideCursor; - self.showCursor = showCursor; +/* eslint-enable indent */ + +export default { + hideCursor, + showCursor +}; - return self; -}); From 4ee939a762ad6be34fa025a60ad52c64a0f1b79a Mon Sep 17 00:00:00 2001 From: Thomas Schwery Date: Sat, 1 Aug 2020 07:49:32 +0000 Subject: [PATCH 052/226] Translated using Weblate (French) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/ --- src/strings/fr.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/strings/fr.json b/src/strings/fr.json index 6d56752211..63cf6b95f9 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -1564,5 +1564,8 @@ "StopPlayback": "Arrêter", "ButtonPlayer": "Démarrer", "Writers": "Écrivains", - "ViewAlbumArtist": "Voir l'album de l'artiste" + "ViewAlbumArtist": "Voir l'album de l'artiste", + "PreviousTrack": "Revenir au précédent", + "NextTrack": "Passer au prochain", + "LabelUnstable": "Instable" } From a609e3e2b4bc5dbca9b661f77e0a9d53a2222919 Mon Sep 17 00:00:00 2001 From: Vitorvlv Date: Sat, 1 Aug 2020 03:05:39 +0000 Subject: [PATCH 053/226] Translated using Weblate (Portuguese (Brazil)) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_BR/ --- src/strings/pt-br.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/strings/pt-br.json b/src/strings/pt-br.json index 413abeea73..e2f61129f5 100644 --- a/src/strings/pt-br.json +++ b/src/strings/pt-br.json @@ -1521,7 +1521,7 @@ "MessageSyncPlayGroupDoesNotExist": "Falha ao participar de grupo pois o mesmo não existe.", "MessageSyncPlayPlaybackPermissionRequired": "É necessária permissão de reprodução.", "MessageSyncPlayNoGroupsAvailable": "Nenhum grupo disponível. Comece a reproduzir algo primeiro.", - "MessageSyncPlayGroupWait": "{0} está carregando. . .", + "MessageSyncPlayGroupWait": "{0} está carregando…", "MessageSyncPlayUserLeft": "{0} deixou o grupo.", "MessageSyncPlayUserJoined": "{0} se juntou ao grupo.", "MessageSyncPlayDisabled": "SyncPlay desativado.", @@ -1564,5 +1564,8 @@ "Writers": "Escritores", "ClearQueue": "Limpar fila", "StopPlayback": "Parar reprodução", - "ViewAlbumArtist": "Ver artista do álbum" + "ViewAlbumArtist": "Ver artista do álbum", + "PreviousTrack": "Ir para o anterior", + "NextTrack": "Ir para o próximo", + "LabelUnstable": "Instável" } From c159d4f6011b4851d7893645949749b1433ace75 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 1 Aug 2020 13:50:37 +0200 Subject: [PATCH 054/226] Update ESLint to 7.6.0 --- .eslintrc.js | 4 +- package.json | 2 +- yarn.lock | 351 +++++++++++++++++++++------------------------------ 3 files changed, 145 insertions(+), 212 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 98fa2b817f..ff12e198c3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -29,7 +29,7 @@ module.exports = { ], rules: { 'block-spacing': ['error'], - 'brace-style': ['error', "1tbs", { "allowSingleLine": true }], + 'brace-style': ['error', '1tbs', { 'allowSingleLine': true }], 'comma-dangle': ['error', 'never'], 'comma-spacing': ['error'], 'eol-last': ['error'], @@ -41,7 +41,7 @@ module.exports = { 'no-multiple-empty-lines': ['error', { 'max': 1 }], 'no-trailing-spaces': ['error'], 'no-unused-expressions': ['error', { 'allowShortCircuit': true, 'allowTernary': true, 'allowTaggedTemplates': true }], - "no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": true }], + 'no-unused-vars': ['error', { 'vars': 'all', 'args': 'none', 'ignoreRestSiblings': true }], 'one-var': ['error', 'never'], 'padded-blocks': ['error', 'never'], 'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }], diff --git a/package.json b/package.json index 17d175b7e7..a18eb8e0fb 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "css-loader": "^4.2.0", "cssnano": "^4.1.10", "del": "^5.1.0", - "eslint": "^6.8.0", + "eslint": "^7.6.0", "eslint-plugin-compat": "^3.5.1", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-import": "^2.21.2", diff --git a/yarn.lock b/yarn.lock index 09181bfc78..94d714872d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1265,10 +1265,10 @@ acorn@^6.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== -acorn@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" - integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== +acorn@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd" + integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA== after@0.8.2: version "0.8.2" @@ -1293,7 +1293,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.5.5: +ajv@^6.1.0, ajv@^6.12.2, ajv@^6.5.5: version "6.12.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== @@ -1303,6 +1303,16 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.10.0, ajv@^6.10.2: + version "6.12.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706" + integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + alameda@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/alameda/-/alameda-1.4.0.tgz#ca53cad0feb5e24994a9be859e0593e8c2d8f58c" @@ -1335,13 +1345,6 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-escapes@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" - integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== - dependencies: - type-fest "^0.11.0" - ansi-gray@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" @@ -2375,7 +2378,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2420,11 +2423,6 @@ character-reference-invalid@^1.0.0: resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - chokidar@^2.0.0, chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -2505,18 +2503,6 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-width@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" - integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== - cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" @@ -2969,7 +2955,7 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -2980,6 +2966,15 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -3354,7 +3349,7 @@ decompress@^4.0.0, decompress@^4.2.0: pify "^2.3.0" strip-dirs "^2.0.0" -deep-is@~0.1.3: +deep-is@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= @@ -3804,6 +3799,13 @@ enhanced-resolve@^4.3.0: memory-fs "^0.5.0" tapable "^1.0.0" +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + entities@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" @@ -4014,7 +4016,7 @@ eslint-rule-composer@^0.3.0: resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== -eslint-scope@5.1.0: +eslint-scope@5.1.0, eslint-scope@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== @@ -4030,47 +4032,35 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" - integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-utils@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== +eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== dependencies: eslint-visitor-keys "^1.1.0" -eslint-visitor-keys@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" - integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== - -eslint-visitor-keys@^1.3.0: +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== -eslint@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== +eslint@^7.6.0: + version "7.6.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.6.0.tgz#522d67cfaea09724d96949c70e7a0550614d64d6" + integrity sha512-QlAManNtqr7sozWm5TF4wIH9gmUm2hE3vNRUvyoYAa4y1l5/jxD/PQStEjBMQtCqZmSep8UxrcecI60hOpe61w== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" + chalk "^4.0.0" + cross-spawn "^7.0.2" debug "^4.0.1" doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" + enquirer "^2.3.5" + eslint-scope "^5.1.0" + eslint-utils "^2.1.0" + eslint-visitor-keys "^1.3.0" + espree "^7.2.0" + esquery "^1.2.0" esutils "^2.0.2" file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" @@ -4079,40 +4069,38 @@ eslint@^6.8.0: ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^7.0.0" is-glob "^4.0.0" js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" + levn "^0.4.1" + lodash "^4.17.19" minimatch "^3.0.4" - mkdirp "^0.5.1" natural-compare "^1.4.0" - optionator "^0.8.3" + optionator "^0.9.1" progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" table "^5.2.3" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== +espree@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.2.0.tgz#1c263d5b513dbad0ac30c4991b93ac354e948d69" + integrity sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g== dependencies: - acorn "^7.1.1" + acorn "^7.3.1" acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" + eslint-visitor-keys "^1.3.0" esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.0.1: +esquery@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== @@ -4292,15 +4280,6 @@ extend@3.0.2, extend@^3.0.0, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -4336,9 +4315,9 @@ fancy-log@^1.1.0, fancy-log@^1.3.2, fancy-log@^1.3.3: time-stamp "^1.0.0" fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^2.2.6: version "2.2.7" @@ -4369,7 +4348,7 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= @@ -4406,13 +4385,6 @@ figures@^1.3.5: escape-string-regexp "^1.0.5" object-assign "^4.1.0" -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - file-entry-cache@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-4.0.0.tgz#633567d15364aefe0b299e1e217735e8f3a9f6e8" @@ -5653,7 +5625,7 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -iconv-lite@0.4.24, iconv-lite@^0.4.24: +iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -5860,25 +5832,6 @@ ini@^1.3.4, ini@^1.3.5: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== -inquirer@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.1.0.tgz#1298a01859883e17c7264b82870ae1034f92dd29" - integrity sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg== - dependencies: - ansi-escapes "^4.2.1" - chalk "^3.0.0" - cli-cursor "^3.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.15" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.5.3" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - interpret@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" @@ -6395,9 +6348,9 @@ js-base64@^2.1.8, js-base64@^2.1.9: integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + version "3.14.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" + integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -6599,13 +6552,13 @@ levenary@^1.1.1: dependencies: leven "^3.1.0" -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" + prelude-ls "^1.2.1" + type-check "~0.4.0" "libass-wasm@https://github.com/jellyfin/JavascriptSubtitlesOctopus#4.0.0-jf-smarttv": version "4.0.0" @@ -7275,11 +7228,6 @@ mime@1.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - mimic-response@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" @@ -7412,11 +7360,6 @@ mute-stdout@^1.0.0: resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - nan@^2.12.1, nan@^2.13.2: version "2.14.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" @@ -7815,13 +7758,6 @@ once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: dependencies: wrappy "1" -onetime@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" - integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== - dependencies: - mimic-fn "^2.1.0" - openurl@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/openurl/-/openurl-1.1.1.tgz#3875b4b0ef7a52c156f0db41d4609dbb0f94b387" @@ -7834,17 +7770,17 @@ opn@5.3.0: dependencies: is-wsl "^1.1.0" -optionator@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" optipng-bin@^6.0.0: version "6.0.0" @@ -7886,7 +7822,7 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= @@ -8208,6 +8144,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -9118,10 +9059,10 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.1 source-map "^0.6.1" supports-color "^6.1.0" -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prepend-http@^1.0.1: version "1.0.4" @@ -9514,10 +9455,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== +regexpp@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" + integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== regexpu-core@^4.7.0: version "4.7.0" @@ -9831,14 +9772,6 @@ responselike@1.0.2: dependencies: lowercase-keys "^1.0.0" -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -9888,11 +9821,6 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - run-parallel@^1.1.9: version "1.1.9" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" @@ -9917,13 +9845,6 @@ rxjs@^5.5.6: dependencies: symbol-observable "1.0.1" -rxjs@^6.5.3: - version "6.5.5" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec" - integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== - dependencies: - tslib "^1.9.0" - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -10038,12 +9959,12 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.3.2, semver@^7.3.2: +semver@7.3.2, semver@^7.2.1, semver@^7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== -semver@^6.0.0, semver@^6.1.2, semver@^6.3.0: +semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -10162,11 +10083,23 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -10774,10 +10707,10 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-json-comments@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180" - integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w== +strip-json-comments@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== strip-outer@^1.0.0: version "1.0.1" @@ -11185,7 +11118,7 @@ through2@^4.0.2: dependencies: readable-stream "3" -through@^2.3.6, through@^2.3.8, through@~2.3.4: +through@^2.3.8, through@~2.3.4: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -11220,13 +11153,6 @@ timsort@^0.3.0: resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - to-absolute-glob@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" @@ -11361,11 +11287,16 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" -tslib@^1.10.0, tslib@^1.9.0: +tslib@^1.10.0: version "1.11.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== +tslib@^1.9.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" + integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -11383,17 +11314,12 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: - prelude-ls "~1.1.2" - -type-fest@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" - integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + prelude-ls "^1.2.1" type-fest@^0.13.1: version "0.13.1" @@ -12084,6 +12010,13 @@ which@1, which@^1.2.14, which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" @@ -12091,7 +12024,7 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -word-wrap@~1.2.3: +word-wrap@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== From 39a1d94c500134b45591a6d48fca02013cf8e159 Mon Sep 17 00:00:00 2001 From: matjaz321 Date: Sat, 1 Aug 2020 14:52:15 +0200 Subject: [PATCH 055/226] Migrated to es6 module --- package.json | 1 + src/controllers/livetvguideprovider.js | 50 +++++++++++++------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 17d175b7e7..efe1fcc2fa 100644 --- a/package.json +++ b/package.json @@ -207,6 +207,7 @@ "src/controllers/searchpage.js", "src/controllers/livetvtuner.js", "src/controllers/livetvstatus.js", + "src/controllers/livetvguideprovider.js", "src/controllers/shows/episodes.js", "src/controllers/shows/tvgenres.js", "src/controllers/shows/tvlatest.js", diff --git a/src/controllers/livetvguideprovider.js b/src/controllers/livetvguideprovider.js index 8f8b9f91c7..6ab195a088 100644 --- a/src/controllers/livetvguideprovider.js +++ b/src/controllers/livetvguideprovider.js @@ -1,30 +1,30 @@ -define(['events', 'loading', 'globalize'], function (events, loading, globalize) { - 'use strict'; +import events from 'events'; +import loading from 'loading'; +import globalize from 'globalize'; - function onListingsSubmitted() { - Dashboard.navigate('livetvstatus.html'); - } +function onListingsSubmitted() { + Dashboard.navigate('livetvstatus.html'); +} - function init(page, type, providerId) { - var url = 'components/tvproviders/' + type + '.js'; +function init(page, type, providerId) { + const url = 'components/tvproviders/' + type + '.js'; - require([url], function (factory) { - var instance = new factory(page, providerId, {}); - events.on(instance, 'submitted', onListingsSubmitted); - instance.init(); - }); - } - - function loadTemplate(page, type, providerId) { - require(['text!./components/tvproviders/' + type + '.template.html'], function (html) { - page.querySelector('.providerTemplate').innerHTML = globalize.translateHtml(html); - init(page, type, providerId); - }); - } - - pageIdOn('pageshow', 'liveTvGuideProviderPage', function () { - loading.show(); - var providerId = getParameterByName('id'); - loadTemplate(this, getParameterByName('type'), providerId); + import(url).then(({default: factory}) => { + const instance = new factory(page, providerId, {}); + events.on(instance, 'submitted', onListingsSubmitted); + instance.init(); }); +} + +function loadTemplate(page, type, providerId) { + import('text!./../components/tvproviders/' + type + '.template.html').then(({default: html}) => { + page.querySelector('.providerTemplate').innerHTML = globalize.translateHtml(html); + init(page, type, providerId); + }); +} + +pageIdOn('pageshow', 'liveTvGuideProviderPage', function () { + loading.show(); + const providerId = getParameterByName('id'); + loadTemplate(this, getParameterByName('type'), providerId); }); From 716c9d71b2aac67af0f37efd57583040a68b94e6 Mon Sep 17 00:00:00 2001 From: Larvitar Date: Sat, 1 Aug 2020 12:52:26 +0000 Subject: [PATCH 056/226] Translated using Weblate (Polish) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pl/ --- src/strings/pl.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/strings/pl.json b/src/strings/pl.json index a141b975cb..3c4c9b3160 100644 --- a/src/strings/pl.json +++ b/src/strings/pl.json @@ -90,7 +90,7 @@ "ButtonMore": "Więcej", "ButtonNetwork": "Sieć", "ButtonNew": "Nowe", - "ButtonNextTrack": "Następna utwór", + "ButtonNextTrack": "Następny utwór", "ButtonOff": "Wyłącz", "ButtonOpen": "Otwórz", "ButtonParentalControl": "Kontrola rodzicielska", @@ -1564,5 +1564,8 @@ "EnableDetailsBanner": "Baner w szczegółach", "EnableDecodingColorDepth10Vp9": "Włącz 10-bitowe dekodowanie sprzętowe dla VP9", "EnableDecodingColorDepth10Hevc": "Włącz 10-bitowe dekodowanie sprzętowe dla HEVC", - "BoxSet": "Kolekcja" + "BoxSet": "Kolekcja", + "PreviousTrack": "Poprzedni", + "NextTrack": "Następny", + "LabelUnstable": "Niestabilny" } From ab52727254019450db9a9fab25bc5eb4cddc504a Mon Sep 17 00:00:00 2001 From: matjaz321 Date: Sat, 1 Aug 2020 15:32:57 +0200 Subject: [PATCH 057/226] Migrated livetvseriestimer to es6 module --- src/controllers/livetv/livetvseriestimers.js | 90 ++++++++++---------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/controllers/livetv/livetvseriestimers.js b/src/controllers/livetv/livetvseriestimers.js index c5d0da60d7..d645a66370 100644 --- a/src/controllers/livetv/livetvseriestimers.js +++ b/src/controllers/livetv/livetvseriestimers.js @@ -1,50 +1,52 @@ -define(['datetime', 'cardBuilder', 'imageLoader', 'apphost', 'loading', 'paper-icon-button-light', 'emby-button'], function (datetime, cardBuilder, imageLoader, appHost, loading) { - 'use strict'; +import cardBuilder from 'cardBuilder'; +import imageLoader from 'imageLoader'; +import loading from 'loading'; +import 'paper-icon-button-light'; +import 'emby-button'; - function renderTimers(context, timers) { - var html = ''; - html += cardBuilder.getCardsHtml({ - items: timers, - shape: 'auto', - defaultShape: 'portrait', - showTitle: true, - cardLayout: false, - preferThumb: 'auto', - coverImage: true, - overlayText: false, - showSeriesTimerTime: true, - showSeriesTimerChannel: true, - centerText: true, - overlayMoreButton: true, - lines: 3 - }); - var elem = context.querySelector('#items'); - elem.innerHTML = html; - imageLoader.lazyChildren(elem); - loading.hide(); - } +function renderTimers(context, timers) { + const html = cardBuilder.getCardsHtml({ + items: timers, + shape: 'auto', + defaultShape: 'portrait', + showTitle: true, + cardLayout: false, + preferThumb: 'auto', + coverImage: true, + overlayText: false, + showSeriesTimerTime: true, + showSeriesTimerChannel: true, + centerText: true, + overlayMoreButton: true, + lines: 3 + }); + const elem = context.querySelector('#items'); + elem.innerHTML = html; + imageLoader.lazyChildren(elem); + loading.hide(); +} - function reload(context, promise) { - loading.show(); - promise.then(function (result) { - renderTimers(context, result.Items); - }); - } +function reload(context, promise) { + loading.show(); + promise.then(function (result) { + renderTimers(context, result.Items); + }); +} - var query = { - SortBy: 'SortName', - SortOrder: 'Ascending' +const query = { + SortBy: 'SortName', + SortOrder: 'Ascending' +}; + +export default function (view, params, tabContent) { + let timersPromise; + const self = this; + + self.preRender = function () { + timersPromise = ApiClient.getLiveTvSeriesTimers(query); }; - return function (view, params, tabContent) { - var timersPromise; - var self = this; - self.preRender = function () { - timersPromise = ApiClient.getLiveTvSeriesTimers(query); - }; - - self.renderTab = function () { - reload(tabContent, timersPromise); - }; + self.renderTab = function () { + reload(tabContent, timersPromise); }; -}); +}; From 0c8e1994b79eebee5056c03bc1056b3d658c94ca Mon Sep 17 00:00:00 2001 From: matjaz321 Date: Sat, 1 Aug 2020 15:36:16 +0200 Subject: [PATCH 058/226] fixed linting errors --- src/controllers/livetv/livetvseriestimers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/livetv/livetvseriestimers.js b/src/controllers/livetv/livetvseriestimers.js index d645a66370..4f6bfaaa6a 100644 --- a/src/controllers/livetv/livetvseriestimers.js +++ b/src/controllers/livetv/livetvseriestimers.js @@ -49,4 +49,4 @@ export default function (view, params, tabContent) { self.renderTab = function () { reload(tabContent, timersPromise); }; -}; +} From 891f54563ba84b72e3b7c451fe331b949de85426 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 2 Aug 2020 01:23:57 +0900 Subject: [PATCH 059/226] change error message key --- src/components/imageeditor/imageeditor.js | 2 +- src/components/mediaLibraryEditor/mediaLibraryEditor.js | 2 +- src/controllers/dashboard/encodingsettings.js | 2 +- src/controllers/dashboard/general.js | 2 +- src/controllers/dashboard/users/usernew.js | 2 +- src/strings/ar.json | 2 +- src/strings/bg-bg.json | 2 +- src/strings/ca.json | 2 +- src/strings/cs.json | 2 +- src/strings/da.json | 2 +- src/strings/de.json | 2 +- src/strings/el.json | 2 +- src/strings/en-gb.json | 2 +- src/strings/en-us.json | 2 +- src/strings/es-ar.json | 2 +- src/strings/es-mx.json | 2 +- src/strings/es.json | 2 +- src/strings/es_419.json | 2 +- src/strings/fa.json | 2 +- src/strings/fi.json | 2 +- src/strings/fr.json | 2 +- src/strings/he.json | 2 +- src/strings/hr.json | 2 +- src/strings/hu.json | 2 +- src/strings/id.json | 2 +- src/strings/is-is.json | 2 +- src/strings/it.json | 2 +- src/strings/ja.json | 2 +- src/strings/kk.json | 2 +- src/strings/ko.json | 2 +- src/strings/lt-lt.json | 2 +- src/strings/lv.json | 2 +- src/strings/nb.json | 2 +- src/strings/nl.json | 2 +- src/strings/pl.json | 2 +- src/strings/pt-br.json | 2 +- src/strings/pt-pt.json | 2 +- src/strings/pt.json | 2 +- src/strings/ro.json | 2 +- src/strings/ru.json | 2 +- src/strings/sk.json | 2 +- src/strings/sl-si.json | 2 +- src/strings/sv.json | 2 +- src/strings/tr.json | 2 +- src/strings/vi.json | 2 +- src/strings/zh-cn.json | 2 +- src/strings/zh-hk.json | 2 +- src/strings/zh-tw.json | 2 +- 48 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index bb8bce269e..46e2dae999 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -217,7 +217,7 @@ import 'css!./imageeditor'; reload(context, null, focusContext); }, function () { import('alert').then(({default: alert}) => { - alert(globalize.translate('MessageDefaultError')); + alert(globalize.translate('ErrorDefault')); }); }); } diff --git a/src/components/mediaLibraryEditor/mediaLibraryEditor.js b/src/components/mediaLibraryEditor/mediaLibraryEditor.js index 66e7253401..0e68c6a289 100644 --- a/src/components/mediaLibraryEditor/mediaLibraryEditor.js +++ b/src/components/mediaLibraryEditor/mediaLibraryEditor.js @@ -85,7 +85,7 @@ import 'flexStyles'; refreshLibraryFromServer(dom.parentWithClass(button, 'dlg-libraryeditor')); }, () => { import('toast').then(({default: toast}) => { - toast(globalize.translate('MessageDefaultError')); + toast(globalize.translate('ErrorDefault')); }); }); }); diff --git a/src/controllers/dashboard/encodingsettings.js b/src/controllers/dashboard/encodingsettings.js index 2c133526bc..3a0ad24430 100644 --- a/src/controllers/dashboard/encodingsettings.js +++ b/src/controllers/dashboard/encodingsettings.js @@ -81,7 +81,7 @@ import libraryMenu from 'libraryMenu'; updateEncoder(form); }, function () { import('alert').then(({default: alert}) => { - alert(globalize.translate('MessageDefaultError')); + alert(globalize.translate('ErrorDefault')); }); Dashboard.processServerConfigurationUpdateResult(); diff --git a/src/controllers/dashboard/general.js b/src/controllers/dashboard/general.js index 9cf4092b5c..eb819dc415 100644 --- a/src/controllers/dashboard/general.js +++ b/src/controllers/dashboard/general.js @@ -52,7 +52,7 @@ import 'emby-button'; }); }, function () { import('alert').then(({default: alert}) => { - alert(globalize.translate('MessageDefaultError')); + alert(globalize.translate('ErrorDefault')); }); Dashboard.processServerConfigurationUpdateResult(); diff --git a/src/controllers/dashboard/users/usernew.js b/src/controllers/dashboard/users/usernew.js index ae3ac0baa9..d3ff449d02 100644 --- a/src/controllers/dashboard/users/usernew.js +++ b/src/controllers/dashboard/users/usernew.js @@ -89,7 +89,7 @@ import 'emby-checkbox'; }); }, function (response) { import('toast').then(({default: toast}) => { - toast(globalize.translate('MessageDefaultError')); + toast(globalize.translate('ErrorDefault')); }); loading.hide(); diff --git a/src/strings/ar.json b/src/strings/ar.json index 744ac928f0..d4ff757824 100644 --- a/src/strings/ar.json +++ b/src/strings/ar.json @@ -92,7 +92,7 @@ "CinemaModeConfigurationHelp": "الطور السينمائي يوفر أجواء سينمائية إلى قلب صالتك مع إمكانية تشغيل عروض إعلانية لأفلام أخرى وعرض مقدمات أخرى من انتقاءاتك قبل تشغيل الفيلم الرئيسي.", "CustomDlnaProfilesHelp": "إنشاء عرائض مخصوصه تستهدف جهازاً جديداً أو يمتطي حساباً نظامياً.", "DeathDateValue": "توفي: {0}", - "MessageDefaultError": "كان هناك خطأ في معالجة الطلب. الرجاء المحاولة لاحقاً.", + "ErrorDefault": "كان هناك خطأ في معالجة الطلب. الرجاء المحاولة لاحقاً.", "Delete": "حذف", "DeleteDeviceConfirmation": "هل أنت متأكد أنك تريد حذف هذا الجهاز؟ سيظهر الجهاز من جديد في المرة القادمة التي يسجل فها مستخدم دخوله عبره.", "DeleteImage": "حذف صورة", diff --git a/src/strings/bg-bg.json b/src/strings/bg-bg.json index ccdc906a9f..f24c10d980 100644 --- a/src/strings/bg-bg.json +++ b/src/strings/bg-bg.json @@ -882,7 +882,7 @@ "CinemaModeConfigurationHelp": "Режимът на кино носи театрално изживяване направо във вашата всекидневна с възможност за пускане на трейлъри и персонализирани интродукции преди основния филм.", "ChangingMetadataImageSettingsNewContent": "Промените в настройките за изтегляне на метаданни или изображения ще се прилагат само за ново съдържание, добавено към вашата библиотека. За да приложите промените към съществуващите заглавия, ще трябва да обновите метаданните им ръчно.", "DefaultMetadataLangaugeDescription": "Това са настройки по подразбиране и могат да се променят на база библиотека.", - "MessageDefaultError": "Възникна грешка при изпълнение на заявката. Моля опитайте по-късно.", + "ErrorDefault": "Възникна грешка при изпълнение на заявката. Моля опитайте по-късно.", "CustomDlnaProfilesHelp": "Създаване на персонализиран профил за целево устройство или заменяне на системния профил.", "CopyStreamURL": "Копиране URL на стрийма", "CopyStreamURLError": "Възникна грешка при копиране на URL.", diff --git a/src/strings/ca.json b/src/strings/ca.json index 90f5ce8930..cf6031e240 100644 --- a/src/strings/ca.json +++ b/src/strings/ca.json @@ -84,7 +84,7 @@ "ConfirmDeletion": "Confirma supressió", "Connect": "Connecta", "Continuing": "Continuant", - "MessageDefaultError": "Hi ha hagut un error processant la petició. Intenta-ho més tard si et plau.", + "ErrorDefault": "Hi ha hagut un error processant la petició. Intenta-ho més tard si et plau.", "Delete": "Esborra", "DeleteImage": "Esborra Imatge", "DeleteImageConfirmation": "Esteu segur que voleu suprimir aquesta imatge?", diff --git a/src/strings/cs.json b/src/strings/cs.json index 13ce07b62d..f35c368a50 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -131,7 +131,7 @@ "DatePlayed": "Datum přehrání", "DeathDateValue": "Zemřel: {0}", "Default": "Výchozí", - "MessageDefaultError": "Došlo k chybě při zpracování požadavku. Prosím zkuste to znovu později.", + "ErrorDefault": "Došlo k chybě při zpracování požadavku. Prosím zkuste to znovu později.", "DefaultMetadataLangaugeDescription": "Toto jsou vaše výchozí hodnoty a lze je přizpůsobit na základě jednotlivých knihoven.", "DefaultSubtitlesHelp": "Titulky jsou načteny na základě výchozích a vynucených nastavení ve vložených metadatech. Jazykové preference jsou vzaty v úvahu, pokud je k dispozici více možností.", "Delete": "Odstranit", diff --git a/src/strings/da.json b/src/strings/da.json index 265d322fc5..0f4433baff 100644 --- a/src/strings/da.json +++ b/src/strings/da.json @@ -119,7 +119,7 @@ "Continuing": "Forsættes", "CustomDlnaProfilesHelp": "Lav brugerdefinerede profiler til nye enheder eller for at overstyre en systemprofil.", "DeathDateValue": "Dødsdato: {0}", - "MessageDefaultError": "Det opstod en fejl ved behandlingen af forespørgslen. Prøv igen senere.", + "ErrorDefault": "Det opstod en fejl ved behandlingen af forespørgslen. Prøv igen senere.", "DefaultMetadataLangaugeDescription": "Dette er dine standarder og kan brugerdefineres på per-biblioteks basis.", "Delete": "Slet", "DeleteDeviceConfirmation": "Er du sikker på du ønsker at slette denne enhed? Den vil dukke op igen næste gang en bruger logger ind med den.", diff --git a/src/strings/de.json b/src/strings/de.json index f88361c1d2..b5c52588c9 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -143,7 +143,7 @@ "DatePlayed": "Abgespielt am", "DeathDateValue": "Gestorben: {0}", "Default": "Standard", - "MessageDefaultError": "Es gab einen Fehler beim verarbeiten der Anfrage. Bitte versuche es später erneut.", + "ErrorDefault": "Es gab einen Fehler beim verarbeiten der Anfrage. Bitte versuche es später erneut.", "DefaultMetadataLangaugeDescription": "Das sind deine Default-Werte, die bibliotheksspezifisch verändert werden können.", "DefaultSubtitlesHelp": "Untertitel werden gemäß der Standard- und Erzwungen-Ansicht aus den eingebetteten Metadaten geladen. Spracheinstellungen werden zur Verfügung gestellt, wenn mehrere Sprachen verfügbar sind.", "Delete": "Löschen", diff --git a/src/strings/el.json b/src/strings/el.json index 5b3f1afc22..fe22f110c3 100644 --- a/src/strings/el.json +++ b/src/strings/el.json @@ -146,7 +146,7 @@ "DatePlayed": "Ημερομηνία Αναπαραγωγής", "DeathDateValue": "Πέθανε: {0}", "Default": "Προεπιλογή", - "MessageDefaultError": "Παρουσιάστηκε σφάλμα κατά την επεξεργασία του αιτήματός σας. Παρακαλώ δοκιμάστε ξανά αργότερα.", + "ErrorDefault": "Παρουσιάστηκε σφάλμα κατά την επεξεργασία του αιτήματός σας. Παρακαλώ δοκιμάστε ξανά αργότερα.", "DefaultMetadataLangaugeDescription": "Αυτές είναι οι προεπιλογές σας και μπορούν να προσαρμοστούν σε βάση ανά βιβλιοθήκη.", "DefaultSubtitlesHelp": "Οι υπότιτλοι φορτώνονται με βάση τις προεπιλεγμένες και αναγκασμένες σημαίες στα ενσωματωμένα μεταδεδομένα. Οι προτιμήσεις γλώσσας εξετάζονται όταν υπάρχουν πολλές επιλογές.", "Delete": "Διαγραφή", diff --git a/src/strings/en-gb.json b/src/strings/en-gb.json index 58bd67426e..e1c2e52a30 100644 --- a/src/strings/en-gb.json +++ b/src/strings/en-gb.json @@ -202,7 +202,7 @@ "DatePlayed": "Date played", "DeathDateValue": "Died: {0}", "Default": "Default", - "MessageDefaultError": "There was an error processing the request. Please try again later.", + "ErrorDefault": "There was an error processing the request. Please try again later.", "DefaultSubtitlesHelp": "Subtitles are loaded based on the default and forced flags in the embedded metadata. Language preferences are considered when multiple options are available.", "Delete": "Delete", "DeleteDeviceConfirmation": "Are you sure you wish to delete this device? It will reappear the next time a user signs in with it.", diff --git a/src/strings/en-us.json b/src/strings/en-us.json index f0e24d63ab..82d2d796f1 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -178,7 +178,7 @@ "DatePlayed": "Date played", "DeathDateValue": "Died: {0}", "Default": "Default", - "MessageDefaultError": "There was an error processing the request. Please try again later.", + "ErrorDefault": "There was an error processing the request. Please try again later.", "DefaultMetadataLangaugeDescription": "These are your defaults and can be customized on a per-library basis.", "DefaultSubtitlesHelp": "Subtitles are loaded based on the default and forced flags in the embedded metadata. Language preferences are considered when multiple options are available.", "DeinterlaceMethodHelp": "Select the deinterlacing method to use when transcoding interlaced content.", diff --git a/src/strings/es-ar.json b/src/strings/es-ar.json index c39e873be7..52c98fbc52 100644 --- a/src/strings/es-ar.json +++ b/src/strings/es-ar.json @@ -201,7 +201,7 @@ "DatePlayed": "Fecha de reproducción", "DeathDateValue": "Muerte: {0}", "Default": "Predeterminado", - "MessageDefaultError": "Hubo un error procesando la solicitud. Por favor intentalo nuevamente mas tarde.", + "ErrorDefault": "Hubo un error procesando la solicitud. Por favor intentalo nuevamente mas tarde.", "DefaultMetadataLangaugeDescription": "Estos son tus predeterminados y pueden ser personalizados por librería únicamente.", "Delete": "Borrar", "DeleteDeviceConfirmation": "Estas seguro que quieres borrar este dispositivo? Este va a volver a aparecer cuando una persona se registre.", diff --git a/src/strings/es-mx.json b/src/strings/es-mx.json index ef23d21528..98b9fd4ab0 100644 --- a/src/strings/es-mx.json +++ b/src/strings/es-mx.json @@ -156,7 +156,7 @@ "DatePlayed": "Fecha de reproducción", "DeathDateValue": "Falleció: {0}", "Default": "Por defecto", - "MessageDefaultError": "Ha ocurrido un error al procesar la solicitud. Por favor, inténtalo de nuevo más tarde.", + "ErrorDefault": "Ha ocurrido un error al procesar la solicitud. Por favor, inténtalo de nuevo más tarde.", "DefaultMetadataLangaugeDescription": "Estos son sus valores por defecto y pueden ser personalizados en cada biblioteca.", "DefaultSubtitlesHelp": "Los subtítulos se cargan basados en los indicadores «por defecto» y «forzado» incluidos en los metadatos. Las preferencias de idioma son consideradas cuando hay múltiples opciones disponibles.", "Delete": "Eliminar", diff --git a/src/strings/es.json b/src/strings/es.json index 1aebb394ab..44456fb83e 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -138,7 +138,7 @@ "CustomDlnaProfilesHelp": "Crear un perfil personalizado para un nuevo dispositivo o reemplazar un perfil del sistema.", "DeathDateValue": "Murió: {0}", "Default": "Por defecto", - "MessageDefaultError": "Ha habido un error procesando la solicitud. Por favor inténtalo más tarde.", + "ErrorDefault": "Ha habido un error procesando la solicitud. Por favor inténtalo más tarde.", "DefaultMetadataLangaugeDescription": "Estos son tus ajustes y se pueden personalizar para cada biblioteca.", "DefaultSubtitlesHelp": "Los subtítulos que se utilizarán dependerán de como estén etiquetadas las pistas de los archivos (si \"por defecto\" o \"forzado\"). Los ajustes de idioma se tienen en cuenta cuando hay varias opciones disponibles.", "Delete": "Borrar", diff --git a/src/strings/es_419.json b/src/strings/es_419.json index 3ce724f19b..fad50d979a 100644 --- a/src/strings/es_419.json +++ b/src/strings/es_419.json @@ -1374,7 +1374,7 @@ "DeinterlaceMethodHelp": "Seleccione el método de desentrelazado que se usará al transcodificar contenido entrelazado.", "DefaultSubtitlesHelp": "Los subtítulos se cargan basados en los indicadores «por defecto» y «forzado» incluidos en los metadatos. Las preferencias de idioma son consideradas cuando hay múltiples opciones disponibles.", "DefaultMetadataLangaugeDescription": "Estos son sus valores por defecto y pueden ser personalizados en cada biblioteca.", - "MessageDefaultError": "Ha ocurrido un error al procesar la solicitud. Por favor, inténtalo de nuevo más tarde.", + "ErrorDefault": "Ha ocurrido un error al procesar la solicitud. Por favor, inténtalo de nuevo más tarde.", "Default": "Por defecto", "DeathDateValue": "Falleció: {0}", "DatePlayed": "Fecha de reproducción", diff --git a/src/strings/fa.json b/src/strings/fa.json index 3535a3693d..fa2e67474c 100644 --- a/src/strings/fa.json +++ b/src/strings/fa.json @@ -272,7 +272,7 @@ "DeleteDeviceConfirmation": "آیا از حذف این دستگاه اطمینان دارید؟ هنگامی که یک کاربر دوباره با آن دستگاه وارد شود، دوباره نمایش داده می‌شود.", "Delete": "حذف", "DefaultMetadataLangaugeDescription": "این موارد پیشفرض‌های شماست و می‌توانید برای هر کتابخانه آن را شخصی سازی کنید.", - "MessageDefaultError": "خطایی در پردازش درخواست رخ داد. لطفا اندکی بعد دوباره تلاش کنید.", + "ErrorDefault": "خطایی در پردازش درخواست رخ داد. لطفا اندکی بعد دوباره تلاش کنید.", "Default": "پیشفرض", "DeathDateValue": "تلف شد: {0}", "DatePlayed": "تاریخ پخش شده", diff --git a/src/strings/fi.json b/src/strings/fi.json index 147d501f46..ab385484f0 100644 --- a/src/strings/fi.json +++ b/src/strings/fi.json @@ -201,7 +201,7 @@ "DateAdded": "Lisäyspäivämäärä", "DatePlayed": "Toistopäivämäärä", "Default": "Oletus", - "MessageDefaultError": "Pyynnön käsittelyssä tapahtui virhe. Yritä myöhemmin uudelleen.", + "ErrorDefault": "Pyynnön käsittelyssä tapahtui virhe. Yritä myöhemmin uudelleen.", "DefaultMetadataLangaugeDescription": "Nämä ovat sinun oletuksetasetukset ja niitä voidaan muokata kirjastokohtaisesti.", "DefaultSubtitlesHelp": "Tekstitykset ladataan pakotettu- ja oletusmäärityksien upotetun metadatan mukaan. Kieliasetukset otetaan huomioon, kun on enemmän kuin yksi tekstitys josta valita.", "DeleteDeviceConfirmation": "Oletko varma, että haluat positaa tämän laitteen? Se ilmaantuu uudelleen seuraavan kerran, kun jokin käyttäjä kirjautuu sillä.", diff --git a/src/strings/fr.json b/src/strings/fr.json index 8d9c0818bc..9122b1861d 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -155,7 +155,7 @@ "DatePlayed": "Date de lecture", "DeathDateValue": "Décédé(e) le {0}", "Default": "Par défaut", - "MessageDefaultError": "Il y a eu une erreur lors de l'exécution de la requête. Veuillez réessayer plus tard.", + "ErrorDefault": "Il y a eu une erreur lors de l'exécution de la requête. Veuillez réessayer plus tard.", "DefaultMetadataLangaugeDescription": "Ce sont vos réglages par défaut. Ils peuvent être personnalisés pour chaque médiathèque.", "DefaultSubtitlesHelp": "Les sous-titres seront chargés selon les marqueurs par défaut et forcé dans les métadonnées intégrées. Les langues préférées seront utilisées quand plusieurs options seront disponibles.", "Delete": "Supprimer", diff --git a/src/strings/he.json b/src/strings/he.json index 7624080423..29824e4c3e 100644 --- a/src/strings/he.json +++ b/src/strings/he.json @@ -53,7 +53,7 @@ "ConfirmDeletion": "אשר מחיקה", "Continuing": "ממשיך", "CustomDlnaProfilesHelp": "צור פרופיל מותאם אישית למכשיר חדש או לעקיפת פרופיל מערכת.", - "MessageDefaultError": "אירעה שגיאה בעיבוד הבקשה. בבקשה נסה שוב מאוחר יותר.", + "ErrorDefault": "אירעה שגיאה בעיבוד הבקשה. בבקשה נסה שוב מאוחר יותר.", "Delete": "מחק", "DeleteImage": "מחק תמונה", "DeleteImageConfirmation": "האם אתה בטוח שברצונך למחוק תמונה זו?", diff --git a/src/strings/hr.json b/src/strings/hr.json index 50e8f7ffaa..ed534a8d95 100644 --- a/src/strings/hr.json +++ b/src/strings/hr.json @@ -106,7 +106,7 @@ "Continuing": "Nastavlja se", "CustomDlnaProfilesHelp": "Kreiraj prilagođeni profili za novi uređaj ili doradi neki od sistemskih profila.", "DeathDateValue": "Umro: {0}", - "MessageDefaultError": "Došlo je do pogreške prilikom obrade zahtjeva. Molimo pokušajte ponovo kasnije.", + "ErrorDefault": "Došlo je do pogreške prilikom obrade zahtjeva. Molimo pokušajte ponovo kasnije.", "Delete": "Izbriši", "DeleteDeviceConfirmation": "Jeste li sigurni da želite izbrisati ovaj uređaj? Pojavit će se sljedeći put kad se korisnik prijavi s njim.", "DeleteImage": "Izbriši sliku", diff --git a/src/strings/hu.json b/src/strings/hu.json index f05472601f..31a26935ef 100644 --- a/src/strings/hu.json +++ b/src/strings/hu.json @@ -645,7 +645,7 @@ "CustomDlnaProfilesHelp": "Hozz létre egyéni profilt az új eszközhöz, vagy módosítsd a rendszerprofilt.", "DeathDateValue": "Elhunyt: {0}", "Default": "Alapértelmezett", - "MessageDefaultError": "Hiba történt a kérés feldolgozása során. Kérlek próbáld újra később.", + "ErrorDefault": "Hiba történt a kérés feldolgozása során. Kérlek próbáld újra később.", "DefaultMetadataLangaugeDescription": "Ezek az alapértelmezettek, és könyvtáranként testre szabhatók.", "DeleteDeviceConfirmation": "Biztosan törölni szeretnéd ezt az eszközt? Legközelebb akkor jelenik meg, amikor a felhasználó bejelentkezik róla.", "DeleteImage": "Kép törlése", diff --git a/src/strings/id.json b/src/strings/id.json index 71641a435a..b0eb49d9df 100644 --- a/src/strings/id.json +++ b/src/strings/id.json @@ -56,7 +56,7 @@ "Actor": "Aktor", "Delete": "Hapus", "DefaultMetadataLangaugeDescription": "Berikut ini adalah standar Anda dan dapat dikustomisasi pada tiap pustakanya.", - "MessageDefaultError": "Terdapat galat dalam memproses permintaan. Silakan coba kembali nanti.", + "ErrorDefault": "Terdapat galat dalam memproses permintaan. Silakan coba kembali nanti.", "Default": "Standar", "DeathDateValue": "Meninggal: {0}", "DatePlayed": "Tanggal dimainkan", diff --git a/src/strings/is-is.json b/src/strings/is-is.json index 21dfe6a472..f46de26e59 100644 --- a/src/strings/is-is.json +++ b/src/strings/is-is.json @@ -380,7 +380,7 @@ "DirectStreamHelp2": "Beint streymi á skrá notar mjög litið vinnsluafl án þess að tapa myndgæðum.", "Descending": "Niður", "DeleteImageConfirmation": "Ertu viss um að þú viljir eyða þessari mynd?", - "MessageDefaultError": "Villa varð við vinnslu beiðninnar. Reyndu aftur síðar.", + "ErrorDefault": "Villa varð við vinnslu beiðninnar. Reyndu aftur síðar.", "DeathDateValue": "Dó: {0}", "DatePlayed": "Dagsetning spilað", "DateAdded": "Dagsetning bætt við", diff --git a/src/strings/it.json b/src/strings/it.json index d3d5f93578..dc1340efe6 100644 --- a/src/strings/it.json +++ b/src/strings/it.json @@ -145,7 +145,7 @@ "DatePlayed": "Visto il", "DeathDateValue": "Morto: {0}", "Default": "Predefinito", - "MessageDefaultError": "Si è verificato un errore durante l'elaborazione della richiesta. Si prega di riprovare più tardi.", + "ErrorDefault": "Si è verificato un errore durante l'elaborazione della richiesta. Si prega di riprovare più tardi.", "DefaultMetadataLangaugeDescription": "Queste sono le tue impostazioni predefinite e possono essere personalizzate per ogni libreria.", "DefaultSubtitlesHelp": "I sottotitoli vengono letti in base agli attributi predefiniti e forzati dai metadati integrati. Le preferenze di lingua sono prese in considerazione quando sono disponibili più opzioni.", "Delete": "Elimina", diff --git a/src/strings/ja.json b/src/strings/ja.json index 0ea7eeb250..ea0fccedfa 100644 --- a/src/strings/ja.json +++ b/src/strings/ja.json @@ -157,7 +157,7 @@ "DateAdded": "追加日時", "DatePlayed": "再生日時", "Default": "デフォルト", - "MessageDefaultError": "要求の処理中にエラーが発生しました。 後でもう一度やり直してください。", + "ErrorDefault": "要求の処理中にエラーが発生しました。 後でもう一度やり直してください。", "DefaultMetadataLangaugeDescription": "これらはデフォルトであり、ライブラリごとにカスタマイズすることができます。", "DefaultSubtitlesHelp": "字幕は、埋め込みメタデータのデフォルトフラグと強制フラグに基づいてロードされます。 複数のオプションが利用可能な場合は、言語設定が考慮されます。", "Delete": "削除", diff --git a/src/strings/kk.json b/src/strings/kk.json index 521dcfad5e..e4eb57a72d 100644 --- a/src/strings/kk.json +++ b/src/strings/kk.json @@ -161,7 +161,7 @@ "DatePlayed": "Oınatylǵan kúni", "DeathDateValue": "Ólgeni: {0}", "Default": "Ádepki", - "MessageDefaultError": "Saýal óńdelý kezinde qate oryn aldy. Áreketti keıin qaıtalańyz.", + "ErrorDefault": "Saýal óńdelý kezinde qate oryn aldy. Áreketti keıin qaıtalańyz.", "DefaultMetadataLangaugeDescription": "Bular sizdiń ádepki maǵynalaryńyz jáne ár tasyǵyshhana negizinde teńsheýge bolady.", "DefaultSubtitlesHelp": "Sýbtıtrler engizilgen metaderekterdegi ádepki jáne májbúrli jalaýshalary negizinde júktelip alynady. Birneshe opsıa qoljetimdi bolǵanda til teńshelimi qarastyrylady.", "Delete": "Joıý", diff --git a/src/strings/ko.json b/src/strings/ko.json index 68f963dea7..53edeed17a 100644 --- a/src/strings/ko.json +++ b/src/strings/ko.json @@ -86,7 +86,7 @@ "Connect": "접속", "CustomDlnaProfilesHelp": "새 장치를 대상으로 하거나 시스템 프로필을 재정의 할 사용자 지정 프로필을 만듭니다.", "DeathDateValue": "사망: {0}", - "MessageDefaultError": "요청을 처리하는 중에 오류가 발생했습니다. 나중에 다시 시도하십시오.", + "ErrorDefault": "요청을 처리하는 중에 오류가 발생했습니다. 나중에 다시 시도하십시오.", "DefaultMetadataLangaugeDescription": "이는 기본값이며 라이브러리별로 사용자 정의될 수 있습니다.", "Delete": "제거", "DeleteImage": "이미지 제거", diff --git a/src/strings/lt-lt.json b/src/strings/lt-lt.json index 6726c85291..8599c332c5 100644 --- a/src/strings/lt-lt.json +++ b/src/strings/lt-lt.json @@ -65,7 +65,7 @@ "ConfirmDeletion": "Patvirtinti trynimą", "Continuing": "Tęsiamas", "CustomDlnaProfilesHelp": "Sukurti kitą profilį naujam įrenginiui ar pakeisti sistemos profilį.", - "MessageDefaultError": "Įvyko klaida vykdant užklausą. Pabandykite vėliau.", + "ErrorDefault": "Įvyko klaida vykdant užklausą. Pabandykite vėliau.", "Delete": "Ištrinti", "DeleteMedia": "Trinti mediją", "DeviceAccessHelp": "Tai taikoma tik įrenginiams, kurie gali būti identifikuojami, ir neuždraus prieigos per naršyklę. Vartotojo įrenginio prieigos filtravimas neleis jiems naudotis naujais įrenginiais kol jie nepatvirtinti čia.", diff --git a/src/strings/lv.json b/src/strings/lv.json index 329354d93b..4a0addb70c 100644 --- a/src/strings/lv.json +++ b/src/strings/lv.json @@ -975,7 +975,7 @@ "DeleteMedia": "Dzēst mediju", "DeleteImageConfirmation": "Vai tu tiešām vēlies izdzēst šo attēlu?", "DeleteDeviceConfirmation": "Vai tu tiešām vēlies noņemt šo ierīci? Tā parādīsies atkārtoti nākamo reizi, kad lietotājs ieiet ar to.", - "MessageDefaultError": "Apstrādājot pieprasījumu notika kļūda. Pēc brītiņa lūdzu mēģini vēlreiz.", + "ErrorDefault": "Apstrādājot pieprasījumu notika kļūda. Pēc brītiņa lūdzu mēģini vēlreiz.", "DeathDateValue": "Miris: {0}", "ConfirmEndPlayerSession": "Vai jūs gribat izslēgt Jellyfin uz {0}?", "ConfirmDeleteItems": "Dzēšot šos vienumus, tie tiks izdzēsti gan no jūsu failu sistēmas, gan mediju bibliotēkas. Vai tiešām turpināt?", diff --git a/src/strings/nb.json b/src/strings/nb.json index ee1905b7e2..8df80afaa8 100644 --- a/src/strings/nb.json +++ b/src/strings/nb.json @@ -126,7 +126,7 @@ "Continuing": "Fortsetter", "CustomDlnaProfilesHelp": "Lag en tilpasset profil til en ny enhet eller for å overstyre en system-profil.", "DeathDateValue": "Døde: {0}", - "MessageDefaultError": "Det oppstod en feil under behandling av forespørselen. Vennligst prøv igjen senere.", + "ErrorDefault": "Det oppstod en feil under behandling av forespørselen. Vennligst prøv igjen senere.", "DefaultMetadataLangaugeDescription": "Dette er standardverdiene dine, de kan også tilpasses per biblioteksbasis.", "Delete": "Slett", "DeleteDeviceConfirmation": "Er du sikker på at du ønsker å slette denne enheten? Den vil gjenoppstå neste gang en bruker logger inn med den.", diff --git a/src/strings/nl.json b/src/strings/nl.json index c185c429b8..c27ea0ef96 100644 --- a/src/strings/nl.json +++ b/src/strings/nl.json @@ -149,7 +149,7 @@ "DatePlayed": "Datum afgespeeld", "DeathDateValue": "Overleden: {0}", "Default": "Standaard", - "MessageDefaultError": "Er is een fout opgetreden. Probeer later opnieuw.", + "ErrorDefault": "Er is een fout opgetreden. Probeer later opnieuw.", "DefaultMetadataLangaugeDescription": "Dit zijn uw standaardinstellingen en kunnen per bibliotheek worden aangepast.", "DefaultSubtitlesHelp": "Ondertitels worden geladen op basis van de standaard en geforceerd markeringen in de ingesloten metadata. Indien meerdere opties aanwezig zijn zal rekening worden gehouden met de taalvoorkeuren.", "Delete": "Verwijderen", diff --git a/src/strings/pl.json b/src/strings/pl.json index cf82877cc4..11822afb8e 100644 --- a/src/strings/pl.json +++ b/src/strings/pl.json @@ -160,7 +160,7 @@ "DatePlayed": "Data odtwarzania", "DeathDateValue": "Zmarły: {0}", "Default": "Domyślny", - "MessageDefaultError": "Wystąpił błąd podczas przetwarzania żądania. Proszę spróbować ponownie później.", + "ErrorDefault": "Wystąpił błąd podczas przetwarzania żądania. Proszę spróbować ponownie później.", "DefaultMetadataLangaugeDescription": "To są twoje ustawienia domyślne. Możesz je zmienić dla każdej biblioteki osobno.", "DefaultSubtitlesHelp": "Napisy będą wczytywane w oparciu o znaczniki metadanych ścieżek dźwiękowych. Preferencje językowe brane są pod uwagę, gdy dostępnych jest wiele możliwości.", "Delete": "Usuń", diff --git a/src/strings/pt-br.json b/src/strings/pt-br.json index b86508e9db..9c227f8809 100644 --- a/src/strings/pt-br.json +++ b/src/strings/pt-br.json @@ -153,7 +153,7 @@ "DatePlayed": "Data de reprodução", "DeathDateValue": "Morte: {0}", "Default": "Padrão", - "MessageDefaultError": "Ocorreu um erro ao processar o pedido. Por favor, tente novamente mais tarde.", + "ErrorDefault": "Ocorreu um erro ao processar o pedido. Por favor, tente novamente mais tarde.", "DefaultMetadataLangaugeDescription": "Estas são suas configurações padrão e podem ser personalizadas por biblioteca.", "DefaultSubtitlesHelp": "Legendas são carregadas com base nas configurações padrão e de legendas forçadas nos metadados incorporados. As preferências de idioma são consideradas quando existem múltiplas opções disponíveis.", "Delete": "Excluir", diff --git a/src/strings/pt-pt.json b/src/strings/pt-pt.json index 5f51f56763..f48f47befd 100644 --- a/src/strings/pt-pt.json +++ b/src/strings/pt-pt.json @@ -915,7 +915,7 @@ "DirectStreamHelp2": "Reprodução direta de um ficheiro requer pouco processamento e não implica perda de qualidade num vídeo.", "DefaultSubtitlesHelp": "As legendas são carregadas com base nas definições por defeito ou forçado nos metadados. As preferências de idioma são consideradas quando existem múltiplas opções disponíveis.", "DefaultMetadataLangaugeDescription": "Estes são os valores por defeito que podem ser customizados para cada uma das bibliotecas.", - "MessageDefaultError": "Ocorreu um erro a processar o pedido. Por favor, tente novamente mais tarde.", + "ErrorDefault": "Ocorreu um erro a processar o pedido. Por favor, tente novamente mais tarde.", "Default": "Por defeito", "DeathDateValue": "Faleceu: {0}", "DatePlayed": "Reproduzido a", diff --git a/src/strings/pt.json b/src/strings/pt.json index 0640f82870..6b6f793ffb 100644 --- a/src/strings/pt.json +++ b/src/strings/pt.json @@ -919,7 +919,7 @@ "DeleteDeviceConfirmation": "Tem a certeza que deseja remover este dispositivo? Reaparecerá na próxima vez que o utilizador inicie sessão a partir dele.", "Delete": "Remover", "DefaultSubtitlesHelp": "As legendas são carregadas com base nas definições por omissão ou forçado nos metadados. As preferências de idioma são consideradas quando existem múltiplas opções disponíveis.", - "MessageDefaultError": "Ocorreu um erro ao processar o pedido. Por favor, tente novamente mais tarde.", + "ErrorDefault": "Ocorreu um erro ao processar o pedido. Por favor, tente novamente mais tarde.", "Default": "Por omissão", "DeathDateValue": "Faleceu: {0}", "DatePlayed": "Reproduzido a", diff --git a/src/strings/ro.json b/src/strings/ro.json index 9996a8fe70..3ea72217bd 100644 --- a/src/strings/ro.json +++ b/src/strings/ro.json @@ -345,7 +345,7 @@ "DatePlayed": "Data redării", "DeathDateValue": "Mort: {0}", "Default": "Implicit", - "MessageDefaultError": "A fost o eroare în procesarea cererii. Vă rugam încercați din nou mai târziu.", + "ErrorDefault": "A fost o eroare în procesarea cererii. Vă rugam încercați din nou mai târziu.", "DeleteImageConfirmation": "Sigur doriți să ștergeți această imagine?", "ButtonRename": "Redenumește", "ButtonRepeat": "Repetă", diff --git a/src/strings/ru.json b/src/strings/ru.json index edc7acdd4f..b24b8ab3ef 100644 --- a/src/strings/ru.json +++ b/src/strings/ru.json @@ -163,7 +163,7 @@ "DatePlayed": "Дата воспроизведения", "DeathDateValue": "Дата смерти: {0}", "Default": "По умолчанию", - "MessageDefaultError": "Произошла ошибка при обработке запроса. Повторите попытку позже.", + "ErrorDefault": "Произошла ошибка при обработке запроса. Повторите попытку позже.", "DefaultMetadataLangaugeDescription": "Они являются значениями по умолчанию и могут быть подстроены индивидуально для каждой медиатеки.", "DefaultSubtitlesHelp": "Загрузки субтитров определяются флагами \"По умолчанию\" и \"Форсированные\" во внедрённых метаданных. Языковые настройки учитываются при наличии нескольких опций.", "Delete": "Удалить", diff --git a/src/strings/sk.json b/src/strings/sk.json index 579420920b..7b6331aa4d 100644 --- a/src/strings/sk.json +++ b/src/strings/sk.json @@ -110,7 +110,7 @@ "DateAdded": "Dátum pridania", "DatePlayed": "Dátum prehrania", "DeathDateValue": "Zomrel/a: {0}", - "MessageDefaultError": "Pri spracovaní požiadavky došlo k chybe. Prosím, skúste to neskôr znova.", + "ErrorDefault": "Pri spracovaní požiadavky došlo k chybe. Prosím, skúste to neskôr znova.", "Delete": "Zmazať", "DeleteDeviceConfirmation": "Ste si istý, že chcete odstrániť toto zariadenie? Objaví sa znovu, keď sa ním používateľ nabudúce prihlási.", "DeleteImage": "Zmazať obrázok", diff --git a/src/strings/sl-si.json b/src/strings/sl-si.json index fd9dde8302..f0f7509010 100644 --- a/src/strings/sl-si.json +++ b/src/strings/sl-si.json @@ -257,7 +257,7 @@ "DeleteImage": "Izbriši sliko", "Delete": "Izbiši", "DefaultMetadataLangaugeDescription": "To so vaše privzete nastavitve, ki jih lahko spreminjate za posamezno knjižnico.", - "MessageDefaultError": "Prišlo je do težave pri obdelavi zahteve. Poskusite ponovno kasneje.", + "ErrorDefault": "Prišlo je do težave pri obdelavi zahteve. Poskusite ponovno kasneje.", "Default": "Privzeto", "DeathDateValue": "Smrt: {0}", "DatePlayed": "Predvajano", diff --git a/src/strings/sv.json b/src/strings/sv.json index 7ab2afc867..16357498af 100644 --- a/src/strings/sv.json +++ b/src/strings/sv.json @@ -145,7 +145,7 @@ "DatePlayed": "Senast visad", "DeathDateValue": "Död: {0}", "Default": "Standard", - "MessageDefaultError": "Ett fel uppstd vid begäran. Försök igen senare.", + "ErrorDefault": "Ett fel uppstd vid begäran. Försök igen senare.", "DefaultSubtitlesHelp": "Undertexter visas baserat på standardspråk och tvingande undertexter i den inbäddade metadatan. Förvalsspråk kommer väljas när fler val är möjliga.", "Delete": "Ta bort", "DeleteDeviceConfirmation": "Är du säker på att du vill ta bort den här enheten? Den kommer att dyka upp igen nästa gång en användare kopplar upp sig med den.", diff --git a/src/strings/tr.json b/src/strings/tr.json index eb89293759..194ff3c1c5 100644 --- a/src/strings/tr.json +++ b/src/strings/tr.json @@ -421,7 +421,7 @@ "DatePlayed": "Oynanan tarih", "DeathDateValue": "Öldü: {0}", "Default": "Varsayılan", - "MessageDefaultError": "İsteğin işlenmesi sırasında bir hata oluştu. Lütfen daha sonra tekrar deneyiniz.", + "ErrorDefault": "İsteğin işlenmesi sırasında bir hata oluştu. Lütfen daha sonra tekrar deneyiniz.", "DefaultMetadataLangaugeDescription": "Bunlar varsayılan ayarlarınızdır ve kitaplık bazında özelleştirilebilir.", "DeleteUserConfirmation": "Bu kullanıcıyı silmek istediğinden emin misin?", "Depressed": "Bunalımlı", diff --git a/src/strings/vi.json b/src/strings/vi.json index d4b120c61c..823eca0a9d 100644 --- a/src/strings/vi.json +++ b/src/strings/vi.json @@ -237,7 +237,7 @@ "ButtonSignIn": "Đăng nhập", "ButtonShutdown": "Tắt", "ButtonSettings": "Cài đặt", - "MessageDefaultError": "Có lỗi xảy ra trong lúc xử lý yêu cầu của bạn. Xin hãy thử lại sau.", + "ErrorDefault": "Có lỗi xảy ra trong lúc xử lý yêu cầu của bạn. Xin hãy thử lại sau.", "Default": "Mặc định", "DeathDateValue": "Không hoạt động: {0}", "DatePlayed": "Ngày phát", diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index dd2ea6be7d..eaf358a6ce 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -148,7 +148,7 @@ "DatePlayed": "播放日期", "DeathDateValue": "去世:{0}", "Default": "默认", - "MessageDefaultError": "处理请求时发生错误。请稍后尝试。", + "ErrorDefault": "处理请求时发生错误。请稍后尝试。", "DefaultMetadataLangaugeDescription": "这些是你的默认设置并且可以在你的每个媒体库中被单独自定义。", "DefaultSubtitlesHelp": "字幕将基于内嵌元数据中的“默认”标志和“强制”标志来载入。当多个选项可用时,将根据语言偏好决定。", "Delete": "删除", diff --git a/src/strings/zh-hk.json b/src/strings/zh-hk.json index da68975e7d..97e7b5633a 100644 --- a/src/strings/zh-hk.json +++ b/src/strings/zh-hk.json @@ -419,7 +419,7 @@ "DeleteMedia": "刪除媒體", "DeleteImageConfirmation": "你確定要刪除此圖片嗎?", "DeleteImage": "刪除圖片", - "MessageDefaultError": "處理此請求時發生錯誤,請稍後再嘗試。", + "ErrorDefault": "處理此請求時發生錯誤,請稍後再嘗試。", "Default": "預設", "DateAdded": "日期已新增", "CopyStreamURLError": "複製URL時發生錯誤。", diff --git a/src/strings/zh-tw.json b/src/strings/zh-tw.json index 4a05bb9ee8..0bb3504023 100644 --- a/src/strings/zh-tw.json +++ b/src/strings/zh-tw.json @@ -421,7 +421,7 @@ "ColorSpace": "色彩空間", "ColorTransfer": "色彩傳輸", "CommunityRating": "社群評分", - "MessageDefaultError": "處理請求時發生錯誤。請稍後再試。", + "ErrorDefault": "處理請求時發生錯誤。請稍後再試。", "DefaultMetadataLangaugeDescription": "這些預設設定可以在你的媒體庫中單獨設定。", "DefaultSubtitlesHelp": "字幕將基於中繼資料中的「預設」標記和「強制」標記來載入,當有多個選項可用時,將根據語言偏好決定。", "DeleteDeviceConfirmation": "你確定你要刪除這個裝置嗎?當有使用者用這個裝置登入時,這個裝置會再次出現。", From 01fd2e056dfb116263c36d1bc0daecaf405d5f43 Mon Sep 17 00:00:00 2001 From: MrTimscampi Date: Sat, 1 Aug 2020 19:18:03 +0200 Subject: [PATCH 060/226] Fix suggestions --- src/components/viewContainer.js | 116 +++++++++++++++----------------- 1 file changed, 54 insertions(+), 62 deletions(-) diff --git a/src/components/viewContainer.js b/src/components/viewContainer.js index 766a12b9ce..4e11ebc7ba 100644 --- a/src/components/viewContainer.js +++ b/src/components/viewContainer.js @@ -1,3 +1,4 @@ +import 'css!components/viewManager/viewContainer'; /* eslint-disable indent */ function setControllerClass(view, options) { @@ -13,7 +14,7 @@ } controllerUrl = Dashboard.getConfigurationResourceUrl(controllerUrl); - return getRequirePromise([controllerUrl]).then((ControllerFactory) => { + return import(controllerUrl).then((ControllerFactory) => { options.controllerFactory = ControllerFactory; }); } @@ -21,12 +22,6 @@ return Promise.resolve(); } - function getRequirePromise(deps) { - return new Promise((resolve, reject) => { - require(deps, resolve); - }); - } - export function loadView(options) { if (!options.cancel) { const selected = selectedPageIndex; @@ -40,75 +35,72 @@ const isPluginpage = options.url.toLowerCase().indexOf('/configurationpage') !== -1; const newViewInfo = normalizeNewView(options, isPluginpage); const newView = newViewInfo.elem; - const modulesToLoad = []; return new Promise((resolve) => { - require(modulesToLoad, () => { - const currentPage = allPages[pageIndex]; + const currentPage = allPages[pageIndex]; - if (currentPage) { - triggerDestroy(currentPage); - } + if (currentPage) { + triggerDestroy(currentPage); + } - let view = newView; + let view = newView; - if (typeof view == 'string') { - view = document.createElement('div'); - view.innerHTML = newView; - } + if (typeof view == 'string') { + view = document.createElement('div'); + view.innerHTML = newView; + } - view.classList.add('mainAnimatedPage'); + view.classList.add('mainAnimatedPage'); - if (currentPage) { - if (newViewInfo.hasScript && window.$) { - view = $(view).appendTo(mainAnimatedPages)[0]; - mainAnimatedPages.removeChild(currentPage); - } else { - mainAnimatedPages.replaceChild(view, currentPage); - } + if (currentPage) { + if (newViewInfo.hasScript && window.$) { + view = $(view).appendTo(mainAnimatedPages)[0]; + mainAnimatedPages.removeChild(currentPage); } else { - if (newViewInfo.hasScript && window.$) { - view = $(view).appendTo(mainAnimatedPages)[0]; - } else { - mainAnimatedPages.appendChild(view); - } + mainAnimatedPages.replaceChild(view, currentPage); + } + } else { + if (newViewInfo.hasScript && window.$) { + view = $(view).appendTo(mainAnimatedPages)[0]; + } else { + mainAnimatedPages.appendChild(view); + } + } + + if (options.type) { + view.setAttribute('data-type', options.type); + } + + const properties = []; + + if (options.fullscreen) { + properties.push('fullscreen'); + } + + if (properties.length) { + view.setAttribute('data-properties', properties.join(',')); + } + + allPages[pageIndex] = view; + setControllerClass(view, options).then(() => { + if (onBeforeChange) { + onBeforeChange(view, false, options); } - if (options.type) { - view.setAttribute('data-type', options.type); + beforeAnimate(allPages, pageIndex, selected); + selectedPageIndex = pageIndex; + currentUrls[pageIndex] = options.url; + + if (!options.cancel && previousAnimatable) { + afterAnimate(allPages, pageIndex); } - const properties = []; - - if (options.fullscreen) { - properties.push('fullscreen'); + if (window.$) { + $.mobile = $.mobile || {}; + $.mobile.activePage = view; } - if (properties.length) { - view.setAttribute('data-properties', properties.join(',')); - } - - allPages[pageIndex] = view; - setControllerClass(view, options).then(() => { - if (onBeforeChange) { - onBeforeChange(view, false, options); - } - - beforeAnimate(allPages, pageIndex, selected); - selectedPageIndex = pageIndex; - currentUrls[pageIndex] = options.url; - - if (!options.cancel && previousAnimatable) { - afterAnimate(allPages, pageIndex); - } - - if (window.$) { - $.mobile = $.mobile || {}; - $.mobile.activePage = view; - } - - resolve(view); - }); + resolve(view); }); }); } From 60ca2d5bd149d412e5e9bdc5ea6b35fd21b86806 Mon Sep 17 00:00:00 2001 From: schbal Date: Sun, 2 Aug 2020 00:27:41 +0000 Subject: [PATCH 061/226] Translated using Weblate (Korean) Translation: Jellyfin/Jellyfin Web Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ko/ --- src/strings/ko.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/strings/ko.json b/src/strings/ko.json index e587031bb5..d78042298f 100644 --- a/src/strings/ko.json +++ b/src/strings/ko.json @@ -813,7 +813,7 @@ "AllowOnTheFlySubtitleExtraction": "실시간 자막 추출 허용", "AllowOnTheFlySubtitleExtractionHelp": "비디오 트랜스코딩을 방지하기 위해 내장된 자막을 비디오에서 추출하여 텍스트로 클라이언트에 전송할 수 있습니다. 다만, 일부 시스템에서 추출 과정은 긴 시간이 걸리고 비디오 재생을 멈출 수 있습니다. 클라이언트에서 트랜스코딩을 사용할 수 없는 경우 이 기능을 비활성화하여 트랜스코딩 시 자막을 영상에 삽입하십시오.", "AllowRemoteAccess": "이 Jellyfin 서버에 원격 접속을 허용합니다.", - "AllowRemoteAccessHelp": "체크 해제 시 모든 외부 접속은 차단됩니다.", + "AllowRemoteAccessHelp": "비 활성화할 시, 모든 외부 접속은 차단됩니다.", "AllowedRemoteAddressesHelp": "외부 접속을 허용할 IP 혹은 IP 넷마스크를 반점(,)으로 구분하여 입력하십시오. 공란일시, 모든 외부 접속이 허용됩니다.", "AlwaysPlaySubtitles": "항상 표시", "AlwaysPlaySubtitlesHelp": "오디오 언어를 불문하고 언어 설정에 적합한 자막을 불러옵니다.", From a72c843b13453a4c9020d18adc46c9337cdcaf75 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 09:12:30 +0100 Subject: [PATCH 062/226] Migration of playbackmanager to ES6 module --- package.json | 1 + src/components/playback/playbackmanager.js | 2080 ++++++++++---------- 2 files changed, 1036 insertions(+), 1045 deletions(-) diff --git a/package.json b/package.json index a18eb8e0fb..e785ae2ebd 100644 --- a/package.json +++ b/package.json @@ -138,6 +138,7 @@ "src/components/playback/mediasession.js", "src/components/playback/nowplayinghelper.js", "src/components/playback/playbackorientation.js", + "src/components/playback/playbackmanager.js", "src/components/playback/playerSelectionMenu.js", "src/components/playback/playersettingsmenu.js", "src/components/playback/playmethodhelper.js", diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 1d74cd69f5..99a21dd3e2 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -1,729 +1,738 @@ -define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'playQueueManager', 'userSettings', 'globalize', 'connectionManager', 'loading', 'apphost', 'screenfull'], function (events, datetime, appSettings, itemHelper, pluginManager, PlayQueueManager, userSettings, globalize, connectionManager, loading, apphost, screenfull) { - 'use strict'; - - PlayQueueManager = PlayQueueManager.default || PlayQueueManager; - - function enableLocalPlaylistManagement(player) { - if (player.getPlaylist) { - return false; - } - - if (player.isLocalPlayer) { - return true; - } +import events from 'events'; +import datetime from 'datetime'; +import appSettings from 'appSettings'; +import itemHelper from 'itemHelper'; +import pluginManager from 'pluginManager'; +import PlayQueueManager from 'playQueueManager'; +import * as userSettings from 'userSettings'; +import globalize from 'globalize'; +import connectionManager from 'connectionManager'; +import loading from 'loading'; +import apphost from 'apphost'; +import screenfull from 'screenfull'; +function enableLocalPlaylistManagement(player) { + if (player.getPlaylist) { return false; } - function bindToFullscreenChange(player) { - if (screenfull.isEnabled) { - screenfull.on('change', function () { - events.trigger(player, 'fullscreenchange'); - }); - } else { - // iOS Safari - document.addEventListener('webkitfullscreenchange', function () { - events.trigger(player, 'fullscreenchange'); - }, false); - } - } - - function triggerPlayerChange(playbackManagerInstance, newPlayer, newTarget, previousPlayer, previousTargetInfo) { - if (!newPlayer && !previousPlayer) { - return; - } - - if (newTarget && previousTargetInfo) { - if (newTarget.id === previousTargetInfo.id) { - return; - } - } - - events.trigger(playbackManagerInstance, 'playerchange', [newPlayer, newTarget, previousPlayer]); - } - - function reportPlayback(playbackManagerInstance, state, player, reportPlaylist, serverId, method, progressEventName) { - if (!serverId) { - // Not a server item - // We can expand on this later and possibly report them - events.trigger(playbackManagerInstance, 'reportplayback', [false]); - return; - } - - var info = Object.assign({}, state.PlayState); - info.ItemId = state.NowPlayingItem.Id; - - if (progressEventName) { - info.EventName = progressEventName; - } - - if (reportPlaylist) { - addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId); - } - - var apiClient = connectionManager.getApiClient(serverId); - var reportPlaybackPromise = apiClient[method](info); - // Notify that report has been sent - reportPlaybackPromise.then(() => { - events.trigger(playbackManagerInstance, 'reportplayback', [true]); - }); - } - - function getPlaylistSync(playbackManagerInstance, player) { - player = player || playbackManagerInstance._currentPlayer; - if (player && !enableLocalPlaylistManagement(player)) { - return player.getPlaylistSync(); - } - - return playbackManagerInstance._playQueueManager.getPlaylist(); - } - - function addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId) { - info.NowPlayingQueue = getPlaylistSync(playbackManagerInstance, player).map(function (i) { - var itemInfo = { - Id: i.Id, - PlaylistItemId: i.PlaylistItemId - }; - - if (i.ServerId !== serverId) { - itemInfo.ServerId = i.ServerId; - } - - return itemInfo; - }); - } - - function normalizeName(t) { - return t.toLowerCase().replace(' ', ''); - } - - function getItemsForPlayback(serverId, query) { - var apiClient = connectionManager.getApiClient(serverId); - - if (query.Ids && query.Ids.split(',').length === 1) { - var itemId = query.Ids.split(','); - - return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) { - return { - Items: [item], - TotalRecordCount: 1 - }; - }); - } else { - query.Limit = query.Limit || 300; - query.Fields = 'Chapters'; - query.ExcludeLocationTypes = 'Virtual'; - query.EnableTotalRecordCount = false; - query.CollapseBoxSetItems = false; - - return apiClient.getItems(apiClient.getCurrentUserId(), query); - } - } - - function createStreamInfoFromUrlItem(item) { - // Check item.Path for games - return { - url: item.Url || item.Path, - playMethod: 'DirectPlay', - item: item, - textTracks: [], - mediaType: item.MediaType - }; - } - - function mergePlaybackQueries(obj1, obj2) { - var query = Object.assign(obj1, obj2); - - var filters = query.Filters ? query.Filters.split(',') : []; - if (filters.indexOf('IsNotFolder') === -1) { - filters.push('IsNotFolder'); - } - query.Filters = filters.join(','); - return query; - } - - function backdropImageUrl(apiClient, item, options) { - options = options || {}; - options.type = options.type || 'Backdrop'; - - // If not resizing, get the original image - if (!options.maxWidth && !options.width && !options.maxHeight && !options.height) { - options.quality = 100; - } - - if (item.BackdropImageTags && item.BackdropImageTags.length) { - options.tag = item.BackdropImageTags[0]; - return apiClient.getScaledImageUrl(item.Id, options); - } - - if (item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) { - options.tag = item.ParentBackdropImageTags[0]; - return apiClient.getScaledImageUrl(item.ParentBackdropItemId, options); - } - - return null; - } - - function getMimeType(type, container) { - container = (container || '').toLowerCase(); - - if (type === 'audio') { - if (container === 'opus') { - return 'audio/ogg'; - } - if (container === 'webma') { - return 'audio/webm'; - } - if (container === 'm4a') { - return 'audio/mp4'; - } - } else if (type === 'video') { - if (container === 'mkv') { - return 'video/x-matroska'; - } - if (container === 'm4v') { - return 'video/mp4'; - } - if (container === 'mov') { - return 'video/quicktime'; - } - if (container === 'mpg') { - return 'video/mpeg'; - } - if (container === 'flv') { - return 'video/x-flv'; - } - } - - return type + '/' + container; - } - - function getParam(name, url) { - name = name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]'); - var regexS = '[\\?&]' + name + '=([^&#]*)'; - var regex = new RegExp(regexS, 'i'); - - var results = regex.exec(url); - if (results == null) { - return ''; - } else { - return decodeURIComponent(results[1].replace(/\+/g, ' ')); - } - } - - function isAutomaticPlayer(player) { - if (player.isLocalPlayer) { - return true; - } - - return false; - } - - function getAutomaticPlayers(instance, forceLocalPlayer) { - if (!forceLocalPlayer) { - var player = instance._currentPlayer; - if (player && !isAutomaticPlayer(player)) { - return [player]; - } - } - - return instance.getPlayers().filter(isAutomaticPlayer); - } - - function isServerItem(item) { - if (!item.Id) { - return false; - } + if (player.isLocalPlayer) { return true; } - function enableIntros(item) { - if (item.MediaType !== 'Video') { - return false; - } - if (item.Type === 'TvChannel') { - return false; - } - // disable for in-progress recordings - if (item.Status === 'InProgress') { - return false; - } + return false; +} - return isServerItem(item); +function bindToFullscreenChange(player) { + if (screenfull.isEnabled) { + screenfull.on('change', function () { + events.trigger(player, 'fullscreenchange'); + }); + } else { + // iOS Safari + document.addEventListener('webkitfullscreenchange', function () { + events.trigger(player, 'fullscreenchange'); + }, false); + } +} + +function triggerPlayerChange(playbackManagerInstance, newPlayer, newTarget, previousPlayer, previousTargetInfo) { + if (!newPlayer && !previousPlayer) { + return; } - function getIntros(firstItem, apiClient, options) { - if (options.startPositionTicks || options.startIndex || options.fullscreen === false || !enableIntros(firstItem) || !userSettings.enableCinemaMode()) { - return Promise.resolve({ - Items: [] - }); + if (newTarget && previousTargetInfo) { + if (newTarget.id === previousTargetInfo.id) { + return; } - - return apiClient.getIntros(firstItem.Id).then(function (result) { - return result; - }, function (err) { - return Promise.resolve({ - Items: [] - }); - }); } - function getAudioMaxValues(deviceProfile) { - // TODO - this could vary per codec and should be done on the server using the entire profile - var maxAudioSampleRate = null; - var maxAudioBitDepth = null; - var maxAudioBitrate = null; + events.trigger(playbackManagerInstance, 'playerchange', [newPlayer, newTarget, previousPlayer]); +} - deviceProfile.CodecProfiles.map(function (codecProfile) { - if (codecProfile.Type === 'Audio') { - (codecProfile.Conditions || []).map(function (condition) { - if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioBitDepth') { - return maxAudioBitDepth = condition.Value; - } else if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioSampleRate') { - return maxAudioSampleRate = condition.Value; - } else if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioBitrate') { - return maxAudioBitrate = condition.Value; - } - }); - } - }); +function reportPlayback(playbackManagerInstance, state, player, reportPlaylist, serverId, method, progressEventName) { + if (!serverId) { + // Not a server item + // We can expand on this later and possibly report them + events.trigger(playbackManagerInstance, 'reportplayback', [false]); + return; + } - return { - maxAudioSampleRate: maxAudioSampleRate, - maxAudioBitDepth: maxAudioBitDepth, - maxAudioBitrate: maxAudioBitrate + const info = Object.assign({}, state.PlayState); + info.ItemId = state.NowPlayingItem.Id; + + if (progressEventName) { + info.EventName = progressEventName; + } + + if (reportPlaylist) { + addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId); + } + + const apiClient = connectionManager.getApiClient(serverId); + const reportPlaybackPromise = apiClient[method](info); + // Notify that report has been sent + reportPlaybackPromise.then(() => { + events.trigger(playbackManagerInstance, 'reportplayback', [true]); + }); +} + +function getPlaylistSync(playbackManagerInstance, player) { + player = player || playbackManagerInstance._currentPlayer; + if (player && !enableLocalPlaylistManagement(player)) { + return player.getPlaylistSync(); + } + + return playbackManagerInstance._playQueueManager.getPlaylist(); +} + +function addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId) { + info.NowPlayingQueue = getPlaylistSync(playbackManagerInstance, player).map(function (i) { + const itemInfo = { + Id: i.Id, + PlaylistItemId: i.PlaylistItemId }; + + if (i.ServerId !== serverId) { + itemInfo.ServerId = i.ServerId; + } + + return itemInfo; + }); +} + +function normalizeName(t) { + return t.toLowerCase().replace(' ', ''); +} + +function getItemsForPlayback(serverId, query) { + const apiClient = connectionManager.getApiClient(serverId); + + if (query.Ids && query.Ids.split(',').length === 1) { + const itemId = query.Ids.split(','); + + return apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) { + return { + Items: [item], + TotalRecordCount: 1 + }; + }); + } else { + query.Limit = query.Limit || 300; + query.Fields = 'Chapters'; + query.ExcludeLocationTypes = 'Virtual'; + query.EnableTotalRecordCount = false; + query.CollapseBoxSetItems = false; + + return apiClient.getItems(apiClient.getCurrentUserId(), query); + } +} + +function createStreamInfoFromUrlItem(item) { + // Check item.Path for games + return { + url: item.Url || item.Path, + playMethod: 'DirectPlay', + item: item, + textTracks: [], + mediaType: item.MediaType + }; +} + +function mergePlaybackQueries(obj1, obj2) { + const query = Object.assign(obj1, obj2); + + const filters = query.Filters ? query.Filters.split(',') : []; + if (filters.indexOf('IsNotFolder') === -1) { + filters.push('IsNotFolder'); + } + query.Filters = filters.join(','); + return query; +} + +function backdropImageUrl(apiClient, item, options) { + options = options || {}; + options.type = options.type || 'Backdrop'; + + // If not resizing, get the original image + if (!options.maxWidth && !options.width && !options.maxHeight && !options.height) { + options.quality = 100; } - var startingPlaySession = new Date().getTime(); - function getAudioStreamUrl(item, transcodingProfile, directPlayContainers, maxBitrate, apiClient, maxAudioSampleRate, maxAudioBitDepth, maxAudioBitrate, startPosition) { - var url = 'Audio/' + item.Id + '/universal'; + if (item.BackdropImageTags && item.BackdropImageTags.length) { + options.tag = item.BackdropImageTags[0]; + return apiClient.getScaledImageUrl(item.Id, options); + } - startingPlaySession++; - return apiClient.getUrl(url, { - UserId: apiClient.getCurrentUserId(), - DeviceId: apiClient.deviceId(), - MaxStreamingBitrate: maxAudioBitrate || maxBitrate, - Container: directPlayContainers, - TranscodingContainer: transcodingProfile.Container || null, - TranscodingProtocol: transcodingProfile.Protocol || null, - AudioCodec: transcodingProfile.AudioCodec, - MaxAudioSampleRate: maxAudioSampleRate, - MaxAudioBitDepth: maxAudioBitDepth, - api_key: apiClient.accessToken(), - PlaySessionId: startingPlaySession, - StartTimeTicks: startPosition || 0, - EnableRedirection: true, - EnableRemoteMedia: apphost.supports('remoteaudio') + if (item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) { + options.tag = item.ParentBackdropImageTags[0]; + return apiClient.getScaledImageUrl(item.ParentBackdropItemId, options); + } + + return null; +} + +function getMimeType(type, container) { + container = (container || '').toLowerCase(); + + if (type === 'audio') { + if (container === 'opus') { + return 'audio/ogg'; + } + if (container === 'webma') { + return 'audio/webm'; + } + if (container === 'm4a') { + return 'audio/mp4'; + } + } else if (type === 'video') { + if (container === 'mkv') { + return 'video/x-matroska'; + } + if (container === 'm4v') { + return 'video/mp4'; + } + if (container === 'mov') { + return 'video/quicktime'; + } + if (container === 'mpg') { + return 'video/mpeg'; + } + if (container === 'flv') { + return 'video/x-flv'; + } + } + + return type + '/' + container; +} + +function getParam(name, url) { + name = name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]'); + const regexS = '[\\?&]' + name + '=([^&#]*)'; + const regex = new RegExp(regexS, 'i'); + + const results = regex.exec(url); + if (results == null) { + return ''; + } else { + return decodeURIComponent(results[1].replace(/\+/g, ' ')); + } +} + +function isAutomaticPlayer(player) { + if (player.isLocalPlayer) { + return true; + } + + return false; +} + +function getAutomaticPlayers(instance, forceLocalPlayer) { + if (!forceLocalPlayer) { + const player = instance._currentPlayer; + if (player && !isAutomaticPlayer(player)) { + return [player]; + } + } + + return instance.getPlayers().filter(isAutomaticPlayer); +} + +function isServerItem(item) { + if (!item.Id) { + return false; + } + return true; +} + +function enableIntros(item) { + if (item.MediaType !== 'Video') { + return false; + } + if (item.Type === 'TvChannel') { + return false; + } + // disable for in-progress recordings + if (item.Status === 'InProgress') { + return false; + } + + return isServerItem(item); +} + +function getIntros(firstItem, apiClient, options) { + if (options.startPositionTicks || options.startIndex || options.fullscreen === false || !enableIntros(firstItem) || !userSettings.enableCinemaMode()) { + return Promise.resolve({ + Items: [] }); } - function getAudioStreamUrlFromDeviceProfile(item, deviceProfile, maxBitrate, apiClient, startPosition) { - var transcodingProfile = deviceProfile.TranscodingProfiles.filter(function (p) { - return p.Type === 'Audio' && p.Context === 'Streaming'; + return apiClient.getIntros(firstItem.Id).then(function (result) { + return result; + }, function (err) { + return Promise.resolve({ + Items: [] + }); + }); +} + +function getAudioMaxValues(deviceProfile) { + // TODO - this could vary per codec and should be done on the server using the entire profile + let maxAudioSampleRate = null; + let maxAudioBitDepth = null; + let maxAudioBitrate = null; + + deviceProfile.CodecProfiles.map(function (codecProfile) { + if (codecProfile.Type === 'Audio') { + (codecProfile.Conditions || []).map(function (condition) { + if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioBitDepth') { + return maxAudioBitDepth = condition.Value; + } else if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioSampleRate') { + return maxAudioSampleRate = condition.Value; + } else if (condition.Condition === 'LessThanEqual' && condition.Property === 'AudioBitrate') { + return maxAudioBitrate = condition.Value; + } + }); + } + }); + + return { + maxAudioSampleRate: maxAudioSampleRate, + maxAudioBitDepth: maxAudioBitDepth, + maxAudioBitrate: maxAudioBitrate + }; +} + +let startingPlaySession = new Date().getTime(); +function getAudioStreamUrl(item, transcodingProfile, directPlayContainers, maxBitrate, apiClient, maxAudioSampleRate, maxAudioBitDepth, maxAudioBitrate, startPosition) { + const url = 'Audio/' + item.Id + '/universal'; + + startingPlaySession++; + return apiClient.getUrl(url, { + UserId: apiClient.getCurrentUserId(), + DeviceId: apiClient.deviceId(), + MaxStreamingBitrate: maxAudioBitrate || maxBitrate, + Container: directPlayContainers, + TranscodingContainer: transcodingProfile.Container || null, + TranscodingProtocol: transcodingProfile.Protocol || null, + AudioCodec: transcodingProfile.AudioCodec, + MaxAudioSampleRate: maxAudioSampleRate, + MaxAudioBitDepth: maxAudioBitDepth, + api_key: apiClient.accessToken(), + PlaySessionId: startingPlaySession, + StartTimeTicks: startPosition || 0, + EnableRedirection: true, + EnableRemoteMedia: apphost.supports('remoteaudio') + }); +} + +function getAudioStreamUrlFromDeviceProfile(item, deviceProfile, maxBitrate, apiClient, startPosition) { + const transcodingProfile = deviceProfile.TranscodingProfiles.filter(function (p) { + return p.Type === 'Audio' && p.Context === 'Streaming'; + })[0]; + + let directPlayContainers = ''; + + deviceProfile.DirectPlayProfiles.map(function (p) { + if (p.Type === 'Audio') { + if (directPlayContainers) { + directPlayContainers += ',' + p.Container; + } else { + directPlayContainers = p.Container; + } + + if (p.AudioCodec) { + directPlayContainers += '|' + p.AudioCodec; + } + } + }); + + const maxValues = getAudioMaxValues(deviceProfile); + + return getAudioStreamUrl(item, transcodingProfile, directPlayContainers, maxBitrate, apiClient, maxValues.maxAudioSampleRate, maxValues.maxAudioBitDepth, maxValues.maxAudioBitrate, startPosition); +} + +function getStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition) { + const audioTranscodingProfile = deviceProfile.TranscodingProfiles.filter(function (p) { + return p.Type === 'Audio' && p.Context === 'Streaming'; + })[0]; + + let audioDirectPlayContainers = ''; + + deviceProfile.DirectPlayProfiles.map(function (p) { + if (p.Type === 'Audio') { + if (audioDirectPlayContainers) { + audioDirectPlayContainers += ',' + p.Container; + } else { + audioDirectPlayContainers = p.Container; + } + + if (p.AudioCodec) { + audioDirectPlayContainers += '|' + p.AudioCodec; + } + } + }); + + const maxValues = getAudioMaxValues(deviceProfile); + + const streamUrls = []; + + for (let i = 0, length = items.length; i < length; i++) { + const item = items[i]; + let streamUrl; + + if (item.MediaType === 'Audio' && !itemHelper.isLocalItem(item)) { + streamUrl = getAudioStreamUrl(item, audioTranscodingProfile, audioDirectPlayContainers, maxBitrate, apiClient, maxValues.maxAudioSampleRate, maxValues.maxAudioBitDepth, maxValues.maxAudioBitrate, startPosition); + } + + streamUrls.push(streamUrl || ''); + + if (i === 0) { + startPosition = 0; + } + } + + return Promise.resolve(streamUrls); +} + +function setStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition) { + return getStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition).then(function (streamUrls) { + for (let i = 0, length = items.length; i < length; i++) { + const item = items[i]; + const streamUrl = streamUrls[i]; + + if (streamUrl) { + item.PresetMediaSource = { + StreamUrl: streamUrl, + Id: item.Id, + MediaStreams: [], + RunTimeTicks: item.RunTimeTicks + }; + } + } + }); +} + +function getPlaybackInfo(player, + apiClient, + item, + deviceProfile, + maxBitrate, + startPosition, + isPlayback, + mediaSourceId, + audioStreamIndex, + subtitleStreamIndex, + liveStreamId, + enableDirectPlay, + enableDirectStream, + allowVideoStreamCopy, + allowAudioStreamCopy) { + if (!itemHelper.isLocalItem(item) && item.MediaType === 'Audio') { + return Promise.resolve({ + MediaSources: [ + { + StreamUrl: getAudioStreamUrlFromDeviceProfile(item, deviceProfile, maxBitrate, apiClient, startPosition), + Id: item.Id, + MediaStreams: [], + RunTimeTicks: item.RunTimeTicks + }] + }); + } + + if (item.PresetMediaSource) { + return Promise.resolve({ + MediaSources: [item.PresetMediaSource] + }); + } + + const itemId = item.Id; + + const query = { + UserId: apiClient.getCurrentUserId(), + StartTimeTicks: startPosition || 0 + }; + + if (isPlayback) { + query.IsPlayback = true; + query.AutoOpenLiveStream = true; + } else { + query.IsPlayback = false; + query.AutoOpenLiveStream = false; + } + + if (audioStreamIndex != null) { + query.AudioStreamIndex = audioStreamIndex; + } + if (subtitleStreamIndex != null) { + query.SubtitleStreamIndex = subtitleStreamIndex; + } + if (enableDirectPlay != null) { + query.EnableDirectPlay = enableDirectPlay; + } + + if (enableDirectStream != null) { + query.EnableDirectStream = enableDirectStream; + } + if (allowVideoStreamCopy != null) { + query.AllowVideoStreamCopy = allowVideoStreamCopy; + } + if (allowAudioStreamCopy != null) { + query.AllowAudioStreamCopy = allowAudioStreamCopy; + } + if (mediaSourceId) { + query.MediaSourceId = mediaSourceId; + } + if (liveStreamId) { + query.LiveStreamId = liveStreamId; + } + if (maxBitrate) { + query.MaxStreamingBitrate = maxBitrate; + } + if (player.enableMediaProbe && !player.enableMediaProbe(item)) { + query.EnableMediaProbe = false; + } + + // lastly, enforce player overrides for special situations + if (query.EnableDirectStream !== false) { + if (player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)) { + query.EnableDirectStream = false; + } + } + + if (player.getDirectPlayProtocols) { + query.DirectPlayProtocols = player.getDirectPlayProtocols(); + } + + return apiClient.getPlaybackInfo(itemId, query, deviceProfile); +} + +function getOptimalMediaSource(apiClient, item, versions) { + const promises = versions.map(function (v) { + return supportsDirectPlay(apiClient, item, v); + }); + + if (!promises.length) { + return Promise.reject(); + } + + return Promise.all(promises).then(function (results) { + for (let i = 0, length = versions.length; i < length; i++) { + versions[i].enableDirectPlay = results[i] || false; + } + let optimalVersion = versions.filter(function (v) { + return v.enableDirectPlay; })[0]; - var directPlayContainers = ''; + if (!optimalVersion) { + optimalVersion = versions.filter(function (v) { + return v.SupportsDirectStream; + })[0]; + } - deviceProfile.DirectPlayProfiles.map(function (p) { - if (p.Type === 'Audio') { - if (directPlayContainers) { - directPlayContainers += ',' + p.Container; - } else { - directPlayContainers = p.Container; - } - - if (p.AudioCodec) { - directPlayContainers += '|' + p.AudioCodec; - } - } - }); - - var maxValues = getAudioMaxValues(deviceProfile); - - return getAudioStreamUrl(item, transcodingProfile, directPlayContainers, maxBitrate, apiClient, maxValues.maxAudioSampleRate, maxValues.maxAudioBitDepth, maxValues.maxAudioBitrate, startPosition); - } - - function getStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition) { - var audioTranscodingProfile = deviceProfile.TranscodingProfiles.filter(function (p) { - return p.Type === 'Audio' && p.Context === 'Streaming'; + optimalVersion = optimalVersion || versions.filter(function (s) { + return s.SupportsTranscoding; })[0]; - var audioDirectPlayContainers = ''; + return optimalVersion || versions[0]; + }); +} - deviceProfile.DirectPlayProfiles.map(function (p) { - if (p.Type === 'Audio') { - if (audioDirectPlayContainers) { - audioDirectPlayContainers += ',' + p.Container; - } else { - audioDirectPlayContainers = p.Container; - } +function getLiveStream(player, apiClient, item, playSessionId, deviceProfile, maxBitrate, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex) { + const postData = { + DeviceProfile: deviceProfile, + OpenToken: mediaSource.OpenToken + }; - if (p.AudioCodec) { - audioDirectPlayContainers += '|' + p.AudioCodec; + const query = { + UserId: apiClient.getCurrentUserId(), + StartTimeTicks: startPosition || 0, + ItemId: item.Id, + PlaySessionId: playSessionId + }; + + if (maxBitrate) { + query.MaxStreamingBitrate = maxBitrate; + } + if (audioStreamIndex != null) { + query.AudioStreamIndex = audioStreamIndex; + } + if (subtitleStreamIndex != null) { + query.SubtitleStreamIndex = subtitleStreamIndex; + } + + // lastly, enforce player overrides for special situations + if (query.EnableDirectStream !== false) { + if (player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)) { + query.EnableDirectStream = false; + } + } + + return apiClient.ajax({ + url: apiClient.getUrl('LiveStreams/Open', query), + type: 'POST', + data: JSON.stringify(postData), + contentType: 'application/json', + dataType: 'json' + + }); +} + +function isHostReachable(mediaSource, apiClient) { + if (mediaSource.IsRemote) { + return Promise.resolve(true); + } + + return apiClient.getEndpointInfo().then(function (endpointInfo) { + if (endpointInfo.IsInNetwork) { + if (!endpointInfo.IsLocal) { + const path = (mediaSource.Path || '').toLowerCase(); + if (path.indexOf('localhost') !== -1 || path.indexOf('127.0.0.1') !== -1) { + // This will only work if the app is on the same machine as the server + return Promise.resolve(false); } } - }); - var maxValues = getAudioMaxValues(deviceProfile); - - var streamUrls = []; - - for (var i = 0, length = items.length; i < length; i++) { - var item = items[i]; - var streamUrl; - - if (item.MediaType === 'Audio' && !itemHelper.isLocalItem(item)) { - streamUrl = getAudioStreamUrl(item, audioTranscodingProfile, audioDirectPlayContainers, maxBitrate, apiClient, maxValues.maxAudioSampleRate, maxValues.maxAudioBitDepth, maxValues.maxAudioBitrate, startPosition); - } - - streamUrls.push(streamUrl || ''); - - if (i === 0) { - startPosition = 0; - } - } - - return Promise.resolve(streamUrls); - } - - function setStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition) { - return getStreamUrls(items, deviceProfile, maxBitrate, apiClient, startPosition).then(function (streamUrls) { - for (var i = 0, length = items.length; i < length; i++) { - var item = items[i]; - var streamUrl = streamUrls[i]; - - if (streamUrl) { - item.PresetMediaSource = { - StreamUrl: streamUrl, - Id: item.Id, - MediaStreams: [], - RunTimeTicks: item.RunTimeTicks - }; - } - } - }); - } - - function getPlaybackInfo(player, - apiClient, - item, - deviceProfile, - maxBitrate, - startPosition, - isPlayback, - mediaSourceId, - audioStreamIndex, - subtitleStreamIndex, - liveStreamId, - enableDirectPlay, - enableDirectStream, - allowVideoStreamCopy, - allowAudioStreamCopy) { - if (!itemHelper.isLocalItem(item) && item.MediaType === 'Audio') { - return Promise.resolve({ - MediaSources: [ - { - StreamUrl: getAudioStreamUrlFromDeviceProfile(item, deviceProfile, maxBitrate, apiClient, startPosition), - Id: item.Id, - MediaStreams: [], - RunTimeTicks: item.RunTimeTicks - }] - }); - } - - if (item.PresetMediaSource) { - return Promise.resolve({ - MediaSources: [item.PresetMediaSource] - }); - } - - var itemId = item.Id; - - var query = { - UserId: apiClient.getCurrentUserId(), - StartTimeTicks: startPosition || 0 - }; - - if (isPlayback) { - query.IsPlayback = true; - query.AutoOpenLiveStream = true; - } else { - query.IsPlayback = false; - query.AutoOpenLiveStream = false; - } - - if (audioStreamIndex != null) { - query.AudioStreamIndex = audioStreamIndex; - } - if (subtitleStreamIndex != null) { - query.SubtitleStreamIndex = subtitleStreamIndex; - } - if (enableDirectPlay != null) { - query.EnableDirectPlay = enableDirectPlay; - } - - if (enableDirectStream != null) { - query.EnableDirectStream = enableDirectStream; - } - if (allowVideoStreamCopy != null) { - query.AllowVideoStreamCopy = allowVideoStreamCopy; - } - if (allowAudioStreamCopy != null) { - query.AllowAudioStreamCopy = allowAudioStreamCopy; - } - if (mediaSourceId) { - query.MediaSourceId = mediaSourceId; - } - if (liveStreamId) { - query.LiveStreamId = liveStreamId; - } - if (maxBitrate) { - query.MaxStreamingBitrate = maxBitrate; - } - if (player.enableMediaProbe && !player.enableMediaProbe(item)) { - query.EnableMediaProbe = false; - } - - // lastly, enforce player overrides for special situations - if (query.EnableDirectStream !== false) { - if (player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)) { - query.EnableDirectStream = false; - } - } - - if (player.getDirectPlayProtocols) { - query.DirectPlayProtocols = player.getDirectPlayProtocols(); - } - - return apiClient.getPlaybackInfo(itemId, query, deviceProfile); - } - - function getOptimalMediaSource(apiClient, item, versions) { - var promises = versions.map(function (v) { - return supportsDirectPlay(apiClient, item, v); - }); - - if (!promises.length) { - return Promise.reject(); - } - - return Promise.all(promises).then(function (results) { - for (var i = 0, length = versions.length; i < length; i++) { - versions[i].enableDirectPlay = results[i] || false; - } - var optimalVersion = versions.filter(function (v) { - return v.enableDirectPlay; - })[0]; - - if (!optimalVersion) { - optimalVersion = versions.filter(function (v) { - return v.SupportsDirectStream; - })[0]; - } - - optimalVersion = optimalVersion || versions.filter(function (s) { - return s.SupportsTranscoding; - })[0]; - - return optimalVersion || versions[0]; - }); - } - - function getLiveStream(player, apiClient, item, playSessionId, deviceProfile, maxBitrate, startPosition, mediaSource, audioStreamIndex, subtitleStreamIndex) { - var postData = { - DeviceProfile: deviceProfile, - OpenToken: mediaSource.OpenToken - }; - - var query = { - UserId: apiClient.getCurrentUserId(), - StartTimeTicks: startPosition || 0, - ItemId: item.Id, - PlaySessionId: playSessionId - }; - - if (maxBitrate) { - query.MaxStreamingBitrate = maxBitrate; - } - if (audioStreamIndex != null) { - query.AudioStreamIndex = audioStreamIndex; - } - if (subtitleStreamIndex != null) { - query.SubtitleStreamIndex = subtitleStreamIndex; - } - - // lastly, enforce player overrides for special situations - if (query.EnableDirectStream !== false) { - if (player.supportsPlayMethod && !player.supportsPlayMethod('DirectStream', item)) { - query.EnableDirectStream = false; - } - } - - return apiClient.ajax({ - url: apiClient.getUrl('LiveStreams/Open', query), - type: 'POST', - data: JSON.stringify(postData), - contentType: 'application/json', - dataType: 'json' - - }); - } - - function isHostReachable(mediaSource, apiClient) { - if (mediaSource.IsRemote) { return Promise.resolve(true); } - return apiClient.getEndpointInfo().then(function (endpointInfo) { - if (endpointInfo.IsInNetwork) { - if (!endpointInfo.IsLocal) { - var path = (mediaSource.Path || '').toLowerCase(); - if (path.indexOf('localhost') !== -1 || path.indexOf('127.0.0.1') !== -1) { - // This will only work if the app is on the same machine as the server - return Promise.resolve(false); - } - } + // media source is in network, but connection is out of network + return Promise.resolve(false); + }); +} - return Promise.resolve(true); - } +function supportsDirectPlay(apiClient, item, mediaSource) { + // folder rip hacks due to not yet being supported by the stream building engine + const isFolderRip = mediaSource.VideoType === 'BluRay' || mediaSource.VideoType === 'Dvd' || mediaSource.VideoType === 'HdDvd'; - // media source is in network, but connection is out of network + if (mediaSource.SupportsDirectPlay || isFolderRip) { + if (mediaSource.IsRemote && !apphost.supports('remotevideo')) { return Promise.resolve(false); - }); - } + } - function supportsDirectPlay(apiClient, item, mediaSource) { - // folder rip hacks due to not yet being supported by the stream building engine - var isFolderRip = mediaSource.VideoType === 'BluRay' || mediaSource.VideoType === 'Dvd' || mediaSource.VideoType === 'HdDvd'; - - if (mediaSource.SupportsDirectPlay || isFolderRip) { - if (mediaSource.IsRemote && !apphost.supports('remotevideo')) { - return Promise.resolve(false); + if (mediaSource.Protocol === 'Http' && !mediaSource.RequiredHttpHeaders.length) { + // If this is the only way it can be played, then allow it + if (!mediaSource.SupportsDirectStream && !mediaSource.SupportsTranscoding) { + return Promise.resolve(true); + } else { + return isHostReachable(mediaSource, apiClient); } + } else if (mediaSource.Protocol === 'File') { + return new Promise(function (resolve, reject) { + // Determine if the file can be accessed directly + import('filesystem').then(({ default: filesystem }) => { + const method = isFolderRip ? + 'directoryExists' : + 'fileExists'; - if (mediaSource.Protocol === 'Http' && !mediaSource.RequiredHttpHeaders.length) { - // If this is the only way it can be played, then allow it - if (!mediaSource.SupportsDirectStream && !mediaSource.SupportsTranscoding) { - return Promise.resolve(true); - } else { - return isHostReachable(mediaSource, apiClient); - } - } else if (mediaSource.Protocol === 'File') { - return new Promise(function (resolve, reject) { - // Determine if the file can be accessed directly - require(['filesystem'], function (filesystem) { - var method = isFolderRip ? - 'directoryExists' : - 'fileExists'; - - filesystem[method](mediaSource.Path).then(function () { - resolve(true); - }, function () { - resolve(false); - }); + filesystem[method](mediaSource.Path).then(function () { + resolve(true); + }, function () { + resolve(false); }); }); - } - } - - return Promise.resolve(false); - } - - function validatePlaybackInfoResult(instance, result) { - if (result.ErrorCode) { - showPlaybackInfoErrorMessage(instance, result.ErrorCode); - return false; - } - - return true; - } - - function showPlaybackInfoErrorMessage(instance, errorCode, playNextTrack) { - require(['alert'], function (alert) { - alert.default({ - text: globalize.translate('PlaybackError' + errorCode), - title: globalize.translate('HeaderPlaybackError') - }).then(function () { - if (playNextTrack) { - instance.nextTrack(); - } }); + } + } + + return Promise.resolve(false); +} + +function validatePlaybackInfoResult(instance, result) { + if (result.ErrorCode) { + showPlaybackInfoErrorMessage(instance, result.ErrorCode); + return false; + } + + return true; +} + +function showPlaybackInfoErrorMessage(instance, errorCode, playNextTrack) { + import('alert').then(({ default: alert }) => { + alert({ + text: globalize.translate('PlaybackError' + errorCode), + title: globalize.translate('HeaderPlaybackError') + }).then(function () { + if (playNextTrack) { + instance.nextTrack(); + } }); + }); +} + +function normalizePlayOptions(playOptions) { + playOptions.fullscreen = playOptions.fullscreen !== false; +} + +function truncatePlayOptions(playOptions) { + return { + fullscreen: playOptions.fullscreen, + mediaSourceId: playOptions.mediaSourceId, + audioStreamIndex: playOptions.audioStreamIndex, + subtitleStreamIndex: playOptions.subtitleStreamIndex, + startPositionTicks: playOptions.startPositionTicks + }; +} + +function getNowPlayingItemForReporting(player, item, mediaSource) { + const nowPlayingItem = Object.assign({}, item); + + if (mediaSource) { + nowPlayingItem.RunTimeTicks = mediaSource.RunTimeTicks; + nowPlayingItem.MediaStreams = mediaSource.MediaStreams; + + // not needed + nowPlayingItem.MediaSources = null; } - function normalizePlayOptions(playOptions) { - playOptions.fullscreen = playOptions.fullscreen !== false; + nowPlayingItem.RunTimeTicks = nowPlayingItem.RunTimeTicks || player.duration() * 10000; + + return nowPlayingItem; +} + +function displayPlayerIndividually(player) { + return !player.isLocalPlayer; +} + +function createTarget(instance, player) { + return { + name: player.name, + id: player.id, + playerName: player.name, + playableMediaTypes: ['Audio', 'Video', 'Photo', 'Book'].map(player.canPlayMediaType), + isLocalPlayer: player.isLocalPlayer, + supportedCommands: instance.getSupportedCommands(player) + }; +} + +function getPlayerTargets(player) { + if (player.getTargets) { + return player.getTargets(); } - function truncatePlayOptions(playOptions) { - return { - fullscreen: playOptions.fullscreen, - mediaSourceId: playOptions.mediaSourceId, - audioStreamIndex: playOptions.audioStreamIndex, - subtitleStreamIndex: playOptions.subtitleStreamIndex, - startPositionTicks: playOptions.startPositionTicks - }; - } + return Promise.resolve([createTarget(player)]); +} - function getNowPlayingItemForReporting(player, item, mediaSource) { - var nowPlayingItem = Object.assign({}, item); +function sortPlayerTargets(a, b) { + let aVal = a.isLocalPlayer ? 0 : 1; + let bVal = b.isLocalPlayer ? 0 : 1; - if (mediaSource) { - nowPlayingItem.RunTimeTicks = mediaSource.RunTimeTicks; - nowPlayingItem.MediaStreams = mediaSource.MediaStreams; + aVal = aVal.toString() + a.name; + bVal = bVal.toString() + b.name; - // not needed - nowPlayingItem.MediaSources = null; - } + return aVal.localeCompare(bVal); +} - nowPlayingItem.RunTimeTicks = nowPlayingItem.RunTimeTicks || player.duration() * 10000; +class PlaybackManager { + constructor() { + const self = this; - return nowPlayingItem; - } - - function displayPlayerIndividually(player) { - return !player.isLocalPlayer; - } - - function createTarget(instance, player) { - return { - name: player.name, - id: player.id, - playerName: player.name, - playableMediaTypes: ['Audio', 'Video', 'Photo', 'Book'].map(player.canPlayMediaType), - isLocalPlayer: player.isLocalPlayer, - supportedCommands: instance.getSupportedCommands(player) - }; - } - - function getPlayerTargets(player) { - if (player.getTargets) { - return player.getTargets(); - } - - return Promise.resolve([createTarget(player)]); - } - - function sortPlayerTargets(a, b) { - var aVal = a.isLocalPlayer ? 0 : 1; - var bVal = b.isLocalPlayer ? 0 : 1; - - aVal = aVal.toString() + a.name; - bVal = bVal.toString() + b.name; - - return aVal.localeCompare(bVal); - } - - function PlaybackManager() { - var self = this; - - var players = []; - var currentTargetInfo; - var currentPairingId = null; + const players = []; + let currentTargetInfo; + let currentPairingId = null; this._playNextAfterEnded = true; - var playerStates = {}; + const playerStates = {}; this._playQueueManager = new PlayQueueManager(); @@ -736,7 +745,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.currentItem(); } - var data = getPlayerData(player); + const data = getPlayerData(player); return data.streamInfo ? data.streamInfo.item : null; }; @@ -749,7 +758,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.currentMediaSource(); } - var data = getPlayerData(player); + const data = getPlayerData(player); return data.streamInfo ? data.streamInfo.mediaSource : null; }; @@ -762,7 +771,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.playMethod(); } - var data = getPlayerData(player); + const data = getPlayerData(player); return data.streamInfo ? data.streamInfo.playMethod : null; }; @@ -775,21 +784,20 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.playSessionId(); } - var data = getPlayerData(player); + const data = getPlayerData(player); return data.streamInfo ? data.streamInfo.playSessionId : null; }; self.getPlayerInfo = function () { - var player = self._currentPlayer; + const player = self._currentPlayer; if (!player) { return null; } - var target = currentTargetInfo || {}; + const target = currentTargetInfo || {}; return { - name: player.name, isLocalPlayer: player.isLocalPlayer, id: target.id, @@ -845,7 +853,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla currentPairingId = targetInfo.id; - var promise = player.tryPair ? + const promise = player.tryPair ? player.tryPair(targetInfo) : Promise.resolve(); @@ -863,11 +871,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }; self.getTargets = function () { - var promises = players.filter(displayPlayerIndividually).map(getPlayerTargets); + const promises = players.filter(displayPlayerIndividually).map(getPlayerTargets); return Promise.all(promises).then(function (responses) { return connectionManager.currentApiClient().getCurrentUser().then(function (user) { - var targets = []; + const targets = []; targets.push({ name: globalize.translate('HeaderMyDevice'), @@ -881,10 +889,10 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla user: user }); - for (var i = 0; i < responses.length; i++) { - var subTargets = responses[i]; + for (let i = 0; i < responses.length; i++) { + const subTargets = responses[i]; - for (var j = 0; j < subTargets.length; j++) { + for (let j = 0; j < subTargets.length; j++) { targets.push(subTargets[j]); } } @@ -899,7 +907,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla throw new Error('player cannot be null'); } - var index = getPlayerData(player).subtitleStreamIndex; + const index = getPlayerData(player).subtitleStreamIndex; if (index == null || index === -1) { return null; @@ -928,7 +936,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }; function removeCurrentPlayer(player) { - var previousPlayer = self._currentPlayer; + const previousPlayer = self._currentPlayer; if (!previousPlayer || player.id === previousPlayer.id) { setCurrentPlayerInternal(null); @@ -936,8 +944,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function setCurrentPlayerInternal(player, targetInfo) { - var previousPlayer = self._currentPlayer; - var previousTargetInfo = currentTargetInfo; + const previousPlayer = self._currentPlayer; + const previousTargetInfo = currentTargetInfo; if (player && !targetInfo && player.isLocalPlayer) { targetInfo = createTarget(self, player); @@ -988,7 +996,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } if (self.isPlaying(player)) { - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); return playerData.streamInfo.mediaType === mediaType; } @@ -1027,7 +1035,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } self.canPlay = function (item) { - var itemType = item.Type; + const itemType = item.Type; if (itemType === 'PhotoAlbum' || itemType === 'MusicGenre' || itemType === 'Season' || itemType === 'Series' || itemType === 'BoxSet' || itemType === 'MusicAlbum' || itemType === 'MusicArtist' || itemType === 'Playlist') { return true; @@ -1057,12 +1065,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla player = player || self._currentPlayer; if (player) { - var current = self.getAspectRatio(player); + const current = self.getAspectRatio(player); - var supported = self.getSupportedAspectRatios(player); + const supported = self.getSupportedAspectRatios(player); - var index = -1; - for (var i = 0, length = supported.length; i < length; i++) { + let index = -1; + for (let i = 0, length = supported.length; i < length; i++) { if (supported[i].id === current) { index = i; break; @@ -1104,7 +1112,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } }; - var brightnessOsdLoaded; + let brightnessOsdLoaded; self.setBrightness = function (val, player) { player = player || self._currentPlayer; @@ -1112,7 +1120,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (!brightnessOsdLoaded) { brightnessOsdLoaded = true; // TODO: Have this trigger an event instead to get the osd out of here - require(['brightnessOsd']); + import('brightnessOsd').then(); } player.setBrightness(val); } @@ -1168,11 +1176,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var currentMediaSource = self.currentMediaSource(player); - var mediaStreams = []; - var i; - var length; - for (i = 0, length = currentMediaSource.MediaStreams.length; i < length; i++) { + const currentMediaSource = self.currentMediaSource(player); + const mediaStreams = []; + for (let i = 0, length = currentMediaSource.MediaStreams.length; i < length; i++) { if (currentMediaSource.MediaStreams[i].Type === 'Audio') { mediaStreams.push(currentMediaSource.MediaStreams[i]); } @@ -1183,16 +1189,16 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var currentStreamIndex = self.getAudioStreamIndex(player); - var indexInList = -1; - for (i = 0, length = mediaStreams.length; i < length; i++) { + const currentStreamIndex = self.getAudioStreamIndex(player); + let indexInList = -1; + for (let i = 0, length = mediaStreams.length; i < length; i++) { if (mediaStreams[i].Index === currentStreamIndex) { indexInList = i; break; } } - var nextIndex = indexInList + 1; + let nextIndex = indexInList + 1; if (nextIndex >= mediaStreams.length) { nextIndex = 0; } @@ -1212,11 +1218,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var currentMediaSource = self.currentMediaSource(player); - var mediaStreams = []; - var i; - var length; - for (i = 0, length = currentMediaSource.MediaStreams.length; i < length; i++) { + const currentMediaSource = self.currentMediaSource(player); + const mediaStreams = []; + for (let i = 0, length = currentMediaSource.MediaStreams.length; i < length; i++) { if (currentMediaSource.MediaStreams[i].Type === 'Subtitle') { mediaStreams.push(currentMediaSource.MediaStreams[i]); } @@ -1227,16 +1231,16 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var currentStreamIndex = self.getSubtitleStreamIndex(player); - var indexInList = -1; - for (i = 0, length = mediaStreams.length; i < length; i++) { + const currentStreamIndex = self.getSubtitleStreamIndex(player); + let indexInList = -1; + for (let i = 0, length = mediaStreams.length; i < length; i++) { if (mediaStreams[i].Index === currentStreamIndex) { indexInList = i; break; } } - var nextIndex = indexInList + 1; + let nextIndex = indexInList + 1; if (nextIndex >= mediaStreams.length) { nextIndex = -1; } @@ -1256,12 +1260,10 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }; function isAudioStreamSupported(mediaSource, index, deviceProfile) { - var mediaStream; - var i; - var length; - var mediaStreams = mediaSource.MediaStreams; + let mediaStream; + const mediaStreams = mediaSource.MediaStreams; - for (i = 0, length = mediaStreams.length; i < length; i++) { + for (let i = 0, length = mediaStreams.length; i < length; i++) { if (mediaStreams[i].Type === 'Audio' && mediaStreams[i].Index === index) { mediaStream = mediaStreams[i]; break; @@ -1272,13 +1274,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return false; } - var codec = (mediaStream.Codec || '').toLowerCase(); + const codec = (mediaStream.Codec || '').toLowerCase(); if (!codec) { return false; } - var profiles = deviceProfile.DirectPlayProfiles || []; + const profiles = deviceProfile.DirectPlayProfiles || []; return profiles.filter(function (p) { if (p.Type === 'Video') { @@ -1327,7 +1329,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla apiClient = connectionManager.currentApiClient(); } - var endpointInfo = apiClient.getSavedEndpointInfo() || {}; + const endpointInfo = apiClient.getSavedEndpointInfo() || {}; return appSettings.maxStreamingBitrate(endpointInfo.IsInNetwork, mediaType); } @@ -1338,16 +1340,16 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.getMaxStreamingBitrate(); } - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); if (playerData.maxStreamingBitrate) { return playerData.maxStreamingBitrate; } - var mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; - var currentItem = self.currentItem(player); + const mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; + const currentItem = self.currentItem(player); - var apiClient = currentItem ? connectionManager.getApiClient(currentItem.ServerId) : connectionManager.currentApiClient(); + const apiClient = currentItem ? connectionManager.getApiClient(currentItem.ServerId) : connectionManager.currentApiClient(); return getSavedMaxStreamingBitrate(apiClient, mediaType); }; @@ -1357,12 +1359,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.enableAutomaticBitrateDetection(); } - var playerData = getPlayerData(player); - var mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; - var currentItem = self.currentItem(player); + const playerData = getPlayerData(player); + const mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; + const currentItem = self.currentItem(player); - var apiClient = currentItem ? connectionManager.getApiClient(currentItem.ServerId) : connectionManager.currentApiClient(); - var endpointInfo = apiClient.getSavedEndpointInfo() || {}; + const apiClient = currentItem ? connectionManager.getApiClient(currentItem.ServerId) : connectionManager.currentApiClient(); + const endpointInfo = apiClient.getSavedEndpointInfo() || {}; return appSettings.enableAutomaticBitrateDetection(endpointInfo.IsInNetwork, mediaType); }; @@ -1373,13 +1375,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.setMaxStreamingBitrate(options); } - var apiClient = connectionManager.getApiClient(self.currentItem(player).ServerId); + const apiClient = connectionManager.getApiClient(self.currentItem(player).ServerId); apiClient.getEndpointInfo().then(function (endpointInfo) { - var playerData = getPlayerData(player); - var mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; + const playerData = getPlayerData(player); + const mediaType = playerData.streamInfo ? playerData.streamInfo.mediaType : null; - var promise; + let promise; if (options.enableAutomaticBitrateDetection) { appSettings.enableAutomaticBitrateDetection(endpointInfo.IsInNetwork, mediaType, true); promise = apiClient.detectBitrate(true); @@ -1472,17 +1474,17 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.setSubtitleStreamIndex(index); } - var currentStream = getCurrentSubtitleStream(player); + const currentStream = getCurrentSubtitleStream(player); - var newStream = getSubtitleStream(player, index); + const newStream = getSubtitleStream(player, index); if (!currentStream && !newStream) { return; } - var selectedTrackElementIndex = -1; + let selectedTrackElementIndex = -1; - var currentPlayMethod = self.playMethod(player); + const currentPlayMethod = self.playMethod(player); if (currentStream && !newStream) { if (getDeliveryMethod(currentStream) === 'Encode' || (getDeliveryMethod(currentStream) === 'Embed' && currentPlayMethod === 'Transcode')) { @@ -1519,30 +1521,30 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla getPlayerData(player).subtitleStreamIndex = index; }; - self.supportSubtitleOffset = function(player) { + self.supportSubtitleOffset = function (player) { player = player || self._currentPlayer; return player && 'setSubtitleOffset' in player; }; - self.enableShowingSubtitleOffset = function(player) { + self.enableShowingSubtitleOffset = function (player) { player = player || self._currentPlayer; player.enableShowingSubtitleOffset(); }; - self.disableShowingSubtitleOffset = function(player) { + self.disableShowingSubtitleOffset = function (player) { player = player || self._currentPlayer; if (player.disableShowingSubtitleOffset) { player.disableShowingSubtitleOffset(); } }; - self.isShowingSubtitleOffsetEnabled = function(player) { + self.isShowingSubtitleOffsetEnabled = function (player) { player = player || self._currentPlayer; return player.isShowingSubtitleOffsetEnabled(); }; - self.isSubtitleStreamExternal = function(index, player) { - var stream = getSubtitleStream(player, index); + self.isSubtitleStreamExternal = function (index, player) { + const stream = getSubtitleStream(player, index); return stream ? getDeliveryMethod(stream) === 'External' : false; }; @@ -1553,15 +1555,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } }; - self.getPlayerSubtitleOffset = function(player) { + self.getPlayerSubtitleOffset = function (player) { player = player || self._currentPlayer; if (player.getSubtitleOffset) { return player.getSubtitleOffset(); } }; - self.canHandleOffsetOnCurrentSubtitle = function(player) { - var index = self.getSubtitleStreamIndex(player); + self.canHandleOffsetOnCurrentSubtitle = function (player) { + const index = self.getSubtitleStreamIndex(player); return index !== -1 && self.isSubtitleStreamExternal(index, player); }; @@ -1590,7 +1592,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } } - var ticks = getCurrentTicks(player) + offsetTicks; + const ticks = getCurrentTicks(player) + offsetTicks; return this.seek(ticks, player); }; @@ -1600,9 +1602,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla throw new Error('player cannot be null'); } - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); - var currentSrc = (playerData.streamInfo.url || '').toLowerCase(); + const currentSrc = (playerData.streamInfo.url || '').toLowerCase(); if (currentSrc.indexOf('.m3u8') !== -1) { return true; @@ -1612,7 +1614,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.seekable(); } - var isPlayMethodTranscode = self.playMethod(player) === 'Transcode'; + const isPlayMethodTranscode = self.playMethod(player) === 'Transcode'; if (isPlayMethodTranscode) { return false; @@ -1629,37 +1631,35 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla params = params || {}; - var liveStreamId = getPlayerData(player).streamInfo.liveStreamId; - var lastMediaInfoQuery = getPlayerData(player).streamInfo.lastMediaInfoQuery; + const liveStreamId = getPlayerData(player).streamInfo.liveStreamId; + const lastMediaInfoQuery = getPlayerData(player).streamInfo.lastMediaInfoQuery; - var playSessionId = self.playSessionId(player); + const playSessionId = self.playSessionId(player); - var currentItem = self.currentItem(player); + const currentItem = self.currentItem(player); player.getDeviceProfile(currentItem, { - isRetry: params.EnableDirectPlay === false - }).then(function (deviceProfile) { - var audioStreamIndex = params.AudioStreamIndex == null ? getPlayerData(player).audioStreamIndex : params.AudioStreamIndex; - var subtitleStreamIndex = params.SubtitleStreamIndex == null ? getPlayerData(player).subtitleStreamIndex : params.SubtitleStreamIndex; + const audioStreamIndex = params.AudioStreamIndex == null ? getPlayerData(player).audioStreamIndex : params.AudioStreamIndex; + const subtitleStreamIndex = params.SubtitleStreamIndex == null ? getPlayerData(player).subtitleStreamIndex : params.SubtitleStreamIndex; - var currentMediaSource = self.currentMediaSource(player); - var apiClient = connectionManager.getApiClient(currentItem.ServerId); + let currentMediaSource = self.currentMediaSource(player); + const apiClient = connectionManager.getApiClient(currentItem.ServerId); if (ticks) { ticks = parseInt(ticks); } - var maxBitrate = params.MaxStreamingBitrate || self.getMaxStreamingBitrate(player); + const maxBitrate = params.MaxStreamingBitrate || self.getMaxStreamingBitrate(player); - var currentPlayOptions = currentItem.playOptions || getDefaultPlayOptions(); + const currentPlayOptions = currentItem.playOptions || getDefaultPlayOptions(); getPlaybackInfo(player, apiClient, currentItem, deviceProfile, maxBitrate, ticks, true, currentMediaSource.Id, audioStreamIndex, subtitleStreamIndex, liveStreamId, params.EnableDirectPlay, params.EnableDirectStream, params.AllowVideoStreamCopy, params.AllowAudioStreamCopy).then(function (result) { if (validatePlaybackInfoResult(self, result)) { currentMediaSource = result.MediaSources[0]; - var streamInfo = createStreamInfo(apiClient, currentItem.MediaType, currentItem, currentMediaSource, ticks); + const streamInfo = createStreamInfo(apiClient, currentItem.MediaType, currentItem, currentMediaSource, ticks); streamInfo.fullscreen = currentPlayOptions.fullscreen; streamInfo.lastMediaInfoQuery = lastMediaInfoQuery; @@ -1679,14 +1679,14 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function changeStreamToUrl(apiClient, player, playSessionId, streamInfo, newPositionTicks) { - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); playerData.isChangingStream = true; if (playerData.streamInfo && playSessionId) { apiClient.stopActiveEncodings(playSessionId).then(function () { // Stop the first transcoding afterwards because the player may still send requests to the original url - var afterSetSrc = function () { + const afterSetSrc = function () { apiClient.stopActiveEncodings(playSessionId); }; setSrcIntoPlayer(apiClient, player, streamInfo).then(afterSetSrc, afterSetSrc); @@ -1698,7 +1698,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla function setSrcIntoPlayer(apiClient, player, streamInfo) { return player.play(streamInfo).then(function () { - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); playerData.isChangingStream = false; playerData.streamInfo = streamInfo; @@ -1707,7 +1707,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla sendProgressUpdate(player, 'timeupdate'); }, function (e) { - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); playerData.isChangingStream = false; onPlaybackError.call(player, e, { @@ -1725,12 +1725,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }); } - var firstItem = items[0]; - var promise; + const firstItem = items[0]; + let promise; - var serverId = firstItem.ServerId; + const serverId = firstItem.ServerId; - var queryOptions = options.queryOptions || {}; + const queryOptions = options.queryOptions || {}; if (firstItem.Type === 'Program') { promise = getItemsForPlayback(serverId, { @@ -1758,9 +1758,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla SortBy: options.shuffle ? 'Random' : 'SortName', MediaTypes: 'Photo,Video' }).then(function (result) { - var items = result.Items; + const items = result.Items; - var index = items.map(function (i) { + let index = items.map(function (i) { return i.Id; }).indexOf(firstItem.Id); @@ -1781,7 +1781,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla SortBy: options.shuffle ? 'Random' : 'SortName', MediaTypes: 'Photo,Video', Limit: 1000 - }); } else if (firstItem.Type === 'MusicGenre') { promise = getItemsForPlayback(serverId, { @@ -1793,18 +1792,16 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }); } else if (firstItem.IsFolder) { promise = getItemsForPlayback(serverId, mergePlaybackQueries({ - ParentId: firstItem.Id, Filters: 'IsNotFolder', Recursive: true, // These are pre-sorted SortBy: options.shuffle ? 'Random' : (['BoxSet'].indexOf(firstItem.Type) === -1 ? 'SortName' : null), MediaTypes: 'Audio,Video' - }, queryOptions)); } else if (firstItem.Type === 'Episode' && items.length === 1 && getPlayer(firstItem, options).supportsProgress !== false) { promise = new Promise(function (resolve, reject) { - var apiClient = connectionManager.getApiClient(firstItem.ServerId); + const apiClient = connectionManager.getApiClient(firstItem.ServerId); apiClient.getCurrentUser().then(function (user) { if (!user.Configuration.EnableNextEpisodeAutoPlay || !firstItem.SeriesId) { @@ -1817,9 +1814,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla IsMissing: false, UserId: apiClient.getCurrentUserId(), Fields: 'Chapters' - }).then(function (episodesResult) { - var foundItem = false; + let foundItem = false; episodesResult.Items = episodesResult.Items.filter(function (e) { if (foundItem) { return true; @@ -1874,9 +1870,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return getItemsForPlayback(options.serverId, { - Ids: options.ids.join(',') - }).then(function (result) { return translateItemsForPlayback(result.Items, options).then(function (items) { return playWithIntros(items, options); @@ -1892,7 +1886,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (!player.name) { throw new Error('player name cannot be null'); } - var state = playerStates[player.name]; + let state = playerStates[player.name]; if (!state) { playerStates[player.name] = {}; @@ -1916,7 +1910,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla item = item || self.currentItem(player); mediaSource = mediaSource || self.currentMediaSource(player); - var state = { + const state = { PlayState: {} }; @@ -1974,13 +1968,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla throw new Error('player cannot be null'); } - var mediaSource = self.currentMediaSource(player); + const mediaSource = self.currentMediaSource(player); if (mediaSource && mediaSource.RunTimeTicks) { return mediaSource.RunTimeTicks; } - var playerDuration = player.duration(); + let playerDuration = player.duration(); if (playerDuration) { playerDuration *= 10000; @@ -1994,9 +1988,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla throw new Error('player cannot be null'); } - var playerTime = Math.floor(10000 * (player || self._currentPlayer).currentTime()); + let playerTime = Math.floor(10000 * (player || self._currentPlayer).currentTime()); - var streamInfo = getPlayerData(player).streamInfo; + const streamInfo = getPlayerData(player).streamInfo; if (streamInfo) { playerTime += getPlayerData(player).streamInfo.transcodingOffsetTicks || 0; } @@ -2008,8 +2002,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla self.getCurrentTicks = getCurrentTicks; function playOther(items, options, user) { - var playStartIndex = options.startIndex || 0; - var player = getPlayer(items[playStartIndex], options); + const playStartIndex = options.startIndex || 0; + const player = getPlayer(items[playStartIndex], options); loading.hide(); @@ -2019,8 +2013,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function playWithIntros(items, options, user) { - var playStartIndex = options.startIndex || 0; - var firstItem = items[playStartIndex]; + let playStartIndex = options.startIndex || 0; + let firstItem = items[playStartIndex]; // If index was bad, reset it if (!firstItem) { @@ -2038,11 +2032,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return playOther(items, options, user); } - var apiClient = connectionManager.getApiClient(firstItem.ServerId); + const apiClient = connectionManager.getApiClient(firstItem.ServerId); return getIntros(firstItem, apiClient, options).then(function (introsResult) { - var introItems = introsResult.Items; - var introPlayOptions; + const introItems = introsResult.Items; + let introPlayOptions; firstItem.playOptions = truncatePlayOptions(options); @@ -2098,9 +2092,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } // TODO: This should be the media type requested, not the original media type - var mediaType = item.MediaType; + const mediaType = item.MediaType; - var onBitrateDetectionFailure = function () { + const onBitrateDetectionFailure = function () { return playAfterBitrateDetect(getSavedMaxStreamingBitrate(connectionManager.getApiClient(item.ServerId), mediaType), item, playOptions, onPlaybackStartedFn); }; @@ -2108,7 +2102,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return onBitrateDetectionFailure(); } - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); apiClient.getEndpointInfo().then(function (endpointInfo) { if ((mediaType === 'Video' || mediaType === 'Audio') && appSettings.enableAutomaticBitrateDetection(endpointInfo.IsInNetwork, mediaType)) { return apiClient.detectBitrate().then(function (bitrate) { @@ -2124,7 +2118,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onInterceptorRejection() { - var player = self._currentPlayer; + const player = self._currentPlayer; if (player) { destroyPlayer(player); @@ -2142,7 +2136,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla function runInterceptors(item, playOptions) { return new Promise(function (resolve, reject) { - var interceptors = pluginManager.ofType('preplayintercept'); + const interceptors = pluginManager.ofType('preplayintercept'); interceptors.sort(function (a, b) { return (a.order || 0) - (b.order || 0); @@ -2155,7 +2149,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla loading.hide(); - var options = Object.assign({}, playOptions); + const options = Object.assign({}, playOptions); options.mediaType = item.MediaType; options.item = item; @@ -2170,7 +2164,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var interceptor = interceptors[index]; + const interceptor = interceptors[index]; interceptor.intercept(options).then(function () { runNextPrePlay(interceptors, index + 1, options, resolve, reject); @@ -2193,12 +2187,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function playAfterBitrateDetect(maxBitrate, item, playOptions, onPlaybackStartedFn) { - var startPosition = playOptions.startPositionTicks; + const startPosition = playOptions.startPositionTicks; - var player = getPlayer(item, playOptions); - var activePlayer = self._currentPlayer; + const player = getPlayer(item, playOptions); + const activePlayer = self._currentPlayer; - var promise; + let promise; if (activePlayer) { // TODO: if changing players within the same playlist, this will cause nextItem to be null @@ -2210,7 +2204,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (!isServerItem(item) || item.MediaType === 'Book') { return promise.then(function () { - var streamInfo = createStreamInfoFromUrlItem(item); + const streamInfo = createStreamInfoFromUrlItem(item); streamInfo.fullscreen = playOptions.fullscreen; getPlayerData(player).isChangingStream = false; return player.play(streamInfo).then(function () { @@ -2225,13 +2219,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return Promise.all([promise, player.getDeviceProfile(item)]).then(function (responses) { - var deviceProfile = responses[1]; + const deviceProfile = responses[1]; - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); - var mediaSourceId = playOptions.mediaSourceId; - var audioStreamIndex = playOptions.audioStreamIndex; - var subtitleStreamIndex = playOptions.subtitleStreamIndex; + const mediaSourceId = playOptions.mediaSourceId; + const audioStreamIndex = playOptions.audioStreamIndex; + const subtitleStreamIndex = playOptions.subtitleStreamIndex; if (player && !enableLocalPlaylistManagement(player)) { return sendPlaybackListToPlayer(player, playOptions.items, deviceProfile, maxBitrate, apiClient, startPosition, mediaSourceId, audioStreamIndex, subtitleStreamIndex, playOptions.startIndex); @@ -2241,7 +2235,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla playOptions.items = null; return getPlaybackMediaSource(player, apiClient, deviceProfile, maxBitrate, item, startPosition, mediaSourceId, audioStreamIndex, subtitleStreamIndex).then(function (mediaSource) { - var streamInfo = createStreamInfo(apiClient, item.MediaType, item, mediaSource, startPosition); + const streamInfo = createStreamInfo(apiClient, item.MediaType, item, mediaSource, startPosition); streamInfo.fullscreen = playOptions.fullscreen; @@ -2269,14 +2263,14 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla self.getPlaybackInfo = function (item, options) { options = options || {}; - var startPosition = options.startPositionTicks || 0; - var mediaType = options.mediaType || item.MediaType; - var player = getPlayer(item, options); - var apiClient = connectionManager.getApiClient(item.ServerId); + const startPosition = options.startPositionTicks || 0; + const mediaType = options.mediaType || item.MediaType; + const player = getPlayer(item, options); + const apiClient = connectionManager.getApiClient(item.ServerId); // Call this just to ensure the value is recorded, it is needed with getSavedMaxStreamingBitrate return apiClient.getEndpointInfo().then(function () { - var maxBitrate = getSavedMaxStreamingBitrate(connectionManager.getApiClient(item.ServerId), mediaType); + const maxBitrate = getSavedMaxStreamingBitrate(connectionManager.getApiClient(item.ServerId), mediaType); return player.getDeviceProfile(item).then(function (deviceProfile) { return getPlaybackMediaSource(player, apiClient, deviceProfile, maxBitrate, item, startPosition, options.mediaSourceId, options.audioStreamIndex, options.subtitleStreamIndex).then(function (mediaSource) { @@ -2288,15 +2282,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla self.getPlaybackMediaSources = function (item, options) { options = options || {}; - var startPosition = options.startPositionTicks || 0; - var mediaType = options.mediaType || item.MediaType; + const startPosition = options.startPositionTicks || 0; + const mediaType = options.mediaType || item.MediaType; // TODO: Remove the true forceLocalPlayer hack - var player = getPlayer(item, options, true); - var apiClient = connectionManager.getApiClient(item.ServerId); + const player = getPlayer(item, options, true); + const apiClient = connectionManager.getApiClient(item.ServerId); // Call this just to ensure the value is recorded, it is needed with getSavedMaxStreamingBitrate return apiClient.getEndpointInfo().then(function () { - var maxBitrate = getSavedMaxStreamingBitrate(connectionManager.getApiClient(item.ServerId), mediaType); + const maxBitrate = getSavedMaxStreamingBitrate(connectionManager.getApiClient(item.ServerId), mediaType); return player.getDeviceProfile(item).then(function (deviceProfile) { return getPlaybackInfo(player, apiClient, item, deviceProfile, maxBitrate, startPosition, false, null, null, null, null).then(function (playbackInfoResult) { @@ -2307,16 +2301,16 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }; function createStreamInfo(apiClient, type, item, mediaSource, startPosition) { - var mediaUrl; - var contentType; - var transcodingOffsetTicks = 0; - var playerStartPositionTicks = startPosition; - var liveStreamId = mediaSource.LiveStreamId; + let mediaUrl; + let contentType; + let transcodingOffsetTicks = 0; + const playerStartPositionTicks = startPosition; + const liveStreamId = mediaSource.LiveStreamId; - var playMethod = 'Transcode'; + let playMethod = 'Transcode'; - var mediaSourceContainer = (mediaSource.Container || '').toLowerCase(); - var directOptions; + const mediaSourceContainer = (mediaSource.Container || '').toLowerCase(); + let directOptions; if (type === 'Video' || type === 'Audio') { contentType = getMimeType(type.toLowerCase(), mediaSourceContainer); @@ -2345,7 +2339,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla directOptions.LiveStreamId = mediaSource.LiveStreamId; } - var prefix = type === 'Video' ? 'Videos' : 'Audio'; + const prefix = type === 'Video' ? 'Videos' : 'Audio'; mediaUrl = apiClient.getUrl(prefix + '/' + item.Id + '/stream.' + mediaSourceContainer, directOptions); playMethod = 'DirectStream'; @@ -2374,7 +2368,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla playMethod = 'DirectPlay'; } - var resultInfo = { + const resultInfo = { url: mediaUrl, mimeType: contentType, transcodingOffsetTicks: transcodingOffsetTicks, @@ -2391,7 +2385,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla title: item.Name }; - var backdropUrl = backdropImageUrl(apiClient, item, {}); + const backdropUrl = backdropImageUrl(apiClient, item, {}); if (backdropUrl) { resultInfo.backdropUrl = backdropUrl; } @@ -2400,19 +2394,19 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function getTextTracks(apiClient, item, mediaSource) { - var subtitleStreams = mediaSource.MediaStreams.filter(function (s) { + const subtitleStreams = mediaSource.MediaStreams.filter(function (s) { return s.Type === 'Subtitle'; }); - var textStreams = subtitleStreams.filter(function (s) { + const textStreams = subtitleStreams.filter(function (s) { return s.DeliveryMethod === 'External'; }); - var tracks = []; + const tracks = []; - for (var i = 0, length = textStreams.length; i < length; i++) { - var textStream = textStreams[i]; - var textStreamUrl; + for (let i = 0, length = textStreams.length; i < length; i++) { + const textStream = textStreams[i]; + let textStreamUrl; if (itemHelper.isLocalItem(item)) { textStreamUrl = textStream.Path; @@ -2459,7 +2453,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function getPlayer(item, playOptions, forceLocalPlayers) { - var serverItem = isServerItem(item); + const serverItem = isServerItem(item); return getAutomaticPlayers(self, forceLocalPlayers).filter(function (p) { if (p.canPlayMediaType(item.MediaType)) { if (serverItem) { @@ -2482,11 +2476,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.setCurrentPlaylistItem(playlistItemId); } - var newItem; - var newItemIndex; - var playlist = self._playQueueManager.getPlaylist(); + let newItem; + let newItemIndex; + const playlist = self._playQueueManager.getPlaylist(); - for (var i = 0, length = playlist.length; i < length; i++) { + for (let i = 0, length = playlist.length; i < length; i++) { if (playlist[i].PlaylistItemId === playlistItemId) { newItem = playlist[i]; newItemIndex = i; @@ -2495,7 +2489,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } if (newItem) { - var newItemPlayOptions = newItem.playOptions || getDefaultPlayOptions(); + const newItemPlayOptions = newItem.playOptions || getDefaultPlayOptions(); playInternal(newItem, newItemPlayOptions, function () { setPlaylistState(newItem.PlaylistItemId, newItemIndex); @@ -2513,18 +2507,19 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.removeFromPlaylist(playlistItemIds); } - var removeResult = self._playQueueManager.removeFromPlaylist(playlistItemIds); + const removeResult = self._playQueueManager.removeFromPlaylist(playlistItemIds); if (removeResult.result === 'empty') { return self.stop(player); } - var isCurrentIndex = removeResult.isCurrentIndex; + const isCurrentIndex = removeResult.isCurrentIndex; events.trigger(player, 'playlistitemremove', [ { playlistItemIds: playlistItemIds - }]); + } + ]); if (isCurrentIndex) { return self.setCurrentPlaylistItem(self._playQueueManager.getPlaylist()[0].PlaylistItemId, player); @@ -2539,7 +2534,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.movePlaylistItem(playlistItemId, newIndex); } - var moveResult = self._playQueueManager.movePlaylistItem(playlistItemId, newIndex); + const moveResult = self._playQueueManager.movePlaylistItem(playlistItemId, newIndex); if (moveResult.result === 'noop') { return; @@ -2549,7 +2544,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla { playlistItemId: moveResult.playlistItemId, newIndex: moveResult.newIndex - }]); + } + ]); }; self.getCurrentPlaylistIndex = function (player) { @@ -2586,12 +2582,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.nextTrack(); } - var newItemInfo = self._playQueueManager.getNextItemInfo(); + const newItemInfo = self._playQueueManager.getNextItemInfo(); if (newItemInfo) { console.debug('playing next track'); - var newItemPlayOptions = newItemInfo.item.playOptions || getDefaultPlayOptions(); + const newItemPlayOptions = newItemInfo.item.playOptions || getDefaultPlayOptions(); playInternal(newItemInfo.item, newItemPlayOptions, function () { setPlaylistState(newItemInfo.item.PlaylistItemId, newItemInfo.index); @@ -2605,13 +2601,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.previousTrack(); } - var newIndex = self.getCurrentPlaylistIndex(player) - 1; + const newIndex = self.getCurrentPlaylistIndex(player) - 1; if (newIndex >= 0) { - var playlist = self._playQueueManager.getPlaylist(); - var newItem = playlist[newIndex]; + const playlist = self._playQueueManager.getPlaylist(); + const newItem = playlist[newIndex]; if (newItem) { - var newItemPlayOptions = newItem.playOptions || getDefaultPlayOptions(); + const newItemPlayOptions = newItem.playOptions || getDefaultPlayOptions(); newItemPlayOptions.startPositionTicks = 0; playInternal(newItem, newItemPlayOptions, function () { @@ -2647,9 +2643,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return getItemsForPlayback(options.serverId, { - Ids: options.ids.join(',') - }).then(function (result) { return translateItemsForPlayback(result.Items, options).then(function (items) { // TODO: Handle options.startIndex for photos @@ -2677,10 +2671,10 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return; } - var queueDirectToPlayer = player && !enableLocalPlaylistManagement(player); + const queueDirectToPlayer = player && !enableLocalPlaylistManagement(player); if (queueDirectToPlayer) { - var apiClient = connectionManager.getApiClient(items[0].ServerId); + const apiClient = connectionManager.getApiClient(items[0].ServerId); player.getDeviceProfile(items[0]).then(function (profile) { setStreamUrls(items, profile, self.getMaxStreamingBitrate(player), apiClient, 0).then(function () { @@ -2704,7 +2698,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlayerProgressInterval() { - var player = this; + const player = this; sendProgressUpdate(player, 'timeupdate'); } @@ -2728,7 +2722,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla setCurrentPlayerInternal(player); - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); playerData.streamInfo = streamInfo; @@ -2743,10 +2737,10 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } self._playNextAfterEnded = true; - var isFirstItem = playOptions.isFirstItem; - var fullscreen = playOptions.fullscreen; + const isFirstItem = playOptions.isFirstItem; + const fullscreen = playOptions.fullscreen; - var state = self.getPlayerState(player, streamInfo.item, streamInfo.mediaSource); + const state = self.getPlayerState(player, streamInfo.item, streamInfo.mediaSource); reportPlayback(self, state, player, true, state.NowPlayingItem.ServerId, 'reportPlaybackStart'); @@ -2762,22 +2756,22 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlaybackStartedFromSelfManagingPlayer(e, item, mediaSource) { - var player = this; + const player = this; setCurrentPlayerInternal(player); - var playOptions = item.playOptions || getDefaultPlayOptions(); - var isFirstItem = playOptions.isFirstItem; - var fullscreen = playOptions.fullscreen; + const playOptions = item.playOptions || getDefaultPlayOptions(); + const isFirstItem = playOptions.isFirstItem; + const fullscreen = playOptions.fullscreen; playOptions.isFirstItem = false; - var playerData = getPlayerData(player); + const playerData = getPlayerData(player); playerData.streamInfo = {}; - var streamInfo = playerData.streamInfo; + const streamInfo = playerData.streamInfo; streamInfo.playbackStartTimeTicks = new Date().getTime() * 10000; - var state = self.getPlayerState(player, item, mediaSource); + const state = self.getPlayerState(player, item, mediaSource); reportPlayback(self, state, player, true, state.NowPlayingItem.ServerId, 'reportPlaybackStart'); @@ -2793,15 +2787,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlaybackStoppedFromSelfManagingPlayer(e, playerStopInfo) { - var player = this; + const player = this; stopPlaybackProgressTimer(player); - var state = self.getPlayerState(player, playerStopInfo.item, playerStopInfo.mediaSource); + const state = self.getPlayerState(player, playerStopInfo.item, playerStopInfo.mediaSource); - var nextItem = playerStopInfo.nextItem; - var nextMediaType = playerStopInfo.nextMediaType; + const nextItem = playerStopInfo.nextItem; + const nextMediaType = playerStopInfo.nextMediaType; - var playbackStopInfo = { + const playbackStopInfo = { player: player, state: state, nextItem: (nextItem ? nextItem.item : null), @@ -2810,7 +2804,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla state.NextMediaType = nextMediaType; - var streamInfo = getPlayerData(player).streamInfo; + const streamInfo = getPlayerData(player).streamInfo; // only used internally as a safeguard to avoid reporting other events to the server after playback stopped streamInfo.ended = true; @@ -2826,8 +2820,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.trigger(player, 'playbackstop', [state]); events.trigger(self, 'playbackstop', [playbackStopInfo]); - var nextItemPlayOptions = nextItem ? (nextItem.item.playOptions || getDefaultPlayOptions()) : getDefaultPlayOptions(); - var newPlayer = nextItem ? getPlayer(nextItem.item, nextItemPlayOptions) : null; + const nextItemPlayOptions = nextItem ? (nextItem.item.playOptions || getDefaultPlayOptions()) : getDefaultPlayOptions(); + const newPlayer = nextItem ? getPlayer(nextItem.item, nextItemPlayOptions) : null; if (newPlayer !== player) { destroyPlayer(player); @@ -2837,7 +2831,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla function enablePlaybackRetryWithTranscoding(streamInfo, errorType, currentlyPreventsVideoStreamCopy, currentlyPreventsAudioStreamCopy) { // mediadecodeerror, medianotsupported, network, servererror - if (streamInfo.mediaSource.SupportsTranscoding && (!currentlyPreventsVideoStreamCopy || !currentlyPreventsAudioStreamCopy)) { return true; } @@ -2846,46 +2839,44 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlaybackError(e, error) { - var player = this; + const player = this; error = error || {}; // network // mediadecodeerror // medianotsupported - var errorType = error.type; + const errorType = error.type; console.debug('playbackmanager playback error type: ' + (errorType || '')); - var streamInfo = error.streamInfo || getPlayerData(player).streamInfo; + const streamInfo = error.streamInfo || getPlayerData(player).streamInfo; if (streamInfo) { - var currentlyPreventsVideoStreamCopy = streamInfo.url.toLowerCase().indexOf('allowvideostreamcopy=false') !== -1; - var currentlyPreventsAudioStreamCopy = streamInfo.url.toLowerCase().indexOf('allowaudiostreamcopy=false') !== -1; + const currentlyPreventsVideoStreamCopy = streamInfo.url.toLowerCase().indexOf('allowvideostreamcopy=false') !== -1; + const currentlyPreventsAudioStreamCopy = streamInfo.url.toLowerCase().indexOf('allowaudiostreamcopy=false') !== -1; // Auto switch to transcoding if (enablePlaybackRetryWithTranscoding(streamInfo, errorType, currentlyPreventsVideoStreamCopy, currentlyPreventsAudioStreamCopy)) { - var startTime = getCurrentTicks(player) || streamInfo.playerStartPositionTicks; + const startTime = getCurrentTicks(player) || streamInfo.playerStartPositionTicks; changeStream(player, startTime, { - // force transcoding EnableDirectPlay: false, EnableDirectStream: false, AllowVideoStreamCopy: false, AllowAudioStreamCopy: currentlyPreventsAudioStreamCopy || currentlyPreventsVideoStreamCopy ? false : null - }); return; } } - var displayErrorCode = 'NoCompatibleStream'; + const displayErrorCode = 'NoCompatibleStream'; onPlaybackStopped.call(player, e, displayErrorCode); } function onPlaybackStopped(e, displayErrorCode) { - var player = this; + const player = this; if (getPlayerData(player).isChangingStream) { return; @@ -2894,15 +2885,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla stopPlaybackProgressTimer(player); // User clicked stop or content ended - var state = self.getPlayerState(player); - var data = getPlayerData(player); - var streamInfo = data.streamInfo; + const state = self.getPlayerState(player); + const data = getPlayerData(player); + const streamInfo = data.streamInfo; - var nextItem = self._playNextAfterEnded ? self._playQueueManager.getNextItemInfo() : null; + const nextItem = self._playNextAfterEnded ? self._playQueueManager.getNextItemInfo() : null; - var nextMediaType = (nextItem ? nextItem.item.MediaType : null); + const nextMediaType = (nextItem ? nextItem.item.MediaType : null); - var playbackStopInfo = { + const playbackStopInfo = { player: player, state: state, nextItem: (nextItem ? nextItem.item : null), @@ -2931,8 +2922,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.trigger(player, 'playbackstop', [state]); events.trigger(self, 'playbackstop', [playbackStopInfo]); - var nextItemPlayOptions = nextItem ? (nextItem.item.playOptions || getDefaultPlayOptions()) : getDefaultPlayOptions(); - var newPlayer = nextItem ? getPlayer(nextItem.item, nextItemPlayOptions) : null; + const nextItemPlayOptions = nextItem ? (nextItem.item.playOptions || getDefaultPlayOptions()) : getDefaultPlayOptions(); + const newPlayer = nextItem ? getPlayer(nextItem.item, nextItemPlayOptions) : null; if (newPlayer !== player) { destroyPlayer(player); @@ -2950,12 +2941,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlaybackChanging(activePlayer, newPlayer, newItem) { - var state = self.getPlayerState(activePlayer); + const state = self.getPlayerState(activePlayer); - var serverId = self.currentItem(activePlayer).ServerId; + const serverId = self.currentItem(activePlayer).ServerId; // User started playing something new while existing content is playing - var promise; + let promise; stopPlaybackProgressTimer(activePlayer); unbindStopped(activePlayer); @@ -2992,47 +2983,47 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } function onPlaybackTimeUpdate(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'timeupdate'); } function onPlaybackPause(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'pause'); } function onPlaybackUnpause(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'unpause'); } function onPlaybackVolumeChange(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'volumechange'); } function onRepeatModeChange(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'repeatmodechange'); } function onShuffleQueueModeChange() { - var player = this; + const player = this; sendProgressUpdate(player, 'shufflequeuemodechange'); } function onPlaylistItemMove(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'playlistitemmove', true); } function onPlaylistItemRemove(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'playlistitemremove', true); } function onPlaylistItemAdd(e) { - var player = this; + const player = this; sendProgressUpdate(player, 'playlistitemadd', true); } @@ -3109,12 +3100,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla throw new Error('player cannot be null'); } - var state = self.getPlayerState(player); + const state = self.getPlayerState(player); if (state.NowPlayingItem) { - var serverId = state.NowPlayingItem.ServerId; + const serverId = state.NowPlayingItem.ServerId; - var streamInfo = getPlayerData(player).streamInfo; + const streamInfo = getPlayerData(player).streamInfo; if (streamInfo && streamInfo.started && !streamInfo.ended) { reportPlayback(self, state, player, reportPlaylist, serverId, 'reportPlaybackProgress', progressEventName); @@ -3133,7 +3124,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla streamInfo.lastMediaInfoQuery = new Date().getTime(); - var apiClient = connectionManager.getApiClient(serverId); + const apiClient = connectionManager.getApiClient(serverId); if (!apiClient.isMinServerVersion('3.2.70.7')) { return; @@ -3143,12 +3134,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla mediaSource.MediaStreams = info.MediaStreams; events.trigger(player, 'mediastreamschange'); }, function () { - }); } self.onAppClose = function () { - var player = this._currentPlayer; + const player = this._currentPlayer; // Try to report playback stopped before the app closes if (player && this.isPlaying(player)) { @@ -3163,64 +3153,64 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return player.playbackStartTime(); } - var streamInfo = getPlayerData(player).streamInfo; + const streamInfo = getPlayerData(player).streamInfo; return streamInfo ? streamInfo.playbackStartTimeTicks : null; }; if (apphost.supports('remotecontrol')) { - require(['serverNotifications'], function (serverNotifications) { + import('serverNotifications').then(({ default: serverNotifications }) => { events.on(serverNotifications, 'ServerShuttingDown', self.setDefaultPlayerActive.bind(self)); events.on(serverNotifications, 'ServerRestarting', self.setDefaultPlayerActive.bind(self)); }); } } - PlaybackManager.prototype.getCurrentPlayer = function () { + getCurrentPlayer() { return this._currentPlayer; - }; + } - PlaybackManager.prototype.currentTime = function (player) { + currentTime(player) { player = player || this._currentPlayer; if (player && !enableLocalPlaylistManagement(player) && !player.isLocalPlayer) { return player.currentTime(); } return this.getCurrentTicks(player); - }; + } - PlaybackManager.prototype.nextItem = function (player) { + nextItem(player) { player = player || this._currentPlayer; if (player && !enableLocalPlaylistManagement(player)) { return player.nextItem(); } - var nextItem = this._playQueueManager.getNextItemInfo(); + const nextItem = this._playQueueManager.getNextItemInfo(); if (!nextItem || !nextItem.item) { return Promise.reject(); } - var apiClient = connectionManager.getApiClient(nextItem.item.ServerId); + const apiClient = connectionManager.getApiClient(nextItem.item.ServerId); return apiClient.getItem(apiClient.getCurrentUserId(), nextItem.item.Id); - }; + } - PlaybackManager.prototype.canQueue = function (item) { + canQueue(item) { if (item.Type === 'MusicAlbum' || item.Type === 'MusicArtist' || item.Type === 'MusicGenre') { return this.canQueueMediaType('Audio'); } return this.canQueueMediaType(item.MediaType); - }; + } - PlaybackManager.prototype.canQueueMediaType = function (mediaType) { + canQueueMediaType(mediaType) { if (this._currentPlayer) { return this._currentPlayer.canPlayMediaType(mediaType); } return false; - }; + } - PlaybackManager.prototype.isMuted = function (player) { + isMuted(player) { player = player || this._currentPlayer; if (player) { @@ -3228,17 +3218,17 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return false; - }; + } - PlaybackManager.prototype.setMute = function (mute, player) { + setMute(mute, player) { player = player || this._currentPlayer; if (player) { player.setMute(mute); } - }; + } - PlaybackManager.prototype.toggleMute = function (mute, player) { + toggleMute(mute, player) { player = player || this._currentPlayer; if (player) { if (player.toggleMute) { @@ -3247,29 +3237,29 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla player.setMute(!player.isMuted()); } } - }; + } - PlaybackManager.prototype.toggleDisplayMirroring = function () { + toggleDisplayMirroring() { this.enableDisplayMirroring(!this.enableDisplayMirroring()); - }; + } - PlaybackManager.prototype.enableDisplayMirroring = function (enabled) { + enableDisplayMirroring(enabled) { if (enabled != null) { - var val = enabled ? '1' : '0'; + const val = enabled ? '1' : '0'; appSettings.set('displaymirror', val); return; } return (appSettings.get('displaymirror') || '') !== '0'; - }; + } - PlaybackManager.prototype.nextChapter = function (player) { + nextChapter(player) { player = player || this._currentPlayer; - var item = this.currentItem(player); + const item = this.currentItem(player); - var ticks = this.getCurrentTicks(player); + const ticks = this.getCurrentTicks(player); - var nextChapter = (item.Chapters || []).filter(function (i) { + const nextChapter = (item.Chapters || []).filter(function (i) { return i.StartPositionTicks > ticks; })[0]; @@ -3278,13 +3268,13 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } else { this.nextTrack(player); } - }; + } - PlaybackManager.prototype.previousChapter = function (player) { + previousChapter(player) { player = player || this._currentPlayer; - var item = this.currentItem(player); + const item = this.currentItem(player); - var ticks = this.getCurrentTicks(player); + let ticks = this.getCurrentTicks(player); // Go back 10 seconds ticks -= 100000000; @@ -3294,7 +3284,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla ticks = Math.max(ticks, 0); } - var previousChapters = (item.Chapters || []).filter(function (i) { + const previousChapters = (item.Chapters || []).filter(function (i) { return i.StartPositionTicks <= ticks; }); @@ -3303,9 +3293,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } else { this.previousTrack(player); } - }; + } - PlaybackManager.prototype.fastForward = function (player) { + fastForward(player) { player = player || this._currentPlayer; if (player.fastForward != null) { @@ -3314,12 +3304,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } // Go back 15 seconds - var offsetTicks = userSettings.skipForwardLength() * 10000; + const offsetTicks = userSettings.skipForwardLength() * 10000; this.seekRelative(offsetTicks, player); - }; + } - PlaybackManager.prototype.rewind = function (player) { + rewind(player) { player = player || this._currentPlayer; if (player.rewind != null) { @@ -3328,38 +3318,38 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } // Go back 15 seconds - var offsetTicks = 0 - (userSettings.skipBackLength() * 10000); + const offsetTicks = 0 - (userSettings.skipBackLength() * 10000); this.seekRelative(offsetTicks, player); - }; + } - PlaybackManager.prototype.seekPercent = function (percent, player) { + seekPercent(percent, player) { player = player || this._currentPlayer; - var ticks = this.duration(player) || 0; + let ticks = this.duration(player) || 0; percent /= 100; ticks *= percent; this.seek(parseInt(ticks), player); - }; + } - PlaybackManager.prototype.seekMs = function (ms, player) { + seekMs(ms, player) { player = player || this._currentPlayer; - var ticks = ms * 10000; + const ticks = ms * 10000; this.seek(ticks, player); - }; + } - PlaybackManager.prototype.playTrailers = function (item) { - var player = this._currentPlayer; + playTrailers(item) { + const player = this._currentPlayer; if (player && player.playTrailers) { return player.playTrailers(item); } - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); - var instance = this; + const instance = this; if (item.LocalTrailerCount) { return apiClient.getLocalTrailers(apiClient.getCurrentUserId(), item.Id).then(function (result) { @@ -3368,7 +3358,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }); }); } else { - var remoteTrailers = item.RemoteTrailers || []; + const remoteTrailers = item.RemoteTrailers || []; if (!remoteTrailers.length) { return Promise.reject(); @@ -3386,15 +3376,15 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }) }); } - }; + } - PlaybackManager.prototype.getSubtitleUrl = function (textStream, serverId) { - var apiClient = connectionManager.getApiClient(serverId); + getSubtitleUrl(textStream, serverId) { + const apiClient = connectionManager.getApiClient(serverId); return !textStream.IsExternalUrl ? apiClient.getUrl(textStream.DeliveryUrl) : textStream.DeliveryUrl; - }; + } - PlaybackManager.prototype.stop = function (player) { + stop(player) { player = player || this._currentPlayer; if (player) { @@ -3407,9 +3397,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return Promise.resolve(); - }; + } - PlaybackManager.prototype.getBufferedRanges = function (player) { + getBufferedRanges(player) { player = player || this._currentPlayer; if (player) { @@ -3419,9 +3409,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } return []; - }; + } - PlaybackManager.prototype.playPause = function (player) { + playPause(player) { player = player || this._currentPlayer; if (player) { @@ -3435,115 +3425,115 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return this.pause(player); } } - }; + } - PlaybackManager.prototype.paused = function (player) { + paused(player) { player = player || this._currentPlayer; if (player) { return player.paused(); } - }; + } - PlaybackManager.prototype.pause = function (player) { + pause(player) { player = player || this._currentPlayer; if (player) { player.pause(); } - }; + } - PlaybackManager.prototype.unpause = function (player) { + unpause(player) { player = player || this._currentPlayer; if (player) { player.unpause(); } - }; + } - PlaybackManager.prototype.setPlaybackRate = function (value, player = this._currentPlayer) { + setPlaybackRate(value, player = this._currentPlayer) { if (player && player.setPlaybackRate) { player.setPlaybackRate(value); } - }; + } - PlaybackManager.prototype.getPlaybackRate = function (player = this._currentPlayer) { + getPlaybackRate(player = this._currentPlayer) { if (player && player.getPlaybackRate) { return player.getPlaybackRate(); } return null; - }; + } - PlaybackManager.prototype.instantMix = function (item, player) { + instantMix(item, player) { player = player || this._currentPlayer; if (player && player.instantMix) { return player.instantMix(item); } - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); - var options = {}; + const options = {}; options.UserId = apiClient.getCurrentUserId(); options.Limit = 200; - var instance = this; + const instance = this; apiClient.getInstantMixFromItem(item.Id, options).then(function (result) { instance.play({ items: result.Items }); }); - }; + } - PlaybackManager.prototype.shuffle = function (shuffleItem, player) { + shuffle(shuffleItem, player) { player = player || this._currentPlayer; if (player && player.shuffle) { return player.shuffle(shuffleItem); } return this.play({ items: [shuffleItem], shuffle: true }); - }; + } - PlaybackManager.prototype.audioTracks = function (player) { + audioTracks(player) { player = player || this._currentPlayer; if (player.audioTracks) { - var result = player.audioTracks(); + const result = player.audioTracks(); if (result) { return result; } } - var mediaSource = this.currentMediaSource(player); + const mediaSource = this.currentMediaSource(player); - var mediaStreams = (mediaSource || {}).MediaStreams || []; + const mediaStreams = (mediaSource || {}).MediaStreams || []; return mediaStreams.filter(function (s) { return s.Type === 'Audio'; }); - }; + } - PlaybackManager.prototype.subtitleTracks = function (player) { + subtitleTracks(player) { player = player || this._currentPlayer; if (player.subtitleTracks) { - var result = player.subtitleTracks(); + const result = player.subtitleTracks(); if (result) { return result; } } - var mediaSource = this.currentMediaSource(player); + const mediaSource = this.currentMediaSource(player); - var mediaStreams = (mediaSource || {}).MediaStreams || []; + const mediaStreams = (mediaSource || {}).MediaStreams || []; return mediaStreams.filter(function (s) { return s.Type === 'Subtitle'; }); - }; + } - PlaybackManager.prototype.getSupportedCommands = function (player) { + getSupportedCommands(player) { player = player || this._currentPlayer || { isLocalPlayer: true }; if (player.isLocalPlayer) { - var list = [ + const list = [ 'GoHome', 'GoToSettings', 'VolumeUp', @@ -3589,45 +3579,45 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return list; } - var info = this.getPlayerInfo(); + const info = this.getPlayerInfo(); return info ? info.supportedCommands : []; - }; + } - PlaybackManager.prototype.setRepeatMode = function (value, player = this._currentPlayer) { + setRepeatMode(value, player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.setRepeatMode(value); } this._playQueueManager.setRepeatMode(value); events.trigger(player, 'repeatmodechange'); - }; + } - PlaybackManager.prototype.getRepeatMode = function (player = this._currentPlayer) { + getRepeatMode(player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.getRepeatMode(); } return this._playQueueManager.getRepeatMode(); - }; + } - PlaybackManager.prototype.setQueueShuffleMode = function (value, player = this._currentPlayer) { + setQueueShuffleMode(value, player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.setQueueShuffleMode(value); } this._playQueueManager.setShuffleMode(value); events.trigger(player, 'shufflequeuemodechange'); - }; + } - PlaybackManager.prototype.getQueueShuffleMode = function (player = this._currentPlayer) { + getQueueShuffleMode(player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.getQueueShuffleMode(); } return this._playQueueManager.getShuffleMode(); - }; + } - PlaybackManager.prototype.toggleQueueShuffleMode = function (player = this._currentPlayer) { + toggleQueueShuffleMode(player = this._currentPlayer) { let currentvalue; if (player && !enableLocalPlaylistManagement(player)) { currentvalue = player.getQueueShuffleMode(); @@ -3645,23 +3635,23 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla this._playQueueManager.toggleShuffleMode(); } events.trigger(player, 'shufflequeuemodechange'); - }; + } - PlaybackManager.prototype.clearQueue = function (clearCurrentItem = false, player = this._currentPlayer) { + clearQueue(clearCurrentItem = false, player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.clearQueue(clearCurrentItem); } this._playQueueManager.clearPlaylist(clearCurrentItem); events.trigger(player, 'playlistitemremove'); - }; + } - PlaybackManager.prototype.trySetActiveDeviceName = function (name) { + trySetActiveDeviceName(name) { name = normalizeName(name); - var instance = this; + const instance = this; instance.getTargets().then(function (result) { - var target = result.filter(function (p) { + const target = result.filter(function (p) { return normalizeName(p.name) === name; })[0]; @@ -3669,50 +3659,50 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla instance.trySetActivePlayer(target.playerName, target); } }); - }; + } - PlaybackManager.prototype.displayContent = function (options, player) { + displayContent(options, player) { player = player || this._currentPlayer; if (player && player.displayContent) { player.displayContent(options); } - }; + } - PlaybackManager.prototype.beginPlayerUpdates = function (player) { + beginPlayerUpdates(player) { if (player.beginPlayerUpdates) { player.beginPlayerUpdates(); } - }; + } - PlaybackManager.prototype.endPlayerUpdates = function (player) { + endPlayerUpdates(player) { if (player.endPlayerUpdates) { player.endPlayerUpdates(); } - }; + } - PlaybackManager.prototype.setDefaultPlayerActive = function () { + setDefaultPlayerActive() { this.setActivePlayer('localplayer'); - }; + } - PlaybackManager.prototype.removeActivePlayer = function (name) { - var playerInfo = this.getPlayerInfo(); + removeActivePlayer(name) { + const playerInfo = this.getPlayerInfo(); if (playerInfo) { if (playerInfo.name === name) { this.setDefaultPlayerActive(); } } - }; + } - PlaybackManager.prototype.removeActiveTarget = function (id) { - var playerInfo = this.getPlayerInfo(); + removeActiveTarget(id) { + const playerInfo = this.getPlayerInfo(); if (playerInfo) { if (playerInfo.id === id) { this.setDefaultPlayerActive(); } } - }; + } - PlaybackManager.prototype.sendCommand = function (cmd, player) { + sendCommand(cmd, player) { console.debug('MediaController received command: ' + cmd.Name); switch (cmd.Name) { case 'SetRepeatMode': @@ -3763,7 +3753,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } break; } - }; + } +} - return new PlaybackManager(); -}); +export default new PlaybackManager(); From 49c1b3e159042695b2befc8cc8aa7d5ea8ba88f2 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 09:12:44 +0100 Subject: [PATCH 063/226] Addition of defaults --- src/components/guide/guide.js | 2 ++ src/components/itemsrefresher.js | 2 ++ src/components/notifications/notifications.js | 2 ++ src/components/recordingcreator/recordingcreator.js | 2 +- src/components/remotecontrol/remotecontrol.js | 3 +++ src/components/subtitlesync/subtitlesync.js | 2 ++ src/components/themeMediaPlayer.js | 2 ++ src/components/upnextdialog/upnextdialog.js | 2 ++ src/controllers/itemDetails/index.js | 2 ++ src/controllers/list.js | 2 ++ src/controllers/movies/moviesrecommended.js | 2 ++ src/plugins/chromecastPlayer/plugin.js | 2 ++ src/plugins/sessionPlayer/plugin.js | 2 ++ src/scripts/libraryMenu.js | 2 ++ src/scripts/serverNotifications.js | 2 ++ 15 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index bd3ad89aaa..6601a0508d 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -1,6 +1,8 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'webcomponents'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function showViewSettings(instance) { require(['guide-settings-dialog'], function (guideSettingsDialog) { guideSettingsDialog.show(instance.categoryOptions).then(function () { diff --git a/src/components/itemsrefresher.js b/src/components/itemsrefresher.js index a210af31af..74b08db07f 100644 --- a/src/components/itemsrefresher.js +++ b/src/components/itemsrefresher.js @@ -1,6 +1,8 @@ define(['playbackManager', 'serverNotifications', 'events'], function (playbackManager, serverNotifications, events) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function onUserDataChanged(e, apiClient, userData) { var instance = this; diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index b4647bbf25..0bf270f2a1 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -1,6 +1,8 @@ define(['serverNotifications', 'playbackManager', 'events', 'globalize', 'require'], function (serverNotifications, playbackManager, events, globalize, require) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function onOneDocumentClick() { document.removeEventListener('click', onOneDocumentClick); document.removeEventListener('keydown', onOneDocumentClick); diff --git a/src/components/recordingcreator/recordingcreator.js b/src/components/recordingcreator/recordingcreator.js index f330e54156..ca5c475829 100644 --- a/src/components/recordingcreator/recordingcreator.js +++ b/src/components/recordingcreator/recordingcreator.js @@ -104,7 +104,7 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c var apiClient = connectionManager.getApiClient(serverId); apiClient.getLiveTvProgram(programId, apiClient.getCurrentUserId()).then(function (item) { - playbackManager.play({ + playbackManager.default.play({ ids: [item.ChannelId], serverId: serverId }); diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 29e77debd1..b5ac4c9a8b 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -1,5 +1,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageLoader', 'playbackManager', 'nowPlayingHelper', 'events', 'connectionManager', 'apphost', 'globalize', 'layoutManager', 'userSettings', 'cardBuilder', 'itemContextMenu', 'cardStyle', 'emby-itemscontainer', 'css!./remotecontrol.css', 'emby-ratingbutton'], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize, layoutManager, userSettings, cardBuilder, itemContextMenu) { 'use strict'; + + playbackManager = playbackManager.default || playbackManager; + var showMuteButton = true; var showVolumeSlider = true; diff --git a/src/components/subtitlesync/subtitlesync.js b/src/components/subtitlesync/subtitlesync.js index e825e8e0a2..203d88535f 100644 --- a/src/components/subtitlesync/subtitlesync.js +++ b/src/components/subtitlesync/subtitlesync.js @@ -1,6 +1,8 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html', 'css!./subtitlesync'], function (playbackManager, layoutManager, template, css) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + var player; var subtitleSyncSlider; var subtitleSyncTextField; diff --git a/src/components/themeMediaPlayer.js b/src/components/themeMediaPlayer.js index dd04f384aa..60f0986884 100644 --- a/src/components/themeMediaPlayer.js +++ b/src/components/themeMediaPlayer.js @@ -1,6 +1,8 @@ define(['playbackManager', 'userSettings', 'connectionManager'], function (playbackManager, userSettings, connectionManager) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + var currentOwnerId; var currentThemeIds = []; diff --git a/src/components/upnextdialog/upnextdialog.js b/src/components/upnextdialog/upnextdialog.js index 1dbe71c632..5eb2a2ffcc 100644 --- a/src/components/upnextdialog/upnextdialog.js +++ b/src/components/upnextdialog/upnextdialog.js @@ -1,6 +1,8 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'layoutManager', 'focusManager', 'globalize', 'itemHelper', 'css!./upnextdialog', 'emby-button', 'flexStyles'], function (dom, playbackManager, connectionManager, events, mediaInfo, layoutManager, focusManager, globalize, itemHelper) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + var transitionEndEventName = dom.whichTransitionEvent(); function seriesImageUrl(item, options) { diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index df2855d69a..3fe24b5594 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -29,6 +29,8 @@ import 'emby-select'; /* eslint-disable indent */ + playbackManager = playbackManager.default || playbackManager; + function getPromise(apiClient, params) { const id = params.id; diff --git a/src/controllers/list.js b/src/controllers/list.js index 01ef35a26a..025a56ca9a 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -1,6 +1,8 @@ define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager', 'cardBuilder', 'loading', 'connectionManager', 'alphaNumericShortcuts', 'scroller', 'playbackManager', 'alphaPicker', 'emby-itemscontainer', 'emby-scroller'], function (globalize, listView, layoutManager, userSettings, focusManager, cardBuilder, loading, connectionManager, AlphaNumericShortcuts, scroller, playbackManager, AlphaPicker) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function getInitialLiveTvQuery(instance, params) { var query = { UserId: connectionManager.getApiClient(params.serverId).getCurrentUserId(), diff --git a/src/controllers/movies/moviesrecommended.js b/src/controllers/movies/moviesrecommended.js index 4ffe7888cf..a633d654cd 100644 --- a/src/controllers/movies/moviesrecommended.js +++ b/src/controllers/movies/moviesrecommended.js @@ -1,6 +1,8 @@ define(['events', 'layoutManager', 'inputManager', 'userSettings', 'libraryMenu', 'mainTabsManager', 'cardBuilder', 'dom', 'imageLoader', 'playbackManager', 'globalize', 'emby-scroller', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager, globalize) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function enableScrollX() { return !layoutManager.desktop; } diff --git a/src/plugins/chromecastPlayer/plugin.js b/src/plugins/chromecastPlayer/plugin.js index f4acc6d8b3..e39e30d8cf 100644 --- a/src/plugins/chromecastPlayer/plugin.js +++ b/src/plugins/chromecastPlayer/plugin.js @@ -1,6 +1,8 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', 'globalize', 'events', 'require', 'castSenderApiLoader'], function (appSettings, userSettings, playbackManager, connectionManager, globalize, events, require, castSenderApiLoader) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + // Based on https://github.com/googlecast/CastVideos-chrome/blob/master/CastVideos.js var currentResolve; var currentReject; diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index 89a18a96cc..fb1f745df3 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -1,6 +1,8 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'], function (playbackManager, events, serverNotifications, connectionManager) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function getActivePlayerId() { var info = playbackManager.getPlayerInfo(); return info ? info.id : null; diff --git a/src/scripts/libraryMenu.js b/src/scripts/libraryMenu.js index d2a68cd6e3..5c0ab467ff 100644 --- a/src/scripts/libraryMenu.js +++ b/src/scripts/libraryMenu.js @@ -1,6 +1,8 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', 'viewManager', 'libraryBrowser', 'appRouter', 'apphost', 'playbackManager', 'syncPlayManager', 'groupSelectionMenu', 'browser', 'globalize', 'scripts/imagehelper', 'paper-icon-button-light', 'material-icons', 'scrollStyles', 'flexStyles'], function (dom, layoutManager, inputManager, connectionManager, events, viewManager, libraryBrowser, appRouter, appHost, playbackManager, syncPlayManager, groupSelectionMenu, browser, globalize, imageHelper) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + function renderHeader() { var html = ''; html += '
'; diff --git a/src/scripts/serverNotifications.js b/src/scripts/serverNotifications.js index 331a75329c..e5fb0bcd61 100644 --- a/src/scripts/serverNotifications.js +++ b/src/scripts/serverNotifications.js @@ -1,6 +1,8 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'inputManager', 'focusManager', 'appRouter'], function (connectionManager, playbackManager, syncPlayManager, events, inputManager, focusManager, appRouter) { 'use strict'; + playbackManager = playbackManager.default || playbackManager; + var serverNotifications = {}; function notifyApp() { From 7ffb7ab0fc07ea8e80d381a971541f0b1c5b1e04 Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 31 Jul 2020 10:36:08 +0100 Subject: [PATCH 064/226] fix lint and bug --- src/components/playback/playbackmanager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 99a21dd3e2..dbab7e0f8f 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -1988,7 +1988,7 @@ class PlaybackManager { throw new Error('player cannot be null'); } - let playerTime = Math.floor(10000 * (player || self._currentPlayer).currentTime()); + let playerTime = Math.floor(10000 * (player).currentTime()); const streamInfo = getPlayerData(player).streamInfo; if (streamInfo) { From 91cd1a75d7970316e793bccb5daf470c1297d5eb Mon Sep 17 00:00:00 2001 From: Cameron Date: Sat, 1 Aug 2020 21:03:27 +0100 Subject: [PATCH 065/226] Apply Suggestions --- src/components/playback/playbackmanager.js | 81 ++++++---------------- src/libraries/screensavermanager.js | 2 + 2 files changed, 25 insertions(+), 58 deletions(-) diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index dbab7e0f8f..1c181c0025 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3147,8 +3147,7 @@ class PlaybackManager { } }; - self.playbackStartTime = function (player) { - player = player || this._currentPlayer; + self.playbackStartTime = function (player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player) && !player.isLocalPlayer) { return player.playbackStartTime(); } @@ -3169,8 +3168,7 @@ class PlaybackManager { return this._currentPlayer; } - currentTime(player) { - player = player || this._currentPlayer; + currentTime(player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player) && !player.isLocalPlayer) { return player.currentTime(); } @@ -3178,9 +3176,7 @@ class PlaybackManager { return this.getCurrentTicks(player); } - nextItem(player) { - player = player || this._currentPlayer; - + nextItem(player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.nextItem(); } @@ -3210,9 +3206,7 @@ class PlaybackManager { return false; } - isMuted(player) { - player = player || this._currentPlayer; - + isMuted(player = this._currentPlayer) { if (player) { return player.isMuted(); } @@ -3220,16 +3214,13 @@ class PlaybackManager { return false; } - setMute(mute, player) { - player = player || this._currentPlayer; - + setMute(mute, player = this._currentPlayer) { if (player) { player.setMute(mute); } } - toggleMute(mute, player) { - player = player || this._currentPlayer; + toggleMute(mute, player = this._currentPlayer) { if (player) { if (player.toggleMute) { player.toggleMute(); @@ -3253,8 +3244,7 @@ class PlaybackManager { return (appSettings.get('displaymirror') || '') !== '0'; } - nextChapter(player) { - player = player || this._currentPlayer; + nextChapter(player = this._currentPlayer) { const item = this.currentItem(player); const ticks = this.getCurrentTicks(player); @@ -3270,8 +3260,7 @@ class PlaybackManager { } } - previousChapter(player) { - player = player || this._currentPlayer; + previousChapter(player = this._currentPlayer) { const item = this.currentItem(player); let ticks = this.getCurrentTicks(player); @@ -3295,9 +3284,7 @@ class PlaybackManager { } } - fastForward(player) { - player = player || this._currentPlayer; - + fastForward(player = this._currentPlayer) { if (player.fastForward != null) { player.fastForward(userSettings.skipForwardLength()); return; @@ -3309,9 +3296,7 @@ class PlaybackManager { this.seekRelative(offsetTicks, player); } - rewind(player) { - player = player || this._currentPlayer; - + rewind(player = this._currentPlayer) { if (player.rewind != null) { player.rewind(userSettings.skipBackLength()); return; @@ -3323,9 +3308,7 @@ class PlaybackManager { this.seekRelative(offsetTicks, player); } - seekPercent(percent, player) { - player = player || this._currentPlayer; - + seekPercent(percent, player = this._currentPlayer) { let ticks = this.duration(player) || 0; percent /= 100; @@ -3333,9 +3316,7 @@ class PlaybackManager { this.seek(parseInt(ticks), player); } - seekMs(ms, player) { - player = player || this._currentPlayer; - + seekMs(ms, player = this._currentPlayer) { const ticks = ms * 10000; this.seek(ticks, player); } @@ -3384,9 +3365,8 @@ class PlaybackManager { return !textStream.IsExternalUrl ? apiClient.getUrl(textStream.DeliveryUrl) : textStream.DeliveryUrl; } - stop(player) { + stop(player ) { player = player || this._currentPlayer; - if (player) { if (enableLocalPlaylistManagement(player)) { this._playNextAfterEnded = false; @@ -3399,9 +3379,7 @@ class PlaybackManager { return Promise.resolve(); } - getBufferedRanges(player) { - player = player || this._currentPlayer; - + getBufferedRanges(player = this._currentPlayer) { if (player) { if (player.getBufferedRanges) { return player.getBufferedRanges(); @@ -3411,9 +3389,7 @@ class PlaybackManager { return []; } - playPause(player) { - player = player || this._currentPlayer; - + playPause(player = this._currentPlayer) { if (player) { if (player.playPause) { return player.playPause(); @@ -3427,25 +3403,19 @@ class PlaybackManager { } } - paused(player) { - player = player || this._currentPlayer; - + paused(player = this._currentPlayer) { if (player) { return player.paused(); } } - pause(player) { - player = player || this._currentPlayer; - + pause(player = this._currentPlayer) { if (player) { player.pause(); } } - unpause(player) { - player = player || this._currentPlayer; - + unpause(player = this._currentPlayer) { if (player) { player.unpause(); } @@ -3465,8 +3435,7 @@ class PlaybackManager { return null; } - instantMix(item, player) { - player = player || this._currentPlayer; + instantMix(item, player = this._currentPlayer) { if (player && player.instantMix) { return player.instantMix(item); } @@ -3486,8 +3455,7 @@ class PlaybackManager { }); } - shuffle(shuffleItem, player) { - player = player || this._currentPlayer; + shuffle(shuffleItem, player = this._currentPlayer) { if (player && player.shuffle) { return player.shuffle(shuffleItem); } @@ -3495,8 +3463,7 @@ class PlaybackManager { return this.play({ items: [shuffleItem], shuffle: true }); } - audioTracks(player) { - player = player || this._currentPlayer; + audioTracks(player = this._currentPlayer) { if (player.audioTracks) { const result = player.audioTracks(); if (result) { @@ -3512,8 +3479,7 @@ class PlaybackManager { }); } - subtitleTracks(player) { - player = player || this._currentPlayer; + subtitleTracks(player = this._currentPlayer) { if (player.subtitleTracks) { const result = player.subtitleTracks(); if (result) { @@ -3661,8 +3627,7 @@ class PlaybackManager { }); } - displayContent(options, player) { - player = player || this._currentPlayer; + displayContent(options, player = this._currentPlayer) { if (player && player.displayContent) { player.displayContent(options); } diff --git a/src/libraries/screensavermanager.js b/src/libraries/screensavermanager.js index b9d7082850..557b31e0f4 100644 --- a/src/libraries/screensavermanager.js +++ b/src/libraries/screensavermanager.js @@ -1,6 +1,8 @@ define(["events", "playbackManager", "pluginManager", "inputManager", "connectionManager", "userSettings"], function (events, playbackManager, pluginManager, inputManager, connectionManager, userSettings) { "use strict"; + playbackManager = playbackManager.default || playbackManager; + function getMinIdleTime() { // Returns the minimum amount of idle time required before the screen saver can be displayed //time units used Millisecond From 042cb4119bd22fbe8679592d110041597bd7a196 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 2 Aug 2020 09:22:03 +0100 Subject: [PATCH 066/226] lint --- src/components/imageeditor/imageeditor.js | 2 -- src/components/playback/playbackmanager.js | 2 +- src/controllers/livetvsettings.js | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/imageeditor/imageeditor.js b/src/components/imageeditor/imageeditor.js index 166ebb2245..46e2dae999 100644 --- a/src/components/imageeditor/imageeditor.js +++ b/src/components/imageeditor/imageeditor.js @@ -19,8 +19,6 @@ import 'css!./imageeditor'; const enableFocusTransform = !browser.slow && !browser.edge; - loading = loading.default || loading; - let currentItem; let hasChanges = false; diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 1c181c0025..ffbb88522c 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -3365,7 +3365,7 @@ class PlaybackManager { return !textStream.IsExternalUrl ? apiClient.getUrl(textStream.DeliveryUrl) : textStream.DeliveryUrl; } - stop(player ) { + stop(player) { player = player || this._currentPlayer; if (player) { if (enableLocalPlaylistManagement(player)) { diff --git a/src/controllers/livetvsettings.js b/src/controllers/livetvsettings.js index 8c296cdd3c..29ec4a10a5 100644 --- a/src/controllers/livetvsettings.js +++ b/src/controllers/livetvsettings.js @@ -3,8 +3,6 @@ import loading from 'loading'; import globalize from 'globalize'; import 'emby-button'; -loading = loading.default || loading; - function loadPage(page, config) { $('.liveTvSettingsForm', page).show(); $('.noLiveTvServices', page).hide(); From 9067047403eddf24a24b0f8b81111464359b6bc9 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 2 Aug 2020 09:27:03 +0100 Subject: [PATCH 067/226] Update src/components/playback/playbackmanager.js Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com> --- src/components/playback/playbackmanager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index ffbb88522c..437127be18 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -620,7 +620,7 @@ function supportsDirectPlay(apiClient, item, mediaSource) { } else if (mediaSource.Protocol === 'File') { return new Promise(function (resolve, reject) { // Determine if the file can be accessed directly - import('filesystem').then(({ default: filesystem }) => { + import('filesystem').then((filesystem) => { const method = isFolderRip ? 'directoryExists' : 'fileExists'; From 1fe25e14ddb6131be62b1ed4dbb12f3a821a5702 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sun, 2 Aug 2020 17:28:25 +0900 Subject: [PATCH 068/226] move themes and plugins into config file --- package.json | 2 + src/components/appRouter.js | 17 +- src/components/apphost.js | 9 +- .../displaySettings/displaySettings.js | 114 ++--------- .../displaySettings.template.html | 20 -- src/components/skinManager.js | 184 ------------------ src/config.template.json | 36 +++- src/index.html | 8 +- src/manifest.json | 2 +- ...romecastHelpers.js => chromecastHelper.js} | 0 src/plugins/chromecastPlayer/plugin.js | 2 +- src/scripts/autoThemes.js | 8 + src/scripts/inputManager.js | 1 + src/scripts/settings/appSettings.js | 41 ---- src/scripts/settings/webSettings.js | 20 +- src/scripts/site.js | 57 +++--- src/scripts/themeLoader.js | 29 --- src/scripts/themeManager.js | 66 +++++++ 18 files changed, 180 insertions(+), 436 deletions(-) delete mode 100644 src/components/skinManager.js rename src/plugins/chromecastPlayer/{chromecastHelpers.js => chromecastHelper.js} (100%) create mode 100644 src/scripts/autoThemes.js delete mode 100644 src/scripts/themeLoader.js create mode 100644 src/scripts/themeManager.js diff --git a/package.json b/package.json index 7943c22e54..8e725e1052 100644 --- a/package.json +++ b/package.json @@ -266,6 +266,8 @@ "src/scripts/globalize.js", "src/scripts/imagehelper.js", "src/scripts/inputManager.js", + "src/scripts/autoThemes.js", + "src/scripts/themeManager.js", "src/scripts/keyboardNavigation.js", "src/scripts/libraryBrowser.js", "src/scripts/multiDownload.js", diff --git a/src/components/appRouter.js b/src/components/appRouter.js index 8c9b953d39..5dbcf765be 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -36,7 +36,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro switch (result.State) { case 'SignedIn': loading.hide(); - skinManager.loadUserSkin(); + Emby.Page.goHome(); break; case 'ServerSignIn': result.ApiClient.getPublicUsers().then(function (users) { @@ -149,7 +149,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro if (typeof route.path === 'string') { loadContentUrl(ctx, next, route, currentRequest); } else { - // ? TODO next(); } }; @@ -287,12 +286,9 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro connectionManager.connect({ enableAutoLogin: appSettings.enableAutoLogin() - }).then(function (result) { firstConnectionResult = result; - options = options || {}; - page({ click: options.click !== false, hashbang: options.hashbang !== false @@ -344,7 +340,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro if (route.isDefaultRoute) { console.debug('appRouter - loading skin home page'); - loadUserSkinWithOptions(ctx); + Emby.Page.goHome(); return; } else if (route.roles) { validateRoles(apiClient, route.roles).then(function () { @@ -358,15 +354,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro callback(); } - function loadUserSkinWithOptions(ctx) { - require(['queryString'], function (queryString) { - var params = queryString.parse(ctx.querystring); - skinManager.loadUserSkin({ - start: params.start - }); - }); - } - function validateRoles(apiClient, roles) { return Promise.all(roles.split(',').map(function (role) { return validateRole(apiClient, role); diff --git a/src/components/apphost.js b/src/components/apphost.js index 8a5581d817..931fcae1db 100644 --- a/src/components/apphost.js +++ b/src/components/apphost.js @@ -277,7 +277,7 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g features.push('targetblank'); features.push('screensaver'); - webSettings.enableMultiServer().then(enabled => { + webSettings.getMultiServer().then(enabled => { if (enabled) features.push('multiserver'); }); @@ -407,13 +407,6 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g getPushTokenInfo: function () { return {}; }, - setThemeColor: function (color) { - var metaThemeColor = document.querySelector('meta[name=theme-color]'); - - if (metaThemeColor) { - metaThemeColor.setAttribute('content', color); - } - }, setUserScalable: function (scalable) { if (!browser.tv) { var att = scalable ? 'width=device-width, initial-scale=1, minimum-scale=1, user-scalable=yes' : 'width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no'; diff --git a/src/components/displaySettings/displaySettings.js b/src/components/displaySettings/displaySettings.js index ba78ab99e1..d9c2fc0b49 100644 --- a/src/components/displaySettings/displaySettings.js +++ b/src/components/displaySettings/displaySettings.js @@ -16,17 +16,22 @@ import 'emby-button'; /* eslint-disable indent */ - function fillThemes(select, isDashboard) { - select.innerHTML = skinManager.getThemes().map(t => { - let value = t.id; - if (t.isDefault && !isDashboard) { - value = ''; - } else if (t.isDefaultServerDashboard && isDashboard) { - value = ''; - } + function fillThemes(context, userSettings) { + const select = context.querySelector('#selectTheme'); - return ``; - }).join(''); + skinManager.getThemes().then(themes => { + select.innerHTML = themes.map(t => { + return ``; + }).join(''); + + // get default theme + var defaultTheme = themes.find(theme => { + return theme.default; + }); + + // set the current theme + select.value = userSettings.theme() || defaultTheme.id; + }); } function loadScreensavers(context, userSettings) { @@ -46,6 +51,7 @@ import 'emby-button'; selectScreensaver.innerHTML = options.map(o => { return ``; }).join(''); + selectScreensaver.value = userSettings.screensaver(); if (!selectScreensaver.value) { @@ -54,57 +60,6 @@ import 'emby-button'; } } - function loadSoundEffects(context, userSettings) { - const selectSoundEffects = context.querySelector('.selectSoundEffects'); - const options = pluginManager.ofType('soundeffects').map(plugin => { - return { - name: plugin.name, - value: plugin.id - }; - }); - - options.unshift({ - name: globalize.translate('None'), - value: 'none' - }); - - selectSoundEffects.innerHTML = options.map(o => { - return ``; - }).join(''); - selectSoundEffects.value = userSettings.soundEffects(); - - if (!selectSoundEffects.value) { - // TODO: set the default instead of none - selectSoundEffects.value = 'none'; - } - } - - function loadSkins(context, userSettings) { - const selectSkin = context.querySelector('.selectSkin'); - - const options = pluginManager.ofType('skin').map(plugin => { - return { - name: plugin.name, - value: plugin.id - }; - }); - - selectSkin.innerHTML = options.map(o => { - return ``; - }).join(''); - selectSkin.value = userSettings.skin(); - - if (!selectSkin.value && options.length) { - selectSkin.value = options[0].value; - } - - if (options.length > 1 && appHost.supports('skins')) { - context.querySelector('.selectSkinContainer').classList.remove('hide'); - } else { - context.querySelector('.selectSkinContainer').classList.add('hide'); - } - } - function showOrHideMissingEpisodesField(context) { if (browser.tizen || browser.web0s) { context.querySelector('.fldDisplayMissingEpisodes').classList.add('hide'); @@ -115,12 +70,6 @@ import 'emby-button'; } function loadForm(context, user, userSettings) { - if (user.Policy.IsAdministrator) { - context.querySelector('.selectDashboardThemeContainer').classList.remove('hide'); - } else { - context.querySelector('.selectDashboardThemeContainer').classList.add('hide'); - } - if (appHost.supports('displaylanguage')) { context.querySelector('.languageSection').classList.remove('hide'); } else { @@ -139,18 +88,6 @@ import 'emby-button'; context.querySelector('.learnHowToContributeContainer').classList.add('hide'); } - if (appHost.supports('runatstartup')) { - context.querySelector('.fldAutorun').classList.remove('hide'); - } else { - context.querySelector('.fldAutorun').classList.add('hide'); - } - - if (appHost.supports('soundeffects')) { - context.querySelector('.fldSoundEffects').classList.remove('hide'); - } else { - context.querySelector('.fldSoundEffects').classList.add('hide'); - } - if (appHost.supports('screensaver')) { context.querySelector('.selectScreensaverContainer').classList.remove('hide'); } else { @@ -173,16 +110,8 @@ import 'emby-button'; context.querySelector('.fldThemeVideo').classList.add('hide'); } - context.querySelector('.chkRunAtStartup').checked = appSettings.runAtStartup(); - - const selectTheme = context.querySelector('#selectTheme'); - const selectDashboardTheme = context.querySelector('#selectDashboardTheme'); - - fillThemes(selectTheme); - fillThemes(selectDashboardTheme, true); + fillThemes(context, userSettings); loadScreensavers(context, userSettings); - loadSoundEffects(context, userSettings); - loadSkins(context, userSettings); context.querySelector('.chkDisplayMissingEpisodes').checked = user.Configuration.DisplayMissingEpisodes || false; @@ -198,9 +127,6 @@ import 'emby-button'; context.querySelector('#txtLibraryPageSize').value = userSettings.libraryPageSize(); - selectDashboardTheme.value = userSettings.dashboardTheme() || ''; - selectTheme.value = userSettings.theme() || ''; - context.querySelector('.selectLayout').value = layoutManager.getSavedLayout() || ''; showOrHideMissingEpisodesField(context); @@ -209,8 +135,6 @@ import 'emby-button'; } function saveUser(context, user, userSettingsInstance, apiClient) { - appSettings.runAtStartup(context.querySelector('.chkRunAtStartup').checked); - user.Configuration.DisplayMissingEpisodes = context.querySelector('.chkDisplayMissingEpisodes').checked; if (appHost.supports('displaylanguage')) { @@ -221,15 +145,11 @@ import 'emby-button'; userSettingsInstance.enableThemeSongs(context.querySelector('#chkThemeSong').checked); userSettingsInstance.enableThemeVideos(context.querySelector('#chkThemeVideo').checked); - userSettingsInstance.dashboardTheme(context.querySelector('#selectDashboardTheme').value); userSettingsInstance.theme(context.querySelector('#selectTheme').value); - userSettingsInstance.soundEffects(context.querySelector('.selectSoundEffects').value); userSettingsInstance.screensaver(context.querySelector('.selectScreensaver').value); userSettingsInstance.libraryPageSize(context.querySelector('#txtLibraryPageSize').value); - userSettingsInstance.skin(context.querySelector('.selectSkin').value); - userSettingsInstance.enableFastFadein(context.querySelector('#chkFadein').checked); userSettingsInstance.enableBlurhash(context.querySelector('#chkBlurhash').checked); userSettingsInstance.enableBackdrops(context.querySelector('#chkBackdrops').checked); diff --git a/src/components/displaySettings/displaySettings.template.html b/src/components/displaySettings/displaySettings.template.html index 7258edf208..fdaf8d70f1 100644 --- a/src/components/displaySettings/displaySettings.template.html +++ b/src/components/displaySettings/displaySettings.template.html @@ -1,5 +1,4 @@
-

${Display}

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