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/sanatizefilename.js",
"src/components/scrollManager.js",
"src/components/slideshow/slideshow.js",
"src/components/sortmenu/sortmenu.js",
"src/plugins/htmlVideoPlayer/plugin.js",
"src/plugins/logoScreensaver/plugin.js",
"src/plugins/playAccessValidation/plugin.js",
"src/components/search/searchfields.js",
"src/components/search/searchresults.js",
"src/components/settingshelper.js",
@ -203,13 +207,16 @@
"src/controllers/music/musicplaylists.js",
"src/controllers/music/musicrecommended.js",
"src/controllers/music/songs.js",
"src/controllers/dashboard/mediaLibrary.js",
"src/controllers/dashboard/library.js",
"src/controllers/dashboard/metadataImages.js",
"src/controllers/dashboard/metadatanfo.js",
"src/controllers/dashboard/networking.js",
"src/controllers/dashboard/notifications/notification.js",
"src/controllers/dashboard/notifications/notifications.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/scheduledtasks/scheduledtask.js",
"src/controllers/dashboard/scheduledtasks/scheduledtasks.js",

View file

@ -2,32 +2,37 @@
* Image viewer component
* @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) {
'use strict';
import dialogHelper from 'dialogHelper';
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.
*/
const transitionEndEventName = dom.whichTransitionEvent();
const transitionEndEventName = dom.whichTransitionEvent();
/**
/**
* Flag to use fake image to fix blurry zoomed image.
* 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.
* @param {object|string} item - Item used to generate the image URL.
* @param {object} options - Options of the image.
* @param {object} apiClient - API client instance used to retrieve the image.
* @returns {null|string} URL of the item's image.
*/
function getImageUrl(item, options, apiClient) {
function getImageUrl(item, options, apiClient) {
options = options || {};
options.type = options.type || 'Primary';
@ -48,16 +53,16 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
return null;
}
}
/**
/**
* Retrieves a backdrop's image URL from the API.
* @param {object} item - Item used to generate the image URL.
* @param {object} options - Options of the image.
* @param {object} apiClient - API client instance used to retrieve the image.
* @returns {null|string} URL of the item's backdrop.
*/
function getBackdropImageUrl(item, options, apiClient) {
function getBackdropImageUrl(item, options, apiClient) {
options = options || {};
options.type = options.type || 'Backdrop';
@ -72,16 +77,16 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
return null;
}
}
/**
/**
* Dispatches a request for an item's image to its respective handler.
* @param {object} item - Item used to generate the image URL.
* @returns {string} URL of the item's image.
*/
function getImgUrl(item, user) {
var apiClient = connectionManager.getApiClient(item.ServerId);
var imageOptions = {};
function getImgUrl(item, user) {
const apiClient = connectionManager.getApiClient(item.ServerId);
const imageOptions = {};
if (item.BackdropImageTags && item.BackdropImageTags.length) {
return getBackdropImageUrl(item, imageOptions, apiClient);
@ -92,9 +97,9 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
imageOptions.type = 'Primary';
return getImageUrl(item, imageOptions, apiClient);
}
}
}
/**
/**
* Generates a button using the specified icon, classes and properties.
* @param {string} icon - Name of the material icon on 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.
* @returns {string} The HTML markup of the button.
*/
function getIcon(icon, cssClass, canFocus, autoFocus) {
var tabIndex = canFocus ? '' : ' tabindex="-1"';
function getIcon(icon, cssClass, canFocus, autoFocus) {
const tabIndex = canFocus ? '' : ' tabindex="-1"';
autoFocus = autoFocus ? ' autofocus' : '';
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.
* @param {boolean} scalable - Flag to set the scalability of the viewport.
*/
function setUserScalable(scalable) {
function setUserScalable(scalable) {
try {
appHost.setUserScalable(scalable);
} catch (err) {
console.error('error in appHost.setUserScalable: ' + err);
}
}
}
return function (options) {
var self = this;
export default function (options) {
const self = this;
/** Initialized instance of Swiper. */
var swiperInstance;
let swiperInstance;
/** Initialized instance of the dialog containing the Swiper instance. */
var dialog;
let dialog;
/** Options of the slideshow components */
var currentOptions;
let currentOptions;
/** ID of the timeout used to hide the OSD. */
var hideTimeout;
let hideTimeout;
/** Last coordinates of the mouse pointer. */
var lastMouseMoveData;
let lastMouseMoveData;
/**
* Creates the HTML markup for the dialog and the OSD.
@ -151,12 +156,12 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
dialog.classList.add('slideshowDialog');
var html = '';
let html = '';
html += '<div class="slideshowSwiperContainer"><div class="swiper-wrapper"></div></div>';
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_right', 'btnSlideshowNext slideshowButton hide-mouse-idle-tv', false);
@ -197,17 +202,17 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
dialogHelper.close(dialog);
});
var btnPause = dialog.querySelector('.btnSlideshowPause');
const btnPause = dialog.querySelector('.btnSlideshowPause');
if (btnPause) {
btnPause.addEventListener('click', playPause);
}
var btnDownload = dialog.querySelector('.btnDownload');
const btnDownload = dialog.querySelector('.btnDownload');
if (btnDownload) {
btnDownload.addEventListener('click', download);
}
var btnShare = dialog.querySelector('.btnShare');
const btnShare = dialog.querySelector('.btnShare');
if (btnShare) {
btnShare.addEventListener('click', share);
}
@ -232,7 +237,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Handles OSD changes when the autoplay is started.
*/
function onAutoplayStart() {
var btnSlideshowPause = dialog.querySelector('.btnSlideshowPause .material-icons');
const btnSlideshowPause = dialog.querySelector('.btnSlideshowPause .material-icons');
if (btnSlideshowPause) {
btnSlideshowPause.classList.replace('play_arrow', 'pause');
}
@ -242,7 +247,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Handles OSD changes when the autoplay is stopped.
*/
function onAutoplayStop() {
var btnSlideshowPause = dialog.querySelector('.btnSlideshowPause .material-icons');
const btnSlideshowPause = dialog.querySelector('.btnSlideshowPause .material-icons');
if (btnSlideshowPause) {
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.
*/
function loadSwiper(dialog, options) {
var slides;
let slides;
if (currentOptions.slides) {
slides = currentOptions.slides;
} else {
slides = currentOptions.items;
}
require(['swiper'], function (Swiper) {
import('swiper').then(({default: Swiper}) => {
swiperInstance = new Swiper(dialog.querySelector('.slideshowSwiperContainer'), {
direction: 'horizontal',
// 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.
*/
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-zoom-container">';
if (useFakeZoomImage) {
@ -405,7 +410,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
*/
function getCurrentImageInfo() {
if (swiperInstance) {
var slide = document.querySelector('.swiper-slide-active');
const slide = document.querySelector('.swiper-slide-active');
if (slide) {
return {
@ -425,9 +430,9 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Starts a download for the currently displayed slide.
*/
function download() {
var imageInfo = getCurrentImageInfo();
const imageInfo = getCurrentImageInfo();
require(['fileDownloader'], function (fileDownloader) {
import('fileDownloader').then(({default: fileDownloader}) => {
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.
*/
function share() {
var imageInfo = getCurrentImageInfo();
const imageInfo = getCurrentImageInfo();
navigator.share({
url: imageInfo.shareUrl
@ -465,7 +470,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Toggles the autoplay feature of the Swiper instance.
*/
function playPause() {
var paused = !dialog.querySelector('.btnSlideshowPause .material-icons').classList.contains('pause');
const paused = !dialog.querySelector('.btnSlideshowPause .material-icons').classList.contains('pause');
if (paused) {
play();
} else {
@ -477,7 +482,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Closes the dialog and destroys the Swiper instance.
*/
function onDialogClosed() {
var swiper = swiperInstance;
const swiper = swiperInstance;
if (swiper) {
swiper.destroy(true, true);
swiperInstance = null;
@ -495,7 +500,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Shows the OSD.
*/
function showOsd() {
var bottom = dialog.querySelector('.slideshowBottomBar');
const bottom = dialog.querySelector('.slideshowBottomBar');
if (bottom) {
slideUpToShow(bottom);
startHideTimer();
@ -506,7 +511,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* Hides the OSD.
*/
function hideOsd() {
var bottom = dialog.querySelector('.slideshowBottomBar');
const bottom = dialog.querySelector('.slideshowBottomBar');
if (bottom) {
slideDownToHide(bottom);
}
@ -541,7 +546,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
element.classList.remove('hide');
var onFinish = function () {
const onFinish = function () {
focusManager.focus(element.querySelector('.btnSlideshowPause'));
};
@ -551,11 +556,11 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
requestAnimationFrame(function () {
var keyframes = [
const keyframes = [
{ transform: 'translate3d(0,' + element.offsetHeight + 'px,0)', opacity: '.3', offset: 0 },
{ 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;
});
}
@ -569,7 +574,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
return;
}
var onFinish = function () {
const onFinish = function () {
element.classList.add('hide');
};
@ -579,11 +584,11 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
requestAnimationFrame(function () {
var keyframes = [
const keyframes = [
{ transform: 'translate3d(0,0,0)', opacity: '1', offset: 0 },
{ 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;
});
}
@ -593,13 +598,13 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
* @param {Event} event - Pointer movement event.
*/
function onPointerMove(event) {
var pointerType = event.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
const pointerType = event.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
if (pointerType === 'mouse') {
var eventX = event.screenX || 0;
var eventY = event.screenY || 0;
const eventX = event.screenX || 0;
const eventY = event.screenY || 0;
var obj = lastMouseMoveData;
const obj = lastMouseMoveData;
if (!obj) {
lastMouseMoveData = {
x: eventX,
@ -665,5 +670,4 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
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) {
'use strict';
import dialogHelper from 'dialogHelper';
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;
focusManager = focusManager.default || focusManager;
function onSubmit(e) {
function onSubmit(e) {
e.preventDefault();
return false;
}
}
function initEditor(context, settings) {
function initEditor(context, settings) {
context.querySelector('form').addEventListener('submit', onSubmit);
context.querySelector('.selectSortOrder').value = settings.sortOrder;
context.querySelector('.selectSortBy').value = settings.sortBy;
}
}
function centerFocus(elem, horiz, on) {
require(['scrollHelper'], function (scrollHelper) {
scrollHelper = scrollHelper.default || scrollHelper;
var fn = on ? 'on' : 'off';
function centerFocus(elem, horiz, on) {
import('scrollHelper').then(({default: scrollHelper}) => {
const fn = on ? 'on' : 'off';
scrollHelper.centerFocus[fn](elem, horiz);
});
}
}
function fillSortBy(context, options) {
var selectSortBy = context.querySelector('.selectSortBy');
function fillSortBy(context, options) {
const selectSortBy = context.querySelector('.selectSortBy');
selectSortBy.innerHTML = options.map(function (o) {
return '<option value="' + o.value + '">' + o.name + '</option>';
}).join('');
}
}
function saveValues(context, settings, settingsKey) {
function saveValues(context, settingsKey) {
userSettings.setFilter(settingsKey + '-sortorder', context.querySelector('.selectSortOrder').value);
userSettings.setFilter(settingsKey + '-sortby', context.querySelector('.selectSortBy').value);
}
}
function SortMenu() {
}
SortMenu.prototype.show = function (options) {
class SortMenu {
show(options) {
return new Promise(function (resolve, reject) {
require(['text!./sortmenu.template.html'], function (template) {
var dialogOptions = {
import('text!./sortmenu.template.html').then(({default: template}) => {
const dialogOptions = {
removeOnClose: true,
scrollY: false
};
@ -55,11 +56,11 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana
dialogOptions.size = 'small';
}
var dlg = dialogHelper.createDialog(dialogOptions);
const dlg = dialogHelper.createDialog(dialogOptions);
dlg.classList.add('formDialog');
var html = '';
let html = '';
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>';
@ -82,7 +83,7 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana
centerFocus(dlg.querySelector('.formDialogContent'), false, true);
}
var submitted;
let submitted;
dlg.querySelector('form').addEventListener('change', function () {
submitted = true;
@ -94,7 +95,7 @@ define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutMana
}
if (submitted) {
saveValues(dlg, options.settings, options.settingsKey);
saveValues(dlg, options.settingsKey);
resolve();
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) {
'use strict';
import $ from 'jQuery';
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) {
var html = '';
var length = Math.min(packageInfo.versions.length, 10);
for (var i = 0; i < length; i++) {
var version = packageInfo.versions[i];
for (let i = 0; i < length; i++) {
let version = packageInfo.versions[i];
html += '<h2 style="margin:.5em 0;">' + version.version + '</h2>';
html += '<div style="margin-bottom:1.5em;">' + version.changelog + '</div>';
}
$('#revisionHistory', page).html(html);
}
}
function populateVersions(packageInfo, page, installedPlugin) {
var html = '';
function populateVersions(packageInfo, page, installedPlugin) {
let html = '';
for (var i = 0; i < packageInfo.versions.length; i++) {
var version = packageInfo.versions[i];
for (let i = 0; i < packageInfo.versions.length; i++) {
const version = packageInfo.versions[i];
html += '<option value="' + version.version + '">' + version.version + '</option>';
}
var selectmenu = $('#selectVersion', page).html(html);
const selectmenu = $('#selectVersion', page).html(html);
if (!installedPlugin) {
$('#pCurrentVersion', page).hide().html('');
}
var packageVersion = packageInfo.versions[0];
const packageVersion = packageInfo.versions[0];
if (packageVersion) {
selectmenu.val(packageVersion.version);
}
}
}
function renderPackage(pkg, installedPlugins, page) {
var installedPlugin = installedPlugins.filter(function (ip) {
function renderPackage(pkg, installedPlugins, page) {
const installedPlugin = installedPlugins.filter(function (ip) {
return ip.Name == pkg.name;
})[0];
@ -58,64 +58,66 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'e
$('#developer', page).html(pkg.owner);
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);
} else {
$('#pCurrentVersion', page).hide().html('');
}
loading.hide();
}
}
function alertText(options) {
require(['alert'], function ({default: alert}) {
function alertText(options) {
import('alert').then(({default: alert}) => {
alert(options);
});
}
}
function performInstallation(page, name, guid, version) {
var developer = $('#developer', page).html().toLowerCase();
function performInstallation(page, name, guid, version) {
const developer = $('#developer', page).html().toLowerCase();
var alertCallback = function () {
const alertCallback = function () {
loading.show();
page.querySelector('#btnInstall').disabled = true;
ApiClient.installPlugin(name, guid, version).then(function () {
ApiClient.installPlugin(name, guid, version).then(() => {
loading.hide();
alertText(globalize.translate('MessagePluginInstalled'));
}).catch(() => {
alertText(globalize.translate('MessagePluginInstallError'));
});
};
if (developer !== 'jellyfin') {
loading.hide();
var msg = globalize.translate('MessagePluginInstallDisclaimer');
let msg = globalize.translate('MessagePluginInstallDisclaimer');
msg += '<br/>';
msg += '<br/>';
msg += globalize.translate('PleaseConfirmPluginInstallation');
require(['confirm'], function (confirm) {
confirm.default(msg, globalize.translate('HeaderConfirmPluginInstallation')).then(function () {
import('confirm').then(({default: confirm}) => {
confirm(msg, globalize.translate('HeaderConfirmPluginInstallation')).then(function () {
alertCallback();
}, function () {
}).catch(() => {
console.debug('plugin not installed');
});
});
} else {
alertCallback();
}
}
}
return function (view, params) {
export default function(view, params) {
$('.addPluginForm', view).on('submit', function () {
loading.show();
var page = $(this).parents('#addPluginPage')[0];
var name = params.name;
var guid = params.guid;
const page = $(this).parents('#addPluginPage')[0];
const name = params.name;
const guid = params.guid;
ApiClient.getInstalledPlugins().then(function (plugins) {
var installedPlugin = plugins.filter(function (plugin) {
const installedPlugin = plugins.filter(function (plugin) {
return plugin.Name == name;
})[0];
var version = $('#selectVersion', page).val();
const version = $('#selectVersion', page).val();
if (installedPlugin && installedPlugin.Version === version) {
loading.hide();
Dashboard.alert({
@ -125,19 +127,20 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'e
} else {
performInstallation(page, name, guid, version);
}
}).catch(() => {
alertText(globalize.translate('MessageGetInstalledPluginsError'));
});
return false;
});
view.addEventListener('viewshow', function () {
var page = this;
const page = this;
loading.show();
var name = params.name;
var guid = params.guid;
var promise1 = ApiClient.getPackageInfo(name, guid);
var promise2 = ApiClient.getInstalledPlugins();
const name = params.name;
const guid = params.guid;
const promise1 = ApiClient.getPackageInfo(name, guid);
const promise2 = ApiClient.getInstalledPlugins();
Promise.all([promise1, promise2]).then(function (responses) {
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) {
'use strict';
import loading from 'loading';
import libraryMenu from 'libraryMenu';
import globalize from 'globalize';
import 'cardStyle';
import 'emby-button';
import 'emby-checkbox';
import 'emby-select';
libraryMenu = libraryMenu.default || libraryMenu;
loading = loading.default || loading;
function reloadList(page) {
function reloadList(page) {
loading.show();
var promise1 = ApiClient.getAvailablePlugins();
var promise2 = ApiClient.getInstalledPlugins();
const promise1 = ApiClient.getAvailablePlugins();
const promise2 = ApiClient.getInstalledPlugins();
Promise.all([promise1, promise2]).then(function (responses) {
populateList({
catalogElement: page.querySelector('#pluginTiles'),
@ -16,10 +18,11 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
installedPlugins: responses[1]
});
});
}
}
function getHeaderText(category) {
function getHeaderText(category) {
category = category.replace(' ', '');
// TODO: Replace with switch
if (category === 'Channel') {
category = 'Channels';
} else if (category === 'Theme') {
@ -31,11 +34,11 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
}
return globalize.translate(category);
}
}
function populateList(options) {
var availablePlugins = options.availablePlugins;
var installedPlugins = options.installedPlugins;
function populateList(options) {
const availablePlugins = options.availablePlugins;
const installedPlugins = options.installedPlugins;
availablePlugins.forEach(function (plugin, index, array) {
plugin.category = plugin.category || 'General';
@ -57,12 +60,12 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
return 0;
});
var currentCategory = null;
var html = '';
let currentCategory = null;
let html = '';
for (var i = 0; i < availablePlugins.length; i++) {
var plugin = availablePlugins[i];
var category = plugin.categoryDisplayName;
for (let i = 0; i < availablePlugins.length; i++) {
const plugin = availablePlugins[i];
const category = plugin.categoryDisplayName;
if (category != currentCategory) {
if (currentCategory) {
html += '</div>';
@ -84,17 +87,17 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
options.catalogElement.innerHTML = html;
loading.hide();
}
}
function getPluginHtml(plugin, options, installedPlugins) {
var html = '';
var href = plugin.externalUrl ? plugin.externalUrl : 'addplugin.html?name=' + encodeURIComponent(plugin.name) + '&guid=' + plugin.guid;
function getPluginHtml(plugin, options, installedPlugins) {
let html = '';
let href = plugin.externalUrl ? plugin.externalUrl : 'addplugin.html?name=' + encodeURIComponent(plugin.name) + '&guid=' + plugin.guid;
if (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="cardBox visualCardBox">';
html += '<div class="cardScalable visualCardBox-cardScalable">';
@ -107,7 +110,7 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
html += "<div class='cardText'>";
html += plugin.name;
html += '</div>';
var installedPlugin = installedPlugins.filter(function (ip) {
const installedPlugin = installedPlugins.filter(function (ip) {
return ip.Id == plugin.guid;
})[0];
html += "<div class='cardText cardText-secondary'>";
@ -116,9 +119,9 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
html += '</div>';
html += '</div>';
return html += '</div>';
}
}
function getTabs() {
function getTabs() {
return [{
href: 'installedplugins.html',
name: globalize.translate('TabMyPlugins')
@ -129,16 +132,11 @@ define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby
href: 'repositories.html',
name: globalize.translate('TabRepositories')
}];
}
}
window.PluginCatalog = {
renderCatalog: populateList
};
return function (view, params) {
export default function (view) {
view.addEventListener('viewshow', function () {
libraryMenu.setTabs('plugins', 1, getTabs);
reloadList(this);
});
};
});
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1545,5 +1545,7 @@
"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.",
"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}.",
"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.",
"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",
"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.",