1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Merge branch 'master' into migrate-to-ES6-46

This commit is contained in:
Cameron 2020-08-08 23:22:14 +01:00 committed by GitHub
commit 7fa715e0cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
52 changed files with 1394 additions and 1346 deletions

View file

@ -160,7 +160,11 @@
"src/components/refreshdialog/refreshdialog.js", "src/components/refreshdialog/refreshdialog.js",
"src/components/sanatizefilename.js", "src/components/sanatizefilename.js",
"src/components/scrollManager.js", "src/components/scrollManager.js",
"src/components/slideshow/slideshow.js",
"src/components/sortmenu/sortmenu.js",
"src/plugins/htmlVideoPlayer/plugin.js", "src/plugins/htmlVideoPlayer/plugin.js",
"src/plugins/logoScreensaver/plugin.js",
"src/plugins/playAccessValidation/plugin.js",
"src/components/search/searchfields.js", "src/components/search/searchfields.js",
"src/components/search/searchresults.js", "src/components/search/searchresults.js",
"src/components/settingshelper.js", "src/components/settingshelper.js",
@ -203,13 +207,16 @@
"src/controllers/music/musicplaylists.js", "src/controllers/music/musicplaylists.js",
"src/controllers/music/musicrecommended.js", "src/controllers/music/musicrecommended.js",
"src/controllers/music/songs.js", "src/controllers/music/songs.js",
"src/controllers/dashboard/mediaLibrary.js", "src/controllers/dashboard/library.js",
"src/controllers/dashboard/metadataImages.js", "src/controllers/dashboard/metadataImages.js",
"src/controllers/dashboard/metadatanfo.js", "src/controllers/dashboard/metadatanfo.js",
"src/controllers/dashboard/networking.js", "src/controllers/dashboard/networking.js",
"src/controllers/dashboard/notifications/notification.js", "src/controllers/dashboard/notifications/notification.js",
"src/controllers/dashboard/notifications/notifications.js", "src/controllers/dashboard/notifications/notifications.js",
"src/controllers/dashboard/playback.js", "src/controllers/dashboard/playback.js",
"src/controllers/dashboard/plugins/add/index.js",
"src/controllers/dashboard/plugins/installed/index.js",
"src/controllers/dashboard/plugins/available/index.js",
"src/controllers/dashboard/plugins/repositories/index.js", "src/controllers/dashboard/plugins/repositories/index.js",
"src/controllers/dashboard/scheduledtasks/scheduledtask.js", "src/controllers/dashboard/scheduledtasks/scheduledtask.js",
"src/controllers/dashboard/scheduledtasks/scheduledtasks.js", "src/controllers/dashboard/scheduledtasks/scheduledtasks.js",

View file

