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

move themes and plugins into config file

This commit is contained in:
dkanada 2020-08-02 17:28:25 +09:00
parent dbd6d2fb35
commit 1fe25e14dd
18 changed files with 180 additions and 436 deletions

View file

@ -266,6 +266,8 @@
"src/scripts/globalize.js", "src/scripts/globalize.js",
"src/scripts/imagehelper.js", "src/scripts/imagehelper.js",
"src/scripts/inputManager.js", "src/scripts/inputManager.js",
"src/scripts/autoThemes.js",
"src/scripts/themeManager.js",
"src/scripts/keyboardNavigation.js", "src/scripts/keyboardNavigation.js",
"src/scripts/libraryBrowser.js", "src/scripts/libraryBrowser.js",
"src/scripts/multiDownload.js", "src/scripts/multiDownload.js",

View file

@ -36,7 +36,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro
switch (result.State) { switch (result.State) {
case 'SignedIn': case 'SignedIn':
loading.hide(); loading.hide();
skinManager.loadUserSkin(); Emby.Page.goHome();
break; break;
case 'ServerSignIn': case 'ServerSignIn':
result.ApiClient.getPublicUsers().then(function (users) { result.ApiClient.getPublicUsers().then(function (users) {
@ -149,7 +149,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro
if (typeof route.path === 'string') { if (typeof route.path === 'string') {
loadContentUrl(ctx, next, route, currentRequest); loadContentUrl(ctx, next, route, currentRequest);
} else { } else {
// ? TODO
next(); next();
} }
}; };
@ -287,12 +286,9 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro
connectionManager.connect({ connectionManager.connect({
enableAutoLogin: appSettings.enableAutoLogin() enableAutoLogin: appSettings.enableAutoLogin()
}).then(function (result) { }).then(function (result) {
firstConnectionResult = result; firstConnectionResult = result;
options = options || {}; options = options || {};
page({ page({
click: options.click !== false, click: options.click !== false,
hashbang: options.hashbang !== false hashbang: options.hashbang !== false
@ -344,7 +340,7 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro
if (route.isDefaultRoute) { if (route.isDefaultRoute) {
console.debug('appRouter - loading skin home page'); console.debug('appRouter - loading skin home page');
loadUserSkinWithOptions(ctx); Emby.Page.goHome();
return; return;
} else if (route.roles) { } else if (route.roles) {
validateRoles(apiClient, route.roles).then(function () { validateRoles(apiClient, route.roles).then(function () {
@ -358,15 +354,6 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro
callback(); callback();
} }
function loadUserSkinWithOptions(ctx) {
require(['queryString'], function (queryString) {
var params = queryString.parse(ctx.querystring);
skinManager.loadUserSkin({
start: params.start
});
});
}
function validateRoles(apiClient, roles) { function validateRoles(apiClient, roles) {
return Promise.all(roles.split(',').map(function (role) { return Promise.all(roles.split(',').map(function (role) {
return validateRole(apiClient, role); return validateRole(apiClient, role);

View file

@ -277,7 +277,7 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g
features.push('targetblank'); features.push('targetblank');
features.push('screensaver'); features.push('screensaver');
webSettings.enableMultiServer().then(enabled => { webSettings.getMultiServer().then(enabled => {
if (enabled) features.push('multiserver'); if (enabled) features.push('multiserver');
}); });
@ -407,13 +407,6 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g
getPushTokenInfo: function () { getPushTokenInfo: function () {
return {}; return {};
}, },
setThemeColor: function (color) {
var metaThemeColor = document.querySelector('meta[name=theme-color]');
if (metaThemeColor) {
metaThemeColor.setAttribute('content', color);
}
},
setUserScalable: function (scalable) { setUserScalable: function (scalable) {
if (!browser.tv) { if (!browser.tv) {
var att = scalable ? 'width=device-width, initial-scale=1, minimum-scale=1, user-scalable=yes' : 'width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no'; var att = scalable ? 'width=device-width, initial-scale=1, minimum-scale=1, user-scalable=yes' : 'width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no';

View file

@ -16,17 +16,22 @@ import 'emby-button';
/* eslint-disable indent */ /* eslint-disable indent */
function fillThemes(select, isDashboard) { function fillThemes(context, userSettings) {
select.innerHTML = skinManager.getThemes().map(t => { const select = context.querySelector('#selectTheme');
let value = t.id;
if (t.isDefault && !isDashboard) {
value = '';
} else if (t.isDefaultServerDashboard && isDashboard) {
value = '';
}
return `<option value="${value}">${t.name}</option>`; skinManager.getThemes().then(themes => {
}).join(''); select.innerHTML = themes.map(t => {
return `<option value="${t.id}">${t.name}</option>`;
}).join('');
// get default theme
var defaultTheme = themes.find(theme => {
return theme.default;
});
// set the current theme
select.value = userSettings.theme() || defaultTheme.id;
});
} }
function loadScreensavers(context, userSettings) { function loadScreensavers(context, userSettings) {
@ -46,6 +51,7 @@ import 'emby-button';
selectScreensaver.innerHTML = options.map(o => { selectScreensaver.innerHTML = options.map(o => {
return `<option value="${o.value}">${o.name}</option>`; return `<option value="${o.value}">${o.name}</option>`;
}).join(''); }).join('');
selectScreensaver.value = userSettings.screensaver(); selectScreensaver.value = userSettings.screensaver();
if (!selectScreensaver.value) { if (!selectScreensaver.value) {
@ -54,57 +60,6 @@ import 'emby-button';
} }
} }
function loadSoundEffects(context, userSettings) {
const selectSoundEffects = context.querySelector('.selectSoundEffects');
const options = pluginManager.ofType('soundeffects').map(plugin => {
return {
name: plugin.name,
value: plugin.id
};
});
options.unshift({
name: globalize.translate('None'),
value: 'none'
});
selectSoundEffects.innerHTML = options.map(o => {
return `<option value="${o.value}">${o.name}</option>`;
}).join('');
selectSoundEffects.value = userSettings.soundEffects();
if (!selectSoundEffects.value) {
// TODO: set the default instead of none
selectSoundEffects.value = 'none';
}
}
function loadSkins(context, userSettings) {
const selectSkin = context.querySelector('.selectSkin');
const options = pluginManager.ofType('skin').map(plugin => {
return {
name: plugin.name,
value: plugin.id
};
});
selectSkin.innerHTML = options.map(o => {
return `<option value="${o.value}">${o.name}</option>`;
}).join('');
selectSkin.value = userSettings.skin();
if (!selectSkin.value && options.length) {
selectSkin.value = options[0].value;
}
if (options.length > 1 && appHost.supports('skins')) {
context.querySelector('.selectSkinContainer').classList.remove('hide');
} else {
context.querySelector('.selectSkinContainer').classList.add('hide');
}
}
function showOrHideMissingEpisodesField(context) { function showOrHideMissingEpisodesField(context) {
if (browser.tizen || browser.web0s) { if (browser.tizen || browser.web0s) {
context.querySelector('.fldDisplayMissingEpisodes').classList.add('hide'); context.querySelector('.fldDisplayMissingEpisodes').classList.add('hide');
@ -115,12 +70,6 @@ import 'emby-button';
} }
function loadForm(context, user, userSettings) { function loadForm(context, user, userSettings) {
if (user.Policy.IsAdministrator) {
context.querySelector('.selectDashboardThemeContainer').classList.remove('hide');
} else {
context.querySelector('.selectDashboardThemeContainer').classList.add('hide');
}
if (appHost.supports('displaylanguage')) { if (appHost.supports('displaylanguage')) {
context.querySelector('.languageSection').classList.remove('hide'); context.querySelector('.languageSection').classList.remove('hide');
} else { } else {
@ -139,18 +88,6 @@ import 'emby-button';
context.querySelector('.learnHowToContributeContainer').classList.add('hide'); context.querySelector('.learnHowToContributeContainer').classList.add('hide');
} }
if (appHost.supports('runatstartup')) {
context.querySelector('.fldAutorun').classList.remove('hide');
} else {
context.querySelector('.fldAutorun').classList.add('hide');
}
if (appHost.supports('soundeffects')) {
context.querySelector('.fldSoundEffects').classList.remove('hide');
} else {
context.querySelector('.fldSoundEffects').classList.add('hide');
}
if (appHost.supports('screensaver')) { if (appHost.supports('screensaver')) {
context.querySelector('.selectScreensaverContainer').classList.remove('hide'); context.querySelector('.selectScreensaverContainer').classList.remove('hide');
} else { } else {
@ -173,16 +110,8 @@ import 'emby-button';
context.querySelector('.fldThemeVideo').classList.add('hide'); context.querySelector('.fldThemeVideo').classList.add('hide');
} }
context.querySelector('.chkRunAtStartup').checked = appSettings.runAtStartup(); fillThemes(context, userSettings);
const selectTheme = context.querySelector('#selectTheme');
const selectDashboardTheme = context.querySelector('#selectDashboardTheme');
fillThemes(selectTheme);
fillThemes(selectDashboardTheme, true);
loadScreensavers(context, userSettings); loadScreensavers(context, userSettings);
loadSoundEffects(context, userSettings);
loadSkins(context, userSettings);
context.querySelector('.chkDisplayMissingEpisodes').checked = user.Configuration.DisplayMissingEpisodes || false; context.querySelector('.chkDisplayMissingEpisodes').checked = user.Configuration.DisplayMissingEpisodes || false;
@ -198,9 +127,6 @@ import 'emby-button';
context.querySelector('#txtLibraryPageSize').value = userSettings.libraryPageSize(); context.querySelector('#txtLibraryPageSize').value = userSettings.libraryPageSize();
selectDashboardTheme.value = userSettings.dashboardTheme() || '';
selectTheme.value = userSettings.theme() || '';
context.querySelector('.selectLayout').value = layoutManager.getSavedLayout() || ''; context.querySelector('.selectLayout').value = layoutManager.getSavedLayout() || '';
showOrHideMissingEpisodesField(context); showOrHideMissingEpisodesField(context);
@ -209,8 +135,6 @@ import 'emby-button';
} }
function saveUser(context, user, userSettingsInstance, apiClient) { function saveUser(context, user, userSettingsInstance, apiClient) {
appSettings.runAtStartup(context.querySelector('.chkRunAtStartup').checked);
user.Configuration.DisplayMissingEpisodes = context.querySelector('.chkDisplayMissingEpisodes').checked; user.Configuration.DisplayMissingEpisodes = context.querySelector('.chkDisplayMissingEpisodes').checked;
if (appHost.supports('displaylanguage')) { if (appHost.supports('displaylanguage')) {
@ -221,15 +145,11 @@ import 'emby-button';
userSettingsInstance.enableThemeSongs(context.querySelector('#chkThemeSong').checked); userSettingsInstance.enableThemeSongs(context.querySelector('#chkThemeSong').checked);
userSettingsInstance.enableThemeVideos(context.querySelector('#chkThemeVideo').checked); userSettingsInstance.enableThemeVideos(context.querySelector('#chkThemeVideo').checked);
userSettingsInstance.dashboardTheme(context.querySelector('#selectDashboardTheme').value);
userSettingsInstance.theme(context.querySelector('#selectTheme').value); userSettingsInstance.theme(context.querySelector('#selectTheme').value);
userSettingsInstance.soundEffects(context.querySelector('.selectSoundEffects').value);
userSettingsInstance.screensaver(context.querySelector('.selectScreensaver').value); userSettingsInstance.screensaver(context.querySelector('.selectScreensaver').value);
userSettingsInstance.libraryPageSize(context.querySelector('#txtLibraryPageSize').value); userSettingsInstance.libraryPageSize(context.querySelector('#txtLibraryPageSize').value);
userSettingsInstance.skin(context.querySelector('.selectSkin').value);
userSettingsInstance.enableFastFadein(context.querySelector('#chkFadein').checked); userSettingsInstance.enableFastFadein(context.querySelector('#chkFadein').checked);
userSettingsInstance.enableBlurhash(context.querySelector('#chkBlurhash').checked); userSettingsInstance.enableBlurhash(context.querySelector('#chkBlurhash').checked);
userSettingsInstance.enableBackdrops(context.querySelector('#chkBackdrops').checked); userSettingsInstance.enableBackdrops(context.querySelector('#chkBackdrops').checked);

View file

@ -1,5 +1,4 @@
<form style="margin: 0 auto;"> <form style="margin: 0 auto;">
<h2 class="sectionTitle"> <h2 class="sectionTitle">
${Display} ${Display}
</h2> </h2>
@ -123,26 +122,14 @@
<div class="fieldDescription">${LabelPleaseRestart}</div> <div class="fieldDescription">${LabelPleaseRestart}</div>
</div> </div>
<div class="selectContainer hide selectSkinContainer">
<select is="emby-select" class="selectSkin" label="${LabelSkin}"></select>
</div>
<div class="selectContainer"> <div class="selectContainer">
<select id="selectTheme" is="emby-select" label="${LabelTheme}"></select> <select id="selectTheme" is="emby-select" label="${LabelTheme}"></select>
</div> </div>
<div class="selectContainer selectDashboardThemeContainer hide">
<select id="selectDashboardTheme" is="emby-select" label="${LabelDashboardTheme}"></select>
</div>
<div class="selectContainer hide selectScreensaverContainer"> <div class="selectContainer hide selectScreensaverContainer">
<select is="emby-select" class="selectScreensaver" label="${LabelScreensaver}"></select> <select is="emby-select" class="selectScreensaver" label="${LabelScreensaver}"></select>
</div> </div>
<div class="selectContainer fldSoundEffects hide">
<select is="emby-select" class="selectSoundEffects" label="${LabelSoundEffects}"></select>
</div>
<div class="inputContainer inputContainer-withDescription"> <div class="inputContainer inputContainer-withDescription">
<input is="emby-input" type="number" id="txtLibraryPageSize" pattern="[0-9]*" required="required" min="0" max="1000" step="1" label="${LabelLibraryPageSize}" /> <input is="emby-input" type="number" id="txtLibraryPageSize" pattern="[0-9]*" required="required" min="0" max="1000" step="1" label="${LabelLibraryPageSize}" />
<div class="fieldDescription">${LabelLibraryPageSizeHelp}</div> <div class="fieldDescription">${LabelLibraryPageSizeHelp}</div>
@ -196,13 +183,6 @@
<div class="fieldDescription checkboxFieldDescription">${EnableThemeVideosHelp}</div> <div class="fieldDescription checkboxFieldDescription">${EnableThemeVideosHelp}</div>
</div> </div>
<div class="checkboxContainer hide fldAutorun">
<label>
<input type="checkbox" is="emby-checkbox" class="chkRunAtStartup" />
<span>${RunAtStartup}</span>
</label>
</div>
<div class="checkboxContainer checkboxContainer-withDescription fldDisplayMissingEpisodes hide"> <div class="checkboxContainer checkboxContainer-withDescription fldDisplayMissingEpisodes hide">
<label> <label>
<input type="checkbox" is="emby-checkbox" class="chkDisplayMissingEpisodes" /> <input type="checkbox" is="emby-checkbox" class="chkDisplayMissingEpisodes" />

View file

@ -1,184 +0,0 @@
define(['apphost', 'userSettings', 'browser', 'events', 'backdrop', 'globalize', 'require', 'appSettings'], function (appHost, userSettings, browser, events, backdrop, globalize, require, appSettings) {
'use strict';
var themeStyleElement;
var currentThemeId;
function unloadTheme() {
var elem = themeStyleElement;
if (elem) {
elem.parentNode.removeChild(elem);
themeStyleElement = null;
currentThemeId = null;
}
}
function loadUserSkin(options) {
options = options || {};
if (options.start) {
Emby.Page.invokeShortcut(options.start);
} else {
Emby.Page.goHome();
}
}
function getThemes() {
return [{
name: 'Apple TV',
id: 'appletv'
}, {
name: 'Blue Radiance',
id: 'blueradiance'
}, {
name: 'Dark',
id: 'dark',
isDefault: true,
isDefaultServerDashboard: true
}, {
name: 'Light',
id: 'light'
}, {
name: 'Purple Haze',
id: 'purplehaze'
}, {
name: 'Windows Media Center',
id: 'wmc'
}];
}
var skinManager = {
getThemes: getThemes,
loadUserSkin: loadUserSkin
};
function getThemeStylesheetInfo(id, isDefaultProperty) {
var themes = skinManager.getThemes();
var defaultTheme;
var selectedTheme;
for (var i = 0, length = themes.length; i < length; i++) {
var theme = themes[i];
if (theme[isDefaultProperty]) {
defaultTheme = theme;
}
if (id === theme.id) {
selectedTheme = theme;
}
}
selectedTheme = selectedTheme || defaultTheme;
return {
stylesheetPath: require.toUrl('themes/' + selectedTheme.id + '/theme.css'),
themeId: selectedTheme.id
};
}
var themeResources = {};
var lastSound = 0;
var currentSound;
function loadThemeResources(id) {
lastSound = 0;
if (currentSound) {
currentSound.stop();
currentSound = null;
}
backdrop.clearBackdrop();
}
function onThemeLoaded() {
document.documentElement.classList.remove('preload');
try {
var color = getComputedStyle(document.querySelector('.skinHeader')).getPropertyValue('background-color');
if (color) {
appHost.setThemeColor(color);
}
} catch (err) {
console.error('error setting theme color: ' + err);
}
}
skinManager.setTheme = function (id, context) {
return new Promise(function (resolve, reject) {
if (currentThemeId && currentThemeId === id) {
resolve();
return;
}
var isDefaultProperty = context === 'serverdashboard' ? 'isDefaultServerDashboard' : 'isDefault';
var info = getThemeStylesheetInfo(id, isDefaultProperty);
if (currentThemeId && currentThemeId === info.themeId) {
resolve();
return;
}
var linkUrl = info.stylesheetPath;
unloadTheme();
var link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', 'text/css');
link.onload = function () {
onThemeLoaded();
resolve();
};
link.setAttribute('href', linkUrl);
document.head.appendChild(link);
themeStyleElement = link;
currentThemeId = info.themeId;
loadThemeResources(info.themeId);
onViewBeforeShow({});
});
};
function onViewBeforeShow(e) {
if (e.detail && e.detail.type === 'video-osd') {
// This removes the space that the scrollbar takes while playing a video
document.body.classList.remove('force-scroll');
return;
}
if (themeResources.backdrop) {
backdrop.setBackdrop(themeResources.backdrop);
}
if (!browser.mobile && userSettings.enableThemeSongs()) {
if (lastSound === 0) {
if (themeResources.themeSong) {
playSound(themeResources.themeSong);
}
} else if ((new Date().getTime() - lastSound) > 30000) {
if (themeResources.effect) {
playSound(themeResources.effect);
}
}
}
// This keeps the scrollbar always present in all pages, so we avoid clipping while switching between pages
// that need the scrollbar and pages that don't.
document.body.classList.add('force-scroll');
}
document.addEventListener('viewshow', onViewBeforeShow);
function playSound(path, volume) {
lastSound = new Date().getTime();
require(['howler'], function (howler) {
/* globals Howl */
try {
var sound = new Howl({
src: [path],
volume: volume || 0.1
});
sound.play();
currentSound = sound;
} catch (err) {
console.error('error playing sound: ' + err);
}
});
}
return skinManager;
});

View file

@ -1,3 +1,37 @@
{ {
"multiserver": false "multiserver": false,
"themes": [
{
"name": "Apple TV",
"id": "appletv"
}, {
"name": "Blue Radiance",
"id": "blueradiance"
}, {
"name": "Dark",
"id": "dark",
"default": true
}, {
"name": "Light",
"id": "light"
}, {
"name": "Purple Haze",
"id": "purplehaze"
}, {
"name": "WMC",
"id": "wmc"
}
],
"plugins": [
"plugins/playAccessValidation/plugin",
"plugins/experimentalWarnings/plugin",
"plugins/htmlAudioPlayer/plugin",
"plugins/photoPlayer/plugin",
"plugins/bookPlayer/plugin",
"plugins/youtubePlayer/plugin",
"plugins/backdropScreensaver/plugin",
"plugins/logoScreensaver/plugin",
"plugins/sessionPlayer/plugin",
"plugins/chromecastPlayer/plugin"
]
} }

View file

@ -1,13 +1,11 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class="preload"> <html class="preload">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no"> <meta name="msapplication-tap-highlight" content="no">
<meta http-equiv="X-UA-Compatibility" content="IE=Edge"> <meta http-equiv="X-UA-Compatibility" content="IE=Edge">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
@ -15,10 +13,9 @@
<meta name="robots" content="noindex, nofollow, noarchive"> <meta name="robots" content="noindex, nofollow, noarchive">
<meta property="og:title" content="Jellyfin"> <meta property="og:title" content="Jellyfin">
<meta property="og:site_name" content="Jellyfin"> <meta property="og:site_name" content="Jellyfin">
<meta property="og:url" content="http://jellyfin.media"> <meta property="og:url" content="http://jellyfin.org">
<meta property="og:description" content="The Free Software Media System."> <meta property="og:description" content="The Free Software Media System">
<meta property="og:type" content="article"> <meta property="og:type" content="article">
<meta property="fb:app_id" content="1618309211750238">
<link rel="apple-touch-icon" sizes="180x180" href="touchicon.png"> <link rel="apple-touch-icon" sizes="180x180" href="touchicon.png">
<!-- iPhone 5 --> <!-- iPhone 5 -->
@ -64,7 +61,6 @@
<link rel="shortcut icon" href="favicon.ico"> <link rel="shortcut icon" href="favicon.ico">
<meta name="msapplication-TileImage" content="touchicon144.png"> <meta name="msapplication-TileImage" content="touchicon144.png">
<meta name="msapplication-TileColor" content="#333333"> <meta name="msapplication-TileColor" content="#333333">
<meta name="theme-color" content="#101010">
<title>Jellyfin</title> <title>Jellyfin</title>

View file

@ -1,6 +1,6 @@
{ {
"name": "Jellyfin", "name": "Jellyfin",
"description": "Jellyfin: the Free Software Media System.", "description": "The Free Software Media System",
"lang": "en-US", "lang": "en-US",
"short_name": "Jellyfin", "short_name": "Jellyfin",
"start_url": "index.html#!/home.html", "start_url": "index.html#!/home.html",

View file

@ -363,7 +363,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', '
} }
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
require(['chromecastHelper'], function (chromecastHelper) { require(['./chromecastHelper'], function (chromecastHelper) {
chromecastHelper.getServerAddress(apiClient).then(function (serverAddress) { chromecastHelper.getServerAddress(apiClient).then(function (serverAddress) {
message.serverAddress = serverAddress; message.serverAddress = serverAddress;
player.sendMessageInternal(message).then(resolve, reject); player.sendMessageInternal(message).then(resolve, reject);

View file

@ -0,0 +1,8 @@
import * as userSettings from 'userSettings';
import skinManager from 'skinManager';
import connectionManager from 'connectionManager';
import events from 'events';
events.on(connectionManager, 'localusersignedin', function (e, user) {
skinManager.setTheme(userSettings.theme());
});

View file

@ -35,6 +35,7 @@ import appHost from 'apphost';
if (eventListenerCount) { if (eventListenerCount) {
eventListenerCount--; eventListenerCount--;
} }
dom.removeEventListener(scope, 'command', fn, {}); dom.removeEventListener(scope, 'command', fn, {});
} }

View file

@ -80,43 +80,6 @@ import events from 'events';
return val ? parseInt(val) : null; return val ? parseInt(val) : null;
} }
export function syncOnlyOnWifi(val) {
if (val !== undefined) {
this.set('syncOnlyOnWifi', val.toString());
}
return this.get('syncOnlyOnWifi') !== 'false';
}
export function syncPath(val) {
if (val !== undefined) {
this.set('syncPath', val);
}
return this.get('syncPath');
}
export function cameraUploadServers(val) {
if (val !== undefined) {
this.set('cameraUploadServers', val.join(','));
}
val = this.get('cameraUploadServers');
if (val) {
return val.split(',');
}
return [];
}
export function runAtStartup(val) {
if (val !== undefined) {
this.set('runatstartup', val.toString());
}
return this.get('runatstartup') === 'true';
}
export function set(name, value, userId) { export function set(name, value, userId) {
const currentValue = this.get(name, userId); const currentValue = this.get(name, userId);
appStorage.setItem(getKey(name, userId), value); appStorage.setItem(getKey(name, userId), value);
@ -139,10 +102,6 @@ export default {
maxStreamingBitrate: maxStreamingBitrate, maxStreamingBitrate: maxStreamingBitrate,
maxStaticMusicBitrate: maxStaticMusicBitrate, maxStaticMusicBitrate: maxStaticMusicBitrate,
maxChromecastBitrate: maxChromecastBitrate, maxChromecastBitrate: maxChromecastBitrate,
syncOnlyOnWifi: syncOnlyOnWifi,
syncPath: syncPath,
cameraUploadServers: cameraUploadServers,
runAtStartup: runAtStartup,
set: set, set: set,
get: get get: get
}; };

View file

@ -18,7 +18,7 @@ function getDefaultConfig() {
}); });
} }
export function enableMultiServer() { export function getMultiServer() {
return getConfig().then(config => { return getConfig().then(config => {
return config.multiserver; return config.multiserver;
}).catch(error => { }).catch(error => {
@ -26,3 +26,21 @@ export function enableMultiServer() {
return false; return false;
}); });
} }
export function getThemes() {
return getConfig().then(config => {
return config.themes;
}).catch(error => {
console.log('cannot get web config:', error);
return [];
});
}
export function getPlugins() {
return getConfig().then(config => {
return config.plugins;
}).catch(error => {
console.log('cannot get web config:', error);
return [];
});
}

View file

@ -477,36 +477,30 @@ function initClient() {
function loadPlugins(appHost, browser, shell) { function loadPlugins(appHost, browser, shell) {
console.debug('loading installed plugins'); console.debug('loading installed plugins');
var list = [
'plugins/playAccessValidation/plugin',
'plugins/experimentalWarnings/plugin',
'plugins/htmlAudioPlayer/plugin',
'plugins/htmlVideoPlayer/plugin',
'plugins/photoPlayer/plugin',
'plugins/bookPlayer/plugin',
'plugins/youtubePlayer/plugin',
'plugins/backdropScreensaver/plugin',
'plugins/logoScreensaver/plugin'
];
if (appHost.supports('remotecontrol')) {
list.push('plugins/sessionPlayer/plugin');
if (browser.chrome || browser.edgeChromium || browser.opera) {
list.push('plugins/chromecastPlayer/plugin');
}
}
if (window.NativeShell) {
list = list.concat(window.NativeShell.getPlugins());
}
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
Promise.all(list.map(loadPlugin)).then(function () { require(['webSettings'], function (webSettings) {
require(['packageManager'], function (packageManager) { webSettings.getPlugins().then(function (list) {
packageManager.init().then(resolve, reject); // these two plugins are dependent on features
if (!appHost.supports('remotecontrol')) {
list.splice(list.indexOf('sessionPlayer'), 1);
if (!browser.chrome && !browser.opera) {
list.splice(list.indexOf('chromecastPlayer', 1));
}
}
// add any native plugins
if (window.NativeShell) {
list = list.concat(window.NativeShell.getPlugins());
}
Promise.all(list.map(loadPlugin)).then(function () {
require(['packageManager'], function (packageManager) {
packageManager.init().then(resolve, reject);
});
}, reject);
}); });
}, reject); });
}); });
} }
@ -532,7 +526,7 @@ function initClient() {
window.Emby.Page = appRouter; window.Emby.Page = appRouter;
require(['emby-button', 'scripts/themeLoader', 'libraryMenu', 'scripts/routes'], function () { require(['emby-button', 'scripts/autoThemes', 'libraryMenu', 'scripts/routes'], function () {
Emby.Page.start({ Emby.Page.start({
click: false, click: false,
hashbang: true hashbang: true
@ -653,8 +647,7 @@ function initClient() {
nowPlayingHelper: componentsPath + '/playback/nowplayinghelper', nowPlayingHelper: componentsPath + '/playback/nowplayinghelper',
pluginManager: componentsPath + '/pluginManager', pluginManager: componentsPath + '/pluginManager',
packageManager: componentsPath + '/packageManager', packageManager: componentsPath + '/packageManager',
screensaverManager: componentsPath + '/screensavermanager', screensaverManager: componentsPath + '/screensavermanager'
chromecastHelper: 'plugins/chromecastPlayer/chromecastHelpers'
}; };
requirejs.onError = onRequireJsError; requirejs.onError = onRequireJsError;
@ -848,7 +841,7 @@ function initClient() {
define('viewContainer', [componentsPath + '/viewContainer'], returnFirstDependency); define('viewContainer', [componentsPath + '/viewContainer'], returnFirstDependency);
define('dialogHelper', [componentsPath + '/dialogHelper/dialogHelper'], returnFirstDependency); define('dialogHelper', [componentsPath + '/dialogHelper/dialogHelper'], returnFirstDependency);
define('serverNotifications', [scriptsPath + '/serverNotifications'], returnFirstDependency); define('serverNotifications', [scriptsPath + '/serverNotifications'], returnFirstDependency);
define('skinManager', [componentsPath + '/skinManager'], returnFirstDependency); define('skinManager', [scriptsPath + '/themeManager'], returnFirstDependency);
define('keyboardnavigation', [scriptsPath + '/keyboardNavigation'], returnFirstDependency); define('keyboardnavigation', [scriptsPath + '/keyboardNavigation'], returnFirstDependency);
define('mouseManager', [scriptsPath + '/mouseManager'], returnFirstDependency); define('mouseManager', [scriptsPath + '/mouseManager'], returnFirstDependency);
define('scrollManager', [componentsPath + '/scrollManager'], returnFirstDependency); define('scrollManager', [componentsPath + '/scrollManager'], returnFirstDependency);

View file

@ -1,29 +0,0 @@
import * as userSettings from 'userSettings';
import skinManager from 'skinManager';
import connectionManager from 'connectionManager';
import events from 'events';
var currentViewType;
pageClassOn('viewbeforeshow', 'page', function () {
var classList = this.classList;
var viewType = classList.contains('type-interior') || classList.contains('wizardPage') ? 'a' : 'b';
if (viewType !== currentViewType) {
currentViewType = viewType;
var theme;
var context;
if (viewType === 'a') {
theme = userSettings.dashboardTheme();
context = 'serverdashboard';
} else {
theme = userSettings.theme();
}
skinManager.setTheme(theme, context);
}
});
events.on(connectionManager, 'localusersignedin', function (e, user) {
currentViewType = null;
});

View file

@ -0,0 +1,66 @@
import * as webSettings from 'webSettings';
var themeStyleElement;
var currentThemeId;
function unloadTheme() {
var elem = themeStyleElement;
if (elem) {
elem.parentNode.removeChild(elem);
themeStyleElement = null;
currentThemeId = null;
}
}
function getThemes() {
return webSettings.getThemes();
}
function getThemeStylesheetInfo(id) {
return getThemes().then(themes => {
var theme = themes.find(theme => {
return id ? theme.id === id : theme.default;
});
return {
stylesheetPath: 'themes/' + theme.id + '/theme.css',
themeId: theme.id
};
});
}
function setTheme(id) {
return new Promise(function (resolve, reject) {
if (currentThemeId && currentThemeId === id) {
resolve();
return;
}
getThemeStylesheetInfo(id).then(function (info) {
if (currentThemeId && currentThemeId === info.themeId) {
resolve();
return;
}
var linkUrl = info.stylesheetPath;
unloadTheme();
var link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', 'text/css');
link.onload = function () {
resolve();
};
link.setAttribute('href', linkUrl);
document.head.appendChild(link);
themeStyleElement = link;
currentThemeId = info.themeId;
});
});
}
export default {
getThemes: getThemes,
setTheme: setTheme
};