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

move emby-webcomponents to components and reflect paths

This commit is contained in:
vitorsemeano 2019-02-23 18:05:42 +00:00
parent e91cbf8438
commit 6ddc62857d
275 changed files with 20 additions and 20 deletions

View file

@ -0,0 +1,11 @@
.searchFieldsInner {
max-width: 60em;
margin: 0 auto;
}
.searchfields-icon {
margin-bottom: .1em;
margin-right: .25em;
font-size: 2em;
align-self: flex-end;
}

View file

@ -0,0 +1,124 @@
define(['layoutManager', 'globalize', 'require', 'events', 'browser', 'alphaPicker', 'emby-input', 'flexStyles', 'material-icons', 'css!./searchfields'], function (layoutManager, globalize, require, events, browser, AlphaPicker) {
'use strict';
function onSearchTimeout() {
var instance = this;
var value = instance.nextSearchValue;
value = (value || '').trim();
events.trigger(instance, 'search', [value]);
}
function triggerSearch(instance, value) {
if (instance.searchTimeout) {
clearTimeout(instance.searchTimeout);
}
instance.nextSearchValue = value;
instance.searchTimeout = setTimeout(onSearchTimeout.bind(instance), 400);
}
function onAlphaValueClicked(e) {
var value = e.detail.value;
var searchFieldsInstance = this;
var txtSearch = searchFieldsInstance.options.element.querySelector('.searchfields-txtSearch');
if (value === 'backspace') {
var val = txtSearch.value;
txtSearch.value = val.length ? val.substring(0, val.length - 1) : '';
} else {
txtSearch.value += value;
}
txtSearch.dispatchEvent(new CustomEvent('input', {
bubbles: true
}));
}
function initAlphaPicker(alphaPickerElement, instance) {
instance.alphaPicker = new AlphaPicker({
element: alphaPickerElement,
mode: 'keyboard'
});
alphaPickerElement.addEventListener('alphavalueclicked', onAlphaValueClicked.bind(instance));
}
function onSearchInput(e) {
var value = e.target.value;
var searchFieldsInstance = this;
triggerSearch(searchFieldsInstance, value);
}
function embed(elem, instance, options) {
require(['text!./searchfields.template.html'], function (template) {
var html = globalize.translateDocument(template, 'core');
if (browser.tizen || browser.orsay) {
html = html.replace('<input ', '<input readonly ');
}
elem.innerHTML = html;
elem.classList.add('searchFields');
var txtSearch = elem.querySelector('.searchfields-txtSearch');
if (layoutManager.tv) {
var alphaPickerElement = elem.querySelector('.alphaPicker');
elem.querySelector('.alphaPicker').classList.remove('hide');
initAlphaPicker(alphaPickerElement, instance);
}
txtSearch.addEventListener('input', onSearchInput.bind(instance));
instance.focus();
});
}
function SearchFields(options) {
this.options = options;
embed(options.element, this, options);
}
SearchFields.prototype.focus = function () {
this.options.element.querySelector('.searchfields-txtSearch').focus();
};
SearchFields.prototype.destroy = function () {
var options = this.options;
if (options) {
options.element.classList.remove('searchFields');
}
this.options = null;
var alphaPicker = this.alphaPicker;
if (alphaPicker) {
alphaPicker.destroy();
}
this.alphaPicker = null;
var searchTimeout = this.searchTimeout;
if (searchTimeout) {
clearTimeout(searchTimeout);
}
this.searchTimeout = null;
this.nextSearchValue = null;
};
return SearchFields;
});

View file

@ -0,0 +1,7 @@
<div class="searchFieldsInner flex align-items-center justify-content-center">
<i class="searchfields-icon md-icon">&#xE8B6;</i>
<div class="inputContainer flex-grow" style="margin-bottom: 0;">
<input is="emby-input" class="searchfields-txtSearch" type="text" data-keyboard="false" placeholder="${Search}" autocomplete="off" maxlength="40" autofocus />
</div>
</div>
<div class="alphaPicker align-items-center hide"></div>

View file

