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 controller

This commit is contained in:
dkanada 2020-06-10 13:57:50 +09:00
commit ab8be03209
96 changed files with 2299 additions and 2021 deletions

View file

@ -132,6 +132,7 @@ module.exports = {
'Object.getOwnPropertyDescriptor',
'Object.getPrototypeOf',
'Object.keys',
'Object.entries',
'Object.getOwnPropertyNames',
'Function.name',
'Function.hasInstance',

3
.gitignore vendored
View file

@ -1,6 +1,3 @@
# config
config.json
# npm
dist
web

View file

@ -22,12 +22,12 @@
"eslint": "^6.8.0",
"eslint-plugin-compat": "^3.5.1",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-import": "^2.21.1",
"eslint-plugin-promise": "^4.2.1",
"file-loader": "^6.0.0",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"gulp-cli": "^2.2.1",
"gulp-cli": "^2.3.0",
"gulp-concat": "^2.6.1",
"gulp-htmlmin": "^5.0.1",
"gulp-if": "^3.0.0",
@ -44,16 +44,17 @@
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.7.0",
"style-loader": "^1.1.3",
"stylelint": "^13.5.0",
"stylelint": "^13.6.0",
"stylelint-config-rational-order": "^0.1.2",
"stylelint-no-browser-hacks": "^1.2.1",
"stylelint-order": "^4.0.0",
"stylelint-order": "^4.1.0",
"webpack": "^4.41.5",
"webpack-merge": "^4.2.2",
"webpack-stream": "^5.2.1"
},
"dependencies": {
"alameda": "^1.4.0",
"blurhash": "^1.1.3",
"classlist.js": "https://github.com/eligrey/classList.js/archive/1.2.20180112.tar.gz",
"core-js": "^3.6.5",
"date-fns": "^2.14.0",
@ -65,7 +66,7 @@
"hls.js": "^0.13.1",
"howler": "^2.2.0",
"intersection-observer": "^0.10.0",
"jellyfin-apiclient": "^1.2.0",
"jellyfin-apiclient": "^1.2.2",
"jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto",
"jquery": "^3.5.1",
"jstree": "^3.3.7",
@ -73,12 +74,12 @@
"material-design-icons-iconfont": "^5.0.1",
"native-promise-only": "^0.8.0-a",
"page": "^1.11.6",
"query-string": "^6.11.1",
"query-string": "^6.13.0",
"resize-observer-polyfill": "^1.5.1",
"screenfull": "^5.0.2",
"shaka-player": "^2.5.12",
"sortablejs": "^1.10.2",
"swiper": "^5.4.1",
"swiper": "^5.4.2",
"webcomponents.js": "^0.7.24",
"whatwg-fetch": "^3.0.0"
},
@ -89,21 +90,31 @@
"overrides": [
{
"test": [
"src/components/accessSchedule/accessSchedule.js",
"src/components/actionSheet/actionSheet.js",
"src/components/autoFocuser.js",
"src/components/cardbuilder/cardBuilder.js",
"src/components/cardbuilder/chaptercardbuilder.js",
"src/components/cardbuilder/peoplecardbuilder.js",
"src/components/images/imageLoader.js",
"src/components/indicators/indicators.js",
"src/components/lazyLoader/lazyLoaderIntersectionObserver.js",
"src/components/playback/brightnessosd.js",
"src/components/playback/mediasession.js",
"src/components/playback/nowplayinghelper.js",
"src/components/playback/playbackorientation.js",
"src/components/playback/playerSelectionMenu.js",
"src/components/playback/playersettingsmenu.js",
"src/components/playback/playmethodhelper.js",
"src/components/playback/remotecontrolautoplay.js",
"src/components/playback/volumeosd.js",
"src/components/playmenu.js",
"src/components/sanatizefilename.js",
"src/components/scrollManager.js",
"src/components/syncplay/groupSelectionMenu.js",
"src/components/syncplay/playbackPermissionManager.js",
"src/components/syncplay/syncPlayManager.js",
"src/components/syncplay/timeSyncManager.js",
"src/components/syncPlay/groupSelectionMenu.js",
"src/components/syncPlay/playbackPermissionManager.js",
"src/components/syncPlay/syncPlayManager.js",
"src/components/syncPlay/timeSyncManager.js",
"src/controllers/dashboard/logs.js",
"src/plugins/bookPlayer/plugin.js",
"src/plugins/bookPlayer/tableOfContents.js",
@ -115,6 +126,9 @@
"src/scripts/filesystem.js",
"src/scripts/imagehelper.js",
"src/scripts/inputManager.js",
"src/plugins/backdropScreensaver/plugin.js",
"src/components/filterdialog/filterdialog.js",
"src/components/fetchhelper.js",
"src/scripts/keyboardNavigation.js",
"src/scripts/settings/appSettings.js",
"src/scripts/settings/userSettings.js",

View file

@ -597,6 +597,7 @@
.detailImageContainer {
position: relative;
margin-top: -25vh;
margin-bottom: 10vh;
float: left;
width: 25vw;
z-index: 3;
@ -641,7 +642,8 @@ div.itemDetailGalleryLink.defaultCardBackground {
}
.itemDetailGalleryLink.defaultCardBackground {
height: 23vw; /* Dirty hack to get it to look somewhat square. Less than ideal. */
/* Dirty hack to get it to look somewhat square. Less than ideal. */
height: 23vw;
}
.itemDetailGalleryLink.defaultCardBackground > .material-icons {
@ -1144,3 +1146,21 @@ div:not(.sectionTitleContainer-cards) > .sectionTitle-cards {
margin-top: 0;
font-size: 1.4em;
}
.overview-controls {
display: flex;
justify-content: flex-end;
}
.detail-clamp-text {
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 12;
-webkit-box-orient: vertical;
}
@media all and (min-width: 40em) {
.detail-clamp-text {
-webkit-line-clamp: 6;
}
}

View file

@ -16,6 +16,12 @@ _define('fetch', function() {
return fetch;
});
// Blurhash
var blurhash = require('blurhash');
_define('blurhash', function() {
return blurhash;
});
// query-string
var query = require('query-string');
_define('queryString', function() {

View file

@ -1,9 +1,20 @@
define(['dialogHelper', 'datetime', 'globalize', 'emby-select', 'paper-icon-button-light', 'formDialogStyle'], function (dialogHelper, datetime, globalize) {
'use strict';
/* eslint-disable indent */
/**
* Module for controlling user parental control from.
* @module components/accessSchedule/accessSchedule
*/
import dialogHelper from 'dialogHelper';
import datetime from 'datetime';
import globalize from 'globalize';
import 'emby-select';
import 'paper-icon-button-light';
import 'formDialogStyle';
function getDisplayTime(hours) {
var minutes = 0;
var pct = hours % 1;
let minutes = 0;
const pct = hours % 1;
if (pct) {
minutes = parseInt(60 * pct);
@ -13,25 +24,25 @@ define(['dialogHelper', 'datetime', 'globalize', 'emby-select', 'paper-icon-butt
}
function populateHours(context) {
var html = '';
let html = '';
for (var i = 0; i < 24; i++) {
html += '<option value="' + i + '">' + getDisplayTime(i) + '</option>';
for (let i = 0; i < 24; i++) {
html += `<option value="${i}">${getDisplayTime(i)}</option>`;
}
html += '<option value="24">' + getDisplayTime(0) + '</option>';
html += `<option value="24">${getDisplayTime(0)}</option>`;
context.querySelector('#selectStart').innerHTML = html;
context.querySelector('#selectEnd').innerHTML = html;
}
function loadSchedule(context, schedule) {
context.querySelector('#selectDay').value = schedule.DayOfWeek || 'Sunday';
context.querySelector('#selectStart').value = schedule.StartHour || 0;
context.querySelector('#selectEnd').value = schedule.EndHour || 0;
function loadSchedule(context, {DayOfWeek, StartHour, EndHour}) {
context.querySelector('#selectDay').value = DayOfWeek || 'Sunday';
context.querySelector('#selectStart').value = StartHour || 0;
context.querySelector('#selectEnd').value = EndHour || 0;
}
function submitSchedule(context, options) {
var updatedSchedule = {
const updatedSchedule = {
DayOfWeek: context.querySelector('#selectDay').value,
StartHour: context.querySelector('#selectStart').value,
EndHour: context.querySelector('#selectEnd').value
@ -46,44 +57,42 @@ define(['dialogHelper', 'datetime', 'globalize', 'emby-select', 'paper-icon-butt
dialogHelper.close(context);
}
return {
show: function (options) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'components/accessSchedule/accessSchedule.template.html', true);
xhr.onload = function (e) {
var template = this.response;
var dlg = dialogHelper.createDialog({
export function show(options) {
return new Promise((resolve, reject) => {
// TODO: remove require
require(['text!./components/accessSchedule/accessSchedule.template.html'], template => {
const dlg = dialogHelper.createDialog({
removeOnClose: true,
size: 'small'
});
dlg.classList.add('formDialog');
var html = '';
let html = '';
html += globalize.translateDocument(template);
dlg.innerHTML = html;
populateHours(dlg);
loadSchedule(dlg, options.schedule);
dialogHelper.open(dlg);
dlg.addEventListener('close', function () {
dlg.addEventListener('close', () => {
if (dlg.submitted) {
resolve(options.schedule);
} else {
reject();
}
});
dlg.querySelector('.btnCancel').addEventListener('click', function () {
dlg.querySelector('.btnCancel').addEventListener('click', () => {
dialogHelper.close(dlg);
});
dlg.querySelector('form').addEventListener('submit', function (event) {
dlg.querySelector('form').addEventListener('submit', event => {
submitSchedule(dlg, options);
event.preventDefault();
return false;
});
};
xhr.send();
});
});
}
/* eslint-enable indent */
export default {
show: show
};
});

View file

@ -503,94 +503,49 @@ import 'programStyles';
const primaryImageAspectRatio = item.PrimaryImageAspectRatio;
let forceName = false;
let imgUrl = null;
let imgTag = null;
let coverImage = false;
let uiAspect = null;
let imgType = null;
let itemId = null;
if (options.preferThumb && item.ImageTags && item.ImageTags.Thumb) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: 'Thumb',
maxWidth: width,
tag: item.ImageTags.Thumb
});
imgType = 'Thumb';
imgTag = item.ImageTags.Thumb;
} else if ((options.preferBanner || shape === 'banner') && item.ImageTags && item.ImageTags.Banner) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: 'Banner',
maxWidth: width,
tag: item.ImageTags.Banner
});
imgType = 'Banner';
imgTag = item.ImageTags.Banner;
} else if (options.preferDisc && item.ImageTags && item.ImageTags.Disc) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: 'Disc',
maxWidth: width,
tag: item.ImageTags.Disc
});
imgType = 'Disc';
imgTag = item.ImageTags.Disc;
} else if (options.preferLogo && item.ImageTags && item.ImageTags.Logo) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: 'Logo',
maxWidth: width,
tag: item.ImageTags.Logo
});
imgType = 'Logo';
imgTag = item.ImageTags.Logo;
} else if (options.preferLogo && item.ParentLogoImageTag && item.ParentLogoItemId) {
imgUrl = apiClient.getScaledImageUrl(item.ParentLogoItemId, {
type: 'Logo',
maxWidth: width,
tag: item.ParentLogoImageTag
});
imgType = 'Logo';
imgTag = item.ParentLogoImageTag;
itemId = item.ParentLogoItemId;
} else if (options.preferThumb && item.SeriesThumbImageTag && options.inheritThumb !== false) {
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
type: 'Thumb',
maxWidth: width,
tag: item.SeriesThumbImageTag
});
imgType = 'Thumb';
imgTag = item.SeriesThumbImageTag;
itemId = item.SeriesId;
} else if (options.preferThumb && item.ParentThumbItemId && options.inheritThumb !== false && item.MediaType !== 'Photo') {
imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, {
type: 'Thumb',
maxWidth: width,
tag: item.ParentThumbImageTag
});
imgType = 'Thumb';
imgTag = item.ParentThumbImageTag;
itemId = item.ParentThumbItemId;
} else if (options.preferThumb && item.BackdropImageTags && item.BackdropImageTags.length) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: 'Backdrop',
maxWidth: width,
tag: item.BackdropImageTags[0]
});
imgType = 'Backdrop';
imgTag = item.BackdropImageTags[0];
forceName = true;
} else if (options.preferThumb && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length && options.inheritThumb !== false && item.Type === 'Episode') {
imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
type: 'Backdrop',
maxWidth: width,
tag: item.ParentBackdropImageTags[0]
});
imgType = 'Backdrop';
imgTag = item.ParentBackdropImageTags[0];
itemId = item.ParentBackdropItemId;
} else if (item.ImageTags && item.ImageTags.Primary) {
imgType = 'Primary';
imgTag = item.ImageTags.Primary;
height = width && primaryImageAspectRatio ? Math.round(width / primaryImageAspectRatio) : null;
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: 'Primary',
maxHeight: height,
maxWidth: width,
tag: item.ImageTags.Primary
});
if (options.preferThumb && options.showTitle !== false) {
forceName = true;
}
@ -603,16 +558,11 @@ import 'programStyles';
}
} else if (item.PrimaryImageTag) {
imgType = 'Primary';
imgTag = item.PrimaryImageTag;
itemId = item.PrimaryImageItemId;
height = width && primaryImageAspectRatio ? Math.round(width / primaryImageAspectRatio) : null;
imgUrl = apiClient.getScaledImageUrl(item.PrimaryImageItemId || item.Id || item.ItemId, {
type: 'Primary',
maxHeight: height,
maxWidth: width,
tag: item.PrimaryImageTag
});
if (options.preferThumb && options.showTitle !== false) {
forceName = true;
}
@ -624,30 +574,19 @@ import 'programStyles';
}
}
} else if (item.ParentPrimaryImageTag) {
imgUrl = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, {
type: 'Primary',
maxWidth: width,
tag: item.ParentPrimaryImageTag
});
imgType = 'Primary';
imgTag = item.ParentPrimaryImageTag;
itemId = item.ParentPrimaryImageItemId;
} else if (item.SeriesPrimaryImageTag) {
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
type: 'Primary',
maxWidth: width,
tag: item.SeriesPrimaryImageTag
});
imgType = 'Primary';
imgTag = item.SeriesPrimaryImageTag;
itemId = item.SeriesId;
} else if (item.AlbumId && item.AlbumPrimaryImageTag) {
imgType = 'Primary';
imgTag = item.AlbumPrimaryImageTag;
itemId = item.AlbumId;
height = width && primaryImageAspectRatio ? Math.round(width / primaryImageAspectRatio) : null;
imgUrl = apiClient.getScaledImageUrl(item.AlbumId, {
type: 'Primary',
maxHeight: height,
maxWidth: width,
tag: item.AlbumPrimaryImageTag
});
if (primaryImageAspectRatio) {
uiAspect = getDesiredAspect(shape);
if (uiAspect) {
@ -655,57 +594,46 @@ import 'programStyles';
}
}
} else if (item.Type === 'Season' && item.ImageTags && item.ImageTags.Thumb) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: 'Thumb',
maxWidth: width,
tag: item.ImageTags.Thumb
});
imgType = 'Thumb';
imgTag = item.ImageTags.Thumb;
} else if (item.BackdropImageTags && item.BackdropImageTags.length) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: 'Backdrop',
maxWidth: width,
tag: item.BackdropImageTags[0]
});
imgType = 'Backdrop';
imgTag = item.BackdropImageTags[0];
} else if (item.ImageTags && item.ImageTags.Thumb) {
imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: 'Thumb',
maxWidth: width,
tag: item.ImageTags.Thumb
});
imgType = 'Thumb';
imgTag = item.ImageTags.Thumb;
} else if (item.SeriesThumbImageTag && options.inheritThumb !== false) {
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
type: 'Thumb',
maxWidth: width,
tag: item.SeriesThumbImageTag
});
imgType = 'Thumb';
imgTag = item.SeriesThumbImageTag;
itemId = item.SeriesId;
} else if (item.ParentThumbItemId && options.inheritThumb !== false) {
imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, {
type: 'Thumb',
maxWidth: width,
tag: item.ParentThumbImageTag
});
imgType = 'Thumb';
imgTag = item.ParentThumbImageTag;
itemId = item.ParentThumbItemId;
} else if (item.ParentBackdropImageTags && item.ParentBackdropImageTags.length && options.inheritThumb !== false) {
imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
type: 'Backdrop',
maxWidth: width,
tag: item.ParentBackdropImageTags[0]
});
imgType = 'Backdrop';
imgTag = item.ParentBackdropImageTags[0];
itemId = item.ParentBackdropItemId;
}
if (!itemId) {
itemId = item.Id;
}
if (imgTag && imgType) {
imgUrl = apiClient.getScaledImageUrl(itemId, {
type: imgType,
maxHeight: height,
maxWidth: width,
tag: imgTag
});
}
let blurHashes = options.imageBlurhashes || item.ImageBlurHashes || {};
return {
imgUrl: imgUrl,
blurhash: (blurHashes[imgType] || {})[imgTag],
forceName: forceName,
coverImage: coverImage
};
@ -1321,6 +1249,7 @@ import 'programStyles';
const imgInfo = getCardImageUrl(item, apiClient, options, shape);
const imgUrl = imgInfo.imgUrl;
const blurhash = imgInfo.blurhash;
const forceName = imgInfo.forceName;
@ -1445,15 +1374,20 @@ import 'programStyles';
cardContentClass += ' cardContent-shadow';
}
let blurhashAttrib = '';
if (blurhash && blurhash.length > 0) {
blurhashAttrib = 'data-blurhash="' + blurhash + '"';
}
if (layoutManager.tv) {
// Don't use the IMG tag with safari because it puts a white border around it
cardImageContainerOpen = imgUrl ? ('<div class="' + cardImageContainerClass + ' ' + cardContentClass + ' lazy" data-src="' + imgUrl + '">') : ('<div class="' + cardImageContainerClass + ' ' + cardContentClass + '">');
cardImageContainerOpen = imgUrl ? ('<div class="' + cardImageContainerClass + ' ' + cardContentClass + ' lazy" data-src="' + imgUrl + '" ' + blurhashAttrib + '>') : ('<div class="' + cardImageContainerClass + ' ' + cardContentClass + '">');
cardImageContainerClose = '</div>';
} else {
// Don't use the IMG tag with safari because it puts a white border around it
cardImageContainerOpen = imgUrl ? ('<button data-action="' + action + '" class="cardContent-button ' + cardImageContainerClass + ' ' + cardContentClass + ' itemAction lazy" data-src="' + imgUrl + '">') : ('<button data-action="' + action + '" class="cardContent-button ' + cardImageContainerClass + ' ' + cardContentClass + ' itemAction">');
cardImageContainerOpen = imgUrl ? ('<button data-action="' + action + '" class="cardContent-button ' + cardImageContainerClass + ' ' + cardContentClass + ' itemAction lazy" data-src="' + imgUrl + '" ' + blurhashAttrib + '>') : ('<button data-action="' + action + '" class="cardContent-button ' + cardImageContainerClass + ' ' + cardContentClass + ' itemAction">');
cardImageContainerClose = '</button>';
}

View file

