1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00
jellyfin-web/src/apps/experimental/components/library/SuggestionsSectionView.tsx

142 lines
5.1 KiB
TypeScript
Raw Normal View History

import type { RecommendationDto } from '@jellyfin/sdk/lib/generated-client/models/recommendation-dto';
import { RecommendationType } from '@jellyfin/sdk/lib/generated-client/models/recommendation-type';
import React, { type FC } from 'react';
2024-01-12 21:08:06 +03:00
import {
useGetMovieRecommendations,
useGetSuggestionSectionsWithItems
} from 'hooks/useFetchItems';
import { appRouter } from 'components/router/appRouter';
2024-08-14 13:31:34 -04:00
import globalize from 'lib/globalize';
2024-01-12 21:08:06 +03:00
import Loading from 'components/loading/LoadingComponent';
2024-09-23 02:53:44 +03:00
import NoItemsMessage from 'components/common/NoItemsMessage';
import SectionContainer from '../../../../components/common/SectionContainer';
import { CardShape } from 'utils/card';
import type { ParentId } from 'types/library';
import type { Section, SectionType } from 'types/sections';
import type { ItemDto } from 'types/base/models/item-dto';
2024-01-12 21:08:06 +03:00
interface SuggestionsSectionViewProps {
parentId: ParentId;
sectionType: SectionType[];
isMovieRecommendationEnabled: boolean | undefined;
}
const SuggestionsSectionView: FC<SuggestionsSectionViewProps> = ({
parentId,
sectionType,
isMovieRecommendationEnabled = false
}) => {
const { isLoading, data: sectionsWithItems } =
useGetSuggestionSectionsWithItems(parentId, sectionType);
const {
isLoading: isRecommendationsLoading,
data: movieRecommendationsItems
} = useGetMovieRecommendations(isMovieRecommendationEnabled, parentId);
if (isLoading || isRecommendationsLoading) {
return <Loading />;
}
if (!sectionsWithItems?.length && !movieRecommendationsItems?.length) {
2024-09-23 02:53:44 +03:00
return <NoItemsMessage />;
2024-01-12 21:08:06 +03:00
}
const getRouteUrl = (section: Section) => {
return appRouter.getRouteUrl('list', {
serverId: window.ApiClient.serverId(),
itemTypes: section.itemTypes,
parentId: parentId
});
};
const getRecommendationTittle = (recommendation: RecommendationDto) => {
let title = '';
switch (recommendation.RecommendationType) {
case RecommendationType.SimilarToRecentlyPlayed:
title = globalize.translate(
'RecommendationBecauseYouWatched',
recommendation.BaselineItemName
);
break;
case RecommendationType.SimilarToLikedItem:
title = globalize.translate(
'RecommendationBecauseYouLike',
recommendation.BaselineItemName
);
break;
case RecommendationType.HasDirectorFromRecentlyPlayed:
case RecommendationType.HasLikedDirector:
title = globalize.translate(
'RecommendationDirectedBy',
recommendation.BaselineItemName
);
break;
case RecommendationType.HasActorFromRecentlyPlayed:
case RecommendationType.HasLikedActor:
title = globalize.translate(
'RecommendationStarring',
recommendation.BaselineItemName
);
break;
}
return title;
2024-01-12 21:08:06 +03:00
};
return (
<>
{sectionsWithItems?.map(({ section, items }) => (
<SectionContainer
key={section.type}
2024-09-23 02:53:44 +03:00
sectionHeaderProps={{
title: globalize.translate(section.name),
url: getRouteUrl(section)
}}
itemsContainerProps={{
queryKey: ['SuggestionSectionWithItems']
}}
items={items}
2024-01-12 21:08:06 +03:00
cardOptions={{
...section.cardOptions,
queryKey: ['SuggestionSectionWithItems'],
2024-01-12 21:08:06 +03:00
showTitle: true,
centerText: true,
cardLayout: false,
overlayText: false
}}
/>
))}
{movieRecommendationsItems?.map((recommendation, index) => (
<SectionContainer
// eslint-disable-next-line react/no-array-index-key
key={`${recommendation.CategoryId}-${index}`} // use a unique id return value may have duplicate id
2024-09-23 02:53:44 +03:00
sectionHeaderProps={{
title: getRecommendationTittle(recommendation)
}}
itemsContainerProps={{
queryKey: ['MovieRecommendations']
}}
items={recommendation.Items as ItemDto[]}
2024-01-12 21:08:06 +03:00
cardOptions={{
queryKey: ['MovieRecommendations'],
shape: CardShape.PortraitOverflow,
2024-01-12 21:08:06 +03:00
showYear: true,
scalable: true,
overlayPlayButton: true,
showTitle: true,
centerText: true,
cardLayout: false
}}
/>
))}
</>
);
};
export default SuggestionsSectionView;