Merge branch 'master' of https://github.com/jellyfin/jellyfin-web into item-detail-page-

# Resolve Conflicts:
#	src/assets/css/librarybrowser.css
#	src/itemdetails.html
This commit is contained in:
grafixeyehero 2020-01-30 20:11:40 +03:00
commit b06afa3305
247 changed files with 5884 additions and 3079 deletions

View file

@ -18,12 +18,15 @@ define(['browser'], function (browser) {
}
}
// Unfortunately haven't yet found a canPlayType for proper detection
if (browser.iOS && (browser.iOSVersion || 0) >= 11) {
return true;
if (browser.ps4) {
return false;
}
return !!(videoTestElement.canPlayType && videoTestElement.canPlayType('video/hevc; codecs="hevc, aac"').replace(/no/, ''));
return !!videoTestElement.canPlayType &&
(videoTestElement.canPlayType('video/mp4; codecs="hvc1.1.L120"').replace(/no/, '') ||
videoTestElement.canPlayType('video/mp4; codecs="hev1.1.L120"').replace(/no/, '') ||
videoTestElement.canPlayType('video/mp4; codecs="hvc1.1.0.L120"').replace(/no/, '') ||
videoTestElement.canPlayType('video/mp4; codecs="hev1.1.0.L120"').replace(/no/, ''));
}
var _supportsTextTracks;
@ -41,7 +44,7 @@ define(['browser'], function (browser) {
}
var _canPlayHls;
function canPlayHls(src) {
function canPlayHls() {
if (_canPlayHls == null) {
_canPlayHls = canPlayNativeHls() || canPlayHlsWithMSE();
}
@ -64,12 +67,8 @@ define(['browser'], function (browser) {
}
function canPlayHlsWithMSE() {
if (window.MediaSource != null) {
// text tracks dont work with this in firefox
return true;
}
return false;
// text tracks dont work with this in firefox
return window.MediaSource != null;
}
function supportsAc3(videoTestElement) {
@ -88,30 +87,45 @@ define(['browser'], function (browser) {
return videoTestElement.canPlayType('audio/mp4; codecs="ec-3"').replace(/no/, '');
}
function supportsAc3InHls(videoTestElement) {
if (browser.tizen || browser.orsay || browser.web0s) {
return true;
}
if (!!videoTestElement.canPlayType) {
return videoTestElement.canPlayType('application/x-mpegurl; codecs="avc1.42E01E, ac-3"').replace(/no/, '') ||
videoTestElement.canPlayType('application/vnd.apple.mpegURL; codecs="avc1.42E01E, ac-3"').replace(/no/, '');
}
return false;
}
function canPlayAudioFormat(format) {
var typeString;
if (format === 'flac') {
if (browser.tizen || browser.orsay || browser.web0s) {
return true;
}
if (browser.edgeUwp) {
if (browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp) {
return true;
}
} else if (format === 'wma') {
if (browser.tizen || browser.orsay) {
if (browser.tizen || browser.orsay || browser.edgeUwp) {
return true;
}
if (browser.edgeUwp) {
} else if (format === 'asf') {
if (browser.tizen || browser.web0s || browser.edgeUwp) {
return true;
}
} else if (format === 'opus') {
typeString = 'audio/ogg; codecs="opus"';
if (document.createElement('audio').canPlayType(typeString).replace(/no/, '')) {
return true;
if (!browser.web0s) {
typeString = 'audio/ogg; codecs="opus"';
return !!document.createElement('audio').canPlayType(typeString).replace(/no/, '');
}
return false;
} else if (format === 'alac') {
if (browser.iOS || browser.osx) {
return true;
}
} else if (format === 'mp2') {
// For now
return false;
@ -125,11 +139,7 @@ define(['browser'], function (browser) {
typeString = 'audio/' + format;
}
if (document.createElement('audio').canPlayType(typeString).replace(/no/, '')) {
return true;
}
return false;
return !!document.createElement('audio').canPlayType(typeString).replace(/no/, '');
}
function testCanPlayMkv(videoTestElement) {
@ -142,8 +152,6 @@ define(['browser'], function (browser) {
return true;
}
var userAgent = navigator.userAgent.toLowerCase();
// Unfortunately there's no real way to detect mkv support
if (browser.chrome) {
// Not supported on opera tv
@ -151,6 +159,8 @@ define(['browser'], function (browser) {
return false;
}
var userAgent = navigator.userAgent.toLowerCase();
// Filter out browsers based on chromium that don't support mkv
if (userAgent.indexOf('vivaldi') !== -1 || userAgent.indexOf('opera') !== -1) {
return false;
@ -199,15 +209,15 @@ define(['browser'], function (browser) {
switch (container) {
case 'asf':
supported = browser.tizen || browser.orsay || browser.edgeUwp;
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
videoAudioCodecs = [];
break;
case 'avi':
supported = browser.tizen || browser.orsay || browser.edgeUwp;
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
break;
case 'mpg':
case 'mpeg':
supported = browser.edgeUwp || browser.tizen || browser.orsay;
supported = browser.tizen || browser.orsay || browser.web0s || browser.edgeUwp;
break;
case 'flv':
supported = browser.tizen || browser.orsay;
@ -223,7 +233,7 @@ define(['browser'], function (browser) {
supported = browser.tizen || browser.orsay;
break;
case 'mov':
supported = browser.tizen || browser.orsay || browser.chrome || browser.edgeUwp;
supported = browser.tizen || browser.orsay || browser.web0s || browser.chrome || browser.edgeUwp;
videoCodecs.push('h264');
break;
case 'm2ts':
@ -259,16 +269,12 @@ define(['browser'], function (browser) {
break;
}
if (!supported) {
return null;
}
return {
return supported ? {
Container: profileContainer,
Type: 'Video',
VideoCodec: videoCodecs.join(','),
AudioCodec: videoAudioCodecs.join(',')
};
} : null;
}
function getMaxBitrate() {
@ -369,8 +375,7 @@ define(['browser'], function (browser) {
// This works in edge desktop, but not mobile
// TODO: Retest this on mobile
var supportsAc3InHls = (!browser.edge || !browser.touch || browser.edgeUwp);
if (supportsAc3InHls) {
if (supportsAc3InHls(videoTestElement)) {
hlsVideoAudioCodecs.push('ac3');
if (eAc3) {
hlsVideoAudioCodecs.push('eac3');
@ -471,6 +476,7 @@ define(['browser'], function (browser) {
mp4VideoCodecs.push('h264');
hlsVideoCodecs.push('h264');
}
if (canPlayH265(videoTestElement, options)) {
mp4VideoCodecs.push('h265');
mp4VideoCodecs.push('hevc');
@ -553,10 +559,10 @@ define(['browser'], function (browser) {
});
}
// aac also appears in the m4a container
// aac also appears in the m4a and m4b container
if (audioFormat === 'aac' || audioFormat === 'alac') {
profile.DirectPlayProfiles.push({
Container: 'm4a',
Container: 'm4a,m4b',
AudioCodec: audioFormat,
Type: 'Audio'
});
@ -648,7 +654,7 @@ define(['browser'], function (browser) {
});
}
if (canPlayHls() && options.enableHls !== false) {
if (canPlayHls() && hlsVideoAudioCodecs.length && options.enableHls !== false) {
profile.TranscodingProfiles.push({
Container: 'ts',
Type: 'Video',
@ -743,11 +749,21 @@ define(['browser'], function (browser) {
});
}
var maxH264Level = browser.chromecast ? 42 : 51;
var maxH264Level = 42;
var h264Profiles = 'high|main|baseline|constrained baseline';
if (maxH264Level >= 51 && browser.chrome && !browser.osx) {
h264Profiles += '|high 10';
if (browser.tizen || browser.orsay || browser.web0s ||
videoTestElement.canPlayType('video/mp4; codecs="avc1.640833"').replace(/no/, '')) {
maxH264Level = 51;
}
if (browser.tizen || browser.orsay ||
videoTestElement.canPlayType('video/mp4; codecs="avc1.6e0033"').replace(/no/, '')) {
// These tests are passing in safari, but playback is failing
if (!browser.safari && !browser.iOS && !browser.web0s && !browser.edge) {
h264Profiles += '|high 10';
}
}
profile.CodecProfiles.push({
@ -763,12 +779,14 @@ define(['browser'], function (browser) {
{
Condition: 'EqualsAny',
Property: 'VideoProfile',
Value: h264Profiles
Value: h264Profiles,
IsRequired: false
},
{
Condition: 'LessThanEqual',
Property: 'VideoLevel',
Value: maxH264Level.toString()
Value: maxH264Level.toString(),
IsRequired: false
}
]
});

View file

@ -43,20 +43,20 @@ define(["datetime", "jQuery", "material-icons"], function (datetime, $) {
}
var htmlName = "<div class='editorNode'>";
if (item.IsFolder) {
htmlName += '<i class="md-icon metadataSidebarIcon">folder</i>';
htmlName += '<i class="material-icons metadataSidebarIcon">folder</i>';
} else if (item.MediaType === "Video") {
htmlName += '<i class="md-icon metadataSidebarIcon">movie</i>';
htmlName += '<i class="material-icons metadataSidebarIcon">movie</i>';
} else if (item.MediaType === "Audio") {
htmlName += '<i class="md-icon metadataSidebarIcon">audiotrack</i>';
htmlName += '<i class="material-icons metadataSidebarIcon">audiotrack</i>';
} else if (item.Type === "TvChannel") {
htmlName += '<i class="md-icon metadataSidebarIcon">live_tv</i>';
htmlName += '<i class="material-icons metadataSidebarIcon">live_tv</i>';
} else if (item.MediaType === "Photo") {
htmlName += '<i class="md-icon metadataSidebarIcon">photo</i>';
htmlName += '<i class="material-icons metadataSidebarIcon">photo</i>';
} else if (item.MediaType === "Book") {
htmlName += '<i class="md-icon metadataSidebarIcon">book</i>';
htmlName += '<i class="material-icons metadataSidebarIcon">book</i>';
}
if (item.LockData) {
htmlName += '<i class="md-icon metadataSidebarIcon">lock</i>';
htmlName += '<i class="material-icons metadataSidebarIcon">lock</i>';
}
htmlName += name;
htmlName += "</div>";

View file

@ -1,4 +1,4 @@
define(['playbackManager', 'focusManager', 'appRouter', 'dom'], function (playbackManager, focusManager, appRouter, dom) {
define(['playbackManager', 'focusManager', 'appRouter', 'dom', 'apphost'], function (playbackManager, focusManager, appRouter, dom, appHost) {
'use strict';
var lastInputTime = new Date().getTime();
@ -22,9 +22,7 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom'], function (playba
var eventListenerCount = 0;
function on(scope, fn) {
if (eventListenerCount) {
eventListenerCount++;
}
eventListenerCount++;
dom.addEventListener(scope, 'command', fn, {});
}
@ -98,7 +96,11 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom'], function (playba
appRouter.showSettings();
break;
case 'back':
appRouter.back();
if (appRouter.canGoBack()) {
appRouter.back();
} else if (appHost.supports('exit')) {
appHost.exit();
}
break;
case 'forward':
break;

View file

@ -91,20 +91,20 @@ define(["userSettings"], function (userSettings) {
html += '<div style="display:inline-block;">';
if (showControls) {
html += '<button is="paper-icon-button-light" class="btnPreviousPage autoSize" ' + (startIndex ? "" : "disabled") + '><i class="md-icon">arrow_back</i></button>';
html += '<button is="paper-icon-button-light" class="btnNextPage autoSize" ' + (startIndex + limit >= totalRecordCount ? "disabled" : "") + '><i class="md-icon">arrow_forward</i></button>';
html += '<button is="paper-icon-button-light" class="btnPreviousPage autoSize" ' + (startIndex ? "" : "disabled") + '><i class="material-icons">arrow_back</i></button>';
html += '<button is="paper-icon-button-light" class="btnNextPage autoSize" ' + (startIndex + limit >= totalRecordCount ? "disabled" : "") + '><i class="material-icons">arrow_forward</i></button>';
}
if (options.addLayoutButton) {
html += '<button is="paper-icon-button-light" title="' + Globalize.translate("ButtonSelectView") + '" class="btnChangeLayout autoSize" data-layouts="' + (options.layouts || "") + '" onclick="LibraryBrowser.showLayoutMenu(this, \'' + (options.currentLayout || "") + '\');"><i class="md-icon">view_comfy</i></button>';
html += '<button is="paper-icon-button-light" title="' + Globalize.translate("ButtonSelectView") + '" class="btnChangeLayout autoSize" data-layouts="' + (options.layouts || "") + '" onclick="LibraryBrowser.showLayoutMenu(this, \'' + (options.currentLayout || "") + '\');"><i class="material-icons">view_comfy</i></button>';
}
if (options.sortButton) {
html += '<button is="paper-icon-button-light" class="btnSort autoSize" title="' + Globalize.translate("ButtonSort") + '"><i class="md-icon">sort_by_alpha</i></button>';
html += '<button is="paper-icon-button-light" class="btnSort autoSize" title="' + Globalize.translate("ButtonSort") + '"><i class="material-icons">sort_by_alpha</i></button>';
}
if (options.filterButton) {
html += '<button is="paper-icon-button-light" class="btnFilter autoSize" title="' + Globalize.translate("ButtonFilter") + '"><i class="md-icon">filter_list</i></button>';
html += '<button is="paper-icon-button-light" class="btnFilter autoSize" title="' + Globalize.translate("ButtonFilter") + '"><i class="material-icons">filter_list</i></button>';
}
html += "</div>";

View file

@ -1,6 +1,38 @@
define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "viewManager", "libraryBrowser", "appRouter", "apphost", "playbackManager", "browser", "globalize", "scripts/imagehelper", "paper-icon-button-light", "material-icons", "scrollStyles", "flexStyles"], function (dom, layoutManager, inputManager, connectionManager, events, viewManager, libraryBrowser, appRouter, appHost, playbackManager, browser, globalize, imageHelper) {
"use strict";
function renderHeader() {
var html = "";
html += '<div class="flex align-items-center flex-grow headerTop">';
html += '<div class="headerLeft">';
html += '<button type="button" is="paper-icon-button-light" class="headerButton headerButtonLeft headerBackButton hide"><i class="material-icons">' + (browser.safari ? "chevron_left" : "arrow_back") + "</i></button>";
html += '<button type="button" is="paper-icon-button-light" class="headerButton headerHomeButton hide barsMenuButton headerButtonLeft"><i class="material-icons">home</i></button>';
html += '<button type="button" is="paper-icon-button-light" class="headerButton mainDrawerButton barsMenuButton headerButtonLeft hide"><i class="material-icons">menu</i></button>';
html += '<h3 class="pageTitle"></h3>';
html += "</div>";
html += '<div class="headerRight">';
html += '<span class="headerSelectedPlayer"></span>';
html += '<button is="paper-icon-button-light" class="headerCastButton castButton headerButton headerButtonRight hide"><i class="material-icons">cast</i></button>';
html += '<button type="button" is="paper-icon-button-light" class="headerButton headerButtonRight headerSearchButton hide"><i class="material-icons">search</i></button>';
html += '<button is="paper-icon-button-light" class="headerButton headerButtonRight headerUserButton hide"><i class="material-icons">person</i></button>';
html += "</div>";
html += "</div>";
html += '<div class="headerTabs sectionTabs hide">';
html += "</div>";
skinHeader.classList.add("skinHeader-withBackground");
skinHeader.classList.add("skinHeader-blurred");
skinHeader.innerHTML = html;
headerHomeButton = skinHeader.querySelector(".headerHomeButton");
headerUserButton = skinHeader.querySelector(".headerUserButton");
headerCastButton = skinHeader.querySelector(".headerCastButton");
headerSearchButton = skinHeader.querySelector(".headerSearchButton");
lazyLoadViewMenuBarImages();
bindMenuEvents();
}
function getCurrentApiClient() {
if (currentUser && currentUser.localUser) {
return connectionManager.getApiClient(currentUser.localUser.ServerId);
@ -68,7 +100,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
headerUserButton.innerHTML = '<div class="headerButton headerButtonRight paper-icon-button-light headerUserButtonRound" style="background-image:url(\'' + src + "');\"></div>";
} else {
headerUserButton.classList.remove("headerUserButtonRound");
headerUserButton.innerHTML = '<i class="md-icon">person</i>';
headerUserButton.innerHTML = '<i class="material-icons">person</i>';
}
}
@ -161,7 +193,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
function refreshLibraryInfoInDrawer(user, drawer) {
var html = "";
html += '<div style="height:.5em;"></div>';
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder" href="home.html"><i class="md-icon navMenuOptionIcon">home</i><span class="navMenuOptionText">' + globalize.translate("ButtonHome") + "</span></a>";
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder" href="home.html"><i class="material-icons navMenuOptionIcon">home</i><span class="navMenuOptionText">' + globalize.translate("ButtonHome") + "</span></a>";
// libraries are added here
html += '<div class="libraryMenuOptions">';
@ -172,8 +204,8 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
html += '<h3 class="sidebarHeader">';
html += globalize.translate("HeaderAdmin");
html += "</h3>";
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder lnkManageServer" data-itemid="dashboard" href="dashboard.html"><i class="md-icon navMenuOptionIcon">dashboard</i><span class="navMenuOptionText">' + globalize.translate("TabDashboard") + "</span></a>";
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder editorViewMenu" data-itemid="editor" href="edititemmetadata.html"><i class="md-icon navMenuOptionIcon">mode_edit</i><span class="navMenuOptionText">' + globalize.translate("Metadata") + "</span></a>";
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder lnkManageServer" data-itemid="dashboard" href="dashboard.html"><i class="material-icons navMenuOptionIcon">dashboard</i><span class="navMenuOptionText">' + globalize.translate("TabDashboard") + "</span></a>";
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder editorViewMenu" data-itemid="editor" href="edititemmetadata.html"><i class="material-icons navMenuOptionIcon">mode_edit</i><span class="navMenuOptionText">' + globalize.translate("Metadata") + "</span></a>";
html += "</div>";
}
@ -184,10 +216,10 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
html += "</h3>";
if (appHost.supports("multiserver")) {
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder" data-itemid="selectserver" href="selectserver.html?showuser=1"><i class="md-icon navMenuOptionIcon">wifi</i><span class="navMenuOptionText">' + globalize.translate("ButtonSelectServer") + "</span></a>";
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder" data-itemid="selectserver" href="selectserver.html?showuser=1"><i class="material-icons navMenuOptionIcon">wifi</i><span class="navMenuOptionText">' + globalize.translate("ButtonSelectServer") + "</span></a>";
}
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder btnLogout" data-itemid="logout" href="#"><i class="md-icon navMenuOptionIcon">exit_to_app</i><span class="navMenuOptionText">' + globalize.translate("ButtonSignOut") + "</span></a>";
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder btnLogout" data-itemid="logout" href="#"><i class="material-icons navMenuOptionIcon">exit_to_app</i><span class="navMenuOptionText">' + globalize.translate("ButtonSignOut") + "</span></a>";
html += "</div>";
}
@ -391,7 +423,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
menuHtml += '<a is="emby-linkbutton" class="navMenuOption" href="' + item.href + '"' + pageIds + pageUrls + ">";
if (item.icon) {
menuHtml += '<i class="md-icon navMenuOptionIcon">' + item.icon + "</i>";
menuHtml += '<i class="material-icons navMenuOptionIcon">' + item.icon + "</i>";
}
menuHtml += '<span class="navMenuOptionText">';
@ -518,7 +550,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
i.onclick;
}
return '<a is="emby-linkbutton" data-itemid="' + itemId + '" class="lnkMediaFolder navMenuOption" href="' + getItemHref(i, i.CollectionType) + '"><i class="md-icon navMenuOptionIcon">' + icon + '</i><span class="sectionName navMenuOptionText">' + i.Name + "</span></a>";
return '<a is="emby-linkbutton" data-itemid="' + itemId + '" class="lnkMediaFolder navMenuOption" href="' + getItemHref(i, i.CollectionType) + '"><i class="material-icons navMenuOptionIcon">' + icon + '</i><span class="sectionName navMenuOptionText">' + i.Name + "</span></a>";
}).join("");
libraryMenuOptions.innerHTML = html;
var elem = libraryMenuOptions;
@ -840,37 +872,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
updateLibraryNavLinks(page);
});
(function () {
var html = "";
html += '<div class="flex align-items-center flex-grow headerTop">';
html += '<div class="headerLeft">';
html += '<button type="button" is="paper-icon-button-light" class="headerButton headerButtonLeft headerBackButton hide"><i class="md-icon">' + (browser.safari ? "chevron_left" : "arrow_back") + "</i></button>";
html += '<button type="button" is="paper-icon-button-light" class="headerButton headerHomeButton hide barsMenuButton headerButtonLeft"><i class="md-icon">home</i></button>';
html += '<button type="button" is="paper-icon-button-light" class="headerButton mainDrawerButton barsMenuButton headerButtonLeft hide"><i class="md-icon">menu</i></button>';
html += '<h3 class="pageTitle"></h3>';
html += "</div>";
html += '<div class="headerRight">';
html += '<span class="headerSelectedPlayer"></span>';
html += '<button is="paper-icon-button-light" class="headerCastButton castButton headerButton headerButtonRight hide"><i class="md-icon">cast</i></button>';
html += '<button type="button" is="paper-icon-button-light" class="headerButton headerButtonRight headerSearchButton hide"><i class="md-icon">search</i></button>';
html += '<button is="paper-icon-button-light" class="headerButton headerButtonRight headerUserButton hide"><i class="md-icon">person</i></button>';
html += "</div>";
html += "</div>";
html += '<div class="headerTabs sectionTabs hide">';
html += "</div>";
skinHeader.classList.add("skinHeader-withBackground");
skinHeader.classList.add("skinHeader-blurred");
skinHeader.innerHTML = html;
headerHomeButton = skinHeader.querySelector(".headerHomeButton");
headerUserButton = skinHeader.querySelector(".headerUserButton");
headerCastButton = skinHeader.querySelector(".headerCastButton");
headerSearchButton = skinHeader.querySelector(".headerSearchButton");
lazyLoadViewMenuBarImages();
bindMenuEvents();
})();
renderHeader();
events.on(connectionManager, "localusersignedin", function (e, user) {
currentDrawerType = null;

View file

@ -226,7 +226,8 @@ define([
autoFocus: false,
anonymous: true,
startup: true,
controller: "auth/login"
controller: "auth/login",
type: "login"
});
defineRoute({
path: "/metadataimages.html",
@ -312,7 +313,8 @@ define([
autoFocus: false,
anonymous: true,
startup: true,
controller: "auth/selectserver"
controller: "auth/selectserver",
type: "selectserver"
});
defineRoute({
path: "/serveractivity.html",

View file

@ -0,0 +1,135 @@
define(['appStorage', 'events'], function (appStorage, events) {
'use strict';
function getKey(name, userId) {
if (userId) {
name = userId + '-' + name;
}
return name;
}
function AppSettings() {
}
AppSettings.prototype.enableAutoLogin = function (val) {
if (val != null) {
this.set('enableAutoLogin', val.toString());
}
return this.get('enableAutoLogin') !== 'false';
};
AppSettings.prototype.enableAutomaticBitrateDetection = function (isInNetwork, mediaType, val) {
var key = 'enableautobitratebitrate-' + mediaType + '-' + isInNetwork;
if (val != null) {
if (isInNetwork && mediaType === 'Audio') {
val = true;
}
this.set(key, val.toString());
}
if (isInNetwork && mediaType === 'Audio') {
return true;
} else {
return this.get(key) !== 'false';
}
};
AppSettings.prototype.maxStreamingBitrate = function (isInNetwork, mediaType, val) {
var key = 'maxbitrate-' + mediaType + '-' + isInNetwork;
if (val != null) {
if (isInNetwork && mediaType === 'Audio') {
// nothing to do, this is always a max value
} else {
this.set(key, val);
}
}
if (isInNetwork && mediaType === 'Audio') {
// return a huge number so that it always direct plays
return 150000000;
} else {
return parseInt(this.get(key) || '0') || 1500000;
}
};
AppSettings.prototype.maxStaticMusicBitrate = function (val) {
if (val !== undefined) {
this.set('maxStaticMusicBitrate', val);
}
var defaultValue = 320000;
return parseInt(this.get('maxStaticMusicBitrate') || defaultValue.toString()) || defaultValue;
};
AppSettings.prototype.maxChromecastBitrate = function (val) {
if (val != null) {
this.set('chromecastBitrate1', val);
}
val = this.get('chromecastBitrate1');
return val ? parseInt(val) : null;
};
AppSettings.prototype.syncOnlyOnWifi = function (val) {
if (val != null) {
this.set('syncOnlyOnWifi', val.toString());
}
return this.get('syncOnlyOnWifi') !== 'false';
};
AppSettings.prototype.syncPath = function (val) {
if (val != null) {
this.set('syncPath', val);
}
return this.get('syncPath');
};
AppSettings.prototype.cameraUploadServers = function (val) {
if (val != null) {
this.set('cameraUploadServers', val.join(','));
}
val = this.get('cameraUploadServers');
if (val) {
return val.split(',');
}
return [];
};
AppSettings.prototype.runAtStartup = function (val) {
if (val != null) {
this.set('runatstartup', val.toString());
}
return this.get('runatstartup') === 'true';
};
AppSettings.prototype.set = function (name, value, userId) {
var currentValue = this.get(name, userId);
appStorage.setItem(getKey(name, userId), value);
if (currentValue !== value) {
events.trigger(this, 'change', [name]);
}
};
AppSettings.prototype.get = function (name, userId) {
return appStorage.getItem(getKey(name, userId));
};
AppSettings.prototype.enableSystemExternalPlayers = function (val) {
if (val != null) {
this.set('enableSystemExternalPlayers', val.toString());
}
return this.get('enableSystemExternalPlayers') === 'true';
};
return new AppSettings();
});

View file

@ -0,0 +1,246 @@
define(['appSettings', 'events'], function (appSettings, events) {
'use strict';
function onSaveTimeout() {
var self = this;
self.saveTimeout = null;
self.currentApiClient.updateDisplayPreferences('usersettings', self.displayPrefs, self.currentUserId, 'emby');
}
function saveServerPreferences(instance) {
if (instance.saveTimeout) {
clearTimeout(instance.saveTimeout);
}
instance.saveTimeout = setTimeout(onSaveTimeout.bind(instance), 50);
}
function UserSettings() {
}
UserSettings.prototype.setUserInfo = function (userId, apiClient) {
if (this.saveTimeout) {
clearTimeout(this.saveTimeout);
}
this.currentUserId = userId;
this.currentApiClient = apiClient;
if (!userId) {
this.displayPrefs = null;
return Promise.resolve();
}
var self = this;
return apiClient.getDisplayPreferences('usersettings', userId, 'emby').then(function (result) {
result.CustomPrefs = result.CustomPrefs || {};
self.displayPrefs = result;
});
};
UserSettings.prototype.getData = function () {
return this.displayPrefs;
};
UserSettings.prototype.importFrom = function (instance) {
this.displayPrefs = instance.getData();
};
UserSettings.prototype.set = function (name, value, enableOnServer) {
var userId = this.currentUserId;
var currentValue = this.get(name, enableOnServer);
var result = appSettings.set(name, value, userId);
if (enableOnServer !== false && this.displayPrefs) {
this.displayPrefs.CustomPrefs[name] = value == null ? value : value.toString();
saveServerPreferences(this);
}
if (currentValue !== value) {
events.trigger(this, 'change', [name]);
}
return result;
};
UserSettings.prototype.get = function (name, enableOnServer) {
var userId = this.currentUserId;
if (enableOnServer !== false && this.displayPrefs) {
return this.displayPrefs.CustomPrefs[name];
}
return appSettings.get(name, userId);
};
UserSettings.prototype.serverConfig = function (config) {
var apiClient = this.currentApiClient;
if (config) {
return apiClient.updateUserConfiguration(this.currentUserId, config);
}
return apiClient.getUser(this.currentUserId).then(function (user) {
return user.Configuration;
});
};
UserSettings.prototype.enableCinemaMode = function (val) {
if (val != null) {
return this.set('enableCinemaMode', val.toString(), false);
}
val = this.get('enableCinemaMode', false);
return val !== 'false';
};
UserSettings.prototype.enableNextVideoInfoOverlay = function (val) {
if (val != null) {
return this.set('enableNextVideoInfoOverlay', val.toString());
}
val = this.get('enableNextVideoInfoOverlay', false);
return val !== 'false';
};
UserSettings.prototype.enableThemeSongs = function (val) {
if (val != null) {
return this.set('enableThemeSongs', val.toString(), false);
}
val = this.get('enableThemeSongs', false);
return val !== 'false';
};
UserSettings.prototype.enableThemeVideos = function (val) {
if (val != null) {
return this.set('enableThemeVideos', val.toString(), false);
}
val = this.get('enableThemeVideos', false);
return val !== 'false';
};
UserSettings.prototype.enableBackdrops = function (val) {
if (val != null) {
return this.set('enableBackdrops', val.toString(), false);
}
val = this.get('enableBackdrops', false);
return val !== 'false';
};
UserSettings.prototype.language = function (val) {
if (val != null) {
return this.set('language', val.toString(), false);
}
return this.get('language', false);
};
UserSettings.prototype.dateTimeLocale = function (val) {
if (val != null) {
return this.set('datetimelocale', val.toString(), false);
}
return this.get('datetimelocale', false);
};
UserSettings.prototype.skipBackLength = function (val) {
if (val != null) {
return this.set('skipBackLength', val.toString());
}
return parseInt(this.get('skipBackLength') || '10000');
};
UserSettings.prototype.skipForwardLength = function (val) {
if (val != null) {
return this.set('skipForwardLength', val.toString());
}
return parseInt(this.get('skipForwardLength') || '30000');
};
UserSettings.prototype.dashboardTheme = function (val) {
if (val != null) {
return this.set('dashboardTheme', val);
}
return this.get('dashboardTheme');
};
UserSettings.prototype.skin = function (val) {
if (val != null) {
return this.set('skin', val, false);
}
return this.get('skin', false);
};
UserSettings.prototype.theme = function (val) {
if (val != null) {
return this.set('appTheme', val, false);
}
return this.get('appTheme', false);
};
UserSettings.prototype.screensaver = function (val) {
if (val != null) {
return this.set('screensaver', val, false);
}
return this.get('screensaver', false);
};
UserSettings.prototype.soundEffects = function (val) {
if (val != null) {
return this.set('soundeffects', val, false);
}
return this.get('soundeffects', false);
};
UserSettings.prototype.loadQuerySettings = function (key, query) {
var values = this.get(key);
if (values) {
values = JSON.parse(values);
return Object.assign(query, values);
}
return query;
};
UserSettings.prototype.saveQuerySettings = function (key, query) {
var values = {};
if (query.SortBy) {
values.SortBy = query.SortBy;
}
if (query.SortOrder) {
values.SortOrder = query.SortOrder;
}
return this.set(key, JSON.stringify(values));
};
UserSettings.prototype.getSubtitleAppearanceSettings = function (key) {
key = key || 'localplayersubtitleappearance3';
return JSON.parse(this.get(key, false) || '{}');
};
UserSettings.prototype.setSubtitleAppearanceSettings = function (value, key) {
key = key || 'localplayersubtitleappearance3';
return this.set(key, JSON.stringify(value), false);
};
UserSettings.prototype.setFilter = function (key, value) {
return this.set(key, value, true);
};
UserSettings.prototype.getFilter = function (key) {
return this.get(key, true);
};
return new UserSettings();
});

View file

@ -315,6 +315,14 @@ var AppInfo = {};
return "components";
}
function getElementsPath() {
return "elements"
}
function getScriptsPath() {
return "scripts"
}
function getPlaybackManager(playbackManager) {
window.addEventListener("beforeunload", function () {
try {
@ -650,8 +658,12 @@ var AppInfo = {};
(function () {
var urlArgs = "v=" + (window.dashboardVersion || new Date().getDate());
var bowerPath = getBowerPath();
var componentsPath = getComponentsPath();
var elementsPath = getElementsPath();
var scriptsPath = getScriptsPath();
var paths = {
browserdeviceprofile: "scripts/browserdeviceprofile",
browser: "scripts/browser",
@ -672,7 +684,6 @@ var AppInfo = {};
itemHelper: componentsPath + "/itemhelper",
itemShortcuts: componentsPath + "/shortcuts",
playQueueManager: componentsPath + "/playback/playqueuemanager",
autoPlayDetect: componentsPath + "/playback/autoplaydetect",
nowPlayingHelper: componentsPath + "/playback/nowplayinghelper",
pluginManager: componentsPath + "/pluginManager",
packageManager: componentsPath + "/packagemanager",
@ -703,7 +714,8 @@ var AppInfo = {};
"swiper",
"sortable",
"libjass",
"webcomponents"
"webcomponents",
"material-icons"
]
},
urlArgs: urlArgs,
@ -721,7 +733,6 @@ var AppInfo = {};
// define styles
// TODO determine which of these files can be moved to the components themselves
define("material-icons", ["css!assets/css/material-icons/style"], returnFirstDependency);
define("systemFontsCss", ["css!assets/css/fonts"], returnFirstDependency);
define("systemFontsSizedCss", ["css!assets/css/fonts.sized"], returnFirstDependency);
define("scrollStyles", ["css!assets/css/scrollstyles"], returnFirstDependency);
@ -765,7 +776,6 @@ var AppInfo = {};
return queryString;
});
var elementsPath = "elements"
define("emby-button", [elementsPath + "/emby-button/emby-button"], returnFirstDependency);
define("paper-icon-button-light", [elementsPath + "/emby-button/paper-icon-button-light"], returnFirstDependency);
define("emby-checkbox", [elementsPath + "/emby-checkbox/emby-checkbox"], returnFirstDependency);
@ -778,6 +788,9 @@ var AppInfo = {};
define("emby-textarea", [elementsPath + "/emby-textarea/emby-textarea"], returnFirstDependency);
define("emby-toggle", [elementsPath + "/emby-toggle/emby-toggle"], returnFirstDependency);
define("appSettings", [scriptsPath + "/settings/appSettings"], returnFirstDependency);
define("userSettings", [scriptsPath + "/settings/userSettings"], returnFirstDependency);
define("chromecastHelper", [componentsPath + "/chromecast/chromecasthelpers"], returnFirstDependency);
define("mediaSession", [componentsPath + "/playback/mediasession"], returnFirstDependency);
define("actionsheet", [componentsPath + "/actionsheet/actionsheet"], returnFirstDependency);
@ -865,9 +878,6 @@ var AppInfo = {};
define("toast", [componentsPath + "/toast/toast"], returnFirstDependency);
define("scrollHelper", [componentsPath + "/scrollhelper"], returnFirstDependency);
define("touchHelper", [componentsPath + "/touchhelper"], returnFirstDependency);
define("appSettings", [componentsPath + "/appSettings"], returnFirstDependency);
define("userSettings", [componentsPath + "/usersettings/usersettings"], returnFirstDependency);
define("userSettingsBuilder", [componentsPath + "/usersettings/usersettingsbuilder", "layoutManager", "browser"], returnFirstDependency);
define("imageUploader", [componentsPath + "/imageuploader/imageuploader"], returnFirstDependency);
define("htmlMediaHelper", [componentsPath + "/htmlMediaHelper"], returnFirstDependency);
define("viewContainer", [componentsPath + "/viewContainer"], returnFirstDependency);