';
html += items.map(function (filter) {
- var itemHtml = '';
- var checkedHtml = isCheckedFn(filter) ? ' checked' : '';
+ let itemHtml = '';
+ const checkedHtml = isCheckedFn(filter) ? 'checked' : '';
itemHtml += '
';
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;
- query.StartIndex = 0;
- query.IsFavorite = !!this.checked || null;
- triggerChange(self);
+ class FilterDialog {
+ constructor(options) {
+ /**
+ * @private
+ */
+ this.options = options;
}
- function onStandardFilterChange() {
- var query = options.query;
- var filterName = this.getAttribute('data-filter');
- var filters = query.Filters || '';
- filters = (',' + filters).replace(',' + filterName, '').substring(1);
+ /**
+ * @private
+ */
+ onFavoriteChange(elem) {
+ const query = this.options.query;
+ query.StartIndex = 0;
+ query.IsFavorite = !!elem.checked || null;
+ triggerChange(this);
+ }
- if (this.checked) {
- filters = filters ? filters + ',' + filterName : filterName;
+ /**
+ * @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 (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;
diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js
index f23b407def..f7183515c5 100644
--- a/src/components/images/imageLoader.js
+++ b/src/components/images/imageLoader.js
@@ -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);
}
-
- if (userSettings.enableFastFadein()) {
- elem.classList.add('lazy-image-fadein-fast');
- } else {
- elem.classList.add('lazy-image-fadein');
- }
-
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');
+ }
+ } 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) {
diff --git a/src/components/images/style.css b/src/components/images/style.css
index 2b9422d55b..a709f732c5 100644
--- a/src/components/images/style.css
+++ b/src/components/images/style.css
@@ -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;
+}
diff --git a/src/components/listview/listview.js b/src/components/listview/listview.js
index 587355b351..7bafc925b2 100644
--- a/src/components/listview/listview.js
+++ b/src/components/listview/listview.js
@@ -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 += '
';
+ html += '
';
} else {
html += '
';
}
diff --git a/src/components/mediainfo/mediainfo.js b/src/components/mediainfo/mediainfo.js
index c569a7c78c..7de11c42f7 100644
--- a/src/components/mediainfo/mediainfo.js
+++ b/src/components/mediainfo/mediainfo.js
@@ -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') {
diff --git a/src/components/packagemanager.js b/src/components/packageManager.js
similarity index 100%
rename from src/components/packagemanager.js
rename to src/components/packageManager.js
diff --git a/src/components/playback/brightnessosd.js b/src/components/playback/brightnessosd.js
index 5ed2b8f81f..5f3becd64b 100644
--- a/src/components/playback/brightnessosd.js
+++ b/src/components/playback/brightnessosd.js
@@ -1,171 +1,171 @@
-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;
- var iconElement;
- var progressElement;
+var currentPlayer;
+var osdElement;
+var iconElement;
+var progressElement;
- var enableAnimation;
+var enableAnimation;
- function getOsdElementHtml() {
- var html = '';
+function getOsdElementHtml() {
+ var html = '';
- html += '
';
+ html += '
';
- html += '
';
+ html += '
';
- return html;
+ return html;
+}
+
+function ensureOsdElement() {
+
+ var elem = osdElement;
+ if (!elem) {
+
+ enableAnimation = browser.supportsCssAnimation();
+
+ elem = document.createElement('div');
+ elem.classList.add('hide');
+ elem.classList.add('iconOsd');
+ elem.classList.add('iconOsd-hidden');
+ elem.classList.add('brightnessOsd');
+ elem.innerHTML = getOsdElementHtml();
+
+ iconElement = elem.querySelector('.material-icons');
+ progressElement = elem.querySelector('.iconOsdProgressInner');
+
+ document.body.appendChild(elem);
+ osdElement = elem;
}
+}
- function ensureOsdElement() {
+function onHideComplete() {
+ this.classList.add('hide');
+}
- var elem = osdElement;
- if (!elem) {
+var hideTimeout;
+function showOsd() {
- enableAnimation = browser.supportsCssAnimation();
+ clearHideTimeout();
- elem = document.createElement('div');
- elem.classList.add('hide');
- elem.classList.add('iconOsd');
- elem.classList.add('iconOsd-hidden');
- elem.classList.add('brightnessOsd');
- elem.innerHTML = getOsdElementHtml();
+ var elem = osdElement;
- iconElement = elem.querySelector('.material-icons');
- progressElement = elem.querySelector('.iconOsdProgressInner');
-
- document.body.appendChild(elem);
- osdElement = elem;
- }
- }
-
- function onHideComplete() {
- this.classList.add('hide');
- }
-
- var hideTimeout;
- function showOsd() {
-
- clearHideTimeout();
-
- var elem = osdElement;
-
- dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
- once: true
- });
-
- elem.classList.remove('hide');
-
- // trigger reflow
- void elem.offsetWidth;
-
- requestAnimationFrame(function () {
- elem.classList.remove('iconOsd-hidden');
-
- hideTimeout = setTimeout(hideOsd, 3000);
- });
- }
-
- function clearHideTimeout() {
- if (hideTimeout) {
- clearTimeout(hideTimeout);
- hideTimeout = null;
- }
- }
-
- function hideOsd() {
-
- clearHideTimeout();
-
- var elem = osdElement;
- if (elem) {
-
- if (enableAnimation) {
- // trigger reflow
- void elem.offsetWidth;
-
- requestAnimationFrame(function () {
- elem.classList.add('iconOsd-hidden');
-
- dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
- once: true
- });
- });
- } else {
- onHideComplete.call(elem);
- }
- }
- }
-
- function setIcon(iconElement, icon) {
- iconElement.classList.remove('brightness_high');
- iconElement.classList.remove('brightness_medium');
- iconElement.classList.remove('brightness_low');
- iconElement.classList.add(icon);
- }
-
- function updateElementsFromPlayer(brightness) {
-
- if (iconElement) {
- if (brightness >= 80) {
- setIcon(iconElement, 'brightness_high');
- } else if (brightness >= 20) {
- setIcon(iconElement, 'brightness_medium');
- } else {
- setIcon(iconElement, 'brightness_low');
- }
- }
- if (progressElement) {
- progressElement.style.width = (brightness || 0) + '%';
- }
- }
-
- function releaseCurrentPlayer() {
-
- var player = currentPlayer;
-
- if (player) {
- events.off(player, 'brightnesschange', onBrightnessChanged);
- events.off(player, 'playbackstop', hideOsd);
- currentPlayer = null;
- }
- }
-
- function onBrightnessChanged(e) {
-
- var player = this;
-
- ensureOsdElement();
-
- updateElementsFromPlayer(playbackManager.getBrightness(player));
-
- showOsd();
- }
-
- function bindToPlayer(player) {
-
- if (player === currentPlayer) {
- return;
- }
-
- releaseCurrentPlayer();
-
- currentPlayer = player;
-
- if (!player) {
- return;
- }
-
- hideOsd();
- events.on(player, 'brightnesschange', onBrightnessChanged);
- events.on(player, 'playbackstop', hideOsd);
- }
-
- events.on(playbackManager, 'playerchange', function () {
- bindToPlayer(playbackManager.getCurrentPlayer());
+ dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
+ once: true
});
- bindToPlayer(playbackManager.getCurrentPlayer());
+ elem.classList.remove('hide');
+ // trigger reflow
+ void elem.offsetWidth;
+
+ requestAnimationFrame(function () {
+ elem.classList.remove('iconOsd-hidden');
+
+ hideTimeout = setTimeout(hideOsd, 3000);
+ });
+}
+
+function clearHideTimeout() {
+ if (hideTimeout) {
+ clearTimeout(hideTimeout);
+ hideTimeout = null;
+ }
+}
+
+function hideOsd() {
+
+ clearHideTimeout();
+
+ var elem = osdElement;
+ if (elem) {
+
+ if (enableAnimation) {
+ // trigger reflow
+ void elem.offsetWidth;
+
+ requestAnimationFrame(function () {
+ elem.classList.add('iconOsd-hidden');
+
+ dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
+ once: true
+ });
+ });
+ } else {
+ onHideComplete.call(elem);
+ }
+ }
+}
+
+function setIcon(iconElement, icon) {
+ iconElement.classList.remove('brightness_high', 'brightness_medium', 'brightness_low');
+ iconElement.classList.add(icon);
+}
+
+function updateElementsFromPlayer(brightness) {
+
+ if (iconElement) {
+ if (brightness >= 80) {
+ setIcon(iconElement, 'brightness_high');
+ } else if (brightness >= 20) {
+ setIcon(iconElement, 'brightness_medium');
+ } else {
+ setIcon(iconElement, 'brightness_low');
+ }
+ }
+ if (progressElement) {
+ progressElement.style.width = (brightness || 0) + '%';
+ }
+}
+
+function releaseCurrentPlayer() {
+
+ var player = currentPlayer;
+
+ if (player) {
+ events.off(player, 'brightnesschange', onBrightnessChanged);
+ events.off(player, 'playbackstop', hideOsd);
+ currentPlayer = null;
+ }
+}
+
+function onBrightnessChanged(e) {
+
+ var player = this;
+
+ ensureOsdElement();
+
+ updateElementsFromPlayer(playbackManager.getBrightness(player));
+
+ showOsd();
+}
+
+function bindToPlayer(player) {
+
+ if (player === currentPlayer) {
+ return;
+ }
+
+ releaseCurrentPlayer();
+
+ currentPlayer = player;
+
+ if (!player) {
+ return;
+ }
+
+ hideOsd();
+ events.on(player, 'brightnesschange', onBrightnessChanged);
+ events.on(player, 'playbackstop', hideOsd);
+}
+
+events.on(playbackManager, 'playerchange', function () {
+ bindToPlayer(playbackManager.getCurrentPlayer());
});
+
+bindToPlayer(playbackManager.getCurrentPlayer());
diff --git a/src/components/playback/nowplayinghelper.js b/src/components/playback/nowplayinghelper.js
index 9bba23c294..310edc03c3 100644
--- a/src/components/playback/nowplayinghelper.js
+++ b/src/components/playback/nowplayinghelper.js
@@ -1,86 +1,82 @@
-define([], function () {
- 'use strict';
+export function getNowPlayingNames(nowPlayingItem, includeNonNameInfo) {
- function getNowPlayingNames(nowPlayingItem, includeNonNameInfo) {
+ var topItem = nowPlayingItem;
+ var bottomItem = null;
+ var topText = nowPlayingItem.Name;
- var topItem = nowPlayingItem;
- var bottomItem = null;
- var topText = nowPlayingItem.Name;
-
- if (nowPlayingItem.AlbumId && nowPlayingItem.MediaType === 'Audio') {
- topItem = {
- Id: nowPlayingItem.AlbumId,
- Name: nowPlayingItem.Album,
- Type: 'MusicAlbum',
- IsFolder: true
- };
- }
-
- if (nowPlayingItem.MediaType === 'Video') {
- if (nowPlayingItem.IndexNumber != null) {
- topText = nowPlayingItem.IndexNumber + ' - ' + topText;
- }
- if (nowPlayingItem.ParentIndexNumber != null) {
- topText = nowPlayingItem.ParentIndexNumber + '.' + topText;
- }
- }
-
- var bottomText = '';
-
- if (nowPlayingItem.ArtistItems && nowPlayingItem.ArtistItems.length) {
-
- bottomItem = {
- Id: nowPlayingItem.ArtistItems[0].Id,
- Name: nowPlayingItem.ArtistItems[0].Name,
- Type: 'MusicArtist',
- IsFolder: true
- };
-
- bottomText = nowPlayingItem.ArtistItems.map(function (a) {
- return a.Name;
- }).join(', ');
-
- } else if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) {
-
- bottomText = nowPlayingItem.Artists.join(', ');
- } else if (nowPlayingItem.SeriesName || nowPlayingItem.Album) {
- bottomText = topText;
- topText = nowPlayingItem.SeriesName || nowPlayingItem.Album;
-
- bottomItem = topItem;
-
- if (nowPlayingItem.SeriesId) {
- topItem = {
- Id: nowPlayingItem.SeriesId,
- Name: nowPlayingItem.SeriesName,
- Type: 'Series',
- IsFolder: true
- };
- } else {
- topItem = null;
- }
- } else if (nowPlayingItem.ProductionYear && includeNonNameInfo !== false) {
- bottomText = nowPlayingItem.ProductionYear;
- }
-
- var list = [];
-
- list.push({
- text: topText,
- item: topItem
- });
-
- if (bottomText) {
- list.push({
- text: bottomText,
- item: bottomItem
- });
- }
-
- return list;
+ if (nowPlayingItem.AlbumId && nowPlayingItem.MediaType === 'Audio') {
+ topItem = {
+ Id: nowPlayingItem.AlbumId,
+ Name: nowPlayingItem.Album,
+ Type: 'MusicAlbum',
+ IsFolder: true
+ };
}
- return {
- getNowPlayingNames: getNowPlayingNames
- };
-});
+ if (nowPlayingItem.MediaType === 'Video') {
+ if (nowPlayingItem.IndexNumber != null) {
+ topText = nowPlayingItem.IndexNumber + ' - ' + topText;
+ }
+ if (nowPlayingItem.ParentIndexNumber != null) {
+ topText = nowPlayingItem.ParentIndexNumber + '.' + topText;
+ }
+ }
+
+ var bottomText = '';
+
+ if (nowPlayingItem.ArtistItems && nowPlayingItem.ArtistItems.length) {
+
+ bottomItem = {
+ Id: nowPlayingItem.ArtistItems[0].Id,
+ Name: nowPlayingItem.ArtistItems[0].Name,
+ Type: 'MusicArtist',
+ IsFolder: true
+ };
+
+ bottomText = nowPlayingItem.ArtistItems.map(function (a) {
+ return a.Name;
+ }).join(', ');
+
+ } else if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) {
+
+ bottomText = nowPlayingItem.Artists.join(', ');
+ } else if (nowPlayingItem.SeriesName || nowPlayingItem.Album) {
+ bottomText = topText;
+ topText = nowPlayingItem.SeriesName || nowPlayingItem.Album;
+
+ bottomItem = topItem;
+
+ if (nowPlayingItem.SeriesId) {
+ topItem = {
+ Id: nowPlayingItem.SeriesId,
+ Name: nowPlayingItem.SeriesName,
+ Type: 'Series',
+ IsFolder: true
+ };
+ } else {
+ topItem = null;
+ }
+ } else if (nowPlayingItem.ProductionYear && includeNonNameInfo !== false) {
+ bottomText = nowPlayingItem.ProductionYear;
+ }
+
+ var list = [];
+
+ list.push({
+ text: topText,
+ item: topItem
+ });
+
+ if (bottomText) {
+ list.push({
+ text: bottomText,
+ item: bottomItem
+ });
+ }
+
+ return list;
+}
+
+export default {
+ getNowPlayingNames: getNowPlayingNames
+};
diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js
index 88d4e0d599..73f07a05f2 100644
--- a/src/components/playback/playbackmanager.js
+++ b/src/components/playback/playbackmanager.js
@@ -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) {
diff --git a/src/components/playback/playbackorientation.js b/src/components/playback/playbackorientation.js
index 654ac29848..2078c6f6a8 100644
--- a/src/components/playback/playbackorientation.js
+++ b/src/components/playback/playbackorientation.js
@@ -1,57 +1,57 @@
-define(['playbackManager', 'layoutManager', 'events'], function (playbackManager, layoutManager, events) {
- 'use strict';
+import playbackManager from 'playbackManager';
+import layoutManager from 'layoutManager';
+import events from 'events';
- var orientationLocked;
+var orientationLocked;
- function onOrientationChangeSuccess() {
- orientationLocked = true;
- }
+function onOrientationChangeSuccess() {
+ orientationLocked = true;
+}
- function onOrientationChangeError(err) {
- orientationLocked = false;
- console.error('error locking orientation: ' + err);
- }
+function onOrientationChangeError(err) {
+ orientationLocked = false;
+ console.error('error locking orientation: ' + err);
+}
- events.on(playbackManager, 'playbackstart', function (e, player, state) {
+events.on(playbackManager, 'playbackstart', function (e, player, state) {
- var isLocalVideo = player.isLocalPlayer && !player.isExternalPlayer && playbackManager.isPlayingVideo(player);
+ var isLocalVideo = player.isLocalPlayer && !player.isExternalPlayer && playbackManager.isPlayingVideo(player);
- if (isLocalVideo && layoutManager.mobile) {
- /* eslint-disable-next-line compat/compat */
- var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation || (screen.orientation && screen.orientation.lock);
+ if (isLocalVideo && layoutManager.mobile) {
+ /* eslint-disable-next-line compat/compat */
+ var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation || (screen.orientation && screen.orientation.lock);
- if (lockOrientation) {
+ if (lockOrientation) {
- try {
- var promise = lockOrientation('landscape');
- if (promise.then) {
- promise.then(onOrientationChangeSuccess, onOrientationChangeError);
- } else {
- // returns a boolean
- orientationLocked = promise;
- }
- } catch (err) {
- onOrientationChangeError(err);
+ try {
+ var promise = lockOrientation('landscape');
+ if (promise.then) {
+ promise.then(onOrientationChangeSuccess, onOrientationChangeError);
+ } else {
+ // returns a boolean
+ orientationLocked = promise;
}
+ } catch (err) {
+ onOrientationChangeError(err);
}
}
- });
-
- events.on(playbackManager, 'playbackstop', function (e, playbackStopInfo) {
-
- if (orientationLocked && !playbackStopInfo.nextMediaType) {
-
- /* eslint-disable-next-line compat/compat */
- var unlockOrientation = screen.unlockOrientation || screen.mozUnlockOrientation || screen.msUnlockOrientation || (screen.orientation && screen.orientation.unlock);
-
- if (unlockOrientation) {
- try {
- unlockOrientation();
- } catch (err) {
- console.error('error unlocking orientation: ' + err);
- }
- orientationLocked = false;
- }
- }
- });
+ }
+});
+
+events.on(playbackManager, 'playbackstop', function (e, playbackStopInfo) {
+
+ if (orientationLocked && !playbackStopInfo.nextMediaType) {
+
+ /* eslint-disable-next-line compat/compat */
+ var unlockOrientation = screen.unlockOrientation || screen.mozUnlockOrientation || screen.msUnlockOrientation || (screen.orientation && screen.orientation.unlock);
+
+ if (unlockOrientation) {
+ try {
+ unlockOrientation();
+ } catch (err) {
+ console.error('error unlocking orientation: ' + err);
+ }
+ orientationLocked = false;
+ }
+ }
});
diff --git a/src/components/playback/playerSelectionMenu.js b/src/components/playback/playerSelectionMenu.js
index 329cc11f92..91b1ddc20b 100644
--- a/src/components/playback/playerSelectionMenu.js
+++ b/src/components/playback/playerSelectionMenu.js
@@ -1,320 +1,325 @@
-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) {
+function mirrorItem(info, player) {
- var item = info.item;
+ var item = info.item;
- playbackManager.displayContent({
+ playbackManager.displayContent({
- ItemName: item.Name,
- ItemId: item.Id,
- ItemType: item.Type,
- Context: info.context
- }, player);
- }
+ ItemName: item.Name,
+ ItemId: item.Id,
+ ItemType: item.Type,
+ Context: info.context
+ }, player);
+}
- function mirrorIfEnabled(info) {
+function mirrorIfEnabled(info) {
- if (info && playbackManager.enableDisplayMirroring()) {
+ if (info && playbackManager.enableDisplayMirroring()) {
- var getPlayerInfo = playbackManager.getPlayerInfo();
+ var getPlayerInfo = playbackManager.getPlayerInfo();
- if (getPlayerInfo) {
- if (!getPlayerInfo.isLocalPlayer && getPlayerInfo.supportedCommands.indexOf('DisplayContent') !== -1) {
- mirrorItem(info, playbackManager.getCurrentPlayer());
- }
+ if (getPlayerInfo) {
+ if (!getPlayerInfo.isLocalPlayer && getPlayerInfo.supportedCommands.indexOf('DisplayContent') !== -1) {
+ mirrorItem(info, playbackManager.getCurrentPlayer());
}
}
}
+}
- function emptyCallback() {
- // avoid console logs about uncaught promises
+function emptyCallback() {
+ // avoid console logs about uncaught promises
+}
+
+function getTargetSecondaryText(target) {
+
+ if (target.user) {
+
+ return target.user.Name;
}
- function getTargetSecondaryText(target) {
+ return null;
+}
- if (target.user) {
+function getIcon(target) {
- return target.user.Name;
- }
+ var deviceType = target.deviceType;
- return null;
- }
-
- function getIcon(target) {
-
- var deviceType = target.deviceType;
-
- if (!deviceType && target.isLocalPlayer) {
- if (browser.tv) {
- deviceType = 'tv';
- } else if (browser.mobile) {
- deviceType = 'smartphone';
- } else {
- deviceType = 'desktop';
- }
- }
-
- if (!deviceType) {
+ if (!deviceType && target.isLocalPlayer) {
+ if (browser.tv) {
deviceType = 'tv';
- }
-
- switch (deviceType) {
-
- case 'smartphone':
- return 'smartphone';
- case 'tablet':
- return 'tablet';
- case 'tv':
- return 'tv';
- case 'cast':
- return 'cast';
- case 'desktop':
- return 'computer';
- default:
- return 'tv';
- }
- }
-
- function showPlayerSelection(button) {
-
- var currentPlayerInfo = playbackManager.getPlayerInfo();
-
- if (currentPlayerInfo) {
- if (!currentPlayerInfo.isLocalPlayer) {
- showActivePlayerMenu(currentPlayerInfo);
- return;
- }
- }
-
- var currentPlayerId = currentPlayerInfo ? currentPlayerInfo.id : null;
-
- loading.show();
-
- playbackManager.getTargets().then(function (targets) {
-
- var menuItems = targets.map(function (t) {
-
- var name = t.name;
-
- if (t.appName && t.appName !== t.name) {
- name += ' - ' + t.appName;
- }
-
- return {
- name: name,
- id: t.id,
- selected: currentPlayerId === t.id,
- secondaryText: getTargetSecondaryText(t),
- icon: getIcon(t)
- };
-
- });
-
- require(['actionsheet'], function (actionsheet) {
-
- loading.hide();
-
- var menuOptions = {
- title: globalize.translate('HeaderPlayOn'),
- items: menuItems,
- positionTo: button,
-
- resolveOnClick: true,
- border: true
- };
-
- // Unfortunately we can't allow the url to change or chromecast will throw a security error
- // Might be able to solve this in the future by moving the dialogs to hashbangs
- if (!(!browser.chrome || appHost.supports('castmenuhashchange'))) {
- menuOptions.enableHistory = false;
- }
-
- actionsheet.show(menuOptions).then(function (id) {
-
- var target = targets.filter(function (t) {
- return t.id === id;
- })[0];
-
- playbackManager.trySetActivePlayer(target.playerName, target);
-
- mirrorIfEnabled();
-
- }, emptyCallback);
- });
- });
- }
-
- function showActivePlayerMenu(playerInfo) {
-
- require(['dialogHelper', 'dialog', 'emby-checkbox', 'emby-button'], function (dialogHelper) {
- showActivePlayerMenuInternal(dialogHelper, playerInfo);
- });
- }
-
- function disconnectFromPlayer(currentDeviceName) {
-
- if (playbackManager.getSupportedCommands().indexOf('EndSession') !== -1) {
-
- require(['dialog'], function (dialog) {
-
- var menuItems = [];
-
- menuItems.push({
- name: globalize.translate('Yes'),
- id: 'yes'
- });
- menuItems.push({
- name: globalize.translate('No'),
- id: 'no'
- });
-
- dialog({
- buttons: menuItems,
- //positionTo: positionTo,
- text: globalize.translate('ConfirmEndPlayerSession', currentDeviceName)
-
- }).then(function (id) {
- switch (id) {
-
- case 'yes':
- playbackManager.getCurrentPlayer().endSession();
- playbackManager.setDefaultPlayerActive();
- break;
- case 'no':
- playbackManager.setDefaultPlayerActive();
- break;
- default:
- break;
- }
- });
-
- });
-
+ } else if (browser.mobile) {
+ deviceType = 'smartphone';
} else {
-
- playbackManager.setDefaultPlayerActive();
+ deviceType = 'desktop';
}
}
- function showActivePlayerMenuInternal(dialogHelper, playerInfo) {
-
- var html = '';
-
- var dialogOptions = {
- removeOnClose: true
- };
-
- dialogOptions.modal = false;
- dialogOptions.entryAnimationDuration = 160;
- dialogOptions.exitAnimationDuration = 160;
- dialogOptions.autoFocus = false;
-
- var dlg = dialogHelper.createDialog(dialogOptions);
-
- dlg.classList.add('promptDialog');
-
- var currentDeviceName = (playerInfo.deviceName || playerInfo.name);
-
- html += '
';
- html += '
';
- html += currentDeviceName;
- html += '
';
-
- html += '
';
-
- if (playerInfo.supportedCommands.indexOf('DisplayContent') !== -1) {
-
- html += '';
- }
-
- html += '
';
-
- html += '
';
-
- html += '';
- html += '';
- html += '';
- html += '
';
-
- html += '
';
- dlg.innerHTML = html;
-
- var chkMirror = dlg.querySelector('.chkMirror');
-
- if (chkMirror) {
- chkMirror.addEventListener('change', onMirrorChange);
- }
-
- var destination = '';
-
- var btnRemoteControl = dlg.querySelector('.btnRemoteControl');
- if (btnRemoteControl) {
- btnRemoteControl.addEventListener('click', function () {
- destination = 'nowplaying';
- dialogHelper.close(dlg);
- });
- }
-
- dlg.querySelector('.btnDisconnect').addEventListener('click', function () {
- destination = 'disconnectFromPlayer';
- dialogHelper.close(dlg);
- });
-
- dlg.querySelector('.btnCancel').addEventListener('click', function () {
- dialogHelper.close(dlg);
- });
-
- dialogHelper.open(dlg).then(function () {
- if (destination === 'nowplaying') {
- appRouter.showNowPlaying();
- } else if (destination === 'disconnectFromPlayer') {
- disconnectFromPlayer(currentDeviceName);
- }
- }, emptyCallback);
+ if (!deviceType) {
+ deviceType = 'tv';
}
- function onMirrorChange() {
- playbackManager.enableDisplayMirroring(this.checked);
+ switch (deviceType) {
+
+ case 'smartphone':
+ return 'smartphone';
+ case 'tablet':
+ return 'tablet';
+ case 'tv':
+ return 'tv';
+ case 'cast':
+ return 'cast';
+ case 'desktop':
+ return 'computer';
+ default:
+ return 'tv';
}
+}
- document.addEventListener('viewshow', function (e) {
+export function show(button) {
- var state = e.detail.state || {};
- var item = state.item;
+ var currentPlayerInfo = playbackManager.getPlayerInfo();
- if (item && item.ServerId) {
- mirrorIfEnabled({
- item: item
- });
+ if (currentPlayerInfo) {
+ if (!currentPlayerInfo.isLocalPlayer) {
+ showActivePlayerMenu(currentPlayerInfo);
return;
}
- });
+ }
- events.on(appSettings, 'change', function (e, name) {
- if (name === 'displaymirror') {
- mirrorIfEnabled();
- }
- });
+ var currentPlayerId = currentPlayerInfo ? currentPlayerInfo.id : null;
- events.on(playbackManager, 'pairing', function (e) {
- loading.show();
- });
+ loading.show();
- events.on(playbackManager, 'paired', function (e) {
- loading.hide();
- });
+ playbackManager.getTargets().then(function (targets) {
- events.on(playbackManager, 'pairerror', function (e) {
- loading.hide();
- });
+ var menuItems = targets.map(function (t) {
- return {
- show: showPlayerSelection
+ var name = t.name;
+
+ if (t.appName && t.appName !== t.name) {
+ name += ' - ' + t.appName;
+ }
+
+ return {
+ name: name,
+ id: t.id,
+ selected: currentPlayerId === t.id,
+ secondaryText: getTargetSecondaryText(t),
+ icon: getIcon(t)
+ };
+
+ });
+
+ require(['actionsheet'], function (actionsheet) {
+
+ loading.hide();
+
+ var menuOptions = {
+ title: globalize.translate('HeaderPlayOn'),
+ items: menuItems,
+ positionTo: button,
+
+ resolveOnClick: true,
+ border: true
+ };
+
+ // Unfortunately we can't allow the url to change or chromecast will throw a security error
+ // Might be able to solve this in the future by moving the dialogs to hashbangs
+ if (!(!browser.chrome || appHost.supports('castmenuhashchange'))) {
+ menuOptions.enableHistory = false;
+ }
+
+ actionsheet.show(menuOptions).then(function (id) {
+
+ var target = targets.filter(function (t) {
+ return t.id === id;
+ })[0];
+
+ playbackManager.trySetActivePlayer(target.playerName, target);
+
+ mirrorIfEnabled();
+
+ }, emptyCallback);
+ });
+ });
+}
+
+function showActivePlayerMenu(playerInfo) {
+
+ require(['dialogHelper', 'dialog', 'emby-checkbox', 'emby-button'], function (dialogHelper) {
+ showActivePlayerMenuInternal(dialogHelper, playerInfo);
+ });
+}
+
+function disconnectFromPlayer(currentDeviceName) {
+
+ if (playbackManager.getSupportedCommands().indexOf('EndSession') !== -1) {
+
+ require(['dialog'], function (dialog) {
+
+ var menuItems = [];
+
+ menuItems.push({
+ name: globalize.translate('Yes'),
+ id: 'yes'
+ });
+ menuItems.push({
+ name: globalize.translate('No'),
+ id: 'no'
+ });
+
+ dialog({
+ buttons: menuItems,
+ //positionTo: positionTo,
+ text: globalize.translate('ConfirmEndPlayerSession', currentDeviceName)
+
+ }).then(function (id) {
+ switch (id) {
+
+ case 'yes':
+ playbackManager.getCurrentPlayer().endSession();
+ playbackManager.setDefaultPlayerActive();
+ break;
+ case 'no':
+ playbackManager.setDefaultPlayerActive();
+ break;
+ default:
+ break;
+ }
+ });
+
+ });
+
+ } else {
+
+ playbackManager.setDefaultPlayerActive();
+ }
+}
+
+function showActivePlayerMenuInternal(dialogHelper, playerInfo) {
+
+ var html = '';
+
+ var dialogOptions = {
+ removeOnClose: true
};
+
+ dialogOptions.modal = false;
+ dialogOptions.entryAnimationDuration = 160;
+ dialogOptions.exitAnimationDuration = 160;
+ dialogOptions.autoFocus = false;
+
+ var dlg = dialogHelper.createDialog(dialogOptions);
+
+ dlg.classList.add('promptDialog');
+
+ var currentDeviceName = (playerInfo.deviceName || playerInfo.name);
+
+ html += '
';
+ html += '
';
+ html += currentDeviceName;
+ html += '
';
+
+ html += '
';
+
+ if (playerInfo.supportedCommands.indexOf('DisplayContent') !== -1) {
+
+ html += '';
+ }
+
+ html += '
';
+
+ html += '
';
+
+ html += '';
+ html += '';
+ html += '';
+ html += '
';
+
+ html += '
';
+ dlg.innerHTML = html;
+
+ var chkMirror = dlg.querySelector('.chkMirror');
+
+ if (chkMirror) {
+ chkMirror.addEventListener('change', onMirrorChange);
+ }
+
+ var destination = '';
+
+ var btnRemoteControl = dlg.querySelector('.btnRemoteControl');
+ if (btnRemoteControl) {
+ btnRemoteControl.addEventListener('click', function () {
+ destination = 'nowplaying';
+ dialogHelper.close(dlg);
+ });
+ }
+
+ dlg.querySelector('.btnDisconnect').addEventListener('click', function () {
+ destination = 'disconnectFromPlayer';
+ dialogHelper.close(dlg);
+ });
+
+ dlg.querySelector('.btnCancel').addEventListener('click', function () {
+ dialogHelper.close(dlg);
+ });
+
+ dialogHelper.open(dlg).then(function () {
+ if (destination === 'nowplaying') {
+ appRouter.showNowPlaying();
+ } else if (destination === 'disconnectFromPlayer') {
+ disconnectFromPlayer(currentDeviceName);
+ }
+ }, emptyCallback);
+}
+
+function onMirrorChange() {
+ playbackManager.enableDisplayMirroring(this.checked);
+}
+
+document.addEventListener('viewshow', function (e) {
+
+ var state = e.detail.state || {};
+ var item = state.item;
+
+ if (item && item.ServerId) {
+ mirrorIfEnabled({
+ item: item
+ });
+ return;
+ }
});
+
+events.on(appSettings, 'change', function (e, name) {
+ if (name === 'displaymirror') {
+ mirrorIfEnabled();
+ }
+});
+
+events.on(playbackManager, 'pairing', function (e) {
+ loading.show();
+});
+
+events.on(playbackManager, 'paired', function (e) {
+ loading.hide();
+});
+
+events.on(playbackManager, 'pairerror', function (e) {
+ loading.hide();
+});
+
+export default {
+ show: show
+};
diff --git a/src/components/playback/playersettingsmenu.js b/src/components/playback/playersettingsmenu.js
index dd67b667e6..33d252c52a 100644
--- a/src/components/playback/playersettingsmenu.js
+++ b/src/components/playback/playersettingsmenu.js
@@ -1,270 +1,272 @@
-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) {
+function showQualityMenu(player, btn) {
- var videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function (stream) {
- return stream.Type === 'Video';
- })[0];
- var videoWidth = videoStream ? videoStream.Width : null;
- var videoHeight = videoStream ? videoStream.Height : null;
+ var videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function (stream) {
+ return stream.Type === 'Video';
+ })[0];
+ var videoWidth = videoStream ? videoStream.Width : null;
+ var videoHeight = videoStream ? videoStream.Height : null;
- var options = qualityoptions.getVideoQualityOptions({
- currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player),
- isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player),
- videoWidth: videoWidth,
- videoHeight: videoHeight,
- enableAuto: true
- });
+ var options = qualityoptions.getVideoQualityOptions({
+ currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player),
+ isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player),
+ videoWidth: videoWidth,
+ videoHeight: videoHeight,
+ enableAuto: true
+ });
- var menuItems = options.map(function (o) {
- var opt = {
- name: o.name,
- id: o.bitrate,
- asideText: o.secondaryText
- };
+ var menuItems = options.map(function (o) {
+ var opt = {
+ name: o.name,
+ id: o.bitrate,
+ asideText: o.secondaryText
+ };
- if (o.selected) {
- opt.selected = true;
- }
+ if (o.selected) {
+ opt.selected = true;
+ }
- return opt;
- });
+ return opt;
+ });
- var selectedId = options.filter(function (o) {
- return o.selected;
- });
+ var selectedId = options.filter(function (o) {
+ return o.selected;
+ });
- selectedId = selectedId.length ? selectedId[0].bitrate : null;
+ selectedId = selectedId.length ? selectedId[0].bitrate : null;
- return actionsheet.show({
- items: menuItems,
- positionTo: btn
- }).then(function (id) {
- var bitrate = parseInt(id);
- if (bitrate !== selectedId) {
- playbackManager.setMaxStreamingBitrate({
- enableAutomaticBitrateDetection: bitrate ? false : true,
- maxBitrate: bitrate
- }, player);
- }
- });
+ return actionsheet.show({
+ items: menuItems,
+ positionTo: btn
+ }).then(function (id) {
+ var bitrate = parseInt(id);
+ if (bitrate !== selectedId) {
+ playbackManager.setMaxStreamingBitrate({
+ enableAutomaticBitrateDetection: bitrate ? false : true,
+ maxBitrate: bitrate
+ }, player);
+ }
+ });
+}
+
+function showRepeatModeMenu(player, btn) {
+ var menuItems = [];
+ var currentValue = playbackManager.getRepeatMode(player);
+
+ menuItems.push({
+ name: globalize.translate('RepeatAll'),
+ id: 'RepeatAll',
+ selected: currentValue === 'RepeatAll'
+ });
+
+ menuItems.push({
+ name: globalize.translate('RepeatOne'),
+ id: 'RepeatOne',
+ selected: currentValue === 'RepeatOne'
+ });
+
+ menuItems.push({
+ name: globalize.translate('None'),
+ id: 'RepeatNone',
+ selected: currentValue === 'RepeatNone'
+ });
+
+ return actionsheet.show({
+ items: menuItems,
+ positionTo: btn
+ }).then(function (mode) {
+ if (mode) {
+ playbackManager.setRepeatMode(mode, player);
+ }
+ });
+}
+
+function getQualitySecondaryText(player) {
+ var state = playbackManager.getPlayerState(player);
+ var isAutoEnabled = playbackManager.enableAutomaticBitrateDetection(player);
+ var currentMaxBitrate = playbackManager.getMaxStreamingBitrate(player);
+
+ var videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function (stream) {
+ return stream.Type === 'Video';
+ })[0];
+
+ var videoWidth = videoStream ? videoStream.Width : null;
+ var videoHeight = videoStream ? videoStream.Height : null;
+
+ var options = qualityoptions.getVideoQualityOptions({
+ currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player),
+ isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player),
+ videoWidth: videoWidth,
+ videoHeight: videoHeight,
+ enableAuto: true
+ });
+
+ var menuItems = options.map(function (o) {
+ var opt = {
+ name: o.name,
+ id: o.bitrate,
+ asideText: o.secondaryText
+ };
+
+ if (o.selected) {
+ opt.selected = true;
+ }
+
+ return opt;
+ });
+
+ var selectedOption = options.filter(function (o) {
+ return o.selected;
+ });
+
+ if (!selectedOption.length) {
+ return null;
}
- function showRepeatModeMenu(player, btn) {
- var menuItems = [];
- var currentValue = playbackManager.getRepeatMode(player);
+ selectedOption = selectedOption[0];
+ var text = selectedOption.name;
- menuItems.push({
- name: globalize.translate('RepeatAll'),
- id: 'RepeatAll',
- selected: currentValue === 'RepeatAll'
- });
-
- menuItems.push({
- name: globalize.translate('RepeatOne'),
- id: 'RepeatOne',
- selected: currentValue === 'RepeatOne'
- });
-
- menuItems.push({
- name: globalize.translate('None'),
- id: 'RepeatNone',
- selected: currentValue === 'RepeatNone'
- });
-
- return actionsheet.show({
- items: menuItems,
- positionTo: btn
- }).then(function (mode) {
- if (mode) {
- playbackManager.setRepeatMode(mode, player);
- }
- });
+ if (selectedOption.autoText) {
+ if (state.PlayState && state.PlayState.PlayMethod !== 'Transcode') {
+ text += ' - Direct';
+ } else {
+ text += ' ' + selectedOption.autoText;
+ }
}
- function getQualitySecondaryText(player) {
- var state = playbackManager.getPlayerState(player);
- var isAutoEnabled = playbackManager.enableAutomaticBitrateDetection(player);
- var currentMaxBitrate = playbackManager.getMaxStreamingBitrate(player);
+ return text;
+}
- var videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function (stream) {
- return stream.Type === 'Video';
- })[0];
+function showAspectRatioMenu(player, btn) {
+ // each has a name and id
+ var currentId = playbackManager.getAspectRatio(player);
+ var menuItems = playbackManager.getSupportedAspectRatios(player).map(function (i) {
+ return {
+ id: i.id,
+ name: i.name,
+ selected: i.id === currentId
+ };
+ });
- var videoWidth = videoStream ? videoStream.Width : null;
- var videoHeight = videoStream ? videoStream.Height : null;
-
- var options = qualityoptions.getVideoQualityOptions({
- currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player),
- isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player),
- videoWidth: videoWidth,
- videoHeight: videoHeight,
- enableAuto: true
- });
-
- var menuItems = options.map(function (o) {
- var opt = {
- name: o.name,
- id: o.bitrate,
- asideText: o.secondaryText
- };
-
- if (o.selected) {
- opt.selected = true;
- }
-
- return opt;
- });
-
- var selectedOption = options.filter(function (o) {
- return o.selected;
- });
-
- if (!selectedOption.length) {
- return null;
- }
-
- selectedOption = selectedOption[0];
- var text = selectedOption.name;
-
- if (selectedOption.autoText) {
- if (state.PlayState && state.PlayState.PlayMethod !== 'Transcode') {
- text += ' - Direct';
- } else {
- text += ' ' + selectedOption.autoText;
- }
- }
-
- return text;
- }
-
- function showAspectRatioMenu(player, btn) {
- // each has a name and id
- var currentId = playbackManager.getAspectRatio(player);
- var menuItems = playbackManager.getSupportedAspectRatios(player).map(function (i) {
- return {
- id: i.id,
- name: i.name,
- selected: i.id === currentId
- };
- });
-
- return actionsheet.show({
- items: menuItems,
- positionTo: btn
- }).then(function (id) {
- if (id) {
- playbackManager.setAspectRatio(id, player);
- return Promise.resolve();
- }
-
- return Promise.reject();
- });
- }
-
- function showWithUser(options, player, user) {
- var supportedCommands = playbackManager.getSupportedCommands(player);
- var mediaType = options.mediaType;
-
- var menuItems = [];
- if (supportedCommands.indexOf('SetAspectRatio') !== -1) {
- var currentAspectRatioId = playbackManager.getAspectRatio(player);
- var currentAspectRatio = playbackManager.getSupportedAspectRatios(player).filter(function (i) {
- return i.id === currentAspectRatioId;
- })[0];
-
- menuItems.push({
- name: globalize.translate('AspectRatio'),
- id: 'aspectratio',
- asideText: currentAspectRatio ? currentAspectRatio.name : null
- });
- }
-
- if (user && user.Policy.EnableVideoPlaybackTranscoding) {
- var secondaryQualityText = getQualitySecondaryText(player);
-
- menuItems.push({
- name: globalize.translate('Quality'),
- id: 'quality',
- asideText: secondaryQualityText
- });
- }
-
- var repeatMode = playbackManager.getRepeatMode(player);
-
- if (supportedCommands.indexOf('SetRepeatMode') !== -1 && playbackManager.currentMediaSource(player).RunTimeTicks) {
- menuItems.push({
- name: globalize.translate('RepeatMode'),
- id: 'repeatmode',
- asideText: repeatMode === 'RepeatNone' ? globalize.translate('None') : globalize.translate('' + repeatMode)
- });
- }
-
- if (options.suboffset) {
- menuItems.push({
- name: globalize.translate('SubtitleOffset'),
- id: 'suboffset',
- asideText: null
- });
- }
-
- if (options.stats) {
- menuItems.push({
- name: globalize.translate('PlaybackData'),
- id: 'stats',
- asideText: null
- });
- }
-
- return actionsheet.show({
- items: menuItems,
- positionTo: options.positionTo
- }).then(function (id) {
- return handleSelectedOption(id, options, player);
- });
- }
-
- function show(options) {
- var player = options.player;
- var currentItem = playbackManager.currentItem(player);
-
- if (!currentItem || !currentItem.ServerId) {
- return showWithUser(options, player, null);
- }
-
- var apiClient = connectionManager.getApiClient(currentItem.ServerId);
- return apiClient.getCurrentUser().then(function (user) {
- return showWithUser(options, player, user);
- });
- }
-
- function handleSelectedOption(id, options, player) {
- switch (id) {
- case 'quality':
- return showQualityMenu(player, options.positionTo);
- case 'aspectratio':
- return showAspectRatioMenu(player, options.positionTo);
- case 'repeatmode':
- return showRepeatModeMenu(player, options.positionTo);
- case 'stats':
- if (options.onOption) {
- options.onOption('stats');
- }
- return Promise.resolve();
- case 'suboffset':
- if (options.onOption) {
- options.onOption('suboffset');
- }
- return Promise.resolve();
- default:
- break;
+ return actionsheet.show({
+ items: menuItems,
+ positionTo: btn
+ }).then(function (id) {
+ if (id) {
+ playbackManager.setAspectRatio(id, player);
+ return Promise.resolve();
}
return Promise.reject();
+ });
+}
+
+function showWithUser(options, player, user) {
+ var supportedCommands = playbackManager.getSupportedCommands(player);
+ var mediaType = options.mediaType;
+
+ var menuItems = [];
+ if (supportedCommands.indexOf('SetAspectRatio') !== -1) {
+ var currentAspectRatioId = playbackManager.getAspectRatio(player);
+ var currentAspectRatio = playbackManager.getSupportedAspectRatios(player).filter(function (i) {
+ return i.id === currentAspectRatioId;
+ })[0];
+
+ menuItems.push({
+ name: globalize.translate('AspectRatio'),
+ id: 'aspectratio',
+ asideText: currentAspectRatio ? currentAspectRatio.name : null
+ });
}
- return {
- show: show
- };
-});
+ if (user && user.Policy.EnableVideoPlaybackTranscoding) {
+ var secondaryQualityText = getQualitySecondaryText(player);
+
+ menuItems.push({
+ name: globalize.translate('Quality'),
+ id: 'quality',
+ asideText: secondaryQualityText
+ });
+ }
+
+ var repeatMode = playbackManager.getRepeatMode(player);
+
+ if (supportedCommands.indexOf('SetRepeatMode') !== -1 && playbackManager.currentMediaSource(player).RunTimeTicks) {
+ menuItems.push({
+ name: globalize.translate('RepeatMode'),
+ id: 'repeatmode',
+ asideText: repeatMode === 'RepeatNone' ? globalize.translate('None') : globalize.translate('' + repeatMode)
+ });
+ }
+
+ if (options.suboffset) {
+ menuItems.push({
+ name: globalize.translate('SubtitleOffset'),
+ id: 'suboffset',
+ asideText: null
+ });
+ }
+
+ if (options.stats) {
+ menuItems.push({
+ name: globalize.translate('PlaybackData'),
+ id: 'stats',
+ asideText: null
+ });
+ }
+
+ return actionsheet.show({
+ items: menuItems,
+ positionTo: options.positionTo
+ }).then(function (id) {
+ return handleSelectedOption(id, options, player);
+ });
+}
+
+export function show(options) {
+ var player = options.player;
+ var currentItem = playbackManager.currentItem(player);
+
+ if (!currentItem || !currentItem.ServerId) {
+ return showWithUser(options, player, null);
+ }
+
+ var apiClient = connectionManager.getApiClient(currentItem.ServerId);
+ return apiClient.getCurrentUser().then(function (user) {
+ return showWithUser(options, player, user);
+ });
+}
+
+function handleSelectedOption(id, options, player) {
+ switch (id) {
+ case 'quality':
+ return showQualityMenu(player, options.positionTo);
+ case 'aspectratio':
+ return showAspectRatioMenu(player, options.positionTo);
+ case 'repeatmode':
+ return showRepeatModeMenu(player, options.positionTo);
+ case 'stats':
+ if (options.onOption) {
+ options.onOption('stats');
+ }
+ return Promise.resolve();
+ case 'suboffset':
+ if (options.onOption) {
+ options.onOption('suboffset');
+ }
+ return Promise.resolve();
+ default:
+ break;
+ }
+
+ return Promise.reject();
+}
+
+export default {
+ show: show
+};
diff --git a/src/components/playback/playmethodhelper.js b/src/components/playback/playmethodhelper.js
index 75af04035c..62793b9a33 100644
--- a/src/components/playback/playmethodhelper.js
+++ b/src/components/playback/playmethodhelper.js
@@ -1,24 +1,20 @@
-define([], function () {
- 'use strict';
+export function getDisplayPlayMethod(session) {
- function getDisplayPlayMethod(session) {
-
- if (!session.NowPlayingItem) {
- return null;
- }
-
- if (session.TranscodingInfo && session.TranscodingInfo.IsVideoDirect) {
- return 'DirectStream';
- } else if (session.PlayState.PlayMethod === 'Transcode') {
- return 'Transcode';
- } else if (session.PlayState.PlayMethod === 'DirectStream') {
- return 'DirectPlay';
- } else if (session.PlayState.PlayMethod === 'DirectPlay') {
- return 'DirectPlay';
- }
+ if (!session.NowPlayingItem) {
+ return null;
}
- return {
- getDisplayPlayMethod: getDisplayPlayMethod
- };
-});
+ if (session.TranscodingInfo && session.TranscodingInfo.IsVideoDirect) {
+ return 'DirectStream';
+ } else if (session.PlayState.PlayMethod === 'Transcode') {
+ return 'Transcode';
+ } else if (session.PlayState.PlayMethod === 'DirectStream') {
+ return 'DirectPlay';
+ } else if (session.PlayState.PlayMethod === 'DirectPlay') {
+ return 'DirectPlay';
+ }
+}
+
+export default {
+ getDisplayPlayMethod: getDisplayPlayMethod
+};
diff --git a/src/components/playback/volumeosd.js b/src/components/playback/volumeosd.js
index 95a13d769d..c2f6761f53 100644
--- a/src/components/playback/volumeosd.js
+++ b/src/components/playback/volumeosd.js
@@ -1,159 +1,161 @@
-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;
- var iconElement;
- var progressElement;
+var currentPlayer;
+var osdElement;
+var iconElement;
+var progressElement;
- var enableAnimation;
+var enableAnimation;
- function getOsdElementHtml() {
- var html = '';
+function getOsdElementHtml() {
+ var html = '';
- html += '
';
+ html += '
';
- html += '
';
+ html += '
';
- return html;
+ return html;
+}
+
+function ensureOsdElement() {
+
+ var elem = osdElement;
+ if (!elem) {
+
+ enableAnimation = browser.supportsCssAnimation();
+
+ elem = document.createElement('div');
+ elem.classList.add('hide');
+ elem.classList.add('iconOsd');
+ elem.classList.add('iconOsd-hidden');
+ elem.classList.add('volumeOsd');
+ elem.innerHTML = getOsdElementHtml();
+
+ iconElement = elem.querySelector('.material-icons');
+ progressElement = elem.querySelector('.iconOsdProgressInner');
+
+ document.body.appendChild(elem);
+ osdElement = elem;
}
+}
- function ensureOsdElement() {
+function onHideComplete() {
+ this.classList.add('hide');
+}
- var elem = osdElement;
- if (!elem) {
+var hideTimeout;
+function showOsd() {
- enableAnimation = browser.supportsCssAnimation();
+ clearHideTimeout();
- elem = document.createElement('div');
- elem.classList.add('hide');
- elem.classList.add('iconOsd');
- elem.classList.add('iconOsd-hidden');
- elem.classList.add('volumeOsd');
- elem.innerHTML = getOsdElementHtml();
+ var elem = osdElement;
- iconElement = elem.querySelector('.material-icons');
- progressElement = elem.querySelector('.iconOsdProgressInner');
-
- document.body.appendChild(elem);
- osdElement = elem;
- }
- }
-
- function onHideComplete() {
- this.classList.add('hide');
- }
-
- var hideTimeout;
- function showOsd() {
-
- clearHideTimeout();
-
- var elem = osdElement;
-
- dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
- once: true
- });
-
- elem.classList.remove('hide');
-
- // trigger reflow
- void elem.offsetWidth;
-
- requestAnimationFrame(function () {
- elem.classList.remove('iconOsd-hidden');
-
- hideTimeout = setTimeout(hideOsd, 3000);
- });
- }
-
- function clearHideTimeout() {
- if (hideTimeout) {
- clearTimeout(hideTimeout);
- hideTimeout = null;
- }
- }
-
- function hideOsd() {
-
- clearHideTimeout();
-
- var elem = osdElement;
- if (elem) {
-
- if (enableAnimation) {
- // trigger reflow
- void elem.offsetWidth;
-
- requestAnimationFrame(function () {
- elem.classList.add('iconOsd-hidden');
-
- dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
- once: true
- });
- });
- } else {
- onHideComplete.call(elem);
- }
- }
- }
-
- function updatePlayerVolumeState(isMuted, volume) {
-
- if (iconElement) {
- iconElement.classList.remove('volume_off', 'volume_up');
- iconElement.classList.add(isMuted ? 'volume_off' : 'volume_up');
- }
- if (progressElement) {
- progressElement.style.width = (volume || 0) + '%';
- }
- }
-
- function releaseCurrentPlayer() {
-
- var player = currentPlayer;
-
- if (player) {
- events.off(player, 'volumechange', onVolumeChanged);
- events.off(player, 'playbackstop', hideOsd);
- currentPlayer = null;
- }
- }
-
- function onVolumeChanged(e) {
-
- var player = this;
-
- ensureOsdElement();
-
- updatePlayerVolumeState(player.isMuted(), player.getVolume());
-
- showOsd();
- }
-
- function bindToPlayer(player) {
-
- if (player === currentPlayer) {
- return;
- }
-
- releaseCurrentPlayer();
-
- currentPlayer = player;
-
- if (!player) {
- return;
- }
-
- hideOsd();
- events.on(player, 'volumechange', onVolumeChanged);
- events.on(player, 'playbackstop', hideOsd);
- }
-
- events.on(playbackManager, 'playerchange', function () {
- bindToPlayer(playbackManager.getCurrentPlayer());
+ dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
+ once: true
});
- bindToPlayer(playbackManager.getCurrentPlayer());
+ elem.classList.remove('hide');
+ // trigger reflow
+ void elem.offsetWidth;
+
+ requestAnimationFrame(function () {
+ elem.classList.remove('iconOsd-hidden');
+
+ hideTimeout = setTimeout(hideOsd, 3000);
+ });
+}
+
+function clearHideTimeout() {
+ if (hideTimeout) {
+ clearTimeout(hideTimeout);
+ hideTimeout = null;
+ }
+}
+
+function hideOsd() {
+
+ clearHideTimeout();
+
+ var elem = osdElement;
+ if (elem) {
+
+ if (enableAnimation) {
+ // trigger reflow
+ void elem.offsetWidth;
+
+ requestAnimationFrame(function () {
+ elem.classList.add('iconOsd-hidden');
+
+ dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, {
+ once: true
+ });
+ });
+ } else {
+ onHideComplete.call(elem);
+ }
+ }
+}
+
+function updatePlayerVolumeState(isMuted, volume) {
+
+ if (iconElement) {
+ iconElement.classList.remove('volume_off', 'volume_up');
+ iconElement.classList.add(isMuted ? 'volume_off' : 'volume_up');
+ }
+ if (progressElement) {
+ progressElement.style.width = (volume || 0) + '%';
+ }
+}
+
+function releaseCurrentPlayer() {
+
+ var player = currentPlayer;
+
+ if (player) {
+ events.off(player, 'volumechange', onVolumeChanged);
+ events.off(player, 'playbackstop', hideOsd);
+ currentPlayer = null;
+ }
+}
+
+function onVolumeChanged(e) {
+
+ var player = this;
+
+ ensureOsdElement();
+
+ updatePlayerVolumeState(player.isMuted(), player.getVolume());
+
+ showOsd();
+}
+
+function bindToPlayer(player) {
+
+ if (player === currentPlayer) {
+ return;
+ }
+
+ releaseCurrentPlayer();
+
+ currentPlayer = player;
+
+ if (!player) {
+ return;
+ }
+
+ hideOsd();
+ events.on(player, 'volumechange', onVolumeChanged);
+ events.on(player, 'playbackstop', hideOsd);
+}
+
+events.on(playbackManager, 'playerchange', function () {
+ bindToPlayer(playbackManager.getCurrentPlayer());
});
+
+bindToPlayer(playbackManager.getCurrentPlayer());
diff --git a/src/components/syncplay/groupSelectionMenu.js b/src/components/syncPlay/groupSelectionMenu.js
similarity index 100%
rename from src/components/syncplay/groupSelectionMenu.js
rename to src/components/syncPlay/groupSelectionMenu.js
diff --git a/src/components/syncplay/playbackPermissionManager.js b/src/components/syncPlay/playbackPermissionManager.js
similarity index 100%
rename from src/components/syncplay/playbackPermissionManager.js
rename to src/components/syncPlay/playbackPermissionManager.js
diff --git a/src/components/syncplay/syncPlayManager.js b/src/components/syncPlay/syncPlayManager.js
similarity index 99%
rename from src/components/syncplay/syncPlayManager.js
rename to src/components/syncPlay/syncPlayManager.js
index f04d1aeb8c..6116884d7c 100644
--- a/src/components/syncplay/syncPlayManager.js
+++ b/src/components/syncPlay/syncPlayManager.js
@@ -1,6 +1,6 @@
/**
* Module that manages the SyncPlay feature.
- * @module components/syncplay/syncPlayManager
+ * @module components/syncPlay/syncPlayManager
*/
import events from 'events';
diff --git a/src/components/syncplay/timeSyncManager.js b/src/components/syncPlay/timeSyncManager.js
similarity index 99%
rename from src/components/syncplay/timeSyncManager.js
rename to src/components/syncPlay/timeSyncManager.js
index ca92939576..6c151b3683 100644
--- a/src/components/syncplay/timeSyncManager.js
+++ b/src/components/syncPlay/timeSyncManager.js
@@ -1,6 +1,6 @@
/**
* Module that manages time syncing with server.
- * @module components/syncplay/timeSyncManager
+ * @module components/syncPlay/timeSyncManager
*/
import events from 'events';
diff --git a/src/components/viewsettings/viewsettings.js b/src/components/viewSettings/viewSettings.js
similarity index 98%
rename from src/components/viewsettings/viewsettings.js
rename to src/components/viewSettings/viewSettings.js
index 441c35157b..087ba3e373 100644
--- a/src/components/viewsettings/viewsettings.js
+++ b/src/components/viewSettings/viewSettings.js
@@ -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,
diff --git a/src/components/viewsettings/viewsettings.template.html b/src/components/viewSettings/viewSettings.template.html
similarity index 100%
rename from src/components/viewsettings/viewsettings.template.html
rename to src/components/viewSettings/viewSettings.template.html
diff --git a/src/config.json b/src/config.json
new file mode 120000
index 0000000000..f1bd2db71e
--- /dev/null
+++ b/src/config.json
@@ -0,0 +1 @@
+config.template.json
\ No newline at end of file
diff --git a/src/config.template.json b/src/config.template.json
index 1e79270943..4b22a699d6 100644
--- a/src/config.template.json
+++ b/src/config.template.json
@@ -1,3 +1,3 @@
{
- "multiserver": true
+ "multiserver": false
}
diff --git a/src/controllers/dashboard/dlna/profile.js b/src/controllers/dashboard/dlna/profile.js
index 81eb099f50..54ef75a6d1 100644
--- a/src/controllers/dashboard/dlna/profile.js
+++ b/src/controllers/dashboard/dlna/profile.js
@@ -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();
diff --git a/src/controllers/dashboard/dlna/settings.js b/src/controllers/dashboard/dlna/settings.js
index da254c0bd9..5bbfea5d4b 100644
--- a/src/controllers/dashboard/dlna/settings.js
+++ b/src/controllers/dashboard/dlna/settings.js
@@ -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 '
';
@@ -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);
diff --git a/src/controllers/dashboard/notifications/notification.js b/src/controllers/dashboard/notifications/notification.js
index 370fc6a369..af9301c13f 100644
--- a/src/controllers/dashboard/notifications/notification.js
+++ b/src/controllers/dashboard/notifications/notification.js
@@ -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;
diff --git a/src/controllers/dashboard/plugins/installed.js b/src/controllers/dashboard/plugins/installed.js
index 5ca739f711..87e9428cc6 100644
--- a/src/controllers/dashboard/plugins/installed.js
+++ b/src/controllers/dashboard/plugins/installed.js
@@ -50,7 +50,7 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'
html += '';
html += '
';
html += "
";
- html += configPage.DisplayName || plugin.Name;
+ html += configPage && configPage.DisplayName ? configPage.DisplayName : plugin.Name;
html += '
';
html += "
";
html += plugin.Version;
diff --git a/src/controllers/dashboard/users/useredit.js b/src/controllers/dashboard/users/useredit.js
index c71c81d9e0..af187412d0 100644
--- a/src/controllers/dashboard/users/useredit.js
+++ b/src/controllers/dashboard/users/useredit.js
@@ -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) {
diff --git a/src/controllers/dashboard/users/userlibraryaccess.js b/src/controllers/dashboard/users/userlibraryaccess.js
index 1fdb6cb599..5ea24e3da3 100644
--- a/src/controllers/dashboard/users/userlibraryaccess.js
+++ b/src/controllers/dashboard/users/userlibraryaccess.js
@@ -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 += '
';
$('.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) {
diff --git a/src/controllers/dashboard/users/usernew.js b/src/controllers/dashboard/users/usernew.js
index 1e4e2bbee2..ef4cd74f86 100644
--- a/src/controllers/dashboard/users/usernew.js
+++ b/src/controllers/dashboard/users/usernew.js
@@ -13,7 +13,7 @@ define(['jQuery', 'loading', 'globalize', 'emby-checkbox'], function ($, loading
html += '
';
$('.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) {
diff --git a/src/controllers/itemDetails.js b/src/controllers/itemDetails.js
index 0fad1ba967..cbb8a1b43e 100644
--- a/src/controllers/itemDetails.js
+++ b/src/controllers/itemDetails.js
@@ -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
});
});
}
diff --git a/src/controllers/livetv/livetvchannels.js b/src/controllers/livetv/livetvchannels.js
index 7f22d3dd13..62906d9d21 100644
--- a/src/controllers/livetv/livetvchannels.js
+++ b/src/controllers/livetv/livetvchannels.js
@@ -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',
diff --git a/src/controllers/movies/moviecollections.js b/src/controllers/movies/moviecollections.js
index e9ae599b92..54d30c0c37 100644
--- a/src/controllers/movies/moviecollections.js
+++ b/src/controllers/movies/moviecollections.js
@@ -171,7 +171,12 @@ define(['loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardB
}
if (!result.Items.length) {
- html = '
' + globalize.translate('MessageNoCollectionsAvailable') + '
';
+ html = '';
+
+ html += '
';
+ html += '
' + globalize.translate('MessageNothingHere') + '
';
+ html += '
' + globalize.translate('MessageNoCollectionsAvailable') + '
';
+ html += '
';
}
var itemsContainer = tabContent.querySelector('.itemsContainer');
diff --git a/src/controllers/movies/moviegenres.js b/src/controllers/movies/moviegenres.js
index e8e49ff9da..ab410c1bd4 100644
--- a/src/controllers/movies/moviegenres.js
+++ b/src/controllers/movies/moviegenres.js
@@ -165,6 +165,15 @@ define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader
html += '
';
}
+ if (!result.Items.length) {
+ html = '';
+
+ html += '
';
+ html += '
' + globalize.translate('MessageNothingHere') + '
';
+ html += '
' + globalize.translate('MessageNoGenresAvailable') + '
';
+ html += '
';
+ }
+
elem.innerHTML = html;
lazyLoader.lazyChildren(elem, fillItemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
diff --git a/src/controllers/movies/movies.js b/src/controllers/movies/movies.js
index 89bcc215e6..c22b52c47e 100644
--- a/src/controllers/movies/movies.js
+++ b/src/controllers/movies/movies.js
@@ -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',
diff --git a/src/controllers/movies/movietrailers.js b/src/controllers/movies/movietrailers.js
index 25d41d4fba..5daad8d7c3 100644
--- a/src/controllers/movies/movietrailers.js
+++ b/src/controllers/movies/movietrailers.js
@@ -158,7 +158,12 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', '
}
if (!result.Items.length) {
- html = '
' + globalize.translate('MessageNoTrailersFound') + '
';
+ html = '';
+
+ html += '
';
+ html += '
' + globalize.translate('MessageNothingHere') + '
';
+ html += '
' + globalize.translate('MessageNoTrailersFound') + '
';
+ html += '
';
}
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',
diff --git a/src/controllers/music/musicalbums.js b/src/controllers/music/musicalbums.js
index ecb51f9dc3..645daf4ad9 100644
--- a/src/controllers/music/musicalbums.js
+++ b/src/controllers/music/musicalbums.js
@@ -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',
diff --git a/src/controllers/music/musicartists.js b/src/controllers/music/musicartists.js
index bd9341be6d..7a889ff8b9 100644
--- a/src/controllers/music/musicartists.js
+++ b/src/controllers/music/musicartists.js
@@ -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,
diff --git a/src/controllers/music/songs.js b/src/controllers/music/songs.js
index 8e50cd720c..aa63ec51fe 100644
--- a/src/controllers/music/songs.js
+++ b/src/controllers/music/songs.js
@@ -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',
diff --git a/src/controllers/shows/episodes.js b/src/controllers/shows/episodes.js
index ca9a807cbf..eeede20661 100644
--- a/src/controllers/shows/episodes.js
+++ b/src/controllers/shows/episodes.js
@@ -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',
diff --git a/src/controllers/shows/tvgenres.js b/src/controllers/shows/tvgenres.js
index de38763e99..7d09307fc2 100644
--- a/src/controllers/shows/tvgenres.js
+++ b/src/controllers/shows/tvgenres.js
@@ -161,6 +161,15 @@ define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader
html += '
';
}
+ if (!result.Items.length) {
+ html = '';
+
+ html += '';
@@ -72,6 +73,7 @@ export default class TableOfContent {
tocHtml += `
${chapter.label}`;
tocHtml += '';
});
+
tocHtml += '';
elem.innerHTML = tocHtml;
@@ -84,7 +86,6 @@ export default class TableOfContent {
this._elem = elem;
this.bindEvents();
-
dialogHelper.open(elem);
}
}
diff --git a/src/plugins/photoPlayer/plugin.js b/src/plugins/photoPlayer/plugin.js
index d8d4ee70ef..d8e55fa67e 100644
--- a/src/plugins/photoPlayer/plugin.js
+++ b/src/plugins/photoPlayer/plugin.js
@@ -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';
}
}
diff --git a/src/scripts/browserDeviceProfile.js b/src/scripts/browserDeviceProfile.js
index a550b69198..a63f39ba9f 100644
--- a/src/scripts/browserDeviceProfile.js
+++ b/src/scripts/browserDeviceProfile.js
@@ -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 = [];
diff --git a/src/scripts/settings/userSettings.js b/src/scripts/settings/userSettings.js
index 06c5fa40a6..1b5283fa43 100644
--- a/src/scripts/settings/userSettings.js
+++ b/src/scripts/settings/userSettings.js
@@ -1,23 +1,30 @@
-/* eslint-disable indent */
-
import appSettings from 'appSettings';
import events from 'events';
- function onSaveTimeout() {
- var self = this;
- self.saveTimeout = null;
- self.currentApiClient.updateDisplayPreferences('usersettings', self.displayPrefs, self.currentUserId, 'emby');
+function onSaveTimeout() {
+ var self = this;
+ self.saveTimeout = null;
+ self.currentApiClient.updateDisplayPreferences('usersettings', self.displayPrefs, self.currentUserId, 'emby');
+}
+
+function saveServerPreferences(instance) {
+ if (instance.saveTimeout) {
+ clearTimeout(instance.saveTimeout);
}
- function saveServerPreferences(instance) {
- if (instance.saveTimeout) {
- clearTimeout(instance.saveTimeout);
- }
+ instance.saveTimeout = setTimeout(onSaveTimeout.bind(instance), 50);
+}
- instance.saveTimeout = setTimeout(onSaveTimeout.bind(instance), 50);
+export class UserSettings {
+ constructor() {
}
- export function setUserInfo(userId, apiClient) {
+ /**
+ * 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);
diff --git a/src/scripts/settings/webSettings.js b/src/scripts/settings/webSettings.js
index d999724aff..64989b4fc2 100644
--- a/src/scripts/settings/webSettings.js
+++ b/src/scripts/settings/webSettings.js
@@ -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;
});
diff --git a/src/scripts/site.js b/src/scripts/site.js
index e60efc757d..65ecfd1b09 100644
--- a/src/scripts/site.js
+++ b/src/scripts/site.js
@@ -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);
diff --git a/src/strings/cs.json b/src/strings/cs.json
index 8b631caf5a..626c63bec6 100644
--- a/src/strings/cs.json
+++ b/src/strings/cs.json
@@ -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ě"
}
diff --git a/src/strings/da.json b/src/strings/da.json
index 45c0ddb336..5cc1f4ab56 100644
--- a/src/strings/da.json
+++ b/src/strings/da.json
@@ -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:",
diff --git a/src/strings/de.json b/src/strings/de.json
index 4e9934e9cc..daad4b05bf 100644
--- a/src/strings/de.json
+++ b/src/strings/de.json
@@ -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"
}
diff --git a/src/strings/en-gb.json b/src/strings/en-gb.json
index 6d49f52c77..3ce9a10476 100644
--- a/src/strings/en-gb.json
+++ b/src/strings/en-gb.json
@@ -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):",
diff --git a/src/strings/en-us.json b/src/strings/en-us.json
index f26ba16c85..b8e081a588 100644
--- a/src/strings/en-us.json
+++ b/src/strings/en-us.json
@@ -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"
}
diff --git a/src/strings/es-mx.json b/src/strings/es-mx.json
index 3a711a558e..b41385feb5 100644
--- a/src/strings/es-mx.json
+++ b/src/strings/es-mx.json
@@ -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",
diff --git a/src/strings/es.json b/src/strings/es.json
index ab46562f94..eedfa3d739 100644
--- a/src/strings/es.json
+++ b/src/strings/es.json
@@ -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"
}
diff --git a/src/strings/fa.json b/src/strings/fa.json
index 88c3794568..f8e2cf8207 100644
--- a/src/strings/fa.json
+++ b/src/strings/fa.json
@@ -798,5 +798,6 @@
"LabelSelectFolderGroups": "به طور خودکار محتواهای پوشههای زیر را به فیلم ، موسیقی و تلویزیون گروه بندی شود:",
"LabelSeasonNumber": "شماره فصل:",
"ConfigureDateAdded": "تنظیم کنید که چگونه تاریخ اضافه شده در داشبورد سرور Jellyfin تحت تنظیمات کتابخانه تعیین میشود",
- "CinemaModeConfigurationHelp": "حالت سینما تجربه تئاتر گونه را مستقیم به اتاق نشیمن شما میآورد با قابلیت پخش تریلرها و پیش نمایشها قبل از سایر ویژگیهای اصلی."
+ "CinemaModeConfigurationHelp": "حالت سینما تجربه تئاتر گونه را مستقیم به اتاق نشیمن شما میآورد با قابلیت پخش تریلرها و پیش نمایشها قبل از سایر ویژگیهای اصلی.",
+ "LaunchWebAppOnStartup": "نمای وب هنگامی که سرور آغاز به کار میکند باز بشود"
}
diff --git a/src/strings/fr.json b/src/strings/fr.json
index 01c8ae4394..81d6470ee9 100644
--- a/src/strings/fr.json
+++ b/src/strings/fr.json
@@ -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 :",
diff --git a/src/strings/hu.json b/src/strings/hu.json
index 6d6307285d..9382927acd 100644
--- a/src/strings/hu.json
+++ b/src/strings/hu.json
@@ -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.",
diff --git a/src/strings/it.json b/src/strings/it.json
index d678cf6e0f..474ff5480e 100644
--- a/src/strings/it.json
+++ b/src/strings/it.json
@@ -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}",
diff --git a/src/strings/kk.json b/src/strings/kk.json
index f32fe9d9ec..2c2c7c3782 100644
--- a/src/strings/kk.json
+++ b/src/strings/kk.json
@@ -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:",
diff --git a/src/strings/ko.json b/src/strings/ko.json
index 33c44334ae..4c3cd60da1 100644
--- a/src/strings/ko.json
+++ b/src/strings/ko.json
@@ -1343,8 +1343,6 @@
"LabelSkipIfAudioTrackPresentHelp": "오디오 언어와 상관없이 모든 비디오가 자막을 갖추도록 하려면 이 항목을 체크하지 마십시오.",
"LabelSelectFolderGroupsHelp": "체크되지 않은 폴더는 폴더 고유의 보기 방식으로 표시됩니다.",
"LabelSelectFolderGroups": "자동으로 이하의 폴더의 항목을 영화, 음악, TV 와 같은 보기 방식으로 그룹화:",
- "EnableFastImageFadeInHelp": "로드된 이미지에 더 빠른 페이드 인 효과를 적용",
- "EnableFastImageFadeIn": "빠른 이미지 페이드 인 효과",
"LabelScheduledTaskLastRan": "최근 실행: {0}, 소모시간: {1}.",
"LabelRemoteClientBitrateLimitHelp": "(선택) 모든 외부 네트워크로 접속된 장치들에 적용되는 각 스트리밍별 비트레이트 제한입니다. 이는 서버의 인터넷이 처리할 수 있는 한계보다 더 높은 비트레이트를 요청하는 것을 방지할 수 있습니다. 비디오를 더 낮은 비트레이트로 트랜스코딩하기 위해 서버에 높은 CPU 부하를 줄 수 있습니다.",
"LabelReasonForTranscoding": "트랜스코딩 원인:",
diff --git a/src/strings/lv.json b/src/strings/lv.json
index 6c10863333..cfdb0c0c06 100644
--- a/src/strings/lv.json
+++ b/src/strings/lv.json
@@ -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:"
}
diff --git a/src/strings/nb.json b/src/strings/nb.json
index 0a616ae2e1..3821c5544d 100644
--- a/src/strings/nb.json
+++ b/src/strings/nb.json
@@ -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:",
diff --git a/src/strings/nl.json b/src/strings/nl.json
index 23a563a8f0..132fd77803 100644
--- a/src/strings/nl.json
+++ b/src/strings/nl.json
@@ -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:",
diff --git a/src/strings/pl.json b/src/strings/pl.json
index 1cea825bf8..f2aa4f9fa5 100644
--- a/src/strings/pl.json
+++ b/src/strings/pl.json
@@ -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",
diff --git a/src/strings/pt-br.json b/src/strings/pt-br.json
index e1e8acfc31..b7948cb6a7 100644
--- a/src/strings/pt-br.json
+++ b/src/strings/pt-br.json
@@ -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",
diff --git a/src/strings/pt.json b/src/strings/pt.json
index 370a1343ea..7e263dbeb8 100644
--- a/src/strings/pt.json
+++ b/src/strings/pt.json
@@ -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:",
diff --git a/src/strings/ro.json b/src/strings/ro.json
index 4e1227d85b..3584741110 100644
--- a/src/strings/ro.json
+++ b/src/strings/ro.json
@@ -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:",
diff --git a/src/strings/ru.json b/src/strings/ru.json
index 4a7e2aa8ab..dcc3a0f5d6 100644
--- a/src/strings/ru.json
+++ b/src/strings/ru.json
@@ -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": "Показать меньше"
}
diff --git a/src/strings/sk.json b/src/strings/sk.json
index e99883d24e..eb236ff9ec 100644
--- a/src/strings/sk.json
+++ b/src/strings/sk.json
@@ -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:",
diff --git a/src/strings/sv.json b/src/strings/sv.json
index 282fec7b7e..a2b1c68e0c 100644
--- a/src/strings/sv.json
+++ b/src/strings/sv.json
@@ -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:",
diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json
index f62b872c93..237dafb165 100644
--- a/src/strings/zh-cn.json
+++ b/src/strings/zh-cn.json
@@ -1464,8 +1464,6 @@
"HeaderNavigation": "导航",
"CopyStreamURLError": "复制URL地址时发生错误。",
"MessageConfirmAppExit": "你要退出吗?",
- "EnableFastImageFadeIn": "快速图片淡入淡出",
- "EnableFastImageFadeInHelp": "为已加载的图片启用更快的图片淡入动画",
"OptionForceRemoteSourceTranscoding": "强制远程转码(像电视直播一样)",
"NoCreatedLibraries": "看上去您还未创建任何资料库。{0} 您想现在创建一个吗? {1}",
"AskAdminToCreateLibrary": "请联系管理员以创建一个新的资料库。",
diff --git a/src/strings/zh-tw.json b/src/strings/zh-tw.json
index ae086d08cc..7023e564be 100644
--- a/src/strings/zh-tw.json
+++ b/src/strings/zh-tw.json
@@ -1610,8 +1610,6 @@
"LaunchWebAppOnStartupHelp": "伺服器啓動時在默認游覽器中打開網頁端。使用重啓伺服器功能時此項不生效。",
"LabelVideoResolution": "視頻解析度:",
"LabelStreamType": "串流類型:",
- "EnableFastImageFadeInHelp": "對已載入的圖片啟用更快的淡入動畫",
- "EnableFastImageFadeIn": "圖片快速淡入效果",
"LabelPlayerDimensions": "播放器尺寸:",
"LabelDroppedFrames": "丟棄的幀:",
"LabelCorruptedFrames": "損壞的幀:",
diff --git a/src/themes/blueradiance/theme.css b/src/themes/blueradiance/theme.css
index 3e86782f37..74a60c91c0 100644
--- a/src/themes/blueradiance/theme.css
+++ b/src/themes/blueradiance/theme.css
@@ -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,
diff --git a/src/themes/dark/theme.css b/src/themes/dark/theme.css
index f9163d82f5..a32e606386 100644
--- a/src/themes/dark/theme.css
+++ b/src/themes/dark/theme.css
@@ -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,
diff --git a/src/themes/purplehaze/theme.css b/src/themes/purplehaze/theme.css
index 82b774a736..de69a5542a 100644
--- a/src/themes/purplehaze/theme.css
+++ b/src/themes/purplehaze/theme.css
@@ -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,
diff --git a/yarn.lock b/yarn.lock
index fa6bc7d767..88dc31d555 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -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"