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

Fix indentation issues

This commit is contained in:
Bill Thornton 2023-04-19 01:56:05 -04:00
parent 52c8cffc82
commit f2726653ae
120 changed files with 30271 additions and 30631 deletions

View file

@ -6,85 +6,82 @@ import '../../elements/emby-button/emby-button';
import confirm from '../../components/confirm/confirm';
import { pageIdOn } from '../../utils/dashboard';
/* eslint-disable indent */
function revoke(page, key) {
confirm(globalize.translate('MessageConfirmRevokeApiKey'), globalize.translate('HeaderConfirmRevokeApiKey')).then(function () {
loading.show();
ApiClient.ajax({
type: 'DELETE',
url: ApiClient.getUrl('Auth/Keys/' + key)
}).then(function () {
loadData(page);
});
});
}
function revoke(page, key) {
confirm(globalize.translate('MessageConfirmRevokeApiKey'), globalize.translate('HeaderConfirmRevokeApiKey')).then(function () {
loading.show();
function renderKeys(page, keys) {
const rows = keys.map(function (item) {
let html = '';
html += '<tr class="detailTableBodyRow detailTableBodyRow-shaded">';
html += '<td class="detailTableBodyCell">';
html += '<button type="button" is="emby-button" data-token="' + item.AccessToken + '" class="raised raised-mini btnRevoke" data-mini="true" title="' + globalize.translate('ButtonRevoke') + '" style="margin:0;">' + globalize.translate('ButtonRevoke') + '</button>';
html += '</td>';
html += '<td class="detailTableBodyCell" style="vertical-align:middle;">';
html += item.AccessToken;
html += '</td>';
html += '<td class="detailTableBodyCell" style="vertical-align:middle;">';
html += item.AppName || '';
html += '</td>';
html += '<td class="detailTableBodyCell" style="vertical-align:middle;">';
const date = datetime.parseISO8601Date(item.DateCreated, true);
html += datetime.toLocaleDateString(date) + ' ' + datetime.getDisplayTime(date);
html += '</td>';
html += '</tr>';
return html;
}).join('');
page.querySelector('.resultBody').innerHTML = rows;
loading.hide();
}
function loadData(page) {
loading.show();
ApiClient.getJSON(ApiClient.getUrl('Auth/Keys')).then(function (result) {
renderKeys(page, result.Items);
});
}
function showNewKeyPrompt(page) {
import('../../components/prompt/prompt').then(({ default: prompt }) => {
prompt({
title: globalize.translate('HeaderNewApiKey'),
label: globalize.translate('LabelAppName'),
description: globalize.translate('LabelAppNameExample')
}).then(function (value) {
ApiClient.ajax({
type: 'DELETE',
url: ApiClient.getUrl('Auth/Keys/' + key)
type: 'POST',
url: ApiClient.getUrl('Auth/Keys', {
App: value
})
}).then(function () {
loadData(page);
});
});
}
function renderKeys(page, keys) {
const rows = keys.map(function (item) {
let html = '';
html += '<tr class="detailTableBodyRow detailTableBodyRow-shaded">';
html += '<td class="detailTableBodyCell">';
html += '<button type="button" is="emby-button" data-token="' + item.AccessToken + '" class="raised raised-mini btnRevoke" data-mini="true" title="' + globalize.translate('ButtonRevoke') + '" style="margin:0;">' + globalize.translate('ButtonRevoke') + '</button>';
html += '</td>';
html += '<td class="detailTableBodyCell" style="vertical-align:middle;">';
html += item.AccessToken;
html += '</td>';
html += '<td class="detailTableBodyCell" style="vertical-align:middle;">';
html += item.AppName || '';
html += '</td>';
html += '<td class="detailTableBodyCell" style="vertical-align:middle;">';
const date = datetime.parseISO8601Date(item.DateCreated, true);
html += datetime.toLocaleDateString(date) + ' ' + datetime.getDisplayTime(date);
html += '</td>';
html += '</tr>';
return html;
}).join('');
page.querySelector('.resultBody').innerHTML = rows;
loading.hide();
}
function loadData(page) {
loading.show();
ApiClient.getJSON(ApiClient.getUrl('Auth/Keys')).then(function (result) {
renderKeys(page, result.Items);
});
}
function showNewKeyPrompt(page) {
import('../../components/prompt/prompt').then(({ default: prompt }) => {
prompt({
title: globalize.translate('HeaderNewApiKey'),
label: globalize.translate('LabelAppName'),
description: globalize.translate('LabelAppNameExample')
}).then(function (value) {
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('Auth/Keys', {
App: value
})
}).then(function () {
loadData(page);
});
});
});
}
pageIdOn('pageinit', 'apiKeysPage', function () {
const page = this;
page.querySelector('.btnNewKey').addEventListener('click', function () {
showNewKeyPrompt(page);
});
page.querySelector('.tblApiKeys').addEventListener('click', function (e) {
const btnRevoke = dom.parentWithClass(e.target, 'btnRevoke');
if (btnRevoke) {
revoke(page, btnRevoke.getAttribute('data-token'));
}
});
});
pageIdOn('pagebeforeshow', 'apiKeysPage', function () {
loadData(this);
});
}
pageIdOn('pageinit', 'apiKeysPage', function () {
const page = this;
page.querySelector('.btnNewKey').addEventListener('click', function () {
showNewKeyPrompt(page);
});
page.querySelector('.tblApiKeys').addEventListener('click', function (e) {
const btnRevoke = dom.parentWithClass(e.target, 'btnRevoke');
if (btnRevoke) {
revoke(page, btnRevoke.getAttribute('data-token'));
}
});
});
pageIdOn('pagebeforeshow', 'apiKeysPage', function () {
loadData(this);
});
/* eslint-enable indent */

File diff suppressed because it is too large Load diff

View file

@ -5,53 +5,50 @@ import '../../../elements/emby-button/emby-button';
import Dashboard from '../../../utils/dashboard';
import { getParameterByName } from '../../../utils/url.ts';
/* eslint-disable indent */
function load(page, device, deviceOptions) {
page.querySelector('#txtCustomName', page).value = deviceOptions.CustomName || '';
page.querySelector('.reportedName', page).innerText = device.Name || '';
}
function load(page, device, deviceOptions) {
page.querySelector('#txtCustomName', page).value = deviceOptions.CustomName || '';
page.querySelector('.reportedName', page).innerText = device.Name || '';
}
function loadData() {
const page = this;
loading.show();
const id = getParameterByName('id');
const promise1 = ApiClient.getJSON(ApiClient.getUrl('Devices/Info', {
Id: id
}));
const promise2 = ApiClient.getJSON(ApiClient.getUrl('Devices/Options', {
Id: id
}));
Promise.all([promise1, promise2]).then(function (responses) {
load(page, responses[0], responses[1]);
loading.hide();
});
}
function loadData() {
const page = this;
loading.show();
const id = getParameterByName('id');
const promise1 = ApiClient.getJSON(ApiClient.getUrl('Devices/Info', {
function save(page) {
const id = getParameterByName('id');
ApiClient.ajax({
url: ApiClient.getUrl('Devices/Options', {
Id: id
}));
const promise2 = ApiClient.getJSON(ApiClient.getUrl('Devices/Options', {
Id: id
}));
Promise.all([promise1, promise2]).then(function (responses) {
load(page, responses[0], responses[1]);
loading.hide();
});
}
}),
type: 'POST',
data: JSON.stringify({
CustomName: page.querySelector('#txtCustomName').value
}),
contentType: 'application/json'
}).then(Dashboard.processServerConfigurationUpdateResult);
}
function save(page) {
const id = getParameterByName('id');
ApiClient.ajax({
url: ApiClient.getUrl('Devices/Options', {
Id: id
}),
type: 'POST',
data: JSON.stringify({
CustomName: page.querySelector('#txtCustomName').value
}),
contentType: 'application/json'
}).then(Dashboard.processServerConfigurationUpdateResult);
}
function onSubmit(e) {
const form = this;
save(dom.parentWithClass(form, 'page'));
e.preventDefault();
return false;
}
function onSubmit(e) {
const form = this;
save(dom.parentWithClass(form, 'page'));
e.preventDefault();
return false;
}
export default function (view) {
view.querySelector('form').addEventListener('submit', onSubmit);
view.addEventListener('viewshow', loadData);
}
export default function (view) {
view.querySelector('form').addEventListener('submit', onSubmit);
view.addEventListener('viewshow', loadData);
}
/* eslint-enable indent */

View file

@ -12,159 +12,157 @@ import '../../../components/cardbuilder/card.scss';
import Dashboard from '../../../utils/dashboard';
import confirm from '../../../components/confirm/confirm';
/* eslint-disable indent */
// Local cache of loaded
let deviceIds = [];
// Local cache of loaded
let deviceIds = [];
function canDelete(deviceId) {
return deviceId !== ApiClient.deviceId();
}
function canDelete(deviceId) {
return deviceId !== ApiClient.deviceId();
}
function deleteAllDevices(page) {
const msg = globalize.translate('DeleteDevicesConfirmation');
function deleteAllDevices(page) {
const msg = globalize.translate('DeleteDevicesConfirmation');
confirm({
text: msg,
title: globalize.translate('HeaderDeleteDevices'),
confirmText: globalize.translate('Delete'),
primary: 'delete'
}).then(async () => {
loading.show();
await Promise.all(
deviceIds.filter(canDelete).map((id) => ApiClient.deleteDevice(id))
);
loadData(page);
});
}
confirm({
text: msg,
title: globalize.translate('HeaderDeleteDevices'),
confirmText: globalize.translate('Delete'),
primary: 'delete'
}).then(async () => {
loading.show();
await Promise.all(
deviceIds.filter(canDelete).map((id) => ApiClient.deleteDevice(id))
);
loadData(page);
function deleteDevice(page, id) {
const msg = globalize.translate('DeleteDeviceConfirmation');
confirm({
text: msg,
title: globalize.translate('HeaderDeleteDevice'),
confirmText: globalize.translate('Delete'),
primary: 'delete'
}).then(async () => {
loading.show();
await ApiClient.deleteDevice(id);
loadData(page);
});
}
function showDeviceMenu(view, btn, deviceId) {
const menuItems = [{
name: globalize.translate('Edit'),
id: 'open',
icon: 'mode_edit'
}];
if (canDelete(deviceId)) {
menuItems.push({
name: globalize.translate('Delete'),
id: 'delete',
icon: 'delete'
});
}
function deleteDevice(page, id) {
const msg = globalize.translate('DeleteDeviceConfirmation');
import('../../../components/actionSheet/actionSheet').then(({ default: actionsheet }) => {
actionsheet.show({
items: menuItems,
positionTo: btn,
callback: function (id) {
switch (id) {
case 'open':
Dashboard.navigate('device.html?id=' + deviceId);
break;
confirm({
text: msg,
title: globalize.translate('HeaderDeleteDevice'),
confirmText: globalize.translate('Delete'),
primary: 'delete'
}).then(async () => {
loading.show();
await ApiClient.deleteDevice(id);
loadData(page);
case 'delete':
deleteDevice(view, deviceId);
}
}
});
}
});
}
function showDeviceMenu(view, btn, deviceId) {
const menuItems = [{
name: globalize.translate('Edit'),
id: 'open',
icon: 'mode_edit'
}];
function load(page, devices) {
const localeWithSuffix = getLocaleWithSuffix();
if (canDelete(deviceId)) {
menuItems.push({
name: globalize.translate('Delete'),
id: 'delete',
icon: 'delete'
});
let html = '';
html += devices.map(function (device) {
let deviceHtml = '';
deviceHtml += "<div data-id='" + device.Id + "' class='card backdropCard'>";
deviceHtml += '<div class="cardBox visualCardBox">';
deviceHtml += '<div class="cardScalable">';
deviceHtml += '<div class="cardPadder cardPadder-backdrop"></div>';
deviceHtml += `<a is="emby-linkbutton" href="#/device.html?id=${device.Id}" class="cardContent cardImageContainer ${cardBuilder.getDefaultBackgroundClass()}">`;
const iconUrl = imageHelper.getDeviceIcon(device);
if (iconUrl) {
deviceHtml += '<div class="cardImage" style="background-image:url(\'' + iconUrl + "');background-size: auto 64%;background-position:center center;\">";
deviceHtml += '</div>';
} else {
deviceHtml += '<span class="cardImageIcon material-icons tablet_android" aria-hidden="true"></span>';
}
import('../../../components/actionSheet/actionSheet').then(({ default: actionsheet }) => {
actionsheet.show({
items: menuItems,
positionTo: btn,
callback: function (id) {
switch (id) {
case 'open':
Dashboard.navigate('device.html?id=' + deviceId);
break;
deviceHtml += '</a>';
deviceHtml += '</div>';
deviceHtml += '<div class="cardFooter">';
case 'delete':
deleteDevice(view, deviceId);
}
}
});
});
}
function load(page, devices) {
const localeWithSuffix = getLocaleWithSuffix();
let html = '';
html += devices.map(function (device) {
let deviceHtml = '';
deviceHtml += "<div data-id='" + device.Id + "' class='card backdropCard'>";
deviceHtml += '<div class="cardBox visualCardBox">';
deviceHtml += '<div class="cardScalable">';
deviceHtml += '<div class="cardPadder cardPadder-backdrop"></div>';
deviceHtml += `<a is="emby-linkbutton" href="#/device.html?id=${device.Id}" class="cardContent cardImageContainer ${cardBuilder.getDefaultBackgroundClass()}">`;
const iconUrl = imageHelper.getDeviceIcon(device);
if (iconUrl) {
deviceHtml += '<div class="cardImage" style="background-image:url(\'' + iconUrl + "');background-size: auto 64%;background-position:center center;\">";
deviceHtml += '</div>';
} else {
deviceHtml += '<span class="cardImageIcon material-icons tablet_android" aria-hidden="true"></span>';
}
deviceHtml += '</a>';
if (canDelete(device.Id)) {
if (globalize.getIsRTL())
deviceHtml += '<div style="text-align:left; float:left;padding-top:5px;">';
else
deviceHtml += '<div style="text-align:right; float:right;padding-top:5px;">';
deviceHtml += '<button type="button" is="paper-icon-button-light" data-id="' + device.Id + '" title="' + globalize.translate('Menu') + '" class="btnDeviceMenu"><span class="material-icons more_vert" aria-hidden="true"></span></button>';
deviceHtml += '</div>';
deviceHtml += '<div class="cardFooter">';
}
if (canDelete(device.Id)) {
if (globalize.getIsRTL())
deviceHtml += '<div style="text-align:left; float:left;padding-top:5px;">';
else
deviceHtml += '<div style="text-align:right; float:right;padding-top:5px;">';
deviceHtml += '<button type="button" is="paper-icon-button-light" data-id="' + device.Id + '" title="' + globalize.translate('Menu') + '" class="btnDeviceMenu"><span class="material-icons more_vert" aria-hidden="true"></span></button>';
deviceHtml += '</div>';
}
deviceHtml += "<div class='cardText'>";
deviceHtml += escapeHtml(device.Name);
deviceHtml += '</div>';
deviceHtml += "<div class='cardText cardText-secondary'>";
deviceHtml += escapeHtml(device.AppName + ' ' + device.AppVersion);
deviceHtml += '</div>';
deviceHtml += "<div class='cardText cardText-secondary'>";
deviceHtml += "<div class='cardText'>";
deviceHtml += escapeHtml(device.Name);
deviceHtml += '</div>';
deviceHtml += "<div class='cardText cardText-secondary'>";
deviceHtml += escapeHtml(device.AppName + ' ' + device.AppVersion);
deviceHtml += '</div>';
deviceHtml += "<div class='cardText cardText-secondary'>";
if (device.LastUserName) {
deviceHtml += escapeHtml(device.LastUserName);
deviceHtml += ', ' + formatDistanceToNow(Date.parse(device.DateLastActivity), localeWithSuffix);
}
if (device.LastUserName) {
deviceHtml += escapeHtml(device.LastUserName);
deviceHtml += ', ' + formatDistanceToNow(Date.parse(device.DateLastActivity), localeWithSuffix);
}
deviceHtml += '&nbsp;';
deviceHtml += '</div>';
deviceHtml += '</div>';
deviceHtml += '</div>';
deviceHtml += '</div>';
return deviceHtml;
}).join('');
page.querySelector('.devicesList').innerHTML = html;
}
deviceHtml += '&nbsp;';
deviceHtml += '</div>';
deviceHtml += '</div>';
deviceHtml += '</div>';
deviceHtml += '</div>';
return deviceHtml;
}).join('');
page.querySelector('.devicesList').innerHTML = html;
}
function loadData(page) {
loading.show();
ApiClient.getJSON(ApiClient.getUrl('Devices')).then(function (result) {
load(page, result.Items);
deviceIds = result.Items.map((device) => device.Id);
loading.hide();
});
}
function loadData(page) {
loading.show();
ApiClient.getJSON(ApiClient.getUrl('Devices')).then(function (result) {
load(page, result.Items);
deviceIds = result.Items.map((device) => device.Id);
loading.hide();
});
}
export default function (view) {
view.querySelector('.devicesList').addEventListener('click', function (e) {
const btnDeviceMenu = dom.parentWithClass(e.target, 'btnDeviceMenu');
export default function (view) {
view.querySelector('.devicesList').addEventListener('click', function (e) {
const btnDeviceMenu = dom.parentWithClass(e.target, 'btnDeviceMenu');
if (btnDeviceMenu) {
showDeviceMenu(view, btnDeviceMenu, btnDeviceMenu.getAttribute('data-id'));
}
});
view.addEventListener('viewshow', function () {
loadData(this);
});
if (btnDeviceMenu) {
showDeviceMenu(view, btnDeviceMenu, btnDeviceMenu.getAttribute('data-id'));
}
});
view.addEventListener('viewshow', function () {
loadData(this);
});
view.querySelector('#deviceDeleteAll').addEventListener('click', function() {
deleteAllDevices(view);
});
}
view.querySelector('#deviceDeleteAll').addEventListener('click', function() {
deleteAllDevices(view);
});
}
/* eslint-enable indent */

File diff suppressed because it is too large Load diff

View file

@ -7,90 +7,87 @@ import '../../../components/listview/listview.scss';
import '../../../elements/emby-button/emby-button';
import confirm from '../../../components/confirm/confirm';
/* eslint-disable indent */
function loadProfiles(page) {
loading.show();
ApiClient.getJSON(ApiClient.getUrl('Dlna/ProfileInfos')).then(function (result) {
renderUserProfiles(page, result);
renderSystemProfiles(page, result);
loading.hide();
});
}
function renderUserProfiles(page, profiles) {
renderProfiles(page, page.querySelector('.customProfiles'), profiles.filter(function (p) {
return p.Type == 'User';
}));
}
function renderSystemProfiles(page, profiles) {
renderProfiles(page, page.querySelector('.systemProfiles'), profiles.filter(function (p) {
return p.Type == 'System';
}));
}
function renderProfiles(page, element, profiles) {
let html = '';
if (profiles.length) {
html += '<div class="paperList">';
}
for (let i = 0, length = profiles.length; i < length; i++) {
const profile = profiles[i];
html += '<div class="listItem listItem-border">';
html += '<span class="listItemIcon material-icons live_tv" aria-hidden="true"></span>';
html += '<div class="listItemBody two-line">';
html += "<a is='emby-linkbutton' style='padding:0;margin:0;' data-ripple='false' class='clearLink' href='#/dlnaprofile.html?id=" + profile.Id + "'>";
html += '<div>' + escapeHtml(profile.Name) + '</div>';
html += '</a>';
html += '</div>';
if (profile.Type == 'User') {
html += '<button type="button" is="paper-icon-button-light" class="btnDeleteProfile" data-profileid="' + profile.Id + '" title="' + globalize.translate('Delete') + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
}
html += '</div>';
}
if (profiles.length) {
html += '</div>';
}
element.innerHTML = html;
$('.btnDeleteProfile', element).on('click', function () {
const id = this.getAttribute('data-profileid');
deleteProfile(page, id);
});
}
function deleteProfile(page, id) {
confirm(globalize.translate('MessageConfirmProfileDeletion'), globalize.translate('HeaderConfirmProfileDeletion')).then(function () {
loading.show();
ApiClient.ajax({
type: 'DELETE',
url: ApiClient.getUrl('Dlna/Profiles/' + id)
}).then(function () {
loading.hide();
loadProfiles(page);
});
});
}
function getTabs() {
return [{
href: '#/dlnasettings.html',
name: globalize.translate('Settings')
}, {
href: '#/dlnaprofiles.html',
name: globalize.translate('TabProfiles')
}];
}
$(document).on('pageshow', '#dlnaProfilesPage', function () {
libraryMenu.setTabs('dlna', 1, getTabs);
loadProfiles(this);
function loadProfiles(page) {
loading.show();
ApiClient.getJSON(ApiClient.getUrl('Dlna/ProfileInfos')).then(function (result) {
renderUserProfiles(page, result);
renderSystemProfiles(page, result);
loading.hide();
});
}
function renderUserProfiles(page, profiles) {
renderProfiles(page, page.querySelector('.customProfiles'), profiles.filter(function (p) {
return p.Type == 'User';
}));
}
function renderSystemProfiles(page, profiles) {
renderProfiles(page, page.querySelector('.systemProfiles'), profiles.filter(function (p) {
return p.Type == 'System';
}));
}
function renderProfiles(page, element, profiles) {
let html = '';
if (profiles.length) {
html += '<div class="paperList">';
}
for (let i = 0, length = profiles.length; i < length; i++) {
const profile = profiles[i];
html += '<div class="listItem listItem-border">';
html += '<span class="listItemIcon material-icons live_tv" aria-hidden="true"></span>';
html += '<div class="listItemBody two-line">';
html += "<a is='emby-linkbutton' style='padding:0;margin:0;' data-ripple='false' class='clearLink' href='#/dlnaprofile.html?id=" + profile.Id + "'>";
html += '<div>' + escapeHtml(profile.Name) + '</div>';
html += '</a>';
html += '</div>';
if (profile.Type == 'User') {
html += '<button type="button" is="paper-icon-button-light" class="btnDeleteProfile" data-profileid="' + profile.Id + '" title="' + globalize.translate('Delete') + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
}
html += '</div>';
}
if (profiles.length) {
html += '</div>';
}
element.innerHTML = html;
$('.btnDeleteProfile', element).on('click', function () {
const id = this.getAttribute('data-profileid');
deleteProfile(page, id);
});
}
function deleteProfile(page, id) {
confirm(globalize.translate('MessageConfirmProfileDeletion'), globalize.translate('HeaderConfirmProfileDeletion')).then(function () {
loading.show();
ApiClient.ajax({
type: 'DELETE',
url: ApiClient.getUrl('Dlna/Profiles/' + id)
}).then(function () {
loading.hide();
loadProfiles(page);
});
});
}
function getTabs() {
return [{
href: '#/dlnasettings.html',
name: globalize.translate('Settings')
}, {
href: '#/dlnaprofiles.html',
name: globalize.translate('TabProfiles')
}];
}
$(document).on('pageshow', '#dlnaProfilesPage', function () {
libraryMenu.setTabs('dlna', 1, getTabs);
loadProfiles(this);
});
/* eslint-enable indent */

View file

@ -5,59 +5,56 @@ import libraryMenu from '../../../scripts/libraryMenu';
import globalize from '../../../scripts/globalize';
import Dashboard from '../../../utils/dashboard';
/* eslint-disable indent */
function loadPage(page, config, users) {
page.querySelector('#chkEnablePlayTo').checked = config.EnablePlayTo;
page.querySelector('#chkEnableDlnaDebugLogging').checked = config.EnableDebugLog;
$('#txtClientDiscoveryInterval', page).val(config.ClientDiscoveryIntervalSeconds);
$('#chkEnableServer', page).prop('checked', config.EnableServer);
$('#chkBlastAliveMessages', page).prop('checked', config.BlastAliveMessages);
$('#txtBlastInterval', page).val(config.BlastAliveMessageIntervalSeconds);
const usersHtml = users.map(function (u) {
return '<option value="' + u.Id + '">' + escapeHtml(u.Name) + '</option>';
}).join('');
$('#selectUser', page).html(usersHtml).val(config.DefaultUserId || '');
loading.hide();
}
function loadPage(page, config, users) {
page.querySelector('#chkEnablePlayTo').checked = config.EnablePlayTo;
page.querySelector('#chkEnableDlnaDebugLogging').checked = config.EnableDebugLog;
$('#txtClientDiscoveryInterval', page).val(config.ClientDiscoveryIntervalSeconds);
$('#chkEnableServer', page).prop('checked', config.EnableServer);
$('#chkBlastAliveMessages', page).prop('checked', config.BlastAliveMessages);
$('#txtBlastInterval', page).val(config.BlastAliveMessageIntervalSeconds);
const usersHtml = users.map(function (u) {
return '<option value="' + u.Id + '">' + escapeHtml(u.Name) + '</option>';
}).join('');
$('#selectUser', page).html(usersHtml).val(config.DefaultUserId || '');
loading.hide();
}
function onSubmit() {
loading.show();
const form = this;
ApiClient.getNamedConfiguration('dlna').then(function (config) {
config.EnablePlayTo = form.querySelector('#chkEnablePlayTo').checked;
config.EnableDebugLog = form.querySelector('#chkEnableDlnaDebugLogging').checked;
config.ClientDiscoveryIntervalSeconds = $('#txtClientDiscoveryInterval', form).val();
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);
});
return false;
}
function getTabs() {
return [{
href: '#/dlnasettings.html',
name: globalize.translate('Settings')
}, {
href: '#/dlnaprofiles.html',
name: globalize.translate('TabProfiles')
}];
}
$(document).on('pageinit', '#dlnaSettingsPage', function () {
$('.dlnaSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#dlnaSettingsPage', function () {
libraryMenu.setTabs('dlna', 0, getTabs);
loading.show();
const page = this;
const promise1 = ApiClient.getNamedConfiguration('dlna');
const promise2 = ApiClient.getUsers();
Promise.all([promise1, promise2]).then(function (responses) {
loadPage(page, responses[0], responses[1]);
});
function onSubmit() {
loading.show();
const form = this;
ApiClient.getNamedConfiguration('dlna').then(function (config) {
config.EnablePlayTo = form.querySelector('#chkEnablePlayTo').checked;
config.EnableDebugLog = form.querySelector('#chkEnableDlnaDebugLogging').checked;
config.ClientDiscoveryIntervalSeconds = $('#txtClientDiscoveryInterval', form).val();
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);
});
return false;
}
function getTabs() {
return [{
href: '#/dlnasettings.html',
name: globalize.translate('Settings')
}, {
href: '#/dlnaprofiles.html',
name: globalize.translate('TabProfiles')
}];
}
$(document).on('pageinit', '#dlnaSettingsPage', function () {
$('.dlnaSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#dlnaSettingsPage', function () {
libraryMenu.setTabs('dlna', 0, getTabs);
loading.show();
const page = this;
const promise1 = ApiClient.getNamedConfiguration('dlna');
const promise2 = ApiClient.getUsers();
Promise.all([promise1, promise2]).then(function (responses) {
loadPage(page, responses[0], responses[1]);
});
});
/* eslint-enable indent */

View file

@ -6,297 +6,294 @@ import libraryMenu from '../../scripts/libraryMenu';
import Dashboard from '../../utils/dashboard';
import alert from '../../components/alert';
/* eslint-disable indent */
function loadPage(page, config, systemInfo) {
Array.prototype.forEach.call(page.querySelectorAll('.chkDecodeCodec'), function (c) {
c.checked = (config.HardwareDecodingCodecs || []).indexOf(c.getAttribute('data-codec')) !== -1;
});
page.querySelector('#chkDecodingColorDepth10Hevc').checked = config.EnableDecodingColorDepth10Hevc;
page.querySelector('#chkDecodingColorDepth10Vp9').checked = config.EnableDecodingColorDepth10Vp9;
page.querySelector('#chkEnhancedNvdecDecoder').checked = config.EnableEnhancedNvdecDecoder;
page.querySelector('#chkSystemNativeHwDecoder').checked = config.PreferSystemNativeHwDecoder;
page.querySelector('#chkIntelLpH264HwEncoder').checked = config.EnableIntelLowPowerH264HwEncoder;
page.querySelector('#chkIntelLpHevcHwEncoder').checked = config.EnableIntelLowPowerHevcHwEncoder;
page.querySelector('#chkHardwareEncoding').checked = config.EnableHardwareEncoding;
page.querySelector('#chkAllowHevcEncoding').checked = config.AllowHevcEncoding;
$('#selectVideoDecoder', page).val(config.HardwareAccelerationType);
$('#selectThreadCount', page).val(config.EncodingThreadCount);
page.querySelector('#chkEnableAudioVbr').checked = config.EnableAudioVbr;
$('#txtDownMixAudioBoost', page).val(config.DownMixAudioBoost);
$('#selectStereoDownmixAlgorithm').val(config.DownMixStereoAlgorithm || 'None');
page.querySelector('#txtMaxMuxingQueueSize').value = config.MaxMuxingQueueSize || '';
page.querySelector('.txtEncoderPath').value = config.EncoderAppPathDisplay || '';
$('#txtTranscodingTempPath', page).val(systemInfo.TranscodingTempPath || '');
page.querySelector('#txtFallbackFontPath').value = config.FallbackFontPath || '';
page.querySelector('#chkEnableFallbackFont').checked = config.EnableFallbackFont;
$('#txtVaapiDevice', page).val(config.VaapiDevice || '');
page.querySelector('#chkTonemapping').checked = config.EnableTonemapping;
page.querySelector('#chkVppTonemapping').checked = config.EnableVppTonemapping;
page.querySelector('#selectTonemappingAlgorithm').value = config.TonemappingAlgorithm;
page.querySelector('#selectTonemappingRange').value = config.TonemappingRange;
page.querySelector('#txtTonemappingDesat').value = config.TonemappingDesat;
page.querySelector('#txtTonemappingThreshold').value = config.TonemappingThreshold;
page.querySelector('#txtTonemappingPeak').value = config.TonemappingPeak;
page.querySelector('#txtTonemappingParam').value = config.TonemappingParam || '';
page.querySelector('#txtVppTonemappingBrightness').value = config.VppTonemappingBrightness;
page.querySelector('#txtVppTonemappingContrast').value = config.VppTonemappingContrast;
page.querySelector('#selectEncoderPreset').value = config.EncoderPreset || '';
page.querySelector('#txtH264Crf').value = config.H264Crf || '';
page.querySelector('#txtH265Crf').value = config.H265Crf || '';
page.querySelector('#selectDeinterlaceMethod').value = config.DeinterlaceMethod || '';
page.querySelector('#chkDoubleRateDeinterlacing').checked = config.DeinterlaceDoubleRate;
page.querySelector('#chkEnableSubtitleExtraction').checked = config.EnableSubtitleExtraction || false;
page.querySelector('#chkEnableThrottling').checked = config.EnableThrottling || false;
page.querySelector('#selectVideoDecoder').dispatchEvent(new CustomEvent('change', {
bubbles: true
}));
loading.hide();
}
function loadPage(page, config, systemInfo) {
Array.prototype.forEach.call(page.querySelectorAll('.chkDecodeCodec'), function (c) {
c.checked = (config.HardwareDecodingCodecs || []).indexOf(c.getAttribute('data-codec')) !== -1;
});
page.querySelector('#chkDecodingColorDepth10Hevc').checked = config.EnableDecodingColorDepth10Hevc;
page.querySelector('#chkDecodingColorDepth10Vp9').checked = config.EnableDecodingColorDepth10Vp9;
page.querySelector('#chkEnhancedNvdecDecoder').checked = config.EnableEnhancedNvdecDecoder;
page.querySelector('#chkSystemNativeHwDecoder').checked = config.PreferSystemNativeHwDecoder;
page.querySelector('#chkIntelLpH264HwEncoder').checked = config.EnableIntelLowPowerH264HwEncoder;
page.querySelector('#chkIntelLpHevcHwEncoder').checked = config.EnableIntelLowPowerHevcHwEncoder;
page.querySelector('#chkHardwareEncoding').checked = config.EnableHardwareEncoding;
page.querySelector('#chkAllowHevcEncoding').checked = config.AllowHevcEncoding;
$('#selectVideoDecoder', page).val(config.HardwareAccelerationType);
$('#selectThreadCount', page).val(config.EncodingThreadCount);
page.querySelector('#chkEnableAudioVbr').checked = config.EnableAudioVbr;
$('#txtDownMixAudioBoost', page).val(config.DownMixAudioBoost);
$('#selectStereoDownmixAlgorithm').val(config.DownMixStereoAlgorithm || 'None');
page.querySelector('#txtMaxMuxingQueueSize').value = config.MaxMuxingQueueSize || '';
page.querySelector('.txtEncoderPath').value = config.EncoderAppPathDisplay || '';
$('#txtTranscodingTempPath', page).val(systemInfo.TranscodingTempPath || '');
page.querySelector('#txtFallbackFontPath').value = config.FallbackFontPath || '';
page.querySelector('#chkEnableFallbackFont').checked = config.EnableFallbackFont;
$('#txtVaapiDevice', page).val(config.VaapiDevice || '');
page.querySelector('#chkTonemapping').checked = config.EnableTonemapping;
page.querySelector('#chkVppTonemapping').checked = config.EnableVppTonemapping;
page.querySelector('#selectTonemappingAlgorithm').value = config.TonemappingAlgorithm;
page.querySelector('#selectTonemappingRange').value = config.TonemappingRange;
page.querySelector('#txtTonemappingDesat').value = config.TonemappingDesat;
page.querySelector('#txtTonemappingThreshold').value = config.TonemappingThreshold;
page.querySelector('#txtTonemappingPeak').value = config.TonemappingPeak;
page.querySelector('#txtTonemappingParam').value = config.TonemappingParam || '';
page.querySelector('#txtVppTonemappingBrightness').value = config.VppTonemappingBrightness;
page.querySelector('#txtVppTonemappingContrast').value = config.VppTonemappingContrast;
page.querySelector('#selectEncoderPreset').value = config.EncoderPreset || '';
page.querySelector('#txtH264Crf').value = config.H264Crf || '';
page.querySelector('#txtH265Crf').value = config.H265Crf || '';
page.querySelector('#selectDeinterlaceMethod').value = config.DeinterlaceMethod || '';
page.querySelector('#chkDoubleRateDeinterlacing').checked = config.DeinterlaceDoubleRate;
page.querySelector('#chkEnableSubtitleExtraction').checked = config.EnableSubtitleExtraction || false;
page.querySelector('#chkEnableThrottling').checked = config.EnableThrottling || false;
page.querySelector('#selectVideoDecoder').dispatchEvent(new CustomEvent('change', {
bubbles: true
}));
loading.hide();
}
function onSaveEncodingPathFailure() {
loading.hide();
alert(globalize.translate('FFmpegSavePathNotFound'));
}
function onSaveEncodingPathFailure() {
loading.hide();
alert(globalize.translate('FFmpegSavePathNotFound'));
}
function updateEncoder(form) {
return ApiClient.getSystemInfo().then(function () {
return ApiClient.ajax({
url: ApiClient.getUrl('System/MediaEncoder/Path'),
type: 'POST',
data: JSON.stringify({
Path: form.querySelector('.txtEncoderPath').value,
PathType: 'Custom'
}),
contentType: 'application/json'
}).then(Dashboard.processServerConfigurationUpdateResult, onSaveEncodingPathFailure);
});
}
function updateEncoder(form) {
return ApiClient.getSystemInfo().then(function () {
return ApiClient.ajax({
url: ApiClient.getUrl('System/MediaEncoder/Path'),
type: 'POST',
data: JSON.stringify({
Path: form.querySelector('.txtEncoderPath').value,
PathType: 'Custom'
}),
contentType: 'application/json'
}).then(Dashboard.processServerConfigurationUpdateResult, onSaveEncodingPathFailure);
});
}
function onSubmit() {
const form = this;
function onSubmit() {
const form = this;
const onDecoderConfirmed = function () {
loading.show();
ApiClient.getNamedConfiguration('encoding').then(function (config) {
config.EnableAudioVbr = form.querySelector('#chkEnableAudioVbr').checked;
config.DownMixAudioBoost = $('#txtDownMixAudioBoost', form).val();
config.DownMixStereoAlgorithm = $('#selectStereoDownmixAlgorithm', form).val() || 'None';
config.MaxMuxingQueueSize = form.querySelector('#txtMaxMuxingQueueSize').value;
config.TranscodingTempPath = $('#txtTranscodingTempPath', form).val();
config.FallbackFontPath = form.querySelector('#txtFallbackFontPath').value;
config.EnableFallbackFont = form.querySelector('#txtFallbackFontPath').value ? form.querySelector('#chkEnableFallbackFont').checked : false;
config.EncodingThreadCount = $('#selectThreadCount', form).val();
config.HardwareAccelerationType = $('#selectVideoDecoder', form).val();
config.VaapiDevice = $('#txtVaapiDevice', form).val();
config.EnableTonemapping = form.querySelector('#chkTonemapping').checked;
config.EnableVppTonemapping = form.querySelector('#chkVppTonemapping').checked;
config.TonemappingAlgorithm = form.querySelector('#selectTonemappingAlgorithm').value;
config.TonemappingRange = form.querySelector('#selectTonemappingRange').value;
config.TonemappingDesat = form.querySelector('#txtTonemappingDesat').value;
config.TonemappingThreshold = form.querySelector('#txtTonemappingThreshold').value;
config.TonemappingPeak = form.querySelector('#txtTonemappingPeak').value;
config.TonemappingParam = form.querySelector('#txtTonemappingParam').value || '0';
config.VppTonemappingBrightness = form.querySelector('#txtVppTonemappingBrightness').value;
config.VppTonemappingContrast = form.querySelector('#txtVppTonemappingContrast').value;
config.EncoderPreset = form.querySelector('#selectEncoderPreset').value;
config.H264Crf = parseInt(form.querySelector('#txtH264Crf').value || '0', 10);
config.H265Crf = parseInt(form.querySelector('#txtH265Crf').value || '0', 10);
config.DeinterlaceMethod = form.querySelector('#selectDeinterlaceMethod').value;
config.DeinterlaceDoubleRate = form.querySelector('#chkDoubleRateDeinterlacing').checked;
config.EnableSubtitleExtraction = form.querySelector('#chkEnableSubtitleExtraction').checked;
config.EnableThrottling = form.querySelector('#chkEnableThrottling').checked;
config.HardwareDecodingCodecs = Array.prototype.map.call(Array.prototype.filter.call(form.querySelectorAll('.chkDecodeCodec'), function (c) {
return c.checked;
}), function (c) {
return c.getAttribute('data-codec');
});
config.EnableDecodingColorDepth10Hevc = form.querySelector('#chkDecodingColorDepth10Hevc').checked;
config.EnableDecodingColorDepth10Vp9 = form.querySelector('#chkDecodingColorDepth10Vp9').checked;
config.EnableEnhancedNvdecDecoder = form.querySelector('#chkEnhancedNvdecDecoder').checked;
config.PreferSystemNativeHwDecoder = form.querySelector('#chkSystemNativeHwDecoder').checked;
config.EnableIntelLowPowerH264HwEncoder = form.querySelector('#chkIntelLpH264HwEncoder').checked;
config.EnableIntelLowPowerHevcHwEncoder = form.querySelector('#chkIntelLpHevcHwEncoder').checked;
config.EnableHardwareEncoding = form.querySelector('#chkHardwareEncoding').checked;
config.AllowHevcEncoding = form.querySelector('#chkAllowHevcEncoding').checked;
ApiClient.updateNamedConfiguration('encoding', config).then(function () {
updateEncoder(form);
}, function () {
alert(globalize.translate('ErrorDefault'));
Dashboard.processServerConfigurationUpdateResult();
});
});
};
if ($('#selectVideoDecoder', form).val()) {
alert({
title: globalize.translate('TitleHardwareAcceleration'),
text: globalize.translate('HardwareAccelerationWarning')
}).then(onDecoderConfirmed);
} else {
onDecoderConfirmed();
}
return false;
}
function setDecodingCodecsVisible(context, value) {
value = value || '';
let any;
Array.prototype.forEach.call(context.querySelectorAll('.chkDecodeCodec'), function (c) {
if (c.getAttribute('data-types').split(',').indexOf(value) === -1) {
dom.parentWithTag(c, 'LABEL').classList.add('hide');
} else {
dom.parentWithTag(c, 'LABEL').classList.remove('hide');
any = true;
}
});
if (any) {
context.querySelector('.decodingCodecsList').classList.remove('hide');
} else {
context.querySelector('.decodingCodecsList').classList.add('hide');
}
}
function getTabs() {
return [{
href: '#/encodingsettings.html',
name: globalize.translate('Transcoding')
}, {
href: '#/playbackconfiguration.html',
name: globalize.translate('ButtonResume')
}, {
href: '#/streamingsettings.html',
name: globalize.translate('TabStreaming')
}];
}
let systemInfo;
function getSystemInfo() {
return systemInfo ? Promise.resolve(systemInfo) : ApiClient.getPublicSystemInfo().then(
info => {
systemInfo = info;
return info;
}
);
}
$(document).on('pageinit', '#encodingSettingsPage', function () {
const page = this;
getSystemInfo();
page.querySelector('#selectVideoDecoder').addEventListener('change', function () {
if (this.value == 'vaapi') {
page.querySelector('.fldVaapiDevice').classList.remove('hide');
page.querySelector('#txtVaapiDevice').setAttribute('required', 'required');
} else {
page.querySelector('.fldVaapiDevice').classList.add('hide');
page.querySelector('#txtVaapiDevice').removeAttribute('required');
}
if (this.value == 'amf' || this.value == 'nvenc' || this.value == 'qsv' || this.value == 'vaapi' || this.value == 'videotoolbox') {
page.querySelector('.fld10bitHevcVp9HwDecoding').classList.remove('hide');
} else {
page.querySelector('.fld10bitHevcVp9HwDecoding').classList.add('hide');
}
if (this.value == 'amf' || this.value == 'nvenc' || this.value == 'qsv' || this.value == 'vaapi') {
page.querySelector('.tonemappingOptions').classList.remove('hide');
} else {
page.querySelector('.tonemappingOptions').classList.add('hide');
}
if (this.value == 'qsv' || this.value == 'vaapi') {
page.querySelector('.fldIntelLp').classList.remove('hide');
} else {
page.querySelector('.fldIntelLp').classList.add('hide');
}
if (systemInfo.OperatingSystem.toLowerCase() === 'linux' && (this.value == 'qsv' || this.value == 'vaapi')) {
page.querySelector('.vppTonemappingOptions').classList.remove('hide');
} else {
page.querySelector('.vppTonemappingOptions').classList.add('hide');
}
if (this.value == 'qsv') {
page.querySelector('.fldSysNativeHwDecoder').classList.remove('hide');
} else {
page.querySelector('.fldSysNativeHwDecoder').classList.add('hide');
}
if (this.value == 'nvenc') {
page.querySelector('.fldEnhancedNvdec').classList.remove('hide');
} else {
page.querySelector('.fldEnhancedNvdec').classList.add('hide');
}
if (this.value) {
page.querySelector('.hardwareAccelerationOptions').classList.remove('hide');
} else {
page.querySelector('.hardwareAccelerationOptions').classList.add('hide');
}
setDecodingCodecsVisible(page, this.value);
});
$('#btnSelectEncoderPath', page).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
includeFiles: true,
callback: function (path) {
if (path) {
$('.txtEncoderPath', page).val(path);
}
picker.close();
}
});
});
});
$('#btnSelectTranscodingTempPath', page).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
callback: function (path) {
if (path) {
$('#txtTranscodingTempPath', page).val(path);
}
picker.close();
},
validateWriteable: true,
header: globalize.translate('HeaderSelectTranscodingPath'),
instruction: globalize.translate('HeaderSelectTranscodingPathHelp')
});
});
});
$('#btnSelectFallbackFontPath', page).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
includeDirectories: true,
callback: function (path) {
if (path) {
page.querySelector('#txtFallbackFontPath').value = path;
}
picker.close();
},
header: globalize.translate('HeaderSelectFallbackFontPath'),
instruction: globalize.translate('HeaderSelectFallbackFontPathHelp')
});
});
});
$('.encodingSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#encodingSettingsPage', function () {
const onDecoderConfirmed = function () {
loading.show();
libraryMenu.setTabs('playback', 0, getTabs);
const page = this;
ApiClient.getNamedConfiguration('encoding').then(function (config) {
ApiClient.getSystemInfo().then(function (fetchedSystemInfo) {
loadPage(page, config, fetchedSystemInfo);
config.EnableAudioVbr = form.querySelector('#chkEnableAudioVbr').checked;
config.DownMixAudioBoost = $('#txtDownMixAudioBoost', form).val();
config.DownMixStereoAlgorithm = $('#selectStereoDownmixAlgorithm', form).val() || 'None';
config.MaxMuxingQueueSize = form.querySelector('#txtMaxMuxingQueueSize').value;
config.TranscodingTempPath = $('#txtTranscodingTempPath', form).val();
config.FallbackFontPath = form.querySelector('#txtFallbackFontPath').value;
config.EnableFallbackFont = form.querySelector('#txtFallbackFontPath').value ? form.querySelector('#chkEnableFallbackFont').checked : false;
config.EncodingThreadCount = $('#selectThreadCount', form).val();
config.HardwareAccelerationType = $('#selectVideoDecoder', form).val();
config.VaapiDevice = $('#txtVaapiDevice', form).val();
config.EnableTonemapping = form.querySelector('#chkTonemapping').checked;
config.EnableVppTonemapping = form.querySelector('#chkVppTonemapping').checked;
config.TonemappingAlgorithm = form.querySelector('#selectTonemappingAlgorithm').value;
config.TonemappingRange = form.querySelector('#selectTonemappingRange').value;
config.TonemappingDesat = form.querySelector('#txtTonemappingDesat').value;
config.TonemappingThreshold = form.querySelector('#txtTonemappingThreshold').value;
config.TonemappingPeak = form.querySelector('#txtTonemappingPeak').value;
config.TonemappingParam = form.querySelector('#txtTonemappingParam').value || '0';
config.VppTonemappingBrightness = form.querySelector('#txtVppTonemappingBrightness').value;
config.VppTonemappingContrast = form.querySelector('#txtVppTonemappingContrast').value;
config.EncoderPreset = form.querySelector('#selectEncoderPreset').value;
config.H264Crf = parseInt(form.querySelector('#txtH264Crf').value || '0', 10);
config.H265Crf = parseInt(form.querySelector('#txtH265Crf').value || '0', 10);
config.DeinterlaceMethod = form.querySelector('#selectDeinterlaceMethod').value;
config.DeinterlaceDoubleRate = form.querySelector('#chkDoubleRateDeinterlacing').checked;
config.EnableSubtitleExtraction = form.querySelector('#chkEnableSubtitleExtraction').checked;
config.EnableThrottling = form.querySelector('#chkEnableThrottling').checked;
config.HardwareDecodingCodecs = Array.prototype.map.call(Array.prototype.filter.call(form.querySelectorAll('.chkDecodeCodec'), function (c) {
return c.checked;
}), function (c) {
return c.getAttribute('data-codec');
});
config.EnableDecodingColorDepth10Hevc = form.querySelector('#chkDecodingColorDepth10Hevc').checked;
config.EnableDecodingColorDepth10Vp9 = form.querySelector('#chkDecodingColorDepth10Vp9').checked;
config.EnableEnhancedNvdecDecoder = form.querySelector('#chkEnhancedNvdecDecoder').checked;
config.PreferSystemNativeHwDecoder = form.querySelector('#chkSystemNativeHwDecoder').checked;
config.EnableIntelLowPowerH264HwEncoder = form.querySelector('#chkIntelLpH264HwEncoder').checked;
config.EnableIntelLowPowerHevcHwEncoder = form.querySelector('#chkIntelLpHevcHwEncoder').checked;
config.EnableHardwareEncoding = form.querySelector('#chkHardwareEncoding').checked;
config.AllowHevcEncoding = form.querySelector('#chkAllowHevcEncoding').checked;
ApiClient.updateNamedConfiguration('encoding', config).then(function () {
updateEncoder(form);
}, function () {
alert(globalize.translate('ErrorDefault'));
Dashboard.processServerConfigurationUpdateResult();
});
});
};
if ($('#selectVideoDecoder', form).val()) {
alert({
title: globalize.translate('TitleHardwareAcceleration'),
text: globalize.translate('HardwareAccelerationWarning')
}).then(onDecoderConfirmed);
} else {
onDecoderConfirmed();
}
return false;
}
function setDecodingCodecsVisible(context, value) {
value = value || '';
let any;
Array.prototype.forEach.call(context.querySelectorAll('.chkDecodeCodec'), function (c) {
if (c.getAttribute('data-types').split(',').indexOf(value) === -1) {
dom.parentWithTag(c, 'LABEL').classList.add('hide');
} else {
dom.parentWithTag(c, 'LABEL').classList.remove('hide');
any = true;
}
});
if (any) {
context.querySelector('.decodingCodecsList').classList.remove('hide');
} else {
context.querySelector('.decodingCodecsList').classList.add('hide');
}
}
function getTabs() {
return [{
href: '#/encodingsettings.html',
name: globalize.translate('Transcoding')
}, {
href: '#/playbackconfiguration.html',
name: globalize.translate('ButtonResume')
}, {
href: '#/streamingsettings.html',
name: globalize.translate('TabStreaming')
}];
}
let systemInfo;
function getSystemInfo() {
return systemInfo ? Promise.resolve(systemInfo) : ApiClient.getPublicSystemInfo().then(
info => {
systemInfo = info;
return info;
}
);
}
$(document).on('pageinit', '#encodingSettingsPage', function () {
const page = this;
getSystemInfo();
page.querySelector('#selectVideoDecoder').addEventListener('change', function () {
if (this.value == 'vaapi') {
page.querySelector('.fldVaapiDevice').classList.remove('hide');
page.querySelector('#txtVaapiDevice').setAttribute('required', 'required');
} else {
page.querySelector('.fldVaapiDevice').classList.add('hide');
page.querySelector('#txtVaapiDevice').removeAttribute('required');
}
if (this.value == 'amf' || this.value == 'nvenc' || this.value == 'qsv' || this.value == 'vaapi' || this.value == 'videotoolbox') {
page.querySelector('.fld10bitHevcVp9HwDecoding').classList.remove('hide');
} else {
page.querySelector('.fld10bitHevcVp9HwDecoding').classList.add('hide');
}
if (this.value == 'amf' || this.value == 'nvenc' || this.value == 'qsv' || this.value == 'vaapi') {
page.querySelector('.tonemappingOptions').classList.remove('hide');
} else {
page.querySelector('.tonemappingOptions').classList.add('hide');
}
if (this.value == 'qsv' || this.value == 'vaapi') {
page.querySelector('.fldIntelLp').classList.remove('hide');
} else {
page.querySelector('.fldIntelLp').classList.add('hide');
}
if (systemInfo.OperatingSystem.toLowerCase() === 'linux' && (this.value == 'qsv' || this.value == 'vaapi')) {
page.querySelector('.vppTonemappingOptions').classList.remove('hide');
} else {
page.querySelector('.vppTonemappingOptions').classList.add('hide');
}
if (this.value == 'qsv') {
page.querySelector('.fldSysNativeHwDecoder').classList.remove('hide');
} else {
page.querySelector('.fldSysNativeHwDecoder').classList.add('hide');
}
if (this.value == 'nvenc') {
page.querySelector('.fldEnhancedNvdec').classList.remove('hide');
} else {
page.querySelector('.fldEnhancedNvdec').classList.add('hide');
}
if (this.value) {
page.querySelector('.hardwareAccelerationOptions').classList.remove('hide');
} else {
page.querySelector('.hardwareAccelerationOptions').classList.add('hide');
}
setDecodingCodecsVisible(page, this.value);
});
$('#btnSelectEncoderPath', page).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
includeFiles: true,
callback: function (path) {
if (path) {
$('.txtEncoderPath', page).val(path);
}
picker.close();
}
});
});
});
$('#btnSelectTranscodingTempPath', page).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
callback: function (path) {
if (path) {
$('#txtTranscodingTempPath', page).val(path);
}
picker.close();
},
validateWriteable: true,
header: globalize.translate('HeaderSelectTranscodingPath'),
instruction: globalize.translate('HeaderSelectTranscodingPathHelp')
});
});
});
$('#btnSelectFallbackFontPath', page).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
includeDirectories: true,
callback: function (path) {
if (path) {
page.querySelector('#txtFallbackFontPath').value = path;
}
picker.close();
},
header: globalize.translate('HeaderSelectFallbackFontPath'),
instruction: globalize.translate('HeaderSelectFallbackFontPathHelp')
});
});
});
$('.encodingSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#encodingSettingsPage', function () {
loading.show();
libraryMenu.setTabs('playback', 0, getTabs);
const page = this;
ApiClient.getNamedConfiguration('encoding').then(function (config) {
ApiClient.getSystemInfo().then(function (fetchedSystemInfo) {
loadPage(page, config, fetchedSystemInfo);
});
});
});
/* eslint-enable indent */

View file

@ -10,110 +10,107 @@ import '../../elements/emby-button/emby-button';
import Dashboard from '../../utils/dashboard';
import alert from '../../components/alert';
/* eslint-disable indent */
function loadPage(page, config, languageOptions, systemInfo) {
page.querySelector('#txtServerName').value = systemInfo.ServerName;
page.querySelector('#txtCachePath').value = systemInfo.CachePath || '';
page.querySelector('#chkQuickConnectAvailable').checked = config.QuickConnectAvailable === true;
$('#txtMetadataPath', page).val(systemInfo.InternalMetadataPath || '');
$('#txtMetadataNetworkPath', page).val(systemInfo.MetadataNetworkPath || '');
$('#selectLocalizationLanguage', page).html(languageOptions.map(function (language) {
return '<option value="' + language.Value + '">' + language.Name + '</option>';
})).val(config.UICulture);
page.querySelector('#txtParallelImageEncodingLimit').value = config.ParallelImageEncodingLimit || '';
function loadPage(page, config, languageOptions, systemInfo) {
page.querySelector('#txtServerName').value = systemInfo.ServerName;
page.querySelector('#txtCachePath').value = systemInfo.CachePath || '';
page.querySelector('#chkQuickConnectAvailable').checked = config.QuickConnectAvailable === true;
$('#txtMetadataPath', page).val(systemInfo.InternalMetadataPath || '');
$('#txtMetadataNetworkPath', page).val(systemInfo.MetadataNetworkPath || '');
$('#selectLocalizationLanguage', page).html(languageOptions.map(function (language) {
return '<option value="' + language.Value + '">' + language.Name + '</option>';
})).val(config.UICulture);
page.querySelector('#txtParallelImageEncodingLimit').value = config.ParallelImageEncodingLimit || '';
loading.hide();
}
loading.hide();
}
function onSubmit() {
loading.show();
const form = this;
$(form).parents('.page');
ApiClient.getServerConfiguration().then(function (config) {
config.ServerName = $('#txtServerName', form).val();
config.UICulture = $('#selectLocalizationLanguage', form).val();
config.CachePath = form.querySelector('#txtCachePath').value;
config.MetadataPath = $('#txtMetadataPath', form).val();
config.MetadataNetworkPath = $('#txtMetadataNetworkPath', form).val();
config.QuickConnectAvailable = form.querySelector('#chkQuickConnectAvailable').checked;
config.ParallelImageEncodingLimit = parseInt(form.querySelector('#txtParallelImageEncodingLimit').value || '0', 10);
function onSubmit() {
loading.show();
const form = this;
$(form).parents('.page');
ApiClient.getServerConfiguration().then(function (config) {
config.ServerName = $('#txtServerName', form).val();
config.UICulture = $('#selectLocalizationLanguage', form).val();
config.CachePath = form.querySelector('#txtCachePath').value;
config.MetadataPath = $('#txtMetadataPath', form).val();
config.MetadataNetworkPath = $('#txtMetadataNetworkPath', form).val();
config.QuickConnectAvailable = form.querySelector('#chkQuickConnectAvailable').checked;
config.ParallelImageEncodingLimit = parseInt(form.querySelector('#txtParallelImageEncodingLimit').value || '0', 10);
ApiClient.updateServerConfiguration(config).then(function() {
ApiClient.getNamedConfiguration(brandingConfigKey).then(function(brandingConfig) {
brandingConfig.LoginDisclaimer = form.querySelector('#txtLoginDisclaimer').value;
brandingConfig.CustomCss = form.querySelector('#txtCustomCss').value;
brandingConfig.SplashscreenEnabled = form.querySelector('#chkSplashScreenAvailable').checked;
ApiClient.updateServerConfiguration(config).then(function() {
ApiClient.getNamedConfiguration(brandingConfigKey).then(function(brandingConfig) {
brandingConfig.LoginDisclaimer = form.querySelector('#txtLoginDisclaimer').value;
brandingConfig.CustomCss = form.querySelector('#txtCustomCss').value;
brandingConfig.SplashscreenEnabled = form.querySelector('#chkSplashScreenAvailable').checked;
ApiClient.updateNamedConfiguration(brandingConfigKey, brandingConfig).then(function () {
Dashboard.processServerConfigurationUpdateResult();
});
});
}, function () {
alert(globalize.translate('ErrorDefault'));
Dashboard.processServerConfigurationUpdateResult();
});
});
return false;
}
const brandingConfigKey = 'branding';
export default function (view) {
$('#btnSelectCachePath', view).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
callback: function (path) {
if (path) {
view.querySelector('#txtCachePath').value = path;
}
picker.close();
},
validateWriteable: true,
header: globalize.translate('HeaderSelectServerCachePath'),
instruction: globalize.translate('HeaderSelectServerCachePathHelp')
ApiClient.updateNamedConfiguration(brandingConfigKey, brandingConfig).then(function () {
Dashboard.processServerConfigurationUpdateResult();
});
});
}, function () {
alert(globalize.translate('ErrorDefault'));
Dashboard.processServerConfigurationUpdateResult();
});
$('#btnSelectMetadataPath', view).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
path: $('#txtMetadataPath', view).val(),
networkSharePath: $('#txtMetadataNetworkPath', view).val(),
callback: function (path, networkPath) {
if (path) {
$('#txtMetadataPath', view).val(path);
}
});
return false;
}
if (networkPath) {
$('#txtMetadataNetworkPath', view).val(networkPath);
}
const brandingConfigKey = 'branding';
export default function (view) {
$('#btnSelectCachePath', view).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
callback: function (path) {
if (path) {
view.querySelector('#txtCachePath').value = path;
}
picker.close();
},
validateWriteable: true,
header: globalize.translate('HeaderSelectMetadataPath'),
instruction: globalize.translate('HeaderSelectMetadataPathHelp'),
enableNetworkSharePath: true
});
picker.close();
},
validateWriteable: true,
header: globalize.translate('HeaderSelectServerCachePath'),
instruction: globalize.translate('HeaderSelectServerCachePathHelp')
});
});
$('.dashboardGeneralForm', view).off('submit', onSubmit).on('submit', onSubmit);
view.addEventListener('viewshow', function () {
const promiseConfig = ApiClient.getServerConfiguration();
const promiseLanguageOptions = ApiClient.getJSON(ApiClient.getUrl('Localization/Options'));
const promiseSystemInfo = ApiClient.getSystemInfo();
Promise.all([promiseConfig, promiseLanguageOptions, promiseSystemInfo]).then(function (responses) {
loadPage(view, responses[0], responses[1], responses[2]);
});
ApiClient.getNamedConfiguration(brandingConfigKey).then(function (config) {
view.querySelector('#txtLoginDisclaimer').value = config.LoginDisclaimer || '';
view.querySelector('#txtCustomCss').value = config.CustomCss || '';
view.querySelector('#chkSplashScreenAvailable').checked = config.SplashscreenEnabled === true;
});
$('#btnSelectMetadataPath', view).on('click.selectDirectory', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
path: $('#txtMetadataPath', view).val(),
networkSharePath: $('#txtMetadataNetworkPath', view).val(),
callback: function (path, networkPath) {
if (path) {
$('#txtMetadataPath', view).val(path);
}
if (networkPath) {
$('#txtMetadataNetworkPath', view).val(networkPath);
}
picker.close();
},
validateWriteable: true,
header: globalize.translate('HeaderSelectMetadataPath'),
instruction: globalize.translate('HeaderSelectMetadataPathHelp'),
enableNetworkSharePath: true
});
});
}
});
$('.dashboardGeneralForm', view).off('submit', onSubmit).on('submit', onSubmit);
view.addEventListener('viewshow', function () {
const promiseConfig = ApiClient.getServerConfiguration();
const promiseLanguageOptions = ApiClient.getJSON(ApiClient.getUrl('Localization/Options'));
const promiseSystemInfo = ApiClient.getSystemInfo();
Promise.all([promiseConfig, promiseLanguageOptions, promiseSystemInfo]).then(function (responses) {
loadPage(view, responses[0], responses[1], responses[2]);
});
ApiClient.getNamedConfiguration(brandingConfigKey).then(function (config) {
view.querySelector('#txtLoginDisclaimer').value = config.LoginDisclaimer || '';
view.querySelector('#txtCustomCss').value = config.CustomCss || '';
view.querySelector('#chkSplashScreenAvailable').checked = config.SplashscreenEnabled === true;
});
});
}
/* eslint-enable indent */

View file

@ -12,399 +12,396 @@ import Dashboard, { pageClassOn, pageIdOn } from '../../utils/dashboard';
import confirm from '../../components/confirm/confirm';
import cardBuilder from '../../components/cardbuilder/cardBuilder';
/* eslint-disable indent */
function addVirtualFolder(page) {
import('../../components/mediaLibraryCreator/mediaLibraryCreator').then(({ default: medialibrarycreator }) => {
new medialibrarycreator({
collectionTypeOptions: getCollectionTypeOptions().filter(function (f) {
return !f.hidden;
}),
refresh: shouldRefreshLibraryAfterChanges(page)
}).then(function (hasChanges) {
if (hasChanges) {
reloadLibrary(page);
}
});
});
}
function editVirtualFolder(page, virtualFolder) {
import('../../components/mediaLibraryEditor/mediaLibraryEditor').then(({ default: medialibraryeditor }) => {
new medialibraryeditor({
refresh: shouldRefreshLibraryAfterChanges(page),
library: virtualFolder
}).then(function (hasChanges) {
if (hasChanges) {
reloadLibrary(page);
}
});
});
}
function deleteVirtualFolder(page, virtualFolder) {
let msg = globalize.translate('MessageAreYouSureYouWishToRemoveMediaFolder');
if (virtualFolder.Locations.length) {
msg += '<br/><br/>' + globalize.translate('MessageTheFollowingLocationWillBeRemovedFromLibrary') + '<br/><br/>';
msg += virtualFolder.Locations.join('<br/>');
}
confirm({
text: msg,
title: globalize.translate('HeaderRemoveMediaFolder'),
confirmText: globalize.translate('Delete'),
primary: 'delete'
}).then(function () {
const refreshAfterChange = shouldRefreshLibraryAfterChanges(page);
ApiClient.removeVirtualFolder(virtualFolder.Name, refreshAfterChange).then(function () {
function addVirtualFolder(page) {
import('../../components/mediaLibraryCreator/mediaLibraryCreator').then(({ default: medialibrarycreator }) => {
new medialibrarycreator({
collectionTypeOptions: getCollectionTypeOptions().filter(function (f) {
return !f.hidden;
}),
refresh: shouldRefreshLibraryAfterChanges(page)
}).then(function (hasChanges) {
if (hasChanges) {
reloadLibrary(page);
});
}
});
});
}
function editVirtualFolder(page, virtualFolder) {
import('../../components/mediaLibraryEditor/mediaLibraryEditor').then(({ default: medialibraryeditor }) => {
new medialibraryeditor({
refresh: shouldRefreshLibraryAfterChanges(page),
library: virtualFolder
}).then(function (hasChanges) {
if (hasChanges) {
reloadLibrary(page);
}
});
});
}
function deleteVirtualFolder(page, virtualFolder) {
let msg = globalize.translate('MessageAreYouSureYouWishToRemoveMediaFolder');
if (virtualFolder.Locations.length) {
msg += '<br/><br/>' + globalize.translate('MessageTheFollowingLocationWillBeRemovedFromLibrary') + '<br/><br/>';
msg += virtualFolder.Locations.join('<br/>');
}
function refreshVirtualFolder(page, virtualFolder) {
import('../../components/refreshdialog/refreshdialog').then(({ default: refreshDialog }) => {
new refreshDialog({
itemIds: [virtualFolder.ItemId],
serverId: ApiClient.serverId(),
mode: 'scan'
}).show();
confirm({
text: msg,
title: globalize.translate('HeaderRemoveMediaFolder'),
confirmText: globalize.translate('Delete'),
primary: 'delete'
}).then(function () {
const refreshAfterChange = shouldRefreshLibraryAfterChanges(page);
ApiClient.removeVirtualFolder(virtualFolder.Name, refreshAfterChange).then(function () {
reloadLibrary(page);
});
}
});
}
function renameVirtualFolder(page, virtualFolder) {
import('../../components/prompt/prompt').then(({ default: prompt }) => {
prompt({
label: globalize.translate('LabelNewName'),
description: globalize.translate('MessageRenameMediaFolder'),
confirmText: globalize.translate('ButtonRename')
}).then(function (newName) {
if (newName && newName != virtualFolder.Name) {
const refreshAfterChange = shouldRefreshLibraryAfterChanges(page);
ApiClient.renameVirtualFolder(virtualFolder.Name, newName, refreshAfterChange).then(function () {
reloadLibrary(page);
});
function refreshVirtualFolder(page, virtualFolder) {
import('../../components/refreshdialog/refreshdialog').then(({ default: refreshDialog }) => {
new refreshDialog({
itemIds: [virtualFolder.ItemId],
serverId: ApiClient.serverId(),
mode: 'scan'
}).show();
});
}
function renameVirtualFolder(page, virtualFolder) {
import('../../components/prompt/prompt').then(({ default: prompt }) => {
prompt({
label: globalize.translate('LabelNewName'),
description: globalize.translate('MessageRenameMediaFolder'),
confirmText: globalize.translate('ButtonRename')
}).then(function (newName) {
if (newName && newName != virtualFolder.Name) {
const refreshAfterChange = shouldRefreshLibraryAfterChanges(page);
ApiClient.renameVirtualFolder(virtualFolder.Name, newName, refreshAfterChange).then(function () {
reloadLibrary(page);
});
}
});
});
}
function showCardMenu(page, elem, virtualFolders) {
const card = dom.parentWithClass(elem, 'card');
const index = parseInt(card.getAttribute('data-index'), 10);
const virtualFolder = virtualFolders[index];
const menuItems = [];
menuItems.push({
name: globalize.translate('EditImages'),
id: 'editimages',
icon: 'photo'
});
menuItems.push({
name: globalize.translate('ManageLibrary'),
id: 'edit',
icon: 'folder'
});
menuItems.push({
name: globalize.translate('ButtonRename'),
id: 'rename',
icon: 'mode_edit'
});
menuItems.push({
name: globalize.translate('ScanLibrary'),
id: 'refresh',
icon: 'refresh'
});
menuItems.push({
name: globalize.translate('ButtonRemove'),
id: 'delete',
icon: 'delete'
});
import('../../components/actionSheet/actionSheet').then((actionsheet) => {
actionsheet.show({
items: menuItems,
positionTo: elem,
callback: function (resultId) {
switch (resultId) {
case 'edit':
editVirtualFolder(page, virtualFolder);
break;
case 'editimages':
editImages(page, virtualFolder);
break;
case 'rename':
renameVirtualFolder(page, virtualFolder);
break;
case 'delete':
deleteVirtualFolder(page, virtualFolder);
break;
case 'refresh':
refreshVirtualFolder(page, virtualFolder);
}
});
}
});
});
}
function reloadLibrary(page) {
loading.show();
ApiClient.getVirtualFolders().then(function (result) {
reloadVirtualFolders(page, result);
});
}
function shouldRefreshLibraryAfterChanges(page) {
return page.id === 'mediaLibraryPage';
}
function reloadVirtualFolders(page, virtualFolders) {
let html = '';
virtualFolders.push({
Name: globalize.translate('ButtonAddMediaLibrary'),
icon: 'add_circle',
Locations: [],
showType: false,
showLocations: false,
showMenu: false,
showNameWithIcon: false,
elementId: 'addLibrary'
});
for (let i = 0; i < virtualFolders.length; i++) {
const virtualFolder = virtualFolders[i];
html += getVirtualFolderHtml(page, virtualFolder, i);
}
function showCardMenu(page, elem, virtualFolders) {
const card = dom.parentWithClass(elem, 'card');
const divVirtualFolders = page.querySelector('#divVirtualFolders');
divVirtualFolders.innerHTML = html;
divVirtualFolders.classList.add('itemsContainer');
divVirtualFolders.classList.add('vertical-wrap');
$('.btnCardMenu', divVirtualFolders).on('click', function () {
showCardMenu(page, this, virtualFolders);
});
divVirtualFolders.querySelector('#addLibrary').addEventListener('click', function () {
addVirtualFolder(page);
});
$('.editLibrary', divVirtualFolders).on('click', function () {
const card = $(this).parents('.card')[0];
const index = parseInt(card.getAttribute('data-index'), 10);
const virtualFolder = virtualFolders[index];
const menuItems = [];
menuItems.push({
name: globalize.translate('EditImages'),
id: 'editimages',
icon: 'photo'
});
menuItems.push({
name: globalize.translate('ManageLibrary'),
id: 'edit',
icon: 'folder'
});
menuItems.push({
name: globalize.translate('ButtonRename'),
id: 'rename',
icon: 'mode_edit'
});
menuItems.push({
name: globalize.translate('ScanLibrary'),
id: 'refresh',
icon: 'refresh'
});
menuItems.push({
name: globalize.translate('ButtonRemove'),
id: 'delete',
icon: 'delete'
});
import('../../components/actionSheet/actionSheet').then((actionsheet) => {
actionsheet.show({
items: menuItems,
positionTo: elem,
callback: function (resultId) {
switch (resultId) {
case 'edit':
editVirtualFolder(page, virtualFolder);
break;
case 'editimages':
editImages(page, virtualFolder);
break;
case 'rename':
renameVirtualFolder(page, virtualFolder);
break;
case 'delete':
deleteVirtualFolder(page, virtualFolder);
break;
case 'refresh':
refreshVirtualFolder(page, virtualFolder);
}
}
});
});
}
function reloadLibrary(page) {
loading.show();
ApiClient.getVirtualFolders().then(function (result) {
reloadVirtualFolders(page, result);
});
}
function shouldRefreshLibraryAfterChanges(page) {
return page.id === 'mediaLibraryPage';
}
function reloadVirtualFolders(page, virtualFolders) {
let html = '';
virtualFolders.push({
Name: globalize.translate('ButtonAddMediaLibrary'),
icon: 'add_circle',
Locations: [],
showType: false,
showLocations: false,
showMenu: false,
showNameWithIcon: false,
elementId: 'addLibrary'
});
for (let i = 0; i < virtualFolders.length; i++) {
const virtualFolder = virtualFolders[i];
html += getVirtualFolderHtml(page, virtualFolder, i);
if (virtualFolder.ItemId) {
editVirtualFolder(page, virtualFolder);
}
});
loading.hide();
}
const divVirtualFolders = page.querySelector('#divVirtualFolders');
divVirtualFolders.innerHTML = html;
divVirtualFolders.classList.add('itemsContainer');
divVirtualFolders.classList.add('vertical-wrap');
$('.btnCardMenu', divVirtualFolders).on('click', function () {
showCardMenu(page, this, virtualFolders);
function editImages(page, virtualFolder) {
import('../../components/imageeditor/imageeditor').then((imageEditor) => {
imageEditor.show({
itemId: virtualFolder.ItemId,
serverId: ApiClient.serverId()
}).then(function () {
reloadLibrary(page);
});
divVirtualFolders.querySelector('#addLibrary').addEventListener('click', function () {
addVirtualFolder(page);
});
$('.editLibrary', divVirtualFolders).on('click', function () {
const card = $(this).parents('.card')[0];
const index = parseInt(card.getAttribute('data-index'), 10);
const virtualFolder = virtualFolders[index];
});
}
if (virtualFolder.ItemId) {
editVirtualFolder(page, virtualFolder);
}
});
loading.hide();
function getLink(text, url) {
return globalize.translate(text, '<a is="emby-linkbutton" class="button-link" href="' + url + '" target="_blank" data-autohide="true">', '</a>');
}
function getCollectionTypeOptions() {
return [{
name: '',
value: ''
}, {
name: globalize.translate('Movies'),
value: 'movies',
message: getLink('MovieLibraryHelp', 'https://jellyfin.org/docs/general/server/media/movies')
}, {
name: globalize.translate('TabMusic'),
value: 'music',
message: getLink('MusicLibraryHelp', 'https://jellyfin.org/docs/general/server/media/music')
}, {
name: globalize.translate('Shows'),
value: 'tvshows',
message: getLink('TvLibraryHelp', 'https://jellyfin.org/docs/general/server/media/shows')
}, {
name: globalize.translate('Books'),
value: 'books',
message: getLink('BookLibraryHelp', 'https://jellyfin.org/docs/general/server/media/books')
}, {
name: globalize.translate('HomeVideosPhotos'),
value: 'homevideos'
}, {
name: globalize.translate('MusicVideos'),
value: 'musicvideos'
}, {
name: globalize.translate('MixedMoviesShows'),
value: 'mixed',
message: globalize.translate('MessageUnsetContentHelp')
}];
}
function getVirtualFolderHtml(page, virtualFolder, index) {
let html = '';
let style = '';
if (page.classList.contains('wizardPage')) {
style += 'min-width:33.3%;';
}
function editImages(page, virtualFolder) {
import('../../components/imageeditor/imageeditor').then((imageEditor) => {
imageEditor.show({
itemId: virtualFolder.ItemId,
serverId: ApiClient.serverId()
}).then(function () {
reloadLibrary(page);
});
const elementId = virtualFolder.elementId ? `id="${virtualFolder.elementId}" ` : '';
html += '<div ' + elementId + 'class="card backdropCard scalableCard backdropCard-scalable" style="' + style + '" data-index="' + index + '" data-id="' + virtualFolder.ItemId + '">';
html += '<div class="cardBox visualCardBox">';
html += '<div class="cardScalable visualCardBox-cardScalable">';
html += '<div class="cardPadder cardPadder-backdrop"></div>';
html += '<div class="cardContent">';
let imgUrl = '';
if (virtualFolder.PrimaryImageItemId) {
imgUrl = ApiClient.getScaledImageUrl(virtualFolder.PrimaryImageItemId, {
maxWidth: Math.round(dom.getScreenWidth() * 0.40),
type: 'Primary'
});
}
function getLink(text, url) {
return globalize.translate(text, '<a is="emby-linkbutton" class="button-link" href="' + url + '" target="_blank" data-autohide="true">', '</a>');
let hasCardImageContainer;
if (imgUrl) {
html += `<div class="cardImageContainer editLibrary ${imgUrl ? '' : cardBuilder.getDefaultBackgroundClass()}" style="cursor:pointer">`;
html += `<img src="${imgUrl}" style="width:100%" />`;
hasCardImageContainer = true;
} else if (!virtualFolder.showNameWithIcon) {
html += `<div class="cardImageContainer editLibrary ${cardBuilder.getDefaultBackgroundClass()}" style="cursor:pointer;">`;
html += '<span class="cardImageIcon material-icons ' + (virtualFolder.icon || imageHelper.getLibraryIcon(virtualFolder.CollectionType)) + '" aria-hidden="true"></span>';
hasCardImageContainer = true;
}
function getCollectionTypeOptions() {
return [{
name: '',
value: ''
}, {
name: globalize.translate('Movies'),
value: 'movies',
message: getLink('MovieLibraryHelp', 'https://jellyfin.org/docs/general/server/media/movies')
}, {
name: globalize.translate('TabMusic'),
value: 'music',
message: getLink('MusicLibraryHelp', 'https://jellyfin.org/docs/general/server/media/music')
}, {
name: globalize.translate('Shows'),
value: 'tvshows',
message: getLink('TvLibraryHelp', 'https://jellyfin.org/docs/general/server/media/shows')
}, {
name: globalize.translate('Books'),
value: 'books',
message: getLink('BookLibraryHelp', 'https://jellyfin.org/docs/general/server/media/books')
}, {
name: globalize.translate('HomeVideosPhotos'),
value: 'homevideos'
}, {
name: globalize.translate('MusicVideos'),
value: 'musicvideos'
}, {
name: globalize.translate('MixedMoviesShows'),
value: 'mixed',
message: globalize.translate('MessageUnsetContentHelp')
}];
}
function getVirtualFolderHtml(page, virtualFolder, index) {
let html = '';
let style = '';
if (page.classList.contains('wizardPage')) {
style += 'min-width:33.3%;';
}
const elementId = virtualFolder.elementId ? `id="${virtualFolder.elementId}" ` : '';
html += '<div ' + elementId + 'class="card backdropCard scalableCard backdropCard-scalable" style="' + style + '" data-index="' + index + '" data-id="' + virtualFolder.ItemId + '">';
html += '<div class="cardBox visualCardBox">';
html += '<div class="cardScalable visualCardBox-cardScalable">';
html += '<div class="cardPadder cardPadder-backdrop"></div>';
html += '<div class="cardContent">';
let imgUrl = '';
if (virtualFolder.PrimaryImageItemId) {
imgUrl = ApiClient.getScaledImageUrl(virtualFolder.PrimaryImageItemId, {
maxWidth: Math.round(dom.getScreenWidth() * 0.40),
type: 'Primary'
});
}
let hasCardImageContainer;
if (imgUrl) {
html += `<div class="cardImageContainer editLibrary ${imgUrl ? '' : cardBuilder.getDefaultBackgroundClass()}" style="cursor:pointer">`;
html += `<img src="${imgUrl}" style="width:100%" />`;
hasCardImageContainer = true;
} else if (!virtualFolder.showNameWithIcon) {
html += `<div class="cardImageContainer editLibrary ${cardBuilder.getDefaultBackgroundClass()}" style="cursor:pointer;">`;
html += '<span class="cardImageIcon material-icons ' + (virtualFolder.icon || imageHelper.getLibraryIcon(virtualFolder.CollectionType)) + '" aria-hidden="true"></span>';
hasCardImageContainer = true;
}
if (hasCardImageContainer) {
html += '<div class="cardIndicators backdropCardIndicators">';
html += '<div is="emby-itemrefreshindicator"' + (virtualFolder.RefreshProgress || virtualFolder.RefreshStatus && virtualFolder.RefreshStatus !== 'Idle' ? '' : ' class="hide"') + ' data-progress="' + (virtualFolder.RefreshProgress || 0) + '" data-status="' + virtualFolder.RefreshStatus + '"></div>';
html += '</div>';
html += '</div>';
}
if (!imgUrl && virtualFolder.showNameWithIcon) {
html += '<h3 class="cardImageContainer addLibrary" style="position:absolute;top:0;left:0;right:0;bottom:0;cursor:pointer;flex-direction:column;">';
html += '<span class="cardImageIcon material-icons ' + (virtualFolder.icon || imageHelper.getLibraryIcon(virtualFolder.CollectionType)) + '" aria-hidden="true"></span>';
if (virtualFolder.showNameWithIcon) {
html += '<div style="margin:1em 0;position:width:100%;">';
html += escapeHtml(virtualFolder.Name);
html += '</div>';
}
html += '</h3>';
}
if (hasCardImageContainer) {
html += '<div class="cardIndicators backdropCardIndicators">';
html += '<div is="emby-itemrefreshindicator"' + (virtualFolder.RefreshProgress || virtualFolder.RefreshStatus && virtualFolder.RefreshStatus !== 'Idle' ? '' : ' class="hide"') + ' data-progress="' + (virtualFolder.RefreshProgress || 0) + '" data-status="' + virtualFolder.RefreshStatus + '"></div>';
html += '</div>';
html += '</div>';
html += '<div class="cardFooter visualCardBox-cardFooter">'; // always show menu unless explicitly hidden
}
if (virtualFolder.showMenu !== false) {
let dirTextAlign = 'right';
if (globalize.getIsRTL())
dirTextAlign = 'left';
html += '<div style="text-align:' + dirTextAlign + '; float:' + dirTextAlign + ';padding-top:5px;">';
html += '<button type="button" is="paper-icon-button-light" class="btnCardMenu autoSize"><span class="material-icons more_vert" aria-hidden="true"></span></button>';
html += '</div>';
}
html += "<div class='cardText'>";
if (!imgUrl && virtualFolder.showNameWithIcon) {
html += '<h3 class="cardImageContainer addLibrary" style="position:absolute;top:0;left:0;right:0;bottom:0;cursor:pointer;flex-direction:column;">';
html += '<span class="cardImageIcon material-icons ' + (virtualFolder.icon || imageHelper.getLibraryIcon(virtualFolder.CollectionType)) + '" aria-hidden="true"></span>';
if (virtualFolder.showNameWithIcon) {
html += '&nbsp;';
} else {
html += '<div style="margin:1em 0;position:width:100%;">';
html += escapeHtml(virtualFolder.Name);
html += '</div>';
}
html += '</h3>';
}
html += '</div>';
html += '</div>';
html += '<div class="cardFooter visualCardBox-cardFooter">'; // always show menu unless explicitly hidden
if (virtualFolder.showMenu !== false) {
let dirTextAlign = 'right';
if (globalize.getIsRTL())
dirTextAlign = 'left';
html += '<div style="text-align:' + dirTextAlign + '; float:' + dirTextAlign + ';padding-top:5px;">';
html += '<button type="button" is="paper-icon-button-light" class="btnCardMenu autoSize"><span class="material-icons more_vert" aria-hidden="true"></span></button>';
html += '</div>';
let typeName = getCollectionTypeOptions().filter(function (t) {
return t.value == virtualFolder.CollectionType;
})[0];
typeName = typeName ? typeName.name : globalize.translate('Other');
}
html += "<div class='cardText'>";
if (virtualFolder.showNameWithIcon) {
html += '&nbsp;';
} else {
html += escapeHtml(virtualFolder.Name);
}
html += '</div>';
let typeName = getCollectionTypeOptions().filter(function (t) {
return t.value == virtualFolder.CollectionType;
})[0];
typeName = typeName ? typeName.name : globalize.translate('Other');
html += "<div class='cardText cardText-secondary'>";
if (virtualFolder.showType === false) {
html += '&nbsp;';
} else {
html += typeName;
}
html += '</div>';
if (virtualFolder.showLocations === false) {
html += "<div class='cardText cardText-secondary'>";
if (virtualFolder.showType === false) {
html += '&nbsp;';
} else {
html += typeName;
}
html += '&nbsp;';
html += '</div>';
if (virtualFolder.showLocations === false) {
html += "<div class='cardText cardText-secondary'>";
html += '&nbsp;';
html += '</div>';
} else if (virtualFolder.Locations.length && virtualFolder.Locations.length === 1) {
html += "<div class='cardText cardText-secondary' dir='ltr' style='text-align:left;'>";
html += virtualFolder.Locations[0];
html += '</div>';
} else {
html += "<div class='cardText cardText-secondary'>";
html += globalize.translate('NumLocationsValue', virtualFolder.Locations.length);
html += '</div>';
}
} else if (virtualFolder.Locations.length && virtualFolder.Locations.length === 1) {
html += "<div class='cardText cardText-secondary' dir='ltr' style='text-align:left;'>";
html += virtualFolder.Locations[0];
html += '</div>';
} else {
html += "<div class='cardText cardText-secondary'>";
html += globalize.translate('NumLocationsValue', virtualFolder.Locations.length);
html += '</div>';
html += '</div>';
return html;
}
function getTabs() {
return [{
href: '#/library.html',
name: globalize.translate('HeaderLibraries')
}, {
href: '#/librarydisplay.html',
name: globalize.translate('Display')
}, {
href: '#/metadataimages.html',
name: globalize.translate('Metadata')
}, {
href: '#/metadatanfo.html',
name: globalize.translate('TabNfoSettings')
}];
html += '</div>';
html += '</div>';
html += '</div>';
return html;
}
function getTabs() {
return [{
href: '#/library.html',
name: globalize.translate('HeaderLibraries')
}, {
href: '#/librarydisplay.html',
name: globalize.translate('Display')
}, {
href: '#/metadataimages.html',
name: globalize.translate('Metadata')
}, {
href: '#/metadatanfo.html',
name: globalize.translate('TabNfoSettings')
}];
}
window.WizardLibraryPage = {
next: function () {
Dashboard.navigate('wizardsettings.html');
}
};
pageClassOn('pageshow', 'mediaLibraryPage', function () {
reloadLibrary(this);
});
pageIdOn('pageshow', 'mediaLibraryPage', function () {
libraryMenu.setTabs('librarysetup', 0, getTabs);
window.WizardLibraryPage = {
next: function () {
Dashboard.navigate('wizardsettings.html');
}
};
pageClassOn('pageshow', 'mediaLibraryPage', function () {
reloadLibrary(this);
const page = this;
taskButton({
mode: 'on',
progressElem: page.querySelector('.refreshProgress'),
taskKey: 'RefreshLibrary',
button: page.querySelector('.btnRefresh')
});
pageIdOn('pageshow', 'mediaLibraryPage', function () {
libraryMenu.setTabs('librarysetup', 0, getTabs);
});
pageIdOn('pagebeforehide', 'mediaLibraryPage', function () {
const page = this;
taskButton({
mode: 'off',
progressElem: page.querySelector('.refreshProgress'),
taskKey: 'RefreshLibrary',
button: page.querySelector('.btnRefresh')
});
});
const page = this;
taskButton({
mode: 'on',
progressElem: page.querySelector('.refreshProgress'),
taskKey: 'RefreshLibrary',
button: page.querySelector('.btnRefresh')
});
});
pageIdOn('pagebeforehide', 'mediaLibraryPage', function () {
const page = this;
taskButton({
mode: 'off',
progressElem: page.querySelector('.refreshProgress'),
taskKey: 'RefreshLibrary',
button: page.querySelector('.btnRefresh')
});
});
/* eslint-enable indent */

View file

@ -5,70 +5,67 @@ import '../../elements/emby-checkbox/emby-checkbox';
import '../../elements/emby-button/emby-button';
import Dashboard from '../../utils/dashboard';
/* eslint-disable indent */
function getTabs() {
return [{
href: '#/library.html',
name: globalize.translate('HeaderLibraries')
}, {
href: '#/librarydisplay.html',
name: globalize.translate('Display')
}, {
href: '#/metadataimages.html',
name: globalize.translate('Metadata')
}, {
href: '#/metadatanfo.html',
name: globalize.translate('TabNfoSettings')
}];
}
function getTabs() {
return [{
href: '#/library.html',
name: globalize.translate('HeaderLibraries')
}, {
href: '#/librarydisplay.html',
name: globalize.translate('Display')
}, {
href: '#/metadataimages.html',
name: globalize.translate('Metadata')
}, {
href: '#/metadatanfo.html',
name: globalize.translate('TabNfoSettings')
}];
}
export default function(view) {
function loadData() {
ApiClient.getServerConfiguration().then(function(config) {
view.querySelector('.chkFolderView').checked = config.EnableFolderView;
view.querySelector('.chkGroupMoviesIntoCollections').checked = config.EnableGroupingIntoCollections;
view.querySelector('.chkDisplaySpecialsWithinSeasons').checked = config.DisplaySpecialsWithinSeasons;
view.querySelector('.chkExternalContentInSuggestions').checked = config.EnableExternalContentInSuggestions;
view.querySelector('#chkSaveMetadataHidden').checked = config.SaveMetadataHidden;
});
ApiClient.getNamedConfiguration('metadata').then(function(metadata) {
view.querySelector('#selectDateAdded').selectedIndex = metadata.UseFileCreationTimeForDateAdded ? 1 : 0;
});
}
view.querySelector('form').addEventListener('submit', function(e) {
loading.show();
const form = this;
ApiClient.getServerConfiguration().then(function(config) {
config.EnableFolderView = form.querySelector('.chkFolderView').checked;
config.EnableGroupingIntoCollections = form.querySelector('.chkGroupMoviesIntoCollections').checked;
config.DisplaySpecialsWithinSeasons = form.querySelector('.chkDisplaySpecialsWithinSeasons').checked;
config.EnableExternalContentInSuggestions = form.querySelector('.chkExternalContentInSuggestions').checked;
config.SaveMetadataHidden = form.querySelector('#chkSaveMetadataHidden').checked;
ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
});
ApiClient.getNamedConfiguration('metadata').then(function(config) {
config.UseFileCreationTimeForDateAdded = $('#selectDateAdded', form).val() === '1';
ApiClient.updateNamedConfiguration('metadata', config);
});
e.preventDefault();
loading.hide();
return false;
export default function(view) {
function loadData() {
ApiClient.getServerConfiguration().then(function(config) {
view.querySelector('.chkFolderView').checked = config.EnableFolderView;
view.querySelector('.chkGroupMoviesIntoCollections').checked = config.EnableGroupingIntoCollections;
view.querySelector('.chkDisplaySpecialsWithinSeasons').checked = config.DisplaySpecialsWithinSeasons;
view.querySelector('.chkExternalContentInSuggestions').checked = config.EnableExternalContentInSuggestions;
view.querySelector('#chkSaveMetadataHidden').checked = config.SaveMetadataHidden;
});
view.addEventListener('viewshow', function() {
libraryMenu.setTabs('librarysetup', 1, getTabs);
loadData();
ApiClient.getSystemInfo().then(function(info) {
if (info.OperatingSystem === 'Windows') {
view.querySelector('.fldSaveMetadataHidden').classList.remove('hide');
} else {
view.querySelector('.fldSaveMetadataHidden').classList.add('hide');
}
});
ApiClient.getNamedConfiguration('metadata').then(function(metadata) {
view.querySelector('#selectDateAdded').selectedIndex = metadata.UseFileCreationTimeForDateAdded ? 1 : 0;
});
}
/* eslint-enable indent */
view.querySelector('form').addEventListener('submit', function(e) {
loading.show();
const form = this;
ApiClient.getServerConfiguration().then(function(config) {
config.EnableFolderView = form.querySelector('.chkFolderView').checked;
config.EnableGroupingIntoCollections = form.querySelector('.chkGroupMoviesIntoCollections').checked;
config.DisplaySpecialsWithinSeasons = form.querySelector('.chkDisplaySpecialsWithinSeasons').checked;
config.EnableExternalContentInSuggestions = form.querySelector('.chkExternalContentInSuggestions').checked;
config.SaveMetadataHidden = form.querySelector('#chkSaveMetadataHidden').checked;
ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
});
ApiClient.getNamedConfiguration('metadata').then(function(config) {
config.UseFileCreationTimeForDateAdded = $('#selectDateAdded', form).val() === '1';
ApiClient.updateNamedConfiguration('metadata', config);
});
e.preventDefault();
loading.hide();
return false;
});
view.addEventListener('viewshow', function() {
libraryMenu.setTabs('librarysetup', 1, getTabs);
loadData();
ApiClient.getSystemInfo().then(function(info) {
if (info.OperatingSystem === 'Windows') {
view.querySelector('.fldSaveMetadataHidden').classList.remove('hide');
} else {
view.querySelector('.fldSaveMetadataHidden').classList.add('hide');
}
});
});
}

View file

@ -7,61 +7,57 @@ import '../../styles/flexstyles.scss';
import Dashboard from '../../utils/dashboard';
import alert from '../../components/alert';
/* eslint-disable indent */
function onSubmit(event) {
event.preventDefault();
loading.show();
const form = this;
ApiClient.getServerConfiguration().then(function (config) {
config.EnableSlowResponseWarning = form.querySelector('#chkSlowResponseWarning').checked;
config.SlowResponseThresholdMs = form.querySelector('#txtSlowResponseWarning').value;
ApiClient.updateServerConfiguration(config).then(function() {
Dashboard.processServerConfigurationUpdateResult();
}, function () {
alert(globalize.translate('ErrorDefault'));
Dashboard.processServerConfigurationUpdateResult();
});
});
return false;
}
function onSubmit(event) {
event.preventDefault();
export default function(view) {
view.querySelector('.logsForm').addEventListener('submit', onSubmit);
view.addEventListener('viewbeforeshow', function() {
loading.show();
const form = this;
ApiClient.getServerConfiguration().then(function (config) {
config.EnableSlowResponseWarning = form.querySelector('#chkSlowResponseWarning').checked;
config.SlowResponseThresholdMs = form.querySelector('#txtSlowResponseWarning').value;
ApiClient.updateServerConfiguration(config).then(function() {
Dashboard.processServerConfigurationUpdateResult();
}, function () {
alert(globalize.translate('ErrorDefault'));
Dashboard.processServerConfigurationUpdateResult();
});
const apiClient = ApiClient;
apiClient.getJSON(apiClient.getUrl('System/Logs')).then(function(logs) {
let html = '';
html += '<div class="paperList">';
html += logs.map(function(log) {
let logUrl = apiClient.getUrl('System/Logs/Log', {
name: log.Name
});
logUrl += '&api_key=' + apiClient.accessToken();
let logHtml = '';
logHtml += '<a is="emby-linkbutton" href="' + logUrl + '" target="_blank" class="listItem listItem-border" style="color:inherit;">';
logHtml += '<div class="listItemBody two-line">';
logHtml += "<h3 class='listItemBodyText' dir='ltr' style='text-align: left'>" + log.Name + '</h3>';
const date = datetime.parseISO8601Date(log.DateModified, true);
let text = datetime.toLocaleDateString(date);
text += ' ' + datetime.getDisplayTime(date);
logHtml += '<div class="listItemBodyText secondary">' + text + '</div>';
logHtml += '</div>';
logHtml += '</a>';
return logHtml;
}).join('');
html += '</div>';
view.querySelector('.serverLogs').innerHTML = html;
});
return false;
}
export default function(view) {
view.querySelector('.logsForm').addEventListener('submit', onSubmit);
view.addEventListener('viewbeforeshow', function() {
loading.show();
const apiClient = ApiClient;
apiClient.getJSON(apiClient.getUrl('System/Logs')).then(function(logs) {
let html = '';
html += '<div class="paperList">';
html += logs.map(function(log) {
let logUrl = apiClient.getUrl('System/Logs/Log', {
name: log.Name
});
logUrl += '&api_key=' + apiClient.accessToken();
let logHtml = '';
logHtml += '<a is="emby-linkbutton" href="' + logUrl + '" target="_blank" class="listItem listItem-border" style="color:inherit;">';
logHtml += '<div class="listItemBody two-line">';
logHtml += "<h3 class='listItemBodyText' dir='ltr' style='text-align: left'>" + log.Name + '</h3>';
const date = datetime.parseISO8601Date(log.DateModified, true);
let text = datetime.toLocaleDateString(date);
text += ' ' + datetime.getDisplayTime(date);
logHtml += '<div class="listItemBodyText secondary">' + text + '</div>';
logHtml += '</div>';
logHtml += '</a>';
return logHtml;
}).join('');
html += '</div>';
view.querySelector('.serverLogs').innerHTML = html;
});
apiClient.getServerConfiguration().then(function (config) {
view.querySelector('#chkSlowResponseWarning').checked = config.EnableSlowResponseWarning;
view.querySelector('#txtSlowResponseWarning').value = config.SlowResponseThresholdMs;
});
loading.hide();
apiClient.getServerConfiguration().then(function (config) {
view.querySelector('#chkSlowResponseWarning').checked = config.EnableSlowResponseWarning;
view.querySelector('#txtSlowResponseWarning').value = config.SlowResponseThresholdMs;
});
}
/* eslint-enable indent */
loading.hide();
});
}

View file

@ -30,88 +30,85 @@ function populateImageResolutionOptions(select) {
select.innerHTML = html;
}
/* eslint-disable indent */
function populateLanguages(select) {
return ApiClient.getCultures().then(function(languages) {
let html = '';
html += "<option value=''></option>";
for (let i = 0, length = languages.length; i < length; i++) {
const culture = languages[i];
html += "<option value='" + culture.TwoLetterISOLanguageName + "'>" + culture.DisplayName + '</option>';
}
select.innerHTML = html;
});
}
function populateCountries(select) {
return ApiClient.getCountries().then(function(allCountries) {
let html = '';
html += "<option value=''></option>";
for (let i = 0, length = allCountries.length; i < length; i++) {
const culture = allCountries[i];
html += "<option value='" + culture.TwoLetterISORegionName + "'>" + culture.DisplayName + '</option>';
}
select.innerHTML = html;
});
}
function loadPage(page) {
const promises = [
ApiClient.getServerConfiguration(),
populateLanguages(page.querySelector('#selectLanguage')),
populateCountries(page.querySelector('#selectCountry'))
];
populateImageResolutionOptions(page.querySelector('#txtChapterImageResolution'));
Promise.all(promises).then(function(responses) {
const config = responses[0];
page.querySelector('#selectLanguage').value = config.PreferredMetadataLanguage || '';
page.querySelector('#selectCountry').value = config.MetadataCountryCode || '';
page.querySelector('#valDummyChapterDuration').value = config.DummyChapterDuration || '';
page.querySelector('#valDummyChapterCount').value = config.DummyChapterCount || '';
page.querySelector('#txtChapterImageResolution').value = config.ChapterImageResolution || '';
loading.hide();
});
}
function onSubmit() {
const form = this;
loading.show();
ApiClient.getServerConfiguration().then(function(config) {
config.PreferredMetadataLanguage = form.querySelector('#selectLanguage').value;
config.MetadataCountryCode = form.querySelector('#selectCountry').value;
config.DummyChapterDuration = form.querySelector('#valDummyChapterDuration').value;
config.DummyChapterCount = form.querySelector('#valDummyChapterCount').value;
config.ChapterImageResolution = form.querySelector('#txtChapterImageResolution').value;
ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
});
return false;
}
function getTabs() {
return [{
href: '#/library.html',
name: globalize.translate('HeaderLibraries')
}, {
href: '#/librarydisplay.html',
name: globalize.translate('Display')
}, {
href: '#/metadataimages.html',
name: globalize.translate('Metadata')
}, {
href: '#/metadatanfo.html',
name: globalize.translate('TabNfoSettings')
}];
}
$(document).on('pageinit', '#metadataImagesConfigurationPage', function() {
$('.metadataImagesConfigurationForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#metadataImagesConfigurationPage', function() {
libraryMenu.setTabs('metadata', 2, getTabs);
loading.show();
loadPage(this);
function populateLanguages(select) {
return ApiClient.getCultures().then(function(languages) {
let html = '';
html += "<option value=''></option>";
for (let i = 0, length = languages.length; i < length; i++) {
const culture = languages[i];
html += "<option value='" + culture.TwoLetterISOLanguageName + "'>" + culture.DisplayName + '</option>';
}
select.innerHTML = html;
});
}
function populateCountries(select) {
return ApiClient.getCountries().then(function(allCountries) {
let html = '';
html += "<option value=''></option>";
for (let i = 0, length = allCountries.length; i < length; i++) {
const culture = allCountries[i];
html += "<option value='" + culture.TwoLetterISORegionName + "'>" + culture.DisplayName + '</option>';
}
select.innerHTML = html;
});
}
function loadPage(page) {
const promises = [
ApiClient.getServerConfiguration(),
populateLanguages(page.querySelector('#selectLanguage')),
populateCountries(page.querySelector('#selectCountry'))
];
populateImageResolutionOptions(page.querySelector('#txtChapterImageResolution'));
Promise.all(promises).then(function(responses) {
const config = responses[0];
page.querySelector('#selectLanguage').value = config.PreferredMetadataLanguage || '';
page.querySelector('#selectCountry').value = config.MetadataCountryCode || '';
page.querySelector('#valDummyChapterDuration').value = config.DummyChapterDuration || '';
page.querySelector('#valDummyChapterCount').value = config.DummyChapterCount || '';
page.querySelector('#txtChapterImageResolution').value = config.ChapterImageResolution || '';
loading.hide();
});
}
function onSubmit() {
const form = this;
loading.show();
ApiClient.getServerConfiguration().then(function(config) {
config.PreferredMetadataLanguage = form.querySelector('#selectLanguage').value;
config.MetadataCountryCode = form.querySelector('#selectCountry').value;
config.DummyChapterDuration = form.querySelector('#valDummyChapterDuration').value;
config.DummyChapterCount = form.querySelector('#valDummyChapterCount').value;
config.ChapterImageResolution = form.querySelector('#txtChapterImageResolution').value;
ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
});
return false;
}
function getTabs() {
return [{
href: '#/library.html',
name: globalize.translate('HeaderLibraries')
}, {
href: '#/librarydisplay.html',
name: globalize.translate('Display')
}, {
href: '#/metadataimages.html',
name: globalize.translate('Metadata')
}, {
href: '#/metadatanfo.html',
name: globalize.translate('TabNfoSettings')
}];
}
$(document).on('pageinit', '#metadataImagesConfigurationPage', function() {
$('.metadataImagesConfigurationForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#metadataImagesConfigurationPage', function() {
libraryMenu.setTabs('metadata', 2, getTabs);
loading.show();
loadPage(this);
});
/* eslint-enable indent */

View file

@ -6,74 +6,71 @@ import globalize from '../../scripts/globalize';
import Dashboard from '../../utils/dashboard';
import alert from '../../components/alert';
/* eslint-disable indent */
function loadPage(page, config, users) {
let html = '<option value="" selected="selected">' + globalize.translate('None') + '</option>';
html += users.map(function (user) {
return '<option value="' + user.Id + '">' + escapeHtml(user.Name) + '</option>';
}).join('');
$('#selectUser', page).html(html).val(config.UserId || '');
$('#selectReleaseDateFormat', page).val(config.ReleaseDateFormat);
page.querySelector('#chkSaveImagePaths').checked = config.SaveImagePathsInNfo;
page.querySelector('#chkEnablePathSubstitution').checked = config.EnablePathSubstitution;
page.querySelector('#chkEnableExtraThumbs').checked = config.EnableExtraThumbsDuplication;
loading.hide();
}
function loadPage(page, config, users) {
let html = '<option value="" selected="selected">' + globalize.translate('None') + '</option>';
html += users.map(function (user) {
return '<option value="' + user.Id + '">' + escapeHtml(user.Name) + '</option>';
}).join('');
$('#selectUser', page).html(html).val(config.UserId || '');
$('#selectReleaseDateFormat', page).val(config.ReleaseDateFormat);
page.querySelector('#chkSaveImagePaths').checked = config.SaveImagePathsInNfo;
page.querySelector('#chkEnablePathSubstitution').checked = config.EnablePathSubstitution;
page.querySelector('#chkEnableExtraThumbs').checked = config.EnableExtraThumbsDuplication;
loading.hide();
}
function onSubmit() {
loading.show();
const form = this;
ApiClient.getNamedConfiguration(metadataKey).then(function (config) {
config.UserId = $('#selectUser', form).val() || null;
config.ReleaseDateFormat = $('#selectReleaseDateFormat', form).val();
config.SaveImagePathsInNfo = form.querySelector('#chkSaveImagePaths').checked;
config.EnablePathSubstitution = form.querySelector('#chkEnablePathSubstitution').checked;
config.EnableExtraThumbsDuplication = form.querySelector('#chkEnableExtraThumbs').checked;
ApiClient.updateNamedConfiguration(metadataKey, config).then(function () {
Dashboard.processServerConfigurationUpdateResult();
showConfirmMessage();
});
});
return false;
}
function showConfirmMessage() {
const msg = [];
msg.push(globalize.translate('MetadataSettingChangeHelp'));
alert({
text: msg.join('<br/><br/>')
});
}
function getTabs() {
return [{
href: '#/library.html',
name: globalize.translate('HeaderLibraries')
}, {
href: '#/librarydisplay.html',
name: globalize.translate('Display')
}, {
href: '#/metadataimages.html',
name: globalize.translate('Metadata')
}, {
href: '#/metadatanfo.html',
name: globalize.translate('TabNfoSettings')
}];
}
const metadataKey = 'xbmcmetadata';
$(document).on('pageinit', '#metadataNfoPage', function () {
$('.metadataNfoForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#metadataNfoPage', function () {
libraryMenu.setTabs('metadata', 3, getTabs);
loading.show();
const page = this;
const promise1 = ApiClient.getUsers();
const promise2 = ApiClient.getNamedConfiguration(metadataKey);
Promise.all([promise1, promise2]).then(function (responses) {
loadPage(page, responses[1], responses[0]);
function onSubmit() {
loading.show();
const form = this;
ApiClient.getNamedConfiguration(metadataKey).then(function (config) {
config.UserId = $('#selectUser', form).val() || null;
config.ReleaseDateFormat = $('#selectReleaseDateFormat', form).val();
config.SaveImagePathsInNfo = form.querySelector('#chkSaveImagePaths').checked;
config.EnablePathSubstitution = form.querySelector('#chkEnablePathSubstitution').checked;
config.EnableExtraThumbsDuplication = form.querySelector('#chkEnableExtraThumbs').checked;
ApiClient.updateNamedConfiguration(metadataKey, config).then(function () {
Dashboard.processServerConfigurationUpdateResult();
showConfirmMessage();
});
});
return false;
}
function showConfirmMessage() {
const msg = [];
msg.push(globalize.translate('MetadataSettingChangeHelp'));
alert({
text: msg.join('<br/><br/>')
});
}
function getTabs() {
return [{
href: '#/library.html',
name: globalize.translate('HeaderLibraries')
}, {
href: '#/librarydisplay.html',
name: globalize.translate('Display')
}, {
href: '#/metadataimages.html',
name: globalize.translate('Metadata')
}, {
href: '#/metadatanfo.html',
name: globalize.translate('TabNfoSettings')
}];
}
const metadataKey = 'xbmcmetadata';
$(document).on('pageinit', '#metadataNfoPage', function () {
$('.metadataNfoForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#metadataNfoPage', function () {
libraryMenu.setTabs('metadata', 3, getTabs);
loading.show();
const page = this;
const promise1 = ApiClient.getUsers();
const promise2 = ApiClient.getNamedConfiguration(metadataKey);
Promise.all([promise1, promise2]).then(function (responses) {
loadPage(page, responses[1], responses[0]);
});
});
/* eslint-enable indent */

View file

@ -5,205 +5,202 @@ import '../../elements/emby-select/emby-select';
import Dashboard from '../../utils/dashboard';
import alert from '../../components/alert';
/* eslint-disable indent */
function onSubmit(e) {
const form = this;
const localAddress = form.querySelector('#txtLocalAddress').value;
const enableUpnp = form.querySelector('#chkEnableUpnp').checked;
confirmSelections(localAddress, enableUpnp, function () {
const validationResult = getValidationAlert(form);
function onSubmit(e) {
const form = this;
const localAddress = form.querySelector('#txtLocalAddress').value;
const enableUpnp = form.querySelector('#chkEnableUpnp').checked;
confirmSelections(localAddress, enableUpnp, function () {
const validationResult = getValidationAlert(form);
if (validationResult) {
showAlertText(validationResult);
return;
}
validateHttps(form).then(function () {
loading.show();
ApiClient.getNamedConfiguration('network').then(function (config) {
config.LocalNetworkSubnets = form.querySelector('#txtLanNetworks').value.split(',').map(function (s) {
return s.trim();
}).filter(function (s) {
return s.length > 0;
});
config.RemoteIPFilter = form.querySelector('#txtExternalAddressFilter').value.split(',').map(function (s) {
return s.trim();
}).filter(function (s) {
return s.length > 0;
});
config.KnownProxies = form.querySelector('#txtKnownProxies').value.split(',').map(function (s) {
return s.trim();
}).filter(function (s) {
return s.length > 0;
});
config.LocalNetworkAddresses = form.querySelector('#txtLocalAddress').value.split(',').map(function (s) {
return s.trim();
}).filter(function (s) {
return s.length > 0;
});
config.PublishedServerUriBySubnet = form.querySelector('#txtPublishedServer').value.split(',').map(function (s) {
return s.trim();
}).filter(function (s) {
return s.length > 0;
});
config.IsRemoteIPFilterBlacklist = form.querySelector('#selectExternalAddressFilterMode').value === 'blacklist';
config.PublicPort = form.querySelector('#txtPublicPort').value;
config.PublicHttpsPort = form.querySelector('#txtPublicHttpsPort').value;
config.HttpServerPortNumber = form.querySelector('#txtPortNumber').value;
config.HttpsPortNumber = form.querySelector('#txtHttpsPort').value;
config.EnableHttps = form.querySelector('#chkEnableHttps').checked;
config.RequireHttps = form.querySelector('#chkRequireHttps').checked;
config.EnableUPnP = enableUpnp;
config.BaseUrl = form.querySelector('#txtBaseUrl').value;
config.EnableRemoteAccess = form.querySelector('#chkRemoteAccess').checked;
config.CertificatePath = form.querySelector('#txtCertificatePath').value || null;
config.CertificatePassword = form.querySelector('#txtCertPassword').value || null;
config.UPnPCreateHttpPortMap = form.querySelector('#chkCreateHttpPortMap').checked;
config.AutoDiscovery = form.querySelector('#chkAutodiscovery').checked;
config.AutoDiscoveryTracing = form.querySelector('#chkAutodiscoveryTracing').checked;
config.EnableIPV6 = form.querySelector('#chkEnableIP6').checked;
config.EnableIPV4 = form.querySelector('#chkEnableIP4').checked;
config.UPnPCreateHttpPortMap = form.querySelector('#chkCreateHttpPortMap').checked;
config.UDPPortRange = form.querySelector('#txtUDPPortRange').value;
config.HDHomerunPortRange = form.querySelector('#txtHDHomerunPortRange').value;
config.EnableSSDPTracing = form.querySelector('#chkEnableSSDPTracing').checked;
config.SSDPTracingFilter = form.querySelector('#txtSSDPTracingFilter').value;
ApiClient.updateNamedConfiguration('network', config).then(Dashboard.processServerConfigurationUpdateResult, Dashboard.processErrorResponse);
});
});
});
e.preventDefault();
}
function triggerChange(select) {
const evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
select.dispatchEvent(evt);
}
function getValidationAlert(form) {
if (form.querySelector('#txtPublicPort').value === form.querySelector('#txtPublicHttpsPort').value) {
return 'The public http and https ports must be different.';
if (validationResult) {
showAlertText(validationResult);
return;
}
if (form.querySelector('#txtPortNumber').value === form.querySelector('#txtHttpsPort').value) {
return 'The http and https ports must be different.';
}
if (!form.querySelector('#chkEnableIP6').checked && !form.querySelector('#chkEnableIP4').checked) {
return 'Either IPv4 or IPv6 need to be checked.';
}
return null;
}
function validateHttps(form) {
const certPath = form.querySelector('#txtCertificatePath').value || null;
const httpsEnabled = form.querySelector('#chkEnableHttps').checked;
if (httpsEnabled && !certPath) {
return showAlertText({
title: globalize.translate('TitleHostingSettings'),
text: globalize.translate('HttpsRequiresCert')
}).then(Promise.reject);
}
return Promise.resolve();
}
function showAlertText(options) {
return new Promise(function (resolve, reject) {
alert(options).then(resolve, reject);
});
}
function confirmSelections(localAddress, enableUpnp, callback) {
if (localAddress || !enableUpnp) {
showAlertText({
title: globalize.translate('TitleHostingSettings'),
text: globalize.translate('SettingsWarning')
}).then(callback);
} else {
callback();
}
}
export default function (view) {
function loadPage(page, config) {
page.querySelector('#txtPortNumber').value = config.HttpServerPortNumber;
page.querySelector('#txtPublicPort').value = config.PublicPort;
page.querySelector('#txtPublicHttpsPort').value = config.PublicHttpsPort;
page.querySelector('#txtLocalAddress').value = (config.LocalNetworkAddresses || []).join(', ');
page.querySelector('#txtLanNetworks').value = (config.LocalNetworkSubnets || []).join(', ');
page.querySelector('#txtKnownProxies').value = (config.KnownProxies || []).join(', ');
page.querySelector('#txtExternalAddressFilter').value = (config.RemoteIPFilter || []).join(', ');
page.querySelector('#selectExternalAddressFilterMode').value = config.IsRemoteIPFilterBlacklist ? 'blacklist' : 'whitelist';
page.querySelector('#chkRemoteAccess').checked = config.EnableRemoteAccess == null || config.EnableRemoteAccess;
page.querySelector('#txtHttpsPort').value = config.HttpsPortNumber;
page.querySelector('#chkEnableHttps').checked = config.EnableHttps;
page.querySelector('#chkRequireHttps').checked = config.RequireHttps;
page.querySelector('#txtBaseUrl').value = config.BaseUrl || '';
const txtCertificatePath = page.querySelector('#txtCertificatePath');
txtCertificatePath.value = config.CertificatePath || '';
page.querySelector('#txtCertPassword').value = config.CertificatePassword || '';
page.querySelector('#chkEnableUpnp').checked = config.EnableUPnP;
triggerChange(page.querySelector('#chkRemoteAccess'));
page.querySelector('#chkCreateHttpPortMap').checked = config.UPnPCreateHttpPortMap;
page.querySelector('#chkAutodiscovery').checked = config.AutoDiscovery;
page.querySelector('#chkAutodiscoveryTracing').checked = config.AutoDiscoveryTracing;
page.querySelector('#chkEnableIP6').checked = config.EnableIPV6;
page.querySelector('#chkEnableIP4').checked = config.EnableIPV4;
page.querySelector('#chkCreateHttpPortMap').checked = config.UPnPCreateHttpPortMap;
page.querySelector('#txtUDPPortRange').value = config.UDPPortRange || '';
page.querySelector('#txtHDHomerunPortRange').checked = config.HDHomerunPortRange || '';
page.querySelector('#chkEnableSSDPTracing').checked = config.EnableSSDPTracing;
page.querySelector('#txtSSDPTracingFilter').value = config.SSDPTracingFilter || '';
page.querySelector('#txtPublishedServer').value = (config.PublishedServerUriBySubnet || []).join(', ');
loading.hide();
}
view.querySelector('#chkRemoteAccess').addEventListener('change', function () {
if (this.checked) {
view.querySelector('.fldExternalAddressFilter').classList.remove('hide');
view.querySelector('.fldExternalAddressFilterMode').classList.remove('hide');
view.querySelector('.fldPublicPort').classList.remove('hide');
view.querySelector('.fldPublicHttpsPort').classList.remove('hide');
view.querySelector('.fldEnableUpnp').classList.remove('hide');
} else {
view.querySelector('.fldExternalAddressFilter').classList.add('hide');
view.querySelector('.fldExternalAddressFilterMode').classList.add('hide');
view.querySelector('.fldPublicPort').classList.add('hide');
view.querySelector('.fldPublicHttpsPort').classList.add('hide');
view.querySelector('.fldEnableUpnp').classList.add('hide');
}
});
view.querySelector('#btnSelectCertPath').addEventListener('click', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
includeFiles: true,
includeDirectories: true,
callback: function (path) {
if (path) {
view.querySelector('#txtCertificatePath').value = path;
}
picker.close();
},
header: globalize.translate('HeaderSelectCertificatePath')
});
});
});
view.querySelector('.dashboardHostingForm').addEventListener('submit', onSubmit);
view.addEventListener('viewshow', function () {
validateHttps(form).then(function () {
loading.show();
ApiClient.getNamedConfiguration('network').then(function (config) {
loadPage(view, config);
config.LocalNetworkSubnets = form.querySelector('#txtLanNetworks').value.split(',').map(function (s) {
return s.trim();
}).filter(function (s) {
return s.length > 0;
});
config.RemoteIPFilter = form.querySelector('#txtExternalAddressFilter').value.split(',').map(function (s) {
return s.trim();
}).filter(function (s) {
return s.length > 0;
});
config.KnownProxies = form.querySelector('#txtKnownProxies').value.split(',').map(function (s) {
return s.trim();
}).filter(function (s) {
return s.length > 0;
});
config.LocalNetworkAddresses = form.querySelector('#txtLocalAddress').value.split(',').map(function (s) {
return s.trim();
}).filter(function (s) {
return s.length > 0;
});
config.PublishedServerUriBySubnet = form.querySelector('#txtPublishedServer').value.split(',').map(function (s) {
return s.trim();
}).filter(function (s) {
return s.length > 0;
});
config.IsRemoteIPFilterBlacklist = form.querySelector('#selectExternalAddressFilterMode').value === 'blacklist';
config.PublicPort = form.querySelector('#txtPublicPort').value;
config.PublicHttpsPort = form.querySelector('#txtPublicHttpsPort').value;
config.HttpServerPortNumber = form.querySelector('#txtPortNumber').value;
config.HttpsPortNumber = form.querySelector('#txtHttpsPort').value;
config.EnableHttps = form.querySelector('#chkEnableHttps').checked;
config.RequireHttps = form.querySelector('#chkRequireHttps').checked;
config.EnableUPnP = enableUpnp;
config.BaseUrl = form.querySelector('#txtBaseUrl').value;
config.EnableRemoteAccess = form.querySelector('#chkRemoteAccess').checked;
config.CertificatePath = form.querySelector('#txtCertificatePath').value || null;
config.CertificatePassword = form.querySelector('#txtCertPassword').value || null;
config.UPnPCreateHttpPortMap = form.querySelector('#chkCreateHttpPortMap').checked;
config.AutoDiscovery = form.querySelector('#chkAutodiscovery').checked;
config.AutoDiscoveryTracing = form.querySelector('#chkAutodiscoveryTracing').checked;
config.EnableIPV6 = form.querySelector('#chkEnableIP6').checked;
config.EnableIPV4 = form.querySelector('#chkEnableIP4').checked;
config.UPnPCreateHttpPortMap = form.querySelector('#chkCreateHttpPortMap').checked;
config.UDPPortRange = form.querySelector('#txtUDPPortRange').value;
config.HDHomerunPortRange = form.querySelector('#txtHDHomerunPortRange').value;
config.EnableSSDPTracing = form.querySelector('#chkEnableSSDPTracing').checked;
config.SSDPTracingFilter = form.querySelector('#txtSSDPTracingFilter').value;
ApiClient.updateNamedConfiguration('network', config).then(Dashboard.processServerConfigurationUpdateResult, Dashboard.processErrorResponse);
});
});
});
e.preventDefault();
}
function triggerChange(select) {
const evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
select.dispatchEvent(evt);
}
function getValidationAlert(form) {
if (form.querySelector('#txtPublicPort').value === form.querySelector('#txtPublicHttpsPort').value) {
return 'The public http and https ports must be different.';
}
/* eslint-enable indent */
if (form.querySelector('#txtPortNumber').value === form.querySelector('#txtHttpsPort').value) {
return 'The http and https ports must be different.';
}
if (!form.querySelector('#chkEnableIP6').checked && !form.querySelector('#chkEnableIP4').checked) {
return 'Either IPv4 or IPv6 need to be checked.';
}
return null;
}
function validateHttps(form) {
const certPath = form.querySelector('#txtCertificatePath').value || null;
const httpsEnabled = form.querySelector('#chkEnableHttps').checked;
if (httpsEnabled && !certPath) {
return showAlertText({
title: globalize.translate('TitleHostingSettings'),
text: globalize.translate('HttpsRequiresCert')
}).then(Promise.reject);
}
return Promise.resolve();
}
function showAlertText(options) {
return new Promise(function (resolve, reject) {
alert(options).then(resolve, reject);
});
}
function confirmSelections(localAddress, enableUpnp, callback) {
if (localAddress || !enableUpnp) {
showAlertText({
title: globalize.translate('TitleHostingSettings'),
text: globalize.translate('SettingsWarning')
}).then(callback);
} else {
callback();
}
}
export default function (view) {
function loadPage(page, config) {
page.querySelector('#txtPortNumber').value = config.HttpServerPortNumber;
page.querySelector('#txtPublicPort').value = config.PublicPort;
page.querySelector('#txtPublicHttpsPort').value = config.PublicHttpsPort;
page.querySelector('#txtLocalAddress').value = (config.LocalNetworkAddresses || []).join(', ');
page.querySelector('#txtLanNetworks').value = (config.LocalNetworkSubnets || []).join(', ');
page.querySelector('#txtKnownProxies').value = (config.KnownProxies || []).join(', ');
page.querySelector('#txtExternalAddressFilter').value = (config.RemoteIPFilter || []).join(', ');
page.querySelector('#selectExternalAddressFilterMode').value = config.IsRemoteIPFilterBlacklist ? 'blacklist' : 'whitelist';
page.querySelector('#chkRemoteAccess').checked = config.EnableRemoteAccess == null || config.EnableRemoteAccess;
page.querySelector('#txtHttpsPort').value = config.HttpsPortNumber;
page.querySelector('#chkEnableHttps').checked = config.EnableHttps;
page.querySelector('#chkRequireHttps').checked = config.RequireHttps;
page.querySelector('#txtBaseUrl').value = config.BaseUrl || '';
const txtCertificatePath = page.querySelector('#txtCertificatePath');
txtCertificatePath.value = config.CertificatePath || '';
page.querySelector('#txtCertPassword').value = config.CertificatePassword || '';
page.querySelector('#chkEnableUpnp').checked = config.EnableUPnP;
triggerChange(page.querySelector('#chkRemoteAccess'));
page.querySelector('#chkCreateHttpPortMap').checked = config.UPnPCreateHttpPortMap;
page.querySelector('#chkAutodiscovery').checked = config.AutoDiscovery;
page.querySelector('#chkAutodiscoveryTracing').checked = config.AutoDiscoveryTracing;
page.querySelector('#chkEnableIP6').checked = config.EnableIPV6;
page.querySelector('#chkEnableIP4').checked = config.EnableIPV4;
page.querySelector('#chkCreateHttpPortMap').checked = config.UPnPCreateHttpPortMap;
page.querySelector('#txtUDPPortRange').value = config.UDPPortRange || '';
page.querySelector('#txtHDHomerunPortRange').checked = config.HDHomerunPortRange || '';
page.querySelector('#chkEnableSSDPTracing').checked = config.EnableSSDPTracing;
page.querySelector('#txtSSDPTracingFilter').value = config.SSDPTracingFilter || '';
page.querySelector('#txtPublishedServer').value = (config.PublishedServerUriBySubnet || []).join(', ');
loading.hide();
}
view.querySelector('#chkRemoteAccess').addEventListener('change', function () {
if (this.checked) {
view.querySelector('.fldExternalAddressFilter').classList.remove('hide');
view.querySelector('.fldExternalAddressFilterMode').classList.remove('hide');
view.querySelector('.fldPublicPort').classList.remove('hide');
view.querySelector('.fldPublicHttpsPort').classList.remove('hide');
view.querySelector('.fldEnableUpnp').classList.remove('hide');
} else {
view.querySelector('.fldExternalAddressFilter').classList.add('hide');
view.querySelector('.fldExternalAddressFilterMode').classList.add('hide');
view.querySelector('.fldPublicPort').classList.add('hide');
view.querySelector('.fldPublicHttpsPort').classList.add('hide');
view.querySelector('.fldEnableUpnp').classList.add('hide');
}
});
view.querySelector('#btnSelectCertPath').addEventListener('click', function () {
import('../../components/directorybrowser/directorybrowser').then(({ default: DirectoryBrowser }) => {
const picker = new DirectoryBrowser();
picker.show({
includeFiles: true,
includeDirectories: true,
callback: function (path) {
if (path) {
view.querySelector('#txtCertificatePath').value = path;
}
picker.close();
},
header: globalize.translate('HeaderSelectCertificatePath')
});
});
});
view.querySelector('.dashboardHostingForm').addEventListener('submit', onSubmit);
view.addEventListener('viewshow', function () {
loading.show();
ApiClient.getNamedConfiguration('network').then(function (config) {
loadPage(view, config);
});
});
}

View file

@ -4,55 +4,52 @@ import libraryMenu from '../../scripts/libraryMenu';
import globalize from '../../scripts/globalize';
import Dashboard from '../../utils/dashboard';
/* eslint-disable indent */
function loadPage(page, config) {
$('#txtMinResumePct', page).val(config.MinResumePct);
$('#txtMaxResumePct', page).val(config.MaxResumePct);
$('#txtMinAudiobookResume', page).val(config.MinAudiobookResume);
$('#txtMaxAudiobookResume', page).val(config.MaxAudiobookResume);
$('#txtMinResumeDuration', page).val(config.MinResumeDurationSeconds);
loading.hide();
}
function loadPage(page, config) {
$('#txtMinResumePct', page).val(config.MinResumePct);
$('#txtMaxResumePct', page).val(config.MaxResumePct);
$('#txtMinAudiobookResume', page).val(config.MinAudiobookResume);
$('#txtMaxAudiobookResume', page).val(config.MaxAudiobookResume);
$('#txtMinResumeDuration', page).val(config.MinResumeDurationSeconds);
loading.hide();
}
function onSubmit() {
loading.show();
const form = this;
ApiClient.getServerConfiguration().then(function (config) {
config.MinResumePct = $('#txtMinResumePct', form).val();
config.MaxResumePct = $('#txtMaxResumePct', form).val();
config.MinAudiobookResume = $('#txtMinAudiobookResume', form).val();
config.MaxAudiobookResume = $('#txtMaxAudiobookResume', form).val();
config.MinResumeDurationSeconds = $('#txtMinResumeDuration', form).val();
function onSubmit() {
loading.show();
const form = this;
ApiClient.getServerConfiguration().then(function (config) {
config.MinResumePct = $('#txtMinResumePct', form).val();
config.MaxResumePct = $('#txtMaxResumePct', form).val();
config.MinAudiobookResume = $('#txtMinAudiobookResume', form).val();
config.MaxAudiobookResume = $('#txtMaxAudiobookResume', form).val();
config.MinResumeDurationSeconds = $('#txtMinResumeDuration', form).val();
ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
});
return false;
}
function getTabs() {
return [{
href: '#/encodingsettings.html',
name: globalize.translate('Transcoding')
}, {
href: '#/playbackconfiguration.html',
name: globalize.translate('ButtonResume')
}, {
href: '#/streamingsettings.html',
name: globalize.translate('TabStreaming')
}];
}
$(document).on('pageinit', '#playbackConfigurationPage', function () {
$('.playbackConfigurationForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#playbackConfigurationPage', function () {
loading.show();
libraryMenu.setTabs('playback', 1, getTabs);
const page = this;
ApiClient.getServerConfiguration().then(function (config) {
loadPage(page, config);
});
ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
});
/* eslint-enable indent */
return false;
}
function getTabs() {
return [{
href: '#/encodingsettings.html',
name: globalize.translate('Transcoding')
}, {
href: '#/playbackconfiguration.html',
name: globalize.translate('ButtonResume')
}, {
href: '#/streamingsettings.html',
name: globalize.translate('TabStreaming')
}];
}
$(document).on('pageinit', '#playbackConfigurationPage', function () {
$('.playbackConfigurationForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#playbackConfigurationPage', function () {
loading.show();
libraryMenu.setTabs('playback', 1, getTabs);
const page = this;
ApiClient.getServerConfiguration().then(function (config) {
loadPage(page, config);
});
});

View file

@ -9,238 +9,235 @@ import '../../../elements/emby-select/emby-select';
import confirm from '../../../components/confirm/confirm';
import { getParameterByName } from '../../../utils/url.ts';
/* eslint-disable indent */
function fillTimeOfDay(select) {
const options = [];
function fillTimeOfDay(select) {
const options = [];
for (let i = 0; i < 86400000; i += 900000) {
options.push({
name: ScheduledTaskPage.getDisplayTime(i * 10000),
value: i * 10000
});
}
select.innerHTML = options.map(function (o) {
return '<option value="' + o.value + '">' + o.name + '</option>';
}).join('');
for (let i = 0; i < 86400000; i += 900000) {
options.push({
name: ScheduledTaskPage.getDisplayTime(i * 10000),
value: i * 10000
});
}
Array.prototype.remove = function (from, to) {
const rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
select.innerHTML = options.map(function (o) {
return '<option value="' + o.value + '">' + o.name + '</option>';
}).join('');
}
const ScheduledTaskPage = {
refreshScheduledTask: function (view) {
loading.show();
const id = getParameterByName('id');
ApiClient.getScheduledTask(id).then(function (task) {
ScheduledTaskPage.loadScheduledTask(view, task);
});
},
loadScheduledTask: function (view, task) {
$('.taskName', view).html(task.Name);
$('#pTaskDescription', view).html(task.Description);
Array.prototype.remove = function (from, to) {
const rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
import('../../../components/listview/listview.scss').then(() => {
ScheduledTaskPage.loadTaskTriggers(view, task);
});
const ScheduledTaskPage = {
refreshScheduledTask: function (view) {
loading.show();
const id = getParameterByName('id');
ApiClient.getScheduledTask(id).then(function (task) {
ScheduledTaskPage.loadScheduledTask(view, task);
});
},
loadScheduledTask: function (view, task) {
$('.taskName', view).html(task.Name);
$('#pTaskDescription', view).html(task.Description);
loading.hide();
},
loadTaskTriggers: function (context, task) {
let html = '';
html += '<div class="paperList">';
import('../../../components/listview/listview.scss').then(() => {
ScheduledTaskPage.loadTaskTriggers(view, task);
});
for (let i = 0, length = task.Triggers.length; i < length; i++) {
const trigger = task.Triggers[i];
loading.hide();
},
loadTaskTriggers: function (context, task) {
let html = '';
html += '<div class="paperList">';
html += '<div class="listItem listItem-border">';
html += '<span class="material-icons listItemIcon schedule" aria-hidden="true"></span>';
if (trigger.MaxRuntimeMs) {
html += '<div class="listItemBody two-line">';
for (let i = 0, length = task.Triggers.length; i < length; i++) {
const trigger = task.Triggers[i];
html += '<div class="listItem listItem-border">';
html += '<span class="material-icons listItemIcon schedule" aria-hidden="true"></span>';
if (trigger.MaxRuntimeMs) {
html += '<div class="listItemBody two-line">';
} else {
html += '<div class="listItemBody">';
}
html += "<div class='listItemBodyText'>" + ScheduledTaskPage.getTriggerFriendlyName(trigger) + '</div>';
if (trigger.MaxRuntimeMs) {
html += '<div class="listItemBodyText secondary">';
const hours = trigger.MaxRuntimeTicks / 36e9;
if (hours == 1) {
html += globalize.translate('ValueTimeLimitSingleHour');
} else {
html += '<div class="listItemBody">';
html += globalize.translate('ValueTimeLimitMultiHour', hours);
}
html += "<div class='listItemBodyText'>" + ScheduledTaskPage.getTriggerFriendlyName(trigger) + '</div>';
if (trigger.MaxRuntimeMs) {
html += '<div class="listItemBodyText secondary">';
const hours = trigger.MaxRuntimeTicks / 36e9;
if (hours == 1) {
html += globalize.translate('ValueTimeLimitSingleHour');
} else {
html += globalize.translate('ValueTimeLimitMultiHour', hours);
}
html += '</div>';
}
html += '</div>';
html += '<button class="btnDeleteTrigger" data-index="' + i + '" type="button" is="paper-icon-button-light" title="' + globalize.translate('Delete') + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
html += '</div>';
}
html += '</div>';
context.querySelector('.taskTriggers').innerHTML = html;
},
// TODO: Replace this mess with date-fns and remove datetime completely
getTriggerFriendlyName: function (trigger) {
if (trigger.Type == 'DailyTrigger') {
return globalize.translate('DailyAt', ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks));
}
if (trigger.Type == 'WeeklyTrigger') {
// TODO: The day of week isn't localised as well
return globalize.translate('WeeklyAt', trigger.DayOfWeek, ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks));
}
if (trigger.Type == 'SystemEventTrigger' && trigger.SystemEvent == 'WakeFromSleep') {
return globalize.translate('OnWakeFromSleep');
}
if (trigger.Type == 'IntervalTrigger') {
const hours = trigger.IntervalTicks / 36e9;
if (hours == 0.25) {
return globalize.translate('EveryXMinutes', '15');
}
if (hours == 0.5) {
return globalize.translate('EveryXMinutes', '30');
}
if (hours == 0.75) {
return globalize.translate('EveryXMinutes', '45');
}
if (hours == 1) {
return globalize.translate('EveryHour');
}
return globalize.translate('EveryXHours', hours);
}
if (trigger.Type == 'StartupTrigger') {
return globalize.translate('OnApplicationStartup');
}
return trigger.Type;
},
getDisplayTime: function (ticks) {
const ms = ticks / 1e4;
const now = new Date();
now.setHours(0, 0, 0, 0);
now.setTime(now.getTime() + ms);
return datetime.getDisplayTime(now);
},
showAddTriggerPopup: function (view) {
$('#selectTriggerType', view).val('DailyTrigger');
view.querySelector('#selectTriggerType').dispatchEvent(new CustomEvent('change', {}));
$('#popupAddTrigger', view).removeClass('hide');
},
confirmDeleteTrigger: function (view, index) {
confirm(globalize.translate('MessageDeleteTaskTrigger'), globalize.translate('HeaderDeleteTaskTrigger')).then(function () {
ScheduledTaskPage.deleteTrigger(view, index);
});
},
deleteTrigger: function (view, index) {
loading.show();
const id = getParameterByName('id');
ApiClient.getScheduledTask(id).then(function (task) {
task.Triggers.remove(index);
ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).then(function () {
ScheduledTaskPage.refreshScheduledTask(view);
});
});
},
refreshTriggerFields: function (page, triggerType) {
if (triggerType == 'DailyTrigger') {
$('#fldTimeOfDay', page).show();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).hide();
$('#selectTimeOfDay', page).attr('required', 'required');
} else if (triggerType == 'WeeklyTrigger') {
$('#fldTimeOfDay', page).show();
$('#fldDayOfWeek', page).show();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).hide();
$('#selectTimeOfDay', page).attr('required', 'required');
} else if (triggerType == 'SystemEventTrigger') {
$('#fldTimeOfDay', page).hide();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).show();
$('#fldSelectInterval', page).hide();
$('#selectTimeOfDay', page).removeAttr('required');
} else if (triggerType == 'IntervalTrigger') {
$('#fldTimeOfDay', page).hide();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).show();
$('#selectTimeOfDay', page).removeAttr('required');
} else if (triggerType == 'StartupTrigger') {
$('#fldTimeOfDay', page).hide();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).hide();
$('#selectTimeOfDay', page).removeAttr('required');
}
},
getTriggerToAdd: function (page) {
const trigger = {
Type: $('#selectTriggerType', page).val()
};
if (trigger.Type == 'DailyTrigger') {
trigger.TimeOfDayTicks = $('#selectTimeOfDay', page).val();
} else if (trigger.Type == 'WeeklyTrigger') {
trigger.DayOfWeek = $('#selectDayOfWeek', page).val();
trigger.TimeOfDayTicks = $('#selectTimeOfDay', page).val();
} else if (trigger.Type == 'SystemEventTrigger') {
trigger.SystemEvent = $('#selectSystemEvent', page).val();
} else if (trigger.Type == 'IntervalTrigger') {
trigger.IntervalTicks = $('#selectInterval', page).val();
}
let timeLimit = $('#txtTimeLimit', page).val() || '0';
timeLimit = parseFloat(timeLimit) * 3600000;
trigger.MaxRuntimeMs = timeLimit || null;
return trigger;
}
};
export default function (view) {
function onSubmit(e) {
loading.show();
const id = getParameterByName('id');
ApiClient.getScheduledTask(id).then(function (task) {
task.Triggers.push(ScheduledTaskPage.getTriggerToAdd(view));
ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).then(function () {
$('#popupAddTrigger').addClass('hide');
ScheduledTaskPage.refreshScheduledTask(view);
});
});
e.preventDefault();
html += '<button class="btnDeleteTrigger" data-index="' + i + '" type="button" is="paper-icon-button-light" title="' + globalize.translate('Delete') + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
html += '</div>';
}
view.querySelector('.addTriggerForm').addEventListener('submit', onSubmit);
fillTimeOfDay(view.querySelector('#selectTimeOfDay'));
$(view.querySelector('#popupAddTrigger').parentNode).trigger('create');
view.querySelector('.selectTriggerType').addEventListener('change', function () {
ScheduledTaskPage.refreshTriggerFields(view, this.value);
});
view.querySelector('.btnAddTrigger').addEventListener('click', function () {
ScheduledTaskPage.showAddTriggerPopup(view);
});
view.addEventListener('click', function (e) {
const btnDeleteTrigger = dom.parentWithClass(e.target, 'btnDeleteTrigger');
html += '</div>';
context.querySelector('.taskTriggers').innerHTML = html;
},
// TODO: Replace this mess with date-fns and remove datetime completely
getTriggerFriendlyName: function (trigger) {
if (trigger.Type == 'DailyTrigger') {
return globalize.translate('DailyAt', ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks));
}
if (btnDeleteTrigger) {
ScheduledTaskPage.confirmDeleteTrigger(view, parseInt(btnDeleteTrigger.getAttribute('data-index'), 10));
if (trigger.Type == 'WeeklyTrigger') {
// TODO: The day of week isn't localised as well
return globalize.translate('WeeklyAt', trigger.DayOfWeek, ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks));
}
if (trigger.Type == 'SystemEventTrigger' && trigger.SystemEvent == 'WakeFromSleep') {
return globalize.translate('OnWakeFromSleep');
}
if (trigger.Type == 'IntervalTrigger') {
const hours = trigger.IntervalTicks / 36e9;
if (hours == 0.25) {
return globalize.translate('EveryXMinutes', '15');
}
if (hours == 0.5) {
return globalize.translate('EveryXMinutes', '30');
}
if (hours == 0.75) {
return globalize.translate('EveryXMinutes', '45');
}
if (hours == 1) {
return globalize.translate('EveryHour');
}
return globalize.translate('EveryXHours', hours);
}
if (trigger.Type == 'StartupTrigger') {
return globalize.translate('OnApplicationStartup');
}
return trigger.Type;
},
getDisplayTime: function (ticks) {
const ms = ticks / 1e4;
const now = new Date();
now.setHours(0, 0, 0, 0);
now.setTime(now.getTime() + ms);
return datetime.getDisplayTime(now);
},
showAddTriggerPopup: function (view) {
$('#selectTriggerType', view).val('DailyTrigger');
view.querySelector('#selectTriggerType').dispatchEvent(new CustomEvent('change', {}));
$('#popupAddTrigger', view).removeClass('hide');
},
confirmDeleteTrigger: function (view, index) {
confirm(globalize.translate('MessageDeleteTaskTrigger'), globalize.translate('HeaderDeleteTaskTrigger')).then(function () {
ScheduledTaskPage.deleteTrigger(view, index);
});
view.addEventListener('viewshow', function () {
ScheduledTaskPage.refreshScheduledTask(view);
},
deleteTrigger: function (view, index) {
loading.show();
const id = getParameterByName('id');
ApiClient.getScheduledTask(id).then(function (task) {
task.Triggers.remove(index);
ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).then(function () {
ScheduledTaskPage.refreshScheduledTask(view);
});
});
},
refreshTriggerFields: function (page, triggerType) {
if (triggerType == 'DailyTrigger') {
$('#fldTimeOfDay', page).show();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).hide();
$('#selectTimeOfDay', page).attr('required', 'required');
} else if (triggerType == 'WeeklyTrigger') {
$('#fldTimeOfDay', page).show();
$('#fldDayOfWeek', page).show();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).hide();
$('#selectTimeOfDay', page).attr('required', 'required');
} else if (triggerType == 'SystemEventTrigger') {
$('#fldTimeOfDay', page).hide();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).show();
$('#fldSelectInterval', page).hide();
$('#selectTimeOfDay', page).removeAttr('required');
} else if (triggerType == 'IntervalTrigger') {
$('#fldTimeOfDay', page).hide();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).show();
$('#selectTimeOfDay', page).removeAttr('required');
} else if (triggerType == 'StartupTrigger') {
$('#fldTimeOfDay', page).hide();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).hide();
$('#selectTimeOfDay', page).removeAttr('required');
}
},
getTriggerToAdd: function (page) {
const trigger = {
Type: $('#selectTriggerType', page).val()
};
if (trigger.Type == 'DailyTrigger') {
trigger.TimeOfDayTicks = $('#selectTimeOfDay', page).val();
} else if (trigger.Type == 'WeeklyTrigger') {
trigger.DayOfWeek = $('#selectDayOfWeek', page).val();
trigger.TimeOfDayTicks = $('#selectTimeOfDay', page).val();
} else if (trigger.Type == 'SystemEventTrigger') {
trigger.SystemEvent = $('#selectSystemEvent', page).val();
} else if (trigger.Type == 'IntervalTrigger') {
trigger.IntervalTicks = $('#selectInterval', page).val();
}
let timeLimit = $('#txtTimeLimit', page).val() || '0';
timeLimit = parseFloat(timeLimit) * 3600000;
trigger.MaxRuntimeMs = timeLimit || null;
return trigger;
}
};
export default function (view) {
function onSubmit(e) {
loading.show();
const id = getParameterByName('id');
ApiClient.getScheduledTask(id).then(function (task) {
task.Triggers.push(ScheduledTaskPage.getTriggerToAdd(view));
ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).then(function () {
$('#popupAddTrigger').addClass('hide');
ScheduledTaskPage.refreshScheduledTask(view);
});
});
e.preventDefault();
}
/* eslint-enable indent */
view.querySelector('.addTriggerForm').addEventListener('submit', onSubmit);
fillTimeOfDay(view.querySelector('#selectTimeOfDay'));
$(view.querySelector('#popupAddTrigger').parentNode).trigger('create');
view.querySelector('.selectTriggerType').addEventListener('change', function () {
ScheduledTaskPage.refreshTriggerFields(view, this.value);
});
view.querySelector('.btnAddTrigger').addEventListener('click', function () {
ScheduledTaskPage.showAddTriggerPopup(view);
});
view.addEventListener('click', function (e) {
const btnDeleteTrigger = dom.parentWithClass(e.target, 'btnDeleteTrigger');
if (btnDeleteTrigger) {
ScheduledTaskPage.confirmDeleteTrigger(view, parseInt(btnDeleteTrigger.getAttribute('data-index'), 10));
}
});
view.addEventListener('viewshow', function () {
ScheduledTaskPage.refreshScheduledTask(view);
});
}

View file

@ -9,194 +9,191 @@ import Events from '../../../utils/events.ts';
import '../../../components/listview/listview.scss';
import '../../../elements/emby-button/emby-button';
/* eslint-disable indent */
function reloadList(page) {
ApiClient.getScheduledTasks({
isHidden: false
}).then(function(tasks) {
populateList(page, tasks);
loading.hide();
});
}
function reloadList(page) {
ApiClient.getScheduledTasks({
isHidden: false
}).then(function(tasks) {
populateList(page, tasks);
loading.hide();
});
}
function populateList(page, tasks) {
tasks = tasks.sort(function(a, b) {
a = a.Category + ' ' + a.Name;
b = b.Category + ' ' + b.Name;
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
}
});
function populateList(page, tasks) {
tasks = tasks.sort(function(a, b) {
a = a.Category + ' ' + a.Name;
b = b.Category + ' ' + b.Name;
if (a > b) {
return 1;
} else if (a < b) {
return -1;
} else {
return 0;
let currentCategory;
let html = '';
for (let i = 0; i < tasks.length; i++) {
const task = tasks[i];
if (task.Category != currentCategory) {
currentCategory = task.Category;
if (currentCategory) {
html += '</div>';
html += '</div>';
}
});
html += '<div class="verticalSection verticalSection-extrabottompadding">';
html += '<div class="sectionTitleContainer" style="margin-bottom:1em;">';
html += '<h2 class="sectionTitle">';
html += currentCategory;
html += '</h2>';
if (i === 0) {
html += '<a is="emby-linkbutton" class="raised button-alt headerHelpButton" target="_blank" href="https://jellyfin.org/docs/general/server/tasks">' + globalize.translate('Help') + '</a>';
}
html += '</div>';
html += '<div class="paperList">';
}
html += '<div class="listItem listItem-border scheduledTaskPaperIconItem" data-status="' + task.State + '">';
html += "<a is='emby-linkbutton' style='margin:0;padding:0;' class='clearLink listItemIconContainer' href='scheduledtask.html?id=" + task.Id + "'>";
html += '<span class="material-icons listItemIcon schedule" aria-hidden="true"></span>';
html += '</a>';
html += '<div class="listItemBody two-line">';
let textAlignStyle = 'left';
if (globalize.getIsRTL())
textAlignStyle = 'right';
html += "<a class='clearLink' style='margin:0;padding:0;display:block;text-align:" + textAlignStyle + ";' is='emby-linkbutton' href='scheduledtask.html?id=" + task.Id + "'>";
html += "<h3 class='listItemBodyText'>" + task.Name + '</h3>';
html += "<div class='secondary listItemBodyText' id='taskProgress" + task.Id + "'>" + getTaskProgressHtml(task) + '</div>';
html += '</a>';
html += '</div>';
if (task.State === 'Running') {
html += '<button type="button" is="paper-icon-button-light" id="btnTask' + task.Id + '" class="btnStopTask" data-taskid="' + task.Id + '" title="' + globalize.translate('ButtonStop') + '"><span class="material-icons stop" aria-hidden="true"></span></button>';
} else if (task.State === 'Idle') {
html += '<button type="button" is="paper-icon-button-light" id="btnTask' + task.Id + '" class="btnStartTask" data-taskid="' + task.Id + '" title="' + globalize.translate('ButtonStart') + '"><span class="material-icons play_arrow" aria-hidden="true"></span></button>';
}
html += '</div>';
}
if (tasks.length) {
html += '</div>';
html += '</div>';
}
page.querySelector('.divScheduledTasks').innerHTML = html;
}
let currentCategory;
let html = '';
function getTaskProgressHtml(task) {
let html = '';
if (task.State === 'Idle') {
if (task.LastExecutionResult) {
const endtime = Date.parse(task.LastExecutionResult.EndTimeUtc);
const starttime = Date.parse(task.LastExecutionResult.StartTimeUtc);
html += globalize.translate('LabelScheduledTaskLastRan', formatDistanceToNow(endtime, getLocaleWithSuffix()),
formatDistance(starttime, endtime, { locale: getLocale() }));
if (task.LastExecutionResult.Status === 'Failed') {
html += " <span style='color:#FF0000;'>(" + globalize.translate('LabelFailed') + ')</span>';
} else if (task.LastExecutionResult.Status === 'Cancelled') {
html += " <span style='color:#0026FF;'>(" + globalize.translate('LabelCancelled') + ')</span>';
} else if (task.LastExecutionResult.Status === 'Aborted') {
html += " <span style='color:#FF0000;'>" + globalize.translate('LabelAbortedByServerShutdown') + '</span>';
}
}
} else if (task.State === 'Running') {
const progress = (task.CurrentProgressPercentage || 0).toFixed(1);
html += '<div style="display:flex;align-items:center;">';
html += '<div class="taskProgressOuter" title="' + progress + '%" style="flex-grow:1;">';
html += '<div class="taskProgressInner" style="width:' + progress + '%;">';
html += '</div>';
html += '</div>';
html += "<span style='color:#00a4dc;margin-left:5px;'>" + progress + '%</span>';
html += '</div>';
} else {
html += "<span style='color:#FF0000;'>" + globalize.translate('LabelStopping') + '</span>';
}
return html;
}
function setTaskButtonIcon(button, icon) {
const inner = button.querySelector('.material-icons');
inner.classList.remove('stop', 'play_arrow');
inner.classList.add(icon);
}
function updateTaskButton(elem, state) {
if (state === 'Running') {
elem.classList.remove('btnStartTask');
elem.classList.add('btnStopTask');
setTaskButtonIcon(elem, 'stop');
elem.title = globalize.translate('ButtonStop');
} else if (state === 'Idle') {
elem.classList.add('btnStartTask');
elem.classList.remove('btnStopTask');
setTaskButtonIcon(elem, 'play_arrow');
elem.title = globalize.translate('ButtonStart');
}
$(elem).parents('.listItem')[0].setAttribute('data-status', state);
}
export default function(view) {
function updateTasks(tasks) {
for (let i = 0; i < tasks.length; i++) {
const task = tasks[i];
if (task.Category != currentCategory) {
currentCategory = task.Category;
if (currentCategory) {
html += '</div>';
html += '</div>';
}
html += '<div class="verticalSection verticalSection-extrabottompadding">';
html += '<div class="sectionTitleContainer" style="margin-bottom:1em;">';
html += '<h2 class="sectionTitle">';
html += currentCategory;
html += '</h2>';
if (i === 0) {
html += '<a is="emby-linkbutton" class="raised button-alt headerHelpButton" target="_blank" href="https://jellyfin.org/docs/general/server/tasks">' + globalize.translate('Help') + '</a>';
}
html += '</div>';
html += '<div class="paperList">';
}
html += '<div class="listItem listItem-border scheduledTaskPaperIconItem" data-status="' + task.State + '">';
html += "<a is='emby-linkbutton' style='margin:0;padding:0;' class='clearLink listItemIconContainer' href='scheduledtask.html?id=" + task.Id + "'>";
html += '<span class="material-icons listItemIcon schedule" aria-hidden="true"></span>';
html += '</a>';
html += '<div class="listItemBody two-line">';
let textAlignStyle = 'left';
if (globalize.getIsRTL())
textAlignStyle = 'right';
html += "<a class='clearLink' style='margin:0;padding:0;display:block;text-align:" + textAlignStyle + ";' is='emby-linkbutton' href='scheduledtask.html?id=" + task.Id + "'>";
html += "<h3 class='listItemBodyText'>" + task.Name + '</h3>';
html += "<div class='secondary listItemBodyText' id='taskProgress" + task.Id + "'>" + getTaskProgressHtml(task) + '</div>';
html += '</a>';
html += '</div>';
if (task.State === 'Running') {
html += '<button type="button" is="paper-icon-button-light" id="btnTask' + task.Id + '" class="btnStopTask" data-taskid="' + task.Id + '" title="' + globalize.translate('ButtonStop') + '"><span class="material-icons stop" aria-hidden="true"></span></button>';
} else if (task.State === 'Idle') {
html += '<button type="button" is="paper-icon-button-light" id="btnTask' + task.Id + '" class="btnStartTask" data-taskid="' + task.Id + '" title="' + globalize.translate('ButtonStart') + '"><span class="material-icons play_arrow" aria-hidden="true"></span></button>';
}
html += '</div>';
view.querySelector('#taskProgress' + task.Id).innerHTML = getTaskProgressHtml(task);
updateTaskButton(view.querySelector('#btnTask' + task.Id), task.State);
}
if (tasks.length) {
html += '</div>';
html += '</div>';
}
page.querySelector('.divScheduledTasks').innerHTML = html;
}
function getTaskProgressHtml(task) {
let html = '';
if (task.State === 'Idle') {
if (task.LastExecutionResult) {
const endtime = Date.parse(task.LastExecutionResult.EndTimeUtc);
const starttime = Date.parse(task.LastExecutionResult.StartTimeUtc);
html += globalize.translate('LabelScheduledTaskLastRan', formatDistanceToNow(endtime, getLocaleWithSuffix()),
formatDistance(starttime, endtime, { locale: getLocale() }));
if (task.LastExecutionResult.Status === 'Failed') {
html += " <span style='color:#FF0000;'>(" + globalize.translate('LabelFailed') + ')</span>';
} else if (task.LastExecutionResult.Status === 'Cancelled') {
html += " <span style='color:#0026FF;'>(" + globalize.translate('LabelCancelled') + ')</span>';
} else if (task.LastExecutionResult.Status === 'Aborted') {
html += " <span style='color:#FF0000;'>" + globalize.translate('LabelAbortedByServerShutdown') + '</span>';
}
}
} else if (task.State === 'Running') {
const progress = (task.CurrentProgressPercentage || 0).toFixed(1);
html += '<div style="display:flex;align-items:center;">';
html += '<div class="taskProgressOuter" title="' + progress + '%" style="flex-grow:1;">';
html += '<div class="taskProgressInner" style="width:' + progress + '%;">';
html += '</div>';
html += '</div>';
html += "<span style='color:#00a4dc;margin-left:5px;'>" + progress + '%</span>';
html += '</div>';
} else {
html += "<span style='color:#FF0000;'>" + globalize.translate('LabelStopping') + '</span>';
}
return html;
}
function setTaskButtonIcon(button, icon) {
const inner = button.querySelector('.material-icons');
inner.classList.remove('stop', 'play_arrow');
inner.classList.add(icon);
}
function updateTaskButton(elem, state) {
if (state === 'Running') {
elem.classList.remove('btnStartTask');
elem.classList.add('btnStopTask');
setTaskButtonIcon(elem, 'stop');
elem.title = globalize.translate('ButtonStop');
} else if (state === 'Idle') {
elem.classList.add('btnStartTask');
elem.classList.remove('btnStopTask');
setTaskButtonIcon(elem, 'play_arrow');
elem.title = globalize.translate('ButtonStart');
}
$(elem).parents('.listItem')[0].setAttribute('data-status', state);
}
export default function(view) {
function updateTasks(tasks) {
for (let i = 0; i < tasks.length; i++) {
const task = tasks[i];
view.querySelector('#taskProgress' + task.Id).innerHTML = getTaskProgressHtml(task);
updateTaskButton(view.querySelector('#btnTask' + task.Id), task.State);
}
}
function onPollIntervalFired() {
if (!ApiClient.isMessageChannelOpen()) {
reloadList(view);
}
}
function onScheduledTasksUpdate(e, apiClient, info) {
if (apiClient.serverId() === serverId) {
updateTasks(info);
}
}
function startInterval() {
ApiClient.sendMessage('ScheduledTasksInfoStart', '1000,1000');
pollInterval && clearInterval(pollInterval);
pollInterval = setInterval(onPollIntervalFired, 1e4);
}
function stopInterval() {
ApiClient.sendMessage('ScheduledTasksInfoStop');
pollInterval && clearInterval(pollInterval);
}
let pollInterval;
const serverId = ApiClient.serverId();
$('.divScheduledTasks', view).on('click', '.btnStartTask', function() {
const button = this;
const id = button.getAttribute('data-taskid');
ApiClient.startScheduledTask(id).then(function() {
updateTaskButton(button, 'Running');
reloadList(view);
});
});
$('.divScheduledTasks', view).on('click', '.btnStopTask', function() {
const button = this;
const id = button.getAttribute('data-taskid');
ApiClient.stopScheduledTask(id).then(function() {
updateTaskButton(button, '');
reloadList(view);
});
});
view.addEventListener('viewbeforehide', function() {
Events.off(serverNotifications, 'ScheduledTasksInfo', onScheduledTasksUpdate);
stopInterval();
});
view.addEventListener('viewshow', function() {
loading.show();
startInterval();
function onPollIntervalFired() {
if (!ApiClient.isMessageChannelOpen()) {
reloadList(view);
Events.on(serverNotifications, 'ScheduledTasksInfo', onScheduledTasksUpdate);
});
}
}
/* eslint-enable indent */
function onScheduledTasksUpdate(e, apiClient, info) {
if (apiClient.serverId() === serverId) {
updateTasks(info);
}
}
function startInterval() {
ApiClient.sendMessage('ScheduledTasksInfoStart', '1000,1000');
pollInterval && clearInterval(pollInterval);
pollInterval = setInterval(onPollIntervalFired, 1e4);
}
function stopInterval() {
ApiClient.sendMessage('ScheduledTasksInfoStop');
pollInterval && clearInterval(pollInterval);
}
let pollInterval;
const serverId = ApiClient.serverId();
$('.divScheduledTasks', view).on('click', '.btnStartTask', function() {
const button = this;
const id = button.getAttribute('data-taskid');
ApiClient.startScheduledTask(id).then(function() {
updateTaskButton(button, 'Running');
reloadList(view);
});
});
$('.divScheduledTasks', view).on('click', '.btnStopTask', function() {
const button = this;
const id = button.getAttribute('data-taskid');
ApiClient.stopScheduledTask(id).then(function() {
updateTaskButton(button, '');
reloadList(view);
});
});
view.addEventListener('viewbeforehide', function() {
Events.off(serverNotifications, 'ScheduledTasksInfo', onScheduledTasksUpdate);
stopInterval();
});
view.addEventListener('viewshow', function() {
loading.show();
startInterval();
reloadList(view);
Events.on(serverNotifications, 'ScheduledTasksInfo', onScheduledTasksUpdate);
});
}

View file

@ -2,34 +2,31 @@ import ActivityLog from '../../components/activitylog';
import globalize from '../../scripts/globalize';
import { toBoolean } from '../../utils/string.ts';
/* eslint-disable indent */
export default function (view, params) {
let activityLog;
export default function (view, params) {
let activityLog;
if (toBoolean(params.useractivity, true)) {
view.querySelector('.activityItems').setAttribute('data-useractivity', 'true');
view.querySelector('.sectionTitle').innerHTML = globalize.translate('HeaderActivity');
} else {
view.querySelector('.activityItems').setAttribute('data-useractivity', 'false');
view.querySelector('.sectionTitle').innerHTML = globalize.translate('Alerts');
}
view.addEventListener('viewshow', function () {
if (!activityLog) {
activityLog = new ActivityLog({
serverId: ApiClient.serverId(),
element: view.querySelector('.activityItems')
});
}
});
view.addEventListener('viewdestroy', function () {
if (activityLog) {
activityLog.destroy();
}
activityLog = null;
});
if (toBoolean(params.useractivity, true)) {
view.querySelector('.activityItems').setAttribute('data-useractivity', 'true');
view.querySelector('.sectionTitle').innerHTML = globalize.translate('HeaderActivity');
} else {
view.querySelector('.activityItems').setAttribute('data-useractivity', 'false');
view.querySelector('.sectionTitle').innerHTML = globalize.translate('Alerts');
}
/* eslint-enable indent */
view.addEventListener('viewshow', function () {
if (!activityLog) {
activityLog = new ActivityLog({
serverId: ApiClient.serverId(),
element: view.querySelector('.activityItems')
});
}
});
view.addEventListener('viewdestroy', function () {
if (activityLog) {
activityLog.destroy();
}
activityLog = null;
});
}

View file

@ -4,46 +4,43 @@ import loading from '../../components/loading/loading';
import globalize from '../../scripts/globalize';
import Dashboard from '../../utils/dashboard';
/* eslint-disable indent */
function loadPage(page, config) {
$('#txtRemoteClientBitrateLimit', page).val(config.RemoteClientBitrateLimit / 1e6 || '');
loading.hide();
}
function loadPage(page, config) {
$('#txtRemoteClientBitrateLimit', page).val(config.RemoteClientBitrateLimit / 1e6 || '');
loading.hide();
}
function onSubmit() {
loading.show();
const form = this;
ApiClient.getServerConfiguration().then(function (config) {
config.RemoteClientBitrateLimit = parseInt(1e6 * parseFloat($('#txtRemoteClientBitrateLimit', form).val() || '0'), 10);
ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
});
return false;
}
function getTabs() {
return [{
href: '#/encodingsettings.html',
name: globalize.translate('Transcoding')
}, {
href: '#/playbackconfiguration.html',
name: globalize.translate('ButtonResume')
}, {
href: '#/streamingsettings.html',
name: globalize.translate('TabStreaming')
}];
}
$(document).on('pageinit', '#streamingSettingsPage', function () {
$('.streamingSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#streamingSettingsPage', function () {
loading.show();
libraryMenu.setTabs('playback', 2, getTabs);
const page = this;
ApiClient.getServerConfiguration().then(function (config) {
loadPage(page, config);
});
function onSubmit() {
loading.show();
const form = this;
ApiClient.getServerConfiguration().then(function (config) {
config.RemoteClientBitrateLimit = parseInt(1e6 * parseFloat($('#txtRemoteClientBitrateLimit', form).val() || '0'), 10);
ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
});
/* eslint-enable indent */
return false;
}
function getTabs() {
return [{
href: '#/encodingsettings.html',
name: globalize.translate('Transcoding')
}, {
href: '#/playbackconfiguration.html',
name: globalize.translate('ButtonResume')
}, {
href: '#/streamingsettings.html',
name: globalize.translate('TabStreaming')
}];
}
$(document).on('pageinit', '#streamingSettingsPage', function () {
$('.streamingSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshow', '#streamingSettingsPage', function () {
loading.show();
libraryMenu.setTabs('playback', 2, getTabs);
const page = this;
ApiClient.getServerConfiguration().then(function (config) {
loadPage(page, config);
});
});

View file

@ -9,265 +9,263 @@ import '../elements/emby-itemscontainer/emby-itemscontainer';
import '../elements/emby-scroller/emby-scroller';
import ServerConnections from '../components/ServerConnections';
/* eslint-disable indent */
function enableScrollX() {
return true;
}
function enableScrollX() {
return true;
}
function getThumbShape() {
return enableScrollX() ? 'overflowBackdrop' : 'backdrop';
}
function getThumbShape() {
return enableScrollX() ? 'overflowBackdrop' : 'backdrop';
}
function getPosterShape() {
return enableScrollX() ? 'overflowPortrait' : 'portrait';
}
function getPosterShape() {
return enableScrollX() ? 'overflowPortrait' : 'portrait';
}
function getSquareShape() {
return enableScrollX() ? 'overflowSquare' : 'square';
}
function getSquareShape() {
return enableScrollX() ? 'overflowSquare' : 'square';
}
function getSections() {
return [{
name: 'Movies',
types: 'Movie',
shape: getPosterShape(),
showTitle: true,
showYear: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}, {
name: 'Shows',
types: 'Series',
shape: getPosterShape(),
showTitle: true,
showYear: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}, {
name: 'Episodes',
types: 'Episode',
shape: getThumbShape(),
preferThumb: false,
showTitle: true,
showParentTitle: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}, {
name: 'Videos',
types: 'Video',
shape: getThumbShape(),
preferThumb: true,
showTitle: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}, {
name: 'Collections',
types: 'BoxSet',
shape: getPosterShape(),
showTitle: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}, {
name: 'Playlists',
types: 'Playlist',
shape: getSquareShape(),
preferThumb: false,
showTitle: true,
overlayText: false,
showParentTitle: false,
centerText: true,
overlayPlayButton: true,
coverImage: true
}, {
name: 'People',
types: 'Person',
shape: getPosterShape(),
preferThumb: false,
showTitle: true,
overlayText: false,
showParentTitle: false,
centerText: true,
overlayPlayButton: true,
coverImage: true
}, {
name: 'Artists',
types: 'MusicArtist',
shape: getSquareShape(),
preferThumb: false,
showTitle: true,
overlayText: false,
showParentTitle: false,
centerText: true,
overlayPlayButton: true,
coverImage: true
}, {
name: 'Albums',
types: 'MusicAlbum',
shape: getSquareShape(),
preferThumb: false,
showTitle: true,
overlayText: false,
showParentTitle: true,
centerText: true,
overlayPlayButton: true,
coverImage: true
}, {
name: 'Songs',
types: 'Audio',
shape: getSquareShape(),
preferThumb: false,
showTitle: true,
overlayText: false,
showParentTitle: true,
centerText: true,
overlayMoreButton: true,
action: 'instantmix',
coverImage: true
}, {
name: 'Books',
types: 'Book',
shape: getPosterShape(),
showTitle: true,
showYear: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}];
}
function getSections() {
return [{
name: 'Movies',
types: 'Movie',
shape: getPosterShape(),
showTitle: true,
showYear: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}, {
name: 'Shows',
types: 'Series',
shape: getPosterShape(),
showTitle: true,
showYear: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}, {
name: 'Episodes',
types: 'Episode',
shape: getThumbShape(),
preferThumb: false,
showTitle: true,
showParentTitle: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}, {
name: 'Videos',
types: 'Video',
shape: getThumbShape(),
preferThumb: true,
showTitle: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}, {
name: 'Collections',
types: 'BoxSet',
shape: getPosterShape(),
showTitle: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}, {
name: 'Playlists',
types: 'Playlist',
shape: getSquareShape(),
preferThumb: false,
showTitle: true,
overlayText: false,
showParentTitle: false,
centerText: true,
overlayPlayButton: true,
coverImage: true
}, {
name: 'People',
types: 'Person',
shape: getPosterShape(),
preferThumb: false,
showTitle: true,
overlayText: false,
showParentTitle: false,
centerText: true,
overlayPlayButton: true,
coverImage: true
}, {
name: 'Artists',
types: 'MusicArtist',
shape: getSquareShape(),
preferThumb: false,
showTitle: true,
overlayText: false,
showParentTitle: false,
centerText: true,
overlayPlayButton: true,
coverImage: true
}, {
name: 'Albums',
types: 'MusicAlbum',
shape: getSquareShape(),
preferThumb: false,
showTitle: true,
overlayText: false,
showParentTitle: true,
centerText: true,
overlayPlayButton: true,
coverImage: true
}, {
name: 'Songs',
types: 'Audio',
shape: getSquareShape(),
preferThumb: false,
showTitle: true,
overlayText: false,
showParentTitle: true,
centerText: true,
overlayMoreButton: true,
action: 'instantmix',
coverImage: true
}, {
name: 'Books',
types: 'Book',
shape: getPosterShape(),
showTitle: true,
showYear: true,
overlayPlayButton: true,
overlayText: false,
centerText: true
}];
}
function getFetchDataFn(section) {
return function () {
const apiClient = this.apiClient;
const options = {
SortBy: 'SeriesName,SortName',
SortOrder: 'Ascending',
Filters: 'IsFavorite',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,BasicSyncInfo',
CollapseBoxSetItems: false,
ExcludeLocationTypes: 'Virtual',
EnableTotalRecordCount: false
};
options.Limit = 20;
const userId = apiClient.getCurrentUserId();
if (section.types === 'MusicArtist') {
return apiClient.getArtists(userId, options);
}
if (section.types === 'Person') {
return apiClient.getPeople(userId, options);
}
options.IncludeItemTypes = section.types;
return apiClient.getItems(userId, options);
function getFetchDataFn(section) {
return function () {
const apiClient = this.apiClient;
const options = {
SortBy: 'SeriesName,SortName',
SortOrder: 'Ascending',
Filters: 'IsFavorite',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,BasicSyncInfo',
CollapseBoxSetItems: false,
ExcludeLocationTypes: 'Virtual',
EnableTotalRecordCount: false
};
}
options.Limit = 20;
const userId = apiClient.getCurrentUserId();
function getRouteUrl(section, serverId) {
return appRouter.getRouteUrl('list', {
serverId: serverId,
itemTypes: section.types,
isFavorite: true
if (section.types === 'MusicArtist') {
return apiClient.getArtists(userId, options);
}
if (section.types === 'Person') {
return apiClient.getPeople(userId, options);
}
options.IncludeItemTypes = section.types;
return apiClient.getItems(userId, options);
};
}
function getRouteUrl(section, serverId) {
return appRouter.getRouteUrl('list', {
serverId: serverId,
itemTypes: section.types,
isFavorite: true
});
}
function getItemsHtmlFn(section) {
return function (items) {
let cardLayout = appHost.preferVisualCards && section.autoCardLayout && section.showTitle;
cardLayout = false;
const serverId = this.apiClient.serverId();
const leadingButtons = layoutManager.tv ? [{
name: globalize.translate('All'),
id: 'more',
icon: 'favorite',
routeUrl: getRouteUrl(section, serverId)
}] : null;
let lines = 0;
if (section.showTitle) {
lines++;
}
if (section.showYear) {
lines++;
}
if (section.showParentTitle) {
lines++;
}
return cardBuilder.getCardsHtml({
items: items,
preferThumb: section.preferThumb,
shape: section.shape,
centerText: section.centerText && !cardLayout,
overlayText: section.overlayText !== false,
showTitle: section.showTitle,
showYear: section.showYear,
showParentTitle: section.showParentTitle,
scalable: true,
coverImage: section.coverImage,
overlayPlayButton: section.overlayPlayButton,
overlayMoreButton: section.overlayMoreButton && !cardLayout,
action: section.action,
allowBottomPadding: !enableScrollX(),
cardLayout: cardLayout,
leadingButtons: leadingButtons,
lines: lines
});
}
};
}
function getItemsHtmlFn(section) {
return function (items) {
let cardLayout = appHost.preferVisualCards && section.autoCardLayout && section.showTitle;
cardLayout = false;
const serverId = this.apiClient.serverId();
const leadingButtons = layoutManager.tv ? [{
name: globalize.translate('All'),
id: 'more',
icon: 'favorite',
routeUrl: getRouteUrl(section, serverId)
}] : null;
let lines = 0;
function createSections(instance, elem, apiClient) {
const sections = getSections();
let html = '';
if (section.showTitle) {
lines++;
}
for (const section of sections) {
let sectionClass = 'verticalSection';
if (section.showYear) {
lines++;
}
if (section.showParentTitle) {
lines++;
}
return cardBuilder.getCardsHtml({
items: items,
preferThumb: section.preferThumb,
shape: section.shape,
centerText: section.centerText && !cardLayout,
overlayText: section.overlayText !== false,
showTitle: section.showTitle,
showYear: section.showYear,
showParentTitle: section.showParentTitle,
scalable: true,
coverImage: section.coverImage,
overlayPlayButton: section.overlayPlayButton,
overlayMoreButton: section.overlayMoreButton && !cardLayout,
action: section.action,
allowBottomPadding: !enableScrollX(),
cardLayout: cardLayout,
leadingButtons: leadingButtons,
lines: lines
});
};
}
function createSections(instance, elem, apiClient) {
const sections = getSections();
let html = '';
for (const section of sections) {
let sectionClass = 'verticalSection';
if (!section.showTitle) {
sectionClass += ' verticalSection-extrabottompadding';
}
html += '<div class="' + sectionClass + ' hide">';
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
if (layoutManager.tv) {
html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate(section.name) + '</h2>';
} else {
html += '<a is="emby-linkbutton" href="' + getRouteUrl(section, apiClient.serverId()) + '" class="more button-flat button-flat-mini sectionTitleTextButton">';
html += '<h2 class="sectionTitle sectionTitle-cards">';
html += globalize.translate(section.name);
html += '</h2>';
html += '<span class="material-icons chevron_right" aria-hidden="true"></span>';
html += '</a>';
}
html += '</div>';
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true"><div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="markfavorite"></div></div>';
html += '</div>';
if (!section.showTitle) {
sectionClass += ' verticalSection-extrabottompadding';
}
elem.innerHTML = html;
window.CustomElements.upgradeSubtree(elem);
html += '<div class="' + sectionClass + ' hide">';
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
const elems = elem.querySelectorAll('.itemsContainer');
for (let i = 0, length = elems.length; i < length; i++) {
const itemsContainer = elems[i];
itemsContainer.fetchData = getFetchDataFn(sections[i]).bind(instance);
itemsContainer.getItemsHtml = getItemsHtmlFn(sections[i]).bind(instance);
itemsContainer.parentContainer = dom.parentWithClass(itemsContainer, 'verticalSection');
if (layoutManager.tv) {
html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate(section.name) + '</h2>';
} else {
html += '<a is="emby-linkbutton" href="' + getRouteUrl(section, apiClient.serverId()) + '" class="more button-flat button-flat-mini sectionTitleTextButton">';
html += '<h2 class="sectionTitle sectionTitle-cards">';
html += globalize.translate(section.name);
html += '</h2>';
html += '<span class="material-icons chevron_right" aria-hidden="true"></span>';
html += '</a>';
}
html += '</div>';
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true"><div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="markfavorite"></div></div>';
html += '</div>';
}
elem.innerHTML = html;
window.CustomElements.upgradeSubtree(elem);
const elems = elem.querySelectorAll('.itemsContainer');
for (let i = 0, length = elems.length; i < length; i++) {
const itemsContainer = elems[i];
itemsContainer.fetchData = getFetchDataFn(sections[i]).bind(instance);
itemsContainer.getItemsHtml = getItemsHtmlFn(sections[i]).bind(instance);
itemsContainer.parentContainer = dom.parentWithClass(itemsContainer, 'verticalSection');
}
}
class FavoritesTab {
constructor(view, params) {
this.view = view;
@ -318,4 +316,3 @@ class FavoritesTab {
export default FavoritesTab;
/* eslint-enable indent */

View file

@ -13,417 +13,415 @@ import '../elements/emby-scroller/emby-scroller';
import ServerConnections from '../components/ServerConnections';
import LibraryMenu from '../scripts/libraryMenu';
/* eslint-disable indent */
function getInitialLiveTvQuery(instance, params, startIndex = 0, limit = 300) {
const query = {
UserId: ServerConnections.getApiClient(params.serverId).getCurrentUserId(),
StartIndex: startIndex,
Fields: 'ChannelInfo,PrimaryImageAspectRatio',
Limit: limit
};
function getInitialLiveTvQuery(instance, params, startIndex = 0, limit = 300) {
const query = {
UserId: ServerConnections.getApiClient(params.serverId).getCurrentUserId(),
StartIndex: startIndex,
Fields: 'ChannelInfo,PrimaryImageAspectRatio',
Limit: limit
};
if (params.type === 'Recordings') {
query.IsInProgress = false;
} else {
query.HasAired = false;
}
if (params.genreId) {
query.GenreIds = params.genreId;
}
if (params.IsMovie === 'true') {
query.IsMovie = true;
} else if (params.IsMovie === 'false') {
query.IsMovie = false;
}
if (params.IsSeries === 'true') {
query.IsSeries = true;
} else if (params.IsSeries === 'false') {
query.IsSeries = false;
}
if (params.IsNews === 'true') {
query.IsNews = true;
} else if (params.IsNews === 'false') {
query.IsNews = false;
}
if (params.IsSports === 'true') {
query.IsSports = true;
} else if (params.IsSports === 'false') {
query.IsSports = false;
}
if (params.IsKids === 'true') {
query.IsKids = true;
} else if (params.IsKids === 'false') {
query.IsKids = false;
}
if (params.IsAiring === 'true') {
query.IsAiring = true;
} else if (params.IsAiring === 'false') {
query.IsAiring = false;
}
return modifyQueryWithFilters(instance, query);
if (params.type === 'Recordings') {
query.IsInProgress = false;
} else {
query.HasAired = false;
}
function modifyQueryWithFilters(instance, query) {
const sortValues = instance.getSortValues();
if (params.genreId) {
query.GenreIds = params.genreId;
}
if (!query.SortBy) {
query.SortBy = sortValues.sortBy;
query.SortOrder = sortValues.sortOrder;
if (params.IsMovie === 'true') {
query.IsMovie = true;
} else if (params.IsMovie === 'false') {
query.IsMovie = false;
}
if (params.IsSeries === 'true') {
query.IsSeries = true;
} else if (params.IsSeries === 'false') {
query.IsSeries = false;
}
if (params.IsNews === 'true') {
query.IsNews = true;
} else if (params.IsNews === 'false') {
query.IsNews = false;
}
if (params.IsSports === 'true') {
query.IsSports = true;
} else if (params.IsSports === 'false') {
query.IsSports = false;
}
if (params.IsKids === 'true') {
query.IsKids = true;
} else if (params.IsKids === 'false') {
query.IsKids = false;
}
if (params.IsAiring === 'true') {
query.IsAiring = true;
} else if (params.IsAiring === 'false') {
query.IsAiring = false;
}
return modifyQueryWithFilters(instance, query);
}
function modifyQueryWithFilters(instance, query) {
const sortValues = instance.getSortValues();
if (!query.SortBy) {
query.SortBy = sortValues.sortBy;
query.SortOrder = sortValues.sortOrder;
}
query.Fields = query.Fields ? query.Fields + ',PrimaryImageAspectRatio' : 'PrimaryImageAspectRatio';
query.ImageTypeLimit = 1;
let hasFilters;
const queryFilters = [];
const filters = instance.getFilters();
if (filters.IsPlayed) {
queryFilters.push('IsPlayed');
hasFilters = true;
}
if (filters.IsUnplayed) {
queryFilters.push('IsUnplayed');
hasFilters = true;
}
if (filters.IsFavorite) {
queryFilters.push('IsFavorite');
hasFilters = true;
}
if (filters.IsResumable) {
queryFilters.push('IsResumable');
hasFilters = true;
}
if (filters.VideoTypes) {
hasFilters = true;
query.VideoTypes = filters.VideoTypes;
}
if (filters.GenreIds) {
hasFilters = true;
query.GenreIds = filters.GenreIds;
}
if (filters.Is4K) {
query.Is4K = true;
hasFilters = true;
}
if (filters.IsHD) {
query.IsHD = true;
hasFilters = true;
}
if (filters.IsSD) {
query.IsHD = false;
hasFilters = true;
}
if (filters.Is3D) {
query.Is3D = true;
hasFilters = true;
}
if (filters.HasSubtitles) {
query.HasSubtitles = true;
hasFilters = true;
}
if (filters.HasTrailer) {
query.HasTrailer = true;
hasFilters = true;
}
if (filters.HasSpecialFeature) {
query.HasSpecialFeature = true;
hasFilters = true;
}
if (filters.HasThemeSong) {
query.HasThemeSong = true;
hasFilters = true;
}
if (filters.HasThemeVideo) {
query.HasThemeVideo = true;
hasFilters = true;
}
query.Filters = queryFilters.length ? queryFilters.join(',') : null;
instance.setFilterStatus(hasFilters);
if (instance.alphaPicker) {
const newValue = instance.alphaPicker.value();
if (newValue === '#') {
query.NameLessThan = 'A';
delete query.NameStartsWith;
} else {
query.NameStartsWith = newValue;
delete query.NameLessThan;
}
}
query.Fields = query.Fields ? query.Fields + ',PrimaryImageAspectRatio' : 'PrimaryImageAspectRatio';
query.ImageTypeLimit = 1;
let hasFilters;
const queryFilters = [];
const filters = instance.getFilters();
return query;
}
if (filters.IsPlayed) {
queryFilters.push('IsPlayed');
hasFilters = true;
}
function setSortButtonIcon(btnSortIcon, icon) {
btnSortIcon.classList.remove('arrow_downward');
btnSortIcon.classList.remove('arrow_upward');
btnSortIcon.classList.add(icon);
}
if (filters.IsUnplayed) {
queryFilters.push('IsUnplayed');
hasFilters = true;
}
function updateSortText(instance) {
const btnSortText = instance.btnSortText;
if (filters.IsFavorite) {
queryFilters.push('IsFavorite');
hasFilters = true;
}
if (btnSortText) {
const options = instance.getSortMenuOptions();
const values = instance.getSortValues();
const sortBy = values.sortBy;
if (filters.IsResumable) {
queryFilters.push('IsResumable');
hasFilters = true;
}
if (filters.VideoTypes) {
hasFilters = true;
query.VideoTypes = filters.VideoTypes;
}
if (filters.GenreIds) {
hasFilters = true;
query.GenreIds = filters.GenreIds;
}
if (filters.Is4K) {
query.Is4K = true;
hasFilters = true;
}
if (filters.IsHD) {
query.IsHD = true;
hasFilters = true;
}
if (filters.IsSD) {
query.IsHD = false;
hasFilters = true;
}
if (filters.Is3D) {
query.Is3D = true;
hasFilters = true;
}
if (filters.HasSubtitles) {
query.HasSubtitles = true;
hasFilters = true;
}
if (filters.HasTrailer) {
query.HasTrailer = true;
hasFilters = true;
}
if (filters.HasSpecialFeature) {
query.HasSpecialFeature = true;
hasFilters = true;
}
if (filters.HasThemeSong) {
query.HasThemeSong = true;
hasFilters = true;
}
if (filters.HasThemeVideo) {
query.HasThemeVideo = true;
hasFilters = true;
}
query.Filters = queryFilters.length ? queryFilters.join(',') : null;
instance.setFilterStatus(hasFilters);
if (instance.alphaPicker) {
const newValue = instance.alphaPicker.value();
if (newValue === '#') {
query.NameLessThan = 'A';
delete query.NameStartsWith;
} else {
query.NameStartsWith = newValue;
delete query.NameLessThan;
for (const option of options) {
if (sortBy === option.value) {
btnSortText.innerHTML = globalize.translate('SortByValue', option.name);
break;
}
}
return query;
const btnSortIcon = instance.btnSortIcon;
if (btnSortIcon) {
setSortButtonIcon(btnSortIcon, values.sortOrder === 'Descending' ? 'arrow_downward' : 'arrow_upward');
}
}
}
function setSortButtonIcon(btnSortIcon, icon) {
btnSortIcon.classList.remove('arrow_downward');
btnSortIcon.classList.remove('arrow_upward');
btnSortIcon.classList.add(icon);
function updateItemsContainerForViewType(instance) {
if (instance.getViewSettings().imageType === 'list') {
instance.itemsContainer.classList.remove('vertical-wrap');
instance.itemsContainer.classList.add('vertical-list');
} else {
instance.itemsContainer.classList.add('vertical-wrap');
instance.itemsContainer.classList.remove('vertical-list');
}
}
function updateSortText(instance) {
const btnSortText = instance.btnSortText;
function updateAlphaPickerState(instance) {
if (instance.alphaPicker) {
const alphaPicker = instance.alphaPickerElement;
if (btnSortText) {
const options = instance.getSortMenuOptions();
if (alphaPicker) {
const values = instance.getSortValues();
const sortBy = values.sortBy;
for (const option of options) {
if (sortBy === option.value) {
btnSortText.innerHTML = globalize.translate('SortByValue', option.name);
break;
}
}
const btnSortIcon = instance.btnSortIcon;
if (btnSortIcon) {
setSortButtonIcon(btnSortIcon, values.sortOrder === 'Descending' ? 'arrow_downward' : 'arrow_upward');
if (values.sortBy.indexOf('SortName') !== -1) {
alphaPicker.classList.remove('hide');
instance.itemsContainer.parentNode.classList.add('padded-right-withalphapicker');
} else {
alphaPicker.classList.add('hide');
instance.itemsContainer.parentNode.classList.remove('padded-right-withalphapicker');
}
}
}
}
function updateItemsContainerForViewType(instance) {
if (instance.getViewSettings().imageType === 'list') {
instance.itemsContainer.classList.remove('vertical-wrap');
instance.itemsContainer.classList.add('vertical-list');
} else {
instance.itemsContainer.classList.add('vertical-wrap');
instance.itemsContainer.classList.remove('vertical-list');
}
function getItems(instance, params, item, sortBy, startIndex, limit) {
const apiClient = ServerConnections.getApiClient(params.serverId);
instance.queryRecursive = false;
if (params.type === 'Recordings') {
return apiClient.getLiveTvRecordings(getInitialLiveTvQuery(instance, params, startIndex, limit));
}
function updateAlphaPickerState(instance) {
if (instance.alphaPicker) {
const alphaPicker = instance.alphaPickerElement;
if (alphaPicker) {
const values = instance.getSortValues();
if (values.sortBy.indexOf('SortName') !== -1) {
alphaPicker.classList.remove('hide');
instance.itemsContainer.parentNode.classList.add('padded-right-withalphapicker');
} else {
alphaPicker.classList.add('hide');
instance.itemsContainer.parentNode.classList.remove('padded-right-withalphapicker');
}
}
if (params.type === 'Programs') {
if (params.IsAiring === 'true') {
return apiClient.getLiveTvRecommendedPrograms(getInitialLiveTvQuery(instance, params, startIndex, limit));
}
return apiClient.getLiveTvPrograms(getInitialLiveTvQuery(instance, params, startIndex, limit));
}
function getItems(instance, params, item, sortBy, startIndex, limit) {
const apiClient = ServerConnections.getApiClient(params.serverId);
if (params.type === 'nextup') {
return apiClient.getNextUpEpisodes(modifyQueryWithFilters(instance, {
Limit: limit,
Fields: 'PrimaryImageAspectRatio,DateCreated,BasicSyncInfo,MediaSourceCount',
UserId: apiClient.getCurrentUserId(),
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Thumb',
EnableTotalRecordCount: false,
SortBy: sortBy,
EnableRewatching: userSettings.enableRewatchingInNextUp()
}));
}
instance.queryRecursive = false;
if (params.type === 'Recordings') {
return apiClient.getLiveTvRecordings(getInitialLiveTvQuery(instance, params, startIndex, limit));
if (!item) {
instance.queryRecursive = true;
let method = 'getItems';
if (params.type === 'MusicArtist') {
method = 'getArtists';
} else if (params.type === 'Person') {
method = 'getPeople';
}
if (params.type === 'Programs') {
if (params.IsAiring === 'true') {
return apiClient.getLiveTvRecommendedPrograms(getInitialLiveTvQuery(instance, params, startIndex, limit));
}
return apiClient.getLiveTvPrograms(getInitialLiveTvQuery(instance, params, startIndex, limit));
}
if (params.type === 'nextup') {
return apiClient.getNextUpEpisodes(modifyQueryWithFilters(instance, {
Limit: limit,
Fields: 'PrimaryImageAspectRatio,DateCreated,BasicSyncInfo,MediaSourceCount',
UserId: apiClient.getCurrentUserId(),
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Thumb',
EnableTotalRecordCount: false,
SortBy: sortBy,
EnableRewatching: userSettings.enableRewatchingInNextUp()
}));
}
if (!item) {
instance.queryRecursive = true;
let method = 'getItems';
if (params.type === 'MusicArtist') {
method = 'getArtists';
} else if (params.type === 'Person') {
method = 'getPeople';
}
return apiClient[method](apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, {
StartIndex: startIndex,
Limit: limit,
Fields: 'PrimaryImageAspectRatio,SortName',
ImageTypeLimit: 1,
IncludeItemTypes: params.type === 'MusicArtist' || params.type === 'Person' ? null : params.type,
Recursive: true,
IsFavorite: params.IsFavorite === 'true' || null,
ArtistIds: params.artistId || null,
SortBy: sortBy
}));
}
if (item.Type === 'Genre' || item.Type === 'MusicGenre' || item.Type === 'Studio' || item.Type === 'Person') {
instance.queryRecursive = true;
const query = {
StartIndex: startIndex,
Limit: limit,
Fields: 'PrimaryImageAspectRatio,SortName',
Recursive: true,
parentId: params.parentId,
SortBy: sortBy
};
if (item.Type === 'Studio') {
query.StudioIds = item.Id;
} else if (item.Type === 'Genre' || item.Type === 'MusicGenre') {
query.GenreIds = item.Id;
} else if (item.Type === 'Person') {
query.PersonIds = item.Id;
}
if (item.Type === 'MusicGenre') {
query.IncludeItemTypes = 'MusicAlbum';
} else if (item.CollectionType === 'movies') {
query.IncludeItemTypes = 'Movie';
} else if (item.CollectionType === 'tvshows') {
query.IncludeItemTypes = 'Series';
} else if (item.Type === 'Genre') {
query.IncludeItemTypes = 'Movie,Series,Video';
} else if (item.Type === 'Person') {
query.IncludeItemTypes = params.type;
}
return apiClient.getItems(apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, query));
}
return apiClient.getItems(apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, {
return apiClient[method](apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, {
StartIndex: startIndex,
Limit: limit,
Fields: 'PrimaryImageAspectRatio,SortName,Path,SongCount,ChildCount,MediaSourceCount',
Fields: 'PrimaryImageAspectRatio,SortName',
ImageTypeLimit: 1,
ParentId: item.Id,
IncludeItemTypes: params.type === 'MusicArtist' || params.type === 'Person' ? null : params.type,
Recursive: true,
IsFavorite: params.IsFavorite === 'true' || null,
ArtistIds: params.artistId || null,
SortBy: sortBy
}));
}
function getItem(params) {
if (params.type === 'Recordings' || params.type === 'Programs' || params.type === 'nextup') {
return Promise.resolve(null);
if (item.Type === 'Genre' || item.Type === 'MusicGenre' || item.Type === 'Studio' || item.Type === 'Person') {
instance.queryRecursive = true;
const query = {
StartIndex: startIndex,
Limit: limit,
Fields: 'PrimaryImageAspectRatio,SortName',
Recursive: true,
parentId: params.parentId,
SortBy: sortBy
};
if (item.Type === 'Studio') {
query.StudioIds = item.Id;
} else if (item.Type === 'Genre' || item.Type === 'MusicGenre') {
query.GenreIds = item.Id;
} else if (item.Type === 'Person') {
query.PersonIds = item.Id;
}
const apiClient = ServerConnections.getApiClient(params.serverId);
const itemId = params.genreId || params.musicGenreId || params.studioId || params.personId || params.parentId;
if (itemId) {
return apiClient.getItem(apiClient.getCurrentUserId(), itemId);
if (item.Type === 'MusicGenre') {
query.IncludeItemTypes = 'MusicAlbum';
} else if (item.CollectionType === 'movies') {
query.IncludeItemTypes = 'Movie';
} else if (item.CollectionType === 'tvshows') {
query.IncludeItemTypes = 'Series';
} else if (item.Type === 'Genre') {
query.IncludeItemTypes = 'Movie,Series,Video';
} else if (item.Type === 'Person') {
query.IncludeItemTypes = params.type;
}
return apiClient.getItems(apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, query));
}
return apiClient.getItems(apiClient.getCurrentUserId(), modifyQueryWithFilters(instance, {
StartIndex: startIndex,
Limit: limit,
Fields: 'PrimaryImageAspectRatio,SortName,Path,SongCount,ChildCount,MediaSourceCount',
ImageTypeLimit: 1,
ParentId: item.Id,
SortBy: sortBy
}));
}
function getItem(params) {
if (params.type === 'Recordings' || params.type === 'Programs' || params.type === 'nextup') {
return Promise.resolve(null);
}
function showViewSettingsMenu() {
const instance = this;
const apiClient = ServerConnections.getApiClient(params.serverId);
const itemId = params.genreId || params.musicGenreId || params.studioId || params.personId || params.parentId;
import('../components/viewSettings/viewSettings').then(({ default: ViewSettings }) => {
new ViewSettings().show({
settingsKey: instance.getSettingsKey(),
settings: instance.getViewSettings(),
visibleSettings: instance.getVisibleViewSettings()
}).then(function () {
updateItemsContainerForViewType(instance);
instance.itemsContainer.refreshItems();
});
});
if (itemId) {
return apiClient.getItem(apiClient.getCurrentUserId(), itemId);
}
function showFilterMenu() {
const instance = this;
return Promise.resolve(null);
}
import('../components/filtermenu/filtermenu').then(({ default: FilterMenu }) => {
new FilterMenu().show({
settingsKey: instance.getSettingsKey(),
settings: instance.getFilters(),
visibleSettings: instance.getVisibleFilters(),
onChange: instance.itemsContainer.refreshItems.bind(instance.itemsContainer),
parentId: instance.params.parentId,
itemTypes: instance.getItemTypes(),
serverId: instance.params.serverId,
filterMenuOptions: instance.getFilterMenuOptions()
}).then(function () {
instance.itemsContainer.refreshItems();
});
function showViewSettingsMenu() {
const instance = this;
import('../components/viewSettings/viewSettings').then(({ default: ViewSettings }) => {
new ViewSettings().show({
settingsKey: instance.getSettingsKey(),
settings: instance.getViewSettings(),
visibleSettings: instance.getVisibleViewSettings()
}).then(function () {
updateItemsContainerForViewType(instance);
instance.itemsContainer.refreshItems();
});
}
});
}
function showSortMenu() {
const instance = this;
function showFilterMenu() {
const instance = this;
import('../components/sortmenu/sortmenu').then(({ default: SortMenu }) => {
new SortMenu().show({
settingsKey: instance.getSettingsKey(),
settings: instance.getSortValues(),
onChange: instance.itemsContainer.refreshItems.bind(instance.itemsContainer),
serverId: instance.params.serverId,
sortOptions: instance.getSortMenuOptions()
}).then(function () {
updateSortText(instance);
updateAlphaPickerState(instance);
instance.itemsContainer.refreshItems();
});
import('../components/filtermenu/filtermenu').then(({ default: FilterMenu }) => {
new FilterMenu().show({
settingsKey: instance.getSettingsKey(),
settings: instance.getFilters(),
visibleSettings: instance.getVisibleFilters(),
onChange: instance.itemsContainer.refreshItems.bind(instance.itemsContainer),
parentId: instance.params.parentId,
itemTypes: instance.getItemTypes(),
serverId: instance.params.serverId,
filterMenuOptions: instance.getFilterMenuOptions()
}).then(function () {
instance.itemsContainer.refreshItems();
});
}
});
}
function onNewItemClick() {
const instance = this;
function showSortMenu() {
const instance = this;
import('../components/playlisteditor/playlisteditor').then(({ default: playlistEditor }) => {
new playlistEditor({
items: [],
serverId: instance.params.serverId
});
import('../components/sortmenu/sortmenu').then(({ default: SortMenu }) => {
new SortMenu().show({
settingsKey: instance.getSettingsKey(),
settings: instance.getSortValues(),
onChange: instance.itemsContainer.refreshItems.bind(instance.itemsContainer),
serverId: instance.params.serverId,
sortOptions: instance.getSortMenuOptions()
}).then(function () {
updateSortText(instance);
updateAlphaPickerState(instance);
instance.itemsContainer.refreshItems();
});
}
});
}
function hideOrShowAll(elems, hide) {
for (const elem of elems) {
if (hide) {
elem.classList.add('hide');
} else {
elem.classList.remove('hide');
}
function onNewItemClick() {
const instance = this;
import('../components/playlisteditor/playlisteditor').then(({ default: playlistEditor }) => {
new playlistEditor({
items: [],
serverId: instance.params.serverId
});
});
}
function hideOrShowAll(elems, hide) {
for (const elem of elems) {
if (hide) {
elem.classList.add('hide');
} else {
elem.classList.remove('hide');
}
}
}
function bindAll(elems, eventName, fn) {
for (const elem of elems) {
elem.addEventListener(eventName, fn);
}
function bindAll(elems, eventName, fn) {
for (const elem of elems) {
elem.addEventListener(eventName, fn);
}
}
class ItemsView {
constructor(view, params) {
@ -1295,4 +1293,3 @@ class ItemsView {
export default ItemsView;
/* eslint-enable indent */

View file

@ -11,294 +11,291 @@ import Events from '../../utils/events.ts';
import '../../elements/emby-itemscontainer/emby-itemscontainer';
/* eslint-disable indent */
export default function (view, params, tabContent) {
function playAll() {
ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) {
playbackManager.play({
items: [item]
});
export default function (view, params, tabContent) {
function playAll() {
ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) {
playbackManager.play({
items: [item]
});
}
function shuffle() {
ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) {
getQuery();
playbackManager.shuffle(item);
});
}
function getPageData() {
const key = getSavedQueryKey();
if (!pageData) {
pageData = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'MusicAlbum',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,SortName,BasicSyncInfo',
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
StartIndex: 0
},
view: libraryBrowser.getSavedView(key) || 'Poster'
};
if (userSettings.libraryPageSize() > 0) {
pageData.query['Limit'] = userSettings.libraryPageSize();
}
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
return pageData;
}
function getQuery() {
return getPageData().query;
}
function getSavedQueryKey() {
if (!savedQueryKey) {
savedQueryKey = libraryBrowser.getSavedQueryKey('musicalbums');
}
return savedQueryKey;
}
const onViewStyleChange = () => {
const viewStyle = this.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') {
itemsContainer.classList.add('vertical-list');
itemsContainer.classList.remove('vertical-wrap');
} else {
itemsContainer.classList.remove('vertical-list');
itemsContainer.classList.add('vertical-wrap');
}
itemsContainer.innerHTML = '';
};
const reloadItems = () => {
loading.show();
isLoading = true;
const query = getQuery();
ApiClient.getItems(ApiClient.getCurrentUserId(), query).then((result) => {
function onNextPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex += query.Limit;
}
reloadItems();
}
function onPreviousPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
}
reloadItems();
}
window.scrollTo(0, 0);
this.alphaPicker?.updateControls(query);
let html;
const pagingHtml = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
showLimit: false,
updatePageSizeSetting: false,
addLayoutButton: false,
sortButton: false,
filterButton: false
});
const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'List') {
html = listView.getListViewHtml({
items: result.Items,
context: 'music',
sortBy: query.SortBy,
addToListButton: true
});
} else if (viewStyle == 'PosterCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'square',
context: 'music',
showTitle: true,
coverImage: true,
showParentTitle: true,
lazy: true,
cardLayout: true
});
} else {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'square',
context: 'music',
showTitle: true,
showParentTitle: true,
lazy: true,
centerText: true,
overlayPlayButton: true
});
}
let elems = tabContent.querySelectorAll('.paging');
for (const elem of elems) {
elem.innerHTML = pagingHtml;
}
elems = tabContent.querySelectorAll('.btnNextPage');
for (const elem of elems) {
elem.addEventListener('click', onNextPageClick);
}
elems = tabContent.querySelectorAll('.btnPreviousPage');
for (const elem of elems) {
elem.addEventListener('click', onPreviousPageClick);
}
const itemsContainer = tabContent.querySelector('.itemsContainer');
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
loading.hide();
isLoading = false;
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(tabContent);
});
});
};
let savedQueryKey;
let pageData;
let isLoading = false;
this.showFilterMenu = function () {
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
const filterDialog = new filterDialogFactory({
query: getQuery(),
mode: 'albums',
serverId: ApiClient.serverId()
});
Events.on(filterDialog, 'filterchange', function () {
getQuery().StartIndex = 0;
reloadItems();
});
filterDialog.show();
});
};
this.getCurrentViewStyle = function () {
return getPageData().view;
};
const initPage = (tabElement) => {
const alphaPickerElement = tabElement.querySelector('.alphaPicker');
const itemsContainer = tabElement.querySelector('.itemsContainer');
alphaPickerElement.addEventListener('alphavaluechanged', function (e) {
const newValue = e.detail.value;
const query = getQuery();
if (newValue === '#') {
query.NameLessThan = 'A';
delete query.NameStartsWith;
} else {
query.NameStartsWith = newValue;
delete query.NameLessThan;
}
query.StartIndex = 0;
reloadItems();
});
this.alphaPicker = new AlphaPicker({
element: alphaPickerElement,
valueChangeEvent: 'click'
});
tabElement.querySelector('.alphaPicker').classList.add('alphabetPicker-right');
alphaPickerElement.classList.add('alphaPicker-fixed-right');
itemsContainer.classList.add('padded-right-withalphapicker');
tabElement.querySelector('.btnFilter').addEventListener('click', () => {
this.showFilterMenu();
});
tabElement.querySelector('.btnSort').addEventListener('click', (e) => {
libraryBrowser.showSortMenu({
items: [{
name: globalize.translate('Name'),
id: 'SortName'
}, {
name: globalize.translate('AlbumArtist'),
id: 'AlbumArtist,SortName'
}, {
name: globalize.translate('OptionCommunityRating'),
id: 'CommunityRating,SortName'
}, {
name: globalize.translate('OptionCriticRating'),
id: 'CriticRating,SortName'
}, {
name: globalize.translate('OptionDateAdded'),
id: 'DateCreated,SortName'
}, {
name: globalize.translate('OptionReleaseDate'),
id: 'ProductionYear,PremiereDate,SortName'
}, {
name: globalize.translate('OptionRandom'),
id: 'Random,SortName'
}],
callback: function () {
getQuery().StartIndex = 0;
reloadItems();
},
query: getQuery(),
button: e.target
});
});
const btnSelectView = tabElement.querySelector('.btnSelectView');
btnSelectView.addEventListener('click', (e) => {
libraryBrowser.showLayoutMenu(e.target, this.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(','));
});
btnSelectView.addEventListener('layoutchange', function (e) {
const viewStyle = e.detail.viewStyle;
getPageData().view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
getQuery().StartIndex = 0;
onViewStyleChange();
reloadItems();
});
tabElement.querySelector('.btnPlayAll').addEventListener('click', playAll);
tabElement.querySelector('.btnShuffle').addEventListener('click', shuffle);
};
initPage(tabContent);
onViewStyleChange();
this.renderTab = () => {
reloadItems();
this.alphaPicker?.updateControls(getQuery());
};
});
}
/* eslint-enable indent */
function shuffle() {
ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) {
getQuery();
playbackManager.shuffle(item);
});
}
function getPageData() {
const key = getSavedQueryKey();
if (!pageData) {
pageData = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'MusicAlbum',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,SortName,BasicSyncInfo',
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
StartIndex: 0
},
view: libraryBrowser.getSavedView(key) || 'Poster'
};
if (userSettings.libraryPageSize() > 0) {
pageData.query['Limit'] = userSettings.libraryPageSize();
}
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
return pageData;
}
function getQuery() {
return getPageData().query;
}
function getSavedQueryKey() {
if (!savedQueryKey) {
savedQueryKey = libraryBrowser.getSavedQueryKey('musicalbums');
}
return savedQueryKey;
}
const onViewStyleChange = () => {
const viewStyle = this.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') {
itemsContainer.classList.add('vertical-list');
itemsContainer.classList.remove('vertical-wrap');
} else {
itemsContainer.classList.remove('vertical-list');
itemsContainer.classList.add('vertical-wrap');
}
itemsContainer.innerHTML = '';
};
const reloadItems = () => {
loading.show();
isLoading = true;
const query = getQuery();
ApiClient.getItems(ApiClient.getCurrentUserId(), query).then((result) => {
function onNextPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex += query.Limit;
}
reloadItems();
}
function onPreviousPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
}
reloadItems();
}
window.scrollTo(0, 0);
this.alphaPicker?.updateControls(query);
let html;
const pagingHtml = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
showLimit: false,
updatePageSizeSetting: false,
addLayoutButton: false,
sortButton: false,
filterButton: false
});
const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'List') {
html = listView.getListViewHtml({
items: result.Items,
context: 'music',
sortBy: query.SortBy,
addToListButton: true
});
} else if (viewStyle == 'PosterCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'square',
context: 'music',
showTitle: true,
coverImage: true,
showParentTitle: true,
lazy: true,
cardLayout: true
});
} else {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'square',
context: 'music',
showTitle: true,
showParentTitle: true,
lazy: true,
centerText: true,
overlayPlayButton: true
});
}
let elems = tabContent.querySelectorAll('.paging');
for (const elem of elems) {
elem.innerHTML = pagingHtml;
}
elems = tabContent.querySelectorAll('.btnNextPage');
for (const elem of elems) {
elem.addEventListener('click', onNextPageClick);
}
elems = tabContent.querySelectorAll('.btnPreviousPage');
for (const elem of elems) {
elem.addEventListener('click', onPreviousPageClick);
}
const itemsContainer = tabContent.querySelector('.itemsContainer');
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
loading.hide();
isLoading = false;
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(tabContent);
});
});
};
let savedQueryKey;
let pageData;
let isLoading = false;
this.showFilterMenu = function () {
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
const filterDialog = new filterDialogFactory({
query: getQuery(),
mode: 'albums',
serverId: ApiClient.serverId()
});
Events.on(filterDialog, 'filterchange', function () {
getQuery().StartIndex = 0;
reloadItems();
});
filterDialog.show();
});
};
this.getCurrentViewStyle = function () {
return getPageData().view;
};
const initPage = (tabElement) => {
const alphaPickerElement = tabElement.querySelector('.alphaPicker');
const itemsContainer = tabElement.querySelector('.itemsContainer');
alphaPickerElement.addEventListener('alphavaluechanged', function (e) {
const newValue = e.detail.value;
const query = getQuery();
if (newValue === '#') {
query.NameLessThan = 'A';
delete query.NameStartsWith;
} else {
query.NameStartsWith = newValue;
delete query.NameLessThan;
}
query.StartIndex = 0;
reloadItems();
});
this.alphaPicker = new AlphaPicker({
element: alphaPickerElement,
valueChangeEvent: 'click'
});
tabElement.querySelector('.alphaPicker').classList.add('alphabetPicker-right');
alphaPickerElement.classList.add('alphaPicker-fixed-right');
itemsContainer.classList.add('padded-right-withalphapicker');
tabElement.querySelector('.btnFilter').addEventListener('click', () => {
this.showFilterMenu();
});
tabElement.querySelector('.btnSort').addEventListener('click', (e) => {
libraryBrowser.showSortMenu({
items: [{
name: globalize.translate('Name'),
id: 'SortName'
}, {
name: globalize.translate('AlbumArtist'),
id: 'AlbumArtist,SortName'
}, {
name: globalize.translate('OptionCommunityRating'),
id: 'CommunityRating,SortName'
}, {
name: globalize.translate('OptionCriticRating'),
id: 'CriticRating,SortName'
}, {
name: globalize.translate('OptionDateAdded'),
id: 'DateCreated,SortName'
}, {
name: globalize.translate('OptionReleaseDate'),
id: 'ProductionYear,PremiereDate,SortName'
}, {
name: globalize.translate('OptionRandom'),
id: 'Random,SortName'
}],
callback: function () {
getQuery().StartIndex = 0;
reloadItems();
},
query: getQuery(),
button: e.target
});
});
const btnSelectView = tabElement.querySelector('.btnSelectView');
btnSelectView.addEventListener('click', (e) => {
libraryBrowser.showLayoutMenu(e.target, this.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(','));
});
btnSelectView.addEventListener('layoutchange', function (e) {
const viewStyle = e.detail.viewStyle;
getPageData().view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
getQuery().StartIndex = 0;
onViewStyleChange();
reloadItems();
});
tabElement.querySelector('.btnPlayAll').addEventListener('click', playAll);
tabElement.querySelector('.btnShuffle').addEventListener('click', shuffle);
};
initPage(tabContent);
onViewStyleChange();
this.renderTab = () => {
reloadItems();
this.alphaPicker?.updateControls(getQuery());
};
}

View file

@ -9,237 +9,234 @@ import Events from '../../utils/events.ts';
import '../../elements/emby-itemscontainer/emby-itemscontainer';
/* eslint-disable indent */
export default function (view, params, tabContent) {
function getPageData(context) {
const key = getSavedQueryKey(context);
let pageData = data[key];
export default function (view, params, tabContent) {
function getPageData(context) {
const key = getSavedQueryKey(context);
let pageData = data[key];
if (!pageData) {
const queryValues = {
SortBy: 'SortName',
SortOrder: 'Ascending',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,SortName,BasicSyncInfo',
StartIndex: 0,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb'
};
if (!pageData) {
const queryValues = {
SortBy: 'SortName',
SortOrder: 'Ascending',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,SortName,BasicSyncInfo',
StartIndex: 0,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb'
};
if (userSettings.libraryPageSize() > 0) {
queryValues['Limit'] = userSettings.libraryPageSize();
}
pageData = data[key] = {
query: queryValues,
view: libraryBrowser.getSavedView(key) || 'Poster'
};
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
if (userSettings.libraryPageSize() > 0) {
queryValues['Limit'] = userSettings.libraryPageSize();
}
return pageData;
pageData = data[key] = {
query: queryValues,
view: libraryBrowser.getSavedView(key) || 'Poster'
};
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
function getQuery(context) {
return getPageData(context).query;
}
const getSavedQueryKey = (context) => {
if (!context.savedQueryKey) {
context.savedQueryKey = libraryBrowser.getSavedQueryKey(this.mode);
}
return context.savedQueryKey;
};
const onViewStyleChange = () => {
const viewStyle = this.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') {
itemsContainer.classList.add('vertical-list');
itemsContainer.classList.remove('vertical-wrap');
} else {
itemsContainer.classList.remove('vertical-list');
itemsContainer.classList.add('vertical-wrap');
}
itemsContainer.innerHTML = '';
};
const reloadItems = (page) => {
loading.show();
isLoading = true;
const query = getQuery(page);
const promise = this.mode == 'albumartists' ?
ApiClient.getAlbumArtists(ApiClient.getCurrentUserId(), query) :
ApiClient.getArtists(ApiClient.getCurrentUserId(), query);
promise.then((result) => {
function onNextPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex += query.Limit;
}
reloadItems(tabContent);
}
function onPreviousPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
}
reloadItems(tabContent);
}
window.scrollTo(0, 0);
this.alphaPicker?.updateControls(query);
let html;
const pagingHtml = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
showLimit: false,
updatePageSizeSetting: false,
addLayoutButton: false,
sortButton: false,
filterButton: false
});
const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'List') {
html = listView.getListViewHtml({
items: result.Items,
sortBy: query.SortBy
});
} else if (viewStyle == 'PosterCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'square',
context: 'music',
showTitle: true,
coverImage: true,
cardLayout: true
});
} else {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'square',
context: 'music',
showTitle: true,
coverImage: true,
lazy: true,
centerText: true,
overlayPlayButton: true
});
}
let elems = tabContent.querySelectorAll('.paging');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].innerHTML = pagingHtml;
}
elems = tabContent.querySelectorAll('.btnNextPage');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onNextPageClick);
}
elems = tabContent.querySelectorAll('.btnPreviousPage');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onPreviousPageClick);
}
const itemsContainer = tabContent.querySelector('.itemsContainer');
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
loading.hide();
isLoading = false;
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(tabContent);
});
});
};
const data = {};
let isLoading = false;
this.showFilterMenu = function () {
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
const filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: this.mode,
serverId: ApiClient.serverId()
});
Events.on(filterDialog, 'filterchange', function () {
getQuery(tabContent).StartIndex = 0;
reloadItems(tabContent);
});
filterDialog.show();
});
};
this.getCurrentViewStyle = function () {
return getPageData(tabContent).view;
};
const initPage = (tabElement) => {
const alphaPickerElement = tabElement.querySelector('.alphaPicker');
const itemsContainer = tabElement.querySelector('.itemsContainer');
alphaPickerElement.addEventListener('alphavaluechanged', function (e) {
const newValue = e.detail.value;
const query = getQuery(tabElement);
if (newValue === '#') {
query.NameLessThan = 'A';
delete query.NameStartsWith;
} else {
query.NameStartsWith = newValue;
delete query.NameLessThan;
}
query.StartIndex = 0;
reloadItems(tabElement);
});
this.alphaPicker = new AlphaPicker({
element: alphaPickerElement,
valueChangeEvent: 'click'
});
tabElement.querySelector('.alphaPicker').classList.add('alphabetPicker-right');
alphaPickerElement.classList.add('alphaPicker-fixed-right');
itemsContainer.classList.add('padded-right-withalphapicker');
tabElement.querySelector('.btnFilter').addEventListener('click', () => {
this.showFilterMenu();
});
const btnSelectView = tabElement.querySelector('.btnSelectView');
btnSelectView.addEventListener('click', (e) => {
libraryBrowser.showLayoutMenu(e.target, this.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(','));
});
btnSelectView.addEventListener('layoutchange', function (e) {
const viewStyle = e.detail.viewStyle;
getPageData(tabElement).view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(tabElement), viewStyle);
getQuery(tabElement).StartIndex = 0;
onViewStyleChange();
reloadItems(tabElement);
});
};
initPage(tabContent);
onViewStyleChange();
this.renderTab = () => {
reloadItems(tabContent);
this.alphaPicker?.updateControls(getQuery(tabContent));
};
return pageData;
}
/* eslint-enable indent */
function getQuery(context) {
return getPageData(context).query;
}
const getSavedQueryKey = (context) => {
if (!context.savedQueryKey) {
context.savedQueryKey = libraryBrowser.getSavedQueryKey(this.mode);
}
return context.savedQueryKey;
};
const onViewStyleChange = () => {
const viewStyle = this.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') {
itemsContainer.classList.add('vertical-list');
itemsContainer.classList.remove('vertical-wrap');
} else {
itemsContainer.classList.remove('vertical-list');
itemsContainer.classList.add('vertical-wrap');
}
itemsContainer.innerHTML = '';
};
const reloadItems = (page) => {
loading.show();
isLoading = true;
const query = getQuery(page);
const promise = this.mode == 'albumartists' ?
ApiClient.getAlbumArtists(ApiClient.getCurrentUserId(), query) :
ApiClient.getArtists(ApiClient.getCurrentUserId(), query);
promise.then((result) => {
function onNextPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex += query.Limit;
}
reloadItems(tabContent);
}
function onPreviousPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
}
reloadItems(tabContent);
}
window.scrollTo(0, 0);
this.alphaPicker?.updateControls(query);
let html;
const pagingHtml = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
showLimit: false,
updatePageSizeSetting: false,
addLayoutButton: false,
sortButton: false,
filterButton: false
});
const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'List') {
html = listView.getListViewHtml({
items: result.Items,
sortBy: query.SortBy
});
} else if (viewStyle == 'PosterCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'square',
context: 'music',
showTitle: true,
coverImage: true,
cardLayout: true
});
} else {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'square',
context: 'music',
showTitle: true,
coverImage: true,
lazy: true,
centerText: true,
overlayPlayButton: true
});
}
let elems = tabContent.querySelectorAll('.paging');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].innerHTML = pagingHtml;
}
elems = tabContent.querySelectorAll('.btnNextPage');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onNextPageClick);
}
elems = tabContent.querySelectorAll('.btnPreviousPage');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onPreviousPageClick);
}
const itemsContainer = tabContent.querySelector('.itemsContainer');
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
loading.hide();
isLoading = false;
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(tabContent);
});
});
};
const data = {};
let isLoading = false;
this.showFilterMenu = function () {
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
const filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: this.mode,
serverId: ApiClient.serverId()
});
Events.on(filterDialog, 'filterchange', function () {
getQuery(tabContent).StartIndex = 0;
reloadItems(tabContent);
});
filterDialog.show();
});
};
this.getCurrentViewStyle = function () {
return getPageData(tabContent).view;
};
const initPage = (tabElement) => {
const alphaPickerElement = tabElement.querySelector('.alphaPicker');
const itemsContainer = tabElement.querySelector('.itemsContainer');
alphaPickerElement.addEventListener('alphavaluechanged', function (e) {
const newValue = e.detail.value;
const query = getQuery(tabElement);
if (newValue === '#') {
query.NameLessThan = 'A';
delete query.NameStartsWith;
} else {
query.NameStartsWith = newValue;
delete query.NameLessThan;
}
query.StartIndex = 0;
reloadItems(tabElement);
});
this.alphaPicker = new AlphaPicker({
element: alphaPickerElement,
valueChangeEvent: 'click'
});
tabElement.querySelector('.alphaPicker').classList.add('alphabetPicker-right');
alphaPickerElement.classList.add('alphaPicker-fixed-right');
itemsContainer.classList.add('padded-right-withalphapicker');
tabElement.querySelector('.btnFilter').addEventListener('click', () => {
this.showFilterMenu();
});
const btnSelectView = tabElement.querySelector('.btnSelectView');
btnSelectView.addEventListener('click', (e) => {
libraryBrowser.showLayoutMenu(e.target, this.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(','));
});
btnSelectView.addEventListener('layoutchange', function (e) {
const viewStyle = e.detail.viewStyle;
getPageData(tabElement).view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(tabElement), viewStyle);
getQuery(tabElement).StartIndex = 0;
onViewStyleChange();
reloadItems(tabElement);
});
};
initPage(tabContent);
onViewStyleChange();
this.renderTab = () => {
reloadItems(tabContent);
this.alphaPicker?.updateControls(getQuery(tabContent));
};
}

View file

@ -3,132 +3,129 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
import imageLoader from '../../components/images/imageLoader';
import loading from '../../components/loading/loading';
/* eslint-disable indent */
export default function (view, params, tabContent) {
function getPageData() {
const key = getSavedQueryKey();
let pageData = data[key];
export default function (view, params, tabContent) {
function getPageData() {
const key = getSavedQueryKey();
let pageData = data[key];
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,ItemCounts',
StartIndex: 0
},
view: libraryBrowser.getSavedView(key) || 'Poster'
};
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
return pageData;
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,ItemCounts',
StartIndex: 0
},
view: libraryBrowser.getSavedView(key) || 'Poster'
};
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
function getQuery() {
return getPageData().query;
}
function getSavedQueryKey() {
return libraryBrowser.getSavedQueryKey('genres');
}
function getPromise() {
loading.show();
const query = getQuery();
return ApiClient.getGenres(ApiClient.getCurrentUserId(), query);
}
const reloadItems = (context, promise) => {
const query = getQuery();
promise.then((result) => {
let html = '';
const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'Thumb') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
preferThumb: true,
context: 'music',
centerText: true,
overlayMoreButton: true,
showTitle: true
});
} else if (viewStyle == 'ThumbCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
preferThumb: true,
context: 'music',
cardLayout: true,
showTitle: true
});
} else if (viewStyle == 'PosterCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'auto',
context: 'music',
cardLayout: true,
showTitle: true
});
} else if (viewStyle == 'Poster') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'auto',
context: 'music',
centerText: true,
overlayMoreButton: true,
showTitle: true
});
}
const elem = context.querySelector('#items');
elem.innerHTML = html;
imageLoader.lazyChildren(elem);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
loading.hide();
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(context);
});
});
};
function fullyReload() {
this.preRender();
this.renderTab();
}
const data = {};
this.getViewStyles = function () {
return 'Poster,PosterCard,Thumb,ThumbCard'.split(',');
};
this.getCurrentViewStyle = function () {
return getPageData().view;
};
this.setCurrentViewStyle = function (viewStyle) {
getPageData().view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
fullyReload();
};
this.enableViewSelection = true;
let promise;
this.preRender = function () {
promise = getPromise();
};
this.renderTab = function () {
reloadItems(tabContent, promise);
};
return pageData;
}
/* eslint-enable indent */
function getQuery() {
return getPageData().query;
}
function getSavedQueryKey() {
return libraryBrowser.getSavedQueryKey('genres');
}
function getPromise() {
loading.show();
const query = getQuery();
return ApiClient.getGenres(ApiClient.getCurrentUserId(), query);
}
const reloadItems = (context, promise) => {
const query = getQuery();
promise.then((result) => {
let html = '';
const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'Thumb') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
preferThumb: true,
context: 'music',
centerText: true,
overlayMoreButton: true,
showTitle: true
});
} else if (viewStyle == 'ThumbCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
preferThumb: true,
context: 'music',
cardLayout: true,
showTitle: true
});
} else if (viewStyle == 'PosterCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'auto',
context: 'music',
cardLayout: true,
showTitle: true
});
} else if (viewStyle == 'Poster') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'auto',
context: 'music',
centerText: true,
overlayMoreButton: true,
showTitle: true
});
}
const elem = context.querySelector('#items');
elem.innerHTML = html;
imageLoader.lazyChildren(elem);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
loading.hide();
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(context);
});
});
};
function fullyReload() {
this.preRender();
this.renderTab();
}
const data = {};
this.getViewStyles = function () {
return 'Poster,PosterCard,Thumb,ThumbCard'.split(',');
};
this.getCurrentViewStyle = function () {
return getPageData().view;
};
this.setCurrentViewStyle = function (viewStyle) {
getPageData().view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
fullyReload();
};
this.enableViewSelection = true;
let promise;
this.preRender = function () {
promise = getPromise();
};
this.renderTab = function () {
reloadItems(tabContent, promise);
};
}

View file

@ -3,87 +3,84 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
import imageLoader from '../../components/images/imageLoader';
import loading from '../../components/loading/loading';
/* eslint-disable indent */
export default function (view, params, tabContent) {
function getPageData() {
const key = getSavedQueryKey();
let pageData = data[key];
export default function (view, params, tabContent) {
function getPageData() {
const key = getSavedQueryKey();
let pageData = data[key];
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'Playlist',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,SortName,CanDelete',
StartIndex: 0
},
view: libraryBrowser.getSavedView(key) || 'Poster'
};
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
return pageData;
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'Playlist',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,SortName,CanDelete',
StartIndex: 0
},
view: libraryBrowser.getSavedView(key) || 'Poster'
};
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
function getQuery() {
return getPageData().query;
}
function getSavedQueryKey() {
return libraryBrowser.getSavedQueryKey('genres');
}
function getPromise() {
loading.show();
const query = getQuery();
return ApiClient.getItems(ApiClient.getCurrentUserId(), query);
}
function reloadItems(context, promise) {
const query = getQuery();
promise.then(function (result) {
let html = '';
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'square',
showTitle: true,
coverImage: true,
centerText: true,
overlayPlayButton: true,
allowBottomPadding: true,
cardLayout: false
});
const elem = context.querySelector('#items');
elem.innerHTML = html;
imageLoader.lazyChildren(elem);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
loading.hide();
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(context);
});
});
}
const data = {};
this.getCurrentViewStyle = function () {
return getPageData().view;
};
let promise;
this.preRender = function () {
promise = getPromise();
};
this.renderTab = function () {
reloadItems(tabContent, promise);
};
return pageData;
}
/* eslint-enable indent */
function getQuery() {
return getPageData().query;
}
function getSavedQueryKey() {
return libraryBrowser.getSavedQueryKey('genres');
}
function getPromise() {
loading.show();
const query = getQuery();
return ApiClient.getItems(ApiClient.getCurrentUserId(), query);
}
function reloadItems(context, promise) {
const query = getQuery();
promise.then(function (result) {
let html = '';
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'square',
showTitle: true,
coverImage: true,
centerText: true,
overlayPlayButton: true,
allowBottomPadding: true,
cardLayout: false
});
const elem = context.querySelector('#items');
elem.innerHTML = html;
imageLoader.lazyChildren(elem);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
loading.hide();
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(context);
});
});
}
const data = {};
this.getCurrentViewStyle = function () {
return getPageData().view;
};
let promise;
this.preRender = function () {
promise = getPromise();
};
this.renderTab = function () {
reloadItems(tabContent, promise);
};
}

View file

@ -16,386 +16,383 @@ import '../../elements/emby-button/emby-button';
import '../../styles/flexstyles.scss';
import Dashboard from '../../utils/dashboard';
/* eslint-disable indent */
function itemsPerRow() {
const screenWidth = dom.getWindowSize().innerWidth;
function itemsPerRow() {
const screenWidth = dom.getWindowSize().innerWidth;
if (screenWidth >= 1920) {
return 9;
}
if (screenWidth >= 1200) {
return 12;
}
if (screenWidth >= 1000) {
return 10;
}
return 8;
if (screenWidth >= 1920) {
return 9;
}
function enableScrollX() {
return !layoutManager.desktop;
if (screenWidth >= 1200) {
return 12;
}
function getSquareShape() {
return enableScrollX() ? 'overflowSquare' : 'square';
if (screenWidth >= 1000) {
return 10;
}
function loadLatest(page, parentId) {
return 8;
}
function enableScrollX() {
return !layoutManager.desktop;
}
function getSquareShape() {
return enableScrollX() ? 'overflowSquare' : 'square';
}
function loadLatest(page, parentId) {
loading.show();
const userId = ApiClient.getCurrentUserId();
const options = {
IncludeItemTypes: 'Audio',
Limit: enableScrollX() ? 3 * itemsPerRow() : 2 * itemsPerRow(),
Fields: 'PrimaryImageAspectRatio,BasicSyncInfo',
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
EnableTotalRecordCount: false
};
ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)).then(function (items) {
const elem = page.querySelector('#recentlyAddedSongs');
elem.innerHTML = cardBuilder.getCardsHtml({
items: items,
showUnplayedIndicator: false,
showLatestItemsPopup: false,
shape: getSquareShape(),
showTitle: true,
showParentTitle: true,
lazy: true,
centerText: true,
overlayPlayButton: true,
allowBottomPadding: !enableScrollX(),
cardLayout: false,
coverImage: true
});
imageLoader.lazyChildren(elem);
loading.hide();
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(page);
});
});
}
function loadRecentlyPlayed(page, parentId) {
const options = {
SortBy: 'DatePlayed',
SortOrder: 'Descending',
IncludeItemTypes: 'Audio',
Limit: itemsPerRow(),
Recursive: true,
Fields: 'PrimaryImageAspectRatio,AudioInfo',
Filters: 'IsPlayed',
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
EnableTotalRecordCount: false
};
ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) {
const elem = page.querySelector('#recentlyPlayed');
if (result.Items.length) {
elem.classList.remove('hide');
} else {
elem.classList.add('hide');
}
const itemsContainer = elem.querySelector('.itemsContainer');
itemsContainer.innerHTML = cardBuilder.getCardsHtml({
items: result.Items,
showUnplayedIndicator: false,
shape: getSquareShape(),
showTitle: true,
showParentTitle: true,
action: 'instantmix',
lazy: true,
centerText: true,
overlayMoreButton: true,
allowBottomPadding: !enableScrollX(),
cardLayout: false,
coverImage: true
});
imageLoader.lazyChildren(itemsContainer);
});
}
function loadFrequentlyPlayed(page, parentId) {
const options = {
SortBy: 'PlayCount',
SortOrder: 'Descending',
IncludeItemTypes: 'Audio',
Limit: itemsPerRow(),
Recursive: true,
Fields: 'PrimaryImageAspectRatio,AudioInfo',
Filters: 'IsPlayed',
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
EnableTotalRecordCount: false
};
ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) {
const elem = page.querySelector('#topPlayed');
if (result.Items.length) {
elem.classList.remove('hide');
} else {
elem.classList.add('hide');
}
const itemsContainer = elem.querySelector('.itemsContainer');
itemsContainer.innerHTML = cardBuilder.getCardsHtml({
items: result.Items,
showUnplayedIndicator: false,
shape: getSquareShape(),
showTitle: true,
showParentTitle: true,
action: 'instantmix',
lazy: true,
centerText: true,
overlayMoreButton: true,
allowBottomPadding: !enableScrollX(),
cardLayout: false,
coverImage: true
});
imageLoader.lazyChildren(itemsContainer);
});
}
function loadSuggestionsTab(page, tabContent, parentId) {
console.debug('loadSuggestionsTab');
loadLatest(tabContent, parentId);
loadRecentlyPlayed(tabContent, parentId);
loadFrequentlyPlayed(tabContent, parentId);
import('../../components/favoriteitems').then(({ default: favoriteItems }) => {
favoriteItems.render(tabContent, ApiClient.getCurrentUserId(), parentId, ['favoriteArtists', 'favoriteAlbums', 'favoriteSongs']);
});
}
function getTabs() {
return [{
name: globalize.translate('Albums')
}, {
name: globalize.translate('Suggestions')
}, {
name: globalize.translate('HeaderAlbumArtists')
}, {
name: globalize.translate('Artists')
}, {
name: globalize.translate('Playlists')
}, {
name: globalize.translate('Songs')
}, {
name: globalize.translate('Genres')
}];
}
function getDefaultTabIndex(folderId) {
switch (userSettings.get('landing-' + folderId)) {
case 'suggestions':
return 1;
case 'albumartists':
return 2;
case 'artists':
return 3;
case 'playlists':
return 4;
case 'songs':
return 5;
case 'genres':
return 6;
default:
return 0;
}
}
export default function (view, params) {
function reload() {
loading.show();
const userId = ApiClient.getCurrentUserId();
const options = {
IncludeItemTypes: 'Audio',
Limit: enableScrollX() ? 3 * itemsPerRow() : 2 * itemsPerRow(),
Fields: 'PrimaryImageAspectRatio,BasicSyncInfo',
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
EnableTotalRecordCount: false
};
ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)).then(function (items) {
const elem = page.querySelector('#recentlyAddedSongs');
elem.innerHTML = cardBuilder.getCardsHtml({
items: items,
showUnplayedIndicator: false,
showLatestItemsPopup: false,
shape: getSquareShape(),
showTitle: true,
showParentTitle: true,
lazy: true,
centerText: true,
overlayPlayButton: true,
allowBottomPadding: !enableScrollX(),
cardLayout: false,
coverImage: true
});
imageLoader.lazyChildren(elem);
loading.hide();
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(page);
});
});
const tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
loadSuggestionsTab(view, tabContent, params.topParentId);
}
function loadRecentlyPlayed(page, parentId) {
const options = {
SortBy: 'DatePlayed',
SortOrder: 'Descending',
IncludeItemTypes: 'Audio',
Limit: itemsPerRow(),
Recursive: true,
Fields: 'PrimaryImageAspectRatio,AudioInfo',
Filters: 'IsPlayed',
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
EnableTotalRecordCount: false
};
ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) {
const elem = page.querySelector('#recentlyPlayed');
function setScrollClasses(elem, scrollX) {
if (scrollX) {
elem.classList.add('hiddenScrollX');
if (result.Items.length) {
elem.classList.remove('hide');
} else {
elem.classList.add('hide');
if (layoutManager.tv) {
elem.classList.add('smoothScrollX');
}
const itemsContainer = elem.querySelector('.itemsContainer');
itemsContainer.innerHTML = cardBuilder.getCardsHtml({
items: result.Items,
showUnplayedIndicator: false,
shape: getSquareShape(),
showTitle: true,
showParentTitle: true,
action: 'instantmix',
lazy: true,
centerText: true,
overlayMoreButton: true,
allowBottomPadding: !enableScrollX(),
cardLayout: false,
coverImage: true
});
imageLoader.lazyChildren(itemsContainer);
});
}
function loadFrequentlyPlayed(page, parentId) {
const options = {
SortBy: 'PlayCount',
SortOrder: 'Descending',
IncludeItemTypes: 'Audio',
Limit: itemsPerRow(),
Recursive: true,
Fields: 'PrimaryImageAspectRatio,AudioInfo',
Filters: 'IsPlayed',
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
EnableTotalRecordCount: false
};
ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) {
const elem = page.querySelector('#topPlayed');
if (result.Items.length) {
elem.classList.remove('hide');
} else {
elem.classList.add('hide');
}
const itemsContainer = elem.querySelector('.itemsContainer');
itemsContainer.innerHTML = cardBuilder.getCardsHtml({
items: result.Items,
showUnplayedIndicator: false,
shape: getSquareShape(),
showTitle: true,
showParentTitle: true,
action: 'instantmix',
lazy: true,
centerText: true,
overlayMoreButton: true,
allowBottomPadding: !enableScrollX(),
cardLayout: false,
coverImage: true
});
imageLoader.lazyChildren(itemsContainer);
});
}
function loadSuggestionsTab(page, tabContent, parentId) {
console.debug('loadSuggestionsTab');
loadLatest(tabContent, parentId);
loadRecentlyPlayed(tabContent, parentId);
loadFrequentlyPlayed(tabContent, parentId);
import('../../components/favoriteitems').then(({ default: favoriteItems }) => {
favoriteItems.render(tabContent, ApiClient.getCurrentUserId(), parentId, ['favoriteArtists', 'favoriteAlbums', 'favoriteSongs']);
});
}
function getTabs() {
return [{
name: globalize.translate('Albums')
}, {
name: globalize.translate('Suggestions')
}, {
name: globalize.translate('HeaderAlbumArtists')
}, {
name: globalize.translate('Artists')
}, {
name: globalize.translate('Playlists')
}, {
name: globalize.translate('Songs')
}, {
name: globalize.translate('Genres')
}];
}
function getDefaultTabIndex(folderId) {
switch (userSettings.get('landing-' + folderId)) {
case 'suggestions':
return 1;
case 'albumartists':
return 2;
case 'artists':
return 3;
case 'playlists':
return 4;
case 'songs':
return 5;
case 'genres':
return 6;
default:
return 0;
elem.classList.add('scrollX');
elem.classList.remove('vertical-wrap');
} else {
elem.classList.remove('hiddenScrollX');
elem.classList.remove('smoothScrollX');
elem.classList.remove('scrollX');
elem.classList.add('vertical-wrap');
}
}
export default function (view, params) {
function reload() {
loading.show();
const tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
loadSuggestionsTab(view, tabContent, params.topParentId);
function onBeforeTabChange(e) {
preLoadTab(view, parseInt(e.detail.selectedTabIndex, 10));
}
function onTabChange(e) {
loadTab(view, parseInt(e.detail.selectedTabIndex, 10));
}
function getTabContainers() {
return view.querySelectorAll('.pageTabContent');
}
function initTabs() {
mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange);
}
const getTabController = (page, index, callback) => {
let depends;
switch (index) {
case 0:
depends = 'musicalbums';
break;
case 1:
depends = 'musicrecommended';
break;
case 2:
case 3:
depends = 'musicartists';
break;
case 4:
depends = 'musicplaylists';
break;
case 5:
depends = 'songs';
break;
case 6:
depends = 'musicgenres';
break;
}
function setScrollClasses(elem, scrollX) {
if (scrollX) {
elem.classList.add('hiddenScrollX');
import(`../music/${depends}`).then(({ default: controllerFactory }) => {
let tabContent;
if (layoutManager.tv) {
elem.classList.add('smoothScrollX');
}
elem.classList.add('scrollX');
elem.classList.remove('vertical-wrap');
} else {
elem.classList.remove('hiddenScrollX');
elem.classList.remove('smoothScrollX');
elem.classList.remove('scrollX');
elem.classList.add('vertical-wrap');
}
}
function onBeforeTabChange(e) {
preLoadTab(view, parseInt(e.detail.selectedTabIndex, 10));
}
function onTabChange(e) {
loadTab(view, parseInt(e.detail.selectedTabIndex, 10));
}
function getTabContainers() {
return view.querySelectorAll('.pageTabContent');
}
function initTabs() {
mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange);
}
const getTabController = (page, index, callback) => {
let depends;
switch (index) {
case 0:
depends = 'musicalbums';
break;
case 1:
depends = 'musicrecommended';
break;
case 2:
case 3:
depends = 'musicartists';
break;
case 4:
depends = 'musicplaylists';
break;
case 5:
depends = 'songs';
break;
case 6:
depends = 'musicgenres';
break;
if (index == 1) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
this.tabContent = tabContent;
}
import(`../music/${depends}`).then(({ default: controllerFactory }) => {
let tabContent;
let controller = tabControllers[index];
if (index == 1) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
this.tabContent = tabContent;
}
if (!controller) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
let controller = tabControllers[index];
if (!controller) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
if (index === 1) {
controller = this;
} else {
controller = new controllerFactory(view, params, tabContent);
}
if (index == 2) {
controller.mode = 'albumartists';
} else if (index == 3) {
controller.mode = 'artists';
}
tabControllers[index] = controller;
if (controller.initTab) {
controller.initTab();
}
}
callback(controller);
});
};
function preLoadTab(page, index) {
getTabController(page, index, function (controller) {
if (renderedTabs.indexOf(index) == -1 && controller.preRender) {
controller.preRender();
}
});
}
function loadTab(page, index) {
currentTabIndex = index;
getTabController(page, index, function (controller) {
if (renderedTabs.indexOf(index) == -1) {
renderedTabs.push(index);
controller.renderTab();
}
});
}
function onInputCommand(e) {
if (e.detail.command === 'search') {
e.preventDefault();
Dashboard.navigate('search.html?collectionType=music&parentId=' + params.topParentId);
}
}
let currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId), 10);
const suggestionsTabIndex = 1;
this.initTab = function () {
const tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
const containers = tabContent.querySelectorAll('.itemsContainer');
for (let i = 0, length = containers.length; i < length; i++) {
setScrollClasses(containers[i], browser.mobile);
}
};
this.renderTab = function () {
reload();
};
const tabControllers = [];
const renderedTabs = [];
view.addEventListener('viewshow', function () {
initTabs();
if (!view.getAttribute('data-title')) {
const parentId = params.topParentId;
if (parentId) {
ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) {
view.setAttribute('data-title', item.Name);
libraryMenu.setTitle(item.Name);
});
if (index === 1) {
controller = this;
} else {
view.setAttribute('data-title', globalize.translate('TabMusic'));
libraryMenu.setTitle(globalize.translate('TabMusic'));
controller = new controllerFactory(view, params, tabContent);
}
if (index == 2) {
controller.mode = 'albumartists';
} else if (index == 3) {
controller.mode = 'artists';
}
tabControllers[index] = controller;
if (controller.initTab) {
controller.initTab();
}
}
inputManager.on(window, onInputCommand);
callback(controller);
});
view.addEventListener('viewbeforehide', function () {
inputManager.off(window, onInputCommand);
});
view.addEventListener('viewdestroy', function () {
tabControllers.forEach(function (t) {
if (t.destroy) {
t.destroy();
}
});
};
function preLoadTab(page, index) {
getTabController(page, index, function (controller) {
if (renderedTabs.indexOf(index) == -1 && controller.preRender) {
controller.preRender();
}
});
}
/* eslint-enable indent */
function loadTab(page, index) {
currentTabIndex = index;
getTabController(page, index, function (controller) {
if (renderedTabs.indexOf(index) == -1) {
renderedTabs.push(index);
controller.renderTab();
}
});
}
function onInputCommand(e) {
if (e.detail.command === 'search') {
e.preventDefault();
Dashboard.navigate('search.html?collectionType=music&parentId=' + params.topParentId);
}
}
let currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId), 10);
const suggestionsTabIndex = 1;
this.initTab = function () {
const tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
const containers = tabContent.querySelectorAll('.itemsContainer');
for (let i = 0, length = containers.length; i < length; i++) {
setScrollClasses(containers[i], browser.mobile);
}
};
this.renderTab = function () {
reload();
};
const tabControllers = [];
const renderedTabs = [];
view.addEventListener('viewshow', function () {
initTabs();
if (!view.getAttribute('data-title')) {
const parentId = params.topParentId;
if (parentId) {
ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) {
view.setAttribute('data-title', item.Name);
libraryMenu.setTitle(item.Name);
});
} else {
view.setAttribute('data-title', globalize.translate('TabMusic'));
libraryMenu.setTitle(globalize.translate('TabMusic'));
}
}
inputManager.on(window, onInputCommand);
});
view.addEventListener('viewbeforehide', function () {
inputManager.off(window, onInputCommand);
});
view.addEventListener('viewdestroy', function () {
tabControllers.forEach(function (t) {
if (t.destroy) {
t.destroy();
}
});
});
}

File diff suppressed because it is too large Load diff

View file

@ -6,69 +6,66 @@ import Dashboard from '../../../utils/dashboard';
import ServerConnections from '../../../components/ServerConnections';
import { ConnectionState } from '../../../utils/jellyfin-apiclient/ConnectionState.ts';
/* eslint-disable indent */
function handleConnectionResult(page, result) {
loading.hide();
switch (result.State) {
case ConnectionState.SignedIn: {
const apiClient = result.ApiClient;
Dashboard.onServerChanged(apiClient.getCurrentUserId(), apiClient.accessToken(), apiClient);
Dashboard.navigate('home.html');
break;
}
case ConnectionState.ServerSignIn:
Dashboard.navigate('login.html?serverid=' + result.Servers[0].Id, false, 'none');
break;
case ConnectionState.ServerSelection:
Dashboard.navigate('selectserver.html', false, 'none');
break;
case ConnectionState.ServerUpdateNeeded:
Dashboard.alert({
message: globalize.translate('ServerUpdateNeeded', '<a href="https://github.com/jellyfin/jellyfin">https://github.com/jellyfin/jellyfin</a>')
});
break;
case ConnectionState.Unavailable:
Dashboard.alert({
message: globalize.translate('MessageUnableToConnectToServer'),
title: globalize.translate('HeaderConnectionFailure')
});
function handleConnectionResult(page, result) {
loading.hide();
switch (result.State) {
case ConnectionState.SignedIn: {
const apiClient = result.ApiClient;
Dashboard.onServerChanged(apiClient.getCurrentUserId(), apiClient.accessToken(), apiClient);
Dashboard.navigate('home.html');
break;
}
case ConnectionState.ServerSignIn:
Dashboard.navigate('login.html?serverid=' + result.Servers[0].Id, false, 'none');
break;
case ConnectionState.ServerSelection:
Dashboard.navigate('selectserver.html', false, 'none');
break;
case ConnectionState.ServerUpdateNeeded:
Dashboard.alert({
message: globalize.translate('ServerUpdateNeeded', '<a href="https://github.com/jellyfin/jellyfin">https://github.com/jellyfin/jellyfin</a>')
});
break;
case ConnectionState.Unavailable:
Dashboard.alert({
message: globalize.translate('MessageUnableToConnectToServer'),
title: globalize.translate('HeaderConnectionFailure')
});
}
}
function submitServer(page) {
loading.show();
const host = page.querySelector('#txtServerHost').value;
ServerConnections.connectToAddress(host, {
enableAutoLogin: appSettings.enableAutoLogin()
}).then(function(result) {
handleConnectionResult(page, result);
}, function() {
handleConnectionResult(page, {
State: ConnectionState.Unavailable
});
});
}
export default function(view) {
view.querySelector('.addServerForm').addEventListener('submit', onServerSubmit);
view.querySelector('.btnCancel').addEventListener('click', goBack);
import('../../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(view);
});
function onServerSubmit(e) {
submitServer(view);
e.preventDefault();
return false;
}
function submitServer(page) {
loading.show();
const host = page.querySelector('#txtServerHost').value;
ServerConnections.connectToAddress(host, {
enableAutoLogin: appSettings.enableAutoLogin()
}).then(function(result) {
handleConnectionResult(page, result);
}, function() {
handleConnectionResult(page, {
State: ConnectionState.Unavailable
});
function goBack() {
import('../../../components/appRouter').then(({ appRouter }) => {
appRouter.back();
});
}
}
export default function(view) {
view.querySelector('.addServerForm').addEventListener('submit', onServerSubmit);
view.querySelector('.btnCancel').addEventListener('click', goBack);
import('../../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(view);
});
function onServerSubmit(e) {
submitServer(view);
e.preventDefault();
return false;
}
function goBack() {
import('../../../components/appRouter').then(({ appRouter }) => {
appRouter.back();
});
}
}
/* eslint-enable indent */

View file

@ -1,59 +1,56 @@
import globalize from '../../../scripts/globalize';
import Dashboard from '../../../utils/dashboard';
/* eslint-disable indent */
function processForgotPasswordResult(result) {
if (result.Action == 'ContactAdmin') {
Dashboard.alert({
message: globalize.translate('MessageContactAdminToResetPassword'),
title: globalize.translate('ButtonForgotPassword')
});
return;
}
if (result.Action == 'InNetworkRequired') {
Dashboard.alert({
message: globalize.translate('MessageForgotPasswordInNetworkRequired'),
title: globalize.translate('ButtonForgotPassword')
});
return;
}
if (result.Action == 'PinCode') {
let msg = globalize.translate('MessageForgotPasswordFileCreated');
msg += '<br/>';
msg += '<br/>';
msg += 'Enter PIN here to finish Password Reset<br/>';
msg += '<br/>';
msg += result.PinFile;
msg += '<br/>';
Dashboard.alert({
message: msg,
title: globalize.translate('ButtonForgotPassword'),
callback: function () {
Dashboard.navigate('forgotpasswordpin.html');
}
});
}
function processForgotPasswordResult(result) {
if (result.Action == 'ContactAdmin') {
Dashboard.alert({
message: globalize.translate('MessageContactAdminToResetPassword'),
title: globalize.translate('ButtonForgotPassword')
});
return;
}
export default function (view) {
function onSubmit(e) {
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('Users/ForgotPassword'),
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify({
EnteredUsername: view.querySelector('#txtName').value
})
}).then(processForgotPasswordResult);
e.preventDefault();
return false;
}
view.querySelector('form').addEventListener('submit', onSubmit);
if (result.Action == 'InNetworkRequired') {
Dashboard.alert({
message: globalize.translate('MessageForgotPasswordInNetworkRequired'),
title: globalize.translate('ButtonForgotPassword')
});
return;
}
/* eslint-enable indent */
if (result.Action == 'PinCode') {
let msg = globalize.translate('MessageForgotPasswordFileCreated');
msg += '<br/>';
msg += '<br/>';
msg += 'Enter PIN here to finish Password Reset<br/>';
msg += '<br/>';
msg += result.PinFile;
msg += '<br/>';
Dashboard.alert({
message: msg,
title: globalize.translate('ButtonForgotPassword'),
callback: function () {
Dashboard.navigate('forgotpasswordpin.html');
}
});
}
}
export default function (view) {
function onSubmit(e) {
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('Users/ForgotPassword'),
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify({
EnteredUsername: view.querySelector('#txtName').value
})
}).then(processForgotPasswordResult);
e.preventDefault();
return false;
}
view.querySelector('form').addEventListener('submit', onSubmit);
}

View file

@ -18,292 +18,289 @@ import baseAlert from '../../../components/alert';
import cardBuilder from '../../../components/cardbuilder/cardBuilder';
import './login.scss';
/* eslint-disable indent */
const enableFocusTransform = !browser.slow && !browser.edge;
const enableFocusTransform = !browser.slow && !browser.edge;
function authenticateUserByName(page, apiClient, username, password) {
loading.show();
apiClient.authenticateUserByName(username, password).then(function (result) {
const user = result.User;
loading.hide();
function authenticateUserByName(page, apiClient, username, password) {
loading.show();
apiClient.authenticateUserByName(username, password).then(function (result) {
const user = result.User;
loading.hide();
onLoginSuccessful(user.Id, result.AccessToken, apiClient);
}, function (response) {
page.querySelector('#txtManualPassword').value = '';
loading.hide();
onLoginSuccessful(user.Id, result.AccessToken, apiClient);
}, function (response) {
page.querySelector('#txtManualPassword').value = '';
loading.hide();
const UnauthorizedOrForbidden = [401, 403];
if (UnauthorizedOrForbidden.includes(response.status)) {
const messageKey = response.status === 401 ? 'MessageInvalidUser' : 'MessageUnauthorizedUser';
toast(globalize.translate(messageKey));
} else {
Dashboard.alert({
message: globalize.translate('MessageUnableToConnectToServer'),
title: globalize.translate('HeaderConnectionFailure')
});
}
});
}
function authenticateQuickConnect(apiClient) {
const url = apiClient.getUrl('/QuickConnect/Initiate');
apiClient.ajax({ type: 'POST', url }, true).then(res => res.json()).then(function (json) {
if (!json.Secret || !json.Code) {
console.error('Malformed quick connect response', json);
return false;
}
baseAlert({
dialogOptions: {
id: 'quickConnectAlert'
},
title: globalize.translate('QuickConnect'),
text: globalize.translate('QuickConnectAuthorizeCode', json.Code)
});
const connectUrl = apiClient.getUrl('/QuickConnect/Connect?Secret=' + json.Secret);
const interval = setInterval(function() {
apiClient.getJSON(connectUrl).then(async function(data) {
if (!data.Authenticated) {
return;
}
clearInterval(interval);
// Close the QuickConnect dialog
const dlg = document.getElementById('quickConnectAlert');
if (dlg) {
dialogHelper.close(dlg);
}
const result = await apiClient.quickConnect(data.Secret);
onLoginSuccessful(result.User.Id, result.AccessToken, apiClient);
}, function (e) {
clearInterval(interval);
// Close the QuickConnect dialog
const dlg = document.getElementById('quickConnectAlert');
if (dlg) {
dialogHelper.close(dlg);
}
Dashboard.alert({
message: globalize.translate('QuickConnectDeactivated'),
title: globalize.translate('HeaderError')
});
console.error('Unable to login with quick connect', e);
});
}, 5000, connectUrl);
return true;
}, function(e) {
const UnauthorizedOrForbidden = [401, 403];
if (UnauthorizedOrForbidden.includes(response.status)) {
const messageKey = response.status === 401 ? 'MessageInvalidUser' : 'MessageUnauthorizedUser';
toast(globalize.translate(messageKey));
} else {
Dashboard.alert({
message: globalize.translate('QuickConnectNotActive'),
title: globalize.translate('HeaderError')
message: globalize.translate('MessageUnableToConnectToServer'),
title: globalize.translate('HeaderConnectionFailure')
});
}
});
}
function authenticateQuickConnect(apiClient) {
const url = apiClient.getUrl('/QuickConnect/Initiate');
apiClient.ajax({ type: 'POST', url }, true).then(res => res.json()).then(function (json) {
if (!json.Secret || !json.Code) {
console.error('Malformed quick connect response', json);
return false;
}
baseAlert({
dialogOptions: {
id: 'quickConnectAlert'
},
title: globalize.translate('QuickConnect'),
text: globalize.translate('QuickConnectAuthorizeCode', json.Code)
});
const connectUrl = apiClient.getUrl('/QuickConnect/Connect?Secret=' + json.Secret);
const interval = setInterval(function() {
apiClient.getJSON(connectUrl).then(async function(data) {
if (!data.Authenticated) {
return;
}
clearInterval(interval);
// Close the QuickConnect dialog
const dlg = document.getElementById('quickConnectAlert');
if (dlg) {
dialogHelper.close(dlg);
}
const result = await apiClient.quickConnect(data.Secret);
onLoginSuccessful(result.User.Id, result.AccessToken, apiClient);
}, function (e) {
clearInterval(interval);
// Close the QuickConnect dialog
const dlg = document.getElementById('quickConnectAlert');
if (dlg) {
dialogHelper.close(dlg);
}
Dashboard.alert({
message: globalize.translate('QuickConnectDeactivated'),
title: globalize.translate('HeaderError')
});
console.error('Unable to login with quick connect', e);
});
}, 5000, connectUrl);
return true;
}, function(e) {
Dashboard.alert({
message: globalize.translate('QuickConnectNotActive'),
title: globalize.translate('HeaderError')
});
console.error('Quick connect error: ', e);
return false;
});
}
function onLoginSuccessful(id, accessToken, apiClient) {
Dashboard.onServerChanged(id, accessToken, apiClient);
Dashboard.navigate('home.html');
}
function showManualForm(context, showCancel, focusPassword) {
context.querySelector('.chkRememberLogin').checked = appSettings.enableAutoLogin();
context.querySelector('.manualLoginForm').classList.remove('hide');
context.querySelector('.visualLoginForm').classList.add('hide');
context.querySelector('.btnManual').classList.add('hide');
if (focusPassword) {
context.querySelector('#txtManualPassword').focus();
} else {
context.querySelector('#txtManualName').focus();
}
if (showCancel) {
context.querySelector('.btnCancel').classList.remove('hide');
} else {
context.querySelector('.btnCancel').classList.add('hide');
}
}
function loadUserList(context, apiClient, users) {
let html = '';
for (let i = 0; i < users.length; i++) {
const user = users[i];
// TODO move card creation code to Card component
let cssClass = 'card squareCard scalableCard squareCard-scalable';
if (layoutManager.tv) {
cssClass += ' show-focus';
if (enableFocusTransform) {
cssClass += ' show-animation';
}
}
const cardBoxCssClass = 'cardBox cardBox-bottompadded';
html += '<button type="button" class="' + cssClass + '">';
html += '<div class="' + cardBoxCssClass + '">';
html += '<div class="cardScalable">';
html += '<div class="cardPadder cardPadder-square"></div>';
html += `<div class="cardContent" data-haspw="${user.HasPassword}" data-username="${user.Name}" data-userid="${user.Id}">`;
let imgUrl;
if (user.PrimaryImageTag) {
imgUrl = apiClient.getUserImageUrl(user.Id, {
width: 300,
tag: user.PrimaryImageTag,
type: 'Primary'
});
console.error('Quick connect error: ', e);
return false;
html += '<div class="cardImageContainer coveredImage" style="background-image:url(\'' + imgUrl + "');\"></div>";
} else {
html += `<div class="cardImage flex align-items-center justify-content-center ${cardBuilder.getDefaultBackgroundClass()}">`;
html += '<span class="material-icons cardImageIcon person" aria-hidden="true"></span>';
html += '</div>';
}
html += '</div>';
html += '</div>';
html += '<div class="cardFooter visualCardBox-cardFooter">';
html += '<div class="cardText singleCardText cardTextCentered">' + user.Name + '</div>';
html += '</div>';
html += '</div>';
html += '</button>';
}
context.querySelector('#divUsers').innerHTML = html;
}
export default function (view, params) {
function getApiClient() {
const serverId = params.serverid;
if (serverId) {
return ServerConnections.getOrCreateApiClient(serverId);
}
return ApiClient;
}
function showVisualForm() {
view.querySelector('.visualLoginForm').classList.remove('hide');
view.querySelector('.manualLoginForm').classList.add('hide');
view.querySelector('.btnManual').classList.remove('hide');
import('../../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(view);
});
}
function onLoginSuccessful(id, accessToken, apiClient) {
Dashboard.onServerChanged(id, accessToken, apiClient);
Dashboard.navigate('home.html');
}
view.querySelector('#divUsers').addEventListener('click', function (e) {
const card = dom.parentWithClass(e.target, 'card');
const cardContent = card ? card.querySelector('.cardContent') : null;
function showManualForm(context, showCancel, focusPassword) {
context.querySelector('.chkRememberLogin').checked = appSettings.enableAutoLogin();
context.querySelector('.manualLoginForm').classList.remove('hide');
context.querySelector('.visualLoginForm').classList.add('hide');
context.querySelector('.btnManual').classList.add('hide');
if (cardContent) {
const context = view;
const id = cardContent.getAttribute('data-userid');
const name = cardContent.getAttribute('data-username');
const haspw = cardContent.getAttribute('data-haspw');
if (focusPassword) {
context.querySelector('#txtManualPassword').focus();
} else {
context.querySelector('#txtManualName').focus();
}
if (showCancel) {
context.querySelector('.btnCancel').classList.remove('hide');
} else {
context.querySelector('.btnCancel').classList.add('hide');
}
}
function loadUserList(context, apiClient, users) {
let html = '';
for (let i = 0; i < users.length; i++) {
const user = users[i];
// TODO move card creation code to Card component
let cssClass = 'card squareCard scalableCard squareCard-scalable';
if (layoutManager.tv) {
cssClass += ' show-focus';
if (enableFocusTransform) {
cssClass += ' show-animation';
}
}
const cardBoxCssClass = 'cardBox cardBox-bottompadded';
html += '<button type="button" class="' + cssClass + '">';
html += '<div class="' + cardBoxCssClass + '">';
html += '<div class="cardScalable">';
html += '<div class="cardPadder cardPadder-square"></div>';
html += `<div class="cardContent" data-haspw="${user.HasPassword}" data-username="${user.Name}" data-userid="${user.Id}">`;
let imgUrl;
if (user.PrimaryImageTag) {
imgUrl = apiClient.getUserImageUrl(user.Id, {
width: 300,
tag: user.PrimaryImageTag,
type: 'Primary'
});
html += '<div class="cardImageContainer coveredImage" style="background-image:url(\'' + imgUrl + "');\"></div>";
if (id === 'manual') {
context.querySelector('#txtManualName').value = '';
showManualForm(context, true);
} else if (haspw == 'false') {
authenticateUserByName(context, getApiClient(), name, '');
} else {
html += `<div class="cardImage flex align-items-center justify-content-center ${cardBuilder.getDefaultBackgroundClass()}">`;
html += '<span class="material-icons cardImageIcon person" aria-hidden="true"></span>';
html += '</div>';
context.querySelector('#txtManualName').value = name;
context.querySelector('#txtManualPassword').value = '';
showManualForm(context, true, true);
}
}
});
view.querySelector('.manualLoginForm').addEventListener('submit', function (e) {
appSettings.enableAutoLogin(view.querySelector('.chkRememberLogin').checked);
const apiClient = getApiClient();
authenticateUserByName(view, apiClient, view.querySelector('#txtManualName').value, view.querySelector('#txtManualPassword').value);
e.preventDefault();
return false;
});
view.querySelector('.btnForgotPassword').addEventListener('click', function () {
Dashboard.navigate('forgotpassword.html');
});
view.querySelector('.btnCancel').addEventListener('click', showVisualForm);
view.querySelector('.btnQuick').addEventListener('click', function () {
const apiClient = getApiClient();
authenticateQuickConnect(apiClient);
return false;
});
view.querySelector('.btnManual').addEventListener('click', function () {
view.querySelector('#txtManualName').value = '';
showManualForm(view, true);
});
view.querySelector('.btnSelectServer').addEventListener('click', function () {
Dashboard.selectServer();
});
html += '</div>';
html += '</div>';
html += '<div class="cardFooter visualCardBox-cardFooter">';
html += '<div class="cardText singleCardText cardTextCentered">' + user.Name + '</div>';
html += '</div>';
html += '</div>';
html += '</button>';
view.addEventListener('viewshow', function () {
loading.show();
libraryMenu.setTransparentMenu(true);
if (!appHost.supports('multiserver')) {
view.querySelector('.btnSelectServer').classList.add('hide');
}
context.querySelector('#divUsers').innerHTML = html;
}
const apiClient = getApiClient();
export default function (view, params) {
function getApiClient() {
const serverId = params.serverid;
if (serverId) {
return ServerConnections.getOrCreateApiClient(serverId);
}
return ApiClient;
}
function showVisualForm() {
view.querySelector('.visualLoginForm').classList.remove('hide');
view.querySelector('.manualLoginForm').classList.add('hide');
view.querySelector('.btnManual').classList.remove('hide');
import('../../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(view);
apiClient.getQuickConnect('Enabled')
.then(enabled => {
if (enabled === true) {
view.querySelector('.btnQuick').classList.remove('hide');
}
})
.catch(() => {
console.debug('Failed to get QuickConnect status');
});
}
view.querySelector('#divUsers').addEventListener('click', function (e) {
const card = dom.parentWithClass(e.target, 'card');
const cardContent = card ? card.querySelector('.cardContent') : null;
apiClient.getPublicUsers().then(function (users) {
if (users.length) {
showVisualForm();
loadUserList(view, apiClient, users);
} else {
view.querySelector('#txtManualName').value = '';
showManualForm(view, false, false);
}
}).catch().then(function () {
loading.hide();
});
apiClient.getJSON(apiClient.getUrl('Branding/Configuration')).then(function (options) {
const loginDisclaimer = view.querySelector('.loginDisclaimer');
if (cardContent) {
const context = view;
const id = cardContent.getAttribute('data-userid');
const name = cardContent.getAttribute('data-username');
const haspw = cardContent.getAttribute('data-haspw');
loginDisclaimer.innerHTML = DOMPurify.sanitize(marked(options.LoginDisclaimer || ''));
if (id === 'manual') {
context.querySelector('#txtManualName').value = '';
showManualForm(context, true);
} else if (haspw == 'false') {
authenticateUserByName(context, getApiClient(), name, '');
} else {
context.querySelector('#txtManualName').value = name;
context.querySelector('#txtManualPassword').value = '';
showManualForm(context, true, true);
for (const elem of loginDisclaimer.querySelectorAll('a')) {
elem.rel = 'noopener noreferrer';
elem.target = '_blank';
elem.classList.add('button-link');
elem.setAttribute('is', 'emby-linkbutton');
if (layoutManager.tv) {
// Disable links navigation on TV
elem.tabIndex = -1;
}
}
});
view.querySelector('.manualLoginForm').addEventListener('submit', function (e) {
appSettings.enableAutoLogin(view.querySelector('.chkRememberLogin').checked);
const apiClient = getApiClient();
authenticateUserByName(view, apiClient, view.querySelector('#txtManualName').value, view.querySelector('#txtManualPassword').value);
e.preventDefault();
return false;
});
view.querySelector('.btnForgotPassword').addEventListener('click', function () {
Dashboard.navigate('forgotpassword.html');
});
view.querySelector('.btnCancel').addEventListener('click', showVisualForm);
view.querySelector('.btnQuick').addEventListener('click', function () {
const apiClient = getApiClient();
authenticateQuickConnect(apiClient);
return false;
});
view.querySelector('.btnManual').addEventListener('click', function () {
view.querySelector('#txtManualName').value = '';
showManualForm(view, true);
});
view.querySelector('.btnSelectServer').addEventListener('click', function () {
Dashboard.selectServer();
});
});
view.addEventListener('viewhide', function () {
libraryMenu.setTransparentMenu(false);
});
}
view.addEventListener('viewshow', function () {
loading.show();
libraryMenu.setTransparentMenu(true);
if (!appHost.supports('multiserver')) {
view.querySelector('.btnSelectServer').classList.add('hide');
}
const apiClient = getApiClient();
apiClient.getQuickConnect('Enabled')
.then(enabled => {
if (enabled === true) {
view.querySelector('.btnQuick').classList.remove('hide');
}
})
.catch(() => {
console.debug('Failed to get QuickConnect status');
});
apiClient.getPublicUsers().then(function (users) {
if (users.length) {
showVisualForm();
loadUserList(view, apiClient, users);
} else {
view.querySelector('#txtManualName').value = '';
showManualForm(view, false, false);
}
}).catch().then(function () {
loading.hide();
});
apiClient.getJSON(apiClient.getUrl('Branding/Configuration')).then(function (options) {
const loginDisclaimer = view.querySelector('.loginDisclaimer');
loginDisclaimer.innerHTML = DOMPurify.sanitize(marked(options.LoginDisclaimer || ''));
for (const elem of loginDisclaimer.querySelectorAll('a')) {
elem.rel = 'noopener noreferrer';
elem.target = '_blank';
elem.classList.add('button-link');
elem.setAttribute('is', 'emby-linkbutton');
if (layoutManager.tv) {
// Disable links navigation on TV
elem.tabIndex = -1;
}
}
});
});
view.addEventListener('viewhide', function () {
libraryMenu.setTransparentMenu(false);
});
}
/* eslint-enable indent */

View file

@ -1,46 +1,43 @@
import globalize from '../../../scripts/globalize';
import Dashboard from '../../../utils/dashboard';
/* eslint-disable indent */
function processForgotPasswordResult(result) {
if (result.Success) {
let msg = globalize.translate('MessagePasswordResetForUsers');
msg += '<br/>';
msg += '<br/>';
msg += result.UsersReset.join('<br/>');
Dashboard.alert({
message: msg,
title: globalize.translate('HeaderPasswordReset'),
callback: function () {
window.location.href = 'index.html';
}
});
return;
}
function processForgotPasswordResult(result) {
if (result.Success) {
let msg = globalize.translate('MessagePasswordResetForUsers');
msg += '<br/>';
msg += '<br/>';
msg += result.UsersReset.join('<br/>');
Dashboard.alert({
message: globalize.translate('MessageInvalidForgotPasswordPin'),
title: globalize.translate('HeaderPasswordReset')
message: msg,
title: globalize.translate('HeaderPasswordReset'),
callback: function () {
window.location.href = 'index.html';
}
});
return;
}
export default function (view) {
function onSubmit(e) {
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('Users/ForgotPassword/Pin'),
dataType: 'json',
data: JSON.stringify({
Pin: view.querySelector('#txtPin').value
}),
contentType: 'application/json'
}).then(processForgotPasswordResult);
e.preventDefault();
return false;
}
Dashboard.alert({
message: globalize.translate('MessageInvalidForgotPasswordPin'),
title: globalize.translate('HeaderPasswordReset')
});
}
view.querySelector('form').addEventListener('submit', onSubmit);
export default function (view) {
function onSubmit(e) {
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('Users/ForgotPassword/Pin'),
dataType: 'json',
data: JSON.stringify({
Pin: view.querySelector('#txtPin').value
}),
contentType: 'application/json'
}).then(processForgotPasswordResult);
e.preventDefault();
return false;
}
/* eslint-enable indent */
view.querySelector('form').addEventListener('submit', onSubmit);
}

View file

@ -21,196 +21,193 @@ import alert from '../../../components/alert';
import cardBuilder from '../../../components/cardbuilder/cardBuilder';
import { ConnectionState } from '../../../utils/jellyfin-apiclient/ConnectionState.ts';
/* eslint-disable indent */
const enableFocusTransform = !browser.slow && !browser.edge;
const enableFocusTransform = !browser.slow && !browser.edge;
function renderSelectServerItems(view, servers) {
const items = servers.map(function (server) {
return {
name: server.Name,
icon: 'storage',
cardType: '',
id: server.Id,
server: server
};
});
let html = items.map(function (item) {
// TODO move card creation code to Card component
const cardImageContainer = '<span class="cardImageIcon material-icons ' + item.icon + '" aria-hidden="true"></span>';
let cssClass = 'card overflowSquareCard loginSquareCard scalableCard overflowSquareCard-scalable';
function renderSelectServerItems(view, servers) {
const items = servers.map(function (server) {
return {
name: server.Name,
icon: 'storage',
cardType: '',
id: server.Id,
server: server
};
});
let html = items.map(function (item) {
// TODO move card creation code to Card component
const cardImageContainer = '<span class="cardImageIcon material-icons ' + item.icon + '" aria-hidden="true"></span>';
let cssClass = 'card overflowSquareCard loginSquareCard scalableCard overflowSquareCard-scalable';
if (layoutManager.tv) {
cssClass += ' show-focus';
if (layoutManager.tv) {
cssClass += ' show-focus';
if (enableFocusTransform) {
cssClass += ' show-animation';
}
}
const cardBoxCssClass = 'cardBox';
const innerOpening = '<div class="' + cardBoxCssClass + '">';
let cardContainer = '';
cardContainer += '<button raised class="' + cssClass + '" style="display:inline-block;" data-id="' + item.id + '" data-url="' + (item.url || '') + '" data-cardtype="' + item.cardType + '">';
cardContainer += innerOpening;
cardContainer += '<div class="cardScalable">';
cardContainer += '<div class="cardPadder cardPadder-square">';
cardContainer += '</div>';
cardContainer += '<div class="cardContent">';
cardContainer += `<div class="cardImageContainer coveredImage ${cardBuilder.getDefaultBackgroundClass()}">`;
cardContainer += cardImageContainer;
cardContainer += '</div>';
cardContainer += '</div>';
cardContainer += '</div>';
cardContainer += '<div class="cardFooter">';
cardContainer += '<div class="cardText cardTextCentered">' + escapeHtml(item.name) + '</div>';
cardContainer += '</div></div></button>';
return cardContainer;
}).join('');
const itemsContainer = view.querySelector('.servers');
if (!items.length) {
html = '<p>' + globalize.translate('MessageNoServersAvailable') + '</p>';
}
itemsContainer.innerHTML = html;
loading.hide();
}
function updatePageStyle(view, params) {
if (params.showuser == '1') {
view.classList.add('libraryPage');
view.classList.remove('standalonePage');
view.classList.add('noSecondaryNavPage');
} else {
view.classList.add('standalonePage');
view.classList.remove('libraryPage');
view.classList.remove('noSecondaryNavPage');
}
}
function alertText(text) {
alertTextWithOptions({
text: text
});
}
function alertTextWithOptions(options) {
alert(options);
}
function showServerConnectionFailure() {
alertText(globalize.translate('MessageUnableToConnectToServer'));
}
export default function (view, params) {
function connectToServer(server) {
loading.show();
ServerConnections.connectToServer(server, {
enableAutoLogin: appSettings.enableAutoLogin()
}).then(function (result) {
loading.hide();
const apiClient = result.ApiClient;
switch (result.State) {
case ConnectionState.SignedIn:
Dashboard.onServerChanged(apiClient.getCurrentUserId(), apiClient.accessToken(), apiClient);
Dashboard.navigate('home.html');
break;
case ConnectionState.ServerSignIn:
Dashboard.onServerChanged(null, null, apiClient);
Dashboard.navigate('login.html?serverid=' + result.Servers[0].Id);
break;
case ConnectionState.ServerUpdateNeeded:
alertTextWithOptions({
text: globalize.translate('core#ServerUpdateNeeded', 'https://github.com/jellyfin/jellyfin'),
html: globalize.translate('core#ServerUpdateNeeded', '<a href="https://github.com/jellyfin/jellyfin">https://github.com/jellyfin/jellyfin</a>')
});
break;
default:
showServerConnectionFailure();
}
});
}
function deleteServer(server) {
loading.show();
ServerConnections.deleteServer(server.Id).then(function () {
loading.hide();
loadServers();
});
}
function onServerClick(server) {
const menuItems = [];
menuItems.push({
name: globalize.translate('Connect'),
id: 'connect'
});
menuItems.push({
name: globalize.translate('Delete'),
id: 'delete'
});
actionSheet.show({
items: menuItems,
title: server.Name
}).then(function (id) {
switch (id) {
case 'connect':
connectToServer(server);
break;
case 'delete':
deleteServer(server);
}
});
}
function onServersRetrieved(result) {
servers = result;
renderSelectServerItems(view, result);
if (layoutManager.tv) {
focusManager.autoFocus(view);
if (enableFocusTransform) {
cssClass += ' show-animation';
}
}
function loadServers() {
loading.show();
ServerConnections.getAvailableServers().then(onServersRetrieved);
}
const cardBoxCssClass = 'cardBox';
let servers;
updatePageStyle(view, params);
view.addEventListener('viewshow', function (e) {
const isRestored = e.detail.isRestored;
libraryMenu.setTitle(null);
libraryMenu.setTransparentMenu(true);
const innerOpening = '<div class="' + cardBoxCssClass + '">';
let cardContainer = '';
cardContainer += '<button raised class="' + cssClass + '" style="display:inline-block;" data-id="' + item.id + '" data-url="' + (item.url || '') + '" data-cardtype="' + item.cardType + '">';
cardContainer += innerOpening;
cardContainer += '<div class="cardScalable">';
cardContainer += '<div class="cardPadder cardPadder-square">';
cardContainer += '</div>';
cardContainer += '<div class="cardContent">';
cardContainer += `<div class="cardImageContainer coveredImage ${cardBuilder.getDefaultBackgroundClass()}">`;
cardContainer += cardImageContainer;
cardContainer += '</div>';
cardContainer += '</div>';
cardContainer += '</div>';
cardContainer += '<div class="cardFooter">';
cardContainer += '<div class="cardText cardTextCentered">' + escapeHtml(item.name) + '</div>';
cardContainer += '</div></div></button>';
return cardContainer;
}).join('');
const itemsContainer = view.querySelector('.servers');
if (!isRestored) {
loadServers();
}
});
view.querySelector('.servers').addEventListener('click', function (e) {
const card = dom.parentWithClass(e.target, 'card');
if (!items.length) {
html = '<p>' + globalize.translate('MessageNoServersAvailable') + '</p>';
}
if (card) {
const url = card.getAttribute('data-url');
itemsContainer.innerHTML = html;
loading.hide();
}
if (url) {
appRouter.show(url);
} else {
const id = card.getAttribute('data-id');
onServerClick(servers.filter(function (s) {
return s.Id === id;
})[0]);
}
function updatePageStyle(view, params) {
if (params.showuser == '1') {
view.classList.add('libraryPage');
view.classList.remove('standalonePage');
view.classList.add('noSecondaryNavPage');
} else {
view.classList.add('standalonePage');
view.classList.remove('libraryPage');
view.classList.remove('noSecondaryNavPage');
}
}
function alertText(text) {
alertTextWithOptions({
text: text
});
}
function alertTextWithOptions(options) {
alert(options);
}
function showServerConnectionFailure() {
alertText(globalize.translate('MessageUnableToConnectToServer'));
}
export default function (view, params) {
function connectToServer(server) {
loading.show();
ServerConnections.connectToServer(server, {
enableAutoLogin: appSettings.enableAutoLogin()
}).then(function (result) {
loading.hide();
const apiClient = result.ApiClient;
switch (result.State) {
case ConnectionState.SignedIn:
Dashboard.onServerChanged(apiClient.getCurrentUserId(), apiClient.accessToken(), apiClient);
Dashboard.navigate('home.html');
break;
case ConnectionState.ServerSignIn:
Dashboard.onServerChanged(null, null, apiClient);
Dashboard.navigate('login.html?serverid=' + result.Servers[0].Id);
break;
case ConnectionState.ServerUpdateNeeded:
alertTextWithOptions({
text: globalize.translate('core#ServerUpdateNeeded', 'https://github.com/jellyfin/jellyfin'),
html: globalize.translate('core#ServerUpdateNeeded', '<a href="https://github.com/jellyfin/jellyfin">https://github.com/jellyfin/jellyfin</a>')
});
break;
default:
showServerConnectionFailure();
}
});
}
/* eslint-enable indent */
function deleteServer(server) {
loading.show();
ServerConnections.deleteServer(server.Id).then(function () {
loading.hide();
loadServers();
});
}
function onServerClick(server) {
const menuItems = [];
menuItems.push({
name: globalize.translate('Connect'),
id: 'connect'
});
menuItems.push({
name: globalize.translate('Delete'),
id: 'delete'
});
actionSheet.show({
items: menuItems,
title: server.Name
}).then(function (id) {
switch (id) {
case 'connect':
connectToServer(server);
break;
case 'delete':
deleteServer(server);
}
});
}
function onServersRetrieved(result) {
servers = result;
renderSelectServerItems(view, result);
if (layoutManager.tv) {
focusManager.autoFocus(view);
}
}
function loadServers() {
loading.show();
ServerConnections.getAvailableServers().then(onServersRetrieved);
}
let servers;
updatePageStyle(view, params);
view.addEventListener('viewshow', function (e) {
const isRestored = e.detail.isRestored;
libraryMenu.setTitle(null);
libraryMenu.setTransparentMenu(true);
if (!isRestored) {
loadServers();
}
});
view.querySelector('.servers').addEventListener('click', function (e) {
const card = dom.parentWithClass(e.target, 'card');
if (card) {
const url = card.getAttribute('data-url');
if (url) {
appRouter.show(url);
} else {
const id = card.getAttribute('data-id');
onServerClick(servers.filter(function (s) {
return s.Id === id;
})[0]);
}
}
});
}

View file

@ -10,243 +10,240 @@ import Events from '../../utils/events.ts';
import '../../elements/emby-itemscontainer/emby-itemscontainer';
/* eslint-disable indent */
export default function (view, params, tabContent) {
function getPageData(context) {
const key = getSavedQueryKey(context);
let pageData = data[key];
export default function (view, params, tabContent) {
function getPageData(context) {
const key = getSavedQueryKey(context);
let pageData = data[key];
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SeriesSortName,SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'Episode',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,MediaSourceCount',
IsMissing: false,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Thumb',
StartIndex: 0
},
view: libraryBrowser.getSavedView(key) || 'Poster'
};
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SeriesSortName,SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'Episode',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,MediaSourceCount',
IsMissing: false,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Thumb',
StartIndex: 0
},
view: libraryBrowser.getSavedView(key) || 'Poster'
};
if (userSettings.libraryPageSize() > 0) {
pageData.query['Limit'] = userSettings.libraryPageSize();
}
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
if (userSettings.libraryPageSize() > 0) {
pageData.query['Limit'] = userSettings.libraryPageSize();
}
return pageData;
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
function getQuery(context) {
return getPageData(context).query;
}
function getSavedQueryKey(context) {
if (!context.savedQueryKey) {
context.savedQueryKey = libraryBrowser.getSavedQueryKey('episodes');
}
return context.savedQueryKey;
}
function onViewStyleChange() {
const viewStyle = self.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') {
itemsContainer.classList.add('vertical-list');
itemsContainer.classList.remove('vertical-wrap');
} else {
itemsContainer.classList.remove('vertical-list');
itemsContainer.classList.add('vertical-wrap');
}
itemsContainer.innerHTML = '';
}
function reloadItems(page) {
loading.show();
isLoading = true;
const query = getQuery(page);
ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) {
function onNextPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex += query.Limit;
}
reloadItems(tabContent);
}
function onPreviousPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
}
reloadItems(tabContent);
}
window.scrollTo(0, 0);
let html;
const pagingHtml = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
showLimit: false,
updatePageSizeSetting: false,
addLayoutButton: false,
sortButton: false,
filterButton: false
});
const viewStyle = self.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') {
html = listView.getListViewHtml({
items: result.Items,
sortBy: query.SortBy,
showParentTitle: true
});
} else if (viewStyle == 'PosterCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
showTitle: true,
showParentTitle: true,
scalable: true,
cardLayout: true
});
} else {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
showTitle: true,
showParentTitle: true,
overlayText: false,
centerText: true,
scalable: true,
overlayPlayButton: true
});
}
let elems;
elems = tabContent.querySelectorAll('.paging');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].innerHTML = pagingHtml;
}
elems = tabContent.querySelectorAll('.btnNextPage');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onNextPageClick);
}
elems = tabContent.querySelectorAll('.btnPreviousPage');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onPreviousPageClick);
}
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
loading.hide();
isLoading = false;
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(page);
});
});
}
const self = this;
const data = {};
let isLoading = false;
self.showFilterMenu = function () {
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
const filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: 'episodes',
serverId: ApiClient.serverId()
});
Events.on(filterDialog, 'filterchange', function () {
reloadItems(tabContent);
});
filterDialog.show();
});
};
self.getCurrentViewStyle = function () {
return getPageData(tabContent).view;
};
function initPage(tabElement) {
tabElement.querySelector('.btnFilter').addEventListener('click', function () {
self.showFilterMenu();
});
tabElement.querySelector('.btnSort').addEventListener('click', function (e) {
libraryBrowser.showSortMenu({
items: [{
name: globalize.translate('Name'),
id: 'SeriesSortName,SortName'
}, {
name: globalize.translate('OptionTvdbRating'),
id: 'CommunityRating,SeriesSortName,SortName'
}, {
name: globalize.translate('OptionDateAdded'),
id: 'DateCreated,SeriesSortName,SortName'
}, {
name: globalize.translate('OptionPremiereDate'),
id: 'PremiereDate,SeriesSortName,SortName'
}, {
name: globalize.translate('OptionDatePlayed'),
id: 'DatePlayed,SeriesSortName,SortName'
}, {
name: globalize.translate('OptionParentalRating'),
id: 'OfficialRating,SeriesSortName,SortName'
}, {
name: globalize.translate('OptionPlayCount'),
id: 'PlayCount,SeriesSortName,SortName'
}, {
name: globalize.translate('Runtime'),
id: 'Runtime,SeriesSortName,SortName'
}],
callback: function () {
reloadItems(tabElement);
},
query: getQuery(tabElement),
button: e.target
});
});
const btnSelectView = tabElement.querySelector('.btnSelectView');
btnSelectView.addEventListener('click', function (e) {
libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(','));
});
btnSelectView.addEventListener('layoutchange', function (e) {
const viewStyle = e.detail.viewStyle;
getPageData(tabElement).view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(tabElement), viewStyle);
onViewStyleChange();
reloadItems(tabElement);
});
}
initPage(tabContent);
onViewStyleChange();
self.renderTab = function () {
reloadItems(tabContent);
};
return pageData;
}
/* eslint-enable indent */
function getQuery(context) {
return getPageData(context).query;
}
function getSavedQueryKey(context) {
if (!context.savedQueryKey) {
context.savedQueryKey = libraryBrowser.getSavedQueryKey('episodes');
}
return context.savedQueryKey;
}
function onViewStyleChange() {
const viewStyle = self.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') {
itemsContainer.classList.add('vertical-list');
itemsContainer.classList.remove('vertical-wrap');
} else {
itemsContainer.classList.remove('vertical-list');
itemsContainer.classList.add('vertical-wrap');
}
itemsContainer.innerHTML = '';
}
function reloadItems(page) {
loading.show();
isLoading = true;
const query = getQuery(page);
ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) {
function onNextPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex += query.Limit;
}
reloadItems(tabContent);
}
function onPreviousPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
}
reloadItems(tabContent);
}
window.scrollTo(0, 0);
let html;
const pagingHtml = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
showLimit: false,
updatePageSizeSetting: false,
addLayoutButton: false,
sortButton: false,
filterButton: false
});
const viewStyle = self.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') {
html = listView.getListViewHtml({
items: result.Items,
sortBy: query.SortBy,
showParentTitle: true
});
} else if (viewStyle == 'PosterCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
showTitle: true,
showParentTitle: true,
scalable: true,
cardLayout: true
});
} else {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
showTitle: true,
showParentTitle: true,
overlayText: false,
centerText: true,
scalable: true,
overlayPlayButton: true
});
}
let elems;
elems = tabContent.querySelectorAll('.paging');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].innerHTML = pagingHtml;
}
elems = tabContent.querySelectorAll('.btnNextPage');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onNextPageClick);
}
elems = tabContent.querySelectorAll('.btnPreviousPage');
for (let i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener('click', onPreviousPageClick);
}
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
loading.hide();
isLoading = false;
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(page);
});
});
}
const self = this;
const data = {};
let isLoading = false;
self.showFilterMenu = function () {
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
const filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: 'episodes',
serverId: ApiClient.serverId()
});
Events.on(filterDialog, 'filterchange', function () {
reloadItems(tabContent);
});
filterDialog.show();
});
};
self.getCurrentViewStyle = function () {
return getPageData(tabContent).view;
};
function initPage(tabElement) {
tabElement.querySelector('.btnFilter').addEventListener('click', function () {
self.showFilterMenu();
});
tabElement.querySelector('.btnSort').addEventListener('click', function (e) {
libraryBrowser.showSortMenu({
items: [{
name: globalize.translate('Name'),
id: 'SeriesSortName,SortName'
}, {
name: globalize.translate('OptionTvdbRating'),
id: 'CommunityRating,SeriesSortName,SortName'
}, {
name: globalize.translate('OptionDateAdded'),
id: 'DateCreated,SeriesSortName,SortName'
}, {
name: globalize.translate('OptionPremiereDate'),
id: 'PremiereDate,SeriesSortName,SortName'
}, {
name: globalize.translate('OptionDatePlayed'),
id: 'DatePlayed,SeriesSortName,SortName'
}, {
name: globalize.translate('OptionParentalRating'),
id: 'OfficialRating,SeriesSortName,SortName'
}, {
name: globalize.translate('OptionPlayCount'),
id: 'PlayCount,SeriesSortName,SortName'
}, {
name: globalize.translate('Runtime'),
id: 'Runtime,SeriesSortName,SortName'
}],
callback: function () {
reloadItems(tabElement);
},
query: getQuery(tabElement),
button: e.target
});
});
const btnSelectView = tabElement.querySelector('.btnSelectView');
btnSelectView.addEventListener('click', function (e) {
libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(','));
});
btnSelectView.addEventListener('layoutchange', function (e) {
const viewStyle = e.detail.viewStyle;
getPageData(tabElement).view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(tabElement), viewStyle);
onViewStyleChange();
reloadItems(tabElement);
});
}
initPage(tabContent);
onViewStyleChange();
self.renderTab = function () {
reloadItems(tabContent);
};
}

View file

@ -8,213 +8,210 @@ import globalize from '../../scripts/globalize';
import { appRouter } from '../../components/appRouter';
import '../../elements/emby-button/emby-button';
/* eslint-disable indent */
export default function (view, params, tabContent) {
function getPageData() {
const key = getSavedQueryKey();
let pageData = data[key];
export default function (view, params, tabContent) {
function getPageData() {
const key = getSavedQueryKey();
let pageData = data[key];
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'Series',
Recursive: true,
EnableTotalRecordCount: false
},
view: 'Poster'
};
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
return pageData;
}
function getQuery() {
return getPageData().query;
}
function getSavedQueryKey() {
return libraryBrowser.getSavedQueryKey('seriesgenres');
}
function getPromise() {
loading.show();
const query = getQuery();
return ApiClient.getGenres(ApiClient.getCurrentUserId(), query);
}
function enableScrollX() {
return !layoutManager.desktop;
}
function getThumbShape() {
return enableScrollX() ? 'overflowBackdrop' : 'backdrop';
}
function getPortraitShape() {
return enableScrollX() ? 'overflowPortrait' : 'portrait';
}
function fillItemsContainer(entry) {
const elem = entry.target;
const id = elem.getAttribute('data-id');
const viewStyle = self.getCurrentViewStyle();
let limit = viewStyle == 'Thumb' || viewStyle == 'ThumbCard' ? 5 : 9;
if (enableScrollX()) {
limit = 10;
}
const enableImageTypes = viewStyle == 'Thumb' || viewStyle == 'ThumbCard' ? 'Primary,Backdrop,Thumb' : 'Primary';
const query = {
SortBy: 'Random',
SortOrder: 'Ascending',
IncludeItemTypes: 'Series',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo',
ImageTypeLimit: 1,
EnableImageTypes: enableImageTypes,
Limit: limit,
GenreIds: id,
EnableTotalRecordCount: false,
ParentId: params.topParentId
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'Series',
Recursive: true,
EnableTotalRecordCount: false
},
view: 'Poster'
};
ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) {
if (viewStyle == 'Thumb') {
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: getThumbShape(),
preferThumb: true,
showTitle: true,
scalable: true,
centerText: true,
overlayMoreButton: true,
allowBottomPadding: false
});
} else if (viewStyle == 'ThumbCard') {
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: getThumbShape(),
preferThumb: true,
showTitle: true,
scalable: true,
centerText: false,
cardLayout: true,
showYear: true
});
} else if (viewStyle == 'PosterCard') {
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: getPortraitShape(),
showTitle: true,
scalable: true,
centerText: false,
cardLayout: true,
showYear: true
});
} else if (viewStyle == 'Poster') {
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: getPortraitShape(),
scalable: true,
showTitle: true,
centerText: true,
showYear: true,
overlayMoreButton: true,
allowBottomPadding: false
});
}
if (result.Items.length >= query.Limit) {
tabContent.querySelector('.btnMoreFromGenre' + id + ' .material-icons').classList.remove('hide');
}
});
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
function reloadItems(context, promise) {
const query = getQuery();
promise.then(function (result) {
const elem = context.querySelector('#items');
let html = '';
const items = result.Items;
for (const item of items) {
html += '<div class="verticalSection">';
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl(item, {
context: 'tvshows',
parentId: params.topParentId
}) + '" class="more button-flat button-flat-mini sectionTitleTextButton btnMoreFromGenre' + item.Id + '">';
html += '<h2 class="sectionTitle sectionTitle-cards">';
html += escapeHtml(item.Name);
html += '</h2>';
html += '<span class="material-icons hide chevron_right" aria-hidden="true"></span>';
html += '</a>';
html += '</div>';
if (enableScrollX()) {
let scrollXClass = 'scrollX hiddenScrollX';
if (layoutManager.tv) {
scrollXClass += 'smoothScrollX padded-top-focusscale padded-bottom-focusscale';
}
html += '<div is="emby-itemscontainer" class="itemsContainer ' + scrollXClass + ' lazy padded-left padded-right" data-id="' + item.Id + '">';
} else {
html += '<div is="emby-itemscontainer" class="itemsContainer vertical-wrap lazy padded-left padded-right" data-id="' + item.Id + '">';
}
html += '</div>';
html += '</div>';
}
if (!result.Items.length) {
html = '';
html += '<div class="noItemsMessage centerMessage">';
html += '<h1>' + globalize.translate('MessageNothingHere') + '</h1>';
html += '<p>' + globalize.translate('MessageNoGenresAvailable') + '</p>';
html += '</div>';
}
elem.innerHTML = html;
lazyLoader.lazyChildren(elem, fillItemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
loading.hide();
});
}
function fullyReload() {
self.preRender();
self.renderTab();
}
const self = this;
const data = {};
self.getViewStyles = function () {
return 'Poster,PosterCard,Thumb,ThumbCard'.split(',');
};
self.getCurrentViewStyle = function () {
return getPageData().view;
};
self.setCurrentViewStyle = function (viewStyle) {
getPageData().view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
fullyReload();
};
self.enableViewSelection = true;
let promise;
self.preRender = function () {
promise = getPromise();
};
self.renderTab = function () {
reloadItems(tabContent, promise);
};
return pageData;
}
/* eslint-enable indent */
function getQuery() {
return getPageData().query;
}
function getSavedQueryKey() {
return libraryBrowser.getSavedQueryKey('seriesgenres');
}
function getPromise() {
loading.show();
const query = getQuery();
return ApiClient.getGenres(ApiClient.getCurrentUserId(), query);
}
function enableScrollX() {
return !layoutManager.desktop;
}
function getThumbShape() {
return enableScrollX() ? 'overflowBackdrop' : 'backdrop';
}
function getPortraitShape() {
return enableScrollX() ? 'overflowPortrait' : 'portrait';
}
function fillItemsContainer(entry) {
const elem = entry.target;
const id = elem.getAttribute('data-id');
const viewStyle = self.getCurrentViewStyle();
let limit = viewStyle == 'Thumb' || viewStyle == 'ThumbCard' ? 5 : 9;
if (enableScrollX()) {
limit = 10;
}
const enableImageTypes = viewStyle == 'Thumb' || viewStyle == 'ThumbCard' ? 'Primary,Backdrop,Thumb' : 'Primary';
const query = {
SortBy: 'Random',
SortOrder: 'Ascending',
IncludeItemTypes: 'Series',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo',
ImageTypeLimit: 1,
EnableImageTypes: enableImageTypes,
Limit: limit,
GenreIds: id,
EnableTotalRecordCount: false,
ParentId: params.topParentId
};
ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) {
if (viewStyle == 'Thumb') {
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: getThumbShape(),
preferThumb: true,
showTitle: true,
scalable: true,
centerText: true,
overlayMoreButton: true,
allowBottomPadding: false
});
} else if (viewStyle == 'ThumbCard') {
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: getThumbShape(),
preferThumb: true,
showTitle: true,
scalable: true,
centerText: false,
cardLayout: true,
showYear: true
});
} else if (viewStyle == 'PosterCard') {
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: getPortraitShape(),
showTitle: true,
scalable: true,
centerText: false,
cardLayout: true,
showYear: true
});
} else if (viewStyle == 'Poster') {
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: getPortraitShape(),
scalable: true,
showTitle: true,
centerText: true,
showYear: true,
overlayMoreButton: true,
allowBottomPadding: false
});
}
if (result.Items.length >= query.Limit) {
tabContent.querySelector('.btnMoreFromGenre' + id + ' .material-icons').classList.remove('hide');
}
});
}
function reloadItems(context, promise) {
const query = getQuery();
promise.then(function (result) {
const elem = context.querySelector('#items');
let html = '';
const items = result.Items;
for (const item of items) {
html += '<div class="verticalSection">';
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl(item, {
context: 'tvshows',
parentId: params.topParentId
}) + '" class="more button-flat button-flat-mini sectionTitleTextButton btnMoreFromGenre' + item.Id + '">';
html += '<h2 class="sectionTitle sectionTitle-cards">';
html += escapeHtml(item.Name);
html += '</h2>';
html += '<span class="material-icons hide chevron_right" aria-hidden="true"></span>';
html += '</a>';
html += '</div>';
if (enableScrollX()) {
let scrollXClass = 'scrollX hiddenScrollX';
if (layoutManager.tv) {
scrollXClass += 'smoothScrollX padded-top-focusscale padded-bottom-focusscale';
}
html += '<div is="emby-itemscontainer" class="itemsContainer ' + scrollXClass + ' lazy padded-left padded-right" data-id="' + item.Id + '">';
} else {
html += '<div is="emby-itemscontainer" class="itemsContainer vertical-wrap lazy padded-left padded-right" data-id="' + item.Id + '">';
}
html += '</div>';
html += '</div>';
}
if (!result.Items.length) {
html = '';
html += '<div class="noItemsMessage centerMessage">';
html += '<h1>' + globalize.translate('MessageNothingHere') + '</h1>';
html += '<p>' + globalize.translate('MessageNoGenresAvailable') + '</p>';
html += '</div>';
}
elem.innerHTML = html;
lazyLoader.lazyChildren(elem, fillItemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(), query);
loading.hide();
});
}
function fullyReload() {
self.preRender();
self.renderTab();
}
const self = this;
const data = {};
self.getViewStyles = function () {
return 'Poster,PosterCard,Thumb,ThumbCard'.split(',');
};
self.getCurrentViewStyle = function () {
return getPageData().view;
};
self.setCurrentViewStyle = function (viewStyle) {
getPageData().view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
fullyReload();
};
self.enableViewSelection = true;
let promise;
self.preRender = function () {
promise = getPromise();
};
self.renderTab = function () {
reloadItems(tabContent, promise);
};
}

View file

@ -16,377 +16,374 @@ import Dashboard from '../../utils/dashboard';
import Events from '../../utils/events.ts';
import autoFocuser from '../../components/autoFocuser';
/* eslint-disable indent */
function getTabs() {
return [{
name: globalize.translate('Shows')
}, {
name: globalize.translate('Suggestions')
}, {
name: globalize.translate('TabUpcoming')
}, {
name: globalize.translate('Genres')
}, {
name: globalize.translate('TabNetworks')
}, {
name: globalize.translate('Episodes')
}];
}
function getTabs() {
return [{
name: globalize.translate('Shows')
}, {
name: globalize.translate('Suggestions')
}, {
name: globalize.translate('TabUpcoming')
}, {
name: globalize.translate('Genres')
}, {
name: globalize.translate('TabNetworks')
}, {
name: globalize.translate('Episodes')
}];
function getDefaultTabIndex(folderId) {
switch (userSettings.get('landing-' + folderId)) {
case 'suggestions':
return 1;
case 'upcoming':
return 2;
case 'genres':
return 3;
case 'networks':
return 4;
case 'episodes':
return 5;
default:
return 0;
}
}
function getDefaultTabIndex(folderId) {
switch (userSettings.get('landing-' + folderId)) {
case 'suggestions':
return 1;
function setScrollClasses(elem, scrollX) {
if (scrollX) {
elem.classList.add('hiddenScrollX');
case 'upcoming':
return 2;
case 'genres':
return 3;
case 'networks':
return 4;
case 'episodes':
return 5;
default:
return 0;
if (layoutManager.tv) {
elem.classList.add('smoothScrollX');
}
elem.classList.add('scrollX');
elem.classList.remove('vertical-wrap');
} else {
elem.classList.remove('hiddenScrollX');
elem.classList.remove('smoothScrollX');
elem.classList.remove('scrollX');
elem.classList.add('vertical-wrap');
}
}
function setScrollClasses(elem, scrollX) {
if (scrollX) {
elem.classList.add('hiddenScrollX');
function initSuggestedTab(page, tabContent) {
const containers = tabContent.querySelectorAll('.itemsContainer');
if (layoutManager.tv) {
elem.classList.add('smoothScrollX');
}
for (let i = 0, length = containers.length; i < length; i++) {
setScrollClasses(containers[i], enableScrollX());
}
}
elem.classList.add('scrollX');
elem.classList.remove('vertical-wrap');
function loadSuggestionsTab(view, params, tabContent) {
const parentId = params.topParentId;
const userId = ApiClient.getCurrentUserId();
console.debug('loadSuggestionsTab');
loadResume(tabContent, userId, parentId);
loadLatest(tabContent, userId, parentId);
loadNextUp(tabContent, userId, parentId);
}
function loadResume(view, userId, parentId) {
const screenWidth = dom.getWindowSize().innerWidth;
const options = {
SortBy: 'DatePlayed',
SortOrder: 'Descending',
IncludeItemTypes: 'Episode',
Filters: 'IsResumable',
Limit: screenWidth >= 1600 ? 5 : 3,
Recursive: true,
Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo',
CollapseBoxSetItems: false,
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
EnableTotalRecordCount: false
};
ApiClient.getItems(userId, options).then(function (result) {
if (result.Items.length) {
view.querySelector('#resumableSection').classList.remove('hide');
} else {
elem.classList.remove('hiddenScrollX');
elem.classList.remove('smoothScrollX');
elem.classList.remove('scrollX');
elem.classList.add('vertical-wrap');
view.querySelector('#resumableSection').classList.add('hide');
}
}
function initSuggestedTab(page, tabContent) {
const containers = tabContent.querySelectorAll('.itemsContainer');
const allowBottomPadding = !enableScrollX();
const container = view.querySelector('#resumableItems');
cardBuilder.buildCards(result.Items, {
itemsContainer: container,
preferThumb: true,
inheritThumb: !userSettings.useEpisodeImagesInNextUpAndResume(),
shape: getThumbShape(),
scalable: true,
overlayPlayButton: true,
allowBottomPadding: allowBottomPadding,
cardLayout: false,
showTitle: true,
showYear: true,
centerText: true
});
loading.hide();
for (let i = 0, length = containers.length; i < length; i++) {
setScrollClasses(containers[i], enableScrollX());
autoFocuser.autoFocus(view);
});
}
function loadLatest(view, userId, parentId) {
const options = {
userId: userId,
IncludeItemTypes: 'Episode',
Limit: 30,
Fields: 'PrimaryImageAspectRatio,BasicSyncInfo',
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Thumb'
};
ApiClient.getLatestItems(options).then(function (items) {
const section = view.querySelector('#latestItemsSection');
const allowBottomPadding = !enableScrollX();
const container = section.querySelector('#latestEpisodesItems');
cardBuilder.buildCards(items, {
parentContainer: section,
itemsContainer: container,
items: items,
shape: 'backdrop',
preferThumb: true,
showTitle: true,
showSeriesYear: true,
showParentTitle: true,
overlayText: false,
cardLayout: false,
allowBottomPadding: allowBottomPadding,
showUnplayedIndicator: false,
showChildCountIndicator: true,
centerText: true,
lazy: true,
overlayPlayButton: true,
lines: 2
});
loading.hide();
autoFocuser.autoFocus(view);
});
}
function loadNextUp(view, userId, parentId) {
const query = {
userId: userId,
Limit: 24,
Fields: 'PrimaryImageAspectRatio,DateCreated,BasicSyncInfo,MediaSourceCount',
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Thumb',
EnableTotalRecordCount: false
};
query.ParentId = libraryMenu.getTopParentId();
ApiClient.getNextUpEpisodes(query).then(function (result) {
if (result.Items.length) {
view.querySelector('.noNextUpItems').classList.add('hide');
} else {
view.querySelector('.noNextUpItems').classList.remove('hide');
}
const section = view.querySelector('#nextUpItemsSection');
const container = section.querySelector('#nextUpItems');
cardBuilder.buildCards(result.Items, {
parentContainer: section,
itemsContainer: container,
preferThumb: true,
inheritThumb: !userSettings.useEpisodeImagesInNextUpAndResume(),
shape: 'backdrop',
scalable: true,
showTitle: true,
showParentTitle: true,
overlayText: false,
centerText: true,
overlayPlayButton: true,
cardLayout: false
});
loading.hide();
autoFocuser.autoFocus(view);
});
}
function enableScrollX() {
return !layoutManager.desktop;
}
function getThumbShape() {
return enableScrollX() ? 'overflowBackdrop' : 'backdrop';
}
export default function (view, params) {
function onBeforeTabChange(e) {
preLoadTab(view, parseInt(e.detail.selectedTabIndex, 10));
}
function loadSuggestionsTab(view, params, tabContent) {
const parentId = params.topParentId;
const userId = ApiClient.getCurrentUserId();
console.debug('loadSuggestionsTab');
loadResume(tabContent, userId, parentId);
loadLatest(tabContent, userId, parentId);
loadNextUp(tabContent, userId, parentId);
function onTabChange(e) {
const newIndex = parseInt(e.detail.selectedTabIndex, 10);
loadTab(view, newIndex);
}
function loadResume(view, userId, parentId) {
const screenWidth = dom.getWindowSize().innerWidth;
const options = {
SortBy: 'DatePlayed',
SortOrder: 'Descending',
IncludeItemTypes: 'Episode',
Filters: 'IsResumable',
Limit: screenWidth >= 1600 ? 5 : 3,
Recursive: true,
Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo',
CollapseBoxSetItems: false,
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
EnableTotalRecordCount: false
};
ApiClient.getItems(userId, options).then(function (result) {
if (result.Items.length) {
view.querySelector('#resumableSection').classList.remove('hide');
} else {
view.querySelector('#resumableSection').classList.add('hide');
function getTabContainers() {
return view.querySelectorAll('.pageTabContent');
}
function initTabs() {
mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange);
}
function getTabController(page, index, callback) {
let depends;
switch (index) {
case 0:
depends = 'tvshows';
break;
case 1:
depends = 'tvrecommended';
break;
case 2:
depends = 'tvupcoming';
break;
case 3:
depends = 'tvgenres';
break;
case 4:
depends = 'tvstudios';
break;
case 5:
depends = 'episodes';
break;
}
import(`../shows/${depends}`).then(({ default: controllerFactory }) => {
let tabContent;
if (index === 1) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
self.tabContent = tabContent;
}
const allowBottomPadding = !enableScrollX();
const container = view.querySelector('#resumableItems');
cardBuilder.buildCards(result.Items, {
itemsContainer: container,
preferThumb: true,
inheritThumb: !userSettings.useEpisodeImagesInNextUpAndResume(),
shape: getThumbShape(),
scalable: true,
overlayPlayButton: true,
allowBottomPadding: allowBottomPadding,
cardLayout: false,
showTitle: true,
showYear: true,
centerText: true
});
loading.hide();
let controller = tabControllers[index];
autoFocuser.autoFocus(view);
});
}
function loadLatest(view, userId, parentId) {
const options = {
userId: userId,
IncludeItemTypes: 'Episode',
Limit: 30,
Fields: 'PrimaryImageAspectRatio,BasicSyncInfo',
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Thumb'
};
ApiClient.getLatestItems(options).then(function (items) {
const section = view.querySelector('#latestItemsSection');
const allowBottomPadding = !enableScrollX();
const container = section.querySelector('#latestEpisodesItems');
cardBuilder.buildCards(items, {
parentContainer: section,
itemsContainer: container,
items: items,
shape: 'backdrop',
preferThumb: true,
showTitle: true,
showSeriesYear: true,
showParentTitle: true,
overlayText: false,
cardLayout: false,
allowBottomPadding: allowBottomPadding,
showUnplayedIndicator: false,
showChildCountIndicator: true,
centerText: true,
lazy: true,
overlayPlayButton: true,
lines: 2
});
loading.hide();
autoFocuser.autoFocus(view);
});
}
function loadNextUp(view, userId, parentId) {
const query = {
userId: userId,
Limit: 24,
Fields: 'PrimaryImageAspectRatio,DateCreated,BasicSyncInfo,MediaSourceCount',
ParentId: parentId,
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Thumb',
EnableTotalRecordCount: false
};
query.ParentId = libraryMenu.getTopParentId();
ApiClient.getNextUpEpisodes(query).then(function (result) {
if (result.Items.length) {
view.querySelector('.noNextUpItems').classList.add('hide');
} else {
view.querySelector('.noNextUpItems').classList.remove('hide');
}
const section = view.querySelector('#nextUpItemsSection');
const container = section.querySelector('#nextUpItems');
cardBuilder.buildCards(result.Items, {
parentContainer: section,
itemsContainer: container,
preferThumb: true,
inheritThumb: !userSettings.useEpisodeImagesInNextUpAndResume(),
shape: 'backdrop',
scalable: true,
showTitle: true,
showParentTitle: true,
overlayText: false,
centerText: true,
overlayPlayButton: true,
cardLayout: false
});
loading.hide();
autoFocuser.autoFocus(view);
});
}
function enableScrollX() {
return !layoutManager.desktop;
}
function getThumbShape() {
return enableScrollX() ? 'overflowBackdrop' : 'backdrop';
}
export default function (view, params) {
function onBeforeTabChange(e) {
preLoadTab(view, parseInt(e.detail.selectedTabIndex, 10));
}
function onTabChange(e) {
const newIndex = parseInt(e.detail.selectedTabIndex, 10);
loadTab(view, newIndex);
}
function getTabContainers() {
return view.querySelectorAll('.pageTabContent');
}
function initTabs() {
mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange);
}
function getTabController(page, index, callback) {
let depends;
switch (index) {
case 0:
depends = 'tvshows';
break;
case 1:
depends = 'tvrecommended';
break;
case 2:
depends = 'tvupcoming';
break;
case 3:
depends = 'tvgenres';
break;
case 4:
depends = 'tvstudios';
break;
case 5:
depends = 'episodes';
break;
}
import(`../shows/${depends}`).then(({ default: controllerFactory }) => {
let tabContent;
if (!controller) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
if (index === 1) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
self.tabContent = tabContent;
}
let controller = tabControllers[index];
if (!controller) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
if (index === 1) {
controller = self;
} else {
controller = new controllerFactory(view, params, tabContent);
}
tabControllers[index] = controller;
if (controller.initTab) {
controller.initTab();
}
}
callback(controller);
});
}
function preLoadTab(page, index) {
getTabController(page, index, function (controller) {
if (renderedTabs.indexOf(index) == -1 && controller.preRender) {
controller.preRender();
}
});
}
function loadTab(page, index) {
currentTabIndex = index;
getTabController(page, index, function (controller) {
if (renderedTabs.indexOf(index) == -1) {
renderedTabs.push(index);
controller.renderTab();
}
});
}
function onPlaybackStop(e, state) {
if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') {
renderedTabs = [];
mainTabsManager.getTabsElement().triggerTabChange();
}
}
function onWebSocketMessage(e, data) {
const msg = data;
if (msg.MessageType === 'UserDataChanged' && msg.Data.UserId == ApiClient.getCurrentUserId()) {
renderedTabs = [];
}
}
function onInputCommand(e) {
if (e.detail.command === 'search') {
e.preventDefault();
Dashboard.navigate('search.html?collectionType=tv&parentId=' + params.topParentId);
}
}
const self = this;
let currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId), 10);
const suggestionsTabIndex = 1;
self.initTab = function () {
const tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
initSuggestedTab(view, tabContent);
};
self.renderTab = function () {
const tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
loadSuggestionsTab(view, params, tabContent);
};
const tabControllers = [];
let renderedTabs = [];
view.addEventListener('viewshow', function () {
initTabs();
if (!view.getAttribute('data-title')) {
const parentId = params.topParentId;
if (parentId) {
ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) {
view.setAttribute('data-title', item.Name);
libraryMenu.setTitle(item.Name);
});
controller = self;
} else {
view.setAttribute('data-title', globalize.translate('Shows'));
libraryMenu.setTitle(globalize.translate('Shows'));
controller = new controllerFactory(view, params, tabContent);
}
tabControllers[index] = controller;
if (controller.initTab) {
controller.initTab();
}
}
Events.on(playbackManager, 'playbackstop', onPlaybackStop);
Events.on(ApiClient, 'message', onWebSocketMessage);
inputManager.on(window, onInputCommand);
});
view.addEventListener('viewbeforehide', function () {
inputManager.off(window, onInputCommand);
Events.off(playbackManager, 'playbackstop', onPlaybackStop);
Events.off(ApiClient, 'message', onWebSocketMessage);
});
view.addEventListener('viewdestroy', function () {
tabControllers.forEach(function (t) {
if (t.destroy) {
t.destroy();
}
});
callback(controller);
});
}
/* eslint-enable indent */
function preLoadTab(page, index) {
getTabController(page, index, function (controller) {
if (renderedTabs.indexOf(index) == -1 && controller.preRender) {
controller.preRender();
}
});
}
function loadTab(page, index) {
currentTabIndex = index;
getTabController(page, index, function (controller) {
if (renderedTabs.indexOf(index) == -1) {
renderedTabs.push(index);
controller.renderTab();
}
});
}
function onPlaybackStop(e, state) {
if (state.NowPlayingItem && state.NowPlayingItem.MediaType == 'Video') {
renderedTabs = [];
mainTabsManager.getTabsElement().triggerTabChange();
}
}
function onWebSocketMessage(e, data) {
const msg = data;
if (msg.MessageType === 'UserDataChanged' && msg.Data.UserId == ApiClient.getCurrentUserId()) {
renderedTabs = [];
}
}
function onInputCommand(e) {
if (e.detail.command === 'search') {
e.preventDefault();
Dashboard.navigate('search.html?collectionType=tv&parentId=' + params.topParentId);
}
}
const self = this;
let currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId), 10);
const suggestionsTabIndex = 1;
self.initTab = function () {
const tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
initSuggestedTab(view, tabContent);
};
self.renderTab = function () {
const tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
loadSuggestionsTab(view, params, tabContent);
};
const tabControllers = [];
let renderedTabs = [];
view.addEventListener('viewshow', function () {
initTabs();
if (!view.getAttribute('data-title')) {
const parentId = params.topParentId;
if (parentId) {
ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) {
view.setAttribute('data-title', item.Name);
libraryMenu.setTitle(item.Name);
});
} else {
view.setAttribute('data-title', globalize.translate('Shows'));
libraryMenu.setTitle(globalize.translate('Shows'));
}
}
Events.on(playbackManager, 'playbackstop', onPlaybackStop);
Events.on(ApiClient, 'message', onWebSocketMessage);
inputManager.on(window, onInputCommand);
});
view.addEventListener('viewbeforehide', function () {
inputManager.off(window, onInputCommand);
Events.off(playbackManager, 'playbackstop', onPlaybackStop);
Events.off(ApiClient, 'message', onWebSocketMessage);
});
view.addEventListener('viewdestroy', function () {
tabControllers.forEach(function (t) {
if (t.destroy) {
t.destroy();
}
});
});
}

View file

@ -10,300 +10,297 @@ import Events from '../../utils/events.ts';
import '../../elements/emby-itemscontainer/emby-itemscontainer';
/* eslint-disable indent */
export default function (view, params, tabContent) {
function getPageData(context) {
const key = getSavedQueryKey(context);
let pageData = data[key];
export default function (view, params, tabContent) {
function getPageData(context) {
const key = getSavedQueryKey(context);
let pageData = data[key];
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'Series',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,BasicSyncInfo',
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
StartIndex: 0
},
view: libraryBrowser.getSavedView(key) || 'Poster'
};
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'Series',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,BasicSyncInfo',
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
StartIndex: 0
},
view: libraryBrowser.getSavedView(key) || 'Poster'
};
if (userSettings.libraryPageSize() > 0) {
pageData.query['Limit'] = userSettings.libraryPageSize();
}
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
if (userSettings.libraryPageSize() > 0) {
pageData.query['Limit'] = userSettings.libraryPageSize();
}
return pageData;
pageData.query.ParentId = params.topParentId;
libraryBrowser.loadSavedQueryValues(key, pageData.query);
}
function getQuery(context) {
return getPageData(context).query;
}
function getSavedQueryKey(context) {
if (!context.savedQueryKey) {
context.savedQueryKey = libraryBrowser.getSavedQueryKey('series');
}
return context.savedQueryKey;
}
const onViewStyleChange = () => {
const viewStyle = this.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') {
itemsContainer.classList.add('vertical-list');
itemsContainer.classList.remove('vertical-wrap');
} else {
itemsContainer.classList.remove('vertical-list');
itemsContainer.classList.add('vertical-wrap');
}
itemsContainer.innerHTML = '';
};
const reloadItems = (page) => {
loading.show();
isLoading = true;
const query = getQuery(page);
ApiClient.getItems(ApiClient.getCurrentUserId(), query).then((result) => {
function onNextPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex += query.Limit;
}
reloadItems(tabContent);
}
function onPreviousPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
}
reloadItems(tabContent);
}
window.scrollTo(0, 0);
this.alphaPicker?.updateControls(query);
let html;
const pagingHtml = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
showLimit: false,
updatePageSizeSetting: false,
addLayoutButton: false,
sortButton: false,
filterButton: false
});
const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'Thumb') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
preferThumb: true,
context: 'tvshows',
overlayMoreButton: true,
showTitle: true,
centerText: true
});
} else if (viewStyle == 'ThumbCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
preferThumb: true,
context: 'tvshows',
cardLayout: true,
showTitle: true,
showYear: true,
centerText: true
});
} else if (viewStyle == 'Banner') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'banner',
preferBanner: true,
context: 'tvshows'
});
} else if (viewStyle == 'List') {
html = listView.getListViewHtml({
items: result.Items,
context: 'tvshows',
sortBy: query.SortBy
});
} else if (viewStyle == 'PosterCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'portrait',
context: 'tvshows',
showTitle: true,
showYear: true,
centerText: true,
cardLayout: true
});
} else {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'portrait',
context: 'tvshows',
centerText: true,
lazy: true,
overlayMoreButton: true,
showTitle: true,
showYear: true
});
}
let elems = tabContent.querySelectorAll('.paging');
for (const elem of elems) {
elem.innerHTML = pagingHtml;
}
elems = tabContent.querySelectorAll('.btnNextPage');
for (const elem of elems) {
elem.addEventListener('click', onNextPageClick);
}
elems = tabContent.querySelectorAll('.btnPreviousPage');
for (const elem of elems) {
elem.addEventListener('click', onPreviousPageClick);
}
const itemsContainer = tabContent.querySelector('.itemsContainer');
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
loading.hide();
isLoading = false;
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(page);
});
});
};
const data = {};
let isLoading = false;
this.showFilterMenu = function () {
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
const filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: 'series',
serverId: ApiClient.serverId()
});
Events.on(filterDialog, 'filterchange', function () {
getQuery(tabContent).StartIndex = 0;
reloadItems(tabContent);
});
filterDialog.show();
});
};
this.getCurrentViewStyle = function () {
return getPageData(tabContent).view;
};
const initPage = (tabElement) => {
const alphaPickerElement = tabElement.querySelector('.alphaPicker');
const itemsContainer = tabElement.querySelector('.itemsContainer');
alphaPickerElement.addEventListener('alphavaluechanged', function (e) {
const newValue = e.detail.value;
const query = getQuery(tabElement);
if (newValue === '#') {
query.NameLessThan = 'A';
delete query.NameStartsWith;
} else {
query.NameStartsWith = newValue;
delete query.NameLessThan;
}
query.StartIndex = 0;
reloadItems(tabElement);
});
this.alphaPicker = new AlphaPicker({
element: alphaPickerElement,
valueChangeEvent: 'click'
});
tabElement.querySelector('.alphaPicker').classList.add('alphabetPicker-right');
alphaPickerElement.classList.add('alphaPicker-fixed-right');
itemsContainer.classList.add('padded-right-withalphapicker');
tabElement.querySelector('.btnFilter').addEventListener('click', () => {
this.showFilterMenu();
});
tabElement.querySelector('.btnSort').addEventListener('click', function (e) {
libraryBrowser.showSortMenu({
items: [{
name: globalize.translate('Name'),
id: 'SortName'
}, {
name: globalize.translate('OptionRandom'),
id: 'Random'
}, {
name: globalize.translate('OptionImdbRating'),
id: 'CommunityRating,SortName'
}, {
name: globalize.translate('OptionDateShowAdded'),
id: 'DateCreated,SortName'
}, {
name: globalize.translate('OptionDateEpisodeAdded'),
id: 'DateLastContentAdded,SortName'
}, {
name: globalize.translate('OptionDatePlayed'),
id: 'SeriesDatePlayed,SortName'
}, {
name: globalize.translate('OptionParentalRating'),
id: 'OfficialRating,SortName'
}, {
name: globalize.translate('OptionReleaseDate'),
id: 'PremiereDate,SortName'
}],
callback: function () {
getQuery(tabElement).StartIndex = 0;
reloadItems(tabElement);
},
query: getQuery(tabElement),
button: e.target
});
});
const btnSelectView = tabElement.querySelector('.btnSelectView');
btnSelectView.addEventListener('click', (e) => {
libraryBrowser.showLayoutMenu(e.target, this.getCurrentViewStyle(), 'Banner,List,Poster,PosterCard,Thumb,ThumbCard'.split(','));
});
btnSelectView.addEventListener('layoutchange', function (e) {
const viewStyle = e.detail.viewStyle;
getPageData(tabElement).view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(tabElement), viewStyle);
getQuery(tabElement).StartIndex = 0;
onViewStyleChange();
reloadItems(tabElement);
});
};
initPage(tabContent);
onViewStyleChange();
this.renderTab = () => {
reloadItems(tabContent);
this.alphaPicker?.updateControls(getQuery(tabContent));
};
return pageData;
}
/* eslint-enable indent */
function getQuery(context) {
return getPageData(context).query;
}
function getSavedQueryKey(context) {
if (!context.savedQueryKey) {
context.savedQueryKey = libraryBrowser.getSavedQueryKey('series');
}
return context.savedQueryKey;
}
const onViewStyleChange = () => {
const viewStyle = this.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') {
itemsContainer.classList.add('vertical-list');
itemsContainer.classList.remove('vertical-wrap');
} else {
itemsContainer.classList.remove('vertical-list');
itemsContainer.classList.add('vertical-wrap');
}
itemsContainer.innerHTML = '';
};
const reloadItems = (page) => {
loading.show();
isLoading = true;
const query = getQuery(page);
ApiClient.getItems(ApiClient.getCurrentUserId(), query).then((result) => {
function onNextPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex += query.Limit;
}
reloadItems(tabContent);
}
function onPreviousPageClick() {
if (isLoading) {
return;
}
if (userSettings.libraryPageSize() > 0) {
query.StartIndex = Math.max(0, query.StartIndex - query.Limit);
}
reloadItems(tabContent);
}
window.scrollTo(0, 0);
this.alphaPicker?.updateControls(query);
let html;
const pagingHtml = libraryBrowser.getQueryPagingHtml({
startIndex: query.StartIndex,
limit: query.Limit,
totalRecordCount: result.TotalRecordCount,
showLimit: false,
updatePageSizeSetting: false,
addLayoutButton: false,
sortButton: false,
filterButton: false
});
const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'Thumb') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
preferThumb: true,
context: 'tvshows',
overlayMoreButton: true,
showTitle: true,
centerText: true
});
} else if (viewStyle == 'ThumbCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'backdrop',
preferThumb: true,
context: 'tvshows',
cardLayout: true,
showTitle: true,
showYear: true,
centerText: true
});
} else if (viewStyle == 'Banner') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'banner',
preferBanner: true,
context: 'tvshows'
});
} else if (viewStyle == 'List') {
html = listView.getListViewHtml({
items: result.Items,
context: 'tvshows',
sortBy: query.SortBy
});
} else if (viewStyle == 'PosterCard') {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'portrait',
context: 'tvshows',
showTitle: true,
showYear: true,
centerText: true,
cardLayout: true
});
} else {
html = cardBuilder.getCardsHtml({
items: result.Items,
shape: 'portrait',
context: 'tvshows',
centerText: true,
lazy: true,
overlayMoreButton: true,
showTitle: true,
showYear: true
});
}
let elems = tabContent.querySelectorAll('.paging');
for (const elem of elems) {
elem.innerHTML = pagingHtml;
}
elems = tabContent.querySelectorAll('.btnNextPage');
for (const elem of elems) {
elem.addEventListener('click', onNextPageClick);
}
elems = tabContent.querySelectorAll('.btnPreviousPage');
for (const elem of elems) {
elem.addEventListener('click', onPreviousPageClick);
}
const itemsContainer = tabContent.querySelector('.itemsContainer');
itemsContainer.innerHTML = html;
imageLoader.lazyChildren(itemsContainer);
libraryBrowser.saveQueryValues(getSavedQueryKey(page), query);
loading.hide();
isLoading = false;
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(page);
});
});
};
const data = {};
let isLoading = false;
this.showFilterMenu = function () {
import('../../components/filterdialog/filterdialog').then(({ default: filterDialogFactory }) => {
const filterDialog = new filterDialogFactory({
query: getQuery(tabContent),
mode: 'series',
serverId: ApiClient.serverId()
});
Events.on(filterDialog, 'filterchange', function () {
getQuery(tabContent).StartIndex = 0;
reloadItems(tabContent);
});
filterDialog.show();
});
};
this.getCurrentViewStyle = function () {
return getPageData(tabContent).view;
};
const initPage = (tabElement) => {
const alphaPickerElement = tabElement.querySelector('.alphaPicker');
const itemsContainer = tabElement.querySelector('.itemsContainer');
alphaPickerElement.addEventListener('alphavaluechanged', function (e) {
const newValue = e.detail.value;
const query = getQuery(tabElement);
if (newValue === '#') {
query.NameLessThan = 'A';
delete query.NameStartsWith;
} else {
query.NameStartsWith = newValue;
delete query.NameLessThan;
}
query.StartIndex = 0;
reloadItems(tabElement);
});
this.alphaPicker = new AlphaPicker({
element: alphaPickerElement,
valueChangeEvent: 'click'
});
tabElement.querySelector('.alphaPicker').classList.add('alphabetPicker-right');
alphaPickerElement.classList.add('alphaPicker-fixed-right');
itemsContainer.classList.add('padded-right-withalphapicker');
tabElement.querySelector('.btnFilter').addEventListener('click', () => {
this.showFilterMenu();
});
tabElement.querySelector('.btnSort').addEventListener('click', function (e) {
libraryBrowser.showSortMenu({
items: [{
name: globalize.translate('Name'),
id: 'SortName'
}, {
name: globalize.translate('OptionRandom'),
id: 'Random'
}, {
name: globalize.translate('OptionImdbRating'),
id: 'CommunityRating,SortName'
}, {
name: globalize.translate('OptionDateShowAdded'),
id: 'DateCreated,SortName'
}, {
name: globalize.translate('OptionDateEpisodeAdded'),
id: 'DateLastContentAdded,SortName'
}, {
name: globalize.translate('OptionDatePlayed'),
id: 'SeriesDatePlayed,SortName'
}, {
name: globalize.translate('OptionParentalRating'),
id: 'OfficialRating,SortName'
}, {
name: globalize.translate('OptionReleaseDate'),
id: 'PremiereDate,SortName'
}],
callback: function () {
getQuery(tabElement).StartIndex = 0;
reloadItems(tabElement);
},
query: getQuery(tabElement),
button: e.target
});
});
const btnSelectView = tabElement.querySelector('.btnSelectView');
btnSelectView.addEventListener('click', (e) => {
libraryBrowser.showLayoutMenu(e.target, this.getCurrentViewStyle(), 'Banner,List,Poster,PosterCard,Thumb,ThumbCard'.split(','));
});
btnSelectView.addEventListener('layoutchange', function (e) {
const viewStyle = e.detail.viewStyle;
getPageData(tabElement).view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(tabElement), viewStyle);
getQuery(tabElement).StartIndex = 0;
onViewStyleChange();
reloadItems(tabElement);
});
};
initPage(tabContent);
onViewStyleChange();
this.renderTab = () => {
reloadItems(tabContent);
this.alphaPicker?.updateControls(getQuery(tabContent));
};
}

View file

@ -2,73 +2,70 @@ import loading from '../../components/loading/loading';
import libraryBrowser from '../../scripts/libraryBrowser';
import cardBuilder from '../../components/cardbuilder/cardBuilder';
/* eslint-disable indent */
function getQuery(params) {
const key = getSavedQueryKey();
let pageData = data[key];
function getQuery(params) {
const key = getSavedQueryKey();
let pageData = data[key];
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'Series',
Recursive: true,
Fields: 'DateCreated,PrimaryImageAspectRatio',
StartIndex: 0
}
};
pageData.query.ParentId = params.topParentId;
}
return pageData.query;
if (!pageData) {
pageData = data[key] = {
query: {
SortBy: 'SortName',
SortOrder: 'Ascending',
IncludeItemTypes: 'Series',
Recursive: true,
Fields: 'DateCreated,PrimaryImageAspectRatio',
StartIndex: 0
}
};
pageData.query.ParentId = params.topParentId;
}
function getSavedQueryKey() {
return libraryBrowser.getSavedQueryKey('studios');
}
return pageData.query;
}
function getPromise(context, params) {
const query = getQuery(params);
loading.show();
return ApiClient.getStudios(ApiClient.getCurrentUserId(), query);
}
function getSavedQueryKey() {
return libraryBrowser.getSavedQueryKey('studios');
}
function reloadItems(context, params, promise) {
promise.then(function (result) {
const elem = context.querySelector('#items');
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: 'backdrop',
preferThumb: true,
showTitle: true,
scalable: true,
centerText: true,
overlayMoreButton: true,
context: 'tvshows'
});
loading.hide();
function getPromise(context, params) {
const query = getQuery(params);
loading.show();
return ApiClient.getStudios(ApiClient.getCurrentUserId(), query);
}
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(context);
});
function reloadItems(context, params, promise) {
promise.then(function (result) {
const elem = context.querySelector('#items');
cardBuilder.buildCards(result.Items, {
itemsContainer: elem,
shape: 'backdrop',
preferThumb: true,
showTitle: true,
scalable: true,
centerText: true,
overlayMoreButton: true,
context: 'tvshows'
});
}
loading.hide();
const data = {};
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(context);
});
});
}
export default function (view, params, tabContent) {
let promise;
const self = this;
const data = {};
self.preRender = function () {
promise = getPromise(view, params);
};
export default function (view, params, tabContent) {
let promise;
const self = this;
self.renderTab = function () {
reloadItems(tabContent, params, promise);
};
}
self.preRender = function () {
promise = getPromise(view, params);
};
self.renderTab = function () {
reloadItems(tabContent, params, promise);
};
}
/* eslint-enable indent */

View file

@ -7,138 +7,135 @@ import globalize from '../../scripts/globalize';
import '../../styles/scrollstyles.scss';
import '../../elements/emby-itemscontainer/emby-itemscontainer';
/* eslint-disable indent */
function getUpcomingPromise(context, params) {
loading.show();
const query = {
Limit: 48,
Fields: 'AirTime',
UserId: ApiClient.getCurrentUserId(),
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
EnableTotalRecordCount: false
};
query.ParentId = params.topParentId;
return ApiClient.getJSON(ApiClient.getUrl('Shows/Upcoming', query));
}
function getUpcomingPromise(context, params) {
loading.show();
const query = {
Limit: 48,
Fields: 'AirTime',
UserId: ApiClient.getCurrentUserId(),
ImageTypeLimit: 1,
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb',
EnableTotalRecordCount: false
};
query.ParentId = params.topParentId;
return ApiClient.getJSON(ApiClient.getUrl('Shows/Upcoming', query));
}
function loadUpcoming(context, params, promise) {
promise.then(function (result) {
const items = result.Items;
function loadUpcoming(context, params, promise) {
promise.then(function (result) {
const items = result.Items;
if (items.length) {
context.querySelector('.noItemsMessage').style.display = 'none';
} else {
context.querySelector('.noItemsMessage').style.display = 'block';
}
if (items.length) {
context.querySelector('.noItemsMessage').style.display = 'none';
} else {
context.querySelector('.noItemsMessage').style.display = 'block';
renderUpcoming(context.querySelector('#upcomingItems'), items);
loading.hide();
});
}
function enableScrollX() {
return !layoutManager.desktop;
}
function getThumbShape() {
return enableScrollX() ? 'overflowBackdrop' : 'backdrop';
}
function renderUpcoming(elem, items) {
const groups = [];
let currentGroupName = '';
let currentGroup = [];
for (let i = 0, length = items.length; i < length; i++) {
const item = items[i];
let dateText = '';
if (item.PremiereDate) {
try {
const premiereDate = datetime.parseISO8601Date(item.PremiereDate, true);
dateText = datetime.isRelativeDay(premiereDate, -1) ? globalize.translate('Yesterday') : datetime.toLocaleDateString(premiereDate, {
weekday: 'long',
month: 'short',
day: 'numeric'
});
} catch (err) {
console.error('error parsing timestamp for upcoming tv shows');
}
}
if (dateText != currentGroupName) {
if (currentGroup.length) {
groups.push({
name: currentGroupName,
items: currentGroup
});
}
renderUpcoming(context.querySelector('#upcomingItems'), items);
loading.hide();
currentGroupName = dateText;
currentGroup = [item];
} else {
currentGroup.push(item);
}
}
let html = '';
for (let i = 0, length = groups.length; i < length; i++) {
const group = groups[i];
html += '<div class="verticalSection">';
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + group.name + '</h2>';
let allowBottomPadding = true;
if (enableScrollX()) {
allowBottomPadding = false;
let scrollXClass = 'scrollX hiddenScrollX';
if (layoutManager.tv) {
scrollXClass += ' smoothScrollX';
}
html += '<div is="emby-itemscontainer" class="itemsContainer ' + scrollXClass + ' padded-left padded-right">';
} else {
html += '<div is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right">';
}
html += cardBuilder.getCardsHtml({
items: group.items,
showLocationTypeIndicator: false,
shape: getThumbShape(),
showTitle: true,
preferThumb: true,
lazy: true,
showDetailsMenu: true,
centerText: true,
showParentTitle: true,
overlayText: false,
allowBottomPadding: allowBottomPadding,
cardLayout: false,
overlayMoreButton: true,
missingIndicator: false
});
html += '</div>';
html += '</div>';
}
function enableScrollX() {
return !layoutManager.desktop;
}
elem.innerHTML = html;
imageLoader.lazyChildren(elem);
}
function getThumbShape() {
return enableScrollX() ? 'overflowBackdrop' : 'backdrop';
}
export default function (view, params, tabContent) {
let upcomingPromise;
const self = this;
function renderUpcoming(elem, items) {
const groups = [];
let currentGroupName = '';
let currentGroup = [];
self.preRender = function () {
upcomingPromise = getUpcomingPromise(view, params);
};
for (let i = 0, length = items.length; i < length; i++) {
const item = items[i];
let dateText = '';
self.renderTab = function () {
loadUpcoming(tabContent, params, upcomingPromise);
};
}
if (item.PremiereDate) {
try {
const premiereDate = datetime.parseISO8601Date(item.PremiereDate, true);
dateText = datetime.isRelativeDay(premiereDate, -1) ? globalize.translate('Yesterday') : datetime.toLocaleDateString(premiereDate, {
weekday: 'long',
month: 'short',
day: 'numeric'
});
} catch (err) {
console.error('error parsing timestamp for upcoming tv shows');
}
}
if (dateText != currentGroupName) {
if (currentGroup.length) {
groups.push({
name: currentGroupName,
items: currentGroup
});
}
currentGroupName = dateText;
currentGroup = [item];
} else {
currentGroup.push(item);
}
}
let html = '';
for (let i = 0, length = groups.length; i < length; i++) {
const group = groups[i];
html += '<div class="verticalSection">';
html += '<h2 class="sectionTitle sectionTitle-cards padded-left">' + group.name + '</h2>';
let allowBottomPadding = true;
if (enableScrollX()) {
allowBottomPadding = false;
let scrollXClass = 'scrollX hiddenScrollX';
if (layoutManager.tv) {
scrollXClass += ' smoothScrollX';
}
html += '<div is="emby-itemscontainer" class="itemsContainer ' + scrollXClass + ' padded-left padded-right">';
} else {
html += '<div is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right">';
}
html += cardBuilder.getCardsHtml({
items: group.items,
showLocationTypeIndicator: false,
shape: getThumbShape(),
showTitle: true,
preferThumb: true,
lazy: true,
showDetailsMenu: true,
centerText: true,
showParentTitle: true,
overlayText: false,
allowBottomPadding: allowBottomPadding,
cardLayout: false,
overlayMoreButton: true,
missingIndicator: false
});
html += '</div>';
html += '</div>';
}
elem.innerHTML = html;
imageLoader.lazyChildren(elem);
}
export default function (view, params, tabContent) {
let upcomingPromise;
const self = this;
self.preRender = function () {
upcomingPromise = getUpcomingPromise(view, params);
};
self.renderTab = function () {
loadUpcoming(tabContent, params, upcomingPromise);
};
}
/* eslint-enable indent */

View file

@ -2,39 +2,36 @@ import DisplaySettings from '../../../components/displaySettings/displaySettings
import * as userSettings from '../../../scripts/settings/userSettings';
import autoFocuser from '../../../components/autoFocuser';
/* eslint-disable indent */
// Shortcuts
const UserSettings = userSettings.UserSettings;
// Shortcuts
const UserSettings = userSettings.UserSettings;
export default function (view, params) {
let settingsInstance;
export default function (view, params) {
let settingsInstance;
const userId = params.userId || ApiClient.getCurrentUserId();
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
const userId = params.userId || ApiClient.getCurrentUserId();
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
view.addEventListener('viewshow', function () {
if (settingsInstance) {
settingsInstance.loadData();
} else {
settingsInstance = new DisplaySettings({
serverId: ApiClient.serverId(),
userId: userId,
element: view.querySelector('.settingsContainer'),
userSettings: currentSettings,
enableSaveButton: true,
enableSaveConfirmation: true,
autoFocus: autoFocuser.isEnabled()
});
}
});
view.addEventListener('viewshow', function () {
if (settingsInstance) {
settingsInstance.loadData();
} else {
settingsInstance = new DisplaySettings({
serverId: ApiClient.serverId(),
userId: userId,
element: view.querySelector('.settingsContainer'),
userSettings: currentSettings,
enableSaveButton: true,
enableSaveConfirmation: true,
autoFocus: autoFocuser.isEnabled()
});
}
});
view.addEventListener('viewdestroy', function () {
if (settingsInstance) {
settingsInstance.destroy();
settingsInstance = null;
}
});
}
view.addEventListener('viewdestroy', function () {
if (settingsInstance) {
settingsInstance.destroy();
settingsInstance = null;
}
});
}
/* eslint-enable indent */

View file

@ -3,39 +3,36 @@ import * as userSettings from '../../../scripts/settings/userSettings';
import autoFocuser from '../../../components/autoFocuser';
import '../../../components/listview/listview.scss';
/* eslint-disable indent */
// Shortcuts
const UserSettings = userSettings.UserSettings;
// Shortcuts
const UserSettings = userSettings.UserSettings;
export default function (view, params) {
let homescreenSettingsInstance;
export default function (view, params) {
let homescreenSettingsInstance;
const userId = params.userId || ApiClient.getCurrentUserId();
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
const userId = params.userId || ApiClient.getCurrentUserId();
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
view.addEventListener('viewshow', function () {
if (homescreenSettingsInstance) {
homescreenSettingsInstance.loadData();
} else {
homescreenSettingsInstance = new HomescreenSettings({
serverId: ApiClient.serverId(),
userId: userId,
element: view.querySelector('.homeScreenSettingsContainer'),
userSettings: currentSettings,
enableSaveButton: true,
enableSaveConfirmation: true,
autoFocus: autoFocuser.isEnabled()
});
}
});
view.addEventListener('viewshow', function () {
if (homescreenSettingsInstance) {
homescreenSettingsInstance.loadData();
} else {
homescreenSettingsInstance = new HomescreenSettings({
serverId: ApiClient.serverId(),
userId: userId,
element: view.querySelector('.homeScreenSettingsContainer'),
userSettings: currentSettings,
enableSaveButton: true,
enableSaveConfirmation: true,
autoFocus: autoFocuser.isEnabled()
});
}
});
view.addEventListener('viewdestroy', function () {
if (homescreenSettingsInstance) {
homescreenSettingsInstance.destroy();
homescreenSettingsInstance = null;
}
});
}
view.addEventListener('viewdestroy', function () {
if (homescreenSettingsInstance) {
homescreenSettingsInstance.destroy();
homescreenSettingsInstance = null;
}
});
}
/* eslint-enable indent */

View file

@ -4,39 +4,36 @@ import * as userSettings from '../../../scripts/settings/userSettings';
import autoFocuser from '../../../components/autoFocuser';
import '../../../components/listview/listview.scss';
/* eslint-disable indent */
// Shortcuts
const UserSettings = userSettings.UserSettings;
// Shortcuts
const UserSettings = userSettings.UserSettings;
export default function (view, params) {
let settingsInstance;
export default function (view, params) {
let settingsInstance;
const userId = params.userId || ApiClient.getCurrentUserId();
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
const userId = params.userId || ApiClient.getCurrentUserId();
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
view.addEventListener('viewshow', function () {
if (settingsInstance) {
settingsInstance.loadData();
} else {
settingsInstance = new PlaybackSettings({
serverId: ApiClient.serverId(),
userId: userId,
element: view.querySelector('.settingsContainer'),
userSettings: currentSettings,
enableSaveButton: true,
enableSaveConfirmation: true,
autoFocus: autoFocuser.isEnabled()
});
}
});
view.addEventListener('viewshow', function () {
if (settingsInstance) {
settingsInstance.loadData();
} else {
settingsInstance = new PlaybackSettings({
serverId: ApiClient.serverId(),
userId: userId,
element: view.querySelector('.settingsContainer'),
userSettings: currentSettings,
enableSaveButton: true,
enableSaveConfirmation: true,
autoFocus: autoFocuser.isEnabled()
});
}
});
view.addEventListener('viewdestroy', function () {
if (settingsInstance) {
settingsInstance.destroy();
settingsInstance = null;
}
});
}
view.addEventListener('viewdestroy', function () {
if (settingsInstance) {
settingsInstance.destroy();
settingsInstance = null;
}
});
}
/* eslint-enable indent */

View file

@ -2,39 +2,36 @@ import SubtitleSettings from '../../../components/subtitlesettings/subtitlesetti
import * as userSettings from '../../../scripts/settings/userSettings';
import autoFocuser from '../../../components/autoFocuser';
/* eslint-disable indent */
// Shortcuts
const UserSettings = userSettings.UserSettings;
// Shortcuts
const UserSettings = userSettings.UserSettings;
export default function (view, params) {
let subtitleSettingsInstance;
export default function (view, params) {
let subtitleSettingsInstance;
const userId = params.userId || ApiClient.getCurrentUserId();
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
const userId = params.userId || ApiClient.getCurrentUserId();
const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings();
view.addEventListener('viewshow', function () {
if (subtitleSettingsInstance) {
subtitleSettingsInstance.loadData();
} else {
subtitleSettingsInstance = new SubtitleSettings({
serverId: ApiClient.serverId(),
userId: userId,
element: view.querySelector('.settingsContainer'),
userSettings: currentSettings,
enableSaveButton: true,
enableSaveConfirmation: true,
autoFocus: autoFocuser.isEnabled()
});
}
});
view.addEventListener('viewshow', function () {
if (subtitleSettingsInstance) {
subtitleSettingsInstance.loadData();
} else {
subtitleSettingsInstance = new SubtitleSettings({
serverId: ApiClient.serverId(),
userId: userId,
element: view.querySelector('.settingsContainer'),
userSettings: currentSettings,
enableSaveButton: true,
enableSaveConfirmation: true,
autoFocus: autoFocuser.isEnabled()
});
}
});
view.addEventListener('viewdestroy', function () {
if (subtitleSettingsInstance) {
subtitleSettingsInstance.destroy();
subtitleSettingsInstance = null;
}
});
}
view.addEventListener('viewdestroy', function () {
if (subtitleSettingsInstance) {
subtitleSettingsInstance.destroy();
subtitleSettingsInstance = null;
}
});
}
/* eslint-enable indent */