@ -2,32 +2,37 @@
* Image viewer component * Image viewer component
* @module components/slideshow/slideshow * @module components/slideshow/slideshow
*/ */
define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'browser', 'apphost', 'dom', 'css!./style', 'material-icons', 'paper-icon-button-light'], function (dialogHelper, inputManager, connectionManager, layoutManager, focusManager, browser, appHost, dom) { import dialogHelper from 'dialogHelper';
'use strict'; import inputManager from 'inputManager';
import connectionManager from 'connectionManager';
import layoutManager from 'layoutManager';
import focusManager from 'focusManager';
import browser from 'browser';
import appHost from 'apphost';
import dom from 'dom';
import 'css!./style';
import 'material-icons';
import 'paper-icon-button-light';
browser = browser.default || browser; /**
layoutManager = layoutManager.default || layoutManager;
focusManager = focusManager.default || focusManager;
/**
* Name of transition event. * Name of transition event.
*/ */
const transitionEndEventName = dom.whichTransitionEvent(); const transitionEndEventName = dom.whichTransitionEvent();
/** /**
* Flag to use fake image to fix blurry zoomed image. * Flag to use fake image to fix blurry zoomed image.
* At least WebKit doesn't restore quality for zoomed images. * At least WebKit doesn't restore quality for zoomed images.
*/ */
const useFakeZoomImage = browser.safari; const useFakeZoomImage = browser.safari;
/** /**
* Retrieves an item's image URL from the API. * Retrieves an item's image URL from the API.
* @param {object|string} item - Item used to generate the image URL. * @param {object|string} item - Item used to generate the image URL.
* @param {object} options - Options of the image. * @param {object} options - Options of the image.
* @param {object} apiClient - API client instance used to retrieve the image. * @param {object} apiClient - API client instance used to retrieve the image.
* @returns {null|string} URL of the item's image. * @returns {null|string} URL of the item's image.
*/ */
function getImageUrl(item, options, apiClient) { function getImageUrl(item, options, apiClient) {
options = options || {}; options = options || {};
options.type = options.type || 'Primary'; options.type = options.type || 'Primary';
@ -48,16 +53,16 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
} }
return null; return null;
} }
/** /**
* Retrieves a backdrop's image URL from the API. * Retrieves a backdrop's image URL from the API.
* @param {object} item - Item used to generate the image URL. * @param {object} item - Item used to generate the image URL.
* @param {object} options - Options of the image. * @param {object} options - Options of the image.
* @param {object} apiClient - API client instance used to retrieve the image. * @param {object} apiClient - API client instance used to retrieve the image.
* @returns {null|string} URL of the item's backdrop. * @returns {null|string} URL of the item's backdrop.
*/ */
function getBackdropImageUrl(item, options, apiClient) { function getBackdropImageUrl(item, options, apiClient) {
options = options || {}; options = options || {};
options.type = options.type || 'Backdrop'; options.type = options.type || 'Backdrop';
@ -72,16 +77,16 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
} }
return null; return null;
} }
/** /**
* Dispatches a request for an item's image to its respective handler. * Dispatches a request for an item's image to its respective handler.
* @param {object} item - Item used to generate the image URL. * @param {object} item - Item used to generate the image URL.
* @returns {string} URL of the item's image. * @returns {string} URL of the item's image.
*/ */
function getImgUrl(item, user) { function getImgUrl(item, user) {
var apiClient = connectionManager.getApiClient(item.ServerId); const apiClient = connectionManager.getApiClient(item.ServerId);
var imageOptions = {}; const imageOptions = {};
if (item.BackdropImageTags && item.BackdropImageTags.length) { if (item.BackdropImageTags && item.BackdropImageTags.length) {
return getBackdropImageUrl(item, imageOptions, apiClient); return getBackdropImageUrl(item, imageOptions, apiClient);
@ -92,9 +97,9 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
imageOptions.type = 'Primary'; imageOptions.type = 'Primary';
return getImageUrl(item, imageOptions, apiClient); return getImageUrl(item, imageOptions, apiClient);
} }
} }
/** /**
* Generates a button using the specified icon, classes and properties. * Generates a button using the specified icon, classes and properties.
* @param {string} icon - Name of the material icon on the button * @param {string} icon - Name of the material icon on the button
* @param {string} cssClass - CSS classes to assign to the button * @param {string} cssClass - CSS classes to assign to the button
@ -102,36 +107,36 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* @param {boolean} autoFocus - Flag to set the autofocus attribute on the button. * @param {boolean} autoFocus - Flag to set the autofocus attribute on the button.
* @returns {string} The HTML markup of the button. * @returns {string} The HTML markup of the button.
*/ */
function getIcon(icon, cssClass, canFocus, autoFocus) { function getIcon(icon, cssClass, canFocus, autoFocus) {
var tabIndex = canFocus ? '' : ' tabindex="-1"'; const tabIndex = canFocus ? '' : ' tabindex="-1"';
autoFocus = autoFocus ? ' autofocus' : ''; autoFocus = autoFocus ? ' autofocus' : '';
return '<button is="paper-icon-button-light" class="autoSize ' + cssClass + '"' + tabIndex + autoFocus + '><span class="material-icons slideshowButtonIcon ' + icon + '"></span></button>'; return '<button is="paper-icon-button-light" class="autoSize ' + cssClass + '"' + tabIndex + autoFocus + '><span class="material-icons slideshowButtonIcon ' + icon + '"></span></button>';
} }
/** /**
* Sets the viewport meta tag to enable or disable scaling by the user. * Sets the viewport meta tag to enable or disable scaling by the user.
* @param {boolean} scalable - Flag to set the scalability of the viewport. * @param {boolean} scalable - Flag to set the scalability of the viewport.
*/ */
function setUserScalable(scalable) { function setUserScalable(scalable) {
try { try {
appHost.setUserScalable(scalable); appHost.setUserScalable(scalable);
} catch (err) { } catch (err) {
console.error('error in appHost.setUserScalable: ' + err); console.error('error in appHost.setUserScalable: ' + err);
} }
} }
return function (options) { export default function (options) {
var self = this; const self = this;
/** Initialized instance of Swiper. */ /** Initialized instance of Swiper. */
var swiperInstance; let swiperInstance;
/** Initialized instance of the dialog containing the Swiper instance. */ /** Initialized instance of the dialog containing the Swiper instance. */
var dialog; let dialog;
/** Options of the slideshow components */ /** Options of the slideshow components */
var currentOptions; let currentOptions;
/** ID of the timeout used to hide the OSD. */ /** ID of the timeout used to hide the OSD. */
var hideTimeout; let hideTimeout;
/** Last coordinates of the mouse pointer. */ /** Last coordinates of the mouse pointer. */
var lastMouseMoveData; let lastMouseMoveData;
/** /**
* Creates the HTML markup for the dialog and the OSD. * Creates the HTML markup for the dialog and the OSD.
@ -151,12 +156,12 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
dialog.classList.add('slideshowDialog'); dialog.classList.add('slideshowDialog');
var html = ''; let html = '';
html += '<div class="slideshowSwiperContainer"><div class="swiper-wrapper"></div></div>'; html += '<div class="slideshowSwiperContainer"><div class="swiper-wrapper"></div></div>';
if (options.interactive && !layoutManager.tv) { if (options.interactive && !layoutManager.tv) {
var actionButtonsOnTop = layoutManager.mobile; const actionButtonsOnTop = layoutManager.mobile;
html += getIcon('keyboard_arrow_left', 'btnSlideshowPrevious slideshowButton hide-mouse-idle-tv', false); html += getIcon('keyboard_arrow_left', 'btnSlideshowPrevious slideshowButton hide-mouse-idle-tv', false);
html += getIcon('keyboard_arrow_right', 'btnSlideshowNext slideshowButton hide-mouse-idle-tv', false); html += getIcon('keyboard_arrow_right', 'btnSlideshowNext slideshowButton hide-mouse-idle-tv', false);
@ -197,17 +202,17 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
dialogHelper.close(dialog); dialogHelper.close(dialog);
}); });
var btnPause = dialog.querySelector('.btnSlideshowPause'); const btnPause = dialog.querySelector('.btnSlideshowPause');
if (btnPause) { if (btnPause) {
btnPause.addEventListener('click', playPause); btnPause.addEventListener('click', playPause);
} }
var btnDownload = dialog.querySelector('.btnDownload'); const btnDownload = dialog.querySelector('.btnDownload');
if (btnDownload) { if (btnDownload) {
btnDownload.addEventListener('click', download); btnDownload.addEventListener('click', download);
} }
var btnShare = dialog.querySelector('.btnShare'); const btnShare = dialog.querySelector('.btnShare');
if (btnShare) { if (btnShare) {
btnShare.addEventListener('click', share); btnShare.addEventListener('click', share);
} }
@ -232,7 +237,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Handles OSD changes when the autoplay is started. * Handles OSD changes when the autoplay is started.
*/ */
function onAutoplayStart() { function onAutoplayStart() {
var btnSlideshowPause = dialog.querySelector('.btnSlideshowPause .material-icons'); const btnSlideshowPause = dialog.querySelector('.btnSlideshowPause .material-icons');
if (btnSlideshowPause) { if (btnSlideshowPause) {
btnSlideshowPause.classList.replace('play_arrow', 'pause'); btnSlideshowPause.classList.replace('play_arrow', 'pause');
} }
@ -242,7 +247,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Handles OSD changes when the autoplay is stopped. * Handles OSD changes when the autoplay is stopped.
*/ */
function onAutoplayStop() { function onAutoplayStop() {
var btnSlideshowPause = dialog.querySelector('.btnSlideshowPause .material-icons'); const btnSlideshowPause = dialog.querySelector('.btnSlideshowPause .material-icons');
if (btnSlideshowPause) { if (btnSlideshowPause) {
btnSlideshowPause.classList.replace('pause', 'play_arrow'); btnSlideshowPause.classList.replace('pause', 'play_arrow');
} }
@ -289,14 +294,14 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* @param {Object} options - Options used to initialize the Swiper instance. * @param {Object} options - Options used to initialize the Swiper instance.
*/ */
function loadSwiper(dialog, options) { function loadSwiper(dialog, options) {
var slides; let slides;
if (currentOptions.slides) { if (currentOptions.slides) {
slides = currentOptions.slides; slides = currentOptions.slides;
} else { } else {
slides = currentOptions.items; slides = currentOptions.items;
} }
require(['swiper'], function (Swiper) { import('swiper').then(({default: Swiper}) => {
swiperInstance = new Swiper(dialog.querySelector('.slideshowSwiperContainer'), { swiperInstance = new Swiper(dialog.querySelector('.slideshowSwiperContainer'), {
direction: 'horizontal', direction: 'horizontal',
// Loop is disabled due to the virtual slides option not supporting it. // Loop is disabled due to the virtual slides option not supporting it.
@ -370,7 +375,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* @returns {string} The HTML markup of the slide. * @returns {string} The HTML markup of the slide.
*/ */
function getSwiperSlideHtmlFromSlide(item) { function getSwiperSlideHtmlFromSlide(item) {
var html = ''; let html = '';
html += '<div class="swiper-slide" data-original="' + item.originalImage + '" data-itemid="' + item.Id + '" data-serverid="' + item.ServerId + '">'; html += '<div class="swiper-slide" data-original="' + item.originalImage + '" data-itemid="' + item.Id + '" data-serverid="' + item.ServerId + '">';
html += '<div class="swiper-zoom-container">'; html += '<div class="swiper-zoom-container">';
if (useFakeZoomImage) { if (useFakeZoomImage) {
@ -405,7 +410,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
*/ */
function getCurrentImageInfo() { function getCurrentImageInfo() {
if (swiperInstance) { if (swiperInstance) {
var slide = document.querySelector('.swiper-slide-active'); const slide = document.querySelector('.swiper-slide-active');
if (slide) { if (slide) {
return { return {
@ -425,9 +430,9 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Starts a download for the currently displayed slide. * Starts a download for the currently displayed slide.
*/ */
function download() { function download() {
var imageInfo = getCurrentImageInfo(); const imageInfo = getCurrentImageInfo();
require(['fileDownloader'], function (fileDownloader) { import('fileDownloader').then(({default: fileDownloader}) => {
fileDownloader.download([imageInfo]); fileDownloader.download([imageInfo]);
}); });
} }
@ -436,7 +441,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Shares the currently displayed slide using the browser's built-in sharing feature. * Shares the currently displayed slide using the browser's built-in sharing feature.
*/ */
function share() { function share() {
var imageInfo = getCurrentImageInfo(); const imageInfo = getCurrentImageInfo();
navigator.share({ navigator.share({
url: imageInfo.shareUrl url: imageInfo.shareUrl
@ -465,7 +470,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Toggles the autoplay feature of the Swiper instance. * Toggles the autoplay feature of the Swiper instance.
*/ */
function playPause() { function playPause() {
var paused = !dialog.querySelector('.btnSlideshowPause .material-icons').classList.contains('pause'); const paused = !dialog.querySelector('.btnSlideshowPause .material-icons').classList.contains('pause');
if (paused) { if (paused) {
play(); play();
} else { } else {
@ -477,7 +482,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Closes the dialog and destroys the Swiper instance. * Closes the dialog and destroys the Swiper instance.
*/ */
function onDialogClosed() { function onDialogClosed() {
var swiper = swiperInstance; const swiper = swiperInstance;
if (swiper) { if (swiper) {
swiper.destroy(true, true); swiper.destroy(true, true);
swiperInstance = null; swiperInstance = null;
@ -495,7 +500,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Shows the OSD. * Shows the OSD.
*/ */
function showOsd() { function showOsd() {
var bottom = dialog.querySelector('.slideshowBottomBar'); const bottom = dialog.querySelector('.slideshowBottomBar');
if (bottom) { if (bottom) {
slideUpToShow(bottom); slideUpToShow(bottom);
startHideTimer(); startHideTimer();
@ -506,7 +511,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Hides the OSD. * Hides the OSD.
*/ */
function hideOsd() { function hideOsd() {
var bottom = dialog.querySelector('.slideshowBottomBar'); const bottom = dialog.querySelector('.slideshowBottomBar');
if (bottom) { if (bottom) {
slideDownToHide(bottom); slideDownToHide(bottom);
} }
@ -541,7 +546,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
element.classList.remove('hide'); element.classList.remove('hide');
var onFinish = function () { const onFinish = function () {
focusManager.focus(element.querySelector('.btnSlideshowPause')); focusManager.focus(element.querySelector('.btnSlideshowPause'));
}; };
@ -551,11 +556,11 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
} }
requestAnimationFrame(function () { requestAnimationFrame(function () {
var keyframes = [ const keyframes = [
{ transform: 'translate3d(0,' + element.offsetHeight + 'px,0)', opacity: '.3', offset: 0 }, { transform: 'translate3d(0,' + element.offsetHeight + 'px,0)', opacity: '.3', offset: 0 },
{ transform: 'translate3d(0,0,0)', opacity: '1', offset: 1 } { transform: 'translate3d(0,0,0)', opacity: '1', offset: 1 }
]; ];
var timing = { duration: 300, iterations: 1, easing: 'ease-out' }; const timing = { duration: 300, iterations: 1, easing: 'ease-out' };
element.animate(keyframes, timing).onfinish = onFinish; element.animate(keyframes, timing).onfinish = onFinish;
}); });
} }
@ -569,7 +574,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
return; return;
} }
var onFinish = function () { const onFinish = function () {
element.classList.add('hide'); element.classList.add('hide');
}; };
@ -579,11 +584,11 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
} }
requestAnimationFrame(function () { requestAnimationFrame(function () {
var keyframes = [ const keyframes = [
{ transform: 'translate3d(0,0,0)', opacity: '1', offset: 0 }, { transform: 'translate3d(0,0,0)', opacity: '1', offset: 0 },
{ transform: 'translate3d(0,' + element.offsetHeight + 'px,0)', opacity: '.3', offset: 1 } { transform: 'translate3d(0,' + element.offsetHeight + 'px,0)', opacity: '.3', offset: 1 }
]; ];
var timing = { duration: 300, iterations: 1, easing: 'ease-out' }; const timing = { duration: 300, iterations: 1, easing: 'ease-out' };
element.animate(keyframes, timing).onfinish = onFinish; element.animate(keyframes, timing).onfinish = onFinish;
}); });
} }
@ -593,13 +598,13 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* @param {Event} event - Pointer movement event. * @param {Event} event - Pointer movement event.
*/ */
function onPointerMove(event) { function onPointerMove(event) {
var pointerType = event.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'); const pointerType = event.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
if (pointerType === 'mouse') { if (pointerType === 'mouse') {
var eventX = event.screenX || 0; const eventX = event.screenX || 0;
var eventY = event.screenY || 0; const eventY = event.screenY || 0;
var obj = lastMouseMoveData; const obj = lastMouseMoveData;
if (!obj) { if (!obj) {
lastMouseMoveData = { lastMouseMoveData = {
x: eventX, x: eventX,
@ -665,5 +670,4 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
dialogHelper.close(dialog); dialogHelper.close(dialog);
} }
}; };
}; }
});

View file

@ -1,50 +1,51 @@
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) { import dialogHelper from 'dialogHelper';
'use strict'; import layoutManager from 'layoutManager';
import globalize from 'globalize';
import * as userSettings from 'userSettings';
import 'emby-select';
import 'paper-icon-button-light';
import 'material-icons';
import 'css!./../formdialog';
import 'emby-button';
import 'flexStyles';
layoutManager = layoutManager.default || layoutManager; function onSubmit(e) {
focusManager = focusManager.default || focusManager;
function onSubmit(e) {
e.preventDefault(); e.preventDefault();
return false; return false;
} }
function initEditor(context, settings) { function initEditor(context, settings) {
context.querySelector('form').addEventListener('submit', onSubmit); context.querySelector('form').addEventListener('submit', onSubmit);
context.querySelector('.selectSortOrder').value = settings.sortOrder; context.querySelector('.selectSortOrder').value = settings.sortOrder;
context.querySelector('.selectSortBy').value = settings.sortBy; context.querySelector('.selectSortBy').value = settings.sortBy;
} }
function centerFocus(elem, horiz, on) { function centerFocus(elem, horiz, on) {
require(['scrollHelper'], function (scrollHelper) { import('scrollHelper').then(({default: scrollHelper}) => {
scrollHelper = scrollHelper.default || scrollHelper; const fn = on ? 'on' : 'off';
var fn = on ? 'on' : 'off';
scrollHelper.centerFocus[fn](elem, horiz); scrollHelper.centerFocus[fn](elem, horiz);
}); });
} }
function fillSortBy(context, options) { function fillSortBy(context, options) {
var selectSortBy = context.querySelector('.selectSortBy'); const selectSortBy = context.querySelector('.selectSortBy');
selectSortBy.innerHTML = options.map(function (o) { selectSortBy.innerHTML = options.map(function (o) {
return '<option value="' + o.value + '">' + o.name + '</option>'; return '<option value="' + o.value + '">' + o.name + '</option>';
}).join(''); }).join('');
} }
function saveValues(context, settings, settingsKey) { function saveValues(context, settingsKey) {
userSettings.setFilter(settingsKey + '-sortorder', context.querySelector('.selectSortOrder').value); userSettings.setFilter(settingsKey + '-sortorder', context.querySelector('.selectSortOrder').value);
userSettings.setFilter(settingsKey + '-sortby', context.querySelector('.selectSortBy').value); userSettings.setFilter(settingsKey + '-sortby', context.querySelector('.selectSortBy').value);
} }
function SortMenu() { class SortMenu {
show(options) {
}
SortMenu.prototype.show = function (options) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
require(['text!./sortmenu.template.html'], function (template) { import('text!./sortmenu.template.html').then(({default: template}) => {
var dialogOptions = { const dialogOptions = {
removeOnClose: true, removeOnClose: true,
scrollY: false scrollY: false
}; };
@ -55,11 +56,11 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana
dialogOptions.size = 'small'; dialogOptions.size = 'small';
} }
var dlg = dialogHelper.createDialog(dialogOptions); const dlg = dialogHelper.createDialog(dialogOptions);
dlg.classList.add('formDialog'); dlg.classList.add('formDialog');
var html = ''; let html = '';
html += '<div class="formDialogHeader">'; html += '<div class="formDialogHeader">';
html += '<button is="paper-icon-button-light" class="btnCancel hide-mouse-idle-tv" tabindex="-1"><span class="material-icons arrow_back"></span></button>'; html += '<button is="paper-icon-button-light" class="btnCancel hide-mouse-idle-tv" tabindex="-1"><span class="material-icons arrow_back"></span></button>';
@ -82,7 +83,7 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana
centerFocus(dlg.querySelector('.formDialogContent'), false, true); centerFocus(dlg.querySelector('.formDialogContent'), false, true);
} }
var submitted; let submitted;
dlg.querySelector('form').addEventListener('change', function () { dlg.querySelector('form').addEventListener('change', function () {
submitted = true; submitted = true;
@ -94,7 +95,7 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana
} }
if (submitted) { if (submitted) {
saveValues(dlg, options.settings, options.settingsKey); saveValues(dlg, options.settingsKey);
resolve(); resolve();
return; return;
} }
@ -103,7 +104,7 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana
}); });
}); });
}); });
}; }
}
return SortMenu; export default SortMenu;
});

View file

@ -1,43 +1,43 @@
define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'emby-button'], function ($, loading, libraryMenu, globalize, connectionManager) { import $ from 'jQuery';
'use strict'; import loading from 'loading';
import globalize from 'globalize';
import 'emby-button';
loading = loading.default || loading; function populateHistory(packageInfo, page) {
let html = '';
const length = Math.min(packageInfo.versions.length, 10);
function populateHistory(packageInfo, page) { for (let i = 0; i < length; i++) {
var html = ''; let version = packageInfo.versions[i];
var length = Math.min(packageInfo.versions.length, 10);
for (var i = 0; i < length; i++) {
var version = packageInfo.versions[i];
html += '<h2 style="margin:.5em 0;">' + version.version + '</h2>'; html += '<h2 style="margin:.5em 0;">' + version.version + '</h2>';
html += '<div style="margin-bottom:1.5em;">' + version.changelog + '</div>'; html += '<div style="margin-bottom:1.5em;">' + version.changelog + '</div>';
} }
$('#revisionHistory', page).html(html); $('#revisionHistory', page).html(html);
} }
function populateVersions(packageInfo, page, installedPlugin) { function populateVersions(packageInfo, page, installedPlugin) {
var html = ''; let html = '';
for (var i = 0; i < packageInfo.versions.length; i++) { for (let i = 0; i < packageInfo.versions.length; i++) {
var version = packageInfo.versions[i]; const version = packageInfo.versions[i];
html += '<option value="' + version.version + '">' + version.version + '</option>'; html += '<option value="' + version.version + '">' + version.version + '</option>';
} }
var selectmenu = $('#selectVersion', page).html(html); const selectmenu = $('#selectVersion', page).html(html);
if (!installedPlugin) { if (!installedPlugin) {
$('#pCurrentVersion', page).hide().html(''); $('#pCurrentVersion', page).hide().html('');
} }
var packageVersion = packageInfo.versions[0]; const packageVersion = packageInfo.versions[0];
if (packageVersion) { if (packageVersion) {
selectmenu.val(packageVersion.version); selectmenu.val(packageVersion.version);
} }
} }
function renderPackage(pkg, installedPlugins, page) { function renderPackage(pkg, installedPlugins, page) {
var installedPlugin = installedPlugins.filter(function (ip) { const installedPlugin = installedPlugins.filter(function (ip) {
return ip.Name == pkg.name; return ip.Name == pkg.name;
})[0]; })[0];
@ -58,64 +58,66 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'e
$('#developer', page).html(pkg.owner); $('#developer', page).html(pkg.owner);
if (installedPlugin) { if (installedPlugin) {
var currentVersionText = globalize.translate('MessageYouHaveVersionInstalled', '<strong>' + installedPlugin.Version + '</strong>'); const currentVersionText = globalize.translate('MessageYouHaveVersionInstalled', '<strong>' + installedPlugin.Version + '</strong>');
$('#pCurrentVersion', page).show().html(currentVersionText); $('#pCurrentVersion', page).show().html(currentVersionText);
} else { } else {
$('#pCurrentVersion', page).hide().html(''); $('#pCurrentVersion', page).hide().html('');
} }
loading.hide(); loading.hide();
} }
function alertText(options) { function alertText(options) {
require(['alert'], function ({default: alert}) { import('alert').then(({default: alert}) => {
alert(options); alert(options);
}); });
} }
function performInstallation(page, name, guid, version) { function performInstallation(page, name, guid, version) {
var developer = $('#developer', page).html().toLowerCase(); const developer = $('#developer', page).html().toLowerCase();
var alertCallback = function () { const alertCallback = function () {
loading.show(); loading.show();
page.querySelector('#btnInstall').disabled = true; page.querySelector('#btnInstall').disabled = true;
ApiClient.installPlugin(name, guid, version).then(function () { ApiClient.installPlugin(name, guid, version).then(() => {
loading.hide(); loading.hide();
alertText(globalize.translate('MessagePluginInstalled')); alertText(globalize.translate('MessagePluginInstalled'));
}).catch(() => {
alertText(globalize.translate('MessagePluginInstallError'));
}); });
}; };
if (developer !== 'jellyfin') { if (developer !== 'jellyfin') {
loading.hide(); loading.hide();
var msg = globalize.translate('MessagePluginInstallDisclaimer'); let msg = globalize.translate('MessagePluginInstallDisclaimer');
msg += '<br/>'; msg += '<br/>';
msg += '<br/>'; msg += '<br/>';
msg += globalize.translate('PleaseConfirmPluginInstallation'); msg += globalize.translate('PleaseConfirmPluginInstallation');
require(['confirm'], function (confirm) { import('confirm').then(({default: confirm}) => {
confirm.default(msg, globalize.translate('HeaderConfirmPluginInstallation')).then(function () { confirm(msg, globalize.translate('HeaderConfirmPluginInstallation')).then(function () {
alertCallback(); alertCallback();
}, function () { }).catch(() => {
console.debug('plugin not installed'); console.debug('plugin not installed');
}); });
}); });
} else { } else {
alertCallback(); alertCallback();
} }
} }
return function (view, params) { export default function(view, params) {
$('.addPluginForm', view).on('submit', function () { $('.addPluginForm', view).on('submit', function () {
loading.show(); loading.show();
var page = $(this).parents('#addPluginPage')[0]; const page = $(this).parents('#addPluginPage')[0];
var name = params.name; const name = params.name;
var guid = params.guid; const guid = params.guid;
ApiClient.getInstalledPlugins().then(function (plugins) { ApiClient.getInstalledPlugins().then(function (plugins) {
var installedPlugin = plugins.filter(function (plugin) { const installedPlugin = plugins.filter(function (plugin) {
return plugin.Name == name; return plugin.Name == name;
})[0]; })[0];
var version = $('#selectVersion', page).val(); const version = $('#selectVersion', page).val();
if (installedPlugin && installedPlugin.Version === version) { if (installedPlugin && installedPlugin.Version === version) {
loading.hide(); loading.hide();
Dashboard.alert({ Dashboard.alert({
@ -125,19 +127,20 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'e
} else { } else {
performInstallation(page, name, guid, version); performInstallation(page, name, guid, version);
} }
}).catch(() => {
alertText(globalize.translate('MessageGetInstalledPluginsError'));
}); });
return false; return false;
}); });
view.addEventListener('viewshow', function () { view.addEventListener('viewshow', function () {
var page = this; const page = this;
loading.show(); loading.show();
var name = params.name; const name = params.name;
var guid = params.guid; const guid = params.guid;
var promise1 = ApiClient.getPackageInfo(name, guid); const promise1 = ApiClient.getPackageInfo(name, guid);
var promise2 = ApiClient.getInstalledPlugins(); const promise2 = ApiClient.getInstalledPlugins();
Promise.all([promise1, promise2]).then(function (responses) { Promise.all([promise1, promise2]).then(function (responses) {
renderPackage(responses[0], responses[1], page); renderPackage(responses[0], responses[1], page);
}); });
}); });
}; }
});

View file

@ -1,13 +1,15 @@
define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby-checkbox', 'emby-select'], function (loading, libraryMenu, globalize) { import loading from 'loading';
'use strict'; import libraryMenu from 'libraryMenu';
import globalize from 'globalize';
import 'cardStyle';
import 'emby-button';
import 'emby-checkbox';
import 'emby-select';
libraryMenu = libraryMenu.default || libraryMenu; function reloadList(page) {
loading = loading.default || loading;
function reloadList(page) {
loading.show(); loading.show();
var promise1 = ApiClient.getAvailablePlugins(); const promise1 = ApiClient.getAvailablePlugins();
var promise2 = ApiClient.getInstalledPlugins(); const promise2 = ApiClient.getInstalledPlugins();
Promise.all([promise1, promise2]).then(function (responses) { Promise.all([promise1, promise2]).then(function (responses) {
populateList({ populateList({
catalogElement: page.querySelector('#pluginTiles'), catalogElement: page.querySelector('#pluginTiles'),
@ -16,10 +18,11 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
installedPlugins: responses[1] installedPlugins: responses[1]
}); });
}); });
} }
function getHeaderText(category) { function getHeaderText(category) {
category = category.replace(' ', ''); category = category.replace(' ', '');
// TODO: Replace with switch
if (category === 'Channel') { if (category === 'Channel') {
category = 'Channels'; category = 'Channels';
} else if (category === 'Theme') { } else if (category === 'Theme') {
@ -31,11 +34,11 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
} }
return globalize.translate(category); return globalize.translate(category);
} }
function populateList(options) { function populateList(options) {
var availablePlugins = options.availablePlugins; const availablePlugins = options.availablePlugins;
var installedPlugins = options.installedPlugins; const installedPlugins = options.installedPlugins;
availablePlugins.forEach(function (plugin, index, array) { availablePlugins.forEach(function (plugin, index, array) {
plugin.category = plugin.category || 'General'; plugin.category = plugin.category || 'General';
@ -57,12 +60,12 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
return 0; return 0;
}); });
var currentCategory = null; let currentCategory = null;
var html = ''; let html = '';
for (var i = 0; i < availablePlugins.length; i++) { for (let i = 0; i < availablePlugins.length; i++) {
var plugin = availablePlugins[i]; const plugin = availablePlugins[i];
var category = plugin.categoryDisplayName; const category = plugin.categoryDisplayName;
if (category != currentCategory) { if (category != currentCategory) {
if (currentCategory) { if (currentCategory) {
html += '</div>'; html += '</div>';
@ -84,17 +87,17 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
options.catalogElement.innerHTML = html; options.catalogElement.innerHTML = html;
loading.hide(); loading.hide();
} }
function getPluginHtml(plugin, options, installedPlugins) { function getPluginHtml(plugin, options, installedPlugins) {
var html = ''; let html = '';
var href = plugin.externalUrl ? plugin.externalUrl : 'addplugin.html?name=' + encodeURIComponent(plugin.name) + '&guid=' + plugin.guid; let href = plugin.externalUrl ? plugin.externalUrl : 'addplugin.html?name=' + encodeURIComponent(plugin.name) + '&guid=' + plugin.guid;
if (options.context) { if (options.context) {
href += '&context=' + options.context; href += '&context=' + options.context;
} }
var target = plugin.externalUrl ? ' target="_blank"' : ''; const target = plugin.externalUrl ? ' target="_blank"' : '';
html += "<div class='card backdropCard'>"; html += "<div class='card backdropCard'>";
html += '<div class="cardBox visualCardBox">'; html += '<div class="cardBox visualCardBox">';
html += '<div class="cardScalable visualCardBox-cardScalable">'; html += '<div class="cardScalable visualCardBox-cardScalable">';
@ -107,7 +110,7 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
html += "<div class='cardText'>"; html += "<div class='cardText'>";
html += plugin.name; html += plugin.name;
html += '</div>'; html += '</div>';
var installedPlugin = installedPlugins.filter(function (ip) { const installedPlugin = installedPlugins.filter(function (ip) {
return ip.Id == plugin.guid; return ip.Id == plugin.guid;
})[0]; })[0];
html += "<div class='cardText cardText-secondary'>"; html += "<div class='cardText cardText-secondary'>";
@ -116,9 +119,9 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
html += '</div>'; html += '</div>';
html += '</div>'; html += '</div>';
return html += '</div>'; return html += '</div>';
} }
function getTabs() { function getTabs() {
return [{ return [{
href: 'installedplugins.html', href: 'installedplugins.html',
name: globalize.translate('TabMyPlugins') name: globalize.translate('TabMyPlugins')
@ -129,16 +132,11 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
href: 'repositories.html', href: 'repositories.html',
name: globalize.translate('TabRepositories') name: globalize.translate('TabRepositories')
}]; }];
} }
window.PluginCatalog = { export default function (view) {
renderCatalog: populateList
};
return function (view, params) {
view.addEventListener('viewshow', function () { view.addEventListener('viewshow', function () {
libraryMenu.setTabs('plugins', 1, getTabs); libraryMenu.setTabs('plugins', 1, getTabs);
reloadList(this); reloadList(this);
}); });
}; }
});

View file

@ -1,13 +1,14 @@
define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'], function (loading, libraryMenu, dom, globalize) { import loading from 'loading';
'use strict'; import libraryMenu from 'libraryMenu';
import dom from 'dom';
import globalize from 'globalize';
import 'cardStyle';
import 'emby-button';
libraryMenu = libraryMenu.default || libraryMenu; function deletePlugin(page, uniqueid, name) {
loading = loading.default || loading; const msg = globalize.translate('UninstallPluginConfirmation', name);
function deletePlugin(page, uniqueid, name) { import('confirm').then(({default: confirm}) => {
var msg = globalize.translate('UninstallPluginConfirmation', name);
require(['confirm'], function (confirm) {
confirm.default({ confirm.default({
title: globalize.translate('HeaderUninstallPlugin'), title: globalize.translate('HeaderUninstallPlugin'),
text: msg, text: msg,
@ -20,26 +21,26 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'
}); });
}); });
}); });
} }
function showNoConfigurationMessage() { function showNoConfigurationMessage() {
Dashboard.alert({ Dashboard.alert({
message: globalize.translate('MessageNoPluginConfiguration') message: globalize.translate('MessageNoPluginConfiguration')
}); });
} }
function showConnectMessage() { function showConnectMessage() {
Dashboard.alert({ Dashboard.alert({
message: globalize.translate('MessagePluginConfigurationRequiresLocalAccess') message: globalize.translate('MessagePluginConfigurationRequiresLocalAccess')
}); });
} }
function getPluginCardHtml(plugin, pluginConfigurationPages) { function getPluginCardHtml(plugin, pluginConfigurationPages) {
var configPage = pluginConfigurationPages.filter(function (pluginConfigurationPage) { const configPage = pluginConfigurationPages.filter(function (pluginConfigurationPage) {
return pluginConfigurationPage.PluginId == plugin.Id; return pluginConfigurationPage.PluginId == plugin.Id;
})[0]; })[0];
var configPageUrl = configPage ? Dashboard.getConfigurationPageUrl(configPage.Name) : null; const configPageUrl = configPage ? Dashboard.getConfigurationPageUrl(configPage.Name) : null;
var html = ''; let html = '';
html += "<div data-id='" + plugin.Id + "' data-name='" + plugin.Name + "' data-removable='" + plugin.CanUninstall + "' class='card backdropCard'>"; html += "<div data-id='" + plugin.Id + "' data-name='" + plugin.Name + "' data-removable='" + plugin.CanUninstall + "' class='card backdropCard'>";
html += '<div class="cardBox visualCardBox">'; html += '<div class="cardBox visualCardBox">';
html += '<div class="cardScalable">'; html += '<div class="cardScalable">';
@ -66,15 +67,15 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'
html += '</div>'; html += '</div>';
html += '</div>'; html += '</div>';
return html; return html;
} }
function renderPlugins(page, plugins) { function renderPlugins(page, plugins) {
ApiClient.getJSON(ApiClient.getUrl('web/configurationpages') + '?pageType=PluginConfiguration').then(function (configPages) { ApiClient.getJSON(ApiClient.getUrl('web/configurationpages') + '?pageType=PluginConfiguration').then(function (configPages) {
populateList(page, plugins, configPages); populateList(page, plugins, configPages);
}); });
} }
function populateList(page, plugins, pluginConfigurationPages) { function populateList(page, plugins, pluginConfigurationPages) {
plugins = plugins.sort(function (plugin1, plugin2) { plugins = plugins.sort(function (plugin1, plugin2) {
if (plugin1.Name > plugin2.Name) { if (plugin1.Name > plugin2.Name) {
return 1; return 1;
@ -83,11 +84,11 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'
return -1; return -1;
}); });
var html = plugins.map(function (p) { let html = plugins.map(function (p) {
return getPluginCardHtml(p, pluginConfigurationPages); return getPluginCardHtml(p, pluginConfigurationPages);
}).join(''); }).join('');
var installedPluginsElement = page.querySelector('.installedPlugins'); const installedPluginsElement = page.querySelector('.installedPlugins');
installedPluginsElement.removeEventListener('click', onInstalledPluginsClick); installedPluginsElement.removeEventListener('click', onInstalledPluginsClick);
installedPluginsElement.addEventListener('click', onInstalledPluginsClick); installedPluginsElement.addEventListener('click', onInstalledPluginsClick);
@ -105,15 +106,15 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'
installedPluginsElement.innerHTML = html; installedPluginsElement.innerHTML = html;
loading.hide(); loading.hide();
} }
function showPluginMenu(page, elem) { function showPluginMenu(page, elem) {
var card = dom.parentWithClass(elem, 'card'); const card = dom.parentWithClass(elem, 'card');
var id = card.getAttribute('data-id'); const id = card.getAttribute('data-id');
var name = card.getAttribute('data-name'); const name = card.getAttribute('data-name');
var removable = card.getAttribute('data-removable'); const removable = card.getAttribute('data-removable');
var configHref = card.querySelector('.cardContent').getAttribute('href'); const configHref = card.querySelector('.cardContent').getAttribute('href');
var menuItems = []; const menuItems = [];
if (configHref) { if (configHref) {
menuItems.push({ menuItems.push({
@ -131,7 +132,7 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'
}); });
} }
require(['actionsheet'], function (actionsheet) { import('actionsheet').then(({default: actionsheet}) => {
actionsheet.show({ actionsheet.show({
items: menuItems, items: menuItems,
positionTo: elem, positionTo: elem,
@ -147,16 +148,16 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'
} }
}); });
}); });
} }
function reloadList(page) { function reloadList(page) {
loading.show(); loading.show();
ApiClient.getInstalledPlugins().then(function (plugins) { ApiClient.getInstalledPlugins().then(function (plugins) {
renderPlugins(page, plugins); renderPlugins(page, plugins);
}); });
} }
function getTabs() { function getTabs() {
return [{ return [{
href: 'installedplugins.html', href: 'installedplugins.html',
name: globalize.translate('TabMyPlugins') name: globalize.translate('TabMyPlugins')
@ -167,27 +168,26 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'
href: 'repositories.html', href: 'repositories.html',
name: globalize.translate('TabRepositories') name: globalize.translate('TabRepositories')
}]; }];
} }
function onInstalledPluginsClick(e) { function onInstalledPluginsClick(e) {
if (dom.parentWithClass(e.target, 'noConfigPluginCard')) { if (dom.parentWithClass(e.target, 'noConfigPluginCard')) {
showNoConfigurationMessage(); showNoConfigurationMessage();
} else if (dom.parentWithClass(e.target, 'connectModePluginCard')) { } else if (dom.parentWithClass(e.target, 'connectModePluginCard')) {
showConnectMessage(); showConnectMessage();
} else { } else {
var btnCardMenu = dom.parentWithClass(e.target, 'btnCardMenu'); const btnCardMenu = dom.parentWithClass(e.target, 'btnCardMenu');
if (btnCardMenu) { if (btnCardMenu) {
showPluginMenu(dom.parentWithClass(btnCardMenu, 'page'), btnCardMenu); showPluginMenu(dom.parentWithClass(btnCardMenu, 'page'), btnCardMenu);
} }
} }
} }
pageIdOn('pageshow', 'pluginsPage', function () { pageIdOn('pageshow', 'pluginsPage', function () {
libraryMenu.setTabs('plugins', 0, getTabs); libraryMenu.setTabs('plugins', 0, getTabs);
reloadList(this); reloadList(this);
});
window.PluginsPage = {
renderPlugins: renderPlugins
};
}); });
window.PluginsPage = {
renderPlugins: renderPlugins
};

View file

@ -137,8 +137,7 @@
} }
@media screen @media screen
and (min-device-width: 992px) and (min-device-width: 992px) {
and (-webkit-min-device-pixel-ratio: 1) {
.splashLogo { .splashLogo {
background-image: url(assets/img/banner-light.png); background-image: url(assets/img/banner-light.png);
} }

View file

@ -1,16 +1,17 @@
define(['pluginManager'], function (pluginManager) { import pluginManager from 'pluginManager';
return function () {
var self = this; export default function () {
const self = this;
self.name = 'Logo ScreenSaver'; self.name = 'Logo ScreenSaver';
self.type = 'screensaver'; self.type = 'screensaver';
self.id = 'logoscreensaver'; self.id = 'logoscreensaver';
self.supportsAnonymous = true; self.supportsAnonymous = true;
var interval; let interval;
function animate() { function animate() {
var animations = [ const animations = [
bounceInLeft, bounceInLeft,
bounceInRight, bounceInRight,
@ -21,10 +22,10 @@ define(['pluginManager'], function (pluginManager) {
rotateOut rotateOut
]; ];
var elem = document.querySelector('.logoScreenSaverImage'); const elem = document.querySelector('.logoScreenSaverImage');
if (elem && elem.animate) { if (elem && elem.animate) {
var random = getRandomInt(0, animations.length - 1); const random = getRandomInt(0, animations.length - 1);
animations[random](elem, 1); animations[random](elem, 1);
} }
@ -35,41 +36,41 @@ define(['pluginManager'], function (pluginManager) {
} }
function bounceInLeft(elem, iterations) { function bounceInLeft(elem, iterations) {
var keyframes = [ const keyframes = [
{ transform: 'translate3d(-3000px, 0, 0)', opacity: '0', offset: 0 }, { transform: 'translate3d(-3000px, 0, 0)', opacity: '0', offset: 0 },
{ transform: 'translate3d(25px, 0, 0)', opacity: '1', offset: 0.6 }, { transform: 'translate3d(25px, 0, 0)', opacity: '1', offset: 0.6 },
{ transform: 'translate3d(-100px, 0, 0)', offset: 0.75 }, { transform: 'translate3d(-100px, 0, 0)', offset: 0.75 },
{ transform: 'translate3d(5px, 0, 0)', offset: 0.9 }, { transform: 'translate3d(5px, 0, 0)', offset: 0.9 },
{ transform: 'none', opacity: '1', offset: 1 }]; { transform: 'none', opacity: '1', offset: 1 }];
var timing = { duration: 900, iterations: iterations, easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' }; const timing = { duration: 900, iterations: iterations, easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' };
return elem.animate(keyframes, timing); return elem.animate(keyframes, timing);
} }
function bounceInRight(elem, iterations) { function bounceInRight(elem, iterations) {
var keyframes = [ const keyframes = [
{ transform: 'translate3d(3000px, 0, 0)', opacity: '0', offset: 0 }, { transform: 'translate3d(3000px, 0, 0)', opacity: '0', offset: 0 },
{ transform: 'translate3d(-25px, 0, 0)', opacity: '1', offset: 0.6 }, { transform: 'translate3d(-25px, 0, 0)', opacity: '1', offset: 0.6 },
{ transform: 'translate3d(100px, 0, 0)', offset: 0.75 }, { transform: 'translate3d(100px, 0, 0)', offset: 0.75 },
{ transform: 'translate3d(-5px, 0, 0)', offset: 0.9 }, { transform: 'translate3d(-5px, 0, 0)', offset: 0.9 },
{ transform: 'none', opacity: '1', offset: 1 }]; { transform: 'none', opacity: '1', offset: 1 }];
var timing = { duration: 900, iterations: iterations, easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' }; const timing = { duration: 900, iterations: iterations, easing: 'cubic-bezier(0.215, 0.610, 0.355, 1.000)' };
return elem.animate(keyframes, timing); return elem.animate(keyframes, timing);
} }
function swing(elem, iterations) { function swing(elem, iterations) {
var keyframes = [ const keyframes = [
{ transform: 'translate(0%)', offset: 0 }, { transform: 'translate(0%)', offset: 0 },
{ transform: 'rotate3d(0, 0, 1, 15deg)', offset: 0.2 }, { transform: 'rotate3d(0, 0, 1, 15deg)', offset: 0.2 },
{ transform: 'rotate3d(0, 0, 1, -10deg)', offset: 0.4 }, { transform: 'rotate3d(0, 0, 1, -10deg)', offset: 0.4 },
{ transform: 'rotate3d(0, 0, 1, 5deg)', offset: 0.6 }, { transform: 'rotate3d(0, 0, 1, 5deg)', offset: 0.6 },
{ transform: 'rotate3d(0, 0, 1, -5deg)', offset: 0.8 }, { transform: 'rotate3d(0, 0, 1, -5deg)', offset: 0.8 },
{ transform: 'rotate3d(0, 0, 1, 0deg)', offset: 1 }]; { transform: 'rotate3d(0, 0, 1, 0deg)', offset: 1 }];
var timing = { duration: 900, iterations: iterations }; const timing = { duration: 900, iterations: iterations };
return elem.animate(keyframes, timing); return elem.animate(keyframes, timing);
} }
function tada(elem, iterations) { function tada(elem, iterations) {
var keyframes = [ const keyframes = [
{ transform: 'scale3d(1, 1, 1)', offset: 0 }, { transform: 'scale3d(1, 1, 1)', offset: 0 },
{ transform: 'scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)', offset: 0.1 }, { transform: 'scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)', offset: 0.1 },
{ transform: 'scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)', offset: 0.2 }, { transform: 'scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)', offset: 0.2 },
@ -81,41 +82,41 @@ define(['pluginManager'], function (pluginManager) {
{ transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)', offset: 0.8 }, { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)', offset: 0.8 },
{ transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.9 }, { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)', offset: 0.9 },
{ transform: 'scale3d(1, 1, 1)', offset: 1 }]; { transform: 'scale3d(1, 1, 1)', offset: 1 }];
var timing = { duration: 900, iterations: iterations }; const timing = { duration: 900, iterations: iterations };
return elem.animate(keyframes, timing); return elem.animate(keyframes, timing);
} }
function wobble(elem, iterations) { function wobble(elem, iterations) {
var keyframes = [ const keyframes = [
{ transform: 'translate(0%)', offset: 0 }, { transform: 'translate(0%)', offset: 0 },
{ transform: 'translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg)', offset: 0.15 }, { transform: 'translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg)', offset: 0.15 },
{ transform: 'translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg)', offset: 0.45 }, { transform: 'translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg)', offset: 0.45 },
{ transform: 'translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg)', offset: 0.6 }, { transform: 'translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg)', offset: 0.6 },
{ transform: 'translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg)', offset: 0.75 }, { transform: 'translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg)', offset: 0.75 },
{ transform: 'translateX(0%)', offset: 1 }]; { transform: 'translateX(0%)', offset: 1 }];
var timing = { duration: 900, iterations: iterations }; const timing = { duration: 900, iterations: iterations };
return elem.animate(keyframes, timing); return elem.animate(keyframes, timing);
} }
function rotateIn(elem, iterations) { function rotateIn(elem, iterations) {
var keyframes = [{ transform: 'rotate3d(0, 0, 1, -200deg)', opacity: '0', transformOrigin: 'center', offset: 0 }, const keyframes = [{ transform: 'rotate3d(0, 0, 1, -200deg)', opacity: '0', transformOrigin: 'center', offset: 0 },
{ transform: 'none', opacity: '1', transformOrigin: 'center', offset: 1 }]; { transform: 'none', opacity: '1', transformOrigin: 'center', offset: 1 }];
var timing = { duration: 900, iterations: iterations }; const timing = { duration: 900, iterations: iterations };
return elem.animate(keyframes, timing); return elem.animate(keyframes, timing);
} }
function rotateOut(elem, iterations) { function rotateOut(elem, iterations) {
var keyframes = [{ transform: 'none', opacity: '1', transformOrigin: 'center', offset: 0 }, const keyframes = [{ transform: 'none', opacity: '1', transformOrigin: 'center', offset: 0 },
{ transform: 'rotate3d(0, 0, 1, 200deg)', opacity: '0', transformOrigin: 'center', offset: 1 }]; { transform: 'rotate3d(0, 0, 1, 200deg)', opacity: '0', transformOrigin: 'center', offset: 1 }];
var timing = { duration: 900, iterations: iterations }; const timing = { duration: 900, iterations: iterations };
return elem.animate(keyframes, timing); return elem.animate(keyframes, timing);
} }
function fadeOut(elem, iterations) { function fadeOut(elem, iterations) {
var keyframes = [ const keyframes = [
{ opacity: '1', offset: 0 }, { opacity: '1', offset: 0 },
{ opacity: '0', offset: 1 }]; { opacity: '0', offset: 1 }];
var timing = { duration: 400, iterations: iterations }; const timing = { duration: 400, iterations: iterations };
return elem.animate(keyframes, timing); return elem.animate(keyframes, timing);
} }
@ -127,8 +128,8 @@ define(['pluginManager'], function (pluginManager) {
} }
self.show = function () { self.show = function () {
require(['css!' + pluginManager.mapPath(self, 'style.css')], function () { import('css!' + pluginManager.mapPath(self, 'style.css')).then(() => {
var elem = document.querySelector('.logoScreenSaver'); let elem = document.querySelector('.logoScreenSaver');
if (!elem) { if (!elem) {
elem = document.createElement('div'); elem = document.createElement('div');
@ -146,20 +147,19 @@ define(['pluginManager'], function (pluginManager) {
self.hide = function () { self.hide = function () {
stopInterval(); stopInterval();
var elem = document.querySelector('.logoScreenSaver'); const elem = document.querySelector('.logoScreenSaver');
if (elem) { if (elem) {
var onAnimationFinish = function () { const onAnimationFinish = function () {
elem.parentNode.removeChild(elem); elem.parentNode.removeChild(elem);
}; };
if (elem.animate) { if (elem.animate) {
var animation = fadeOut(elem, 1); const animation = fadeOut(elem, 1);
animation.onfinish = onAnimationFinish; animation.onfinish = onAnimationFinish;
} else { } else {
onAnimationFinish(); onAnimationFinish();
} }
} }
}; };
}; }
});

View file

@ -1,33 +1,26 @@
define(['connectionManager', 'globalize'], function (connectionManager, globalize) { import connectionManager from 'connectionManager';
'use strict'; import globalize from 'globalize';
function getRequirePromise(deps) { function showErrorMessage() {
return new Promise(function (resolve, reject) { return import('alert').then(({default: alert}) => {
require(deps, resolve); return alert(globalize.translate('MessagePlayAccessRestricted'));
}); });
} }
function showErrorMessage() { class PlayAccessValidation {
return getRequirePromise(['alert']).then(function (alert) { constructor() {
return alert(globalize.translate('MessagePlayAccessRestricted')).then(function () {
return Promise.reject();
});
});
}
function PlayAccessValidation() {
this.name = 'Playback validation'; this.name = 'Playback validation';
this.type = 'preplayintercept'; this.type = 'preplayintercept';
this.id = 'playaccessvalidation'; this.id = 'playaccessvalidation';
this.order = -2; this.order = -2;
} }
PlayAccessValidation.prototype.intercept = function (options) { intercept(options) {
var item = options.item; const item = options.item;
if (!item) { if (!item) {
return Promise.resolve(); return Promise.resolve();
} }
var serverId = item.ServerId; const serverId = item.ServerId;
if (!serverId) { if (!serverId) {
return Promise.resolve(); return Promise.resolve();
} }
@ -44,7 +37,7 @@ define(['connectionManager', 'globalize'], function (connectionManager, globaliz
return showErrorMessage(); return showErrorMessage();
}); });
}; }
}
return PlayAccessValidation; export default PlayAccessValidation;
});

View file

@ -112,54 +112,69 @@ import 'detailtablecss';
}); });
defineRoute({ defineRoute({
path: '/dashboard.html', alias: '/dashboard.html',
path: '/controllers/dashboard/dashboard.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/dashboard' controller: 'dashboard/dashboard'
}); });
defineRoute({ defineRoute({
path: '/dashboardgeneral.html', alias: '/dashboardgeneral.html',
path: '/controllers/dashboard/general.html',
controller: 'dashboard/general', controller: 'dashboard/general',
autoFocus: false, autoFocus: false,
roles: 'admin' roles: 'admin'
}); });
defineRoute({ defineRoute({
path: '/networking.html', alias: '/networking.html',
path: '/controllers/dashboard/networking.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/networking' controller: 'dashboard/networking'
}); });
defineRoute({ defineRoute({
path: '/devices.html', alias: '/devices.html',
path: '/controllers/dashboard/devices/devices.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/devices/devices' controller: 'dashboard/devices/devices'
}); });
defineRoute({ defineRoute({
path: '/device.html', alias: '/device.html',
path: '/controllers/dashboard/devices/device.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/devices/device' controller: 'dashboard/devices/device'
}); });
defineRoute({ defineRoute({
path: '/dlnaprofile.html', alias: '/dlnaprofile.html',
path: '/controllers/dashboard/dlna/profile.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/dlna/profile' controller: 'dashboard/dlna/profile'
}); });
defineRoute({ defineRoute({
path: '/dlnaprofiles.html', alias: '/dlnaprofiles.html',
path: '/controllers/dashboard/dlna/profiles.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/dlna/profiles' controller: 'dashboard/dlna/profiles'
}); });
defineRoute({
alias: '/dlnasettings.html',
path: '/controllers/dashboard/dlna/settings.html',
autoFocus: false,
roles: 'admin',
controller: 'dashboard/dlna/settings'
});
defineRoute({ defineRoute({
alias: '/addplugin.html', alias: '/addplugin.html',
path: '/controllers/dashboard/plugins/add/index.html', path: '/controllers/dashboard/plugins/add/index.html',
@ -169,54 +184,54 @@ import 'detailtablecss';
}); });
defineRoute({ defineRoute({
path: '/library.html', alias: '/library.html',
path: '/controllers/dashboard/library.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/mediaLibrary' controller: 'dashboard/library'
}); });
defineRoute({ defineRoute({
path: '/librarydisplay.html', alias: '/librarydisplay.html',
path: '/controllers/dashboard/librarydisplay.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/librarydisplay' controller: 'dashboard/librarydisplay'
}); });
defineRoute({ defineRoute({
path: '/dlnasettings.html', alias: '/edititemmetadata.html',
autoFocus: false, path: '/controllers/edititemmetadata.html',
roles: 'admin',
controller: 'dashboard/dlna/settings'
});
defineRoute({
path: '/edititemmetadata.html',
controller: 'edititemmetadata', controller: 'edititemmetadata',
autoFocus: false autoFocus: false
}); });
defineRoute({ defineRoute({
path: '/encodingsettings.html', alias: '/encodingsettings.html',
path: '/controllers/dashboard/encodingsettings.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/encodingsettings' controller: 'dashboard/encodingsettings'
}); });
defineRoute({ defineRoute({
path: '/log.html', alias: '/log.html',
path: '/controllers/dashboard/logs.html',
roles: 'admin', roles: 'admin',
controller: 'dashboard/logs' controller: 'dashboard/logs'
}); });
defineRoute({ defineRoute({
path: '/metadataimages.html', alias: '/metadataimages.html',
path: '/controllers/dashboard/metadataimages.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/metadataImages' controller: 'dashboard/metadataImages'
}); });
defineRoute({ defineRoute({
path: '/metadatanfo.html', alias: '/metadatanfo.html',
path: '/controllers/dashboard/metadatanfo.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/metadatanfo' controller: 'dashboard/metadatanfo'
@ -239,7 +254,8 @@ import 'detailtablecss';
}); });
defineRoute({ defineRoute({
path: '/playbackconfiguration.html', alias: '/playbackconfiguration.html',
path: '/controllers/dashboard/playback.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/playback' controller: 'dashboard/playback'
@ -262,19 +278,22 @@ import 'detailtablecss';
}); });
defineRoute({ defineRoute({
path: '/home.html', alias: '/home.html',
path: '/controllers/home.html',
autoFocus: false, autoFocus: false,
controller: 'home', controller: 'home',
type: 'home' type: 'home'
}); });
defineRoute({ defineRoute({
path: '/search.html', alias: '/search.html',
path: '/controllers/search.html',
controller: 'searchpage' controller: 'searchpage'
}); });
defineRoute({ defineRoute({
path: '/list.html', alias: '/list.html',
path: '/controllers/list.html',
autoFocus: false, autoFocus: false,
controller: 'list' controller: 'list'
}); });
@ -287,46 +306,53 @@ import 'detailtablecss';
}); });
defineRoute({ defineRoute({
path: '/livetv.html', alias: '/livetv.html',
path: '/controllers/livetv.html',
controller: 'livetv/livetvsuggested', controller: 'livetv/livetvsuggested',
autoFocus: false autoFocus: false
}); });
defineRoute({ defineRoute({
path: '/livetvguideprovider.html', alias: '/livetvguideprovider.html',
path: '/controllers/livetvguideprovider.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'livetvguideprovider' controller: 'livetvguideprovider'
}); });
defineRoute({ defineRoute({
path: '/livetvsettings.html', alias: '/livetvsettings.html',
path: '/controllers/livetvsettings.html',
autoFocus: false, autoFocus: false,
controller: 'livetvsettings' controller: 'livetvsettings'
}); });
defineRoute({ defineRoute({
path: '/livetvstatus.html', alias: '/livetvstatus.html',
path: '/controllers/livetvstatus.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'livetvstatus' controller: 'livetvstatus'
}); });
defineRoute({ defineRoute({
path: '/livetvtuner.html', alias: '/livetvtuner.html',
path: '/controllers/livetvtuner.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'livetvtuner' controller: 'livetvtuner'
}); });
defineRoute({ defineRoute({
path: '/movies.html', alias: '/movies.html',
path: '/controllers/movies/movies.html',
autoFocus: false, autoFocus: false,
controller: 'movies/moviesrecommended' controller: 'movies/moviesrecommended'
}); });
defineRoute({ defineRoute({
path: '/music.html', alias: '/music.html',
path: '/controllers/music/music.html',
controller: 'music/musicrecommended', controller: 'music/musicrecommended',
autoFocus: false autoFocus: false
}); });
@ -340,82 +366,94 @@ import 'detailtablecss';
}); });
defineRoute({ defineRoute({
path: '/scheduledtask.html', alias: '/scheduledtask.html',
path: '/controllers/dashboard/scheduledtasks/scheduledtask.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/scheduledtasks/scheduledtask' controller: 'dashboard/scheduledtasks/scheduledtask'
}); });
defineRoute({ defineRoute({
path: '/scheduledtasks.html', alias: '/scheduledtasks.html',
path: '/controllers/dashboard/scheduledtasks/scheduledtasks.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/scheduledtasks/scheduledtasks' controller: 'dashboard/scheduledtasks/scheduledtasks'
}); });
defineRoute({ defineRoute({
path: '/serveractivity.html', alias: '/serveractivity.html',
path: '/controllers/dashboard/serveractivity.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/serveractivity' controller: 'dashboard/serveractivity'
}); });
defineRoute({ defineRoute({
path: '/apikeys.html', alias: '/apikeys.html',
path: '/controllers/dashboard/apikeys.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/apikeys' controller: 'dashboard/apikeys'
}); });
defineRoute({ defineRoute({
path: '/streamingsettings.html', alias: '/streamingsettings.html',
path: '/controllers/dashboard/streaming.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/streaming' controller: 'dashboard/streaming'
}); });
defineRoute({ defineRoute({
path: '/tv.html', alias: '/tv.html',
path: '/controllers/shows/tvrecommended.html',
autoFocus: false, autoFocus: false,
controller: 'shows/tvrecommended' controller: 'shows/tvrecommended'
}); });
defineRoute({ defineRoute({
path: '/useredit.html', alias: '/useredit.html',
path: '/controllers/dashboard/users/useredit.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/users/useredit' controller: 'dashboard/users/useredit'
}); });
defineRoute({ defineRoute({
path: '/userlibraryaccess.html', alias: '/userlibraryaccess.html',
path: '/controllers/dashboard/users/userlibraryaccess.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/users/userlibraryaccess' controller: 'dashboard/users/userlibraryaccess'
}); });
defineRoute({ defineRoute({
path: '/usernew.html', alias: '/usernew.html',
path: '/controllers/dashboard/users/usernew.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/users/usernew' controller: 'dashboard/users/usernew'
}); });
defineRoute({ defineRoute({
path: '/userparentalcontrol.html', alias: '/userparentalcontrol.html',
path: '/controllers/dashboard/users/userparentalcontrol.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/users/userparentalcontrol' controller: 'dashboard/users/userparentalcontrol'
}); });
defineRoute({ defineRoute({
path: '/userpassword.html', alias: '/userpassword.html',
path: '/controllers/dashboard/users/userpassword.html',
autoFocus: false, autoFocus: false,
controller: 'dashboard/users/userpasswordpage' controller: 'dashboard/users/userpasswordpage'
}); });
defineRoute({ defineRoute({
path: '/userprofiles.html', alias: '/userprofiles.html',
path: '/controllers/dashboard/users/userprofiles.html',
autoFocus: false, autoFocus: false,
roles: 'admin', roles: 'admin',
controller: 'dashboard/users/userprofilespage' controller: 'dashboard/users/userprofilespage'
@ -438,10 +476,11 @@ import 'detailtablecss';
}); });
defineRoute({ defineRoute({
path: '/wizardlibrary.html', alias: '/wizardlibrary.html',
path: '/controllers/wizard/library.html',
autoFocus: false, autoFocus: false,
anonymous: true, anonymous: true,
controller: 'dashboard/mediaLibrary' controller: 'dashboard/library'
}); });
defineRoute({ defineRoute({

View file

@ -1545,5 +1545,7 @@
"LabelUnstable": "Instabil", "LabelUnstable": "Instabil",
"SubtitleVerticalPositionHelp": "Zeilennummer, in der der Text angezeigt wird. Positive Zahlen geben die Zeile von oben an. Negative Zahlen geben die Zeile von unten an.", "SubtitleVerticalPositionHelp": "Zeilennummer, in der der Text angezeigt wird. Positive Zahlen geben die Zeile von oben an. Negative Zahlen geben die Zeile von unten an.",
"Preview": "Vorschau", "Preview": "Vorschau",
"LabelSubtitleVerticalPosition": "Vertikale Position:" "LabelSubtitleVerticalPosition": "Vertikale Position:",
"MessageGetInstalledPluginsError": "Beim Abrufen der Liste der derzeit installierten Plugins ist ein Fehler aufgetreten.",
"MessagePluginInstallError": "Bei der Installation des Plugins ist ein Fehler aufgetreten."
} }

View file

@ -1282,6 +1282,8 @@
"PleaseRestartServerName": "Please restart Jellyfin Server - {0}.", "PleaseRestartServerName": "Please restart Jellyfin Server - {0}.",
"PleaseSelectTwoItems": "Please select at least two items.", "PleaseSelectTwoItems": "Please select at least two items.",
"MessagePluginInstalled": "The plugin has been successfully installed. Jellyfin Server will need to be restarted for changes to take effect.", "MessagePluginInstalled": "The plugin has been successfully installed. Jellyfin Server will need to be restarted for changes to take effect.",
"MessagePluginInstallError": "An error occured while installing the plugin.",
"MessageGetInstalledPluginsError": "An error occured while getting the list of currently installed plugins.",
"PreferEmbeddedTitlesOverFileNames": "Prefer embedded titles over filenames", "PreferEmbeddedTitlesOverFileNames": "Prefer embedded titles over filenames",
"PreferEmbeddedTitlesOverFileNamesHelp": "This determines the default display title when no internet metadata or local metadata is available.", "PreferEmbeddedTitlesOverFileNamesHelp": "This determines the default display title when no internet metadata or local metadata is available.",
"PreferEmbeddedEpisodeInfosOverFileNamesHelp": "This uses the episode information from the embedded metadata if available.", "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "This uses the episode information from the embedded metadata if available.",