2022-08-06 02:38:27 +03:00
|
|
|
import '../../elements/emby-button/emby-button';
|
|
|
|
import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
|
|
|
|
2022-10-05 02:44:28 +03:00
|
|
|
import type { BaseItemDtoQueryResult } from '@jellyfin/sdk/lib/generated-client';
|
2022-08-06 02:38:27 +03:00
|
|
|
import escapeHTML from 'escape-html';
|
2022-10-02 19:07:42 +03:00
|
|
|
import React, { FC, useCallback, useEffect, useRef } from 'react';
|
2022-08-06 01:36:13 +03:00
|
|
|
|
2022-08-06 02:38:27 +03:00
|
|
|
import { appRouter } from '../../components/appRouter';
|
2022-08-06 01:36:13 +03:00
|
|
|
import cardBuilder from '../../components/cardbuilder/cardBuilder';
|
|
|
|
import layoutManager from '../../components/layoutManager';
|
2022-08-06 02:38:27 +03:00
|
|
|
import lazyLoader from '../../components/lazyLoader/lazyLoaderIntersectionObserver';
|
|
|
|
import globalize from '../../scripts/globalize';
|
2022-08-06 01:36:13 +03:00
|
|
|
|
2022-10-02 19:07:42 +03:00
|
|
|
interface GenresItemsContainerI {
|
2022-08-06 01:36:13 +03:00
|
|
|
topParentId?: string | null;
|
|
|
|
getCurrentViewStyle: () => string;
|
|
|
|
itemsResult?: BaseItemDtoQueryResult;
|
|
|
|
}
|
|
|
|
|
2022-10-02 19:07:42 +03:00
|
|
|
const GenresItemsContainer: FC<GenresItemsContainerI> = ({ topParentId, getCurrentViewStyle, itemsResult = {} }) => {
|
2022-08-06 01:36:13 +03:00
|
|
|
const element = useRef<HTMLDivElement>(null);
|
|
|
|
|
|
|
|
const enableScrollX = useCallback(() => {
|
|
|
|
return !layoutManager.desktop;
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
const getPortraitShape = useCallback(() => {
|
|
|
|
return enableScrollX() ? 'overflowPortrait' : 'portrait';
|
|
|
|
}, [enableScrollX]);
|
|
|
|
|
|
|
|
const getThumbShape = useCallback(() => {
|
|
|
|
return enableScrollX() ? 'overflowBackdrop' : 'backdrop';
|
|
|
|
}, [enableScrollX]);
|
|
|
|
|
|
|
|
const fillItemsContainer = useCallback((entry) => {
|
|
|
|
const elem = entry.target;
|
|
|
|
const id = elem.getAttribute('data-id');
|
|
|
|
const viewStyle = getCurrentViewStyle();
|
|
|
|
let limit = viewStyle == 'Thumb' || viewStyle == 'ThumbCard' ? 5 : 9;
|
|
|
|
|
|
|
|
if (enableScrollX()) {
|
|
|
|
limit = 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
const enableImageTypes = viewStyle == 'Thumb' || viewStyle == 'ThumbCard' ? 'Primary,Backdrop,Thumb' : 'Primary';
|
|
|
|
const query = {
|
|
|
|
SortBy: 'Random',
|
|
|
|
SortOrder: 'Ascending',
|
|
|
|
IncludeItemTypes: 'Movie',
|
|
|
|
Recursive: true,
|
|
|
|
Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo',
|
|
|
|
ImageTypeLimit: 1,
|
|
|
|
EnableImageTypes: enableImageTypes,
|
|
|
|
Limit: limit,
|
|
|
|
GenreIds: id,
|
|
|
|
EnableTotalRecordCount: false,
|
|
|
|
ParentId: topParentId
|
|
|
|
};
|
|
|
|
window.ApiClient.getItems(window.ApiClient.getCurrentUserId(), query).then((result) => {
|
|
|
|
const items = result.Items || [];
|
|
|
|
if (viewStyle == 'Thumb') {
|
|
|
|
cardBuilder.buildCards(items, {
|
|
|
|
itemsContainer: elem,
|
|
|
|
shape: getThumbShape(),
|
|
|
|
preferThumb: true,
|
|
|
|
showTitle: true,
|
|
|
|
scalable: true,
|
|
|
|
centerText: true,
|
|
|
|
overlayMoreButton: true,
|
|
|
|
allowBottomPadding: false
|
|
|
|
});
|
|
|
|
} else if (viewStyle == 'ThumbCard') {
|
|
|
|
cardBuilder.buildCards(items, {
|
|
|
|
itemsContainer: elem,
|
|
|
|
shape: getThumbShape(),
|
|
|
|
preferThumb: true,
|
|
|
|
showTitle: true,
|
|
|
|
scalable: true,
|
|
|
|
centerText: false,
|
|
|
|
cardLayout: true,
|
|
|
|
showYear: true
|
|
|
|
});
|
|
|
|
} else if (viewStyle == 'PosterCard') {
|
|
|
|
cardBuilder.buildCards(items, {
|
|
|
|
itemsContainer: elem,
|
|
|
|
shape: getPortraitShape(),
|
|
|
|
showTitle: true,
|
|
|
|
scalable: true,
|
|
|
|
centerText: false,
|
|
|
|
cardLayout: true,
|
|
|
|
showYear: true
|
|
|
|
});
|
|
|
|
} else if (viewStyle == 'Poster') {
|
|
|
|
cardBuilder.buildCards(items, {
|
|
|
|
itemsContainer: elem,
|
|
|
|
shape: getPortraitShape(),
|
|
|
|
scalable: true,
|
|
|
|
overlayMoreButton: true,
|
|
|
|
allowBottomPadding: true,
|
|
|
|
showTitle: true,
|
|
|
|
centerText: true,
|
|
|
|
showYear: true
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}, [enableScrollX, getCurrentViewStyle, getPortraitShape, getThumbShape, topParentId]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const elem = element.current?.querySelector('#items') as HTMLDivElement;
|
|
|
|
let html = '';
|
|
|
|
const items = itemsResult.Items || [];
|
|
|
|
|
|
|
|
for (let i = 0, length = items.length; i < length; i++) {
|
|
|
|
const item = items[i];
|
|
|
|
|
|
|
|
html += '<div class="verticalSection">';
|
|
|
|
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
|
|
|
|
html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl(item, {
|
|
|
|
context: 'movies',
|
|
|
|
parentId: topParentId
|
|
|
|
}) + '" class="more button-flat button-flat-mini sectionTitleTextButton btnMoreFromGenre' + item.Id + '">';
|
|
|
|
html += '<h2 class="sectionTitle sectionTitle-cards">';
|
|
|
|
html += escapeHTML(item.Name);
|
|
|
|
html += '</h2>';
|
|
|
|
html += '<span class="material-icons chevron_right" aria-hidden="true"></span>';
|
|
|
|
html += '</a>';
|
|
|
|
html += '</div>';
|
|
|
|
if (enableScrollX()) {
|
2022-08-21 03:09:22 +03:00
|
|
|
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
|
|
|
|
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x lazy" data-id="' + item.Id + '">';
|
2022-08-06 01:36:13 +03:00
|
|
|
} else {
|
|
|
|
html += '<div is="emby-itemscontainer" class="itemsContainer vertical-wrap lazy padded-left padded-right" data-id="' + item.Id + '">';
|
|
|
|
}
|
|
|
|
|
|
|
|
html += '</div>';
|
|
|
|
html += '</div>';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!itemsResult.Items?.length) {
|
|
|
|
html = '';
|
|
|
|
|
|
|
|
html += '<div class="noItemsMessage centerMessage">';
|
|
|
|
html += '<h1>' + globalize.translate('MessageNothingHere') + '</h1>';
|
|
|
|
html += '<p>' + globalize.translate('MessageNoGenresAvailable') + '</p>';
|
|
|
|
html += '</div>';
|
|
|
|
}
|
|
|
|
|
|
|
|
elem.innerHTML = html;
|
|
|
|
lazyLoader.lazyChildren(elem, fillItemsContainer);
|
2022-08-06 03:06:41 +03:00
|
|
|
}, [getCurrentViewStyle, itemsResult.Items, fillItemsContainer, topParentId, enableScrollX]);
|
2022-08-06 01:36:13 +03:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div ref={element}>
|
2022-08-10 22:08:49 +03:00
|
|
|
<div id='items'/>
|
2022-08-06 01:36:13 +03:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default GenresItemsContainer;
|