@ -0,0 +1,646 @@
define(['layoutManager', 'globalize', 'require', 'events', 'connectionManager', 'cardBuilder', 'appRouter', 'emby-scroller', 'emby-itemscontainer', 'emby-linkbutton'], function (layoutManager, globalize, require, events, connectionManager, cardBuilder, appRouter) {
'use strict';
function loadSuggestions(instance, context, apiClient) {
var options = {
SortBy: "IsFavoriteOrLiked,Random",
IncludeItemTypes: "Movie,Series,MusicArtist",
Limit: 20,
Recursive: true,
ImageTypeLimit: 0,
EnableImages: false,
ParentId: instance.options.parentId,
EnableTotalRecordCount: false
};
apiClient.getItems(apiClient.getCurrentUserId(), options).then(function (result) {
if (instance.mode !== 'suggestions') {
result.Items = [];
}
var html = result.Items.map(function (i) {
var href = appRouter.getRouteUrl(i);
var itemHtml = '<div><a is="emby-linkbutton" class="button-link" style="display:inline-block;padding:.5em 1em;" href="' + href + '">';
itemHtml += i.Name;
itemHtml += '</a></div>';
return itemHtml;
}).join('');
var searchSuggestions = context.querySelector('.searchSuggestions');
searchSuggestions.querySelector('.searchSuggestionsList').innerHTML = html;
if (result.Items.length) {
searchSuggestions.classList.remove('hide');
}
});
}
function getSearchHints(instance, apiClient, query) {
if (!query.searchTerm) {
return Promise.resolve({
SearchHints: []
});
}
var allowSearch = true;
var queryIncludeItemTypes = query.IncludeItemTypes;
if (instance.options.collectionType === 'tvshows') {
if (query.IncludeArtists) {
allowSearch = false;
}
else if (queryIncludeItemTypes === 'Movie' ||
queryIncludeItemTypes === 'LiveTvProgram' ||
queryIncludeItemTypes === 'MusicAlbum' ||
queryIncludeItemTypes === 'Audio' ||
queryIncludeItemTypes === 'Book' ||
queryIncludeItemTypes === 'AudioBook' ||
queryIncludeItemTypes === 'Playlist' ||
queryIncludeItemTypes === 'PhotoAlbum' ||
query.MediaTypes === 'Video' ||
query.MediaTypes === 'Photo') {
allowSearch = false;
}
}
else if (instance.options.collectionType === 'movies') {
if (query.IncludeArtists) {
allowSearch = false;
}
else if (queryIncludeItemTypes === 'Series' ||
queryIncludeItemTypes === 'Episode' ||
queryIncludeItemTypes === 'LiveTvProgram' ||
queryIncludeItemTypes === 'MusicAlbum' ||
queryIncludeItemTypes === 'Audio' ||
queryIncludeItemTypes === 'Book' ||
queryIncludeItemTypes === 'AudioBook' ||
queryIncludeItemTypes === 'Playlist' ||
queryIncludeItemTypes === 'PhotoAlbum' ||
query.MediaTypes === 'Video' ||
query.MediaTypes === 'Photo') {
allowSearch = false;
}
}
else if (instance.options.collectionType === 'music') {
if (query.People) {
allowSearch = false;
}
else if (queryIncludeItemTypes === 'Series' ||
queryIncludeItemTypes === 'Episode' ||
queryIncludeItemTypes === 'LiveTvProgram' ||
queryIncludeItemTypes === 'Movie') {
allowSearch = false;
}
}
else if (instance.options.collectionType === 'livetv') {
if (query.IncludeArtists || query.IncludePeople) {
allowSearch = false;
}
else if (queryIncludeItemTypes === 'Series' ||
queryIncludeItemTypes === 'Episode' ||
queryIncludeItemTypes === 'MusicAlbum' ||
queryIncludeItemTypes === 'Audio' ||
queryIncludeItemTypes === 'Book' ||
queryIncludeItemTypes === 'AudioBook' ||
queryIncludeItemTypes === 'PhotoAlbum' ||
queryIncludeItemTypes === 'Movie' ||
query.MediaTypes === 'Video' ||
query.MediaTypes === 'Photo') {
allowSearch = false;
}
}
if (queryIncludeItemTypes === 'NullType') {
allowSearch = false;
}
if (!allowSearch) {
return Promise.resolve({
SearchHints: []
});
}
// Convert the search hint query to a regular item query
if (apiClient.isMinServerVersion('3.4.1.31')) {
query.Fields = 'PrimaryImageAspectRatio,CanDelete,BasicSyncInfo,MediaSourceCount';
query.Recursive = true;
query.EnableTotalRecordCount = false;
query.ImageTypeLimit = 1;
var methodName = 'getItems';
if (!query.IncludeMedia) {
if (query.IncludePeople) {
methodName = 'getPeople';
} else if (query.IncludeArtists) {
methodName = 'getArtists';
}
}
return apiClient[methodName](apiClient.getCurrentUserId(), query);
}
query.UserId = apiClient.getCurrentUserId();
return apiClient.getSearchHints(query);
}
function search(instance, apiClient, context, value) {
if (value || layoutManager.tv) {
instance.mode = 'search';
context.querySelector('.searchSuggestions').classList.add('hide');
} else {
instance.mode = 'suggestions';
loadSuggestions(instance, context, apiClient);
}
if (instance.options.collectionType === 'livetv') {
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "LiveTvProgram",
IsMovie: true,
IsKids: false,
IsNews: false
}, context, '.movieResults', {
preferThumb: true,
inheritThumb: false,
shape: (enableScrollX() ? 'overflowPortrait' : 'portrait'),
showParentTitleOrTitle: true,
showTitle: false,
centerText: true,
coverImage: true,
overlayText: false,
overlayMoreButton: true,
showAirTime: true,
showAirDateTime: true,
showChannelName: true
});
} else {
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "Movie"
}, context, '.movieResults', {
showTitle: true,
overlayText: false,
centerText: true,
showYear: true
});
}
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "Series"
}, context, '.seriesResults', {
showTitle: true,
overlayText: false,
centerText: true,
showYear: true
});
if (instance.options.collectionType === 'livetv') {
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "LiveTvProgram",
IsSeries: true,
IsSports: false,
IsKids: false,
IsNews: false
}, context, '.episodeResults', {
preferThumb: true,
inheritThumb: false,
shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'),
showParentTitleOrTitle: true,
showTitle: false,
centerText: true,
coverImage: true,
overlayText: false,
overlayMoreButton: true,
showAirTime: true,
showAirDateTime: true,
showChannelName: true
});
} else {
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "Episode"
}, context, '.episodeResults', {
coverImage: true,
showTitle: true,
showParentTitle: true
});
}
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
// NullType to hide
IncludeItemTypes: instance.options.collectionType === 'livetv' ? 'LiveTvProgram' : 'NullType',
IsSports: true
}, context, '.sportsResults', {
preferThumb: true,
inheritThumb: false,
shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'),
showParentTitleOrTitle: true,
showTitle: false,
centerText: true,
coverImage: true,
overlayText: false,
overlayMoreButton: true,
showAirTime: true,
showAirDateTime: true,
showChannelName: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
// NullType to hide
IncludeItemTypes: instance.options.collectionType === 'livetv' ? 'LiveTvProgram' : 'NullType',
IsKids: true
}, context, '.kidsResults', {
preferThumb: true,
inheritThumb: false,
shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'),
showParentTitleOrTitle: true,
showTitle: false,
centerText: true,
coverImage: true,
overlayText: false,
overlayMoreButton: true,
showAirTime: true,
showAirDateTime: true,
showChannelName: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
// NullType to hide
IncludeItemTypes: instance.options.collectionType === 'livetv' ? 'LiveTvProgram' : 'NullType',
IsNews: true
}, context, '.newsResults', {
preferThumb: true,
inheritThumb: false,
shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'),
showParentTitleOrTitle: true,
showTitle: false,
centerText: true,
coverImage: true,
overlayText: false,
overlayMoreButton: true,
showAirTime: true,
showAirDateTime: true,
showChannelName: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "LiveTvProgram",
IsMovie: instance.options.collectionType === 'livetv' ? false : null,
IsSeries: instance.options.collectionType === 'livetv' ? false : null,
IsSports: instance.options.collectionType === 'livetv' ? false : null,
IsKids: instance.options.collectionType === 'livetv' ? false : null,
IsNews: instance.options.collectionType === 'livetv' ? false : null
}, context, '.programResults', {
preferThumb: true,
inheritThumb: false,
shape: (enableScrollX() ? 'overflowBackdrop' : 'backdrop'),
showParentTitleOrTitle: true,
showTitle: false,
centerText: true,
coverImage: true,
overlayText: false,
overlayMoreButton: true,
showAirTime: true,
showAirDateTime: true,
showChannelName: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
MediaTypes: "Video",
ExcludeItemTypes: "Movie,Episode"
}, context, '.videoResults', {
showParentTitle: true,
showTitle: true,
overlayText: false,
centerText: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: true,
IncludeMedia: false,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false
}, context, '.peopleResults', {
coverImage: true,
showTitle: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: false,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: true
}, context, '.artistResults', {
coverImage: true,
showTitle: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "MusicAlbum"
}, context, '.albumResults', {
showParentTitle: true,
showTitle: true,
overlayText: false,
centerText: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "Audio"
}, context, '.songResults', {
showParentTitle: true,
showTitle: true,
overlayText: false,
centerText: true,
action: 'play'
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
MediaTypes: "Photo"
}, context, '.photoResults', {
showParentTitle: false,
showTitle: true,
overlayText: false,
centerText: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "PhotoAlbum"
}, context, '.photoAlbumResults', {
showTitle: true,
overlayText: false,
centerText: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "Book"
}, context, '.bookResults', {
showTitle: true,
overlayText: false,
centerText: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "AudioBook"
}, context, '.audioBookResults', {
showTitle: true,
overlayText: false,
centerText: true
});
searchType(instance, apiClient, {
searchTerm: value,
IncludePeople: false,
IncludeMedia: true,
IncludeGenres: false,
IncludeStudios: false,
IncludeArtists: false,
IncludeItemTypes: "Playlist"
}, context, '.playlistResults', {
showTitle: true,
overlayText: false,
centerText: true
});
}
function searchType(instance, apiClient, query, context, section, cardOptions) {
query.Limit = enableScrollX() ? 24 : 16;
query.ParentId = instance.options.parentId;
getSearchHints(instance, apiClient, query).then(function (result) {
populateResults(result, context, section, cardOptions);
});
}
function populateResults(result, context, section, cardOptions) {
section = context.querySelector(section);
var items = result.Items || result.SearchHints;
var itemsContainer = section.querySelector('.itemsContainer');
cardBuilder.buildCards(items, Object.assign({
itemsContainer: itemsContainer,
parentContainer: section,
shape: enableScrollX() ? 'autooverflow' : 'auto',
scalable: true,
overlayText: false,
centerText: true,
allowBottomPadding: !enableScrollX()
}, cardOptions || {}));
section.querySelector('.emby-scroller').scrollToBeginning(true);
}
function enableScrollX() {
return true;
}
function replaceAll(originalString, strReplace, strWith) {
var reg = new RegExp(strReplace, 'ig');
return originalString.replace(reg, strWith);
}
function embed(elem, instance, options) {
require(['text!./searchresults.template.html'], function (template) {
if (!enableScrollX()) {
template = replaceAll(template, 'data-horizontal="true"', 'data-horizontal="false"');
template = replaceAll(template, 'itemsContainer scrollSlider', 'itemsContainer scrollSlider vertical-wrap');
}
var html = globalize.translateDocument(template, 'core');
elem.innerHTML = html;
elem.classList.add('searchResults');
instance.search('');
});
}
function SearchResults(options) {
this.options = options;
embed(options.element, this, options);
}
SearchResults.prototype.search = function (value) {
var apiClient = connectionManager.getApiClient(this.options.serverId);
search(this, apiClient, this.options.element, value);
};
SearchResults.prototype.destroy = function () {
var options = this.options;
if (options) {
options.element.classList.remove('searchFields');
}
this.options = null;
};
return SearchResults;
});

