diff --git a/package.json b/package.json index 5d9f5bc951..d1c45ef2b5 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "repository": "https://github.com/jellyfin/jellyfin-web", "license": "GPL-2.0-or-later", "devDependencies": { - "@babel/core": "^7.11.0", + "@babel/core": "^7.11.1", "@babel/eslint-parser": "^7.11.0", "@babel/eslint-plugin": "^7.11.0", "@babel/plugin-proposal-class-properties": "^7.10.1", @@ -38,7 +38,7 @@ "gulp-postcss": "^8.0.0", "gulp-sass": "^4.0.2", "gulp-sourcemaps": "^2.6.5", - "gulp-terser": "^1.3.0", + "gulp-terser": "^1.3.2", "html-webpack-plugin": "^4.3.0", "lazypipe": "^1.0.2", "node-sass": "^4.13.1", @@ -80,7 +80,7 @@ "sortablejs": "^1.10.2", "swiper": "^5.4.5", "webcomponents.js": "^0.7.24", - "whatwg-fetch": "^3.2.0" + "whatwg-fetch": "^3.3.1" }, "babel": { "presets": [ @@ -110,6 +110,7 @@ "src/components/favoriteitems.js", "src/components/fetchhelper.js", "src/components/filterdialog/filterdialog.js", + "src/components/focusManager.js", "src/components/groupedcards.js", "src/components/homeScreenSettings/homeScreenSettings.js", "src/components/homesections/homesections.js", @@ -152,6 +153,8 @@ "src/components/playlisteditor/playlisteditor.js", "src/components/playmenu.js", "src/components/prompt/prompt.js", + "src/components/recordingcreator/seriesrecordingeditor.js", + "src/components/recordingcreator/recordinghelper.js", "src/components/refreshdialog/refreshdialog.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", @@ -167,9 +170,12 @@ "src/components/syncPlay/syncPlayManager.js", "src/components/syncPlay/timeSyncManager.js", "src/components/tabbedview/tabbedview.js", + "src/components/tvproviders/schedulesdirect.js", + "src/components/tvproviders/xmltv.js", "src/components/toast/toast.js", "src/components/upnextdialog/upnextdialog.js", "src/components/viewContainer.js", + "src/components/castSenderApi.js", "src/controllers/session/addServer/index.js", "src/controllers/session/forgotPassword/index.js", "src/controllers/session/redeemPassword/index.js", @@ -214,6 +220,11 @@ "src/controllers/edititemmetadata.js", "src/controllers/favorites.js", "src/controllers/hometab.js", + "src/controllers/movies/moviecollections.js", + "src/controllers/movies/moviegenres.js", + "src/controllers/movies/movies.js", + "src/controllers/movies/moviesrecommended.js", + "src/controllers/movies/movietrailers.js", "src/controllers/playback/nowplaying.js", "src/controllers/playback/videoosd.js", "src/controllers/itemDetails/index.js", @@ -224,6 +235,10 @@ "src/controllers/livetvstatus.js", "src/controllers/livetvguideprovider.js", "src/controllers/livetvsettings.js", + "src/controllers/livetv/livetvrecordings.js", + "src/controllers/livetv/livetvschedule.js", + "src/controllers/livetv/livetvseriestimers.js", + "src/controllers/livetv/livetvchannels.js", "src/controllers/shows/episodes.js", "src/controllers/shows/tvgenres.js", "src/controllers/shows/tvlatest.js", @@ -321,6 +336,7 @@ "Firefox ESR" ], "scripts": { + "start": "yarn serve", "serve": "gulp serve --development", "prepare": "gulp --production", "build:development": "gulp --development", diff --git a/src/components/castSenderApi.js b/src/components/castSenderApi.js index b541c1f87a..c7fd5df217 100644 --- a/src/components/castSenderApi.js +++ b/src/components/castSenderApi.js @@ -1,34 +1,28 @@ -define([], function() { - 'use strict'; - - if (window.appMode === 'cordova' || window.appMode === 'android') { - return { - load: function () { - window.chrome = window.chrome || {}; +class CastSenderApi { + load() { + if (window.appMode === 'cordova' || window.appMode === 'android') { + window.chrome = window.chrome || {}; + return Promise.resolve(); + } else { + let ccLoaded = false; + if (ccLoaded) { return Promise.resolve(); } - }; - } else { - var ccLoaded = false; - return { - load: function () { - if (ccLoaded) { - return Promise.resolve(); - } - return new Promise(function (resolve, reject) { - var fileref = document.createElement('script'); - fileref.setAttribute('type', 'text/javascript'); + return new Promise(function (resolve) { + const fileref = document.createElement('script'); + fileref.setAttribute('type', 'text/javascript'); - fileref.onload = function () { - ccLoaded = true; - resolve(); - }; + fileref.onload = function () { + ccLoaded = true; + resolve(); + }; - fileref.setAttribute('src', 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js'); - document.querySelector('head').appendChild(fileref); - }); - } - }; + fileref.setAttribute('src', 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js'); + document.querySelector('head').appendChild(fileref); + }); + } } -}); +} + +export default CastSenderApi; diff --git a/src/components/filtermenu/filtermenu.js b/src/components/filtermenu/filtermenu.js index 20399fb52d..b02b5fb9f8 100644 --- a/src/components/filtermenu/filtermenu.js +++ b/src/components/filtermenu/filtermenu.js @@ -1,5 +1,6 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', 'inputManager', 'layoutManager', 'connectionManager', 'appRouter', 'globalize', 'userSettings', 'emby-checkbox', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button', 'flexStyles'], function (require, dom, focusManager, dialogHelper, loading, appHost, inputManager, layoutManager, connectionManager, appRouter, globalize, userSettings) { 'use strict'; + focusManager = focusManager.default || focusManager; function onSubmit(e) { e.preventDefault(); diff --git a/src/components/focusManager.js b/src/components/focusManager.js index 9c495bf952..a9ec377cce 100644 --- a/src/components/focusManager.js +++ b/src/components/focusManager.js @@ -1,5 +1,7 @@ -define(['dom', 'scrollManager'], function (dom, scrollManager) { - 'use strict'; +/* eslint-disable indent */ + +import dom from 'dom'; +import scrollManager from 'scrollManager'; var scopes = []; function pushScope(elem) { @@ -472,37 +474,38 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) { } } - return { - autoFocus: autoFocus, - focus: focus, - focusableParent: focusableParent, - getFocusableElements: getFocusableElements, - moveLeft: function (sourceElement, options) { - var container = options ? options.container : null; - var focusableElements = options ? options.focusableElements : null; - nav(sourceElement, 0, container, focusableElements); - }, - moveRight: function (sourceElement, options) { - var container = options ? options.container : null; - var focusableElements = options ? options.focusableElements : null; - nav(sourceElement, 1, container, focusableElements); - }, - moveUp: function (sourceElement, options) { - var container = options ? options.container : null; - var focusableElements = options ? options.focusableElements : null; - nav(sourceElement, 2, container, focusableElements); - }, - moveDown: function (sourceElement, options) { - var container = options ? options.container : null; - var focusableElements = options ? options.focusableElements : null; - nav(sourceElement, 3, container, focusableElements); - }, - sendText: sendText, - isCurrentlyFocusable: isCurrentlyFocusable, - pushScope: pushScope, - popScope: popScope, - focusFirst: focusFirst, - focusLast: focusLast, - moveFocus: moveFocus - }; -}); +/* eslint-enable indent */ + +export default { + autoFocus: autoFocus, + focus: focus, + focusableParent: focusableParent, + getFocusableElements: getFocusableElements, + moveLeft: function (sourceElement, options) { + var container = options ? options.container : null; + var focusableElements = options ? options.focusableElements : null; + nav(sourceElement, 0, container, focusableElements); + }, + moveRight: function (sourceElement, options) { + var container = options ? options.container : null; + var focusableElements = options ? options.focusableElements : null; + nav(sourceElement, 1, container, focusableElements); + }, + moveUp: function (sourceElement, options) { + var container = options ? options.container : null; + var focusableElements = options ? options.focusableElements : null; + nav(sourceElement, 2, container, focusableElements); + }, + moveDown: function (sourceElement, options) { + var container = options ? options.container : null; + var focusableElements = options ? options.focusableElements : null; + nav(sourceElement, 3, container, focusableElements); + }, + sendText: sendText, + isCurrentlyFocusable: isCurrentlyFocusable, + pushScope: pushScope, + popScope: popScope, + focusFirst: focusFirst, + focusLast: focusLast, + moveFocus: moveFocus +}; diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index 61caa9188f..71d63f82c0 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -4,6 +4,7 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', playbackManager = playbackManager.default || playbackManager; browser = browser.default || browser; loading = loading.default || loading; + focusManager = focusManager.default || focusManager; function showViewSettings(instance) { require(['guide-settings-dialog'], function (guideSettingsDialog) { diff --git a/src/components/recordingcreator/recordingbutton.js b/src/components/recordingcreator/recordingbutton.js index 3ad4ffa594..1207208e90 100644 --- a/src/components/recordingcreator/recordingbutton.js +++ b/src/components/recordingcreator/recordingbutton.js @@ -1,6 +1,8 @@ define(['globalize', 'connectionManager', 'require', 'loading', 'apphost', 'dom', 'recordingHelper', 'events', 'paper-icon-button-light', 'emby-button', 'css!./recordingfields'], function (globalize, connectionManager, require, loading, appHost, dom, recordingHelper, events) { 'use strict'; + recordingHelper = recordingHelper.default || recordingHelper; + function onRecordingButtonClick(e) { var item = this.item; diff --git a/src/components/recordingcreator/recordingeditor.js b/src/components/recordingcreator/recordingeditor.js index 2086129a9e..2e54b3601c 100644 --- a/src/components/recordingcreator/recordingeditor.js +++ b/src/components/recordingcreator/recordingeditor.js @@ -12,6 +12,8 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c function deleteTimer(apiClient, timerId) { return new Promise(function (resolve, reject) { require(['recordingHelper'], function (recordingHelper) { + recordingHelper = recordingHelper.default || recordingHelper; + recordingHelper.cancelTimerWithConfirmation(timerId, apiClient.serverId()).then(resolve, reject); }); }); diff --git a/src/components/recordingcreator/recordingfields.js b/src/components/recordingcreator/recordingfields.js index e3739f1cfe..741570581e 100644 --- a/src/components/recordingcreator/recordingfields.js +++ b/src/components/recordingcreator/recordingfields.js @@ -1,6 +1,7 @@ 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'; + recordingHelper = recordingHelper.default || recordingHelper; loading = loading.default || loading; function loadData(parent, program, apiClient) { diff --git a/src/components/recordingcreator/recordinghelper.js b/src/components/recordingcreator/recordinghelper.js index 5d72394282..13359de2bc 100644 --- a/src/components/recordingcreator/recordinghelper.js +++ b/src/components/recordingcreator/recordinghelper.js @@ -1,194 +1,195 @@ -define(['globalize', 'loading', 'connectionManager'], function (globalize, loading, connectionManager) { - 'use strict'; +import globalize from 'globalize'; +import loading from 'loading'; +import connectionManager from 'connectionManager'; - loading = loading.default || loading; +/*eslint prefer-const: "error"*/ - function changeRecordingToSeries(apiClient, timerId, programId, confirmTimerCancellation) { - loading.show(); +function changeRecordingToSeries(apiClient, timerId, programId, confirmTimerCancellation) { + loading.show(); - return apiClient.getItem(apiClient.getCurrentUserId(), programId).then(function (item) { - if (item.IsSeries) { - // create series - return apiClient.getNewLiveTvTimerDefaults({ programId: programId }).then(function (timerDefaults) { - return apiClient.createLiveTvSeriesTimer(timerDefaults).then(function () { - loading.hide(); - sendToast(globalize.translate('SeriesRecordingScheduled')); + return apiClient.getItem(apiClient.getCurrentUserId(), programId).then(function (item) { + if (item.IsSeries) { + // create series + return apiClient.getNewLiveTvTimerDefaults({ programId: programId }).then(function (timerDefaults) { + return apiClient.createLiveTvSeriesTimer(timerDefaults).then(function () { + loading.hide(); + sendToast(globalize.translate('SeriesRecordingScheduled')); + }); + }); + } else { + // cancel + if (confirmTimerCancellation) { + return cancelTimerWithConfirmation(timerId, apiClient.serverId()); + } + + return cancelTimer(apiClient.serverId(), timerId, true); + } + }); +} + +function cancelTimerWithConfirmation(timerId, serverId) { + return new Promise(function (resolve, reject) { + import('confirm').then(({ default: confirm }) => { + confirm.default({ + + text: globalize.translate('MessageConfirmRecordingCancellation'), + primary: 'delete', + confirmText: globalize.translate('HeaderCancelRecording'), + cancelText: globalize.translate('HeaderKeepRecording') + + }).then(function () { + loading.show(); + + const apiClient = connectionManager.getApiClient(serverId); + cancelTimer(apiClient, timerId, true).then(resolve, reject); + }, reject); + }); + }); +} + +function cancelSeriesTimerWithConfirmation(timerId, serverId) { + return new Promise(function (resolve, reject) { + import('confirm').then(({ default: confirm }) => { + confirm.default({ + + text: globalize.translate('MessageConfirmRecordingCancellation'), + primary: 'delete', + confirmText: globalize.translate('HeaderCancelSeries'), + cancelText: globalize.translate('HeaderKeepSeries') + + }).then(function () { + loading.show(); + + const apiClient = connectionManager.getApiClient(serverId); + apiClient.cancelLiveTvSeriesTimer(timerId).then(function () { + import('toast').then(({default: toast}) => { + toast(globalize.translate('SeriesCancelled')); }); + + loading.hide(); + resolve(); + }, reject); + }, reject); + }); + }); +} + +function cancelTimer(apiClient, timerId, hideLoading) { + loading.show(); + return apiClient.cancelLiveTvTimer(timerId).then(function () { + if (hideLoading !== false) { + loading.hide(); + sendToast(globalize.translate('RecordingCancelled')); + } + }); +} + +function createRecording(apiClient, programId, isSeries) { + loading.show(); + return apiClient.getNewLiveTvTimerDefaults({ programId: programId }).then(function (item) { + const promise = isSeries ? + apiClient.createLiveTvSeriesTimer(item) : + apiClient.createLiveTvTimer(item); + + return promise.then(function () { + loading.hide(); + sendToast(globalize.translate('RecordingScheduled')); + }); + }); +} + +function sendToast(msg) { + import('toast').then(({ default: toast }) => { + toast(msg); + }); +} + +function showMultiCancellationPrompt(serverId, programId, timerId, timerStatus, seriesTimerId) { + return new Promise(function (resolve, reject) { + import('dialog').then(({ default: dialog }) => { + const items = []; + + items.push({ + name: globalize.translate('HeaderKeepRecording'), + id: 'cancel', + type: 'submit' + }); + + if (timerStatus === 'InProgress') { + items.push({ + name: globalize.translate('HeaderStopRecording'), + id: 'canceltimer', + type: 'cancel' }); } else { - // cancel - if (confirmTimerCancellation) { - return cancelTimerWithConfirmation(timerId, apiClient.serverId()); - } - - return cancelTimer(apiClient.serverId(), timerId, true); + items.push({ + name: globalize.translate('HeaderCancelRecording'), + id: 'canceltimer', + type: 'cancel' + }); } - }); - } - function cancelTimerWithConfirmation(timerId, serverId) { - return new Promise(function (resolve, reject) { - require(['confirm'], function (confirm) { - confirm.default({ - - text: globalize.translate('MessageConfirmRecordingCancellation'), - primary: 'delete', - confirmText: globalize.translate('HeaderCancelRecording'), - cancelText: globalize.translate('HeaderKeepRecording') - - }).then(function () { - loading.show(); - - var apiClient = connectionManager.getApiClient(serverId); - cancelTimer(apiClient, timerId, true).then(resolve, reject); - }, reject); + items.push({ + name: globalize.translate('HeaderCancelSeries'), + id: 'cancelseriestimer', + type: 'cancel' }); - }); - } - function cancelSeriesTimerWithConfirmation(timerId, serverId) { - return new Promise(function (resolve, reject) { - require(['confirm'], function (confirm) { - confirm.default({ + dialog({ - text: globalize.translate('MessageConfirmRecordingCancellation'), - primary: 'delete', - confirmText: globalize.translate('HeaderCancelSeries'), - cancelText: globalize.translate('HeaderKeepSeries') + text: globalize.translate('MessageConfirmRecordingCancellation'), + buttons: items - }).then(function () { + }).then(function (result) { + const apiClient = connectionManager.getApiClient(serverId); + + if (result === 'canceltimer') { loading.show(); - var apiClient = connectionManager.getApiClient(serverId); - apiClient.cancelLiveTvSeriesTimer(timerId).then(function () { - require(['toast'], function (toast) { + cancelTimer(apiClient, timerId, true).then(resolve, reject); + } else if (result === 'cancelseriestimer') { + loading.show(); + + apiClient.cancelLiveTvSeriesTimer(seriesTimerId).then(function () { + import('toast').then(({ default: toast }) => { toast(globalize.translate('SeriesCancelled')); }); loading.hide(); resolve(); }, reject); - }, reject); - }); - }); - } - - function cancelTimer(apiClient, timerId, hideLoading) { - loading.show(); - return apiClient.cancelLiveTvTimer(timerId).then(function () { - if (hideLoading !== false) { - loading.hide(); - sendToast(globalize.translate('RecordingCancelled')); - } - }); - } - - function createRecording(apiClient, programId, isSeries) { - loading.show(); - return apiClient.getNewLiveTvTimerDefaults({ programId: programId }).then(function (item) { - var promise = isSeries ? - apiClient.createLiveTvSeriesTimer(item) : - apiClient.createLiveTvTimer(item); - - return promise.then(function () { - loading.hide(); - sendToast(globalize.translate('RecordingScheduled')); - }); - }); - } - - function sendToast(msg) { - require(['toast'], function (toast) { - toast(msg); - }); - } - - function showMultiCancellationPrompt(serverId, programId, timerId, timerStatus, seriesTimerId) { - return new Promise(function (resolve, reject) { - require(['dialog'], function (dialog) { - var items = []; - - items.push({ - name: globalize.translate('HeaderKeepRecording'), - id: 'cancel', - type: 'submit' - }); - - if (timerStatus === 'InProgress') { - items.push({ - name: globalize.translate('HeaderStopRecording'), - id: 'canceltimer', - type: 'cancel' - }); } else { - items.push({ - name: globalize.translate('HeaderCancelRecording'), - id: 'canceltimer', - type: 'cancel' - }); + resolve(); } - - items.push({ - name: globalize.translate('HeaderCancelSeries'), - id: 'cancelseriestimer', - type: 'cancel' - }); - - dialog({ - - text: globalize.translate('MessageConfirmRecordingCancellation'), - buttons: items - - }).then(function (result) { - var apiClient = connectionManager.getApiClient(serverId); - - if (result === 'canceltimer') { - loading.show(); - - cancelTimer(apiClient, timerId, true).then(resolve, reject); - } else if (result === 'cancelseriestimer') { - loading.show(); - - apiClient.cancelLiveTvSeriesTimer(seriesTimerId).then(function () { - require(['toast'], function (toast) { - toast(globalize.translate('SeriesCancelled')); - }); - - loading.hide(); - resolve(); - }, reject); - } else { - resolve(); - } - }, reject); - }); + }, reject); }); - } + }); +} - function toggleRecording(serverId, programId, timerId, timerStatus, seriesTimerId) { - var apiClient = connectionManager.getApiClient(serverId); - var hasTimer = timerId && timerStatus !== 'Cancelled'; - if (seriesTimerId && hasTimer) { - // cancel - return showMultiCancellationPrompt(serverId, programId, timerId, timerStatus, seriesTimerId); - } else if (hasTimer && programId) { - // change to series recording, if possible - // otherwise cancel individual recording - return changeRecordingToSeries(apiClient, timerId, programId, true); - } else if (programId) { - // schedule recording - return createRecording(apiClient, programId); - } else { - return Promise.reject(); - } +function toggleRecording(serverId, programId, timerId, timerStatus, seriesTimerId) { + const apiClient = connectionManager.getApiClient(serverId); + const hasTimer = timerId && timerStatus !== 'Cancelled'; + if (seriesTimerId && hasTimer) { + // cancel + return showMultiCancellationPrompt(serverId, programId, timerId, timerStatus, seriesTimerId); + } else if (hasTimer && programId) { + // change to series recording, if possible + // otherwise cancel individual recording + return changeRecordingToSeries(apiClient, timerId, programId, true); + } else if (programId) { + // schedule recording + return createRecording(apiClient, programId); + } else { + return Promise.reject(); } +} + +export default { + cancelTimer: cancelTimer, + createRecording: createRecording, + changeRecordingToSeries: changeRecordingToSeries, + toggleRecording: toggleRecording, + cancelTimerWithConfirmation: cancelTimerWithConfirmation, + cancelSeriesTimerWithConfirmation: cancelSeriesTimerWithConfirmation +}; - return { - cancelTimer: cancelTimer, - createRecording: createRecording, - changeRecordingToSeries: changeRecordingToSeries, - toggleRecording: toggleRecording, - cancelTimerWithConfirmation: cancelTimerWithConfirmation, - cancelSeriesTimerWithConfirmation: cancelSeriesTimerWithConfirmation - }; -}); diff --git a/src/components/recordingcreator/seriesrecordingeditor.js b/src/components/recordingcreator/seriesrecordingeditor.js index b115e273e6..48fbbcf22c 100644 --- a/src/components/recordingcreator/seriesrecordingeditor.js +++ b/src/components/recordingcreator/seriesrecordingeditor.js @@ -1,143 +1,200 @@ -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'; +import dialogHelper from 'dialogHelper'; +import globalize from 'globalize'; +import layoutManager from 'layoutManager'; +import connectionManager from 'connectionManager'; +import loading from 'loading'; +import scrollHelper from 'scrollHelper'; +import datetime from 'datetime'; +import 'scrollStyles'; +import 'emby-button'; +import 'emby-checkbox'; +import 'emby-input'; +import 'emby-select'; +import 'paper-icon-button-light'; +import 'css!./../formdialog'; +import 'css!./recordingcreator'; +import 'material-icons'; +import 'flexStyles'; - loading = loading.default || loading; +/*eslint prefer-const: "error"*/ - var currentDialog; - var recordingUpdated = false; - var recordingDeleted = false; - var currentItemId; - var currentServerId; +let currentDialog; +let recordingUpdated = false; +let recordingDeleted = false; +let currentItemId; +let currentServerId; - function deleteTimer(apiClient, timerId) { - return new Promise(function (resolve, reject) { - require(['recordingHelper'], function (recordingHelper) { - recordingHelper.cancelSeriesTimerWithConfirmation(timerId, apiClient.serverId()).then(resolve, reject); - }); +function deleteTimer(apiClient, timerId) { + return new Promise(function (resolve, reject) { + import('recordingHelper').then(({ default: recordingHelper }) => { + recordingHelper.cancelSeriesTimerWithConfirmation(timerId, apiClient.serverId()).then(resolve, reject); }); + }); +} + +function renderTimer(context, item) { + context.querySelector('#txtPrePaddingMinutes').value = item.PrePaddingSeconds / 60; + context.querySelector('#txtPostPaddingMinutes').value = item.PostPaddingSeconds / 60; + + context.querySelector('.selectChannels').value = item.RecordAnyChannel ? 'all' : 'one'; + context.querySelector('.selectAirTime').value = item.RecordAnyTime ? 'any' : 'original'; + + context.querySelector('.selectShowType').value = item.RecordNewOnly ? 'new' : 'all'; + context.querySelector('.chkSkipEpisodesInLibrary').checked = item.SkipEpisodesInLibrary; + context.querySelector('.selectKeepUpTo').value = item.KeepUpTo || 0; + + if (item.ChannelName || item.ChannelNumber) { + context.querySelector('.optionChannelOnly').innerHTML = globalize.translate('ChannelNameOnly', item.ChannelName || item.ChannelNumber); + } else { + context.querySelector('.optionChannelOnly').innerHTML = globalize.translate('OneChannel'); } - function renderTimer(context, item, apiClient) { - context.querySelector('#txtPrePaddingMinutes').value = item.PrePaddingSeconds / 60; - context.querySelector('#txtPostPaddingMinutes').value = item.PostPaddingSeconds / 60; + context.querySelector('.optionAroundTime').innerHTML = globalize.translate('AroundTime', datetime.getDisplayTime(datetime.parseISO8601Date(item.StartDate))); - context.querySelector('.selectChannels').value = item.RecordAnyChannel ? 'all' : 'one'; - context.querySelector('.selectAirTime').value = item.RecordAnyTime ? 'any' : 'original'; + loading.hide(); +} - context.querySelector('.selectShowType').value = item.RecordNewOnly ? 'new' : 'all'; - context.querySelector('.chkSkipEpisodesInLibrary').checked = item.SkipEpisodesInLibrary; - context.querySelector('.selectKeepUpTo').value = item.KeepUpTo || 0; +function closeDialog(isDeleted) { + recordingUpdated = true; + recordingDeleted = isDeleted; - if (item.ChannelName || item.ChannelNumber) { - context.querySelector('.optionChannelOnly').innerHTML = globalize.translate('ChannelNameOnly', item.ChannelName || item.ChannelNumber); - } else { - context.querySelector('.optionChannelOnly').innerHTML = globalize.translate('OneChannel'); - } + dialogHelper.close(currentDialog); +} - context.querySelector('.optionAroundTime').innerHTML = globalize.translate('AroundTime', datetime.getDisplayTime(datetime.parseISO8601Date(item.StartDate))); +function onSubmit(e) { + const form = this; + const apiClient = connectionManager.getApiClient(currentServerId); + + apiClient.getLiveTvSeriesTimer(currentItemId).then(function (item) { + item.PrePaddingSeconds = form.querySelector('#txtPrePaddingMinutes').value * 60; + item.PostPaddingSeconds = form.querySelector('#txtPostPaddingMinutes').value * 60; + item.RecordAnyChannel = form.querySelector('.selectChannels').value === 'all'; + item.RecordAnyTime = form.querySelector('.selectAirTime').value === 'any'; + item.RecordNewOnly = form.querySelector('.selectShowType').value === 'new'; + item.SkipEpisodesInLibrary = form.querySelector('.chkSkipEpisodesInLibrary').checked; + item.KeepUpTo = form.querySelector('.selectKeepUpTo').value; + + apiClient.updateLiveTvSeriesTimer(item); + }); + + e.preventDefault(); + + // Disable default form submission + return false; +} + +function init(context) { + fillKeepUpTo(context); + + context.querySelector('.btnCancel').addEventListener('click', function () { + closeDialog(false); + }); + + context.querySelector('.btnCancelRecording').addEventListener('click', function () { + const apiClient = connectionManager.getApiClient(currentServerId); + deleteTimer(apiClient, currentItemId).then(function () { + closeDialog(true); + }); + }); + + context.querySelector('form').addEventListener('submit', onSubmit); +} + +function reload(context, id) { + const apiClient = connectionManager.getApiClient(currentServerId); + + loading.show(); + if (typeof id === 'string') { + currentItemId = id; + + apiClient.getLiveTvSeriesTimer(id).then(function (result) { + renderTimer(context, result); + loading.hide(); + }); + } else if (id) { + currentItemId = id.Id; + + renderTimer(context, id); loading.hide(); } +} - function closeDialog(isDeleted) { - recordingUpdated = true; - recordingDeleted = isDeleted; +function fillKeepUpTo(context) { + let html = ''; - dialogHelper.close(currentDialog); - } + for (let i = 0; i <= 50; i++) { + let text; - function onSubmit(e) { - var form = this; - - var apiClient = connectionManager.getApiClient(currentServerId); - - apiClient.getLiveTvSeriesTimer(currentItemId).then(function (item) { - item.PrePaddingSeconds = form.querySelector('#txtPrePaddingMinutes').value * 60; - item.PostPaddingSeconds = form.querySelector('#txtPostPaddingMinutes').value * 60; - item.RecordAnyChannel = form.querySelector('.selectChannels').value === 'all'; - item.RecordAnyTime = form.querySelector('.selectAirTime').value === 'any'; - item.RecordNewOnly = form.querySelector('.selectShowType').value === 'new'; - item.SkipEpisodesInLibrary = form.querySelector('.chkSkipEpisodesInLibrary').checked; - item.KeepUpTo = form.querySelector('.selectKeepUpTo').value; - - apiClient.updateLiveTvSeriesTimer(item); - }); - - e.preventDefault(); - - // Disable default form submission - return false; - } - - function init(context) { - fillKeepUpTo(context); - - context.querySelector('.btnCancel').addEventListener('click', function () { - closeDialog(false); - }); - - context.querySelector('.btnCancelRecording').addEventListener('click', function () { - var apiClient = connectionManager.getApiClient(currentServerId); - deleteTimer(apiClient, currentItemId).then(function () { - closeDialog(true); - }); - }); - - context.querySelector('form').addEventListener('submit', onSubmit); - } - - function reload(context, id) { - var apiClient = connectionManager.getApiClient(currentServerId); - - loading.show(); - if (typeof id === 'string') { - currentItemId = id; - - apiClient.getLiveTvSeriesTimer(id).then(function (result) { - renderTimer(context, result, apiClient); - loading.hide(); - }); - } else if (id) { - currentItemId = id.Id; - - renderTimer(context, id, apiClient); - loading.hide(); - } - } - - function fillKeepUpTo(context) { - var html = ''; - - for (var i = 0; i <= 50; i++) { - var text; - - if (i === 0) { - text = globalize.translate('AsManyAsPossible'); - } else if (i === 1) { - text = globalize.translate('ValueOneEpisode'); - } else { - text = globalize.translate('ValueEpisodeCount', i); - } - - html += ''; + if (i === 0) { + text = globalize.translate('AsManyAsPossible'); + } else if (i === 1) { + text = globalize.translate('ValueOneEpisode'); + } else { + text = globalize.translate('ValueEpisodeCount', i); } - context.querySelector('.selectKeepUpTo').innerHTML = html; + html += ''; } - function onFieldChange(e) { - this.querySelector('.btnSubmit').click(); - } + context.querySelector('.selectKeepUpTo').innerHTML = html; +} - function embed(itemId, serverId, options) { +function onFieldChange() { + this.querySelector('.btnSubmit').click(); +} + +function embed(itemId, serverId, options) { + recordingUpdated = false; + recordingDeleted = false; + currentServerId = serverId; + loading.show(); + options = options || {}; + + import('text!./seriesrecordingeditor.template.html').then(({ default: template }) => { + const dialogOptions = { + removeOnClose: true, + scrollY: false + }; + + if (layoutManager.tv) { + dialogOptions.size = 'fullscreen'; + } else { + dialogOptions.size = 'small'; + } + + const dlg = options.context; + + dlg.classList.add('hide'); + dlg.innerHTML = globalize.translateHtml(template, 'core'); + + dlg.querySelector('.formDialogHeader').classList.add('hide'); + dlg.querySelector('.formDialogFooter').classList.add('hide'); + dlg.querySelector('.formDialogContent').className = ''; + dlg.querySelector('.dialogContentInner').className = ''; + dlg.classList.remove('hide'); + + dlg.removeEventListener('change', onFieldChange); + dlg.addEventListener('change', onFieldChange); + + currentDialog = dlg; + + init(dlg); + + reload(dlg, itemId); + }); +} + +function showEditor(itemId, serverId, options) { + return new Promise(function (resolve, reject) { recordingUpdated = false; recordingDeleted = false; currentServerId = serverId; loading.show(); options = options || {}; - require(['text!./seriesrecordingeditor.template.html'], function (template) { - var dialogOptions = { + import('text!./seriesrecordingeditor.template.html').then(({ default: template }) => { + const dialogOptions = { removeOnClose: true, scrollY: false }; @@ -148,101 +205,58 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c dialogOptions.size = 'small'; } - var dlg = options.context; + const dlg = dialogHelper.createDialog(dialogOptions); - dlg.classList.add('hide'); - dlg.innerHTML = globalize.translateHtml(template, 'core'); + dlg.classList.add('formDialog'); + dlg.classList.add('recordingDialog'); - dlg.querySelector('.formDialogHeader').classList.add('hide'); - dlg.querySelector('.formDialogFooter').classList.add('hide'); - dlg.querySelector('.formDialogContent').className = ''; - dlg.querySelector('.dialogContentInner').className = ''; - dlg.classList.remove('hide'); + if (!layoutManager.tv) { + dlg.style['min-width'] = '20%'; + } - dlg.removeEventListener('change', onFieldChange); - dlg.addEventListener('change', onFieldChange); + let html = ''; + + html += globalize.translateHtml(template, 'core'); + + dlg.innerHTML = html; + + if (options.enableCancel === false) { + dlg.querySelector('.formDialogFooter').classList.add('hide'); + } currentDialog = dlg; + dlg.addEventListener('closing', function () { + if (!recordingDeleted) { + this.querySelector('.btnSubmit').click(); + } + }); + + dlg.addEventListener('close', function () { + if (recordingUpdated) { + resolve({ + updated: true, + deleted: recordingDeleted + }); + } else { + reject(); + } + }); + + if (layoutManager.tv) { + scrollHelper.centerFocus.on(dlg.querySelector('.formDialogContent'), false); + } + init(dlg); reload(dlg, itemId); + + dialogHelper.open(dlg); }); - } + }); +} - function showEditor(itemId, serverId, options) { - return new Promise(function (resolve, reject) { - recordingUpdated = false; - recordingDeleted = false; - currentServerId = serverId; - loading.show(); - options = options || {}; - - require(['text!./seriesrecordingeditor.template.html'], function (template) { - var dialogOptions = { - removeOnClose: true, - scrollY: false - }; - - if (layoutManager.tv) { - dialogOptions.size = 'fullscreen'; - } else { - dialogOptions.size = 'small'; - } - - var dlg = dialogHelper.createDialog(dialogOptions); - - dlg.classList.add('formDialog'); - dlg.classList.add('recordingDialog'); - - if (!layoutManager.tv) { - dlg.style['min-width'] = '20%'; - } - - var html = ''; - - html += globalize.translateHtml(template, 'core'); - - dlg.innerHTML = html; - - if (options.enableCancel === false) { - dlg.querySelector('.formDialogFooter').classList.add('hide'); - } - - currentDialog = dlg; - - dlg.addEventListener('closing', function () { - if (!recordingDeleted) { - this.querySelector('.btnSubmit').click(); - } - }); - - dlg.addEventListener('close', function () { - if (recordingUpdated) { - resolve({ - updated: true, - deleted: recordingDeleted - }); - } else { - reject(); - } - }); - - if (layoutManager.tv) { - scrollHelper.centerFocus.on(dlg.querySelector('.formDialogContent'), false); - } - - init(dlg); - - reload(dlg, itemId); - - dialogHelper.open(dlg); - }); - }); - } - - return { - show: showEditor, - embed: embed - }; -}); +export default { + show: showEditor, + embed: embed +}; diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index 60c458e234..38728ec6c6 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -6,6 +6,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f 'use strict'; browser = browser.default || browser; + focusManager = focusManager.default || focusManager; /** * Name of transition event. diff --git a/src/components/sortmenu/sortmenu.js b/src/components/sortmenu/sortmenu.js index f62e5bb3a4..52a7b95c40 100644 --- a/src/components/sortmenu/sortmenu.js +++ b/src/components/sortmenu/sortmenu.js @@ -1,6 +1,8 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutManager', 'connectionManager', 'globalize', 'userSettings', 'emby-select', 'paper-icon-button-light', 'material-icons', 'css!./../formdialog', 'emby-button', 'flexStyles'], function (require, dom, focusManager, dialogHelper, loading, layoutManager, connectionManager, globalize, userSettings) { 'use strict'; + focusManager = focusManager.default || focusManager; + function onSubmit(e) { e.preventDefault(); return false; diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js index 7df24b5da8..c42658b2d5 100644 --- a/src/components/subtitleeditor/subtitleeditor.js +++ b/src/components/subtitleeditor/subtitleeditor.js @@ -2,6 +2,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', 'use strict'; loading = loading.default || loading; + focusManager = focusManager.default || focusManager; var currentItem; var hasChanges; diff --git a/src/components/tunerPicker.js b/src/components/tunerPicker.js index 5bc9386053..4e78030a2a 100644 --- a/src/components/tunerPicker.js +++ b/src/components/tunerPicker.js @@ -3,6 +3,7 @@ define(['dialogHelper', 'dom', 'layoutManager', 'connectionManager', 'globalize' browser = browser.default || browser; loading = loading.default || loading; + focusManager = focusManager.default || focusManager; var enableFocusTransform = !browser.slow && !browser.edge; diff --git a/src/components/tvproviders/schedulesdirect.js b/src/components/tvproviders/schedulesdirect.js index a0c29f48b8..de469e1845 100644 --- a/src/components/tvproviders/schedulesdirect.js +++ b/src/components/tvproviders/schedulesdirect.js @@ -1,299 +1,304 @@ -define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'listViewStyle', 'emby-input', 'emby-select', 'emby-button', 'flexStyles'], function ($, loading, globalize) { - 'use strict'; +import $ from 'jQuery'; +import loading from 'loading'; +import globalize from 'globalize'; +import 'emby-checkbox'; +import 'emby-input'; +import 'listViewStyle'; +import 'paper-icon-button-light'; +import 'emby-select'; +import 'emby-button'; +import 'flexStyles'; - loading = loading.default || loading; +export default function (page, providerId, options) { + function reload() { + loading.show(); + ApiClient.getNamedConfiguration('livetv').then(function (config) { + const info = config.ListingProviders.filter(function (i) { + return i.Id === providerId; + })[0] || {}; + listingsId = info.ListingsId; + $('#selectListing', page).val(info.ListingsId || ''); + page.querySelector('.txtUser').value = info.Username || ''; + page.querySelector('.txtPass').value = ''; + page.querySelector('.txtZipCode').value = info.ZipCode || ''; - return function (page, providerId, options) { - function reload() { - loading.show(); - ApiClient.getNamedConfiguration('livetv').then(function (config) { - var info = config.ListingProviders.filter(function (i) { - return i.Id === providerId; - })[0] || {}; - listingsId = info.ListingsId; - $('#selectListing', page).val(info.ListingsId || ''); - page.querySelector('.txtUser').value = info.Username || ''; - page.querySelector('.txtPass').value = ''; - page.querySelector('.txtZipCode').value = info.ZipCode || ''; - - if (info.Username && info.Password) { - page.querySelector('.listingsSection').classList.remove('hide'); - } else { - page.querySelector('.listingsSection').classList.add('hide'); - } - - page.querySelector('.chkAllTuners').checked = info.EnableAllTuners; - - if (info.EnableAllTuners) { - page.querySelector('.selectTunersSection').classList.add('hide'); - } else { - page.querySelector('.selectTunersSection').classList.remove('hide'); - } - - setCountry(info); - refreshTunerDevices(page, info, config.TunerHosts); - }); - } - - function setCountry(info) { - ApiClient.getJSON(ApiClient.getUrl('LiveTv/ListingProviders/SchedulesDirect/Countries')).then(function (result) { - var i; - var length; - var countryList = []; - - for (var region in result) { - var countries = result[region]; - - if (countries.length && region !== 'ZZZ') { - for (i = 0, length = countries.length; i < length; i++) { - countryList.push({ - name: countries[i].fullName, - value: countries[i].shortName - }); - } - } - } - - countryList.sort(function (a, b) { - if (a.name > b.name) { - return 1; - } - - if (a.name < b.name) { - return -1; - } - - return 0; - }); - $('#selectCountry', page).html(countryList.map(function (c) { - return ''; - }).join('')).val(info.Country || ''); - $(page.querySelector('.txtZipCode')).trigger('change'); - }, function () { // ApiClient.getJSON() error handler - Dashboard.alert({ - message: globalize.translate('ErrorGettingTvLineups') - }); - }); - loading.hide(); - } - - function sha256(str) { - if (!self.TextEncoder) { - return Promise.resolve(''); + if (info.Username && info.Password) { + page.querySelector('.listingsSection').classList.remove('hide'); + } else { + page.querySelector('.listingsSection').classList.add('hide'); } - var buffer = new TextEncoder('utf-8').encode(str); - return crypto.subtle.digest('SHA-256', buffer).then(function (hash) { - return hex(hash); - }); - } + page.querySelector('.chkAllTuners').checked = info.EnableAllTuners; - function hex(buffer) { - var hexCodes = []; - var view = new DataView(buffer); - - for (var i = 0; i < view.byteLength; i += 4) { - var value = view.getUint32(i); - var stringValue = value.toString(16); - var paddedValue = ('00000000' + stringValue).slice(-'00000000'.length); - hexCodes.push(paddedValue); + if (info.EnableAllTuners) { + page.querySelector('.selectTunersSection').classList.add('hide'); + } else { + page.querySelector('.selectTunersSection').classList.remove('hide'); } - return hexCodes.join(''); - } + setCountry(info); + refreshTunerDevices(page, info, config.TunerHosts); + }); + } - function submitLoginForm() { - loading.show(); - sha256(page.querySelector('.txtPass').value).then(function (passwordHash) { - var info = { - Type: 'SchedulesDirect', - Username: page.querySelector('.txtUser').value, - EnableAllTuners: true, - Password: passwordHash, - Pw: page.querySelector('.txtPass').value - }; - var id = providerId; + function setCountry(info) { + ApiClient.getJSON(ApiClient.getUrl('LiveTv/ListingProviders/SchedulesDirect/Countries')).then(function (result) { + let i; + let length; + const countryList = []; - if (id) { - info.Id = id; + for (const region in result) { + const countries = result[region]; + + if (countries.length && region !== 'ZZZ') { + for (i = 0, length = countries.length; i < length; i++) { + countryList.push({ + name: countries[i].fullName, + value: countries[i].shortName + }); + } + } + } + + countryList.sort(function (a, b) { + if (a.name > b.name) { + return 1; } - ApiClient.ajax({ - type: 'POST', - url: ApiClient.getUrl('LiveTv/ListingProviders', { - ValidateLogin: true - }), - data: JSON.stringify(info), - contentType: 'application/json', - dataType: 'json' - }).then(function (result) { - Dashboard.processServerConfigurationUpdateResult(); - providerId = result.Id; - reload(); - }, function () { - Dashboard.alert({ // ApiClient.ajax() error handler - message: globalize.translate('ErrorSavingTvProvider') - }); - }); + if (a.name < b.name) { + return -1; + } + + return 0; }); + $('#selectCountry', page).html(countryList.map(function (c) { + return ''; + }).join('')).val(info.Country || ''); + $(page.querySelector('.txtZipCode')).trigger('change'); + }, function () { // ApiClient.getJSON() error handler + Dashboard.alert({ + message: globalize.translate('ErrorGettingTvLineups') + }); + }); + loading.hide(); + } + + function sha256(str) { + if (!self.TextEncoder) { + return Promise.resolve(''); } - function submitListingsForm() { - var selectedListingsId = $('#selectListing', page).val(); + const buffer = new TextEncoder('utf-8').encode(str); + return crypto.subtle.digest('SHA-256', buffer).then(function (hash) { + return hex(hash); + }); + } - if (!selectedListingsId) { - return void Dashboard.alert({ - message: globalize.translate('ErrorPleaseSelectLineup') - }); - } + function hex(buffer) { + const hexCodes = []; + const view = new DataView(buffer); - loading.show(); - var id = providerId; - ApiClient.getNamedConfiguration('livetv').then(function (config) { - var info = config.ListingProviders.filter(function (i) { - return i.Id === id; - })[0]; - info.ZipCode = page.querySelector('.txtZipCode').value; - info.Country = $('#selectCountry', page).val(); - info.ListingsId = selectedListingsId; - info.EnableAllTuners = page.querySelector('.chkAllTuners').checked; - info.EnabledTuners = info.EnableAllTuners ? [] : $('.chkTuner', page).get().filter(function (i) { - return i.checked; - }).map(function (i) { - return i.getAttribute('data-id'); - }); - ApiClient.ajax({ - type: 'POST', - url: ApiClient.getUrl('LiveTv/ListingProviders', { - ValidateListings: true - }), - data: JSON.stringify(info), - contentType: 'application/json' - }).then(function (result) { - loading.hide(); - - if (options.showConfirmation) { - Dashboard.processServerConfigurationUpdateResult(); - } - - Events.trigger(self, 'submitted'); - }, function () { - loading.hide(); - Dashboard.alert({ - message: globalize.translate('ErrorAddingListingsToSchedulesDirect') - }); - }); - }); + for (let i = 0; i < view.byteLength; i += 4) { + const value = view.getUint32(i); + const stringValue = value.toString(16); + const paddedValue = ('00000000' + stringValue).slice(-'00000000'.length); + hexCodes.push(paddedValue); } - function refreshListings(value) { - if (!value) { - return void $('#selectListing', page).html(''); + return hexCodes.join(''); + } + + function submitLoginForm() { + loading.show(); + sha256(page.querySelector('.txtPass').value).then(function (passwordHash) { + const info = { + Type: 'SchedulesDirect', + Username: page.querySelector('.txtUser').value, + EnableAllTuners: true, + Password: passwordHash, + Pw: page.querySelector('.txtPass').value + }; + const id = providerId; + + if (id) { + info.Id = id; } - loading.show(); ApiClient.ajax({ - type: 'GET', - url: ApiClient.getUrl('LiveTv/ListingProviders/Lineups', { - Id: providerId, - Location: value, - Country: $('#selectCountry', page).val() + type: 'POST', + url: ApiClient.getUrl('LiveTv/ListingProviders', { + ValidateLogin: true }), + data: JSON.stringify(info), + contentType: 'application/json', dataType: 'json' }).then(function (result) { - $('#selectListing', page).html(result.map(function (o) { - return ''; - })); - - if (listingsId) { - $('#selectListing', page).val(listingsId); - } - - loading.hide(); - }, function (result) { - Dashboard.alert({ - message: globalize.translate('ErrorGettingTvLineups') + Dashboard.processServerConfigurationUpdateResult(); + providerId = result.Id; + reload(); + }, function () { + Dashboard.alert({ // ApiClient.ajax() error handler + message: globalize.translate('ErrorSavingTvProvider') }); - refreshListings(''); + }); + }); + } + + function submitListingsForm() { + const selectedListingsId = $('#selectListing', page).val(); + + if (!selectedListingsId) { + return void Dashboard.alert({ + message: globalize.translate('ErrorPleaseSelectLineup') + }); + } + + loading.show(); + const id = providerId; + ApiClient.getNamedConfiguration('livetv').then(function (config) { + const info = config.ListingProviders.filter(function (i) { + return i.Id === id; + })[0]; + info.ZipCode = page.querySelector('.txtZipCode').value; + info.Country = $('#selectCountry', page).val(); + info.ListingsId = selectedListingsId; + info.EnableAllTuners = page.querySelector('.chkAllTuners').checked; + info.EnabledTuners = info.EnableAllTuners ? [] : $('.chkTuner', page).get().filter(function (i) { + return i.checked; + }).map(function (i) { + return i.getAttribute('data-id'); + }); + ApiClient.ajax({ + type: 'POST', + url: ApiClient.getUrl('LiveTv/ListingProviders', { + ValidateListings: true + }), + data: JSON.stringify(info), + contentType: 'application/json' + }).then(function (result) { loading.hide(); - }); - } - function getTunerName(providerId) { - switch (providerId = providerId.toLowerCase()) { - case 'm3u': - return 'M3U Playlist'; - case 'hdhomerun': - return 'HDHomerun'; - case 'satip': - return 'DVB'; - default: - return 'Unknown'; - } - } - - function refreshTunerDevices(page, providerInfo, devices) { - var html = ''; - - for (var i = 0, length = devices.length; i < length; i++) { - var device = devices[i]; - html += '
http://example.com/<baseurl>
",
+ "LabelBaseUrlHelp": "サーバーの URL に、カスタム サブディレクトリを加えます。例 : http://example.com/<baseurl>
",
"LabelEnableSingleImageInDidlLimitHelp": "Didl 内に複数の画像が埋め込まれている場合、一部のデバイスでは正しくレンダリングされません。",
- "LabelEnableRealtimeMonitorHelp": "ファイルへの変更は、サポートされているファイルシステム上ですぐに処理されます。",
- "LabelEnableHttpsHelp": "構成された HTTPS ポートからサーバーがリッスンするのを有効にします。この機能を有効にするには、適切な証明書を設定する必要があります。",
+ "LabelEnableRealtimeMonitorHelp": "サポートしているファイルシステムでは、ファイルの変更をすぐに処理します。",
+ "LabelEnableHttpsHelp": "設定した HTTPS ポートをリッスンします。この機能を有効にするには、適切な証明書の設定が必要です。",
"LabelImageFetchersHelp": "画像検索サイトの優先度を設定します。",
"LabelPostProcessorArgumentsHelp": "{path}を録画ファイルのパスとして使用します。",
"LabelPostProcessorArguments": "後処理のコマンドライン引数:",
@@ -1214,5 +1214,7 @@
"LabelKodiMetadataDateFormatHelp": "NFOファイル内の全データが,このフォーマットによって解析されます。",
"LabelKeepUpTo": "最新:",
"LabelInNetworkSignInWithEasyPasswordHelp": "ローカルネットワーク内では簡単なPINコードを利用してサインインするようにします。ローカル以外からのアクセスのときのみ通常のパスワードが必要になります。PINコードを空欄にした場合,ローカルネットワーク内からのアクセスではパスワードが不要になります。",
- "LabelInNetworkSignInWithEasyPassword": "簡単なPINコードを利用してネットワーク内からサインインする機能の有効化"
+ "LabelInNetworkSignInWithEasyPassword": "簡単なPINコードを利用してネットワーク内からサインインする機能の有効化",
+ "LabelIconMaxWidthHelp": "upnp:icon として表示されるアイコンの最大解像度(幅)。",
+ "LabelIconMaxHeightHelp": "upnp:icon として表示されるアイコンの最大解像度(高さ)。"
}
diff --git a/src/strings/nl.json b/src/strings/nl.json
index 39b2ea1b5e..860783b083 100644
--- a/src/strings/nl.json
+++ b/src/strings/nl.json
@@ -1441,7 +1441,7 @@
"Season": "Seizoen",
"PreferEmbeddedEpisodeInfosOverFileNames": "Verkies ingeladen afleveringsinformatie boven bestandsnaam",
"PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Dit gebruikt de afleveringsinformatie van de ingeladen metadata als deze aanwezig is.",
- "PlaybackErrorNoCompatibleStream": "Deze machine is niet leesbaar met de media en de server verstuurd geen leesbare media formaten.",
+ "PlaybackErrorNoCompatibleStream": "Dit apparaat ondersteund de afgespeelde media niet en de server verstuurd geen ondersteund formaat.",
"Person": "Persoon",
"OptionForceRemoteSourceTranscoding": "Forceer het transcoderen van op afstand bediende media bronnen (zoals LiveTV)",
"NoCreatedLibraries": "Het lijkt erop dat er geen bibliotheek is gecreëerd. {0}Wilt u er nu een aanmaken?{1}",
diff --git a/src/strings/ru.json b/src/strings/ru.json
index 9089e4bea7..199d0f24ae 100644
--- a/src/strings/ru.json
+++ b/src/strings/ru.json
@@ -175,8 +175,8 @@
"DetectingDevices": "Обнаруживются устройства",
"DeviceAccessHelp": "Это относится только к устройствам, которые могут быть однозначно распознаны и не препятствует доступу через браузер. Фильтрация доступа пользовательского устройства запретит использование новых устройств до тех пор, пока они не будут одобрены.",
"DirectPlaying": "Воспроизводится напрямую",
- "DirectStreamHelp1": "Медиаданные совместимы с устройством в отношении разрешения и типа медиаданных (H.264, AC3, и т.д.), но в несовместимом файловом контейнере (mkv, avi, wmv и т.д.). Видео будет повторно упаковано динамически перед его трансляцией на устройство.",
- "DirectStreamHelp2": "При прямой трансляции файла расходуется очень мало вычислительной мощности без потери качества видео.",
+ "DirectStreamHelp1": "Медиаданные совместимы с устройством в отношении разрешения и типа медиаданных (H.264, AC3, и т.д.), но в несовместимом файловом контейнере (mkv, avi, wmv и т.д.). Видео будет повторно упаковано динамически перед его отправлением на устройство.",
+ "DirectStreamHelp2": "Прямая трансляции расходует очень мало вычислительной мощности с минимальной потерей качества видео.",
"DirectStreaming": "Транслируется напрямую",
"Director": "Режиссёр",
"Directors": "Режиссёры",
@@ -287,7 +287,7 @@
"HeaderAllowMediaDeletionFrom": "Разрешить удаление медиаданных из",
"HeaderApiKey": "API-ключ",
"HeaderApiKeys": "API-ключи",
- "HeaderApiKeysHelp": "Внешним приложениям требуется API-ключ для того, чтобы подключиться к Jellyfin Server. Ключи выдаются при входе с учётной записью Jellyfin или ключ предоставляется приложению вручную.",
+ "HeaderApiKeysHelp": "Внешним приложениям требуется API-ключ для того, чтобы подключиться к серверу. Ключи выдаются при входе с учётной записью обычного пользователя или ключ предоставляется приложению вручную.",
"HeaderApp": "Приложение",
"HeaderAppearsOn": "Фигурирует в",
"HeaderAudioBooks": "Аудиокниги",
@@ -359,7 +359,7 @@
"HeaderItems": "Элементы",
"HeaderKeepRecording": "Хранение записи",
"HeaderKeepSeries": "Хранение сериала",
- "HeaderKodiMetadataHelp": "Для включения или отключения NFO-метаданных, начните править медиатеку в области настройки медиатек и найдите раздел хранителей метаданных.",
+ "HeaderKodiMetadataHelp": "Для включения или отключения NFO-метаданных, правьте медиатеку и найдите раздел хранителей метаданных.",
"HeaderLatestEpisodes": "Новейшие эпизоды",
"HeaderLatestMedia": "Новейшие медиаданные",
"HeaderLatestMovies": "Новейшие фильмы",
@@ -408,7 +408,7 @@
"HeaderPreferredMetadataLanguage": "Выбор языка метаданных",
"HeaderProfile": "Профиль",
"HeaderProfileInformation": "О профиле",
- "HeaderProfileServerSettingsHelp": "Данные значения управляют тем, как Jellyfin Server будет представляться устройству.",
+ "HeaderProfileServerSettingsHelp": "Данные значения управляют тем, как сервер будет представлять себя клиентам.",
"HeaderRecentlyPlayed": "Воспроизведённые недавно",
"HeaderRecordingOptions": "Опции записи",
"HeaderRecordingPostProcessing": "Постобработка записи",
@@ -426,13 +426,13 @@
"HeaderSecondsValue": "{0} с",
"HeaderSelectCertificatePath": "Выбор пути к сертификату",
"HeaderSelectMetadataPath": "Выбор пути для метаданных",
- "HeaderSelectMetadataPathHelp": "Найдите или введите путь, в пределах которого хотите хранить метаданные. Папка должна быть доступна для записи.",
+ "HeaderSelectMetadataPathHelp": "Найдите или введите путь, который хотите использовать для метаданныхе. Папка должна быть доступна для записи.",
"HeaderSelectPath": "Выбор пути",
"HeaderSelectServer": "Выбор сервера",
"HeaderSelectServerCachePath": "Выбор пути для серверного кэша",
"HeaderSelectServerCachePathHelp": "Найдите или введите путь, чтобы использовать для файлов серверного кэша. Папка должна быть доступна для записи.",
"HeaderSelectTranscodingPath": "Выбор пути для временных файлов перекодировки",
- "HeaderSelectTranscodingPathHelp": "Найдите или введите путь, чтобы использовать для временных файлов перекодировки. Папка должна быть доступна для записи.",
+ "HeaderSelectTranscodingPathHelp": "Найдите или введите путь, чтобы использовать для файлов перекодировки. Папка должна быть доступна для записи.",
"HeaderSendMessage": "Передача сообщения",
"HeaderSeries": "Сериалы",
"HeaderSeriesOptions": "Опции сериала",
@@ -485,8 +485,8 @@
"HttpsRequiresCert": "Чтобы включить HTTPS для внешних подключений, вам нужно будет предоставить доверенный SSL-cертификат, например, Let's Encrypt. Предоставьте сертификат или отключите защищенные соединения.",
"Identify": "Распознать",
"Images": "Изображения",
- "ImportFavoriteChannelsHelp": "При включении, будут импортированы только каналы, которые обозначены как избранное на тюнерном устройстве.",
- "ImportMissingEpisodesHelp": "При включении, информация об отсутствующих эпизодах будет импортирована в вашу базу данных Jellyfin и отображаться в пределах сезонов и сериалов. Это может увеличить время сканирования медиатеки.",
+ "ImportFavoriteChannelsHelp": "Будут импортированы только каналы, которые обозначены как избранное на тюнерном устройстве.",
+ "ImportMissingEpisodesHelp": "Информация об отсутствующих эпизодах будет импортирована в вашу базу данных и отображена в пределах сезонов и сериалов. Это может заметно увеличить время сканирования медиатеки.",
"InstallingPackage": "Устанавливается {0} (версия {1})",
"InstantMix": "Автомикс",
"ItemCount": "{0} элемент(а/ов)",
@@ -517,15 +517,15 @@
"LabelAppName": "Название приложения",
"LabelAppNameExample": "Пример: Sickbeard, Sonarr",
"LabelArtists": "Исполнители:",
- "LabelArtistsHelp": "Для разделения используйте точку с запятой ;",
+ "LabelArtistsHelp": "Для разделения исполнителей используйте точку с запятой ;",
"LabelAudio": "Аудио",
"LabelAudioLanguagePreference": "Выбор языка аудио:",
"LabelAutomaticallyRefreshInternetMetadataEvery": "Автоматически обновлять метаданные из Интернета:",
"LabelBindToLocalNetworkAddress": "Привязка к адресу в локальной сети:",
- "LabelBindToLocalNetworkAddressHelp": "Необязательно. Переопределяется локальный IP-адрес для привязки HTTP-сервера. Если поле пусто, то привязка сервера будет ко всем доступным адресам. При изменении данного значения потребуется перезапуск Jellyfin Server.",
+ "LabelBindToLocalNetworkAddressHelp": "Переопределяется локальный IP-адрес для HTTP-сервера. Если поле пусто, то привязка сервера будет ко всем доступным адресам. При изменении данного значения потребуется перезапуск Jellyfin Server.",
"LabelBirthDate": "Дата рождения:",
"LabelBirthYear": "Год рождения:",
- "LabelBlastMessageInterval": "Интервал сообщений проверки активности, с",
+ "LabelBlastMessageInterval": "Интервал сообщений проверки активности",
"LabelBlastMessageIntervalHelp": "Определяет длительность в секундах между бомбардированием сообщениями проверки активности.",
"LabelBlockContentWithTags": "Блокирование элементов с тегами:",
"LabelBurnSubtitles": "Внедрение субтитров:",
@@ -545,7 +545,7 @@
"LabelCustomCertificatePath": "Путь к пользовательскому SSL-сертификату:",
"LabelCustomCertificatePathHelp": "Путь к файлу PKCS #12, содержащему сертификат и \tзакрытый ключ для включения поддержки TLS на произвольном домене.",
"LabelCustomCss": "Настраиваемые CSS:",
- "LabelCustomCssHelp": "Применяйте свою собственную настраиваемую стилизацию к веб-интерфейсу.",
+ "LabelCustomCssHelp": "Применяйте свои собственные настраиваемые стили в веб-интерфейсе.",
"LabelCustomDeviceDisplayName": "Отображаемое название:",
"LabelCustomDeviceDisplayNameHelp": "Приведите произвольное имя для отображения или не заполняйте, чтобы использовать имя, выданное устройством.",
"LabelCustomRating": "Произвольная возрастная категория:",
@@ -585,7 +585,7 @@
"LabelEnableDlnaDebugLogging": "Включить журналирование отладки DLNA",
"LabelEnableDlnaDebugLoggingHelp": "Создаются большие файлы Журнала, рекомендуется использовать только для поиска неполадок.",
"LabelEnableDlnaPlayTo": "Включить DLNA-функцию Воспроизвести На",
- "LabelEnableDlnaPlayToHelp": "Обнаруживаются устройства внутри своей сети, а также предоставляется возможность удалённо управлять ими.",
+ "LabelEnableDlnaPlayToHelp": "Обнаруживаются устройства внутри своей сети, а также предоставляется возможность управлять ими удалённо.",
"LabelEnableDlnaServer": "Включить DLNA-сервер",
"LabelEnableDlnaServerHelp": "Для UPnP-устройств домашней сети возможна навигация по содержанию и его воспроизведение.",
"LabelEnableHardwareDecodingFor": "Включить аппаратное декодирование для:",
@@ -606,9 +606,9 @@
"LabelForgotPasswordUsernameHelp": "Введите имя пользователя, если помните его.",
"LabelFormat": "Формат:",
"LabelFriendlyName": "Понятное имя:",
- "LabelServerNameHelp": "Это имя используется для распознавания сервера и будет по умолчанию именем компьютера.",
+ "LabelServerNameHelp": "Это имя используется для распознавания сервера и будет по умолчанию именем хоста сервера.",
"LabelGroupMoviesIntoCollections": "Группировать фильмы внутрь коллекций",
- "LabelGroupMoviesIntoCollectionsHelp": "При отображении списка фильмов, элементы, принадлежащие к одной коллекции будут отображаться как единый сгруппированный элемент.",
+ "LabelGroupMoviesIntoCollectionsHelp": "При отображении списков фильмов, фильмы из коллекции будут отображаться как единый группированный элемент.",
"LabelH264Crf": "Значение CRF H264-кодирования:",
"LabelEncoderPreset": "Предустановка H264-кодирования:",
"LabelHardwareAccelerationType": "Аппаратное ускорение:",
@@ -616,7 +616,7 @@
"LabelHomeNetworkQuality": "Качество в домашней сети:",
"LabelHomeScreenSectionValue": "Главная страница - раздел {0}:",
"LabelHttpsPort": "Номер локального HTTPS-порта:",
- "LabelHttpsPortHelp": "TCP-порт, ко которому следует создать привязку HTTPS-сервера Jellyfin.",
+ "LabelHttpsPortHelp": "Номер TCP-порта для HTTPS-сервера.",
"LabelIconMaxHeight": "Макс. высота значка:",
"LabelIconMaxHeightHelp": "Максимальное разрешение значков представляемых с помощью upnp:icon.",
"LabelIconMaxWidth": "Макс. ширина значка:",
@@ -644,7 +644,7 @@
"LabelLanguage": "Язык:",
"LabelLineup": "Список сопоставления:",
"LabelLocalHttpServerPortNumber": "Номер локального HTTP-порта:",
- "LabelLocalHttpServerPortNumberHelp": "TCP-порт, ко которому следует создать привязку HTTP-сервера Jellyfin.",
+ "LabelLocalHttpServerPortNumberHelp": "Номер TCP-порта для HTTP-сервера.",
"LabelLockItemToPreventChanges": "Зафиксировать данный элемент, чтобы запретить будущие правки",
"LabelLoginDisclaimer": "Предупреждение при входе:",
"LabelLoginDisclaimerHelp": "Сообщение будет отображаться в нижней части страницы входа в систему.",
@@ -670,7 +670,7 @@
"LabelMetadataReaders": "Считыватели метаданных:",
"LabelMetadataReadersHelp": "Ранжируйте предпочитаемые локальные источники метаданных в порядке приоритета. Будет считан первый же найденный файл.",
"LabelMetadataSavers": "Хранители метаданных:",
- "LabelMetadataSaversHelp": "Выберите форматы файлов, куда будут сохраняться метаданные.",
+ "LabelMetadataSaversHelp": "Выберите форматы файлов, которые будут использоваться при сохранении метаданных.",
"LabelMethod": "Метод:",
"LabelMinBackdropDownloadWidth": "Минимальная ширина загружаемого фона:",
"LabelMinResumeDuration": "Минимальная длительность для возобновления:",
@@ -686,7 +686,7 @@
"LabelMovieCategories": "Фильмовые категории:",
"LabelMoviePrefix": "Префикс фильма:",
"LabelMoviePrefixHelp": "При применении к названиям фильмов префикса, введите его здесь, чтобы он правильно обрабатывался на сервере.",
- "LabelMovieRecordingPath": "Путь к записываемым фильмам (необязательно):",
+ "LabelMovieRecordingPath": "Путь к записываемым фильмам:",
"LabelMusicStreamingTranscodingBitrate": "Битрейт перекодировки музыки:",
"LabelMusicStreamingTranscodingBitrateHelp": "Укажите максимальный битрейт при трансляции музыки.",
"LabelName": "Имя:",
@@ -699,7 +699,7 @@
"LabelNumber": "Номер:",
"LabelNumberOfGuideDays": "Число дней для загрузки данных телегида:",
"LabelNumberOfGuideDaysHelp": "Больше дней загрузки данных телегида обеспечивает возможность заблаговременно назначать расписание и просматривать больше перечней, однако это займёт больше времени для загрузки. При значении «Авто» выбор определяется числом каналов.",
- "LabelOptionalNetworkPath": "(Необязательно) Общедоступная сетевая папка:",
+ "LabelOptionalNetworkPath": "Общедоступная сетевая папка:",
"LabelOptionalNetworkPathHelp": "Если данная папка является общей в сети, указание пути к сетевой папке может позволить Jellyfin-приложениям на других устройствах иметь прямой доступ к медиафайлам. Например, {0} или {1}.",
"LabelOriginalAspectRatio": "Исходное соотношение сторон:",
"LabelOriginalTitle": "Оригинальное название:",
@@ -744,7 +744,7 @@
"LabelReleaseDate": "Дата выпуска:",
"LabelRemoteClientBitrateLimit": "Ограничение битрейта интернет-трансляции, Мбит/с:",
"LabelRemoteClientBitrateLimitHelp": "Необязательное ограничение битрейта для каждого из сетевых устройств. Может потребоваться, чтобы не допускать использования устройствами большего битрейта, чем способно пропустить интернет-соединение. Может привести к росту загрузки процессора на вашем сервере, так как потребуется динамическое перекодирование видео для снижения битрейта.",
- "LabelRuntimeMinutes": "Длительность, мин:",
+ "LabelRuntimeMinutes": "Длительность:",
"LabelSaveLocalMetadata": "Сохранять иллюстрации внутри медиапапок",
"LabelSaveLocalMetadataHelp": "При сохранении иллюстраций внутри медиапапок, те помещаются в месте, где их можно легко править.",
"LabelScheduledTaskLastRan": "Последний запуск был {0}, занял {1}.",
@@ -756,7 +756,7 @@
"LabelSelectVersionToInstall": "Выбрать версию для установки:",
"LabelSendNotificationToUsers": "Передача уведомления для:",
"LabelSerialNumber": "Серийный номер",
- "LabelSeriesRecordingPath": "Путь к записываемым сериалам (необязательно):",
+ "LabelSeriesRecordingPath": "Путь к записываемым сериалам:",
"LabelServerHost": "Узел:",
"LabelServerHostHelp": "192.168.1.100:8096 или https://myserver.com",
"LabelSimultaneousConnectionLimit": "Лимит одновременных потоков:",
@@ -917,7 +917,7 @@
"MessageYouHaveVersionInstalled": "В настоящее время установлена версия {0}.",
"Metadata": "Метаданные",
"MetadataManager": "Дисп. метаданных",
- "MetadataSettingChangeHelp": "Изменение параметров метаданных повлияет на новое содержание, которое будет добавляться в дальнейшем. Чтобы обновить существующие содержание, откройте экран с подробностями и нажмите кнопку Обновить, или выполните массовое обновление, с помощью Диспетчера метаданных.",
+ "MetadataSettingChangeHelp": "Изменение параметров метаданных повлияет на новое содержание, добавляемое в будущем.. Чтобы обновить существующие содержание, откройте экран с подробностями и нажмите кнопку Обновить, или выполните массовое обновление, с помощью Диспетчера метаданных.",
"MinutesAfter": "минут(у/ы) после",
"MinutesBefore": "минут(у/ы) до",
"Mobile": "Мобильный",
@@ -966,7 +966,7 @@
"OptionAllowLinkSharingHelp": "Общедоступны только веб-страницы содержащие сведения о медиаданных. Медиафайлы никогда не предоставляются для общего просмотра. Совместно используемые ресурсы ограничены во времени, а срок действия истекает через {0} дн(я/ей).",
"OptionAllowManageLiveTv": "Разрешить управление эфирными записями",
"OptionAllowMediaPlayback": "Разрешить воспроизведение медиаданных",
- "OptionAllowMediaPlaybackTranscodingHelp": "Ограничение доступа к перекодировке может привести к сбоям воспроизведения в Jellyfin-приложениях из-за неподдерживаемых форматов носителей.",
+ "OptionAllowMediaPlaybackTranscodingHelp": "Ограничение доступа к перекодировке может привести к сбоям воспроизведения в клиентах из-за неподдерживаемых форматов носителей.",
"OptionAllowRemoteControlOthers": "Разрешить удалённое управление другими пользователями",
"OptionAllowRemoteSharedDevices": "Разрешить удалённое управление используемыми совместно устройствами",
"OptionAllowRemoteSharedDevicesHelp": "DLNA-устройства считаются используемыми совместно, пока какой-либо пользователь не начнёт управлять ими.",
@@ -979,7 +979,7 @@
"OptionAuto": "Авто",
"OptionAutomatic": "Авто",
"OptionAutomaticallyGroupSeries": "Автоматически сливать вместе сериалы, которые разбросаны по нескольким папкам",
- "OptionAutomaticallyGroupSeriesHelp": "При включении, сериалы, которые разбросаны по нескольким папкам данной медиатеки, будут автоматически слиты в единый сериал.",
+ "OptionAutomaticallyGroupSeriesHelp": "Части сериала, которые разбросаны по нескольким папкам данной медиатеки, будут автоматически слиты в единый сериал.",
"OptionBlockBooks": "Книги",
"OptionBlockChannelContent": "Содержание интернет-канала",
"OptionBlockLiveTvChannels": "Эфирные каналы",
@@ -999,7 +999,7 @@
"OptionDatePlayed": "Дата воспроизведения",
"OptionDescending": "По убыванию",
"OptionDisableUser": "Заблокировать пользователя",
- "OptionDisableUserHelp": "При блокировании, этому пользователю не разрешаются любые подключения к серверу. Имеющиеся соединения будут разорваны.",
+ "OptionDisableUserHelp": "Этому пользователю не разрешаются любые подключения к серверу. Имеющиеся соединения будут разорваны.",
"OptionDislikes": "Не нравящиеся",
"OptionDisplayFolderView": "Отображать аспект Папки для просмотра обычных медиапапок",
"OptionDisplayFolderViewHelp": "Отображение аспекта \"Папки\" рядом с другими вашими медиатеками. Это может быть полезно, если вы хотите вид обычных папок.",
@@ -1009,7 +1009,7 @@
"OptionDownloadBoxImage": "DVD-бокс",
"OptionDownloadDiscImage": "Диск",
"OptionDownloadImagesInAdvance": "Загружать изображения заблаговременно",
- "OptionDownloadImagesInAdvanceHelp": "По умолчанию, большинство изображений загружаются только при запросе от Jellyfin-приложения. Включите данную опцию, чтобы загружать все изображения заблаговременно, при импорте новых медиаданных. Это может привести к существенно длительным сканированиям медиатеки.",
+ "OptionDownloadImagesInAdvanceHelp": "По умолчанию, большинство изображений загружаются только при запросе от клиента. Включите данную опцию, чтобы загружать все изображения заблаговременно, при импорте новых медиаданных. Это может привести к существенно длительным сканированиям медиатеки.",
"OptionDownloadLogoImage": "Логотип",
"OptionDownloadMenuImage": "Меню",
"OptionDownloadPrimaryImage": "Основной",
@@ -1042,7 +1042,7 @@
"OptionHlsSegmentedSubtitles": "Сегмент. субтитры HLS",
"OptionHomeVideos": "Фотографии",
"OptionIgnoreTranscodeByteRangeRequests": "Игнорировать запросы диапазона байтов перекодировки",
- "OptionIgnoreTranscodeByteRangeRequestsHelp": "При включении, эти запросы будут учтены, но заголовок диапазона байтов будет проигнорирован.",
+ "OptionIgnoreTranscodeByteRangeRequestsHelp": "Эти запросы будут учтены, но заголовок диапазона байтов будет проигнорирован.",
"OptionImdbRating": "Оценка IMDb",
"OptionLikes": "Нравящиеся",
"OptionMax": "Макс.",
@@ -1055,9 +1055,9 @@
"OptionOnInterval": "В интервале",
"OptionParentalRating": "Возрастная категория",
"OptionPlainStorageFolders": "Отображать все папки, как обычные папки хранения",
- "OptionPlainStorageFoldersHelp": "При включении, все папки описываются в DIDL как «object.container.storageFolder», вместо более конкретного типа, например, «object.container.person.musicArtist».",
+ "OptionPlainStorageFoldersHelp": "Все папки описываются в DIDL как «object.container.storageFolder», вместо более специфичного типа, например, «object.container.person.musicArtist».",
"OptionPlainVideoItems": "Отображать все видео, как обычные видео элементы",
- "OptionPlainVideoItemsHelp": "При включении, все видео описываются в DIDL как «object.item.videoItem», вместо более конкретного типа, например, «object.item.videoItem.movie».",
+ "OptionPlainVideoItemsHelp": "Все видео описываются в DIDL как «object.item.videoItem», вместо более специфичного типа, например, «object.item.videoItem.movie».",
"OptionPlayCount": "Кол. воспроизведений",
"OptionPlayed": "Воспроизведённые",
"OptionPremiereDate": "Дата премьеры",
@@ -1148,7 +1148,7 @@
"RecordingScheduled": "Запись назначена.",
"Recordings": "Записи",
"Refresh": "Обновить",
- "RefreshDialogHelp": "Обновление метаданных определяются параметрами и интернет-услугами, которые включены в Панели Jellyfin Server.",
+ "RefreshDialogHelp": "Обновление метаданных определяются параметрами и интернет-услугами, которые включены в Панели.",
"RefreshMetadata": "Обновить метаданные",
"RefreshQueued": "Обновление в очереди.",
"ReleaseDate": "Дата выпуска",
@@ -1395,11 +1395,11 @@
"OptionPosterCard": "Постер-карта",
"OptionThumb": "Эскиз",
"OptionThumbCard": "Эскиз-карта",
- "PasswordResetProviderHelp": "Выберите поставщика сброса пароля, который будет использоваться, когда этот пользователь запрашивает сброс пароля",
+ "PasswordResetProviderHelp": "Выберите поставщика сброса пароля, который использовуется при запросе пользователем сброса пароля",
"PlaybackData": "Данные воспроизведения",
"SubtitleOffset": "Сдвиг субтитров",
"TabNetworking": "Работа в сети",
- "LabelBaseUrlHelp": "Добавляется пользовательский подкаталог к URL сервера. Например: http://example.com/<baseurl>
",
+ "LabelBaseUrlHelp": "Добавляет пользовательский подкаталог к URL сервера. Например: http://example.com/<baseurl>
",
"LabelPlayer": "Проигрыватель:",
"MoreMediaInfo": "О медиаданных",
"LabelVideoCodec": "Видео кодек:",
@@ -1472,7 +1472,7 @@
"UnsupportedPlayback": "Jellyfin не может расшифровать содержимое, защищенное DRM, но в любом случае будет предпринята попытка расшифровки всего содержимого, включая защищенные заголовки. Некоторые файлы могут выглядеть полностью черными из-за шифрования или других неподдерживаемых функций, таких как интерактивные заголовки.",
"HeaderFavoritePlaylists": "Избранные плей-листы",
"LabelRequireHttpsHelp": "Если этот флажок установлен, сервер будет автоматически перенаправлять все запросы через HTTP на HTTPS. Это не имеет никакого эффекта, если сервер не слушает HTTPS.",
- "LabelEnableHttpsHelp": "Позволяет серверу слушать HTTPS-порт. Для работы необходим действующий сертификат.",
+ "LabelEnableHttpsHelp": "Прослушивается указанный HTTPS-порт. Чтобы это вступило в силу, также необходимо предоставить действительный сертификат.",
"ApiKeysCaption": "Список действующих текущих API-ключей",
"TabDVR": "DVR",
"SaveChanges": "Сохранить изменения",
@@ -1521,7 +1521,7 @@
"EnableBlurHashHelp": "Рисунки, которые всё ещё загружаются, будут отображаться с размытым заполнением",
"EnableBlurHash": "Включить размытые заполнители для изображений",
"ButtonSyncPlay": "SyncPlay",
- "ButtonCast": "В ролях",
+ "ButtonCast": "Транслировать",
"TabRepositories": "Репозитории",
"MessageNoGenresAvailable": "Разрешить поставщикам метаданных получать жанры из интернета.",
"MessageAddRepository": "Если вы хотите добавить репозиторий, нажмите кнопку рядом с заголовком и заполните необходимую информацию.",
@@ -1539,5 +1539,8 @@
"Writers": "Сценаристы",
"ViewAlbumArtist": "Посмотреть альбом исполнителя",
"ClearQueue": "Очистить очередь",
- "ButtonPlayer": "Проигрыватель"
+ "ButtonPlayer": "Проигрыватель",
+ "PreviousTrack": "Перейти к предыдущему",
+ "NextTrack": "Перейти к следующему",
+ "LabelUnstable": "Нестабильная"
}
diff --git a/src/strings/sl-si.json b/src/strings/sl-si.json
index a8f3bd020c..423ee7797c 100644
--- a/src/strings/sl-si.json
+++ b/src/strings/sl-si.json
@@ -448,7 +448,7 @@
"FastForward": "Hitro naprej",
"FFmpegSavePathNotFound": "Nismo mogli locirati FFmpeg na navedeni poti. FFprobe je prav tako zahtevan in mora biti v isti mapi. Ti komponenti sta običajno združeni skupaj v istem prenosu. Preverite pot in poskusite znova.",
"Extras": "Dodatki",
- "ExtractChapterImagesHelp": "Izločanje slik poglavij omogoča odjemalcem prikaz grafičnih menijev za izbor scene. Ta proces je lahko počasen, procesorsko zahteven in lahko potrebuje več gigabajtov prostora na disku. Teče ob odkritju novih videov in kot načrtovana naloga ponoči. Urnik izvajanja lahko nastavite v nastavitvah načrtovanih nalog. Zaganjanje tega procesa med urami visoke obremenitve ni priporočeno.",
+ "ExtractChapterImagesHelp": "Ekstrakcija slik poglavij omogoča odjemalcem prikaz grafičnih menijev za izbor scene. Ta proces je lahko počasen, procesorsko zahteven in lahko potrebuje več gigabajtov prostora na disku. Teče ob odkritju novih videov in kot načrtovana naloga ponoči. Urnik izvajanja lahko nastavite v nastavitvah načrtovanih nalog. Zaganjanje tega procesa med urami visoke obremenitve ni priporočeno.",
"ExtraLarge": "Zelo veliko",
"ExitFullscreen": "Izhod in celozaslonskega načina",
"ErrorSavingTvProvider": "Prišlo je do težave pri shranjevanju TV ponudnika. Preverite ali je dostopen in poskusite znova.",
@@ -723,16 +723,16 @@
"LabelMonitorUsers": "Spremljaj aktivnost iz:",
"LabelMovieCategories": "Kategorije filmov:",
"LabelMoviePrefix": "Predpona filma:",
- "LabelMovieRecordingPath": "Pot za snemanje filmov (neobvezno):",
+ "LabelMovieRecordingPath": "Pot za snemanje filmov:",
"LabelMusicStreamingTranscodingBitrate": "Bitna hitrost pretvarjanja glasbe:",
- "LabelMusicStreamingTranscodingBitrateHelp": "Določi največjo bitno hitrost pretakanja glasbe.",
+ "LabelMusicStreamingTranscodingBitrateHelp": "Določite največjo bitno hitrost pretakanja glasbe.",
"LabelName": "Ime:",
"LabelFriendlyName": "Uporabniku prijazno ime:",
"LabelKodiMetadataEnablePathSubstitutionHelp": "Omogoči zamenjavo poti za poti slik glede na nastavitve zamenjave poti strežnika.",
"LabelKodiMetadataSaveImagePaths": "Shrani poti slik znotraj nfo datotek",
"LabelMetadataDownloadersHelp": "Omogoči in uredi želene vire metapodatkov po prioriteti. Viri z nižjo prioriteto bodo uporabljeni zgolj za dopolnjevanje manjkajočih informacij.",
"LabelBaseUrlHelp": "Dodjte podnaslov po meri na konec URL-ja strežnika. Na primer: http://example.com/<baseurl>
",
- "LabelExtractChaptersDuringLibraryScanHelp": "Ustvari slike poglavij med uvozom videov pri preiskovanju knjižnjice. Sicer bodo ustvarjene med načrtovanim opravilom, kar omogoča hitrejše preiskovanje knjižnjice.",
+ "LabelExtractChaptersDuringLibraryScanHelp": "Ustvari slike poglavij med uvozom videov pri preiskovanju knjižnjice. Sicer bodo ustvarjene med načrtovanim opravilom ekstrakcije slik, kar omogoča hitrejše preiskovanje knjižnjice.",
"LabelForgotPasswordUsernameHelp": "Vpišite svoje uporabniško ime, v kolikor se ga spomnite.",
"LabelInNetworkSignInWithEasyPasswordHelp": "Uporabi enostavno PIN kodo za prijavo v naprave znotraj lokalnega omrežja. Vaše geslo bo potrebno zgolj za prijave zunaj domačega omrežja. Če pustite prazno, za prijavo v domačem omrežju omrežju ne boste potrebovali gesla.",
"LabelMaxStreamingBitrate": "Največja kvaliteta pretakanja:",
@@ -785,7 +785,7 @@
"MessagePlayAccessRestricted": "Predvajanje te vsebine je trenutno omejeno. Za več informacij se obrnite na skrbnika strežnika.",
"NoSubtitlesHelp": "Podnapisi se privzeto ne bodo naložili. Med predvajanjem jih lahko še vedno ročno vklopite.",
"MessagePluginConfigurationRequiresLocalAccess": "Za nastavitev tega dodatka se prosimo prijavite neposredno na vaš lokalni strežnik.",
- "OptionAllowMediaPlaybackTranscodingHelp": "Omejitev dostopa do prekodiranja lahko povzroči napake pri predvajanju v Jellyfin aplikacijah zaradi nepodprtih formatov predstavnosti.",
+ "OptionAllowMediaPlaybackTranscodingHelp": "Omejitev dostopa do prekodiranja lahko povzroči napake pri predvajanju v odjemalcih zaradi nepodprtih formatov predstavnosti.",
"OptionAllowVideoPlaybackRemuxing": "Dovoli predvajanje videoposnetkov, ki zahtevajo pretvarjanje brez prekodiranja",
"ViewPlaybackInfo": "Oglejte si informacije o predvajanju",
"WizardCompleted": "To je vse kar potrebujemo za zdaj. Jellyfin je začel zbirati informacije o vaši knjižnici predstavnosti. Oglejte si nekaj naših aplikacij in nato kliknite Zaključi za ogled Nadzorne plošče.",
@@ -820,7 +820,7 @@
"OptionReportByteRangeSeekingWhenTranscoding": "Sporoči, da strežnik podpira iskanje po bajtih pri prekodiranju",
"Quality": "Kvaliteta",
"PlaceFavoriteChannelsAtBeginning": "Postavi priljubljene kanale na začetek",
- "LabelOptionalNetworkPath": "(Neobvezno) Omrežna mapa:",
+ "LabelOptionalNetworkPath": "Omrežna mapa v skupni rabi:",
"LabelOptionalNetworkPathHelp": "V primeru, da je mapa deljena v vašem omrežju, lahko Jellyfin deli omrežno pot z ostalimi napravami in jim omogoči neposreden dostop do vsebin. Na primer {0} ali {1}.",
"LabelRemoteClientBitrateLimitHelp": "Neobvezna omejitev bitne hitrosti na posamezno predvajanje za vse naprave izven domačega omrežja. S tem lahko preprečite, da bi naprave zahtevale višjo bitno hitrost predvajanja, kot jo lahko prenese vaše omrežje. To lahko poveča obremenitev CPU-ja, saj bo morda potrebno sprotno prekodiranje za zmanjšanje bitne hitrosti.",
"LanNetworksHelp": "Z vejico ločen seznam IP naslovov ali IP/maska omrežji, ki bodo upoštevana kot lokalna pri uveljavljanju omejitev pasovne širine. Če nastavite, se bodo vsi ostali naslovi upoštevali kot zunanji in bodo predmet omejitve pasovne širine. Če pustite prazno, bo kot lokalno omrežje upoštevano zgolj omrežje strežnika.",
@@ -848,14 +848,14 @@
"OptionWeekly": "Tedensko",
"OriginalAirDateValue": "Prvotni datum predvajanja: {0}",
"Overview": "Pregled",
- "PackageInstallCancelled": "{0} namestitev preklicana.",
- "PackageInstallCompleted": "{0} namestitev uspešna.",
- "PackageInstallFailed": "{0} namestitev neuspešna.",
+ "PackageInstallCancelled": "{0} (različica {1}) namestitev preklicana.",
+ "PackageInstallCompleted": "{0} (različica {1}) namestitev uspešna.",
+ "PackageInstallFailed": "{0} (različica {1}) namestitev neuspešna.",
"PasswordMatchError": "Geslo in potrditev gesla se moreta ujemati.",
"PasswordResetComplete": "Geslo je bilo ponastavljeno.",
"PasswordResetConfirmation": "Ali ste prepričani, da želite ponastaviti geslo?",
"HeaderResetPassword": "Ponastavi geslo",
- "PasswordResetProviderHelp": "Izberite ponudnika ponastavitve gesla, ki bo uporabljen, ko bo ta uporabnik zahteval ponastavitev gesla",
+ "PasswordResetProviderHelp": "Izberite ponudnika ponastavitve gesla, ki bo uporabljen, ko bo ta uporabnik zahteval ponastavitev gesla.",
"PasswordSaved": "Geslo shranjeno.",
"PerfectMatch": "Popolno ujemanje",
"PictureInPicture": "Slika v sliki",
@@ -886,7 +886,7 @@
"MediaInfoExternal": "Zunanji",
"Refresh": "Osveži",
"MetadataManager": "Upravitelj metapodatkov",
- "MetadataSettingChangeHelp": "Spreminjanje nastavitev metapodatkov bo vplivalo na nove vsebine. Za osvežitev obstoječih vsebin, odprite okno s podrobnostmi in kliknite gumb Osveži, ali množično osvežite metapodatke z upraviteljem metapodatkov.",
+ "MetadataSettingChangeHelp": "Spreminjanje nastavitev metapodatkov bo vplivalo na novo dodane vsebine. Za osvežitev obstoječih vsebin, odprite okno s podrobnostmi in kliknite gumb Osveži, ali množično osvežite metapodatke z upraviteljem metapodatkov.",
"RefreshMetadata": "Osveži metapodatke",
"RefreshQueued": "Osvežitev v čakalni vrsti.",
"Shuffle": "Premešaj",
@@ -910,7 +910,7 @@
"LabelPasswordResetProvider": "Ponudnik ponastavitve gesla:",
"LabelPasswordConfirm": "Potrditev gesla:",
"LabelPassword": "Geslo:",
- "OptionDisableUserHelp": "Če onemogočite strežnik ne bo dovolil povezav od tega uporabnika. Obstoječe povezave bodo prekinjene.",
+ "OptionDisableUserHelp": "Strežnik ne bo dovolil nobenih povezav od tega uporabnika. Obstoječe povezave bodo prekinjene.",
"OptionDescending": "Padajoče",
"OptionDatePlayed": "Datum predvajanja",
"OptionDateAddedImportTime": "Uporabi datum dodajanja v knjižnico",
@@ -929,7 +929,7 @@
"OptionBlockMovies": "Filmi",
"OptionBlockBooks": "Knjige",
"OptionBanner": "Pasica",
- "OptionAutomaticallyGroupSeriesHelp": "Če je omogočeno, bodo serije, ki so razdeljene v več mapah znotraj knjižnice samodejno združene v eno serijo.",
+ "OptionAutomaticallyGroupSeriesHelp": "Serije, ki so razdeljene v več mapah znotraj knjižnice bodo samodejno združene v eno serijo.",
"OptionAutomaticallyGroupSeries": "Samodejno združi serije, ki so razdeljene po več mapah",
"OptionAscending": "Naraščajoče",
"OptionArtist": "Izvajalec",
@@ -940,7 +940,7 @@
"MessagePleaseWait": "Prosimo, počakajte. To lahko traja nekaj minut.",
"MessagePleaseEnsureInternetMetadata": "Prosimo poskrbite, da je prenašanje spletnih metapodatkov omogočeno.",
"MessageNothingHere": "Tu ni nič.",
- "MessageNoTrailersFound": "Napovednikov ni bilo mogoče najti. Namestite kanal napovednikov in izboljšajte svojo filmsko izkušnjo s knjižnico spletnih napovednikov.",
+ "MessageNoTrailersFound": "Namestite kanal napovednikov in izboljšajte svojo knjižnico z dodajanjem spletnih napovednikov.",
"MessageNoServersAvailable": "Z samodejnim odkrivanjem strežnikov ni bilo mogoče najti nobenega strežnika.",
"MessageNoPluginsInstalled": "Nameščenih nimate nobenih dodatkov.",
"MessageNoAvailablePlugins": "Dodatki niso na voljo.",
@@ -981,7 +981,7 @@
"MediaInfoResolution": "Ločljivost",
"MediaInfoRefFrames": "Ref sličice",
"MediaInfoProfile": "Profil",
- "MediaInfoPixelFormat": "Format pik",
+ "MediaInfoPixelFormat": "Format pikslov",
"MediaInfoPath": "Pot",
"MediaInfoLevel": "Stopnja",
"MediaInfoInterlaced": "Prepleteno",
@@ -1047,7 +1047,7 @@
"OptionDvd": "DVD",
"OptionDownloadMenuImage": "Meni",
"OptionDownloadLogoImage": "Logotip",
- "OptionDownloadImagesInAdvanceHelp": "Privzeto se večina slik prenese šele, ko jih zahtevajo aplikacije. Omogočite to možnost za prenos slik vnaprej, pri uvozu predstavnosti. To lahko občutno podaljša preiskovanje knjižnice.",
+ "OptionDownloadImagesInAdvanceHelp": "Privzeto se večina slik prenese šele, ko jih zahtevajo odjemalci. Omogočite to možnost za prenos slik vnaprej, pri uvozu predstavnosti. To lahko občutno podaljša preiskovanje knjižnic.",
"OptionDownloadImagesInAdvance": "Prenesi slike vnaprej",
"OptionAllowSyncTranscoding": "Dovoli prenašanje in sinhronizacijo predstavnosti ki zahteva pretvarjanje",
"OptionAllowRemoteControlOthers": "Dovoli daljinsko upravljanje drugih uporabnikov",
@@ -1077,14 +1077,14 @@
"LabelServerName": "Ime strežnika:",
"LabelServerHostHelp": "192.168.1.100:8096 ali https://myserver.com",
"LabelServerHost": "Naslov:",
- "LabelSeriesRecordingPath": "Pot za snemanje serij (neobvezno):",
+ "LabelSeriesRecordingPath": "Pot za snemanje serij:",
"LabelSerialNumber": "Serijska številka",
"LabelSendNotificationToUsers": "Pošlji obvestilo na:",
"LabelSeasonNumber": "Številka sezone:",
"LabelScreensaver": "Ohranjevalnik zaslona:",
"LabelSaveLocalMetadataHelp": "Shranjevanje slik v mape predstavnosti omogoča lažji dostop in urejanje slik.",
"LabelSaveLocalMetadata": "Shrani slike v mape predstavnosti",
- "LabelRuntimeMinutes": "Čas trajanja (minute):",
+ "LabelRuntimeMinutes": "Čas trajanja:",
"LabelRemoteClientBitrateLimit": "Omejitev bitne hitrosti pretakanja preko interneta (Mbps):",
"LabelRecordingPathHelp": "Določite privzeto lokacijo za shranjevanje posnetkov. Če pustite prazno, bo uporabljena mapa namestitve strežnika.",
"LabelRecordingPath": "Privzeta pot posnetkov:",
@@ -1377,5 +1377,57 @@
"TabNotifications": "Obvestila",
"TabNfoSettings": "Nastavitve NFO",
"TabMusicVideos": "Videospoti",
- "TabMovies": "Filmi"
+ "TabMovies": "Filmi",
+ "OptionForceRemoteSourceTranscoding": "Vsili prekodiranje oddaljenih virov predstavnosti (na primer TV v živo)",
+ "Off": "Izključeno",
+ "Normal": "Normalno",
+ "NoSubtitleSearchResultsFound": "Ni zadetkov.",
+ "MessageNoNextUpItems": "Ničesar ni bilo mogoče najti. Začnite gledati vaše serije!",
+ "NoCreatedLibraries": "Izgleda da niste dodali še nobene knjižnice. {0}Želite dodati eno zdaj?{1}",
+ "NextTrack": "Preskoči na naslednjo",
+ "TvLibraryHelp": "Preglejte {0}napotke za poimenovanje serij{1}.",
+ "MusicLibraryHelp": "Preglejte {0}napotke za poimenovanje glasbe{1}.",
+ "MovieLibraryHelp": "Preglejte {0}napotke za poimenovanje filmov{1}.",
+ "MoreMediaInfo": "Informacije o predstavnosti",
+ "Mobile": "Telefon",
+ "MessageSyncPlayErrorMedia": "Aktivacija SyncPlay ni uspela! Napaka predstavnosti.",
+ "MessageSyncPlayErrorMissingSession": "Aktivacija SyncPlay ni uspela! Manjka seja.",
+ "MessageSyncPlayErrorNoActivePlayer": "Najdeno ni bilo nobeno aktivno predvajanje. SyncPlay je bil onemogočen.",
+ "MessageSyncPlayErrorAccessingGroups": "Pri dostopu do seznama skupin je prišlo do napake.",
+ "MessageSyncPlayJoinGroupDenied": "Za uporabo SyncPlay je potrebno dovoljenje.",
+ "MessageSyncPlayGroupDoesNotExist": "Pridružitev skupini ni bila uspešna, ker ta ne obstaja.",
+ "MessageSyncPlayNoGroupsAvailable": "Na voljo ni nobene skupine. Začnite gledati nekaj.",
+ "MessageSyncPlayDisabled": "SyncPlay onemogočen.",
+ "MessageSyncPlayEnabled": "SyncPlay omogočen.",
+ "MessageUnsetContentHelp": "Vsebine bodo prikazane kot preproste mape. Za najboljše rezultate uporabite upravitelj metapodatkov in nastavite vrsto vsebin podmap.",
+ "MessageLeaveEmptyToInherit": "Pustite prazno za podedovanje nastavitev od nadrejenega elementa ali globalne privzete vrednosti.",
+ "LabelXDlnaDocHelp": "Določa vsebino X_DLNADOC elementa v urn:schemas-dlna-org:device-1-0 namespace.",
+ "LabelXDlnaCapHelp": "Določa vsebino X_DLNACAP elementa v urn:schemas-dlna-org:device-1-0 namespace.",
+ "OptionDislikes": "Ni mi všeč",
+ "ClearQueue": "Počisti čakalno vrsto",
+ "StopPlayback": "Ustavi predvajanje",
+ "ButtonCast": "Zasedba",
+ "EnableBlurHashHelp": "Med nalaganjem bodo slike nadomeščene z edinstvenimi nadomestnimi sličicami.",
+ "EnableBlurHash": "Omogoči zamegljene začasne sličice za slike",
+ "UnsupportedPlayback": "Jellyfin ne more dešifrirati vsebin zaščitenih z DRM, vendar bo strežnik kljub temu poskušal predvajati vse vsebine. Zaradi šifriranja ali drugih nepodprtih funkcij, na primer interaktivnih naslovov, bodo nekatere vsebine prikazane popolnoma črne.",
+ "OnApplicationStartup": "Ob zagonu aplikacije",
+ "EveryXHours": "Vsakih {0} ur",
+ "EveryHour": "Vsako uro",
+ "EveryXMinutes": "Vsakih {0} minut",
+ "OnWakeFromSleep": "Ob prebujenju iz spanja",
+ "WeeklyAt": "{0}s ob {1}",
+ "DailyAt": "Vsak dan ob {0}",
+ "OptionPlainVideoItemsHelp": "Vsi videi so predstavljeni v DIDL kot \"object.item.videoItem\" namesto bolj specifičen tip, kot na primer \"object.item.videoItem.movie\".",
+ "OptionPlainVideoItems": "Prikaži vse videe kot preproste video vsebine",
+ "OptionPlainStorageFoldersHelp": "Vse mape so predstavljene v DIDL kot \"object.container.storageFolder\" namesto bolj specifičen tip, kot na primer \"object.container.person.musicArtist\".",
+ "OptionPlainStorageFolders": "Prikaži vse mape kot enostavne mape shrambe",
+ "OptionHlsSegmentedSubtitles": "HLS ločeni podnapisi",
+ "OptionExtractChapterImage": "Omogoči ekstrakcijo slik poglavij",
+ "OptionEstimateContentLength": "Oceni dolžino vsebine pri prekodiranju",
+ "OptionEquals": "Je enako",
+ "OptionEnded": "Zaključeno",
+ "OptionEnableM2tsModeHelp": "Omogoči m2ts način pri kodiranju v mpegts.",
+ "OptionEnableM2tsMode": "Omogoči M2ts način",
+ "OptionDisplayFolderViewHelp": "Prikaže mape poleg ostalih knjižnic predstavnosti. Uporabno za preprost ogled map.",
+ "OptionDisplayFolderView": "Prikaži pogled mape za prikaz navadnih map predstavnosti"
}
diff --git a/yarn.lock b/yarn.lock
index 17c2b176ef..3ec7f21487 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -18,16 +18,16 @@
invariant "^2.2.4"
semver "^5.5.0"
-"@babel/core@>=7.2.2", "@babel/core@>=7.9.0", "@babel/core@^7.11.0":
- version "7.11.0"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.0.tgz#73b9c33f1658506887f767c26dae07798b30df76"
- integrity sha512-mkLq8nwaXmDtFmRkQ8ED/eA2CnVw4zr7dCztKalZXBvdK5EeNUAesrrwUqjQEzFgomJssayzB0aqlOsP1vGLqg==
+"@babel/core@>=7.2.2", "@babel/core@>=7.9.0", "@babel/core@^7.11.1":
+ version "7.11.1"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.1.tgz#2c55b604e73a40dc21b0e52650b11c65cf276643"
+ integrity sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ==
dependencies:
"@babel/code-frame" "^7.10.4"
"@babel/generator" "^7.11.0"
"@babel/helper-module-transforms" "^7.11.0"
"@babel/helpers" "^7.10.4"
- "@babel/parser" "^7.11.0"
+ "@babel/parser" "^7.11.1"
"@babel/template" "^7.10.4"
"@babel/traverse" "^7.11.0"
"@babel/types" "^7.11.0"
@@ -281,10 +281,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/parser@^7.10.4", "@babel/parser@^7.11.0":
- version "7.11.0"
- resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.0.tgz#a9d7e11aead25d3b422d17b2c6502c8dddef6a5d"
- integrity sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==
+"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.1":
+ version "7.11.1"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.1.tgz#d91a387990b21e5d20047b336bb19b0553f02ff5"
+ integrity sha512-u9QMIRdKVF7hfEkb3nu2LgZDIzCQPv+yHD9Eg6ruoJLjkrQ9fFz4IBSlF/9XwoNri9+2F1IY+dYuOfZrXq8t3w==
"@babel/plugin-proposal-async-generator-functions@^7.10.4":
version "7.10.4"
@@ -5262,11 +5262,12 @@ gulp-sourcemaps@^2.6.5:
strip-bom-string "1.X"
through2 "2.X"
-gulp-terser@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/gulp-terser/-/gulp-terser-1.3.0.tgz#6423fdb7dd15cc376e28063b5271271a928084bd"
- integrity sha512-EvizE1LJLfOh3/EmpJoq9iqYziObOkTzFgN4KvxfB0ICp3+W5H+MOO9B7Xq5Iuu9N+RKByNJLmqR+Ph13U1vtQ==
+gulp-terser@^1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/gulp-terser/-/gulp-terser-1.3.2.tgz#c91a71c31de0c40a94330bfd43b20c2a40df9a6b"
+ integrity sha512-hLx9Ww9PX304R3E7pMyL+jFftH47QXQCgKE6IZajbz7OoqAPMdr+sTxBpaujgIVkdbnJwJ7AFhfrcyy/cjBgZQ==
dependencies:
+ is-promise "^4.0.0"
plugin-error "^1.0.1"
terser ">=4"
through2 "^4.0.2"
@@ -6166,6 +6167,11 @@ is-promise@^2.1:
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
+is-promise@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3"
+ integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==
+
is-regex@^1.0.5, is-regex@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff"
@@ -11988,10 +11994,10 @@ webworkify@^1.5.0:
resolved "https://registry.yarnpkg.com/webworkify/-/webworkify-1.5.0.tgz#734ad87a774de6ebdd546e1d3e027da5b8f4a42c"
integrity sha512-AMcUeyXAhbACL8S2hqqdqOLqvJ8ylmIbNwUIqQujRSouf4+eUFaXbG6F1Rbu+srlJMmxQWsiU7mOJi0nMBfM1g==
-whatwg-fetch@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.2.0.tgz#8e134f701f0a4ab5fda82626f113e2b647fd16dc"
- integrity sha512-SdGPoQMMnzVYThUbSrEvqTlkvC1Ux27NehaJ/GUHBfNrh5Mjg+1/uRyFMwVnxO2MrikMWvWAqUGgQOfVU4hT7w==
+whatwg-fetch@^3.3.1:
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.3.1.tgz#6c1acf37dec176b0fd6bc9a74b616bec2f612935"
+ integrity sha512-faXTmGDcLuEPBpJwb5LQfyxvubKiE+RlbmmweFGKjvIPFj4uHTTfdtTIkdTRhC6OSH9S9eyYbx8kZ0UEaQqYTA==
which-module@^1.0.0:
version "1.0.0"