@ -1,13 +1,23 @@
define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browser'], function (datetime, imageLoader, connectionManager, layoutManager, browser) {
'use strict';
/* eslint-disable indent */
var enableFocusTransform = !browser.slow && !browser.edge;
/**
* Module for building cards from item data.
* @module components/cardBuilder/chaptercardbuilder
*/
import datetime from 'datetime';
import imageLoader from 'imageLoader';
import connectionManager from 'connectionManager';
import layoutManager from 'layoutManager';
import browser from 'browser';
const enableFocusTransform = !browser.slow && !browser.edge;
function buildChapterCardsHtml(item, chapters, options) {
// TODO move card creation code to Card component
var className = 'card itemAction chapterCard';
let className = 'card itemAction chapterCard';
if (layoutManager.tv) {
className += ' show-focus';
@ -17,12 +27,12 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse
}
}
var mediaStreams = ((item.MediaSources || [])[0] || {}).MediaStreams || [];
var videoStream = mediaStreams.filter(function (i) {
return i.Type === 'Video';
const mediaStreams = ((item.MediaSources || [])[0] || {}).MediaStreams || [];
const videoStream = mediaStreams.filter(({Type}) => {
return Type === 'Video';
})[0] || {};
var shape = (options.backdropShape || 'backdrop');
let shape = (options.backdropShape || 'backdrop');
if (videoStream.Width && videoStream.Height) {
@ -31,24 +41,24 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse
}
}
className += ' ' + shape + 'Card';
className += ` ${shape}Card`;
if (options.block || options.rows) {
className += ' block';
}
var html = '';
var itemsInRow = 0;
let html = '';
let itemsInRow = 0;
var apiClient = connectionManager.getApiClient(item.ServerId);
const apiClient = connectionManager.getApiClient(item.ServerId);
for (var i = 0, length = chapters.length; i < length; i++) {
for (let i = 0, length = chapters.length; i < length; i++) {
if (options.rows && itemsInRow === 0) {
html += '<div class="cardColumn">';
}
var chapter = chapters[i];
const chapter = chapters[i];
html += buildChapterCard(item, apiClient, chapter, i, options, className, shape);
itemsInRow++;
@ -62,50 +72,50 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse
return html;
}
function getImgUrl(item, chapter, index, maxWidth, apiClient) {
function getImgUrl({Id}, {ImageTag}, index, maxWidth, apiClient) {
if (chapter.ImageTag) {
if (ImageTag) {
return apiClient.getScaledImageUrl(item.Id, {
return apiClient.getScaledImageUrl(Id, {
maxWidth: maxWidth * 2,
tag: chapter.ImageTag,
tag: ImageTag,
type: 'Chapter',
index: index
index
});
}
return null;
}
function buildChapterCard(item, apiClient, chapter, index, options, className, shape) {
function buildChapterCard(item, apiClient, chapter, index, {width, coverImage}, className, shape) {
var imgUrl = getImgUrl(item, chapter, index, options.width || 400, apiClient);
const imgUrl = getImgUrl(item, chapter, index, width || 400, apiClient);
var cardImageContainerClass = 'cardContent cardContent-shadow cardImageContainer chapterCardImageContainer';
if (options.coverImage) {
let cardImageContainerClass = 'cardContent cardContent-shadow cardImageContainer chapterCardImageContainer';
if (coverImage) {
cardImageContainerClass += ' coveredImage';
}
var dataAttributes = ' data-action="play" data-isfolder="' + item.IsFolder + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-type="' + item.Type + '" data-mediatype="' + item.MediaType + '" data-positionticks="' + chapter.StartPositionTicks + '"';
var cardImageContainer = imgUrl ? ('<div class="' + cardImageContainerClass + ' lazy" data-src="' + imgUrl + '">') : ('<div class="' + cardImageContainerClass + '">');
const dataAttributes = ` data-action="play" data-isfolder="${item.IsFolder}" data-id="${item.Id}" data-serverid="${item.ServerId}" data-type="${item.Type}" data-mediatype="${item.MediaType}" data-positionticks="${chapter.StartPositionTicks}"`;
let cardImageContainer = imgUrl ? (`<div class="${cardImageContainerClass} lazy" data-src="${imgUrl}">`) : (`<div class="${cardImageContainerClass}">`);
if (!imgUrl) {
cardImageContainer += '<span class="material-icons cardImageIcon local_movies"></span>';
}
var nameHtml = '';
nameHtml += '<div class="cardText">' + chapter.Name + '</div>';
nameHtml += '<div class="cardText">' + datetime.getDisplayRunningTime(chapter.StartPositionTicks) + '</div>';
let nameHtml = '';
nameHtml += `<div class="cardText">${chapter.Name}</div>`;
nameHtml += `<div class="cardText">${datetime.getDisplayRunningTime(chapter.StartPositionTicks)}</div>`;
var cardBoxCssClass = 'cardBox';
var cardScalableClass = 'cardScalable';
const cardBoxCssClass = 'cardBox';
const cardScalableClass = 'cardScalable';
var html = '<button type="button" class="' + className + '"' + dataAttributes + '><div class="' + cardBoxCssClass + '"><div class="' + cardScalableClass + '"><div class="cardPadder-' + shape + '"></div>' + cardImageContainer + '</div><div class="innerCardFooter">' + nameHtml + '</div></div></div></button>';
const html = `<button type="button" class="${className}"${dataAttributes}><div class="${cardBoxCssClass}"><div class="${cardScalableClass}"><div class="cardPadder-${shape}"></div>${cardImageContainer}</div><div class="innerCardFooter">${nameHtml}</div></div></div></button>`;
return html;
}
function buildChapterCards(item, chapters, options) {
export function buildChapterCards(item, chapters, options) {
if (options.parentContainer) {
// Abort if the container has been disposed
@ -121,15 +131,16 @@ define(['datetime', 'imageLoader', 'connectionManager', 'layoutManager', 'browse
}
}
var html = buildChapterCardsHtml(item, chapters, options);
const html = buildChapterCardsHtml(item, chapters, options);
options.itemsContainer.innerHTML = html;
imageLoader.lazyChildren(options.itemsContainer);
}
return {
/* eslint-enable indent */
export default {
buildChapterCards: buildChapterCards
};
});

View file

@ -1,7 +1,13 @@
define(['cardBuilder'], function (cardBuilder) {
'use strict';
/* eslint-disable indent */
function buildPeopleCards(items, options) {
/**
* Module for building cards from item data.
* @module components/cardBuilder/peoplecardbuilder
*/
import cardBuilder from 'cardBuilder';
export function buildPeopleCards(items, options) {
options = Object.assign(options || {}, {
cardLayout: false,
@ -15,8 +21,8 @@ define(['cardBuilder'], function (cardBuilder) {
cardBuilder.buildCards(items, options);
}
return {
/* eslint-enable indent */
export default {
buildPeopleCards: buildPeopleCards
};
});

View file

@ -181,6 +181,7 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', '
context.querySelector('#chkThemeSong').checked = userSettings.enableThemeSongs();
context.querySelector('#chkThemeVideo').checked = userSettings.enableThemeVideos();
context.querySelector('#chkFadein').checked = userSettings.enableFastFadein();
context.querySelector('#chkBlurhash').checked = userSettings.enableBlurhash();
context.querySelector('#chkBackdrops').checked = userSettings.enableBackdrops();
context.querySelector('#chkDetailsBanner').checked = userSettings.detailsBanner();
@ -223,6 +224,7 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', '
userSettingsInstance.skin(context.querySelector('.selectSkin').value);
userSettingsInstance.enableFastFadein(context.querySelector('#chkFadein').checked);
userSettingsInstance.enableBlurhash(context.querySelector('#chkBlurhash').checked);
userSettingsInstance.enableBackdrops(context.querySelector('#chkBackdrops').checked);
userSettingsInstance.detailsBanner(context.querySelector('#chkDetailsBanner').checked);

View file

@ -143,20 +143,28 @@
<select is="emby-select" class="selectSoundEffects" label="${LabelSoundEffects}"></select>
</div>
<div class="inputContainer inputContainer-withDescription fldFadein">
<div class="inputContainer inputContainer-withDescription">
<input is="emby-input" type="number" id="txtLibraryPageSize" pattern="[0-9]*" required="required" min="0" max="1000" step="1" label="${LabelLibraryPageSize}" />
<div class="fieldDescription">${LabelLibraryPageSizeHelp}</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription fldFadein">
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input type="checkbox" is="emby-checkbox" id="chkFadein" />
<span>${EnableFastImageFadeIn}</span>
<span>${EnableFasterAnimations}</span>
</label>
<div class="fieldDescription checkboxFieldDescription">${EnableFastImageFadeInHelp}</div>
<div class="fieldDescription checkboxFieldDescription">${EnableFasterAnimationsHelp}</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription fldDetailsBanner">
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input type="checkbox" is="emby-checkbox" id="chkBlurhash" />
<span>${EnableBlurhash}</span>
</label>
<div class="fieldDescription checkboxFieldDescription">${EnableBlurhashHelp}</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input type="checkbox" is="emby-checkbox" id="chkDetailsBanner" />
<span>${EnableDetailsBanner}</span>

View file

@ -1,21 +1,19 @@
define([], function () {
'use strict';
/* eslint-disable indent */
export function getFetchPromise(request) {
function getFetchPromise(request) {
var headers = request.headers || {};
const headers = request.headers || {};
if (request.dataType === 'json') {
headers.accept = 'application/json';
}
var fetchRequest = {
const fetchRequest = {
headers: headers,
method: request.type,
credentials: 'same-origin'
};
var contentType = request.contentType;
let contentType = request.contentType;
if (request.data) {
@ -33,12 +31,12 @@ define([], function () {
headers['Content-Type'] = contentType;
}
var url = request.url;
let url = request.url;
if (request.query) {
var paramString = paramsToString(request.query);
const paramString = paramsToString(request.query);
if (paramString) {
url += '?' + paramString;
url += `?${paramString}`;
}
}
@ -51,11 +49,11 @@ define([], function () {
function fetchWithTimeout(url, options, timeoutMs) {
console.debug('fetchWithTimeout: timeoutMs: ' + timeoutMs + ', url: ' + url);
console.debug(`fetchWithTimeout: timeoutMs: ${timeoutMs}, url: ${url}`);
return new Promise(function (resolve, reject) {
var timeout = setTimeout(reject, timeoutMs);
const timeout = setTimeout(reject, timeoutMs);
options = options || {};
options.credentials = 'same-origin';
@ -63,50 +61,47 @@ define([], function () {
fetch(url, options).then(function (response) {
clearTimeout(timeout);
console.debug('fetchWithTimeout: succeeded connecting to url: ' + url);
console.debug(`fetchWithTimeout: succeeded connecting to url: ${url}`);
resolve(response);
}, function (error) {
clearTimeout(timeout);
console.debug('fetchWithTimeout: timed out connecting to url: ' + url);
console.debug(`fetchWithTimeout: timed out connecting to url: ${url}`);
reject();
reject(error);
});
});
}
/**
* @param params {Record<string, string | number | boolean>}
* @returns {string} Query string
*/
function paramsToString(params) {
var values = [];
for (var key in params) {
var value = params[key];
if (value !== null && value !== undefined && value !== '') {
values.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
}
}
return values.join('&');
return Object.entries(params)
// eslint-disable-next-line no-unused-vars
.filter(([_, v]) => v !== null && v !== undefined && v !== '')
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&');
}
function ajax(request) {
export function ajax(request) {
if (!request) {
throw new Error('Request cannot be null');
}
request.headers = request.headers || {};
console.debug('requesting url: ' + request.url);
console.debug(`requesting url: ${request.url}`);
return getFetchPromise(request).then(function (response) {
console.debug('response status: ' + response.status + ', url: ' + request.url);
console.debug(`response status: ${response.status}, url: ${request.url}`);
if (response.status < 400) {
if (request.dataType === 'json' || request.headers.accept === 'application/json') {
return response.json();
} else if (request.dataType === 'text' || (response.headers.get('Content-Type') || '').toLowerCase().indexOf('text/') === 0) {
} else if (request.dataType === 'text' || (response.headers.get('Content-Type') || '').toLowerCase().startsWith('text/')) {
return response.text();
} else {
return response;
@ -115,12 +110,8 @@ define([], function () {
return Promise.reject(response);
}
}, function (err) {
console.error('request failed to url: ' + request.url);
console.error(`request failed to url: ${request.url}`);
throw err;
});
}
return {
getFetchPromise: getFetchPromise,
ajax: ajax
};
});
/* eslint-enable indent */

View file

@ -1,21 +1,28 @@
define(['dom', 'dialogHelper', 'globalize', 'connectionManager', 'events', 'browser', 'require', 'emby-checkbox', 'emby-collapse', 'css!./style'], function (dom, dialogHelper, globalize, connectionManager, events, browser, require) {
'use strict';
import dom from 'dom';
import dialogHelper from 'dialogHelper';
import globalize from 'globalize';
import connectionManager from 'connectionManager';
import events from 'events';
import 'emby-checkbox';
import 'emby-collapse';
import 'css!./style.css';
/* eslint-disable indent */
function renderOptions(context, selector, cssClass, items, isCheckedFn) {
var elem = context.querySelector(selector);
const elem = context.querySelector(selector);
if (items.length) {
elem.classList.remove('hide');
} else {
elem.classList.add('hide');
}
var html = '';
let html = '';
html += '<div class="checkboxList">';
html += items.map(function (filter) {
var itemHtml = '';
var checkedHtml = isCheckedFn(filter) ? ' checked' : '';
let itemHtml = '';
const checkedHtml = isCheckedFn(filter) ? 'checked' : '';
itemHtml += '<label>';
itemHtml += '<input is="emby-checkbox" type="checkbox"' + checkedHtml + ' data-filter="' + filter + '" class="' + cssClass + '"/>';
itemHtml += '<span>' + filter + '</span>';
itemHtml += `<input is="emby-checkbox" type="checkbox" ${checkedHtml} data-filter="${filter}" class="${cssClass}"/>`;
itemHtml += `<span>${filter}</span>`;
itemHtml += '</label>';
return itemHtml;
}).join('');
@ -24,21 +31,24 @@ define(['dom', 'dialogHelper', 'globalize', 'connectionManager', 'events', 'brow
}
function renderFilters(context, result, query) {
if (result.Tags) {
result.Tags.length = Math.min(result.Tags.length, 50);
}
renderOptions(context, '.genreFilters', 'chkGenreFilter', result.Genres, function (i) {
var delimeter = '|';
return (delimeter + (query.Genres || '') + delimeter).indexOf(delimeter + i + delimeter) != -1;
const delimeter = '|';
return (delimeter + (query.Genres || '') + delimeter).includes(delimeter + i + delimeter);
});
renderOptions(context, '.officialRatingFilters', 'chkOfficialRatingFilter', result.OfficialRatings, function (i) {
var delimeter = '|';
return (delimeter + (query.OfficialRatings || '') + delimeter).indexOf(delimeter + i + delimeter) != -1;
const delimeter = '|';
return (delimeter + (query.OfficialRatings || '') + delimeter).includes(delimeter + i + delimeter);
});
renderOptions(context, '.tagFilters', 'chkTagFilter', result.Tags, function (i) {
var delimeter = '|';
return (delimeter + (query.Tags || '') + delimeter).indexOf(delimeter + i + delimeter) != -1;
const delimeter = '|';
return (delimeter + (query.Tags || '') + delimeter).includes(delimeter + i + delimeter);
});
renderOptions(context, '.yearFilters', 'chkYearFilter', result.Years, function (i) {
var delimeter = ',';
return (delimeter + (query.Years || '') + delimeter).indexOf(delimeter + i + delimeter) != -1;
const delimeter = ',';
return (delimeter + (query.Years || '') + delimeter).includes(delimeter + i + delimeter);
});
}
@ -52,59 +62,58 @@ define(['dom', 'dialogHelper', 'globalize', 'connectionManager', 'events', 'brow
});
}
/**
* @param context {HTMLDivElement} Dialog
* @param options {any} Options
*/
function updateFilterControls(context, options) {
var elems;
var i;
var length;
var query = options.query;
const query = options.query;
if (options.mode == 'livetvchannels') {
context.querySelector('.chkFavorite').checked = query.IsFavorite == true;
context.querySelector('.chkLikes').checked = query.IsLiked == true;
context.querySelector('.chkDislikes').checked = query.IsDisliked == true;
if (options.mode === 'livetvchannels') {
context.querySelector('.chkFavorite').checked = query.IsFavorite === true;
context.querySelector('.chkLikes').checked = query.IsLiked === true;
context.querySelector('.chkDislikes').checked = query.IsDisliked === true;
} else {
elems = context.querySelectorAll('.chkStandardFilter');
for (i = 0, length = elems.length; i < length; i++) {
var chkStandardFilter = elems[i];
var filters = ',' + (query.Filters || '');
var filterName = chkStandardFilter.getAttribute('data-filter');
chkStandardFilter.checked = filters.indexOf(',' + filterName) != -1;
for (const elem of context.querySelectorAll('.chkStandardFilter')) {
const filters = `,${query.Filters || ''}`;
const filterName = elem.getAttribute('data-filter');
elem.checked = filters.includes(`,${filterName}`);
}
}
elems = context.querySelectorAll('.chkVideoTypeFilter');
for (i = 0, length = elems.length; i < length; i++) {
var chkVideoTypeFilter = elems[i];
var filters = ',' + (query.VideoTypes || '');
var filterName = chkVideoTypeFilter.getAttribute('data-filter');
chkVideoTypeFilter.checked = filters.indexOf(',' + filterName) != -1;
for (const elem of context.querySelectorAll('.chkVideoTypeFilter')) {
const filters = `,${query.VideoTypes || ''}`;
const filterName = elem.getAttribute('data-filter');
elem.checked = filters.includes(`,${filterName}`);
}
context.querySelector('.chk3DFilter').checked = query.Is3D == true;
context.querySelector('.chkHDFilter').checked = query.IsHD == true;
context.querySelector('.chk4KFilter').checked = query.Is4K == true;
context.querySelector('.chkSDFilter').checked = query.IsHD == true;
context.querySelector('#chkSubtitle').checked = query.HasSubtitles == true;
context.querySelector('#chkTrailer').checked = query.HasTrailer == true;
context.querySelector('#chkThemeSong').checked = query.HasThemeSong == true;
context.querySelector('#chkThemeVideo').checked = query.HasThemeVideo == true;
context.querySelector('#chkSpecialFeature').checked = query.HasSpecialFeature == true;
context.querySelector('#chkSpecialEpisode').checked = query.ParentIndexNumber == 0;
context.querySelector('#chkMissingEpisode').checked = query.IsMissing == true;
context.querySelector('#chkFutureEpisode').checked = query.IsUnaired == true;
for (i = 0, length = elems.length; i < length; i++) {
var chkStatus = elems[i];
var filters = ',' + (query.SeriesStatus || '');
var filterName = chkStatus.getAttribute('data-filter');
chkStatus.checked = filters.indexOf(',' + filterName) != -1;
context.querySelector('.chk3DFilter').checked = query.Is3D === true;
context.querySelector('.chkHDFilter').checked = query.IsHD === true;
context.querySelector('.chk4KFilter').checked = query.Is4K === true;
context.querySelector('.chkSDFilter').checked = query.IsHD === true;
context.querySelector('#chkSubtitle').checked = query.HasSubtitles === true;
context.querySelector('#chkTrailer').checked = query.HasTrailer === true;
context.querySelector('#chkThemeSong').checked = query.HasThemeSong === true;
context.querySelector('#chkThemeVideo').checked = query.HasThemeVideo === true;
context.querySelector('#chkSpecialFeature').checked = query.HasSpecialFeature === true;
context.querySelector('#chkSpecialEpisode').checked = query.ParentIndexNumber === 0;
context.querySelector('#chkMissingEpisode').checked = query.IsMissing === true;
context.querySelector('#chkFutureEpisode').checked = query.IsUnaired === true;
for (const elem of context.querySelectorAll('.chkStatus')) {
const filters = `,${query.SeriesStatus || ''}`;
const filterName = elem.getAttribute('data-filter');
elem.checked = filters.includes(`,${filterName}`);
}
}
/**
* @param instance {FilterDialog} An instance of FilterDialog
*/
function triggerChange(instance) {
events.trigger(instance, 'filterchange');
}
function setVisibility(context, options) {
if (options.mode == 'livetvchannels' || options.mode == 'albums' || options.mode == 'artists' || options.mode == 'albumartists' || options.mode == 'songs') {
if (options.mode === 'livetvchannels' || options.mode === 'albums' || options.mode === 'artists' || options.mode === 'albumartists' || options.mode === 'songs') {
hideByClass(context, 'videoStandard');
}
@ -115,263 +124,287 @@ define(['dom', 'dialogHelper', 'globalize', 'connectionManager', 'events', 'brow
context.querySelector('.yearFilters').classList.remove('hide');
}
if (options.mode == 'movies' || options.mode == 'episodes') {
if (options.mode === 'movies' || options.mode === 'episodes') {
context.querySelector('.videoTypeFilters').classList.remove('hide');
}
if (options.mode == 'movies' || options.mode == 'series' || options.mode == 'episodes') {
if (options.mode === 'movies' || options.mode === 'series' || options.mode === 'episodes') {
context.querySelector('.features').classList.remove('hide');
}
if (options.mode == 'series') {
if (options.mode === 'series') {
context.querySelector('.seriesStatus').classList.remove('hide');
}
if (options.mode == 'episodes') {
if (options.mode === 'episodes') {
showByClass(context, 'episodeFilter');
}
}
function showByClass(context, className) {
var elems = context.querySelectorAll('.' + className);
for (var i = 0, length = elems.length; i < length; i++) {
elems[i].classList.remove('hide');
for (const elem of context.querySelectorAll(`.${className}`)) {
elem.classList.remove('hide');
}
}
function hideByClass(context, className) {
var elems = context.querySelectorAll('.' + className);
for (var i = 0, length = elems.length; i < length; i++) {
elems[i].classList.add('hide');
for (const elem of context.querySelectorAll(`.${className}`)) {
elem.classList.add('hide');
}
}
function enableDynamicFilters(mode) {
return mode == 'movies' || mode == 'series' || mode == 'albums' || mode == 'albumartists' || mode == 'artists' || mode == 'songs' || mode == 'episodes';
return mode === 'movies' || mode === 'series' || mode === 'albums' || mode === 'albumartists' || mode === 'artists' || mode === 'songs' || mode === 'episodes';
}
return function (options) {
function onFavoriteChange() {
var query = options.query;
class FilterDialog {
constructor(options) {
/**
* @private
*/
this.options = options;
}
/**
* @private
*/
onFavoriteChange(elem) {
const query = this.options.query;
query.StartIndex = 0;
query.IsFavorite = !!this.checked || null;
triggerChange(self);
query.IsFavorite = !!elem.checked || null;
triggerChange(this);
}
function onStandardFilterChange() {
var query = options.query;
var filterName = this.getAttribute('data-filter');
var filters = query.Filters || '';
filters = (',' + filters).replace(',' + filterName, '').substring(1);
/**
* @private
*/
onStandardFilterChange(elem) {
const query = this.options.query;
const filterName = elem.getAttribute('data-filter');
let filters = query.Filters || '';
filters = (`,${filters}`).replace(`,${filterName}`, '').substring(1);
if (this.checked) {
filters = filters ? filters + ',' + filterName : filterName;
if (elem.checked) {
filters = filters ? `${filters},${filterName}` : filterName;
}
query.StartIndex = 0;
query.Filters = filters;
triggerChange(self);
triggerChange(this);
}
function onVideoTypeFilterChange() {
var query = options.query;
var filterName = this.getAttribute('data-filter');
var filters = query.VideoTypes || '';
filters = (',' + filters).replace(',' + filterName, '').substring(1);
/**
* @private
*/
onVideoTypeFilterChange(elem) {
const query = this.options.query;
const filterName = elem.getAttribute('data-filter');
let filters = query.VideoTypes || '';
filters = (`,${filters}`).replace(`,${filterName}`, '').substring(1);
if (this.checked) {
filters = filters ? filters + ',' + filterName : filterName;
if (elem.checked) {
filters = filters ? `${filters},${filterName}` : filterName;
}
query.StartIndex = 0;
query.VideoTypes = filters;
triggerChange(self);
triggerChange(this);
}
function onStatusChange() {
var query = options.query;
var filterName = this.getAttribute('data-filter');
var filters = query.SeriesStatus || '';
filters = (',' + filters).replace(',' + filterName, '').substring(1);
/**
* @private
*/
onStatusChange(elem) {
const query = this.options.query;
const filterName = elem.getAttribute('data-filter');
let filters = query.SeriesStatus || '';
filters = (`,${filters}`).replace(`,${filterName}`, '').substring(1);
if (this.checked) {
filters = filters ? filters + ',' + filterName : filterName;
if (elem.checked) {
filters = filters ? `${filters},${filterName}` : filterName;
}
query.SeriesStatus = filters;
query.StartIndex = 0;
triggerChange(self);
triggerChange(this);
}
function bindEvents(context) {
var elems;
var i;
var length;
var query = options.query;
/**
* @param context {HTMLDivElement} The dialog
*/
bindEvents(context) {
const query = this.options.query;
if (options.mode == 'livetvchannels') {
elems = context.querySelectorAll('.chkFavorite');
for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('change', onFavoriteChange);
if (this.options.mode === 'livetvchannels') {
for (const elem of context.querySelectorAll('.chkFavorite')) {
elem.addEventListener('change', () => this.onFavoriteChange(elem));
}
context.querySelector('.chkLikes').addEventListener('change', function () {
const chkLikes = context.querySelector('.chkLikes');
chkLikes.addEventListener('change', () => {
query.StartIndex = 0;
query.IsLiked = this.checked ? true : null;
triggerChange(self);
query.IsLiked = chkLikes.checked ? true : null;
triggerChange(this);
});
context.querySelector('.chkDislikes').addEventListener('change', function () {
const chkDislikes = context.querySelector('.chkDislikes');
chkDislikes.addEventListener('change', () => {
query.StartIndex = 0;
query.IsDisliked = this.checked ? true : null;
triggerChange(self);
query.IsDisliked = chkDislikes.checked ? true : null;
triggerChange(this);
});
} else {
elems = context.querySelectorAll('.chkStandardFilter');
for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('change', onStandardFilterChange);
for (const elem of context.querySelectorAll('.chkStandardFilter')) {
elem.addEventListener('change', () => this.onStandardFilterChange(elem));
}
}
elems = context.querySelectorAll('.chkVideoTypeFilter');
for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('change', onVideoTypeFilterChange);
for (const elem of context.querySelectorAll('.chkVideoTypeFilter')) {
elem.addEventListener('change', () => this.onVideoTypeFilterChange(elem));
}
context.querySelector('.chk3DFilter').addEventListener('change', function () {
const chk3DFilter = context.querySelector('.chk3DFilter');
chk3DFilter.addEventListener('change', () => {
query.StartIndex = 0;
query.Is3D = this.checked ? true : null;
triggerChange(self);
query.Is3D = chk3DFilter.checked ? true : null;
triggerChange(this);
});
context.querySelector('.chk4KFilter').addEventListener('change', function () {
const chk4KFilter = context.querySelector('.chk4KFilter');
chk4KFilter.addEventListener('change', () => {
query.StartIndex = 0;
query.Is4K = this.checked ? true : null;
triggerChange(self);
query.Is4K = chk4KFilter.checked ? true : null;
triggerChange(this);
});
context.querySelector('.chkHDFilter').addEventListener('change', function () {
const chkHDFilter = context.querySelector('.chkHDFilter');
chkHDFilter.addEventListener('change', () => {
query.StartIndex = 0;
query.IsHD = this.checked ? true : null;
triggerChange(self);
query.IsHD = chkHDFilter.checked ? true : null;
triggerChange(this);
});
context.querySelector('.chkSDFilter').addEventListener('change', function () {
const chkSDFilter = context.querySelector('.chkSDFilter');
chkSDFilter.addEventListener('change', () => {
query.StartIndex = 0;
query.IsHD = this.checked ? false : null;
triggerChange(self);
query.IsHD = chkSDFilter.checked ? false : null;
triggerChange(this);
});
elems = context.querySelectorAll('.chkStatus');
for (i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('change', onStatusChange);
for (const elem of context.querySelectorAll('.chkStatus')) {
elem.addEventListener('change', () => this.onStatusChange(elem));
}
context.querySelector('#chkTrailer').addEventListener('change', function () {
const chkTrailer = context.querySelector('#chkTrailer');
chkTrailer.addEventListener('change', () => {
query.StartIndex = 0;
query.HasTrailer = this.checked ? true : null;
triggerChange(self);
query.HasTrailer = chkTrailer.checked ? true : null;
triggerChange(this);
});
context.querySelector('#chkThemeSong').addEventListener('change', function () {
const chkThemeSong = context.querySelector('#chkThemeSong');
chkThemeSong.addEventListener('change', () => {
query.StartIndex = 0;
query.HasThemeSong = this.checked ? true : null;
triggerChange(self);
query.HasThemeSong = chkThemeSong.checked ? true : null;
triggerChange(this);
});
context.querySelector('#chkSpecialFeature').addEventListener('change', function () {
const chkSpecialFeature = context.querySelector('#chkSpecialFeature');
chkSpecialFeature.addEventListener('change', () => {
query.StartIndex = 0;
query.HasSpecialFeature = this.checked ? true : null;
triggerChange(self);
query.HasSpecialFeature = chkSpecialFeature.checked ? true : null;
triggerChange(this);
});
context.querySelector('#chkThemeVideo').addEventListener('change', function () {
const chkThemeVideo = context.querySelector('#chkThemeVideo');
chkThemeVideo.addEventListener('change', () => {
query.StartIndex = 0;
query.HasThemeVideo = this.checked ? true : null;
triggerChange(self);
query.HasThemeVideo = chkThemeVideo.checked ? true : null;
triggerChange(this);
});
context.querySelector('#chkMissingEpisode').addEventListener('change', function () {
const chkMissingEpisode = context.querySelector('#chkMissingEpisode');
chkMissingEpisode.addEventListener('change', () => {
query.StartIndex = 0;
query.IsMissing = this.checked ? true : false;
triggerChange(self);
query.IsMissing = !!chkMissingEpisode.checked;
triggerChange(this);
});
context.querySelector('#chkSpecialEpisode').addEventListener('change', function () {
const chkSpecialEpisode = context.querySelector('#chkSpecialEpisode');
chkSpecialEpisode.addEventListener('change', () => {
query.StartIndex = 0;
query.ParentIndexNumber = this.checked ? 0 : null;
triggerChange(self);
query.ParentIndexNumber = chkSpecialEpisode.checked ? 0 : null;
triggerChange(this);
});
context.querySelector('#chkFutureEpisode').addEventListener('change', function () {
const chkFutureEpisode = context.querySelector('#chkFutureEpisode');
chkFutureEpisode.addEventListener('change', () => {
query.StartIndex = 0;
if (this.checked) {
if (chkFutureEpisode.checked) {
query.IsUnaired = true;
query.IsVirtualUnaired = null;
} else {
query.IsUnaired = null;
query.IsVirtualUnaired = false;
}
triggerChange(self);
triggerChange(this);
});
context.querySelector('#chkSubtitle').addEventListener('change', function () {
const chkSubtitle = context.querySelector('#chkSubtitle');
chkSubtitle.addEventListener('change', () => {
query.StartIndex = 0;
query.HasSubtitles = this.checked ? true : null;
triggerChange(self);
query.HasSubtitles = chkSubtitle.checked ? true : null;
triggerChange(this);
});
context.addEventListener('change', function (e) {
var chkGenreFilter = dom.parentWithClass(e.target, 'chkGenreFilter');
context.addEventListener('change', (e) => {
const chkGenreFilter = dom.parentWithClass(e.target, 'chkGenreFilter');
if (chkGenreFilter) {
var filterName = chkGenreFilter.getAttribute('data-filter');
var filters = query.Genres || '';
var delimiter = '|';
const filterName = chkGenreFilter.getAttribute('data-filter');
let filters = query.Genres || '';
const delimiter = '|';
filters = (delimiter + filters).replace(delimiter + filterName, '').substring(1);
if (chkGenreFilter.checked) {
filters = filters ? (filters + delimiter + filterName) : filterName;
}
query.StartIndex = 0;
query.Genres = filters;
triggerChange(self);
triggerChange(this);
return;
}
var chkTagFilter = dom.parentWithClass(e.target, 'chkTagFilter');
const chkTagFilter = dom.parentWithClass(e.target, 'chkTagFilter');
if (chkTagFilter) {
var filterName = chkTagFilter.getAttribute('data-filter');
var filters = query.Tags || '';
var delimiter = '|';
const filterName = chkTagFilter.getAttribute('data-filter');
let filters = query.Tags || '';
const delimiter = '|';
filters = (delimiter + filters).replace(delimiter + filterName, '').substring(1);
if (chkTagFilter.checked) {
filters = filters ? (filters + delimiter + filterName) : filterName;
}
query.StartIndex = 0;
query.Tags = filters;
triggerChange(self);
triggerChange(this);
return;
}
var chkYearFilter = dom.parentWithClass(e.target, 'chkYearFilter');
const chkYearFilter = dom.parentWithClass(e.target, 'chkYearFilter');
if (chkYearFilter) {
var filterName = chkYearFilter.getAttribute('data-filter');
var filters = query.Years || '';
var delimiter = ',';
const filterName = chkYearFilter.getAttribute('data-filter');
let filters = query.Years || '';
const delimiter = ',';
filters = (delimiter + filters).replace(delimiter + filterName, '').substring(1);
if (chkYearFilter.checked) {
filters = filters ? (filters + delimiter + filterName) : filterName;
}
query.StartIndex = 0;
query.Years = filters;
triggerChange(self);
triggerChange(this);
return;
}
var chkOfficialRatingFilter = dom.parentWithClass(e.target, 'chkOfficialRatingFilter');
const chkOfficialRatingFilter = dom.parentWithClass(e.target, 'chkOfficialRatingFilter');
if (chkOfficialRatingFilter) {
var filterName = chkOfficialRatingFilter.getAttribute('data-filter');
var filters = query.OfficialRatings || '';
var delimiter = '|';
const filterName = chkOfficialRatingFilter.getAttribute('data-filter');
let filters = query.OfficialRatings || '';
const delimiter = '|';
filters = (delimiter + filters).replace(delimiter + filterName, '').substring(1);
if (chkOfficialRatingFilter.checked) {
filters = filters ? (filters + delimiter + filterName) : filterName;
}
query.StartIndex = 0;
query.OfficialRatings = filters;
triggerChange(self);
return;
triggerChange(this);
}
});
}
var self = this;
self.show = function () {
return new Promise(function (resolve, reject) {
require(['text!./filterdialog.template.html'], function (template) {
var dlg = dialogHelper.createDialog({
show() {
return import('text!./filterdialog.template.html').then(({default: template}) => {
return new Promise((resolve) => {
const dlg = dialogHelper.createDialog({
removeOnClose: true,
modal: false
});
@ -380,18 +413,21 @@ define(['dom', 'dialogHelper', 'globalize', 'connectionManager', 'events', 'brow
dlg.classList.add('formDialog');
dlg.classList.add('filterDialog');
dlg.innerHTML = globalize.translateDocument(template);
setVisibility(dlg, options);
setVisibility(dlg, this.options);
dialogHelper.open(dlg);
dlg.addEventListener('close', resolve);
updateFilterControls(dlg, options);
bindEvents(dlg);
if (enableDynamicFilters(options.mode)) {
updateFilterControls(dlg, this.options);
this.bindEvents(dlg);
if (enableDynamicFilters(this.options.mode)) {
dlg.classList.add('dynamicFilterDialog');
var apiClient = connectionManager.getApiClient(options.serverId);
loadDynamicFilters(dlg, apiClient, apiClient.getCurrentUserId(), options.query);
const apiClient = connectionManager.getApiClient(this.options.serverId);
loadDynamicFilters(dlg, apiClient, apiClient.getCurrentUserId(), this.options.query);
}
});
});
};
};
});
}
}
/* eslint-enable indent */
export default FilterDialog;

View file

@ -1,5 +1,6 @@
import * as lazyLoader from 'lazyLoader';
import * as userSettings from 'userSettings';
import * as blurhash from 'blurhash';
import 'css!./style';
/* eslint-disable indent */
@ -11,47 +12,111 @@ import 'css!./style';
fillImageElement(elem, source);
}
async function itemBlurhashing(target, blurhashstr) {
if (blurhash.isBlurhashValid(blurhashstr)) {
// Although the default values recommended by Blurhash developers is 32x32, a size of 18x18 seems to be the sweet spot for us,
// improving the performance and reducing the memory usage, while retaining almost full blur quality.
// Lower values had more visible pixelation
let width = 18;
let height = 18;
let pixels;
try {
pixels = blurhash.decode(blurhashstr, width, height);
} catch (err) {
console.error('Blurhash decode error: ', err);
target.classList.add('non-blurhashable');
return;
}
let canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
let ctx = canvas.getContext('2d');
let imgData = ctx.createImageData(width, height);
imgData.data.set(pixels);
ctx.putImageData(imgData, 0, 0);
let child = target.appendChild(canvas);
child.classList.add('blurhash-canvas');
child.style.opacity = 1;
if (userSettings.enableFastFadein()) {
child.classList.add('lazy-blurhash-fadein-fast');
} else {
child.classList.add('lazy-blurhash-fadein');
}
target.classList.add('blurhashed');
target.removeAttribute('data-blurhash');
}
}
function switchCanvas(elem) {
let child = elem.getElementsByClassName('blurhash-canvas')[0];
if (child) {
child.style.opacity = elem.getAttribute('data-src') ? 1 : 0;
}
}
export function fillImage(entry) {
if (!entry) {
throw new Error('entry cannot be null');
}
let target = entry.target;
var source = undefined;
if (entry.target) {
source = entry.target.getAttribute('data-src');
if (target) {
source = target.getAttribute('data-src');
var blurhashstr = target.getAttribute('data-blurhash');
} else {
source = entry;
}
if (userSettings.enableBlurhash()) {
if (!target.classList.contains('blurhashed', 'non-blurhashable') && blurhashstr) {
itemBlurhashing(target, blurhashstr);
} else if (!blurhashstr && !target.classList.contains('blurhashed')) {
target.classList.add('non-blurhashable');
}
}
if (entry.intersectionRatio > 0) {
if (source) fillImageElement(entry.target, source);
if (source) fillImageElement(target, source);
} else if (!source) {
emptyImageElement(entry.target);
emptyImageElement(target);
}
}
function fillImageElement(elem, url) {
if (url === undefined) {
throw new Error('url cannot be undefined');
throw new TypeError('url cannot be undefined');
}
let preloaderImg = new Image();
preloaderImg.src = url;
// This is necessary here, so changing blurhash settings without reloading the page works
if (!userSettings.enableBlurhash() || elem.classList.contains('non-blurhashable')) {
elem.classList.add('lazy-hidden');
}
preloaderImg.addEventListener('load', () => {
if (elem.tagName !== 'IMG') {
elem.style.backgroundImage = "url('" + url + "')";
} else {
elem.setAttribute('src', url);
}
elem.removeAttribute('data-src');
if (elem.classList.contains('non-blurhashable') || !userSettings.enableBlurhash()) {
elem.classList.remove('lazy-hidden');
if (userSettings.enableFastFadein()) {
elem.classList.add('lazy-image-fadein-fast');
} else {
elem.classList.add('lazy-image-fadein');
}
elem.removeAttribute('data-src');
} else {
switchCanvas(elem);
}
});
}
@ -65,11 +130,14 @@ import 'css!./style';
url = elem.getAttribute('src');
elem.setAttribute('src', '');
}
elem.setAttribute('data-src', url);
elem.classList.remove('lazy-image-fadein-fast');
elem.classList.remove('lazy-image-fadein');
if (elem.classList.contains('non-blurhashable') || !userSettings.enableBlurhash()) {
elem.classList.remove('lazy-image-fadein-fast', 'lazy-image-fadein');
elem.classList.add('lazy-hidden');
} else {
switchCanvas(elem);
}
}
export function lazyChildren(elem) {

View file

@ -1,13 +1,32 @@
.cardImageContainer.lazy {
opacity: 0;
}
.cardImageContainer.lazy.lazy-image-fadein {
.lazy-image-fadein {
opacity: 1;
transition: opacity 0.7s;
}
.cardImageContainer.lazy.lazy-image-fadein-fast {
.lazy-image-fadein-fast {
opacity: 1;
transition: opacity 0.2s;
}
.lazy-hidden {
opacity: 0;
}
.lazy-blurhash-fadein-fast {
transition: opacity 0.2s;
}
.lazy-blurhash-fadein {
transition: opacity 0.7s;
}
.blurhash-canvas {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 100;
}

View file

@ -70,6 +70,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
function getImageUrl(item, width) {
var apiClient = connectionManager.getApiClient(item.ServerId);
let itemId;
var options = {
maxWidth: width * 2,
@ -77,45 +78,45 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
};
if (item.ImageTags && item.ImageTags.Primary) {
options.tag = item.ImageTags.Primary;
return apiClient.getScaledImageUrl(item.Id, options);
itemId = item.Id;
}
if (item.AlbumId && item.AlbumPrimaryImageTag) {
options.tag = item.AlbumPrimaryImageTag;
return apiClient.getScaledImageUrl(item.AlbumId, options);
itemId = item.AlbumId;
} else if (item.SeriesId && item.SeriesPrimaryImageTag) {
options.tag = item.SeriesPrimaryImageTag;
return apiClient.getScaledImageUrl(item.SeriesId, options);
itemId = item.SeriesId;
} else if (item.ParentPrimaryImageTag) {
options.tag = item.ParentPrimaryImageTag;
return apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, options);
itemId = item.ParentPrimaryImageItemId;
}
let blurHashes = item.ImageBlurHashes || {};
let blurhashstr = (blurHashes[options.type] || {})[options.tag];
return null;
if (itemId) {
return { url: apiClient.getScaledImageUrl(itemId, options), blurhash: blurhashstr };
}
}
function getChannelImageUrl(item, width) {
var apiClient = connectionManager.getApiClient(item.ServerId);
var options = {
maxWidth: width * 2,
type: 'Primary'
};
if (item.ChannelId && item.ChannelPrimaryImageTag) {
options.tag = item.ChannelPrimaryImageTag;
return apiClient.getScaledImageUrl(item.ChannelId, options);
}
let blurHashes = item.ImageBlurHashes || {};
let blurhashstr = (blurHashes[options.type])[options.tag];
return null;
if (item.ChannelId) {
return { url: apiClient.getScaledImageUrl(item.ChannelId, options), blurhash: blurhashstr };
}
}
function getTextLinesHtml(textlines, isLargeStyle) {
@ -268,8 +269,10 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
}
if (options.image !== false) {
var imgUrl = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth);
var imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage';
let imgData = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth);
let imgUrl = imgData.url;
let blurhash = imgData.blurhash;
let imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage';
if (isLargeStyle && layoutManager.tv) {
imageClass += ' listItemImage-large-tv';
@ -283,8 +286,13 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
var imageAction = playOnImageClick ? 'resume' : action;
let blurhashAttrib = '';
if (blurhash && blurhash.length > 0) {
blurhashAttrib = 'data-blurhash="' + blurhash + '"';
}
if (imgUrl) {
html += '<div data-action="' + imageAction + '" class="' + imageClass + ' lazy" data-src="' + imgUrl + '" item-icon>';
html += '<div data-action="' + imageAction + '" class="' + imageClass + ' lazy" data-src="' + imgUrl + '" ' + blurhashAttrib + ' item-icon>';
} else {
html += '<div class="' + imageClass + '">';
}

View file

@ -273,7 +273,7 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater
}
}
if (item.RunTimeTicks && item.Type !== 'Series' && item.Type !== 'Program' && !showFolderRuntime && options.runtime !== false) {
if (item.RunTimeTicks && item.Type !== 'Series' && item.Type !== 'Program' && item.Type !== 'Book' && !showFolderRuntime && options.runtime !== false) {
if (item.Type === 'Audio') {

View file

@ -1,5 +1,9 @@
define(['events', 'playbackManager', 'dom', 'browser', 'css!./iconosd', 'material-icons'], function (events, playbackManager, dom, browser) {
'use strict';
import events from 'events';
import playbackManager from 'playbackManager';
import dom from 'dom';
import browser from 'browser';
import 'css!./iconosd';
import 'material-icons';
var currentPlayer;
var osdElement;
@ -99,9 +103,7 @@ define(['events', 'playbackManager', 'dom', 'browser', 'css!./iconosd', 'materia
}
function setIcon(iconElement, icon) {
iconElement.classList.remove('brightness_high');
iconElement.classList.remove('brightness_medium');
iconElement.classList.remove('brightness_low');
iconElement.classList.remove('brightness_high', 'brightness_medium', 'brightness_low');
iconElement.classList.add(icon);
}
@ -167,5 +169,3 @@ define(['events', 'playbackManager', 'dom', 'browser', 'css!./iconosd', 'materia
});
bindToPlayer(playbackManager.getCurrentPlayer());
});

View file

@ -1,7 +1,4 @@
define([], function () {
'use strict';
function getNowPlayingNames(nowPlayingItem, includeNonNameInfo) {
export function getNowPlayingNames(nowPlayingItem, includeNonNameInfo) {
var topItem = nowPlayingItem;
var bottomItem = null;
@ -80,7 +77,6 @@ define([], function () {
return list;
}
return {
export default {
getNowPlayingNames: getNowPlayingNames
};
});

View file

@ -1907,11 +1907,8 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
// Setting this to true may cause some incorrect sorting
Recursive: false,
SortBy: options.shuffle ? 'Random' : 'SortName',
MediaTypes: 'Photo,Video',
Limit: 500
MediaTypes: 'Photo,Video'
}).then(function (result) {
var items = result.Items;
var index = items.map(function (i) {

View file

@ -1,5 +1,6 @@
define(['playbackManager', 'layoutManager', 'events'], function (playbackManager, layoutManager, events) {
'use strict';
import playbackManager from 'playbackManager';
import layoutManager from 'layoutManager';
import events from 'events';
var orientationLocked;
@ -54,4 +55,3 @@ define(['playbackManager', 'layoutManager', 'events'], function (playbackManager
}
}
});
});

View file

@ -1,5 +1,11 @@
define(['appSettings', 'events', 'browser', 'loading', 'playbackManager', 'appRouter', 'globalize', 'apphost'], function (appSettings, events, browser, loading, playbackManager, appRouter, globalize, appHost) {
'use strict';
import appSettings from 'appSettings';
import events from 'events';
import browser from 'browser';
import loading from 'loading';
import playbackManager from 'playbackManager';
import appRouter from 'appRouter';
import globalize from 'globalize';
import appHost from 'apphost';
function mirrorItem(info, player) {
@ -77,7 +83,7 @@ define(['appSettings', 'events', 'browser', 'loading', 'playbackManager', 'appRo
}
}
function showPlayerSelection(button) {
export function show(button) {
var currentPlayerInfo = playbackManager.getPlayerInfo();
@ -314,7 +320,6 @@ define(['appSettings', 'events', 'browser', 'loading', 'playbackManager', 'appRo
loading.hide();
});
return {
show: showPlayerSelection
export default {
show: show
};
});

View file

@ -1,5 +1,8 @@
define(['connectionManager', 'actionsheet', 'datetime', 'playbackManager', 'globalize', 'appSettings', 'qualityoptions'], function (connectionManager, actionsheet, datetime, playbackManager, globalize, appSettings, qualityoptions) {
'use strict';
import connectionManager from 'connectionManager';
import actionsheet from 'actionsheet';
import playbackManager from 'playbackManager';
import globalize from 'globalize';
import qualityoptions from 'qualityoptions';
function showQualityMenu(player, btn) {
@ -225,7 +228,7 @@ define(['connectionManager', 'actionsheet', 'datetime', 'playbackManager', 'glob
});
}
function show(options) {
export function show(options) {
var player = options.player;
var currentItem = playbackManager.currentItem(player);
@ -264,7 +267,6 @@ define(['connectionManager', 'actionsheet', 'datetime', 'playbackManager', 'glob
return Promise.reject();
}
return {
export default {
show: show
};
});

View file

@ -1,7 +1,4 @@
define([], function () {
'use strict';
function getDisplayPlayMethod(session) {
export function getDisplayPlayMethod(session) {
if (!session.NowPlayingItem) {
return null;
@ -18,7 +15,6 @@ define([], function () {
}
}
return {
export default {
getDisplayPlayMethod: getDisplayPlayMethod
};
});

View file

@ -1,5 +1,9 @@
define(['events', 'playbackManager', 'dom', 'browser', 'css!./iconosd', 'material-icons'], function (events, playbackManager, dom, browser) {
'use strict';
import events from 'events';
import playbackManager from 'playbackManager';
import dom from 'dom';
import browser from 'browser';
import 'css!./iconosd';
import 'material-icons';
var currentPlayer;
var osdElement;
@ -155,5 +159,3 @@ define(['events', 'playbackManager', 'dom', 'browser', 'css!./iconosd', 'materia
});
bindToPlayer(playbackManager.getCurrentPlayer());
});

View file

@ -1,6 +1,6 @@
/**
* Module that manages the SyncPlay feature.
* @module components/syncplay/syncPlayManager
* @module components/syncPlay/syncPlayManager
*/
import events from 'events';

View file

@ -1,6 +1,6 @@
/**
* Module that manages time syncing with server.
* @module components/syncplay/timeSyncManager
* @module components/syncPlay/timeSyncManager
*/
import events from 'events';

View file

@ -57,7 +57,7 @@ define(['require', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'conne
return new Promise(function (resolve, reject) {
require(['text!./viewsettings.template.html'], function (template) {
require(['text!./viewSettings.template.html'], function (template) {
var dialogOptions = {
removeOnClose: true,

1
src/config.json Symbolic link
View file

@ -0,0 +1 @@
config.template.json

View file

@ -1,3 +1,3 @@
{
"multiserver": true
"multiserver": false
}

View file

@ -23,8 +23,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in
$('.chkMediaType', page).each(function () {
this.checked = -1 != (profile.SupportedMediaTypes || '').split(',').indexOf(this.getAttribute('data-value'));
});
$('#chkEnableAlbumArtInDidl', page).checked = profile.EnableAlbumArtInDidl;
$('#chkEnableSingleImageLimit', page).checked = profile.EnableSingleAlbumArtLimit;
$('#chkEnableAlbumArtInDidl', page).prop('checked', profile.EnableAlbumArtInDidl);
$('#chkEnableSingleImageLimit', page).prop('checked', profile.EnableSingleAlbumArtLimit);
renderXmlDocumentAttributes(page, profile.XmlRootAttributes || []);
var idInfo = profile.Identification || {};
renderIdentificationHeaders(page, idInfo.Headers || []);
@ -51,11 +51,11 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in
$('#txtAlbumArtMaxHeight', page).val(profile.MaxAlbumArtHeight || '');
$('#txtIconMaxWidth', page).val(profile.MaxIconWidth || '');
$('#txtIconMaxHeight', page).val(profile.MaxIconHeight || '');
$('#chkIgnoreTranscodeByteRangeRequests', page).checked = profile.IgnoreTranscodeByteRangeRequests;
$('#chkIgnoreTranscodeByteRangeRequests', page).prop('checked', profile.IgnoreTranscodeByteRangeRequests);
$('#txtMaxAllowedBitrate', page).val(profile.MaxStreamingBitrate || '');
$('#txtMusicStreamingTranscodingBitrate', page).val(profile.MusicStreamingTranscodingBitrate || '');
$('#chkRequiresPlainFolders', page).checked = profile.RequiresPlainFolders;
$('#chkRequiresPlainVideoItems', page).checked = profile.RequiresPlainVideoItems;
$('#chkRequiresPlainFolders', page).prop('checked', profile.RequiresPlainFolders);
$('#chkRequiresPlainVideoItems', page).prop('checked', profile.RequiresPlainVideoItems);
$('#txtProtocolInfo', page).val(profile.ProtocolInfo || '');
$('#txtXDlnaCap', page).val(profile.XDlnaCap || '');
$('#txtXDlnaDoc', page).val(profile.XDlnaDoc || '');
@ -357,9 +357,9 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in
$('#txtTranscodingAudioCodec', popup).val(transcodingProfile.AudioCodec || '');
$('#txtTranscodingVideoCodec', popup).val(transcodingProfile.VideoCodec || '');
$('#selectTranscodingProtocol', popup).val(transcodingProfile.Protocol || 'Http');
$('#chkEnableMpegtsM2TsMode', popup).checked = transcodingProfile.EnableMpegtsM2TsMode || false;
$('#chkEstimateContentLength', popup).checked = transcodingProfile.EstimateContentLength || false;
$('#chkReportByteRangeRequests', popup).checked = 'Bytes' == transcodingProfile.TranscodeSeekInfo;
$('#chkEnableMpegtsM2TsMode', popup).prop('checked', transcodingProfile.EnableMpegtsM2TsMode || false);
$('#chkEstimateContentLength', popup).prop('checked', transcodingProfile.EstimateContentLength || false);
$('#chkReportByteRangeRequests', popup).prop('checked', 'Bytes' == transcodingProfile.TranscodeSeekInfo);
$('.radioTabButton:first', popup).trigger('click');
openPopup(popup[0]);
}
@ -376,9 +376,9 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in
currentSubProfile.VideoCodec = $('#txtTranscodingVideoCodec', page).val();
currentSubProfile.Protocol = $('#selectTranscodingProtocol', page).val();
currentSubProfile.Context = 'Streaming';
currentSubProfile.EnableMpegtsM2TsMode = $('#chkEnableMpegtsM2TsMode', page).checked;
currentSubProfile.EstimateContentLength = $('#chkEstimateContentLength', page).checked;
currentSubProfile.TranscodeSeekInfo = $('#chkReportByteRangeRequests', page).checked ? 'Bytes' : 'Auto';
currentSubProfile.EnableMpegtsM2TsMode = $('#chkEnableMpegtsM2TsMode', page).is(':checked');
currentSubProfile.EstimateContentLength = $('#chkEstimateContentLength', page).is(':checked');
currentSubProfile.TranscodeSeekInfo = $('#chkReportByteRangeRequests', page).is(':checked') ? 'Bytes' : 'Auto';
if (isSubProfileNew) {
currentProfile.TranscodingProfiles.push(currentSubProfile);
@ -647,8 +647,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in
function updateProfile(page, profile) {
profile.Name = $('#txtName', page).val();
profile.EnableAlbumArtInDidl = $('#chkEnableAlbumArtInDidl', page).checked;
profile.EnableSingleAlbumArtLimit = $('#chkEnableSingleImageLimit', page).checked;
profile.EnableAlbumArtInDidl = $('#chkEnableAlbumArtInDidl', page).is(':checked');
profile.EnableSingleAlbumArtLimit = $('#chkEnableSingleImageLimit', page).is(':checked');
profile.SupportedMediaTypes = $('.chkMediaType:checked', page).get().map(function (c) {
return c.getAttribute('data-value');
}).join(',');
@ -675,9 +675,9 @@ define(['jQuery', 'loading', 'globalize', 'emby-select', 'emby-button', 'emby-in
profile.MaxAlbumArtHeight = $('#txtAlbumArtMaxHeight', page).val();
profile.MaxIconWidth = $('#txtIconMaxWidth', page).val();
profile.MaxIconHeight = $('#txtIconMaxHeight', page).val();
profile.RequiresPlainFolders = $('#chkRequiresPlainFolders', page).checked;
profile.RequiresPlainVideoItems = $('#chkRequiresPlainVideoItems', page).checked;
profile.IgnoreTranscodeByteRangeRequests = $('#chkIgnoreTranscodeByteRangeRequests', page).checked;
profile.RequiresPlainFolders = $('#chkRequiresPlainFolders', page).is(':checked');
profile.RequiresPlainVideoItems = $('#chkRequiresPlainVideoItems', page).is(':checked');
profile.IgnoreTranscodeByteRangeRequests = $('#chkIgnoreTranscodeByteRangeRequests', page).is(':checked');
profile.MaxStreamingBitrate = $('#txtMaxAllowedBitrate', page).val();
profile.MusicStreamingTranscodingBitrate = $('#txtMusicStreamingTranscodingBitrate', page).val();
profile.ProtocolInfo = $('#txtProtocolInfo', page).val();

View file

@ -5,8 +5,8 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading,
page.querySelector('#chkEnablePlayTo').checked = config.EnablePlayTo;
page.querySelector('#chkEnableDlnaDebugLogging').checked = config.EnableDebugLog;
$('#txtClientDiscoveryInterval', page).val(config.ClientDiscoveryIntervalSeconds);
$('#chkEnableServer', page).checked = config.EnableServer;
$('#chkBlastAliveMessages', page).checked = config.BlastAliveMessages;
$('#chkEnableServer', page).prop('checked', config.EnableServer);
$('#chkBlastAliveMessages', page).prop('checked', config.BlastAliveMessages);
$('#txtBlastInterval', page).val(config.BlastAliveMessageIntervalSeconds);
var usersHtml = users.map(function (u) {
return '<option value="' + u.Id + '">' + u.Name + '</option>';
@ -22,8 +22,8 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading,
config.EnablePlayTo = form.querySelector('#chkEnablePlayTo').checked;
config.EnableDebugLog = form.querySelector('#chkEnableDlnaDebugLogging').checked;
config.ClientDiscoveryIntervalSeconds = $('#txtClientDiscoveryInterval', form).val();
config.EnableServer = $('#chkEnableServer', form).checked;
config.BlastAliveMessages = $('#chkBlastAliveMessages', form).checked;
config.EnableServer = $('#chkEnableServer', form).is(':checked');
config.BlastAliveMessages = $('#chkBlastAliveMessages', form).is(':checked');
config.BlastAliveMessageIntervalSeconds = $('#txtBlastInterval', form).val();
config.DefaultUserId = $('#selectUser', form).val();
ApiClient.updateNamedConfiguration('dlna', config).then(Dashboard.processServerConfigurationUpdateResult);

View file

@ -50,7 +50,7 @@ define(['jQuery', 'emby-checkbox'], function ($) {
fillItems($('.monitorUsersList', page), users, 'chkMonitor', 'chkMonitor', notificationConfig.DisabledMonitorUsers);
fillItems($('.sendToUsersList', page), users, 'chkSendTo', 'chkSendTo', notificationConfig.SendToUsers, true);
fillItems($('.servicesList', page), services, 'chkService', 'chkService', notificationConfig.DisabledServices);
$('#chkEnabled', page).checked = notificationConfig.Enabled || false;
$('#chkEnabled', page).prop('checked', notificationConfig.Enabled || false);
$('#selectUsers', page).val(notificationConfig.SendToUserMode).trigger('change');
});
}
@ -73,7 +73,7 @@ define(['jQuery', 'emby-checkbox'], function ($) {
notificationOptions.Options.push(notificationConfig);
}
notificationConfig.Enabled = $('#chkEnabled', page).checked;
notificationConfig.Enabled = $('#chkEnabled', page).is(':checked');
notificationConfig.SendToUserMode = $('#selectUsers', page).val();
notificationConfig.DisabledMonitorUsers = $('.chkMonitor', page).get().filter(function (c) {
return !c.checked;

View file

@ -50,7 +50,7 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'
html += '<button type="button" is="paper-icon-button-light" class="btnCardMenu autoSize"><span class="material-icons more_vert"></span></button>';
html += '</div>';
html += "<div class='cardText'>";
html += configPage.DisplayName || plugin.Name;
html += configPage && configPage.DisplayName ? configPage.DisplayName : plugin.Name;
html += '</div>';
html += "<div class='cardText cardText-secondary'>";
html += plugin.Version;

View file

@ -27,7 +27,7 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading,
}
$('.deleteAccess', page).html(html).trigger('create');
$('#chkEnableDeleteAllFolders', page).checked = user.Policy.EnableContentDeletion;
$('#chkEnableDeleteAllFolders', page).prop('checked', user.Policy.EnableContentDeletion);
});
}
@ -85,23 +85,23 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading,
libraryMenu.setTitle(user.Name);
page.querySelector('.username').innerHTML = user.Name;
$('#txtUserName', page).val(user.Name);
$('#chkIsAdmin', page).checked = user.Policy.IsAdministrator;
$('#chkDisabled', page).checked = user.Policy.IsDisabled;
$('#chkIsHidden', page).checked = user.Policy.IsHidden;
$('#chkRemoteControlSharedDevices', page).checked = user.Policy.EnableSharedDeviceControl;
$('#chkEnableRemoteControlOtherUsers', page).checked = user.Policy.EnableRemoteControlOfOtherUsers;
$('#chkEnableDownloading', page).checked = user.Policy.EnableContentDownloading;
$('#chkManageLiveTv', page).checked = user.Policy.EnableLiveTvManagement;
$('#chkEnableLiveTvAccess', page).checked = user.Policy.EnableLiveTvAccess;
$('#chkEnableMediaPlayback', page).checked = user.Policy.EnableMediaPlayback;
$('#chkEnableAudioPlaybackTranscoding', page).checked = user.Policy.EnableAudioPlaybackTranscoding;
$('#chkEnableVideoPlaybackTranscoding', page).checked = user.Policy.EnableVideoPlaybackTranscoding;
$('#chkEnableVideoPlaybackRemuxing', page).checked = user.Policy.EnablePlaybackRemuxing;
$('#chkForceRemoteSourceTranscoding', page).checked = user.Policy.ForceRemoteSourceTranscoding;
$('#chkRemoteAccess', page).checked = null == user.Policy.EnableRemoteAccess || user.Policy.EnableRemoteAccess;
$('#chkEnableSyncTranscoding', page).checked = user.Policy.EnableSyncTranscoding;
$('#chkEnableConversion', page).checked = user.Policy.EnableMediaConversion || false;
$('#chkEnableSharing', page).checked = user.Policy.EnablePublicSharing;
$('#chkIsAdmin', page).prop('checked', user.Policy.IsAdministrator);
$('#chkDisabled', page).prop('checked', user.Policy.IsDisabled);
$('#chkIsHidden', page).prop('checked', user.Policy.IsHidden);
$('#chkRemoteControlSharedDevices', page).prop('checked', user.Policy.EnableSharedDeviceControl);
$('#chkEnableRemoteControlOtherUsers', page).prop('checked', user.Policy.EnableRemoteControlOfOtherUsers);
$('#chkEnableDownloading', page).prop('checked', user.Policy.EnableContentDownloading);
$('#chkManageLiveTv', page).prop('checked', user.Policy.EnableLiveTvManagement);
$('#chkEnableLiveTvAccess', page).prop('checked', user.Policy.EnableLiveTvAccess);
$('#chkEnableMediaPlayback', page).prop('checked', user.Policy.EnableMediaPlayback);
$('#chkEnableAudioPlaybackTranscoding', page).prop('checked', user.Policy.EnableAudioPlaybackTranscoding);
$('#chkEnableVideoPlaybackTranscoding', page).prop('checked', user.Policy.EnableVideoPlaybackTranscoding);
$('#chkEnableVideoPlaybackRemuxing', page).prop('checked', user.Policy.EnablePlaybackRemuxing);
$('#chkForceRemoteSourceTranscoding', page).prop('checked', user.Policy.ForceRemoteSourceTranscoding);
$('#chkRemoteAccess', page).prop('checked', null == user.Policy.EnableRemoteAccess || user.Policy.EnableRemoteAccess);
$('#chkEnableSyncTranscoding', page).prop('checked', user.Policy.EnableSyncTranscoding);
$('#chkEnableConversion', page).prop('checked', user.Policy.EnableMediaConversion || false);
$('#chkEnableSharing', page).prop('checked', user.Policy.EnablePublicSharing);
$('#txtRemoteClientBitrateLimit', page).val(user.Policy.RemoteClientBitrateLimit / 1e6 || '');
$('#txtLoginAttemptsBeforeLockout', page).val(user.Policy.LoginAttemptsBeforeLockout || '0');
$('#selectSyncPlayAccess').val(user.Policy.SyncPlayAccess);
@ -119,28 +119,28 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading,
function saveUser(user, page) {
user.Name = $('#txtUserName', page).val();
user.Policy.IsAdministrator = $('#chkIsAdmin', page).checked;
user.Policy.IsHidden = $('#chkIsHidden', page).checked;
user.Policy.IsDisabled = $('#chkDisabled', page).checked;
user.Policy.EnableRemoteControlOfOtherUsers = $('#chkEnableRemoteControlOtherUsers', page).checked;
user.Policy.EnableLiveTvManagement = $('#chkManageLiveTv', page).checked;
user.Policy.EnableLiveTvAccess = $('#chkEnableLiveTvAccess', page).checked;
user.Policy.EnableSharedDeviceControl = $('#chkRemoteControlSharedDevices', page).checked;
user.Policy.EnableMediaPlayback = $('#chkEnableMediaPlayback', page).checked;
user.Policy.EnableAudioPlaybackTranscoding = $('#chkEnableAudioPlaybackTranscoding', page).checked;
user.Policy.EnableVideoPlaybackTranscoding = $('#chkEnableVideoPlaybackTranscoding', page).checked;
user.Policy.EnablePlaybackRemuxing = $('#chkEnableVideoPlaybackRemuxing', page).checked;
user.Policy.ForceRemoteSourceTranscoding = $('#chkForceRemoteSourceTranscoding', page).checked;
user.Policy.EnableContentDownloading = $('#chkEnableDownloading', page).checked;
user.Policy.EnableSyncTranscoding = $('#chkEnableSyncTranscoding', page).checked;
user.Policy.EnableMediaConversion = $('#chkEnableConversion', page).checked;
user.Policy.EnablePublicSharing = $('#chkEnableSharing', page).checked;
user.Policy.EnableRemoteAccess = $('#chkRemoteAccess', page).checked;
user.Policy.IsAdministrator = $('#chkIsAdmin', page).is(':checked');
user.Policy.IsHidden = $('#chkIsHidden', page).is(':checked');
user.Policy.IsDisabled = $('#chkDisabled', page).is(':checked');
user.Policy.EnableRemoteControlOfOtherUsers = $('#chkEnableRemoteControlOtherUsers', page).is(':checked');
user.Policy.EnableLiveTvManagement = $('#chkManageLiveTv', page).is(':checked');
user.Policy.EnableLiveTvAccess = $('#chkEnableLiveTvAccess', page).is(':checked');
user.Policy.EnableSharedDeviceControl = $('#chkRemoteControlSharedDevices', page).is(':checked');
user.Policy.EnableMediaPlayback = $('#chkEnableMediaPlayback', page).is(':checked');
user.Policy.EnableAudioPlaybackTranscoding = $('#chkEnableAudioPlaybackTranscoding', page).is(':checked');
user.Policy.EnableVideoPlaybackTranscoding = $('#chkEnableVideoPlaybackTranscoding', page).is(':checked');
user.Policy.EnablePlaybackRemuxing = $('#chkEnableVideoPlaybackRemuxing', page).is(':checked');
user.Policy.ForceRemoteSourceTranscoding = $('#chkForceRemoteSourceTranscoding', page).is(':checked');
user.Policy.EnableContentDownloading = $('#chkEnableDownloading', page).is(':checked');
user.Policy.EnableSyncTranscoding = $('#chkEnableSyncTranscoding', page).is(':checked');
user.Policy.EnableMediaConversion = $('#chkEnableConversion', page).is(':checked');
user.Policy.EnablePublicSharing = $('#chkEnableSharing', page).is(':checked');
user.Policy.EnableRemoteAccess = $('#chkRemoteAccess', page).is(':checked');
user.Policy.RemoteClientBitrateLimit = parseInt(1e6 * parseFloat($('#txtRemoteClientBitrateLimit', page).val() || '0'));
user.Policy.LoginAttemptsBeforeLockout = parseInt($('#txtLoginAttemptsBeforeLockout', page).val() || '0');
user.Policy.AuthenticationProviderId = page.querySelector('.selectLoginProvider').value;
user.Policy.PasswordResetProviderId = page.querySelector('.selectPasswordResetProvider').value;
user.Policy.EnableContentDeletion = $('#chkEnableDeleteAllFolders', page).checked;
user.Policy.EnableContentDeletion = $('#chkEnableDeleteAllFolders', page).is(':checked');
user.Policy.EnableContentDeletionFromFolders = user.Policy.EnableContentDeletion ? [] : $('.chkFolder', page).get().filter(function (c) {
return c.checked;
}).map(function (c) {

View file

@ -47,7 +47,7 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading,
$('.channelAccessContainer', page).hide();
}
$('#chkEnableAllChannels', page).checked = user.Policy.EnableAllChannels;
$('#chkEnableAllChannels', page).prop('checked', user.Policy.EnableAllChannels);
}
function loadDevices(page, user, devices) {
@ -63,7 +63,7 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading,
html += '</div>';
$('.deviceAccess', page).show().html(html);
$('#chkEnableAllDevices', page).checked = user.Policy.EnableAllDevices;
$('#chkEnableAllDevices', page).prop('checked', user.Policy.EnableAllDevices);
if (user.Policy.IsAdministrator) {
page.querySelector('.deviceAccessContainer').classList.add('hide');
@ -90,19 +90,19 @@ define(['jQuery', 'loading', 'libraryMenu', 'globalize'], function ($, loading,
}
function saveUser(user, page) {
user.Policy.EnableAllFolders = $('#chkEnableAllFolders', page).checked;
user.Policy.EnableAllFolders = $('#chkEnableAllFolders', page).is(':checked');
user.Policy.EnabledFolders = user.Policy.EnableAllFolders ? [] : $('.chkFolder', page).get().filter(function (c) {
return c.checked;
}).map(function (c) {
return c.getAttribute('data-id');
});
user.Policy.EnableAllChannels = $('#chkEnableAllChannels', page).checked;
user.Policy.EnableAllChannels = $('#chkEnableAllChannels', page).is(':checked');
user.Policy.EnabledChannels = user.Policy.EnableAllChannels ? [] : $('.chkChannel', page).get().filter(function (c) {
return c.checked;
}).map(function (c) {
return c.getAttribute('data-id');
});
user.Policy.EnableAllDevices = $('#chkEnableAllDevices', page).checked;
user.Policy.EnableAllDevices = $('#chkEnableAllDevices', page).is(':checked');
user.Policy.EnabledDevices = user.Policy.EnableAllDevices ? [] : $('.chkDevice', page).get().filter(function (c) {
return c.checked;
}).map(function (c) {

View file

@ -13,7 +13,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox'], function ($, loading
html += '</div>';
$('.folderAccess', page).html(html).trigger('create');
$('#chkEnableAllFolders', page).checked = false;
$('#chkEnableAllFolders', page).prop('checked', false);
}
function loadChannels(page, channels) {
@ -35,7 +35,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox'], function ($, loading
$('.channelAccessContainer', page).hide();
}
$('#chkEnableAllChannels', page).checked = false;
$('#chkEnableAllChannels', page).prop('checked', false);
}
function loadUser(page) {
@ -58,7 +58,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox'], function ($, loading
user.Name = $('#txtUsername', page).val();
user.Password = $('#txtPassword', page).val();
ApiClient.createUser(user).then(function (user) {
user.Policy.EnableAllFolders = $('#chkEnableAllFolders', page).checked;
user.Policy.EnableAllFolders = $('#chkEnableAllFolders', page).is(':checked');
user.Policy.EnabledFolders = [];
if (!user.Policy.EnableAllFolders) {
@ -69,7 +69,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox'], function ($, loading
});
}
user.Policy.EnableAllChannels = $('#chkEnableAllChannels', page).checked;
user.Policy.EnableAllChannels = $('#chkEnableAllChannels', page).is(':checked');
user.Policy.EnabledChannels = [];
if (!user.Policy.EnableAllChannels) {

View file

@ -972,6 +972,19 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
}
}
function toggleLineClamp(clampTarget, e) {
var expandButton = e.target;
var clampClassName = 'detail-clamp-text';
if (clampTarget.classList.contains(clampClassName)) {
clampTarget.classList.remove(clampClassName);
expandButton.innerHTML = globalize.translate('ShowLess');
} else {
clampTarget.classList.add(clampClassName);
expandButton.innerHTML = globalize.translate('ShowMore');
}
}
function renderOverview(elems, item) {
for (var i = 0, length = elems.length; i < length; i++) {
var elem = elems[i];
@ -980,6 +993,21 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
if (overview) {
elem.innerHTML = overview;
elem.classList.remove('hide');
elem.classList.add('detail-clamp-text');
// Grab the sibling element to control the expand state
var expandButton = elem.parentElement.querySelector('.overview-expand');
// Detect if we have overflow of text. Based on this StackOverflow answer
// https://stackoverflow.com/a/35157976
if (Math.abs(elem.scrollHeight - elem.offsetHeight) > 2) {
expandButton.classList.remove('hide');
} else {
expandButton.classList.add('hide');
}
expandButton.addEventListener('click', toggleLineClamp.bind(null, elem));
var anchors = elem.querySelectorAll('a');
for (var j = 0, length2 = anchors.length; j < length2; j++) {
@ -1863,7 +1891,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
itemsContainer: castContent,
coverImage: true,
serverId: item.ServerId,
shape: 'overflowPortrait'
shape: 'overflowPortrait',
imageBlurhashes: item.ImageBlurHashes
});
});
}

View file

@ -86,7 +86,7 @@ define(['cardBuilder', 'imageLoader', 'libraryBrowser', 'loading', 'events', 'us
}
function showFilterMenu(context) {
require(['components/filterdialog/filterdialog'], function (filterDialogFactory) {
require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) {
var filterDialog = new filterDialogFactory({
query: getQuery(),
mode: 'livetvchannels',

View file

@ -171,7 +171,12 @@ define(['loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardB
}
if (!result.Items.length) {
html = '<p style="text-align:center;">' + globalize.translate('MessageNoCollectionsAvailable') + '</p>';
html = '';
html += '<div class="noItemsMessage centerMessage">';
html += '<h1>' + globalize.translate('MessageNothingHere') + '</h1>';
html += '<p>' + globalize.translate('MessageNoCollectionsAvailable') + '</p>';
html += '</div>';
}
var itemsContainer = tabContent.querySelector('.itemsContainer');

View file

@ -165,6 +165,15 @@ define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader
html += '</div>';
}
if (!result.Items.length) {
html = '';
html += '<div class="noItemsMessage centerMessage">';
html += '<h1>' + globalize.translate('MessageNothingHere') + '</h1>';
html += '<p>' + globalize.translate('MessageNoGenresAvailable') + '</p>';
html += '</div>';
}
elem.innerHTML = html;
lazyLoader.lazyChildren(elem, fillItemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);

View file

@ -270,7 +270,7 @@ define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser',
query = userSettings.loadQuerySettings(savedQueryKey, query);
self.showFilterMenu = function () {
require(['components/filterdialog/filterdialog'], function (filterDialogFactory) {
require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) {
var filterDialog = new filterDialogFactory({
query: query,
mode: 'movies',

View file

@ -158,7 +158,12 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
}
if (!result.Items.length) {
html = '<p style="text-align:center;">' + globalize.translate('MessageNoTrailersFound') + '</p>';
html = '';
html += '<div class="noItemsMessage centerMessage">';
html += '<h1>' + globalize.translate('MessageNothingHere') + '</h1>';
html += '<p>' + globalize.translate('MessageNoTrailersFound') + '</p>';
html += '</div>';
}
var itemsContainer = tabContent.querySelector('.itemsContainer');
@ -180,7 +185,7 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
var isLoading = false;
self.showFilterMenu = function () {
require(['components/filterdialog/filterdialog'], function (filterDialogFactory) {
require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) {
var filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: 'movies',

View file

@ -186,7 +186,7 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser
var isLoading = false;
self.showFilterMenu = function () {
require(['components/filterdialog/filterdialog'], function (filterDialogFactory) {
require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) {
var filterDialog = new filterDialogFactory({
query: getQuery(),
mode: 'albums',

View file

@ -170,7 +170,7 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
var isLoading = false;
self.showFilterMenu = function () {
require(['components/filterdialog/filterdialog'], function (filterDialogFactory) {
require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) {
var filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: self.mode,

View file

@ -124,7 +124,7 @@ define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userS
var isLoading = false;
self.showFilterMenu = function () {
require(['components/filterdialog/filterdialog'], function (filterDialogFactory) {
require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) {
var filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: 'songs',

View file

@ -164,7 +164,7 @@ define(['loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardB
var isLoading = false;
self.showFilterMenu = function () {
require(['components/filterdialog/filterdialog'], function (filterDialogFactory) {
require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) {
var filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: 'episodes',

View file

@ -161,6 +161,15 @@ define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader
html += '</div>';
}
if (!result.Items.length) {
html = '';
html += '<div class="noItemsMessage centerMessage">';
html += '<h1>' + globalize.translate('MessageNothingHere') + '</h1>';
html += '<p>' + globalize.translate('MessageNoGenresAvailable') + '</p>';
html += '</div>';
}
elem.innerHTML = html;
lazyLoader.lazyChildren(elem, fillItemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);

View file

@ -197,7 +197,7 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
var isLoading = false;
self.showFilterMenu = function () {
require(['components/filterdialog/filterdialog'], function (filterDialogFactory) {
require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) {
var filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: 'series',

View file

@ -1,6 +1,9 @@
define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySettings, userSettings, autoFocuser) {
'use strict';
// Shortcuts
const UserSettings = userSettings.UserSettings;
return function (view, params) {
function onBeforeUnload(e) {
if (hasChanges) {
@ -11,7 +14,7 @@ define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySett
var settingsInstance;
var hasChanges;
var userId = params.userId || ApiClient.getCurrentUserId();
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new userSettings();
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
view.addEventListener('viewshow', function () {
window.addEventListener('beforeunload', onBeforeUnload);

View file

@ -1,6 +1,9 @@
define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (HomescreenSettings, dom, globalize, loading, userSettings, autoFocuser) {
'use strict';
// Shortcuts
const UserSettings = userSettings.UserSettings;
return function (view, params) {
function onBeforeUnload(e) {
if (hasChanges) {
@ -11,7 +14,7 @@ define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'au
var homescreenSettingsInstance;
var hasChanges;
var userId = params.userId || ApiClient.getCurrentUserId();
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new userSettings();
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
view.addEventListener('viewshow', function () {
window.addEventListener('beforeunload', onBeforeUnload);

View file

@ -1,6 +1,9 @@
define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (PlaybackSettings, dom, globalize, loading, userSettings, autoFocuser) {
'use strict';
// Shortcuts
const UserSettings = userSettings.UserSettings;
return function (view, params) {
function onBeforeUnload(e) {
if (hasChanges) {
@ -11,7 +14,7 @@ define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'auto
var settingsInstance;
var hasChanges;
var userId = params.userId || ApiClient.getCurrentUserId();
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new userSettings();
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
view.addEventListener('viewshow', function () {
window.addEventListener('beforeunload', onBeforeUnload);

View file

@ -1,6 +1,9 @@
define(['subtitleSettings', 'userSettings', 'autoFocuser'], function (SubtitleSettings, userSettings, autoFocuser) {
'use strict';
// Shortcuts
const UserSettings = userSettings.UserSettings;
return function (view, params) {
function onBeforeUnload(e) {
if (hasChanges) {
@ -11,7 +14,7 @@ define(['subtitleSettings', 'userSettings', 'autoFocuser'], function (SubtitleSe
var subtitleSettingsInstance;
var hasChanges;
var userId = params.userId || ApiClient.getCurrentUserId();
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new userSettings();
var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
view.addEventListener('viewshow', function () {
window.addEventListener('beforeunload', onBeforeUnload);

View file

@ -148,6 +148,9 @@
<p class="itemGenres"></p>
<h3 class="tagline"></h3>
<p class="overview"></p>
<div class="overview-controls">
<a class="overview-expand hide" is="emby-linkbutton" href="#">${ShowMore}</a>
</div>
<p id="itemBirthday"></p>
<p id="itemBirthLocation"></p>
<p id="itemDeathDate"></p>

View file

@ -1,24 +0,0 @@
Dashboard.confirm = function(message, title, callback) {
'use strict';
require(['confirm'], function(confirm) {
confirm(message, title).then(function() {
callback(!0);
}).catch(function() {
callback(!1);
});
});
};
Dashboard.showLoadingMsg = function() {
'use strict';
require(['loading'], function(loading) {
loading.show();
});
};
Dashboard.hideLoadingMsg = function() {
'use strict';
require(['loading'], function(loading) {
loading.hide();
});
};

View file

@ -1,19 +1,15 @@
define(['connectionManager'], function (connectionManager) {
/* eslint-disable indent */
import connectionManager from 'connectionManager';
return function () {
var self = this;
self.name = 'Backdrop ScreenSaver';
self.type = 'screensaver';
self.id = 'backdropscreensaver';
self.supportsAnonymous = false;
var currentSlideshow;
self.show = function () {
var query = {
class BackdropScreensaver {
constructor() {
this.name = 'Backdrop ScreenSaver';
this.type = 'screensaver';
this.id = 'backdropscreensaver';
this.supportsAnonymous = false;
}
show() {
const query = {
ImageTypes: 'Backdrop',
EnableImageTypes: 'Backdrop',
IncludeItemTypes: 'Movie,Series,MusicArtist',
@ -25,32 +21,32 @@ define(['connectionManager'], function (connectionManager) {
Limit: 200
};
var apiClient = connectionManager.currentApiClient();
apiClient.getItems(apiClient.getCurrentUserId(), query).then(function (result) {
const apiClient = connectionManager.currentApiClient();
apiClient.getItems(apiClient.getCurrentUserId(), query).then((result) => {
if (result.Items.length) {
require(['slideshow'], function (slideshow) {
var newSlideShow = new slideshow({
import('slideshow').then(({default: Slideshow}) => {
const newSlideShow = new Slideshow({
showTitle: true,
cover: true,
items: result.Items
});
newSlideShow.show();
currentSlideshow = newSlideShow;
});
this.currentSlideshow = newSlideShow;
}).catch(console.error);
}
});
};
self.hide = function () {
if (currentSlideshow) {
currentSlideshow.hide();
currentSlideshow = null;
}
};
};
});
hide() {
if (this.currentSlideshow) {
this.currentSlideshow.hide();
this.currentSlideshow = null;
}
}
}
/* eslint-enable indent */
export default BackdropScreensaver;

View file

@ -7,7 +7,7 @@ import 'css!./style';
import 'material-icons';
import 'paper-icon-button-light';
import TableOfContent from './tableOfContent';
import TableOfContents from './tableOfContents';
export class BookPlayer {
constructor() {
@ -163,7 +163,7 @@ export class BookPlayer {
openTableOfContents() {
if (this._loaded) {
this._tocElement = new TableOfContent(this);
this._tocElement = new TableOfContents(this);
}
}
@ -238,11 +238,17 @@ export class BookPlayer {
this.bindEvents();
return this._rendition.book.locations.generate(1024).then(() => {
return this._rendition.book.locations.generate(1024).then(async () => {
if (cancellationToken.shouldCancel) {
return reject();
}
const percentageTicks = options.startPositionTicks / 10000000;
if (percentageTicks !== 0.0) {
const resumeLocation = book.locations.cfiFromPercentage(percentageTicks);
await rendition.display(resumeLocation);
}
this._loaded = true;
epubElem.style.display = 'block';
rendition.on('relocated', (locations) => {
@ -271,6 +277,7 @@ export class BookPlayer {
if (item.Path && (item.Path.endsWith('epub'))) {
return true;
}
return false;
}
}

View file

@ -1,6 +1,6 @@
import dialogHelper from 'dialogHelper';
export default class TableOfContent {
export default class TableOfContents {
constructor(bookPlayer) {
this._bookPlayer = bookPlayer;
this._rendition = bookPlayer._rendition;
@ -59,6 +59,7 @@ export default class TableOfContent {
autoFocus: false,
removeOnClose: true
});
elem.id = 'dialogToc';
let tocHtml = '<div class="topRightActionButtons">';
@ -72,6 +73,7 @@ export default class TableOfContent {
tocHtml += `<a href="${rendition.book.path.directory + link}">${chapter.label}</a>`;
tocHtml += '</li>';
});
tocHtml += '</ul>';
elem.innerHTML = tocHtml;
@ -84,7 +86,6 @@ export default class TableOfContent {
this._elem = elem;
this.bindEvents();
dialogHelper.open(elem);
}
}

View file

@ -9,17 +9,12 @@ export default class PhotoPlayer {
}
play(options) {
return new Promise(function (resolve, reject) {
import('slideshow').then(({default: slideshow}) => {
var index = options.startIndex || 0;
var apiClient = connectionManager.currentApiClient();
apiClient.getCurrentUser().then(function(result) {
var newSlideShow = new slideshow({
showTitle: false,
cover: false,
@ -31,7 +26,6 @@ export default class PhotoPlayer {
});
newSlideShow.show();
resolve();
});
});
@ -39,7 +33,6 @@ export default class PhotoPlayer {
}
canPlayMediaType(mediaType) {
return (mediaType || '').toLowerCase() === 'photo';
}
}

View file

@ -6,18 +6,10 @@ define(['browser'], function (browser) {
}
function canPlayH265(videoTestElement, options) {
if (browser.tizen || browser.orsay || browser.xboxOne || browser.web0s || options.supportsHevc) {
if (browser.tizen || browser.xboxOne || browser.web0s || options.supportsHevc) {
return true;
}
var userAgent = navigator.userAgent.toLowerCase();
if (browser.chromecast) {
var isChromecastUltra = userAgent.indexOf('aarch64') !== -1;
if (isChromecastUltra) {
return true;
}
}
if (browser.ps4) {
return false;
}
@ -31,7 +23,7 @@ define(['browser'], function (browser) {
var _supportsTextTracks;
function supportsTextTracks() {
if (browser.tizen || browser.orsay) {
if (browser.tizen) {
return true;
}
@ -53,7 +45,7 @@ define(['browser'], function (browser) {
}
function canPlayNativeHls() {
if (browser.tizen || browser.orsay) {
if (browser.tizen) {
return true;
}
@ -72,7 +64,7 @@ define(['browser'], function (browser) {
}
function supportsAc3(videoTestElement) {
if (browser.edgeUwp || browser.tizen || browser.orsay || browser.web0s) {
if (browser.edgeUwp || browser.tizen || browser.web0s) {
return true;
}
@ -80,7 +72,7 @@ define(['browser'], function (browser) {
}
function supportsEac3(videoTestElement) {
if (browser.tizen || browser.orsay || browser.web0s) {
if (browser.tizen || browser.web0s) {
return true;
}
@ -88,7 +80,7 @@ define(['browser'], function (browser) {
}
function supportsAc3InHls(videoTestElement) {
if (browser.tizen || browser.orsay || browser.web0s) {
if (browser.tizen || browser.web0s) {
return true;
}
@ -104,11 +96,11 @@ define(['browser'], function (browser) {
var typeString;
if (format === 'flac') {
if (browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp) {
if (browser.tizen || browser.web0s || browser.edgeUwp) {
return true;
}
} else if (format === 'wma') {
if (browser.tizen || browser.orsay || browser.edgeUwp) {
if (browser.tizen || browser.edgeUwp) {
return true;
}
} else if (format === 'asf') {
@ -143,7 +135,7 @@ define(['browser'], function (browser) {
}
function testCanPlayMkv(videoTestElement) {
if (browser.tizen || browser.orsay || browser.web0s) {
if (browser.tizen || browser.web0s) {
return true;
}
@ -152,23 +144,6 @@ define(['browser'], function (browser) {
return true;
}
// Unfortunately there's no real way to detect mkv support
if (browser.chrome) {
// Not supported on opera tv
if (browser.operaTv) {
return false;
}
var userAgent = navigator.userAgent.toLowerCase();
// Filter out browsers based on chromium that don't support mkv
if (userAgent.indexOf('vivaldi') !== -1 || userAgent.indexOf('opera') !== -1) {
return false;
}
return true;
}
if (browser.edgeUwp) {
return true;
}
@ -177,15 +152,15 @@ define(['browser'], function (browser) {
}
function testCanPlayTs() {
return browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
return browser.tizen || browser.web0s || browser.edgeUwp;
}
function supportsMpeg2Video() {
return browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
return browser.tizen || browser.web0s || browser.edgeUwp;
}
function supportsVc1() {
return browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
return browser.tizen || browser.web0s || browser.edgeUwp;
}
function getDirectPlayProfileForVideoContainer(container, videoAudioCodecs, videoTestElement, options) {
@ -195,11 +170,11 @@ define(['browser'], function (browser) {
switch (container) {
case 'asf':
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
supported = browser.tizen || browser.web0s || browser.edgeUwp;
videoAudioCodecs = [];
break;
case 'avi':
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
supported = browser.tizen || browser.web0s || browser.edgeUwp;
// New Samsung TV don't support XviD/DivX
// Explicitly add supported codecs to make other codecs be transcoded
if (browser.tizenVersion >= 4) {
@ -212,24 +187,24 @@ define(['browser'], function (browser) {
break;
case 'mpg':
case 'mpeg':
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
supported = browser.tizen || browser.web0s || browser.edgeUwp;
break;
case 'flv':
supported = browser.tizen || browser.orsay;
supported = browser.tizen;
break;
case '3gp':
case 'mts':
case 'trp':
case 'vob':
case 'vro':
supported = browser.tizen || browser.orsay;
supported = browser.tizen;
break;
case 'mov':
supported = browser.tizen || browser.orsay || browser.web0s || browser.chrome || browser.edgeUwp;
supported = browser.tizen || browser.web0s || browser.chrome || browser.edgeUwp;
videoCodecs.push('h264');
break;
case 'm2ts':
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
supported = browser.tizen || browser.web0s || browser.edgeUwp;
videoCodecs.push('h264');
if (supportsVc1()) {
videoCodecs.push('vc1');
@ -239,7 +214,7 @@ define(['browser'], function (browser) {
}
break;
case 'wmv':
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
supported = browser.tizen || browser.web0s || browser.edgeUwp;
videoAudioCodecs = [];
break;
case 'ts':
@ -274,21 +249,6 @@ define(['browser'], function (browser) {
}
function getGlobalMaxVideoBitrate() {
var userAgent = navigator.userAgent.toLowerCase();
if (browser.chromecast) {
var isChromecastUltra = userAgent.indexOf('aarch64') !== -1;
if (isChromecastUltra) {
return null;
}
// This is a hack to try and detect chromecast on vizio
if (self.screen && self.screen.width >= 3800) {
return null;
}
return 30000000;
}
var isTizenFhd = false;
if (browser.tizen) {
try {
@ -333,11 +293,12 @@ define(['browser'], function (browser) {
var videoAudioCodecs = [];
var hlsVideoAudioCodecs = [];
var supportsMp3VideoAudio = videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.69"').replace(/no/, '') ||
videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.6B"').replace(/no/, '');
var supportsMp3VideoAudio = videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.69"').replace(/no/, '')
|| videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.6B"').replace(/no/, '')
|| videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp3"').replace(/no/, '');
// Not sure how to test for this
var supportsMp2VideoAudio = browser.edgeUwp || browser.tizen || browser.orsay || browser.web0s;
var supportsMp2VideoAudio = browser.edgeUwp || browser.tizen || browser.web0s;
var maxVideoWidth = browser.xboxOne ?
(self.screen ? self.screen.width : null) :
@ -349,11 +310,6 @@ define(['browser'], function (browser) {
var canPlayAacVideoAudio = videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.2"').replace(/no/, '');
if (canPlayAacVideoAudio && browser.chromecast && physicalAudioChannels <= 2) {
// prioritize this first
videoAudioCodecs.push('aac');
}
// Only put mp3 first if mkv support is there
// Otherwise with HLS and mp3 audio we're seeing some browsers
// safari is lying
@ -376,11 +332,6 @@ define(['browser'], function (browser) {
}
}
if (canPlayAacVideoAudio && browser.chromecast && videoAudioCodecs.indexOf('aac') === -1) {
// prioritize this first
videoAudioCodecs.push('aac');
}
if (supportsMp3VideoAudio) {
videoAudioCodecs.push('mp3');
@ -415,7 +366,7 @@ define(['browser'], function (browser) {
videoAudioCodecs.push('mp2');
}
var supportsDts = browser.tizen || browser.orsay || browser.web0s || options.supportsDts;
var supportsDts = browser.tizen || browser.web0s || options.supportsDts;
// DTS audio not supported in 2018 models (Tizen 4.0)
if (browser.tizenVersion >= 4) {
@ -427,7 +378,7 @@ define(['browser'], function (browser) {
videoAudioCodecs.push('dts');
}
if (browser.tizen || browser.orsay || browser.web0s) {
if (browser.tizen || browser.web0s) {
videoAudioCodecs.push('pcm_s16le');
videoAudioCodecs.push('pcm_s24le');
}
@ -436,7 +387,7 @@ define(['browser'], function (browser) {
videoAudioCodecs.push('truehd');
}
if (browser.tizen || browser.orsay) {
if (browser.tizen) {
videoAudioCodecs.push('aac_latm');
}
@ -484,7 +435,7 @@ define(['browser'], function (browser) {
mp4VideoCodecs.push('vc1');
}
if (browser.tizen || browser.orsay) {
if (browser.tizen) {
mp4VideoCodecs.push('msmpeg4v2');
}
@ -496,7 +447,7 @@ define(['browser'], function (browser) {
mp4VideoCodecs.push('vp9');
}
if (canPlayVp8 || browser.tizen || browser.orsay) {
if (canPlayVp8 || browser.tizen) {
videoAudioCodecs.push('vorbis');
}
@ -628,7 +579,7 @@ define(['browser'], function (browser) {
});
});
if (canPlayMkv && !browser.tizen && !browser.orsay && options.enableMkvProgressive !== false) {
if (canPlayMkv && !browser.tizen && options.enableMkvProgressive !== false) {
profile.TranscodingProfiles.push({
Container: 'mkv',
Type: 'Video',
@ -693,7 +644,7 @@ define(['browser'], function (browser) {
profile.CodecProfiles = [];
var supportsSecondaryAudio = browser.tizen || browser.orsay || videoTestElement.audioTracks;
var supportsSecondaryAudio = browser.tizen || videoTestElement.audioTracks;
var aacCodecProfileConditions = [];
@ -716,15 +667,6 @@ define(['browser'], function (browser) {
});
}
if (browser.chromecast) {
aacCodecProfileConditions.push({
Condition: 'LessThanEqual',
Property: 'AudioChannels',
Value: '2',
IsRequired: true
});
}
if (aacCodecProfileConditions.length) {
profile.CodecProfiles.push({
Type: 'VideoAudio',
@ -750,7 +692,7 @@ define(['browser'], function (browser) {
var maxH264Level = 42;
var h264Profiles = 'high|main|baseline|constrained baseline';
if (browser.tizen || browser.orsay || browser.web0s ||
if (browser.tizen || browser.web0s ||
videoTestElement.canPlayType('video/mp4; codecs="avc1.640833"').replace(/no/, '')) {
maxH264Level = 51;
}
@ -760,7 +702,7 @@ define(['browser'], function (browser) {
maxH264Level = 52;
}
if (browser.tizen || browser.orsay ||
if (browser.tizen ||
videoTestElement.canPlayType('video/mp4; codecs="avc1.6e0033"').replace(/no/, '')) {
// These tests are passing in safari, but playback is failing
@ -794,20 +736,13 @@ define(['browser'], function (browser) {
]
});
if (!browser.edgeUwp && !browser.tizen && !browser.orsay && !browser.web0s) {
//profile.CodecProfiles[profile.CodecProfiles.length - 1].Conditions.push({
// Condition: 'NotEquals',
// Property: 'IsAVC',
// Value: 'false',
// IsRequired: false
//});
//profile.CodecProfiles[profile.CodecProfiles.length - 1].Conditions.push({
// Condition: 'NotEquals',
// Property: 'IsInterlaced',
// Value: 'true',
// IsRequired: false
//});
if (!browser.edgeUwp && !browser.tizen && !browser.web0s) {
profile.CodecProfiles[profile.CodecProfiles.length - 1].Conditions.push({
Condition: 'NotEquals',
Property: 'IsInterlaced',
Value: 'true',
IsRequired: false
});
}
if (maxVideoWidth) {
@ -858,19 +793,6 @@ define(['browser'], function (browser) {
});
}
if (browser.chromecast) {
profile.CodecProfiles.push({
Type: 'Audio',
Codec: 'flac',
Conditions: [
{
Condition: 'LessThanEqual',
Property: 'AudioSampleRate',
Value: '96000'
}]
});
}
// Subtitle profiles
// External vtt or burn in
profile.SubtitleProfiles = [];

View file

@ -1,5 +1,3 @@
/* eslint-disable indent */
import appSettings from 'appSettings';
import events from 'events';
@ -17,7 +15,16 @@ import events from 'events';
instance.saveTimeout = setTimeout(onSaveTimeout.bind(instance), 50);
}
export function setUserInfo(userId, apiClient) {
export class UserSettings {
constructor() {
}
/**
* Bind UserSettings instance to user.
* @param {string} - User identifier.
* @param {Object} - ApiClient instance.
*/
setUserInfo(userId, apiClient) {
if (this.saveTimeout) {
clearTimeout(this.saveTimeout);
}
@ -38,15 +45,24 @@ import events from 'events';
});
}
export function getData() {
// FIXME: Seems unused
getData() {
return this.displayPrefs;
}
export function importFrom(instance) {
// FIXME: Seems unused
importFrom(instance) {
this.displayPrefs = instance.getData();
}
export function set(name, value, enableOnServer) {
// FIXME: 'appSettings.set' doesn't return any value
/**
* Set value of setting.
* @param {string} name - Name of setting.
* @param {mixed} value - Value of setting.
* @param {boolean} enableOnServer - Flag to save preferences on server.
*/
set(name, value, enableOnServer) {
var userId = this.currentUserId;
var currentValue = this.get(name, enableOnServer);
var result = appSettings.set(name, value, userId);
@ -63,7 +79,13 @@ import events from 'events';
return result;
}
export function get(name, enableOnServer) {
/**
* Get value of setting.
* @param {string} name - Name of setting.
* @param {boolean} enableOnServer - Flag to return preferences from server (cached).
* @return {string} Value of setting.
*/
get(name, enableOnServer) {
var userId = this.currentUserId;
if (enableOnServer !== false && this.displayPrefs) {
return this.displayPrefs.CustomPrefs[name];
@ -72,7 +94,12 @@ import events from 'events';
return appSettings.get(name, userId);
}
export function serverConfig(config) {
/**
* Get or set user config.
* @param {Object|undefined} config - Configuration or undefined.
* @return {Object|Promise} Configuration or Promise.
*/
serverConfig(config) {
var apiClient = this.currentApiClient;
if (config) {
return apiClient.updateUserConfiguration(this.currentUserId, config);
@ -83,7 +110,12 @@ import events from 'events';
});
}
export function enableCinemaMode(val) {
/**
* Get or set 'Cinema Mode' state.
* @param {boolean|undefined} val - Flag to enable 'Cinema Mode' or undefined.
* @return {boolean} 'Cinema Mode' state.
*/
enableCinemaMode(val) {
if (val !== undefined) {
return this.set('enableCinemaMode', val.toString(), false);
}
@ -92,7 +124,12 @@ import events from 'events';
return val !== 'false';
}
export function enableNextVideoInfoOverlay(val) {
/**
* Get or set 'Next Video Info Overlay' state.
* @param {boolean|undefined} val - Flag to enable 'Next Video Info Overlay' or undefined.
* @return {boolean} 'Next Video Info Overlay' state.
*/
enableNextVideoInfoOverlay(val) {
if (val !== undefined) {
return this.set('enableNextVideoInfoOverlay', val.toString());
}
@ -101,7 +138,12 @@ import events from 'events';
return val !== 'false';
}
export function enableThemeSongs(val) {
/**
* Get or set 'Theme Songs' state.
* @param {boolean|undefined} val - Flag to enable 'Theme Songs' or undefined.
* @return {boolean} 'Theme Songs' state.
*/
enableThemeSongs(val) {
if (val !== undefined) {
return this.set('enableThemeSongs', val.toString(), false);
}
@ -110,7 +152,12 @@ import events from 'events';
return val === 'true';
}
export function enableThemeVideos(val) {
/**
* Get or set 'Theme Videos' state.
* @param {boolean|undefined} val - Flag to enable 'Theme Videos' or undefined.
* @return {boolean} 'Theme Videos' state.
*/
enableThemeVideos(val) {
if (val !== undefined) {
return this.set('enableThemeVideos', val.toString(), false);
}
@ -119,7 +166,12 @@ import events from 'events';
return val === 'true';
}
export function enableFastFadein(val) {
/**
* Get or set 'Fast Fade-in' state.
* @param {boolean|undefined} val - Flag to enable 'Fast Fade-in' or undefined.
* @return {boolean} 'Fast Fade-in' state.
*/
enableFastFadein(val) {
if (val !== undefined) {
return this.set('fastFadein', val.toString(), false);
}
@ -128,7 +180,26 @@ import events from 'events';
return val !== 'false';
}
export function enableBackdrops(val) {
/**
* Get or set 'Blurhash' state.
* @param {boolean|undefined} val - Flag to enable 'Blurhash' or undefined.
* @return {boolean} 'Blurhash' state.
*/
enableBlurhash(val) {
if (val !== undefined) {
return this.set('blurhash', val.toString(), false);
}
val = this.get('blurhash', false);
return val !== 'false';
}
/**
* Get or set 'Backdrops' state.
* @param {boolean|undefined} val - Flag to enable 'Backdrops' or undefined.
* @return {boolean} 'Backdrops' state.
*/
enableBackdrops(val) {
if (val !== undefined) {
return this.set('enableBackdrops', val.toString(), false);
}
@ -137,7 +208,12 @@ import events from 'events';
return val !== 'false';
}
export function detailsBanner(val) {
/**
* Get or set 'Details Banner' state.
* @param {boolean|undefined} val - Flag to enable 'Details Banner' or undefined.
* @return {boolean} 'Details Banner' state.
*/
detailsBanner(val) {
if (val !== undefined) {
return this.set('detailsBanner', val.toString(), false);
}
@ -146,7 +222,12 @@ import events from 'events';
return val !== 'false';
}
export function language(val) {
/**
* Get or set language.
* @param {string|undefined} val - Language.
* @return {string} Language.
*/
language(val) {
if (val !== undefined) {
return this.set('language', val.toString(), false);
}
@ -154,7 +235,12 @@ import events from 'events';
return this.get('language', false);
}
export function dateTimeLocale(val) {
/**
* Get or set datetime locale.
* @param {string|undefined} val - Datetime locale.
* @return {string} Datetime locale.
*/
dateTimeLocale(val) {
if (val !== undefined) {
return this.set('datetimelocale', val.toString(), false);
}
@ -162,7 +248,12 @@ import events from 'events';
return this.get('datetimelocale', false);
}
export function chromecastVersion(val) {
/**
* Get or set Chromecast version.
* @param {string|undefined} val - Chromecast version.
* @return {string} Chromecast version.
*/
chromecastVersion(val) {
if (val !== undefined) {
return this.set('chromecastVersion', val.toString());
}
@ -170,7 +261,12 @@ import events from 'events';
return this.get('chromecastVersion') || 'stable';
}
export function skipBackLength(val) {
/**
* Get or set amount of rewind.
* @param {number|undefined} val - Amount of rewind.
* @return {number} Amount of rewind.
*/
skipBackLength(val) {
if (val !== undefined) {
return this.set('skipBackLength', val.toString());
}
@ -178,7 +274,12 @@ import events from 'events';
return parseInt(this.get('skipBackLength') || '10000');
}
export function skipForwardLength(val) {
/**
* Get or set amount of fast forward.
* @param {number|undefined} val - Amount of fast forward.
* @return {number} Amount of fast forward.
*/
skipForwardLength(val) {
if (val !== undefined) {
return this.set('skipForwardLength', val.toString());
}
@ -186,7 +287,12 @@ import events from 'events';
return parseInt(this.get('skipForwardLength') || '30000');
}
export function dashboardTheme(val) {
/**
* Get or set theme for Dashboard.
* @param {string|undefined} val - Theme for Dashboard.
* @return {string} Theme for Dashboard.
*/
dashboardTheme(val) {
if (val !== undefined) {
return this.set('dashboardTheme', val);
}
@ -194,7 +300,12 @@ import events from 'events';
return this.get('dashboardTheme');
}
export function skin(val) {
/**
* Get or set skin.
* @param {string|undefined} val - Skin.
* @return {string} Skin.
*/
skin(val) {
if (val !== undefined) {
return this.set('skin', val, false);
}
@ -202,7 +313,12 @@ import events from 'events';
return this.get('skin', false);
}
export function theme(val) {
/**
* Get or set main theme.
* @param {string|undefined} val - Main theme.
* @return {string} Main theme.
*/
theme(val) {
if (val !== undefined) {
return this.set('appTheme', val, false);
}
@ -210,7 +326,12 @@ import events from 'events';
return this.get('appTheme', false);
}
export function screensaver(val) {
/**
* Get or set screensaver.
* @param {string|undefined} val - Screensaver.
* @return {string} Screensaver.
*/
screensaver(val) {
if (val !== undefined) {
return this.set('screensaver', val, false);
}
@ -218,7 +339,12 @@ import events from 'events';
return this.get('screensaver', false);
}
export function libraryPageSize(val) {
/**
* Get or set library page size.
* @param {number|undefined} val - Library page size.
* @return {number} Library page size.
*/
libraryPageSize(val) {
if (val !== undefined) {
return this.set('libraryPageSize', parseInt(val, 10), false);
}
@ -232,7 +358,12 @@ import events from 'events';
}
}
export function soundEffects(val) {
/**
* Get or set sound effects.
* @param {string|undefined} val - Sound effects.
* @return {string} Sound effects.
*/
soundEffects(val) {
if (val !== undefined) {
return this.set('soundeffects', val, false);
}
@ -240,7 +371,13 @@ import events from 'events';
return this.get('soundeffects', false);
}
export function loadQuerySettings(key, query) {
/**
* Load query settings.
* @param {string} key - Query key.
* @param {Object} query - Query base.
* @return {Object} Query.
*/
loadQuerySettings(key, query) {
var values = this.get(key);
if (values) {
values = JSON.parse(values);
@ -250,7 +387,12 @@ import events from 'events';
return query;
}
export function saveQuerySettings(key, query) {
/**
* Save query settings.
* @param {string} key - Query key.
* @param {Object} query - Query.
*/
saveQuerySettings(key, query) {
var values = {};
if (query.SortBy) {
values.SortBy = query.SortBy;
@ -263,52 +405,76 @@ import events from 'events';
return this.set(key, JSON.stringify(values));
}
export function getSubtitleAppearanceSettings(key) {
/**
* Get subtitle appearance settings.
* @param {string|undefined} key - Settings key.
* @return {Object} Subtitle appearance settings.
*/
getSubtitleAppearanceSettings(key) {
key = key || 'localplayersubtitleappearance3';
return JSON.parse(this.get(key, false) || '{}');
}
export function setSubtitleAppearanceSettings(value, key) {
/**
* Set subtitle appearance settings.
* @param {Object} value - Subtitle appearance settings.
* @param {string|undefined} key - Settings key.
*/
setSubtitleAppearanceSettings(value, key) {
key = key || 'localplayersubtitleappearance3';
return this.set(key, JSON.stringify(value), false);
}
export function setFilter(key, value) {
/**
* Set filter.
* @param {string} key - Filter key.
* @param {string} value - Filter value.
*/
setFilter(key, value) {
return this.set(key, value, true);
}
export function getFilter(key) {
/**
* Get filter.
* @param {string} key - Filter key.
* @return {string} Filter value.
*/
getFilter(key) {
return this.get(key, true);
}
}
/* eslint-enable indent */
export default {
setUserInfo: setUserInfo,
getData: getData,
importFrom: importFrom,
set: set,
get: get,
serverConfig: serverConfig,
enableCinemaMode: enableCinemaMode,
enableNextVideoInfoOverlay: enableNextVideoInfoOverlay,
enableThemeSongs: enableThemeSongs,
enableThemeVideos: enableThemeVideos,
enableFastFadein: enableFastFadein,
enableBackdrops: enableBackdrops,
language: language,
dateTimeLocale: dateTimeLocale,
skipBackLength: skipBackLength,
skipForwardLength: skipForwardLength,
dashboardTheme: dashboardTheme,
skin: skin,
theme: theme,
screensaver: screensaver,
libraryPageSize: libraryPageSize,
soundEffects: soundEffects,
loadQuerySettings: loadQuerySettings,
saveQuerySettings: saveQuerySettings,
getSubtitleAppearanceSettings: getSubtitleAppearanceSettings,
setSubtitleAppearanceSettings: setSubtitleAppearanceSettings,
setFilter: setFilter,
getFilter: getFilter
};
export const currentSettings = new UserSettings;
// Wrappers for non-ES6 modules and backward compatibility
export const setUserInfo = currentSettings.setUserInfo.bind(currentSettings);
export const getData = currentSettings.getData.bind(currentSettings);
export const importFrom = currentSettings.importFrom.bind(currentSettings);
export const set = currentSettings.set.bind(currentSettings);
export const get = currentSettings.get.bind(currentSettings);
export const serverConfig = currentSettings.serverConfig.bind(currentSettings);
export const enableCinemaMode = currentSettings.enableCinemaMode.bind(currentSettings);
export const enableNextVideoInfoOverlay = currentSettings.enableNextVideoInfoOverlay.bind(currentSettings);
export const enableThemeSongs = currentSettings.enableThemeSongs.bind(currentSettings);
export const enableThemeVideos = currentSettings.enableThemeVideos.bind(currentSettings);
export const enableFastFadein = currentSettings.enableFastFadein.bind(currentSettings);
export const enableBlurhash = currentSettings.enableBlurhash.bind(currentSettings);
export const enableBackdrops = currentSettings.enableBackdrops.bind(currentSettings);
export const detailsBanner = currentSettings.detailsBanner.bind(currentSettings);
export const language = currentSettings.language.bind(currentSettings);
export const dateTimeLocale = currentSettings.dateTimeLocale.bind(currentSettings);
export const chromecastVersion = currentSettings.chromecastVersion.bind(currentSettings);
export const skipBackLength = currentSettings.skipBackLength.bind(currentSettings);
export const skipForwardLength = currentSettings.skipForwardLength.bind(currentSettings);
export const dashboardTheme = currentSettings.dashboardTheme.bind(currentSettings);
export const skin = currentSettings.skin.bind(currentSettings);
export const theme = currentSettings.theme.bind(currentSettings);
export const screensaver = currentSettings.screensaver.bind(currentSettings);
export const libraryPageSize = currentSettings.libraryPageSize.bind(currentSettings);
export const soundEffects = currentSettings.soundEffects.bind(currentSettings);
export const loadQuerySettings = currentSettings.loadQuerySettings.bind(currentSettings);
export const saveQuerySettings = currentSettings.saveQuerySettings.bind(currentSettings);
export const getSubtitleAppearanceSettings = currentSettings.getSubtitleAppearanceSettings.bind(currentSettings);
export const setSubtitleAppearanceSettings = currentSettings.setSubtitleAppearanceSettings.bind(currentSettings);
export const setFilter = currentSettings.setFilter.bind(currentSettings);
export const getFilter = currentSettings.getFilter.bind(currentSettings);

View file

@ -2,7 +2,7 @@ let data;
function getConfig() {
if (data) return Promise.resolve(data);
return fetch('/config.json?nocache=' + new Date().getUTCMilliseconds()).then(response => {
return fetch('config.json?nocache=' + new Date().getUTCMilliseconds()).then(response => {
data = response.json();
return data;
}).catch(error => {
@ -12,7 +12,7 @@ function getConfig() {
}
function getDefaultConfig() {
return fetch('/config.template.json').then(function (response) {
return fetch('config.template.json').then(function (response) {
data = response.json();
return data;
});

View file

@ -228,6 +228,28 @@ var Dashboard = {
} else {
Dashboard.navigate('selectserver.html');
}
},
hideLoadingMsg: function() {
'use strict';
require(['loading'], function(loading) {
loading.hide();
});
},
showLoadingMsg: function() {
'use strict';
require(['loading'], function(loading) {
loading.show();
});
},
confirm: function(message, title, callback) {
'use strict';
require(['confirm'], function(confirm) {
confirm(message, title).then(function() {
callback(!0);
}).catch(function() {
callback(!1);
});
});
}
};
@ -653,7 +675,7 @@ var AppInfo = {};
playQueueManager: componentsPath + '/playback/playqueuemanager',
nowPlayingHelper: componentsPath + '/playback/nowplayinghelper',
pluginManager: componentsPath + '/pluginManager',
packageManager: componentsPath + '/packagemanager',
packageManager: componentsPath + '/packageManager',
screensaverManager: componentsPath + '/screensavermanager',
chromecastHelper: 'plugins/chromecastPlayer/chromecastHelpers'
};
@ -737,7 +759,6 @@ var AppInfo = {};
// define legacy features
// TODO delete the rest of these
define('fnchecked', ['legacy/fnchecked'], returnFirstDependency);
define('legacyDashboard', ['legacy/dashboard'], returnFirstDependency);
define('legacySelectMenu', ['legacy/selectmenu'], returnFirstDependency);
// there are several objects that need to be instantiated
@ -820,10 +841,10 @@ var AppInfo = {};
define('playbackSettings', [componentsPath + '/playbackSettings/playbackSettings'], returnFirstDependency);
define('homescreenSettings', [componentsPath + '/homeScreenSettings/homeScreenSettings'], returnFirstDependency);
define('playbackManager', [componentsPath + '/playback/playbackmanager'], getPlaybackManager);
define('timeSyncManager', [componentsPath + '/syncplay/timeSyncManager'], returnDefault);
define('groupSelectionMenu', [componentsPath + '/syncplay/groupSelectionMenu'], returnFirstDependency);
define('syncPlayManager', [componentsPath + '/syncplay/syncPlayManager'], returnDefault);
define('playbackPermissionManager', [componentsPath + '/syncplay/playbackPermissionManager'], returnDefault);
define('timeSyncManager', [componentsPath + '/syncPlay/timeSyncManager'], returnDefault);
define('groupSelectionMenu', [componentsPath + '/syncPlay/groupSelectionMenu'], returnFirstDependency);
define('syncPlayManager', [componentsPath + '/syncPlay/syncPlayManager'], returnDefault);
define('playbackPermissionManager', [componentsPath + '/syncPlay/playbackPermissionManager'], returnDefault);
define('layoutManager', [componentsPath + '/layoutManager', 'apphost'], getLayoutManager);
define('homeSections', [componentsPath + '/homesections/homesections'], returnFirstDependency);
define('playMenu', [componentsPath + '/playmenu'], returnFirstDependency);
@ -847,7 +868,7 @@ var AppInfo = {};
define('userdataButtons', [componentsPath + '/userdatabuttons/userdatabuttons'], returnFirstDependency);
define('listView', [componentsPath + '/listview/listview'], returnFirstDependency);
define('indicators', [componentsPath + '/indicators/indicators'], returnFirstDependency);
define('viewSettings', [componentsPath + '/viewsettings/viewsettings'], returnFirstDependency);
define('viewSettings', [componentsPath + '/viewSettings/viewSettings'], returnFirstDependency);
define('filterMenu', [componentsPath + '/filtermenu/filtermenu'], returnFirstDependency);
define('sortMenu', [componentsPath + '/sortmenu/sortmenu'], returnFirstDependency);
define('sanitizefilename', [componentsPath + '/sanitizeFilename'], returnFirstDependency);

View file

@ -1540,8 +1540,6 @@
"CopyStreamURLError": "Při kopírování URL došlo k chybě.",
"LabelVideoResolution": "Rozlišení videa:",
"LabelStreamType": "Typ streamu:",
"EnableFastImageFadeInHelp": "Zobrazí plakáty a další obrázky s rychlejší animací přechodu po dokončení načítání.",
"EnableFastImageFadeIn": "Rychlé animace přechodů obrazu",
"LabelPlayerDimensions": "Zobrazené rozlišení:",
"LabelDroppedFrames": "Vynechané snímky:",
"LabelCorruptedFrames": "Poškozené snímky:",
@ -1603,7 +1601,7 @@
"HeaderDVR": "Nahrávání",
"SaveChanges": "Uložit změny",
"LabelSyncPlayPlaybackDiff": "Rozdíl v době přehrávání:",
"SyncPlayAccessHelp": "Určuje úroveň přístupu k synchronizaci přehrávání, kterou tento uživatel bude mít. Tato funkce umožňuje synchronizovat přehrávání s dalšími uživateli.",
"SyncPlayAccessHelp": "Určuje úroveň přístupu k synchronizaci přehrávání, kterou tento uživatel bude mít. Tato funkce umožňuje synchronizovat přehrávání s dalšími zařízeními.",
"MessageSyncPlayErrorMedia": "Zapnutí synchronizace přehrávání se nezdařilo. Chyba média.",
"MessageSyncPlayErrorMissingSession": "Zapnutí synchronizace přehrávání se nezdařilo. Nebyla nalezena relace.",
"MessageSyncPlayErrorNoActivePlayer": "Nebyl nalezen žádný aktivní přehrávač. Synchronizace přehrávání byla vypnuta.",
@ -1633,5 +1631,7 @@
"HeaderSyncPlayEnabled": "Synchronizace přehrávání povolena",
"HeaderSyncPlaySelectGroup": "Připojit ke skupině",
"EnableDetailsBannerHelp": "Zobrazí obrázek ve vrchní části detailu položky.",
"EnableDetailsBanner": "Obrázek detailu"
"EnableDetailsBanner": "Obrázek detailu",
"ShowMore": "Zobrazit více",
"ShowLess": "Zobrazit méně"
}

View file

@ -1569,8 +1569,6 @@
"LabelStreamType": "Stream type:",
"LabelSonyAggregationFlags": "Sony aggregering flag:",
"LabelSize": "Størrelse:",
"EnableFastImageFadeInHelp": "Aktivér hurtigere fade-in-animation til indlæste billeder",
"EnableFastImageFadeIn": "Hurtigt billede indtoning",
"LabelPleaseRestart": "Ændringer vil træde i kraft efter web klienten er blevet genindlæst manuelt.",
"LabelPlayMethod": "Afspilnings metode:",
"LabelPlayerDimensions": "Afspillerdimensioner:",

View file

@ -1478,8 +1478,6 @@
"MessageConfirmAppExit": "Wirklich verlassen?",
"LabelVideoResolution": "Videoauflösung:",
"LabelStreamType": "Streamtyp:",
"EnableFastImageFadeInHelp": "Zeige Poster und andere Bilder mit einer schnelleren Einblendeanimation, wenn diese fertig geladen sind.",
"EnableFastImageFadeIn": "Schnelle Bildeinblendungsanimationen",
"LabelPlayerDimensions": "Playerabmessungen:",
"LabelDroppedFrames": "Verlorene Frames:",
"LabelCorruptedFrames": "Fehlerhafte Frames:",
@ -1571,5 +1569,7 @@
"HeaderSyncPlayEnabled": "SyncPlay aktiviert",
"HeaderSyncPlaySelectGroup": "Tritt einer Gruppe bei",
"EnableDetailsBannerHelp": "Zeigt ein Bannerbild im oberen Bereich der Seite Item-Details.",
"EnableDetailsBanner": "Detailbanner"
"EnableDetailsBanner": "Detailbanner",
"ShowMore": "Mehr anzeigen",
"ShowLess": "Weniger anzeigen"
}

View file

@ -837,8 +837,8 @@
"LabelSecureConnectionsMode": "Secure connection mode:",
"LabelSeasonNumber": "Season number:",
"LabelScreensaver": "Screensaver:",
"EnableFastImageFadeIn": "Fast image fade-in",
"EnableFastImageFadeInHelp": "Enable faster fade-in animation for loaded images",
"EnableFasterAnimations": "Faster animations",
"EnableFasterAnimationsHelp": "Use faster animations and transitions",
"LabelScheduledTaskLastRan": "Last ran {0}, taking {1}.",
"LabelSaveLocalMetadataHelp": "Saving artwork into media folders will put them in a place where they can be easily edited.",
"LabelRuntimeMinutes": "Run time (minutes):",

View file

@ -826,8 +826,8 @@
"LabelSaveLocalMetadataHelp": "Saving artwork into media folders will put them in a place where they can be easily edited.",
"LabelScheduledTaskLastRan": "Last ran {0}, taking {1}.",
"LabelScreensaver": "Screensaver:",
"EnableFastImageFadeIn": "Fast Image Fade Animations",
"EnableFastImageFadeInHelp": "Show posters and other images with a quicker fade animation when they finish loading.",
"EnableFasterAnimations": "Faster animations",
"EnableFasterAnimationsHelp": "Use faster animations and transitions",
"LabelSeasonNumber": "Season number:",
"LabelSelectFolderGroups": "Automatically group content from the following folders into views such as Movies, Music and TV:",
"LabelSelectFolderGroupsHelp": "Folders that are unchecked will be displayed by themselves in their own view.",
@ -1024,10 +1024,11 @@
"MessageLeaveEmptyToInherit": "Leave empty to inherit settings from a parent item or the global default value.",
"MessageNoAvailablePlugins": "No available plugins.",
"MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, and Albums. Click the + button to start creating collections.",
"MessageNoGenresAvailable": "Enable some metadata providers to pull genres from the internet.",
"MessageNoMovieSuggestionsAvailable": "No movie suggestions are currently available. Start watching and rating your movies, and then come back to view your recommendations.",
"MessageNoPluginsInstalled": "You have no plugins installed.",
"MessageNoServersAvailable": "No servers have been found using the automatic server discovery.",
"MessageNoTrailersFound": "No trailers found. Install the Trailer channel to enhance your movie experience by adding a library of internet trailers.",
"MessageNoTrailersFound": "Install the trailers channel to enhance your movie experience by adding a library of internet trailers.",
"MessageNothingHere": "Nothing here.",
"MessagePasswordResetForUsers": "The following users have had their passwords reset. They can now sign in with the pin codes that were used to perform the reset.",
"MessagePlayAccessRestricted": "Playback of this content is currently restricted. Please contact your server administrator for more information.",
@ -1373,6 +1374,8 @@
"Share": "Share",
"ShowAdvancedSettings": "Show advanced settings",
"ShowIndicatorsFor": "Show indicators for:",
"ShowLess": "Show less",
"ShowMore": "Show more",
"ShowTitle": "Show title",
"ShowYear": "Show year",
"Shows": "Shows",
@ -1546,5 +1549,7 @@
"EveryHour": "Every hour",
"EveryXHours": "Every {0} hours",
"OnApplicationStartup": "On application startup",
"UnsupportedPlayback": "Jellyfin cannot decrypt content protected by DRM but all content will be attempted regardless, including protected titles. Some files may appear completely black due to encryption or other unsupported features, such as interactive titles."
"UnsupportedPlayback": "Jellyfin cannot decrypt content protected by DRM but all content will be attempted regardless, including protected titles. Some files may appear completely black due to encryption or other unsupported features, such as interactive titles.",
"EnableBlurhash": "Enable blurred placeholders for images",
"EnableBlurhashHelp": "Images that are still being loaded will be displayed with a blurred placeholder"
}

View file

@ -1453,7 +1453,6 @@
"LabelTranscodingFramerate": "Velocidad de cuadros de la transcodificación:",
"LabelSize": "Tamaño:",
"SelectAdminUsername": "Por favor, selecciona un nombre de usuario para la cuenta de administrador.",
"EnableFastImageFadeInHelp": "Habilita una animación más rápida de desvanecimiento para las imágenes cargadas.",
"LabelDroppedFrames": "Cuadros saltados:",
"CopyStreamURLError": "Hubo un error al copiar la URL.",
"ButtonSplit": "Dividir",
@ -1484,7 +1483,6 @@
"MessageConfirmAppExit": "¿Deseas salir?",
"LabelVideoResolution": "Resolución de video:",
"LabelStreamType": "Tipo de transmisión:",
"EnableFastImageFadeIn": "Desvanecimiento rápido de animaciones",
"LabelPlayerDimensions": "Dimensiones del reproductor:",
"LabelCorruptedFrames": "Cuadros corruptos:",
"HeaderNavigation": "Navegación",

View file

@ -1,5 +1,5 @@
{
"AccessRestrictedTryAgainLater": "El acceso está restringido actualmente. Por favor, inténtalo más tarde.",
"AccessRestrictedTryAgainLater": "Actualmente el acceso está restringido. Por favor, inténtalo de nuevo más tarde.",
"Add": "Añadir",
"AddItemToCollectionHelp": "Agregue elementos a las colecciones buscándolos y haciendo clic con el botón derecho o tocando los menús para agregarlos a una colección.",
"AddToCollection": "Añadir a la colección",
@ -1458,8 +1458,8 @@
"ButtonSplit": "Dividir",
"HeaderNavigation": "Navegación",
"MessageConfirmAppExit": "¿Quieres salir?",
"EnableFastImageFadeInHelp": "Mostrar carteles y otras imágenes con difuminado rápido cuando termine la carga.",
"EnableFastImageFadeIn": "Difuminado rápido de imágenes",
"EnableFasterAnimationsHelp": "Las animaciones y transiciones durarán menos tiempo",
"EnableFasterAnimations": "Animaciones más rápidas",
"CopyStreamURLError": "Ha habido un error copiando la dirección.",
"AllowFfmpegThrottlingHelp": "Cuando una transcodificación o un remux se adelanta lo suficiente desde la posición de reproducción actual, pause el proceso para que consuma menos recursos. Esto es más útil cuando se reproduce de forma linear, sin saltar de posición de reproducción a menudo. Desactívelo si experimenta problemas de reproducción.",
"PlaybackErrorNoCompatibleStream": "Este contenido no es compatible con este dispositivo y no se puede reproducir: No se puede obtener del servidor en un formato compatible.",
@ -1524,8 +1524,10 @@
"LabelEnableHttps": "Activar HTTPS",
"TabDVR": "DVR",
"SaveChanges": "Guardar cambios",
"EnableBlurhash": "Mostrar una representación de las imágenes mientras cargan",
"EnableBlurhashHelp": "Aparecerá una representación de los colores de las imágenes antes de que terminen de cargar",
"HeaderDVR": "DVR",
"SyncPlayAccessHelp": "Selecciona los permisos de este usuario para utilizar SyncPlay. SyncPlay te permite sincroniza la reproducción entre varios dispositivos.",
"SyncPlayAccessHelp": "Selecciona los permisos de este usuario para utilizar SyncPlay. SyncPlay te permite sincronizar la reproducción entre varios dispositivos.",
"MessageSyncPlayErrorMedia": "¡No se pudo activar SyncPlay! Error de medio.",
"MessageSyncPlayErrorMissingSession": "¡No se pudo activar SyncPlay! Sesión desconectada.",
"MessageSyncPlayErrorNoActivePlayer": "No hay reproductor activo. SyncPlay ha sido desactivado.",
@ -1556,5 +1558,7 @@
"HeaderSyncPlayEnabled": "Syncplay activo",
"HeaderSyncPlaySelectGroup": "Unirse a un grupo",
"EnableDetailsBannerHelp": "Mostrar imagen de banner en el tope de la página de detalles del elemento.",
"EnableDetailsBanner": "Barra de Detalles"
"EnableDetailsBanner": "Barra de Detalles",
"ShowMore": "Mostrar más",
"ShowLess": "Mostrar menos"
}

View file

@ -798,5 +798,6 @@
"LabelSelectFolderGroups": "به طور خودکار محتواهای پوشه‌های زیر را به فیلم ، موسیقی و تلویزیون گروه بندی شود:",
"LabelSeasonNumber": "شماره فصل:",
"ConfigureDateAdded": "تنظیم کنید که چگونه تاریخ اضافه شده در داشبورد سرور Jellyfin تحت تنظیمات کتابخانه تعیین می‌شود",
"CinemaModeConfigurationHelp": "حالت سینما تجربه تئاتر گونه را مستقیم به اتاق نشیمن شما می‌آورد با قابلیت پخش تریلرها و پیش نمایش‌ها قبل از سایر ویژگی‌های اصلی."
"CinemaModeConfigurationHelp": "حالت سینما تجربه تئاتر گونه را مستقیم به اتاق نشیمن شما می‌آورد با قابلیت پخش تریلرها و پیش نمایش‌ها قبل از سایر ویژگی‌های اصلی.",
"LaunchWebAppOnStartup": "نمای وب هنگامی که سرور آغاز به کار می‌کند باز بشود"
}

View file

@ -1458,8 +1458,6 @@
"MessageConfirmAppExit": "Voulez-vous quitter ?",
"LabelVideoResolution": "Résolution vidéo :",
"LabelStreamType": "Type de flux :",
"EnableFastImageFadeInHelp": "Activer un fondu plus rapide pour l'animation des images chargées.",
"EnableFastImageFadeIn": "Fondu d'image rapide",
"LabelPlayerDimensions": "Dimension du lecteur :",
"LabelDroppedFrames": "Images perdues :",
"LabelCorruptedFrames": "Images corrompues:",

View file

@ -1393,8 +1393,6 @@
"ButtonSplit": "Szétvág",
"Absolute": "Abszolút",
"LabelSkipIfAudioTrackPresentHelp": "Vedd ki a pipát, ha minden videóhoz szeretnél feliratot az audio nyelvétől függetlenül.",
"EnableFastImageFadeInHelp": "Poszterek és más képek megjelenítése gyorsabb animációkkal.",
"EnableFastImageFadeIn": "Gyors kép-előtűnés",
"SubtitleOffset": "Felirat eltolása",
"SeriesDisplayOrderHelp": "Rakd sorba az epizódokat az adásba kerülésük dátuma, a DVD sorszám, vagy az abszolút számozás szerint.",
"SelectAdminUsername": "Kérjük válassz felhasználónevet az adminisztrátor fiók számára.",

View file

@ -1455,8 +1455,6 @@
"MessageConfirmAppExit": "Vuoi uscire?",
"HeaderNavigation": "Navigazione",
"CopyStreamURLError": "Si è verificato un errore nel copiare l'indirizzo.",
"EnableFastImageFadeInHelp": "Mostra i poster e le altre immagini con una dissolvenza veloce alla fine del caricamento.",
"EnableFastImageFadeIn": "Dissolvenza Immagine Veloce",
"PlaybackErrorNoCompatibleStream": "Il client è incompatibile con il media e il server non sta inviando un formato compatibile.",
"OptionForceRemoteSourceTranscoding": "Forza la transcodifica da fonti di media remoti (come LiveTV)",
"NoCreatedLibraries": "Sembra che tu non abbia ancora creato delle librerie. {0}Vuoi crearne una adesso?{1}",

View file

@ -1484,8 +1484,6 @@
"MessageConfirmAppExit": "Shyǵýdy qalaısyz ba?",
"LabelVideoResolution": "Beıne ajyratymdylyǵy:",
"LabelStreamType": "Aǵyn túri:",
"EnableFastImageFadeInHelp": "Júktelgen sýretter úshin shapshan kórsetilýin qosý",
"EnableFastImageFadeIn": "Sýrettiń shapshan kórsetilýi",
"LabelPlayerDimensions": "Oınatqysh ólshemderi:",
"LabelDroppedFrames": "Ótkizilgen kadrlar:",
"LabelCorruptedFrames": "Búlingen kadrlar:",

View file

@ -1343,8 +1343,6 @@
"LabelSkipIfAudioTrackPresentHelp": "오디오 언어와 상관없이 모든 비디오가 자막을 갖추도록 하려면 이 항목을 체크하지 마십시오.",
"LabelSelectFolderGroupsHelp": "체크되지 않은 폴더는 폴더 고유의 보기 방식으로 표시됩니다.",
"LabelSelectFolderGroups": "자동으로 이하의 폴더의 항목을 영화, 음악, TV 와 같은 보기 방식으로 그룹화:",
"EnableFastImageFadeInHelp": "로드된 이미지에 더 빠른 페이드 인 효과를 적용",
"EnableFastImageFadeIn": "빠른 이미지 페이드 인 효과",
"LabelScheduledTaskLastRan": "최근 실행: {0}, 소모시간: {1}.",
"LabelRemoteClientBitrateLimitHelp": "(선택) 모든 외부 네트워크로 접속된 장치들에 적용되는 각 스트리밍별 비트레이트 제한입니다. 이는 서버의 인터넷이 처리할 수 있는 한계보다 더 높은 비트레이트를 요청하는 것을 방지할 수 있습니다. 비디오를 더 낮은 비트레이트로 트랜스코딩하기 위해 서버에 높은 CPU 부하를 줄 수 있습니다.",
"LabelReasonForTranscoding": "트랜스코딩 원인:",

View file

@ -1232,7 +1232,5 @@
"MessageUnauthorizedUser": "Jūs neesat autorizēti lai piekļūtu serverim šajā brīdī. Lūdzu sazinieties ar savu servera administratoru priekš papildus informācijas.",
"MessageInstallPluginFromApp": "Šis paplašinājums ir jāuzstāda no lietotnes, kurā jūs to vēlaties izmantot.",
"LabelEmbedAlbumArtDidl": "Ievietot albumu vākus iekš Didl",
"EnableFastImageFadeIn": "Ātra attēlu ieplūšana",
"EnableFastImageFadeInHelp": "Iespējot ātrāku ieplūšanas animāciju priekš ielādētiem attēliem",
"LabelSelectFolderGroups": "Automātiski grupēt saturu no sekojošām datnēm skatos kā Filmas, Mūzika un TV:"
}

View file

@ -1454,8 +1454,6 @@
"SelectAdminUsername": "Vennligst velg et brukernavn for administrator kontoen. ",
"HeaderNavigation": "Navigering",
"MessageConfirmAppExit": "Vil du avslutte?",
"EnableFastImageFadeInHelp": "Bruk rask inntoning av animasjon for lastede bilder",
"EnableFastImageFadeIn": "Rask bilde inntoning",
"CopyStreamURLError": "Det var en feil under kopiering av URL'en.",
"LabelVideoResolution": "Oppløsning på video:",
"LabelPlayerDimensions": "Dimensjoner på avspiller:",

View file

@ -1471,8 +1471,6 @@
"Artist": "Artiest",
"AllowFfmpegThrottlingHelp": "Wanneer een transcode of remux ver genoeg voorloopt op de huidige afspeelpositie, pauzeer het proces, zodat het minder middelen verbruikt. Dit is vooral handig wanneer u kijkt zonder vaak te zoeken. Schakel dit uit als u afspeelproblemen ondervindt.",
"AllowFfmpegThrottling": "Throttle Transcodes",
"EnableFastImageFadeInHelp": "Toon posters en andere afbeeldingen met een snellere fade-animatie wanneer ze klaar zijn met laden.",
"EnableFastImageFadeIn": "Fast Image Fade Animaties",
"LabelPlayerDimensions": "Afspeellengte:",
"LabelLibraryPageSizeHelp": "Kies het aantal artikelen dat wordt weergegeven op een bibliotheekpagina. Kies 0 om dit te verbergen.",
"LabelLibraryPageSize": "Bibliotheekpagina grootte:",

View file

@ -1466,8 +1466,6 @@
"NoCreatedLibraries": "Wygląda na to, że nie utworzyłeś jeszcze żadnych bibliotek. {0}Czy chcesz utworzyć jedną teraz?{1}",
"LabelVideoResolution": "Rozdzielczość wideo:",
"LabelStreamType": "Typ transmisji:",
"EnableFastImageFadeInHelp": "Włącz szybszą animację pojawiania się dla załadowanych obrazów",
"EnableFastImageFadeIn": "Szybkie pojawianie się obrazów",
"Artist": "Artysta",
"AlbumArtist": "Album artysty",
"Album": "Album",

View file

@ -1456,7 +1456,6 @@
"MessageConfirmAppExit": "Você quer sair?",
"LabelVideoResolution": "Resolução de vídeo:",
"LabelStreamType": "Tipo de stream:",
"EnableFastImageFadeIn": "Fade-in rápido da imagem",
"LabelPlayerDimensions": "Dimensões do player:",
"LabelCorruptedFrames": "Quadros corrompidos:",
"HeaderNavigation": "Navegação",
@ -1465,7 +1464,6 @@
"AskAdminToCreateLibrary": "Peça a um administrador para criar uma biblioteca.",
"AllowFfmpegThrottling": "Transcodes do Acelerador",
"PlaybackErrorNoCompatibleStream": "Este cliente não é compatível com a media e o servidor não está enviando um formato de mídia compatível.",
"EnableFastImageFadeInHelp": "Mostrar pôsteres e outras imagens com uma animação mais rápida ao terminar de carregar.",
"LabelDroppedFrames": "Quadros caídos:",
"AllowFfmpegThrottlingHelp": "Quando uma transcodificação ou remux estiver suficientemente avançada da posição atual de reprodução, pause o processo para que consuma menos recursos. Isso é mais proveitoso para quando não há avanço ou retrocesso do vídeo com frequência. Desative se tiver problemas de reprodução.",
"PreferEmbeddedEpisodeInfosOverFileNames": "Preferir informações dos episódios incorporadas nos arquivos ao invés dos nomes",

View file

@ -1314,8 +1314,6 @@
"LabelSortOrder": "Ordem de classificação:",
"LabelSortBy": "Ordenar por:",
"LabelSkin": "Pele:",
"EnableFastImageFadeInHelp": "Habilite uma animação mais rápida para imagens carregadas",
"EnableFastImageFadeIn": "Efeito de imagem fade-in rápido",
"LabelRemoteClientBitrateLimitHelp": "Um limite opcional de taxa de bits por fluxo para todos os dispositivos fora da rede. Isso é útil para impedir que os dispositivos solicitem uma taxa de bits mais alta do que a sua conexão à Internet pode suportar. Isso pode resultar no aumento da carga da CPU no servidor para transcodificar vídeos em tempo real para uma taxa de bits mais baixa.",
"LabelPlayerDimensions": "Dimensões do reprodutor:",
"LabelParentNumber": "Número pai:",

View file

@ -1454,8 +1454,6 @@
"HeaderNavigation": "Navigare",
"MessageConfirmAppExit": "Vrei să ieși?",
"CopyStreamURLError": "A apărut o eroare la copierea adresei URL.",
"EnableFastImageFadeInHelp": "Arătați postere și alte imagini cu o animație de tranziție rapidă când sunt deja încărcate.",
"EnableFastImageFadeIn": "Animație de Tranziție a Imaginii Rapidă",
"LabelVideoResolution": "Rezoluția video:",
"LabelStreamType": "Tipul streamului:",
"LabelPlayerDimensions": "Dimensiunile soft redare:",

View file

@ -1460,8 +1460,6 @@
"HeaderNavigation": "Навигация",
"LabelVideoResolution": "Разрешение видео:",
"LabelStreamType": "Тип потока:",
"EnableFastImageFadeInHelp": "Показывать постеры и другие рисунки анимацией побыстрее , когда они закончат загружаться.",
"EnableFastImageFadeIn": "Быстрое анимация рисунка",
"LabelPlayerDimensions": "Размеры проигрывателя:",
"LabelDroppedFrames": "Пропущенные кадры:",
"LabelCorruptedFrames": "Испорченные кадры:",
@ -1552,5 +1550,7 @@
"SyncPlayAccessHelp": "Выберите уровень доступа данного пользователя к функциональности SyncPlay. SyncPlay позволяет синхронизировать воспроизведение с другими устройствами.",
"MessageSyncPlayErrorMedia": "Не удалось включить SyncPlay! Ошибка медиаданных.",
"MessageSyncPlayErrorMissingSession": "Не удалось включить SyncPlay! Отсутствует сеанс.",
"MessageSyncPlayErrorNoActivePlayer": "Активный проигрыватель не найден. SyncPlay был отключен."
"MessageSyncPlayErrorNoActivePlayer": "Активный проигрыватель не найден. SyncPlay был отключен.",
"ShowMore": "Показать больше",
"ShowLess": "Показать меньше"
}

View file

@ -1457,8 +1457,6 @@
"MessageConfirmAppExit": "Chceli by ste odísiť?",
"LabelVideoResolution": "Rozlíšenie videa:",
"LabelStreamType": "Typ streamu:",
"EnableFastImageFadeInHelp": "Zobrazí plagát a ostatné obrázky s rýchlejšou animáciou prechodu po dokončení načítania.",
"EnableFastImageFadeIn": "Rýchla animácia prechodu obrázku",
"LabelPlayerDimensions": "Rozmery prehrávača:",
"LabelDroppedFrames": "Vynechané snímky:",
"LabelCorruptedFrames": "Poškodené snímky:",

View file

@ -1344,8 +1344,6 @@
"LabelSize": "Storlek:",
"LabelServerName": "Servernamn:",
"LabelSecureConnectionsMode": "Säker uppkopplings läge:",
"EnableFastImageFadeInHelp": "Aktivera snabbare fade-in animationer för laddade bilder",
"EnableFastImageFadeIn": "Snabb bild fade-in",
"LabelPostProcessorArgumentsHelp": "Använd {path} som sökväg till inspelade filen.",
"LabelPostProcessorArguments": "Post-processor kommandoradsargument:",
"LabelDroppedFrames": "Tappade ramar:",

View file

@ -1464,8 +1464,6 @@
"HeaderNavigation": "导航",
"CopyStreamURLError": "复制URL地址时发生错误。",
"MessageConfirmAppExit": "你要退出吗?",
"EnableFastImageFadeIn": "快速图片淡入淡出",
"EnableFastImageFadeInHelp": "为已加载的图片启用更快的图片淡入动画",
"OptionForceRemoteSourceTranscoding": "强制远程转码(像电视直播一样)",
"NoCreatedLibraries": "看上去您还未创建任何资料库。{0} 您想现在创建一个吗? {1}",
"AskAdminToCreateLibrary": "请联系管理员以创建一个新的资料库。",

View file

@ -1610,8 +1610,6 @@
"LaunchWebAppOnStartupHelp": "伺服器啓動時在默認游覽器中打開網頁端。使用重啓伺服器功能時此項不生效。",
"LabelVideoResolution": "視頻解析度:",
"LabelStreamType": "串流類型:",
"EnableFastImageFadeInHelp": "對已載入的圖片啟用更快的淡入動畫",
"EnableFastImageFadeIn": "圖片快速淡入效果",
"LabelPlayerDimensions": "播放器尺寸:",
"LabelDroppedFrames": "丟棄的幀:",
"LabelCorruptedFrames": "損壞的幀:",

View file

@ -131,23 +131,23 @@ html {
}
.defaultCardBackground1 {
background-color: #d2b019;
background-color: #213440;
}
.defaultCardBackground2 {
background-color: #338abb;
background-color: #8c6565;
}
.defaultCardBackground3 {
background-color: #6b689d;
background-color: #57778c;
}
.defaultCardBackground4 {
background-color: #dd452b;
background-color: #8c8c49;
}
.defaultCardBackground5 {
background-color: #5ccea9;
background-color: #404024;
}
.cardText-secondary,

View file

@ -113,23 +113,23 @@ html {
}
.defaultCardBackground1 {
background-color: #d2b019;
background-color: #00455c;
}
.defaultCardBackground2 {
background-color: #338abb;
background-color: #44bae1;
}
.defaultCardBackground3 {
background-color: #6b689d;
background-color: #00a4db;
}
.defaultCardBackground4 {
background-color: #dd452b;
background-color: #1c4c5c;
}
.defaultCardBackground5 {
background-color: #5ccea9;
background-color: #007ea8;
}
.cardText-secondary,

View file

@ -221,23 +221,23 @@ a[data-role=button] {
}
.defaultCardBackground1 {
background-color: #d2b019;
background-color: #9c20ab;
}
.defaultCardBackground2 {
background-color: #338abb;
background-color: #d799de;
}
.defaultCardBackground3 {
background-color: #6b689d;
background-color: #412378;
}
.defaultCardBackground4 {
background-color: #dd452b;
background-color: #857b48;
}
.defaultCardBackground5 {
background-color: #5ccea9;
background-color: #ab8820;
}
.cardText-secondary,

179
yarn.lock
View file

@ -911,6 +911,11 @@
resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.0.tgz#551a4589b6ee2cc9c1dff08056128aec29b94880"
integrity sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA==
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/jszip@^3.4.1":
version "3.4.1"
resolved "https://registry.yarnpkg.com/@types/jszip/-/jszip-3.4.1.tgz#e7a4059486e494c949ef750933d009684227846f"
@ -1427,7 +1432,7 @@ array-find-index@^1.0.1:
resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=
array-includes@^3.0.3:
array-includes@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348"
integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==
@ -1487,7 +1492,7 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
array.prototype.flat@^1.2.1:
array.prototype.flat@^1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b"
integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==
@ -1606,7 +1611,7 @@ atob@^2.1.2:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
autoprefixer@^9.0.0, autoprefixer@^9.6.1, autoprefixer@^9.7.6, autoprefixer@^9.8.0:
autoprefixer@^9.0.0, autoprefixer@^9.6.1, autoprefixer@^9.8.0:
version "9.8.0"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.0.tgz#68e2d2bef7ba4c3a65436f662d0a56a741e56511"
integrity sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==
@ -1836,6 +1841,11 @@ bluebird@^3.5.5:
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
blurhash@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-1.1.3.tgz#dc325af7da836d07a0861d830bdd63694382483e"
integrity sha512-yUhPJvXexbqbyijCIE/T2NCXcj9iNPhWmOKbPTuR/cm7Q5snXYIfnVnz6m7MWOXxODMz/Cr3UcVkRdHiuDVRDw==
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
version "4.11.8"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
@ -3838,7 +3848,7 @@ escape-string-regexp@^2.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
eslint-import-resolver-node@^0.3.2:
eslint-import-resolver-node@^0.3.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404"
integrity sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==
@ -3846,7 +3856,7 @@ eslint-import-resolver-node@^0.3.2:
debug "^2.6.9"
resolve "^1.13.1"
eslint-module-utils@^2.4.1:
eslint-module-utils@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6"
integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==
@ -3875,23 +3885,24 @@ eslint-plugin-eslint-comments@^3.2.0:
escape-string-regexp "^1.0.5"
ignore "^5.0.5"
eslint-plugin-import@^2.20.2:
version "2.20.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz#91fc3807ce08be4837141272c8b99073906e588d"
integrity sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg==
eslint-plugin-import@^2.21.1:
version "2.21.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.21.1.tgz#3398318e5e4abbd23395c4964ce61538705154c8"
integrity sha512-qYOOsgUv63vHof7BqbzuD+Ud34bXHxFJxntuAC1ZappFZXYbRIek3aJ7jc9i2dHDGDyZ/0zlO0cpioES265Lsw==
dependencies:
array-includes "^3.0.3"
array.prototype.flat "^1.2.1"
array-includes "^3.1.1"
array.prototype.flat "^1.2.3"
contains-path "^0.1.0"
debug "^2.6.9"
doctrine "1.5.0"
eslint-import-resolver-node "^0.3.2"
eslint-module-utils "^2.4.1"
eslint-import-resolver-node "^0.3.3"
eslint-module-utils "^2.6.0"
has "^1.0.3"
minimatch "^3.0.4"
object.values "^1.1.0"
object.values "^1.1.1"
read-pkg-up "^2.0.0"
resolve "^1.12.0"
resolve "^1.17.0"
tsconfig-paths "^3.9.0"
eslint-plugin-promise@^4.2.1:
version "4.2.1"
@ -4869,10 +4880,10 @@ globby@^10.0.0, globby@^10.0.1:
merge2 "^1.2.3"
slash "^3.0.0"
globby@^11.0.0:
version "11.0.0"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.0.tgz#56fd0e9f0d4f8fb0c456f1ab0dee96e1380bc154"
integrity sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==
globby@^11.0.1:
version "11.0.1"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357"
integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==
dependencies:
array-union "^2.1.0"
dir-glob "^3.0.1"
@ -5017,10 +5028,10 @@ gulp-babel@^8.0.0:
through2 "^2.0.0"
vinyl-sourcemaps-apply "^0.2.0"
gulp-cli@^2.2.0, gulp-cli@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.2.1.tgz#376e427661b7996430a89d71c15df75defa3360a"
integrity sha512-yEMxrXqY8mJFlaauFQxNrCpzWJThu0sH1sqlToaTOT063Hub9s/Nt2C+GSLe6feQ/IMWrHvGOOsyES7CQc9O+A==
gulp-cli@^2.2.0, gulp-cli@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.3.0.tgz#ec0d380e29e52aa45e47977f0d32e18fd161122f"
integrity sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==
dependencies:
ansi-colors "^1.0.1"
archy "^1.0.0"
@ -5030,7 +5041,7 @@ gulp-cli@^2.2.0, gulp-cli@^2.2.1:
copy-props "^2.0.1"
fancy-log "^1.3.2"
gulplog "^1.0.0"
interpret "^1.1.0"
interpret "^1.4.0"
isobject "^3.0.1"
liftoff "^3.1.0"
matchdep "^2.0.0"
@ -5038,7 +5049,7 @@ gulp-cli@^2.2.0, gulp-cli@^2.2.1:
pretty-hrtime "^1.0.0"
replace-homedir "^1.0.0"
semver-greatest-satisfied-range "^1.1.0"
v8flags "^3.0.1"
v8flags "^3.2.0"
yargs "^7.1.0"
gulp-concat@^2.6.1:
@ -5552,10 +5563,10 @@ ignore@^4.0.3, ignore@^4.0.6:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
ignore@^5.0.4, ignore@^5.0.5, ignore@^5.1.1, ignore@^5.1.4:
version "5.1.4"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf"
integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==
ignore@^5.0.4, ignore@^5.0.5, ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8:
version "5.1.8"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
imagemin-gifsicle@^7.0.0:
version "7.0.0"
@ -5744,10 +5755,10 @@ inquirer@^7.0.0:
strip-ansi "^6.0.0"
through "^2.3.6"
interpret@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
interpret@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
intersection-observer@^0.10.0:
version "0.10.0"
@ -6228,10 +6239,10 @@ isurl@^1.0.0-alpha5:
has-to-string-tag-x "^1.2.0"
is-object "^1.0.1"
jellyfin-apiclient@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/jellyfin-apiclient/-/jellyfin-apiclient-1.2.1.tgz#1da577f7e22c37be8ec23c139b9ddab2c36da5a2"
integrity sha512-5aNtUq7YsoDPZ0LL6cq55HDnSTVfECfw05hbPFxNsFlUogEiHwaoIz+ahWRO13OUFQJuiu8f3fy16glcGzrBIQ==
jellyfin-apiclient@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/jellyfin-apiclient/-/jellyfin-apiclient-1.2.2.tgz#64f058320603df02d926f4c1b929b42c6acc4527"
integrity sha512-UwC56orm4darWlnNQJ1nbKo+W8ywlheJSJC6d9zm06CslYtOc/Dkv9kz2PadQEh+6EiBsB0hAZCc7FJ9ahOoGQ==
"jellyfin-noto@https://github.com/jellyfin/jellyfin-noto":
version "1.0.3"
@ -7654,7 +7665,7 @@ object.reduce@^1.0.0:
for-own "^1.0.0"
make-iterator "^1.0.0"
object.values@^1.1.0:
object.values@^1.1.0, object.values@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e"
integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==
@ -8851,12 +8862,12 @@ postcss-sass@^0.4.4:
gonzales-pe "^4.3.0"
postcss "^7.0.21"
postcss-scss@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-2.0.0.tgz#248b0a28af77ea7b32b1011aba0f738bda27dea1"
integrity sha512-um9zdGKaDZirMm+kZFKKVsnKPF7zF7qBAtIfTSnZXD1jZ0JNZIxdB6TxQOjCnlSzLRInVl2v3YdBh/M881C4ug==
postcss-scss@^2.0.0, postcss-scss@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-2.1.1.tgz#ec3a75fa29a55e016b90bf3269026c53c1d2b383"
integrity sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==
dependencies:
postcss "^7.0.0"
postcss "^7.0.6"
postcss-selector-matches@^4.0.0:
version "4.0.0"
@ -8979,10 +8990,10 @@ postcss@^5.0.0, postcss@^5.0.18:
source-map "^0.5.6"
supports-color "^3.2.3"
postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.30, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7:
version "7.0.30"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.30.tgz#cc9378beffe46a02cbc4506a0477d05fcea9a8e2"
integrity sha512-nu/0m+NtIzoubO+xdAlwZl/u5S5vi/y6BCsoL8D+8IxsD3XvBS8X4YEADNIVXKVuQvduiucnRv+vPIqj56EGMQ==
postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.30, postcss@^7.0.31, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7:
version "7.0.32"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d"
integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==
dependencies:
chalk "^2.4.2"
source-map "^0.6.1"
@ -9142,10 +9153,10 @@ query-string@^5.0.1:
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
query-string@^6.11.1:
version "6.12.1"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.12.1.tgz#2ae4d272db4fba267141665374e49a1de09e8a7c"
integrity sha512-OHj+zzfRMyj3rmo/6G8a5Ifvw3AleL/EbcHMD27YA31Q+cO5lfmQxECkImuNVjcskLcvBRVHNAB3w6udMs1eAA==
query-string@^6.13.0:
version "6.13.0"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.0.tgz#8d875f66581c854d7480ac79478abb847de742f6"
integrity sha512-KJe8p8EUcixhPCp4cJoTYVfmgKHjnAB/Pq3fiqlmyNHvpHnOL5U4YE7iI2PYivGHp4HFocWz300906BAQX0H7g==
dependencies:
decode-uri-component "^0.2.0"
split-on-first "^1.0.0"
@ -9678,7 +9689,7 @@ resolve-url@^0.2.1:
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.3.2, resolve@^1.4.0:
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.4.0:
version "1.17.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
@ -10725,23 +10736,23 @@ stylelint-order@^2.2.1:
postcss "^7.0.2"
postcss-sorting "^4.1.0"
stylelint-order@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/stylelint-order/-/stylelint-order-4.0.0.tgz#2a945c2198caac3ff44687d7c8582c81d044b556"
integrity sha512-bXV0v+jfB0+JKsqIn3mLglg1Dj2QCYkFHNfL1c+rVMEmruZmW5LUqT/ARBERfBm8SFtCuXpEdatidw/3IkcoiA==
stylelint-order@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/stylelint-order/-/stylelint-order-4.1.0.tgz#692d05b7d0c235ac66fcf5ea1d9e5f08a76747f6"
integrity sha512-sVTikaDvMqg2aJjh4r48jsdfmqLT+nqB1MOsaBnvM3OwLx4S+WXcsxsgk5w18h/OZoxZCxuyXMh61iBHcj9Qiw==
dependencies:
lodash "^4.17.15"
postcss "^7.0.26"
postcss "^7.0.31"
postcss-sorting "^5.0.1"
stylelint@^13.5.0:
version "13.5.0"
resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.5.0.tgz#9edbf90c8c02c47fd0c4818376e3799145f22cab"
integrity sha512-+Jy7ieKAWKTf2tmcAE7jgScxH39Urb87i0bjK/enScFaGWWaFn4kAPwepGOSk2b7CLUDVt/O6kwA0x0p/V7moQ==
stylelint@^13.6.0:
version "13.6.0"
resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.6.0.tgz#3528bc402a71f2af2a3de32fa4e9f1c24e49666d"
integrity sha512-55gG2pNjVr183JJM/tlr3KAua6vTVX7Ho/lgKKuCIWszTZ1gmrXjX4Wok53SI8wRYFPbwKAcJGULQ77OJxTcNw==
dependencies:
"@stylelint/postcss-css-in-js" "^0.37.1"
"@stylelint/postcss-markdown" "^0.36.1"
autoprefixer "^9.7.6"
autoprefixer "^9.8.0"
balanced-match "^1.0.0"
chalk "^4.0.0"
cosmiconfig "^6.0.0"
@ -10750,10 +10761,10 @@ stylelint@^13.5.0:
file-entry-cache "^5.0.1"
get-stdin "^8.0.0"
global-modules "^2.0.0"
globby "^11.0.0"
globby "^11.0.1"
globjoin "^0.1.4"
html-tags "^3.1.0"
ignore "^5.1.4"
ignore "^5.1.8"
import-lazy "^4.0.0"
imurmurhash "^0.1.4"
known-css-properties "^0.19.0"
@ -10764,7 +10775,7 @@ stylelint@^13.5.0:
meow "^7.0.1"
micromatch "^4.0.2"
normalize-selector "^0.2.0"
postcss "^7.0.30"
postcss "^7.0.32"
postcss-html "^0.36.0"
postcss-less "^3.1.4"
postcss-media-query-parser "^0.2.3"
@ -10772,7 +10783,7 @@ stylelint@^13.5.0:
postcss-resolve-nested-selector "^0.1.1"
postcss-safe-parser "^4.0.2"
postcss-sass "^0.4.4"
postcss-scss "^2.0.0"
postcss-scss "^2.1.1"
postcss-selector-parser "^6.0.2"
postcss-syntax "^0.36.2"
postcss-value-parser "^4.1.0"
@ -10785,7 +10796,7 @@ stylelint@^13.5.0:
sugarss "^2.0.0"
svg-tags "^1.0.0"
table "^5.4.6"
v8-compile-cache "^2.1.0"
v8-compile-cache "^2.1.1"
write-file-atomic "^3.0.3"
stylelint@^9.1, stylelint@^9.10.1:
@ -10913,10 +10924,10 @@ svgo@^1.0.0, svgo@^1.3.2:
unquote "~1.1.1"
util.promisify "~1.0.0"
swiper@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/swiper/-/swiper-5.4.1.tgz#6731e000e97f8b6560c11b141ebaf559063af565"
integrity sha512-l2EiWe7uOXB2EBMVLtJqn51FW22wF9e24WETT+S+tuFNvSDq1gadc/hyGGsAMqFGKJKIO6q6cqk7ToVaOI+onw==
swiper@^5.4.2:
version "5.4.2"
resolved "https://registry.yarnpkg.com/swiper/-/swiper-5.4.2.tgz#ed4cf60ea7100edac2703e406ae4ae2c43d33e7c"
integrity sha512-c6E5kDC3xAhnhdV0omIkDKLr+qNxzMfTO3Nw/T4xNAwSMoJwPvgsRoVzDBEUQbkWqwomHsvcjPMn12VQ6IHDTQ==
dependencies:
dom7 "^2.1.5"
ssr-window "^2.0.0"
@ -11219,6 +11230,16 @@ trough@^1.0.0:
dependencies:
glob "^7.1.2"
tsconfig-paths@^3.9.0:
version "3.9.0"
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b"
integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==
dependencies:
"@types/json5" "^0.0.29"
json5 "^1.0.1"
minimist "^1.2.0"
strip-bom "^3.0.0"
tslib@^1.10.0, tslib@^1.9.0:
version "1.11.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
@ -11668,15 +11689,15 @@ uuid@^3.0.1, uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e"
integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==
v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745"
integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==
v8flags@^3.0.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.3.tgz#fc9dc23521ca20c5433f81cc4eb9b3033bb105d8"
integrity sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==
v8flags@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656"
integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==
dependencies:
homedir-polyfill "^1.0.1"