View file

@ -0,0 +1,146 @@
<div class="hide verticalSection searchSuggestions" style="text-align:center;">
<div>
<h2 class="sectionTitle padded-left padded-right">${Suggestions}</h2>
</div>
<div class="searchSuggestionsList padded-left padded-right">
</div>
</div>
<div class="hide verticalSection movieResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Movies}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection seriesResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Shows}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection episodeResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Episodes}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection sportsResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Sports}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection kidsResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Kids}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection newsResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${News}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection programResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Programs}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection videoResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Videos}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection playlistResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Playlists}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection artistResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Artists}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection albumResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Albums}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection songResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Songs}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection photoAlbumResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${HeaderPhotoAlbums}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection photoResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Photos}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection audioBookResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${HeaderAudioBooks}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection bookResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${Books}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>
<div class="hide verticalSection peopleResults">
<h2 class="sectionTitle sectionTitle-cards focuscontainer-x padded-left padded-right">${People}</h2>
<div is="emby-scroller" data-horizontal="true" data-centerfocus="card" data-mousewheel="false" class="padded-top-focusscale padded-bottom-focusscale">
<div is="emby-itemscontainer" class="focuscontainer-x padded-left padded-right itemsContainer scrollSlider"></div>
</div>
</div>