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

unify backdrops

This commit is contained in:
Luke Pulverenti 2016-03-12 02:28:13 -05:00
parent ba749de15d
commit aed49d567d
14 changed files with 420 additions and 296 deletions

View file

@ -16,12 +16,12 @@
}, },
"devDependencies": {}, "devDependencies": {},
"ignore": [], "ignore": [],
"version": "1.1.37", "version": "1.1.42",
"_release": "1.1.37", "_release": "1.1.42",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "1.1.37", "tag": "1.1.42",
"commit": "7235838b8cff53a9bb2aea7d6c6418160728cd3a" "commit": "324128b974bbf7d7e011a2add0beae2c0611f9aa"
}, },
"_source": "git://github.com/MediaBrowser/emby-webcomponents.git", "_source": "git://github.com/MediaBrowser/emby-webcomponents.git",
"_target": "~1.1.5", "_target": "~1.1.5",

View file

@ -0,0 +1,236 @@
define(['browser', 'css!./style'], function (browser) {
function enableAnimation() {
if (browser.mobile) {
return false;
}
return true;
}
function backdrop() {
var self = this;
var isDestroyed;
self.load = function (url, parent, existingBackdropImage) {
var img = new Image();
img.onload = function () {
if (isDestroyed) {
return;
}
var backdropImage = document.createElement('div');
backdropImage.classList.add('backdropImage');
backdropImage.classList.add('displayingBackdropImage');
backdropImage.style.backgroundImage = "url('" + url + "')";
backdropImage.setAttribute('data-url', url);
parent.appendChild(backdropImage);
if (!enableAnimation()) {
if (existingBackdropImage && existingBackdropImage.parentNode) {
existingBackdropImage.parentNode.removeChild(existingBackdropImage);
}
internalBackdrop(true);
return;
}
var animation = fadeIn(backdropImage, 1);
currentAnimation = animation;
animation.onfinish = function () {
if (animation == currentAnimation) {
currentAnimation = null;
}
if (existingBackdropImage && existingBackdropImage.parentNode) {
existingBackdropImage.parentNode.removeChild(existingBackdropImage);
}
};
internalBackdrop(true);
};
img.src = url;
};
var currentAnimation;
function fadeIn(elem, iterations) {
var keyframes = [
{ opacity: '0', offset: 0 },
{ opacity: '1', offset: 1 }];
var timing = { duration: 800, iterations: iterations, easing: 'ease-in' };
return elem.animate(keyframes, timing);
}
function cancelAnimation() {
var animation = currentAnimation;
if (animation) {
console.log('Cancelling backdrop animation');
animation.cancel();
currentAnimation = null;
}
}
self.destroy = function () {
isDestroyed = true;
cancelAnimation();
};
}
var backdropContainer;
function getBackdropContainer() {
if (!backdropContainer) {
backdropContainer = document.querySelector('.backdropContainer');
}
if (!backdropContainer) {
backdropContainer = document.createElement('div');
backdropContainer.classList.add('backdropContainer');
document.body.insertBefore(backdropContainer, document.body.firstChild);
}
return backdropContainer;
}
function clearBackdrop(clearAll) {
if (currentLoadingBackdrop) {
currentLoadingBackdrop.destroy();
currentLoadingBackdrop = null;
}
var elem = getBackdropContainer();
elem.innerHTML = '';
if (clearAll) {
hasExternalBackdrop = false;
}
internalBackdrop(false);
}
var skinContainer;
function setSkinContainerBackgroundEnabled() {
if (!skinContainer) {
skinContainer = document.querySelector('.skinContainer');
}
if (hasInternalBackdrop || hasExternalBackdrop) {
skinContainer.classList.add('withBackdrop');
} else {
skinContainer.classList.remove('withBackdrop');
}
}
var hasInternalBackdrop;
function internalBackdrop(enabled) {
hasInternalBackdrop = enabled;
setSkinContainerBackgroundEnabled();
}
var hasExternalBackdrop;
function externalBackdrop(enabled) {
hasExternalBackdrop = enabled;
setSkinContainerBackgroundEnabled();
}
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
var currentLoadingBackdrop;
function setBackdropImage(url) {
if (currentLoadingBackdrop) {
currentLoadingBackdrop.destroy();
currentLoadingBackdrop = null;
}
var elem = getBackdropContainer();
var existingBackdropImage = elem.querySelector('.displayingBackdropImage');
if (existingBackdropImage && existingBackdropImage.getAttribute('data-url') == url) {
if (existingBackdropImage.getAttribute('data-url') == url) {
return;
}
existingBackdropImage.classList.remove('displayingBackdropImage');
}
var instance = new backdrop();
instance.load(url, elem, existingBackdropImage);
currentLoadingBackdrop = instance;
}
function setBackdrops(items) {
var images = items.map(function (i) {
if (i.BackdropImageTags && i.BackdropImageTags.length > 0) {
return {
id: i.Id,
tag: i.BackdropImageTags[0],
serverId: i.ServerId
};
}
if (i.ParentBackdropItemId && i.ParentBackdropImageTags && i.ParentBackdropImageTags.length) {
return {
id: i.ParentBackdropItemId,
tag: i.ParentBackdropImageTags[0],
serverId: i.ServerId
};
}
return null;
}).filter(function (i) {
return i != null;
});
if (images.length) {
var index = getRandom(0, images.length - 1);
var item = images[index];
require(['connectionManager'], function (connectionManager) {
var apiClient = connectionManager.getApiClient(item.serverId);
var imgUrl = apiClient.getScaledImageUrl(item.id, {
type: "Backdrop",
tag: item.tag,
//maxWidth: window.innerWidth,
quality: 100
});
setBackdrop(imgUrl);
});
} else {
clearBackdrop();
}
}
function setBackdrop(url) {
if (url) {
setBackdropImage(url);
} else {
clearBackdrop();
}
}
return {
setBackdrops: setBackdrops,
setBackdrop: setBackdrop,
clear: clearBackdrop,
externalBackdrop: externalBackdrop
};
});

