Use float for item details poster (#7195)

* Use float for item details poster

* Add list view children to primary content

* Move additional sections to primary container

* Add series to list view children

* Fix order of primary content sections
This commit is contained in:
Bill Thornton
2025-10-17 16:42:40 -04:00
committed by GitHub
parent 1ed047df3d
commit 4fa5176982
10 changed files with 243 additions and 190 deletions
+156 -142
View File
@@ -4,172 +4,186 @@
<div class="detailLogo"></div>
<div class="detailPageWrapperContainer">
<div class="detailPagePrimaryContainer padded-left padded-right">
<div class="infoWrapper">
<div class="detailImageContainer padded-left"></div>
<div class="nameContainer"></div>
<div class="itemMiscInfo itemMiscInfo-primary" style="margin-bottom: 0.6em;"></div>
<div class="itemMiscInfo itemMiscInfo-secondary" style="margin-bottom: 0.6em;"></div>
<div class="detailPagePrimaryContainer">
<div class="detailImageContainer hide-mobile"></div>
<div class="detailRibbon padded-left padded-right">
<div class="infoWrapper">
<div class="detailImageContainer hide-desktop hide-tv"></div>
<div class="nameContainer"></div>
<div class="itemMiscInfo itemMiscInfo-primary" style="margin-bottom: 0.6em;"></div>
<div class="itemMiscInfo itemMiscInfo-secondary" style="margin-bottom: 0.6em;"></div>
</div>
<div class="mainDetailButtons focuscontainer-x">
<button is="emby-button" type="button" class="button-flat btnPlay hide detailButton" title="${ButtonResume}" data-action="resume">
<div class="detailButton-content">
<span class="material-icons detailButton-icon play_arrow" aria-hidden="true"></span>
</div>
</button>
<button is="emby-button" type="button" class="button-flat btnReplay hide detailButton" title="${Play}" data-action="play">
<div class="detailButton-content">
<span class="material-icons detailButton-icon replay" aria-hidden="true"></span>
</div>
</button>
<button is="emby-button" type="button" class="button-flat btnDownload hide detailButton" title="${Download}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon get_app" aria-hidden="true"></span>
</div>
</button>
<button is="emby-button" type="button" class="button-flat btnPlayTrailer hide detailButton" title="${ButtonTrailer}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon theaters" aria-hidden="true"></span>
</div>
</button>
<button is="emby-button" type="button" class="button-flat btnInstantMix hide detailButton" title="${HeaderInstantMix}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon explore" aria-hidden="true"></span>
</div>
</button>
<button is="emby-button" type="button" class="button-flat btnShuffle hide detailButton" title="${Shuffle}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon shuffle" aria-hidden="true"></span>
</div>
</button>
<button is="emby-button" type="button" class="button-flat btnCancelSeriesTimer hide detailButton" title="${CancelSeries}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon delete" aria-hidden="true"></span>
</div>
</button>
<button is="emby-button" type="button" class="button-flat btnCancelTimer hide detailButton" title="${StopRecording}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon stop" aria-hidden="true"></span>
</div>
</button>
<button is="emby-playstatebutton" type="button" class="button-flat btnPlaystate hide detailButton" title="">
<div class="detailButton-content">
<span class="material-icons detailButton-icon check" aria-hidden="true"></span>
</div>
</button>
<button is="emby-ratingbutton" type="button" class="button-flat btnUserRating hide detailButton" title="${Rate}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon favorite" aria-hidden="true"></span>
</div>
</button>
<button is="emby-button" type="button" class="button-flat btnSplitVersions hide detailButton" title="${ButtonSplit}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon call_split" aria-hidden="true"></span>
</div>
</button>
<button is="emby-button" type="button" class="button-flat btnMoreCommands hide detailButton" title="${ButtonMore}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon more_vert" aria-hidden="true"></span>
</div>
</button>
</div>
</div>
<div class="mainDetailButtons focuscontainer-x">
<button is="emby-button" type="button" class="button-flat btnPlay hide detailButton" title="${ButtonResume}" data-action="resume">
<div class="detailButton-content">
<span class="material-icons detailButton-icon play_arrow" aria-hidden="true"></span>
</div>
</button>
<div class="detailPagePrimaryContent padded-right">
<div class="detailSection">
<form class="trackSelections hide focuscontainer-x">
<div class="selectContainer selectSourceContainer hide trackSelectionFieldContainer flex-shrink-zero">
<select is="emby-select" class="selectSource detailTrackSelect" label=""></select>
</div>
<div class="selectContainer selectVideoContainer hide trackSelectionFieldContainer flex-shrink-zero">
<select is="emby-select" class="selectVideo detailTrackSelect" label=""></select>
</div>
<div class="selectContainer selectAudioContainer hide trackSelectionFieldContainer flex-shrink-zero">
<select is="emby-select" class="selectAudio detailTrackSelect" label=""></select>
</div>
<div class="selectContainer selectSubtitlesContainer hide trackSelectionFieldContainer flex-shrink-zero">
<select is="emby-select" class="selectSubtitles detailTrackSelect" label=""></select>
</div>
</form>
<button is="emby-button" type="button" class="button-flat btnReplay hide detailButton" title="${Play}" data-action="play">
<div class="detailButton-content">
<span class="material-icons detailButton-icon replay" aria-hidden="true"></span>
</div>
</button>
<div class="recordingFields hide" style="margin: 0.5em 0 1.5em;"></div>
<button is="emby-button" type="button" class="button-flat btnDownload hide detailButton" title="${Download}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon get_app" aria-hidden="true"></span>
</div>
</button>
<div class="detailSectionContent">
<p class="itemGenres"></p>
<h3 class="tagline"></h3>
<p class="overview"></p>
<div class="overview-controls">
<a class="overview-expand hide" is="emby-linkbutton" href="#">${ShowMore}</a>
</div>
<p id="itemBirthday"></p>
<p id="itemBirthLocation"></p>
<p id="itemDeathDate"></p>
<p id="seriesAirTime"></p>
<button is="emby-button" type="button" class="button-flat btnPlayTrailer hide detailButton" title="${ButtonTrailer}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon theaters" aria-hidden="true"></span>
<div class="itemTags focuscontainer-x hide" style="margin: 0.7em 0; font-size: 92%;"></div>
<div class="itemExternalLinks focuscontainer-x hide" style="margin: 0.7em 0; font-size: 92%;"></div>
<div class="seriesRecordingEditor"></div>
</div>
</button>
<button is="emby-button" type="button" class="button-flat btnInstantMix hide detailButton" title="${HeaderInstantMix}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon explore" aria-hidden="true"></span>
</div>
</button>
<div class="itemDetailsGroup">
<div class="detailsGroupItem genresGroup hide">
<div class="genresLabel label"></div>
<div class="genres content focuscontainer-x"></div>
</div>
<button is="emby-button" type="button" class="button-flat btnShuffle hide detailButton" title="${Shuffle}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon shuffle" aria-hidden="true"></span>
</div>
</button>
<div class="detailsGroupItem directorsGroup hide">
<div class="directorsLabel label"></div>
<div class="directors content focuscontainer-x"></div>
</div>
<button is="emby-button" type="button" class="button-flat btnCancelSeriesTimer hide detailButton" title="${CancelSeries}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon delete" aria-hidden="true"></span>
</div>
</button>
<div class="detailsGroupItem writersGroup hide">
<div class="writersLabel label"></div>
<div class="writers content focuscontainer-x"></div>
</div>
<button is="emby-button" type="button" class="button-flat btnCancelTimer hide detailButton" title="${StopRecording}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon stop" aria-hidden="true"></span>
<div class="detailsGroupItem studiosGroup hide">
<div class="studiosLabel label"></div>
<div class="studios content focuscontainer-x"></div>
</div>
</div>
</button>
<button is="emby-playstatebutton" type="button" class="button-flat btnPlaystate hide detailButton" title="">
<div class="detailButton-content">
<span class="material-icons detailButton-icon check" aria-hidden="true"></span>
<div id="seriesTimerScheduleSection" class="verticalSection detailVerticalSection hide" style="margin-top: -3em;">
<h2 class="sectionTitle">${Schedule}</h2>
<div id="seriesTimerSchedule" is="emby-itemscontainer" class="itemsContainer vertical-list padded-right" data-contextmenu="false"></div>
</div>
</button>
<button is="emby-ratingbutton" type="button" class="button-flat btnUserRating hide detailButton" title="${Rate}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon favorite" aria-hidden="true"></span>
</div>
</button>
<div class="collectionItems hide"></div>
<button is="emby-button" type="button" class="button-flat btnSplitVersions hide detailButton" title="${ButtonSplit}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon call_split" aria-hidden="true"></span>
<div class="nextUpSection verticalSection detailVerticalSection hide">
<h2 class="sectionTitle sectionTitle-cards">${NextUp}</h2>
<div is="emby-itemscontainer" class="nextUpItems vertical-wrap padded-right"></div>
</div>
</button>
<button is="emby-button" type="button" class="button-flat btnMoreCommands hide detailButton" title="${ButtonMore}">
<div class="detailButton-content">
<span class="material-icons detailButton-icon more_vert" aria-hidden="true"></span>
<div class="programGuideSection hide verticalSection detailVerticalSection">
<div class="programGuide"></div>
</div>
</button>
<div id="listChildrenCollapsible" class="hide verticalSection detailVerticalSection">
<h2 class="sectionTitle sectionTitle-cards hide">
<span></span>
</h2>
<div id="childrenContent">
<div is="emby-itemscontainer" class="itemsContainer padded-right" style="text-align: left;"></div>
</div>
</div>
</div>
</div>
</div>
<div class="detailPageSecondaryContainer padded-bottom-page">
<div class="detailPageContent">
<div class="detailPagePrimaryContent padded-right">
<div class="detailSection">
<form class="trackSelections hide focuscontainer-x">
<div class="selectContainer selectSourceContainer hide trackSelectionFieldContainer flex-shrink-zero">
<select is="emby-select" class="selectSource detailTrackSelect" label=""></select>
</div>
<div class="selectContainer selectVideoContainer hide trackSelectionFieldContainer flex-shrink-zero">
<select is="emby-select" class="selectVideo detailTrackSelect" label=""></select>
</div>
<div class="selectContainer selectAudioContainer hide trackSelectionFieldContainer flex-shrink-zero">
<select is="emby-select" class="selectAudio detailTrackSelect" label=""></select>
</div>
<div class="selectContainer selectSubtitlesContainer hide trackSelectionFieldContainer flex-shrink-zero">
<select is="emby-select" class="selectSubtitles detailTrackSelect" label=""></select>
</div>
</form>
<div class="recordingFields hide" style="margin: 0.5em 0 1.5em;"></div>
<div class="detailSectionContent">
<p class="itemGenres"></p>
<h3 class="tagline"></h3>
<p class="overview"></p>
<div class="overview-controls">
<a class="overview-expand hide" is="emby-linkbutton" href="#">${ShowMore}</a>
</div>
<p id="itemBirthday"></p>
<p id="itemBirthLocation"></p>
<p id="itemDeathDate"></p>
<p id="seriesAirTime"></p>
<div class="itemTags focuscontainer-x hide" style="margin: 0.7em 0; font-size: 92%;"></div>
<div class="itemExternalLinks focuscontainer-x hide" style="margin: 0.7em 0; font-size: 92%;"></div>
<div class="seriesRecordingEditor"></div>
</div>
<div class="itemDetailsGroup">
<div class="detailsGroupItem genresGroup hide">
<div class="genresLabel label"></div>
<div class="genres content focuscontainer-x"></div>
</div>
<div class="detailsGroupItem directorsGroup hide">
<div class="directorsLabel label"></div>
<div class="directors content focuscontainer-x"></div>
</div>
<div class="detailsGroupItem writersGroup hide">
<div class="writersLabel label"></div>
<div class="writers content focuscontainer-x"></div>
</div>
<div class="detailsGroupItem studiosGroup hide">
<div class="studiosLabel label"></div>
<div class="studios content focuscontainer-x"></div>
</div>
</div>
</div>
</div>
<div id="seriesTimerScheduleSection" class="verticalSection detailVerticalSection hide" style="margin-top: -3em;">
<h2 class="sectionTitle">${Schedule}</h2>
<div id="seriesTimerSchedule" is="emby-itemscontainer" class="itemsContainer vertical-list padded-right" data-contextmenu="false"></div>
</div>
<div class="collectionItems hide"></div>
<div class="nextUpSection verticalSection detailVerticalSection hide">
<h2 class="sectionTitle sectionTitle-cards">${NextUp}</h2>
<div is="emby-itemscontainer" class="nextUpItems vertical-wrap padded-right"></div>
</div>
<div class="programGuideSection hide verticalSection detailVerticalSection">
<div class="programGuide"></div>
</div>
<div id="childrenCollapsible" class="hide verticalSection detailVerticalSection">
<h2 class="childrenSectionHeader sectionTitle sectionTitle-cards hide">
<span id="childrenTitle"></span>
<h2 class="sectionTitle sectionTitle-cards hide">
<span></span>
</h2>
<div id="childrenContent">
<div is="emby-itemscontainer" class="childrenItemsContainer itemsContainer padded-right" style="text-align: left;"></div>
<div>
<div is="emby-itemscontainer" class="itemsContainer padded-right" style="text-align: left;"></div>
</div>
</div>
+37 -19
View File
@@ -45,6 +45,14 @@ import 'elements/emby-select/emby-select';
import 'styles/scrollstyles.scss';
/** Item types that use a list view for their children. */
const LIST_VIEW_TYPES = [
BaseItemKind.MusicAlbum,
BaseItemKind.Playlist,
BaseItemKind.Season,
BaseItemKind.Series
];
function autoFocus(container) {
import('../../components/autoFocuser').then(({ default: autoFocuser }) => {
autoFocuser.autoFocus(container);
@@ -554,7 +562,6 @@ function reloadFromItem(instance, page, params, item, user) {
renderBackdrop(page, item);
// 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);
@@ -749,12 +756,15 @@ function renderDetailImage(apiClient, elem, item, loader) {
}
function renderImage(page, item, apiClient) {
renderDetailImage(
apiClient,
page.querySelector('.detailImageContainer'),
item,
imageLoader
);
page.querySelectorAll('.detailImageContainer')
.forEach(elem => {
renderDetailImage(
apiClient,
elem,
item,
imageLoader
);
});
}
function setPeopleHeader(page, item) {
@@ -803,18 +813,22 @@ function setInitialCollapsibleState(page, item, apiClient, context, user) {
page.querySelector('.collectionItems').innerHTML = '';
if (item.Type == 'Playlist') {
page.querySelector('#childrenCollapsible').classList.remove('hide');
page.querySelector('#listChildrenCollapsible').classList.remove('hide');
page.querySelector('#childrenCollapsible').classList.add('hide');
renderPlaylistItems(page, item);
} else if (item.Type == 'Studio' || item.Type == 'Person' || item.Type == 'Genre' || item.Type == 'MusicGenre' || item.Type == 'MusicArtist') {
page.querySelector('#childrenCollapsible').classList.remove('hide');
page.querySelector('#listChildrenCollapsible').classList.remove('hide');
page.querySelector('#childrenCollapsible').classList.add('hide');
renderItemsByName(page, item);
} else if (item.IsFolder) {
if (item.Type == 'BoxSet') {
page.querySelector('#listChildrenCollapsible').classList.add('hide');
page.querySelector('#childrenCollapsible').classList.add('hide');
}
renderChildren(page, item);
} else {
page.querySelector('#listChildrenCollapsible').classList.add('hide');
page.querySelector('#childrenCollapsible').classList.add('hide');
}
@@ -1338,6 +1352,9 @@ function renderTags(page, item) {
}
function renderChildren(page, item) {
const childrenCollapsible = page.querySelector(LIST_VIEW_TYPES.includes(item.Type) ? '#listChildrenCollapsible' : '#childrenCollapsible');
const childrenItemsContainer = childrenCollapsible.querySelector('.itemsContainer');
let fields = 'ItemCounts,PrimaryImageAspectRatio,CanDelete,MediaSourceCount';
const query = {
ParentId: item.Id,
@@ -1375,7 +1392,6 @@ function renderChildren(page, item) {
let html = '';
let scrollX = false;
let isList = false;
const childrenItemsContainer = page.querySelector('.childrenItemsContainer');
if (item.Type == 'MusicAlbum') {
let showArtist = false;
@@ -1451,7 +1467,7 @@ function renderChildren(page, item) {
}
if (item.Type !== 'BoxSet') {
page.querySelector('#childrenCollapsible').classList.remove('hide');
childrenCollapsible.classList.remove('hide');
}
if (scrollX) {
childrenItemsContainer.classList.add('scrollX');
@@ -1502,21 +1518,23 @@ function renderChildren(page, item) {
}
});
let childrenTitle = globalize.translate('Items');
if (item.Type == 'Season') {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('Episodes');
childrenTitle = globalize.translate('Episodes');
} else if (item.Type == 'Series') {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderSeasons');
childrenTitle = globalize.translate('HeaderSeasons');
} else if (item.Type == 'MusicAlbum') {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderTracks');
} else {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('Items');
childrenTitle = globalize.translate('HeaderTracks');
}
childrenCollapsible.querySelectorAll('.sectionTitle > span').forEach(el => {
el.innerText = childrenTitle;
});
if (item.Type == 'MusicAlbum' || item.Type == 'Season') {
page.querySelector('.childrenSectionHeader').classList.add('hide');
page.querySelector('#childrenCollapsible').classList.add('verticalSection-extrabottompadding');
childrenCollapsible.querySelector('.sectionTitle').classList.add('hide');
childrenCollapsible.classList.add('verticalSection-extrabottompadding');
} else {
page.querySelector('.childrenSectionHeader').classList.remove('hide');
childrenCollapsible.querySelector('.sectionTitle').classList.remove('hide');
}
}