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

refactor: extract reusable component

This commit is contained in:
grafixeyehero 2023-10-26 02:05:08 +03:00
parent 4882d9c8cc
commit d370afd0b2
17 changed files with 437 additions and 216 deletions

View file

@ -9,8 +9,8 @@ import { ParentId } from 'types/library';
interface GenresItemsContainerProps {
parentId: ParentId;
collectionType: CollectionType;
itemType: BaseItemKind;
collectionType: CollectionType | undefined;
itemType: BaseItemKind[];
}
const GenresItemsContainer: FC<GenresItemsContainerProps> = ({

View file

@ -16,8 +16,8 @@ import { ParentId } from 'types/library';
interface GenresSectionContainerProps {
parentId: ParentId;
collectionType: CollectionType;
itemType: BaseItemKind;
collectionType: CollectionType | undefined;
itemType: BaseItemKind[];
genre: BaseItemDto;
}
@ -31,7 +31,7 @@ const GenresSectionContainer: FC<GenresSectionContainerProps> = ({
return {
sortBy: [ItemSortBy.Random],
sortOrder: [SortOrder.Ascending],
includeItemTypes: [itemType],
includeItemTypes: itemType,
recursive: true,
fields: [
ItemFields.PrimaryImageAspectRatio,
@ -70,9 +70,9 @@ const GenresSectionContainer: FC<GenresSectionContainerProps> = ({
showTitle: true,
centerText: true,
cardLayout: false,
shape: itemType === BaseItemKind.MusicAlbum ? 'overflowSquare' : 'overflowPortrait',
showParentTitle: itemType === BaseItemKind.MusicAlbum,
showYear: itemType !== BaseItemKind.MusicAlbum
shape: collectionType === CollectionType.Music ? 'overflowSquare' : 'overflowPortrait',
showParentTitle: collectionType === CollectionType.Music,
showYear: collectionType !== CollectionType.Music
}}
/>;
};

View file

@ -0,0 +1,23 @@
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind';
import React, { FC } from 'react';
import GenresItemsContainer from './GenresItemsContainer';
import { ParentId } from 'types/library';
import { CollectionType } from 'types/collectionType';
interface GenresViewProps {
parentId: ParentId;
collectionType: CollectionType | undefined;
itemType: BaseItemKind[];
}
const GenresView: FC<GenresViewProps> = ({ parentId, collectionType, itemType }) => {
return (
<GenresItemsContainer
parentId={parentId}
collectionType={collectionType}
itemType={itemType}
/>
);
};
export default GenresView;

View file

@ -0,0 +1,65 @@
import React, { FC } from 'react';
import SuggestionsView from './SuggestionsView';
import UpcomingView from './UpcomingView';
import GenresView from './GenresView';
import ItemsView from './ItemsView';
import { LibraryTab } from 'types/libraryTab';
import { ParentId } from 'types/library';
import { LibraryTabContent } from 'types/libraryTabContent';
interface PageTabContentProps {
parentId: ParentId;
currentTab: LibraryTabContent;
}
const PageTabContent: FC<PageTabContentProps> = ({ parentId, currentTab }) => {
if (currentTab.viewType === LibraryTab.Suggestions) {
return (
<SuggestionsView
parentId={parentId}
suggestionSectionViews={
currentTab.sectionsType?.suggestionSectionsView
}
isMovieRecommendations={
currentTab.sectionsType?.isMovieRecommendations
}
/>
);
}
if (currentTab.viewType === LibraryTab.Upcoming) {
return <UpcomingView parentId={parentId} />;
}
if (currentTab.viewType === LibraryTab.Genres) {
return (
<GenresView
parentId={parentId}
collectionType={currentTab.collectionType}
itemType={currentTab.itemType || []}
/>
);
}
return (
<ItemsView
viewType={currentTab.viewType}
parentId={parentId}
collectionType={currentTab.collectionType}
isBtnPlayAllEnabled={currentTab.isBtnPlayAllEnabled}
isBtnQueueEnabled={currentTab.isBtnQueueEnabled}
isBtnShuffleEnabled={currentTab.isBtnShuffleEnabled}
isBtnNewCollectionEnabled={currentTab.isBtnNewCollectionEnabled}
isBtnFilterEnabled={currentTab.isBtnFilterEnabled}
isBtnGridListEnabled={currentTab.isBtnGridListEnabled}
isBtnSortEnabled={currentTab.isBtnSortEnabled}
isAlphabetPickerEnabled={currentTab.isAlphabetPickerEnabled}
itemType={currentTab.itemType || []}
noItemsMessage={
currentTab.noItemsMessage || 'MessageNoItemsAvailable'
}
/>
);
};
export default PageTabContent;

View file

@ -0,0 +1,46 @@
import React, { FC } from 'react';
import { useGetMovieRecommendations } from 'hooks/useFetchItems';
import Loading from 'components/loading/LoadingComponent';
import globalize from 'scripts/globalize';
import RecommendationContainer from './RecommendationContainer';
import { ParentId } from 'types/library';
interface RecommendationItemsContainerProps {
parentId?: ParentId;
}
const RecommendationItemsContainer: FC<RecommendationItemsContainerProps> = ({
parentId
}) => {
const { isLoading, data: movieRecommendationsItems } =
useGetMovieRecommendations(parentId);
if (isLoading) return <Loading />;
if (!movieRecommendationsItems?.length) {
return (
<div className='noItemsMessage centerMessage'>
<h1>{globalize.translate('MessageNothingHere')}</h1>
<p>
{globalize.translate('MessageNoMovieSuggestionsAvailable')}
</p>
</div>
);
}
return (
<>
{movieRecommendationsItems.map((recommendation, index) => {
return (
<RecommendationContainer
// eslint-disable-next-line react/no-array-index-key
key={`${recommendation.CategoryId}-${index}`} // use a unique id return value may have duplicate id
recommendation={recommendation}
/>
);
})}
</>
);
};
export default RecommendationItemsContainer;

View file

@ -0,0 +1,33 @@
import React, { FC } from 'react';
import { Box } from '@mui/material';
import SuggestionsItemsContainer from './SuggestionsItemsContainer';
import RecommendationItemsContainer from './RecommendationItemsContainer';
import { ParentId } from 'types/library';
import { SectionsView } from 'types/suggestionsSections';
interface SuggestionsViewProps {
parentId: ParentId;
suggestionSectionViews: SectionsView[] | undefined;
isMovieRecommendations: boolean | undefined;
}
const SuggestionsView: FC<SuggestionsViewProps> = ({
parentId,
suggestionSectionViews = [],
isMovieRecommendations = false
}) => {
return (
<Box>
<SuggestionsItemsContainer
parentId={parentId}
sectionsView={suggestionSectionViews}
/>
{isMovieRecommendations && (
<RecommendationItemsContainer parentId={parentId} />
)}
</Box>
);
};
export default SuggestionsView;

View file

@ -0,0 +1,48 @@
import React, { FC } from 'react';
import Box from '@mui/material/Box';
import { useGetGroupsUpcomingEpisodes } from 'hooks/useFetchItems';
import Loading from 'components/loading/LoadingComponent';
import globalize from 'scripts/globalize';
import SectionContainer from './SectionContainer';
import { LibraryViewProps } from 'types/library';
const UpcomingView: FC<LibraryViewProps> = ({ parentId }) => {
const { isLoading, data: groupsUpcomingEpisodes } = useGetGroupsUpcomingEpisodes(parentId);
if (isLoading) return <Loading />;
return (
<Box>
{!groupsUpcomingEpisodes?.length ? (
<div className='noItemsMessage centerMessage'>
<h1>{globalize.translate('MessageNothingHere')}</h1>
<p>
{globalize.translate(
'MessagePleaseEnsureInternetMetadata'
)}
</p>
</div>
) : (
groupsUpcomingEpisodes?.map((group) => (
<SectionContainer
key={group.name}
sectionTitle={group.name}
items={group.items ?? []}
cardOptions={{
shape: 'overflowBackdrop',
showLocationTypeIndicator: false,
showParentTitle: true,
preferThumb: true,
lazy: true,
showDetailsMenu: true,
missingIndicator: false,
cardLayout: false
}}
/>
))
)}
</Box>
);
};
export default UpcomingView;