View file

@ -0,0 +1,11 @@
.backdropImage {
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
background-attachment: fixed;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}

View file

@ -120,36 +120,37 @@ define([], function () {
return elem; return elem;
} }
function getOffset(elem, doc) { function getWindowData(win, documentElement) {
var box = { top: 0, left: 0 }; return {
pageYOffset: win.pageYOffset,
if (!doc) { pageXOffset: win.pageXOffset,
return box; clientTop: documentElement.clientTop,
clientLeft: documentElement.clientLeft
};
} }
var docElem = doc.documentElement; function getOffset(elem, windowData) {
var box = { top: 0, left: 0 };
// Support: BlackBerry 5, iOS 3 (original iPhone) // Support: BlackBerry 5, iOS 3 (original iPhone)
// If we don't have gBCR, just use 0,0 rather than error // If we don't have gBCR, just use 0,0 rather than error
if (elem.getBoundingClientRect) { if (elem.getBoundingClientRect) {
box = elem.getBoundingClientRect(); box = elem.getBoundingClientRect();
} }
var win = doc.defaultView;
return { return {
top: box.top + win.pageYOffset - docElem.clientTop, top: box.top + windowData.pageYOffset - windowData.clientTop,
left: box.left + win.pageXOffset - docElem.clientLeft left: box.left + windowData.pageXOffset - windowData.clientLeft
}; };
} }
function getViewportBoundingClientRect(elem) { function getViewportBoundingClientRect(elem, windowData) {
var doc = elem.ownerDocument; var offset = getOffset(elem, windowData);
var offset = getOffset(elem, doc);
var win = doc.defaultView;
var posY = offset.top - win.pageXOffset; var posY = offset.top - windowData.pageXOffset;
var posX = offset.left - win.pageYOffset; var posX = offset.left - windowData.pageYOffset;
var width = elem.offsetWidth; var width = elem.offsetWidth;
var height = elem.offsetHeight; var height = elem.offsetHeight;
@ -162,11 +163,6 @@ define([], function () {
right: posX + width, right: posX + width,
bottom: posY + height bottom: posY + height
}; };
var scrollLeft = (((t = document.documentElement) || (t = document.body.parentNode))
&& typeof t.scrollLeft == 'number' ? t : document.body).scrollLeft;
var scrollTop = (((t = document.documentElement) || (t = document.body.parentNode))
&& typeof t.scrollTop == 'number' ? t : document.body).scrollTop;
} }
function nav(activeElement, direction) { function nav(activeElement, direction) {
@ -186,7 +182,9 @@ define([], function () {
var focusableContainer = parentWithClass(activeElement, 'focusable'); var focusableContainer = parentWithClass(activeElement, 'focusable');
var rect = getViewportBoundingClientRect(activeElement); var doc = activeElement.ownerDocument;
var windowData = getWindowData(doc.defaultView, doc.documentElement);
var rect = getViewportBoundingClientRect(activeElement, windowData);
var focusableElements = []; var focusableElements = [];
var focusable = container.querySelectorAll(focusableQuery); var focusable = container.querySelectorAll(focusableQuery);
@ -205,7 +203,7 @@ define([], function () {
continue; continue;
} }
var elementRect = getViewportBoundingClientRect(curr); var elementRect = getViewportBoundingClientRect(curr, windowData);
switch (direction) { switch (direction) {

View file

@ -45,7 +45,7 @@
"tag": "v1.0.11", "tag": "v1.0.11",
"commit": "e3c1ab0c72905b58fb4d9adc2921ea73b5c085a5" "commit": "e3c1ab0c72905b58fb4d9adc2921ea73b5c085a5"
}, },
"_source": "git://github.com/PolymerElements/paper-behaviors.git", "_source": "git://github.com/polymerelements/paper-behaviors.git",
"_target": "^1.0.0", "_target": "^1.0.0",
"_originalSource": "PolymerElements/paper-behaviors" "_originalSource": "polymerelements/paper-behaviors"
} }

View file

@ -32,14 +32,14 @@
"iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0" "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
}, },
"ignore": [], "ignore": [],
"homepage": "https://github.com/PolymerElements/paper-ripple", "homepage": "https://github.com/polymerelements/paper-ripple",
"_release": "1.0.5", "_release": "1.0.5",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v1.0.5", "tag": "v1.0.5",
"commit": "d72e7a9a8ab518b901ed18dde492df3b87a93be5" "commit": "d72e7a9a8ab518b901ed18dde492df3b87a93be5"
}, },
"_source": "git://github.com/PolymerElements/paper-ripple.git", "_source": "git://github.com/polymerelements/paper-ripple.git",
"_target": "^1.0.0", "_target": "^1.0.0",
"_originalSource": "PolymerElements/paper-ripple" "_originalSource": "polymerelements/paper-ripple"
} }

