jellyfish-web/src/components/common/GenresItemsContainer.tsx

127 lines
4.8 KiB
TypeScript
Raw Normal View History

2022-08-06 02:38:27 +03:00
import '../../elements/emby-button/emby-button';
import '../../elements/emby-itemscontainer/emby-itemscontainer';
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-10-27 00:59:46 +03:00
import { appRouter } from '../appRouter';
import cardBuilder from '../cardbuilder/cardBuilder';
import layoutManager from '../layoutManager';
import lazyLoader from '../lazyLoader/lazyLoaderIntersectionObserver';
2022-08-06 02:38:27 +03:00
import globalize from '../../scripts/globalize';
import ItemsScrollerContainerElement from '../../elements/ItemsScrollerContainerElement';
import ItemsContainerElement from '../../elements/ItemsContainerElement';
const createLinkElement = ({ className, title, href }: { className?: string, title?: string | null, href?: string }) => ({
__html: `<a
is="emby-linkbutton"
class="${className}"
href="${href}"
>
<h2 class='sectionTitle sectionTitle-cards'>
${title}
</h2>
<span class='material-icons chevron_right' aria-hidden='true'></span>
</a>`
});
2022-08-06 01:36:13 +03:00
2022-10-14 02:07:54 +03:00
interface GenresItemsContainerProps {
2022-08-06 01:36:13 +03:00
topParentId?: string | null;
itemsResult: BaseItemDtoQueryResult;
2022-08-06 01:36:13 +03:00
}
const GenresItemsContainer: FC<GenresItemsContainerProps> = ({
topParentId,
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 fillItemsContainer = useCallback((entry) => {
const elem = entry.target;
const id = elem.getAttribute('data-id');
const query = {
SortBy: 'Random',
SortOrder: 'Ascending',
IncludeItemTypes: 'Movie',
Recursive: true,
Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo',
ImageTypeLimit: 1,
EnableImageTypes: 'Primary',
Limit: 12,
2022-08-06 01:36:13 +03:00
GenreIds: id,
EnableTotalRecordCount: false,
ParentId: topParentId
};
window.ApiClient.getItems(window.ApiClient.getCurrentUserId(), query).then((result) => {
cardBuilder.buildCards(result.Items || [], {
itemsContainer: elem,
shape: getPortraitShape(),
scalable: true,
overlayMoreButton: true,
allowBottomPadding: true,
showTitle: true,
centerText: true,
showYear: true
});
2022-08-06 01:36:13 +03:00
});
}, [getPortraitShape, topParentId]);
2022-08-06 01:36:13 +03:00
useEffect(() => {
const elem = element.current;
2022-08-06 01:36:13 +03:00
lazyLoader.lazyChildren(elem, fillItemsContainer);
}, [itemsResult.Items, fillItemsContainer]);
2022-08-06 01:36:13 +03:00
const items = itemsResult.Items || [];
2022-08-06 01:36:13 +03:00
return (
<div ref={element}>
{
!items.length ? (
<div className='noItemsMessage centerMessage'>
<h1>{globalize.translate('MessageNothingHere')}</h1>
<p>{globalize.translate('MessageNoGenresAvailable')}</p>
</div>
) : items.map((item, index) => (
<div key={index} className='verticalSection'>
<div
className='sectionTitleContainer sectionTitleContainer-cards padded-left'
dangerouslySetInnerHTML={createLinkElement({
className: 'more button-flat button-flat-mini sectionTitleTextButton btnMoreFromGenre',
title: escapeHTML(item.Name),
href: appRouter.getRouteUrl(item, {
context: 'movies',
parentId: topParentId
})
})}
/>
{enableScrollX() ?
<ItemsScrollerContainerElement
scrollerclassName='padded-top-focusscale padded-bottom-focusscale'
dataMousewheel='false'
dataCenterfocus='true'
className='itemsContainer scrollSlider focuscontainer-x lazy'
dataId={item.Id}
/> : <ItemsContainerElement
className='itemsContainer vertical-wrap lazy padded-left padded-right'
dataId={item.Id}
/>
}
</div>
))
}
2022-08-06 01:36:13 +03:00
</div>
);
};
export default GenresItemsContainer;