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

Refactor details page

This commit is contained in:
MrTimscampi 2020-05-10 13:36:26 +02:00
parent a8e45f30ab
commit d57eff1c9b
9 changed files with 128 additions and 107 deletions

View file

@ -577,14 +577,14 @@
padding-left: 32.45vw; padding-left: 32.45vw;
} }
.layout-desktop .detailSticky, .layout-desktop .detailRibbon,
.layout-tv .detailSticky { .layout-tv .detailRibbon {
margin-top: -7.2em; margin-top: -7.2em;
height: 7.18em; height: 7.18em;
} }
.layout-desktop .noBackdrop .detailSticky, .layout-desktop .noBackdrop .detailRibbon,
.layout-tv .noBackdrop .detailSticky { .layout-tv .noBackdrop .detailRibbon {
margin-top: 0; margin-top: 0;
} }

View file

@ -212,8 +212,15 @@ import 'css!./style';
} }
} }
export function setLazyImage(element, url) {
element.classList.add('lazy');
element.setAttribute('data-src', url);
lazyImage(element);
}
/* eslint-enable indent */ /* eslint-enable indent */
export default { export default {
serLazyImage: setLazyImage,
fillImages: fillImages, fillImages: fillImages,
fillImage: fillImage, fillImage: fillImage,
lazyImage: lazyImage, lazyImage: lazyImage,

View file

@ -336,7 +336,14 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
return html = html.join(' / '); return html = html.join(' / ');
} }
function renderName(item, container, isStatic, context) {
/**
* Rneders the item's name block
* @param {Object} item - Item used to render the name.
* @param {HTMLDivElement} container - Container to render the information into.
* @param {Object} context - Application context.
*/
function renderName(item, container, context) {
var parentRoute; var parentRoute;
var parentNameHtml = []; var parentNameHtml = [];
var parentNameLast = false; var parentNameLast = false;
@ -364,8 +371,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
if (item.SeriesName && 'Season' === item.Type) { if (item.SeriesName && 'Season' === item.Type) {
parentRoute = appRouter.getRouteUrl({ parentRoute = appRouter.getRouteUrl({
Id: item.SeriesId,
Name: item.SeriesName,
Type: 'Series', Type: 'Series',
IsFolder: true, IsFolder: true,
ServerId: item.ServerId ServerId: item.ServerId
@ -501,21 +506,25 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
} }
function reloadFromItem(instance, page, params, item, user) { function reloadFromItem(instance, page, params, item, user) {
var context = params.context; const apiClient = connectionManager.getApiClient(item.ServerId);
page.querySelector('.detailPagePrimaryContainer').classList.add('detailSticky');
renderName(item, page.querySelector('.nameContainer'), false, context); Emby.Page.setTitle('');
var apiClient = connectionManager.getApiClient(item.ServerId);
renderSeriesTimerEditor(page, item, apiClient, user); // Start rendering the artwork first
renderTimerEditor(page, item, apiClient, user);
renderImage(page, item, apiClient, user); renderImage(page, item, apiClient, user);
renderLogo(page, item, apiClient); renderLogo(page, item, apiClient);
Emby.Page.setTitle('');
setInitialCollapsibleState(page, item, apiClient, context, user);
renderDetails(page, item, apiClient, context);
renderTrackSelections(page, instance, item);
renderBackdrop(item); renderBackdrop(item);
renderDetailPageBackdrop(page, item, apiClient); renderDetailPageBackdrop(page, item, apiClient);
// Render the main information for the item
page.querySelector('.detailPagePrimaryContainer').classList.add('detailRibbon');
renderName(item, page.querySelector('.nameContainer'), params.context);
renderDetails(page, item, apiClient, params.context);
renderTrackSelections(page, instance, item);
renderSeriesTimerEditor(page, item, apiClient, user);
renderTimerEditor(page, item, apiClient, user);
setInitialCollapsibleState(page, item, apiClient, params.context, user);
var canPlay = reloadPlayButtons(page, item); var canPlay = reloadPlayButtons(page, item);
if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf('PlayTrailers')) { if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf('PlayTrailers')) {
@ -617,18 +626,17 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
} }
function renderLogo(page, item, apiClient) { function renderLogo(page, item, apiClient) {
var url = logoImageUrl(item, apiClient, {
maxWidth: 400
});
var detailLogo = page.querySelector('.detailLogo'); var detailLogo = page.querySelector('.detailLogo');
var url = logoImageUrl(item, apiClient, {
maxWidth: detailLogo.clientWidth
});
if (!layoutManager.mobile && !userSettings.enableBackdrops()) { if (!layoutManager.mobile && !userSettings.enableBackdrops()) {
detailLogo.classList.add('hide'); detailLogo.classList.add('hide');
} else if (url) { } else if (url) {
detailLogo.classList.remove('hide'); detailLogo.classList.remove('hide');
detailLogo.classList.add('lazy'); imageLoader.setLazyImage(detailLogo, url);
detailLogo.setAttribute('data-src', url);
imageLoader.lazyImage(detailLogo);
} else { } else {
detailLogo.classList.add('hide'); detailLogo.classList.add('hide');
} }
@ -654,31 +662,32 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
} }
} }
function renderLinks(linksElem, item) { function renderLinks(page, item) {
var html = []; var externalLinksElem = page.querySelector('.itemExternalLinks');
var links = []; var links = [];
if (!layoutManager.tv && item.HomePageUrl) { if (!layoutManager.tv && item.HomePageUrl) {
links.push('<a style="color:inherit;" is="emby-linkbutton" class="button-link" href="' + item.HomePageUrl + '" target="_blank">' + globalize.translate('ButtonWebsite') + '</a>'); links.push(`<a is="emby-linkbutton" class="button-link" href="${item.HomePageUrl}" target="_blank">${globalize.translate('ButtonWebsite')}</a>`);
} }
if (item.ExternalUrls) { if (item.ExternalUrls) {
for (var i = 0, length = item.ExternalUrls.length; i < length; i++) { for (let url of item.ExternalUrls) {
var url = item.ExternalUrls[i]; links.push(`<a is="emby-linkbutton" class="button-link" href="${url.Url}" target="_blank">${url.Name}</a>`);
links.push('<a style="color:inherit;" is="emby-linkbutton" class="button-link" href="' + url.Url + '" target="_blank">' + url.Name + '</a>');
} }
} }
var html = [];
if (links.length) { if (links.length) {
html.push(links.join(', ')); html.push(links.join(', '));
} }
linksElem.innerHTML = html.join(', '); externalLinksElem.innerHTML = html.join(', ');
if (html.length) { if (html.length) {
linksElem.classList.remove('hide'); externalLinksElem.classList.remove('hide');
} else { } else {
linksElem.classList.add('hide'); externalLinksElem.classList.add('hide');
} }
} }
@ -828,37 +837,39 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
} }
} }
function renderOverview(elems, item) { function renderOverview(page, item) {
for (var i = 0, length = elems.length; i < length; i++) { var overviewElemnts = page.querySelectorAll('.overview');
var elem = elems[i];
for (let overviewElemnt of overviewElemnts) {
var overview = item.Overview || ''; var overview = item.Overview || '';
if (overview) { if (overview) {
elem.innerHTML = overview; overviewElemnt.innerHTML = overview;
elem.classList.remove('hide'); overviewElemnt.classList.remove('hide');
elem.classList.add('detail-clamp-text'); overviewElemnt.classList.add('detail-clamp-text');
// Grab the sibling element to control the expand state // Grab the sibling element to control the expand state
var expandButton = elem.parentElement.querySelector('.overview-expand'); var expandButton = overviewElemnt.parentElement.querySelector('.overview-expand');
// Detect if we have overflow of text. Based on this StackOverflow answer // Detect if we have overflow of text. Based on this StackOverflow answer
// https://stackoverflow.com/a/35157976 // https://stackoverflow.com/a/35157976
if (Math.abs(elem.scrollHeight - elem.offsetHeight) > 2) { if (Math.abs(overviewElemnt.scrollHeight - overviewElemnt.offsetHeight) > 2) {
expandButton.classList.remove('hide'); expandButton.classList.remove('hide');
} else { } else {
expandButton.classList.add('hide'); expandButton.classList.add('hide');
} }
expandButton.addEventListener('click', toggleLineClamp.bind(null, elem)); expandButton.addEventListener('click', toggleLineClamp.bind(null, overviewElemnt));
var anchors = elem.querySelectorAll('a'); var anchors = overviewElemnt.querySelectorAll('a');
for (var j = 0, length2 = anchors.length; j < length2; j++) { var anchors = overviewElemnt.querySelectorAll('a');
anchors[j].setAttribute('target', '_blank'); for (let anchor of anchors) {
anchor.setAttribute('target', '_blank');
} }
} else { } else {
elem.innerHTML = ''; overviewElemnt.innerHTML = '';
elem.classList.add('hide'); overviewElemnt.classList.add('hide');
} }
} }
} }
@ -902,18 +913,19 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
} }
function renderDirector(page, item, context) { function renderDirector(page, item, context) {
var directors = (item.People || []).filter(function (p) { var directors = (item.People || []).filter(function (person) {
return 'Director' === p.Type; return person.Type === 'Director';
}); });
var html = directors.map(function (p) {
var html = directors.map(function (person) {
return '<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + appRouter.getRouteUrl({ return '<a style="color:inherit;" class="button-link" is="emby-linkbutton" href="' + appRouter.getRouteUrl({
Name: p.Name, Name: person.Name,
Type: 'Person', Type: 'Person',
ServerId: item.ServerId, ServerId: item.ServerId,
Id: p.Id Id: person.Id
}, { }, {
context: context context: context
}) + '">' + p.Name + '</a>'; }) + '">' + person.Name + '</a>';
}).join(', '); }).join(', ');
var directorsLabel = page.querySelector('.directorsLabel'); var directorsLabel = page.querySelector('.directorsLabel');
@ -929,13 +941,39 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
} }
} }
function renderDetails(page, item, apiClient, context, isStatic) { function renderMiscInfo(page, item) {
renderSimilarItems(page, item, context); const primaryItemMiscInfo = page.querySelectorAll('.itemMiscInfo-primary');
renderMoreFromSeason(page, item, apiClient);
renderMoreFromArtist(page, item, apiClient); for (let miscInfo of primaryItemMiscInfo) {
renderDirector(page, item, context); mediaInfo.fillPrimaryMediaInfo(miscInfo, item, {
renderGenres(page, item, context); interactive: true,
renderChannelGuide(page, apiClient, item); episodeTitle: false,
subtitles: false
});
if (miscInfo.innerHTML && 'SeriesTimer' !== item.Type) {
miscInfo.classList.remove('hide');
} else {
miscInfo.classList.add('hide');
}
}
const secondaryItemMiscInfo = page.querySelectorAll('.itemMiscInfo-secondary');
for (let miscInfo of secondaryItemMiscInfo) {
mediaInfo.fillSecondaryMediaInfo(miscInfo, item, {
interactive: true
});
if (miscInfo.innerHTML && 'SeriesTimer' !== item.Type) {
miscInfo.classList.remove('hide');
} else {
miscInfo.classList.add('hide');
}
}
}
function renderTagline(page, item) {
var taglineElement = page.querySelector('.tagline'); var taglineElement = page.querySelector('.tagline');
if (item.Taglines && item.Taglines.length) { if (item.Taglines && item.Taglines.length) {
@ -944,45 +982,20 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
} else { } else {
taglineElement.classList.add('hide'); taglineElement.classList.add('hide');
} }
}
var overview = page.querySelector('.overview'); function renderDetails(page, item, apiClient, context, isStatic) {
var externalLinksElem = page.querySelector('.itemExternalLinks'); renderSimilarItems(page, item, context);
renderMoreFromSeason(page, item, apiClient);
renderOverview([overview], item); renderMoreFromArtist(page, item, apiClient);
var i; renderDirector(page, item, context);
var itemMiscInfo; renderGenres(page, item, context);
itemMiscInfo = page.querySelectorAll('.itemMiscInfo-primary'); renderChannelGuide(page, apiClient, item);
renderTagline(page, item);
for (i = 0; i < itemMiscInfo.length; i++) { renderOverview(page, item);
mediaInfo.fillPrimaryMediaInfo(itemMiscInfo[i], item, { renderMiscInfo(page, item);
interactive: true,
episodeTitle: false,
subtitles: false
});
if (itemMiscInfo[i].innerHTML && 'SeriesTimer' !== item.Type) {
itemMiscInfo[i].classList.remove('hide');
} else {
itemMiscInfo[i].classList.add('hide');
}
}
itemMiscInfo = page.querySelectorAll('.itemMiscInfo-secondary');
for (i = 0; i < itemMiscInfo.length; i++) {
mediaInfo.fillSecondaryMediaInfo(itemMiscInfo[i], item, {
interactive: true
});
if (itemMiscInfo[i].innerHTML && 'SeriesTimer' !== item.Type) {
itemMiscInfo[i].classList.remove('hide');
} else {
itemMiscInfo[i].classList.add('hide');
}
}
reloadUserDataButtons(page, item); reloadUserDataButtons(page, item);
renderLinks(externalLinksElem, item); renderLinks(page, item);
renderTags(page, item); renderTags(page, item);
renderSeriesAirTime(page, item, isStatic); renderSeriesAirTime(page, item, isStatic);
} }
@ -1765,17 +1778,18 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti
return function (view, params) { return function (view, params) {
function reload(instance, page, params) { function reload(instance, page, params) {
loading.show(); loading.show();
var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient; var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient;
var promises = [getPromise(apiClient, params), apiClient.getCurrentUser()];
Promise.all(promises).then(function (responses) { Promise.all([getPromise(apiClient, params), apiClient.getCurrentUser()]).then(([item, user]) => {
var item = responses[0];
var user = responses[1];
currentItem = item; currentItem = item;
reloadFromItem(instance, page, params, item, user); reloadFromItem(instance, page, params, item, user);
let detailImageContainer = page.querySelector('.detailImageContainer'); let detailImageContainer = page.querySelector('.detailImageContainer');
const overlayPlayButton = detailImageContainer.querySelector('.cardOverlayFab-primary'); const overlayPlayButton = detailImageContainer.querySelector('.cardOverlayFab-primary');
overlayPlayButton.addEventListener('click', onPlayClick); overlayPlayButton.addEventListener('click', onPlayClick);
}).catch((error) => {
console.error('failed to get item or current user: ', error);
}); });
} }

View file

@ -227,7 +227,7 @@ html {
color: #fff !important; color: #fff !important;
} }
.detailSticky { .detailRibbon {
background: #303030; background: #303030;
background: -webkit-gradient(linear, left top, right top, from(#bcbcbc), color-stop(#a7b4b7), color-stop(#beb5a5), color-stop(#adbec2), to(#b9c7cb)); background: -webkit-gradient(linear, left top, right top, from(#bcbcbc), color-stop(#a7b4b7), color-stop(#beb5a5), color-stop(#adbec2), to(#b9c7cb));
background: -webkit-linear-gradient(left, #bcbcbc, #a7b4b7, #beb5a5, #adbec2, #b9c7cb); background: -webkit-linear-gradient(left, #bcbcbc, #a7b4b7, #beb5a5, #adbec2, #b9c7cb);

View file

@ -223,7 +223,7 @@ html {
color: #fff !important; color: #fff !important;
} }
.detailSticky { .detailRibbon {
background: #303030; background: #303030;
background: -webkit-gradient(linear, left top, right top, from(#291a31), color-stop(#033664), color-stop(#011432), color-stop(#141a3a), to(#291a31)); background: -webkit-gradient(linear, left top, right top, from(#291a31), color-stop(#033664), color-stop(#011432), color-stop(#141a3a), to(#291a31));
background: -webkit-linear-gradient(left, #291a31, #033664, #011432, #141a3a, #291a31); background: -webkit-linear-gradient(left, #291a31, #033664, #011432, #141a3a, #291a31);

View file

@ -203,11 +203,11 @@ html {
background: rgba(30, 30, 30, 0.9); background: rgba(30, 30, 30, 0.9);
} }
.detailSticky { .detailRibbon {
background: rgba(32, 32, 32, 0.8); background: rgba(32, 32, 32, 0.8);
} }
.noBackdrop .detailSticky { .noBackdrop .detailRibbon {
background: #202020; background: #202020;
} }

View file

@ -221,7 +221,7 @@ html {
color: #fff !important; color: #fff !important;
} }
.detailSticky { .detailRibbon {
background-color: #303030; background-color: #303030;
color: #ccc; color: #ccc;
color: rgba(255, 255, 255, 0.87); color: rgba(255, 255, 255, 0.87);

View file

@ -307,7 +307,7 @@ a[data-role=button] {
color: #f8f8fe !important; color: #f8f8fe !important;
} }
.detailSticky { .detailRibbon {
background: #000420; background: #000420;
background: -moz-linear-gradient(left, #000420 0%, #06256f 18%, #2b052b 38%, #2b052b 68%, #06256f 81%, #000420 100%); background: -moz-linear-gradient(left, #000420 0%, #06256f 18%, #2b052b 38%, #2b052b 68%, #06256f 81%, #000420 100%);
background: -webkit-linear-gradient(left, #000420 0%, #06256f 18%, #2b052b 38%, #2b052b 68%, #06256f 81%, #000420 100%); background: -webkit-linear-gradient(left, #000420 0%, #06256f 18%, #2b052b 38%, #2b052b 68%, #06256f 81%, #000420 100%);

View file

@ -209,7 +209,7 @@ html {
color: #fff !important; color: #fff !important;
} }
.detailSticky { .detailRibbon {
background-color: #081b3b; background-color: #081b3b;
} }