View file

@ -196,7 +196,9 @@
// But for now, if you change songs but keep the same artist, the backdrop will flicker because in-between songs it clears out the image // But for now, if you change songs but keep the same artist, the backdrop will flicker because in-between songs it clears out the image
if (!browser.mobile) { if (!browser.mobile) {
// Exclude from mobile because it just doesn't perform well // Exclude from mobile because it just doesn't perform well
Backdrops.setBackdropUrl(context, backdropUrl); require(['backdrop'], function (backdrop) {
backdrop.setBackdrop(backdropUrl);
});
} }
ApiClient.getItem(Dashboard.getCurrentUserId(), item.Id).then(function (fullItem) { ApiClient.getItem(Dashboard.getCurrentUserId(), item.Id).then(function (fullItem) {

View file

@ -30,8 +30,7 @@
background-color: transparent !important; background-color: transparent !important;
} }
.backdropContainer .pageBackground { .backdropContainer {
background-color: rgba(20, 20,20, .92);
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
@ -40,15 +39,23 @@
z-index: -1; z-index: -1;
} }
.pageWithAbsoluteTabs neon-animatable { .pageBackground {
z-index: 2; display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
} }
.backdropContainer { .withBackdrop .pageBackground {
background-repeat: no-repeat; background-color: rgba(20, 20,20, .92);
background-position: center center; display: block;
background-size: cover; }
background-attachment: fixed;
.pageWithAbsoluteTabs neon-animatable {
z-index: 2;
} }
.libraryPage .header { .libraryPage .header {
@ -389,7 +396,7 @@ span.itemCommunityRating:not(:empty) + .userDataIcons {
margin-top: 0 !important; margin-top: 0 !important;
} }
.backdropPage .noBackdrop { .withBackdrop .noBackdrop {
background-color: transparent; background-color: transparent;
} }

View file

@ -4,7 +4,7 @@
<title></title> <title></title>
</head> </head>
<body> <body>
<div id="itemDetailPage" data-role="page" class="page libraryPage itemDetailPage noSecondaryNavPage" data-theme="b" data-require="scripts/itemdetailpage,tileitemcss,scripts/livetvcomponents,paper-fab,paper-item-body,paper-icon-item"> <div id="itemDetailPage" data-role="page" class="page libraryPage itemDetailPage noSecondaryNavPage selfBackdropPage" data-theme="b" data-require="scripts/itemdetailpage,tileitemcss,scripts/livetvcomponents,paper-fab,paper-item-body,paper-icon-item">
<div id="tvShowsTabs" class="itemTabs" style="display: none;"> <div id="tvShowsTabs" class="itemTabs" style="display: none;">
<div class="libraryViewNav scopedLibraryViewNav"> <div class="libraryViewNav scopedLibraryViewNav">

View file

@ -4,7 +4,7 @@
<title>Emby</title> <title>Emby</title>
</head> </head>
<body> <body>
<div id="nowPlayingPage" data-role="page" class="page libraryPage nowPlayingPage noSecondaryNavPage" data-contextname="${TitleRemoteControl}" data-theme="b" data-require="scripts/nowplayingpage,paper-tabs,paper-icon-button,paper-slider"> <div id="nowPlayingPage" data-role="page" class="page libraryPage nowPlayingPage noSecondaryNavPage selfBackdropPage" data-contextname="${TitleRemoteControl}" data-theme="b" data-require="scripts/nowplayingpage,paper-tabs,paper-icon-button,paper-slider">
<div class="remoteControlContent"> <div class="remoteControlContent">

View file

@ -0,0 +1,115 @@
define(['backdrop', 'appStorage'], function (backdrop, appStorage) {
function isEnabledByDefault() {
if (AppInfo.hasLowImageBandwidth) {
return false;
}
return false;
}
function enabled() {
var userId = Dashboard.getCurrentUserId();
var val = appStorage.getItem('enableBackdrops-' + userId);
// For bandwidth
return val == '1' || (val != '0' && isEnabledByDefault());
}
var cache = {};
function getBackdropItemIds(apiClient, userId, types, parentId) {
var key = 'backdrops2_' + userId + (types || '') + (parentId || '');
var data = cache[key];
if (data) {
console.log('Found backdrop id list in cache. Key: ' + key)
data = JSON.parse(data);
return Promise.resolve(data);
} else {
var options = {
SortBy: "IsFavoriteOrLiked,Random",
Limit: 20,
Recursive: true,
IncludeItemTypes: types,
ImageTypes: "Backdrop",
//Ids: "8114409aa00a2722456c08e298f90bed",
ParentId: parentId
};
return apiClient.getItems(Dashboard.getCurrentUserId(), options).then(function (result) {
var images = result.Items.map(function (i) {
return {
Id: i.Id,
tag: i.BackdropImageTags[0],
ServerId: i.ServerId
};
});
cache[key] = JSON.stringify(images);
return images;
});
}
}
function showBackdrop(type, parentId) {
var apiClient = window.ApiClient;
if (!apiClient) {
return;
}
getBackdropItemIds(apiClient, Dashboard.getCurrentUserId(), type, parentId).then(function (images) {
if (images.length) {
backdrop.setBackdrops(images.map(function (i) {
i.BackdropImageTags = [i.tag];
return i;
}));
} else {
backdrop.clear();
}
});
}
pageClassOn('pagebeforeshow', "page", function () {
var page = this;
// These pages self-manage their backdrops
if (page.classList.contains('selfBackdropPage')) {
return;
}
if (page.classList.contains('backdropPage')) {
if (enabled()) {
var type = page.getAttribute('data-backdroptype');
var parentId = page.classList.contains('globalBackdropPage') ? '' : LibraryMenu.getTopParentId();
showBackdrop(type, parentId);
} else {
page.classList.remove('backdropPage');
backdrop.clear();
}
} else {
backdrop.clear();
}
});
});

View file

@ -1,249 +0,0 @@
define(['appStorage'], function (appStorage) {
var pageBackgroundCreated;
function getElement() {
//var elem = $('.backdropContainer');
//if (!elem.length) {
// elem = $('<div class="backdropContainer"></div>').prependTo(document.body);
//}
var elem = document.documentElement;
elem.classList.add('backdropContainer');
elem.classList.add('noFade');
if (!pageBackgroundCreated) {
pageBackgroundCreated = true;
var div = document.createElement('div');
div.classList.add('pageBackground');
document.body.insertBefore(div, document.body.firstChild);
}
return elem;
}
function clearBackdrop() {
var elem = document.documentElement;
elem.classList.remove('backdropContainer');
elem.removeAttribute('data-url');
elem.style.backgroundImage = '';
}
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
var cache = {};
function getBackdropItemIds(apiClient, userId, types, parentId) {
var key = 'backdrops2_' + userId + (types || '') + (parentId || '');
var deferred = $.Deferred();
var data = cache[key];
if (data) {
console.log('Found backdrop id list in cache. Key: ' + key)
data = JSON.parse(data);
deferred.resolveWith(null, [data]);
} else {
var options = {
SortBy: "IsFavoriteOrLiked,Random",
Limit: 20,
Recursive: true,
IncludeItemTypes: types,
ImageTypes: "Backdrop",
//Ids: "8114409aa00a2722456c08e298f90bed",
ParentId: parentId
};
apiClient.getItems(Dashboard.getCurrentUserId(), options).then(function (result) {
var images = result.Items.map(function (i) {
return {
id: i.Id,
tag: i.BackdropImageTags[0]
};
});
cache[key] = JSON.stringify(images);
deferred.resolveWith(null, [images]);
});
}
return deferred.promise();
}
function setBackdropImage(elem, url) {
if (url == elem.getAttribute('data-url')) {
return;
}
elem.setAttribute('data-url', url);
ImageLoader.lazyImage(elem, url);
}
function showBackdrop(type, parentId) {
var apiClient = window.ApiClient;
if (!apiClient) {
return;
}
getBackdropItemIds(apiClient, Dashboard.getCurrentUserId(), type, parentId).then(function (images) {
if (images.length) {
var index = getRandom(0, images.length - 1);
var item = images[index];
var screenWidth = $(window).width();
var imgUrl = apiClient.getScaledImageUrl(item.id, {
type: "Backdrop",
tag: item.tag,
maxWidth: screenWidth,
quality: 50
});
setBackdropImage(getElement(), imgUrl);
} else {
clearBackdrop();
}
});
}
function setDefault(page) {
var elem = getElement();
elem.style.backgroundImage = "url(css/images/splash.jpg)";
elem.setAttribute('data-url', 'css/images/splash.jpg');
page = $(page)[0];
page.classList.add('backdropPage');
page.classList.add('staticBackdropPage');
}
function isEnabledByDefault() {
if (AppInfo.hasLowImageBandwidth) {
return false;
}
return false;
}
function enabled() {
var userId = Dashboard.getCurrentUserId();
var val = appStorage.getItem('enableBackdrops-' + userId);
// For bandwidth
return val == '1' || (val != '0' && isEnabledByDefault());
}
function setBackdrops(page, items) {
var images = items.map(function (i) {
if (i.BackdropImageTags.length > 0) {
return {
id: i.Id,
tag: i.BackdropImageTags[0]
};
}
if (i.ParentBackdropItemId && i.ParentBackdropImageTags && i.ParentBackdropImageTags.length) {
return {
id: i.ParentBackdropItemId,
tag: i.ParentBackdropImageTags[0]
};
}
return null;
}).filter(function (i) {
return i != null;
});
if (images.length) {
page.classList.add('backdropPage');
var index = getRandom(0, images.length - 1);
var item = images[index];
var screenWidth = $(window).width();
var imgUrl = ApiClient.getScaledImageUrl(item.id, {
type: "Backdrop",
tag: item.tag,
maxWidth: screenWidth,
quality: 50
});
setBackdropImage(getElement(), imgUrl);
} else {
page.classList.remove('backdropPage');
}
}
function setBackdropUrl(page, url) {
if (url) {
page.classList.add('backdropPage');
setBackdropImage(getElement(), url);
} else {
page.classList.remove('backdropPage');
clearBackdrop();
}
}
pageClassOn('pagebeforeshow', "page", function () {
var page = this;
if (page.classList.contains('backdropPage')) {
if (enabled()) {
var type = page.getAttribute('data-backdroptype');
var parentId = page.classList.contains('globalBackdropPage') ? '' : LibraryMenu.getTopParentId();
showBackdrop(type, parentId);
} else {
page.classList.remove('backdropPage');
clearBackdrop();
}
} else {
clearBackdrop();
}
});
window.Backdrops = {
setBackdrops: setBackdrops,
setBackdropUrl: setBackdropUrl,
setDefault: setDefault,
clear: clearBackdrop
};
});

View file

@ -73,7 +73,9 @@
// For these types, make the backdrop a little smaller so that the items are more quickly accessible // For these types, make the backdrop a little smaller so that the items are more quickly accessible
if (item.Type == 'MusicArtist' || item.Type == "MusicAlbum" || item.Type == "Playlist" || item.Type == "BoxSet" || item.Type == "Audio") { if (item.Type == 'MusicArtist' || item.Type == "MusicAlbum" || item.Type == "Playlist" || item.Type == "BoxSet" || item.Type == "Audio") {
$('#itemBackdrop', page).addClass('noBackdrop').css('background-image', 'none'); $('#itemBackdrop', page).addClass('noBackdrop').css('background-image', 'none');
Backdrops.setBackdrops(page, [item]); require(['backdrop'], function (backdrop) {
backdrop.setBackdrops([item]);
});
} }
else { else {
//$('#itemBackdrop', page).addClass('noBackdrop').css('background-image', 'none'); //$('#itemBackdrop', page).addClass('noBackdrop').css('background-image', 'none');

View file

@ -1767,6 +1767,8 @@ var AppInfo = {};
define("actionsheet", [embyWebComponentsBowerPath + "/actionsheet/actionsheet"], returnFirstDependency); define("actionsheet", [embyWebComponentsBowerPath + "/actionsheet/actionsheet"], returnFirstDependency);
} }
define("backdrop", [embyWebComponentsBowerPath + "/backdrop/backdrop"], returnFirstDependency);
// hack for an android test before browserInfo is loaded // hack for an android test before browserInfo is loaded
if (Dashboard.isRunningInCordova() && window.MainActivity) { if (Dashboard.isRunningInCordova() && window.MainActivity) {
paths.appStorage = "cordova/android/appstorage"; paths.appStorage = "cordova/android/appstorage";
@ -2242,7 +2244,6 @@ var AppInfo = {};
deps.push('scripts/search'); deps.push('scripts/search');
deps.push('scripts/librarylist'); deps.push('scripts/librarylist');
deps.push('scripts/backdrops');
deps.push('scripts/librarymenu'); deps.push('scripts/librarymenu');
deps.push('scripts/librarybrowser'); deps.push('scripts/librarybrowser');
deps.push('jqm'); deps.push('jqm');
@ -2262,6 +2263,7 @@ var AppInfo = {};
postInitDependencies.push('scripts/remotecontrol'); postInitDependencies.push('scripts/remotecontrol');
postInitDependencies.push('css!css/notifications.css'); postInitDependencies.push('css!css/notifications.css');
postInitDependencies.push('css!css/chromecast.css'); postInitDependencies.push('css!css/chromecast.css');
postInitDependencies.push('scripts/autobackdrops');
if (Dashboard.isRunningInCordova()) { if (Dashboard.isRunningInCordova()) {