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

@ -1,24 +0,0 @@
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind';
import React, { FC } from 'react';
import ItemsView from '../../components/library/ItemsView';
import { LibraryViewProps } from 'types/library';
import { CollectionType } from 'types/collectionType';
import { LibraryTab } from 'types/libraryTab';
const CollectionsView: FC<LibraryViewProps> = ({ parentId }) => {
return (
<ItemsView
viewType={LibraryTab.Collections}
parentId={parentId}
collectionType={CollectionType.Movies}
isBtnFilterEnabled={false}
isBtnNewCollectionEnabled={true}
isAlphabetPickerEnabled={false}
itemType={[BaseItemKind.BoxSet]}
noItemsMessage='MessageNoCollectionsAvailable'
/>
);
};
export default CollectionsView;

View file

@ -1,19 +0,0 @@
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind';
import React, { FC } from 'react';
import ItemsView from '../../components/library/ItemsView';
import { LibraryViewProps } from 'types/library';
import { LibraryTab } from 'types/libraryTab';
const FavoritesView: FC<LibraryViewProps> = ({ parentId }) => {
return (
<ItemsView
viewType={LibraryTab.Favorites}
parentId={parentId}
itemType={[BaseItemKind.Movie]}
noItemsMessage='MessageNoFavoritesAvailable'
/>
);
};
export default FavoritesView;

View file

@ -1,17 +0,0 @@
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind';
import React, { FC } from 'react';
import GenresItemsContainer from '../../components/library/GenresItemsContainer';
import { LibraryViewProps } from 'types/library';
import { CollectionType } from 'types/collectionType';
const GenresView: FC<LibraryViewProps> = ({ parentId }) => {
return (
<GenresItemsContainer
parentId={parentId}
collectionType={CollectionType.Movies}
itemType={BaseItemKind.Movie}
/>
);
};
export default GenresView;

View file

@ -1,22 +0,0 @@
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind';
import React, { FC } from 'react';
import ItemsView from '../../components/library/ItemsView';
import { LibraryViewProps } from 'types/library';
import { CollectionType } from 'types/collectionType';
import { LibraryTab } from 'types/libraryTab';
const MoviesView: FC<LibraryViewProps> = ({ parentId }) => {
return (
<ItemsView
viewType={LibraryTab.Movies}
parentId={parentId}
collectionType={CollectionType.Movies}
isBtnShuffleEnabled={true}
itemType={[BaseItemKind.Movie]}
noItemsMessage='MessageNoItemsAvailable'
/>
);
};
export default MoviesView;

View file

@ -1,52 +0,0 @@
import React, { FC } from 'react';
import { useGetMovieRecommendations } from 'hooks/useFetchItems';
import globalize from 'scripts/globalize';
import Loading from 'components/loading/LoadingComponent';
import RecommendationContainer from '../../components/library/RecommendationContainer';
import SuggestionsItemsContainer from '../../components/library/SuggestionsItemsContainer';
import { LibraryViewProps } from 'types/library';
import { SectionsView } from 'types/suggestionsSections';
const SuggestionsView: FC<LibraryViewProps> = ({ parentId }) => {
const {
isLoading,
data: movieRecommendationsItems
} = useGetMovieRecommendations(parentId);
if (isLoading) {
return <Loading />;
}
return (
<>
<SuggestionsItemsContainer
parentId={parentId}
sectionsView={[SectionsView.ContinueWatchingMovies, SectionsView.LatestMovies]}
/>
{!movieRecommendationsItems?.length ? (
<div className='noItemsMessage centerMessage'>
<h1>{globalize.translate('MessageNothingHere')}</h1>
<p>
{globalize.translate(
'MessageNoMovieSuggestionsAvailable'
)}
</p>
</div>
) : (
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 SuggestionsView;

View file

@ -1,19 +0,0 @@
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind';
import React, { FC } from 'react';
import ItemsView from '../../components/library/ItemsView';
import { LibraryViewProps } from 'types/library';
import { LibraryTab } from 'types/libraryTab';
const TrailersView: FC<LibraryViewProps> = ({ parentId }) => {
return (
<ItemsView
viewType={LibraryTab.Trailers}
parentId={parentId}
itemType={[BaseItemKind.Trailer]}
noItemsMessage='MessageNoTrailersFound'
/>
);
};
export default TrailersView;

View file

@ -1,55 +1,72 @@
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind';
import React, { FC } from 'react';
import { useLocation, useSearchParams } from 'react-router-dom';
import { getDefaultTabIndex } from '../../components/tabs/tabRoutes';
import useCurrentTab from 'hooks/useCurrentTab';
import Page from 'components/Page';
import CollectionsView from './CollectionsView';
import FavoritesView from './FavoritesView';
import GenresView from './GenresView';
import MoviesView from './MoviesView';
import SuggestionsView from './SuggestionsView';
import TrailersView from './TrailersView';
import PageTabContent from '../../components/library/PageTabContent';
import { LibraryTab } from 'types/libraryTab';
import { CollectionType } from 'types/collectionType';
import { LibraryTabContent, LibraryTabMapping } from 'types/libraryTabContent';
import { SectionsView } from 'types/suggestionsSections';
const moviesTabContent: LibraryTabContent = {
viewType: LibraryTab.Movies,
collectionType: CollectionType.Movies,
isBtnShuffleEnabled: true,
itemType: [BaseItemKind.Movie]
};
const collectionsTabContent: LibraryTabContent = {
viewType: LibraryTab.Collections,
collectionType: CollectionType.Movies,
isBtnFilterEnabled: false,
isBtnNewCollectionEnabled: true,
isAlphabetPickerEnabled: false,
itemType: [BaseItemKind.BoxSet],
noItemsMessage: 'MessageNoCollectionsAvailable'
};
const favoritesTabContent: LibraryTabContent = {
viewType: LibraryTab.Favorites,
collectionType: CollectionType.Movies,
itemType: [BaseItemKind.Movie]
};
const trailersTabContent: LibraryTabContent = {
viewType: LibraryTab.Trailers,
itemType: [BaseItemKind.Trailer],
noItemsMessage: 'MessageNoTrailersFound'
};
const suggestionsTabContent: LibraryTabContent = {
viewType: LibraryTab.Suggestions,
collectionType: CollectionType.Movies,
sectionsType: {
suggestionSectionsView: [
SectionsView.ContinueWatchingMovies,
SectionsView.LatestMovies
],
isMovieRecommendations: true
}
};
const genresTabContent: LibraryTabContent = {
viewType: LibraryTab.Genres,
collectionType: CollectionType.Movies,
itemType: [BaseItemKind.Movie]
};
const moviesTabMapping: LibraryTabMapping = {
0: moviesTabContent,
1: suggestionsTabContent,
2: trailersTabContent,
3: favoritesTabContent,
4: collectionsTabContent,
5: genresTabContent
};
const Movies: FC = () => {
const location = useLocation();
const [ searchParams ] = useSearchParams();
const searchParamsParentId = searchParams.get('topParentId');
const searchParamsTab = searchParams.get('tab');
const currentTabIndex = searchParamsTab !== null ? parseInt(searchParamsTab, 10) :
getDefaultTabIndex(location.pathname, searchParamsParentId);
const getTabComponent = (index: number) => {
if (index == null) {
throw new Error('index cannot be null');
}
let component;
switch (index) {
case 1:
component = <SuggestionsView parentId={searchParamsParentId} />;
break;
case 2:
component = <TrailersView parentId={searchParamsParentId} />;
break;
case 3:
component = <FavoritesView parentId={searchParamsParentId} />;
break;
case 4:
component = <CollectionsView parentId={searchParamsParentId} />;
break;
case 5:
component = <GenresView parentId={searchParamsParentId} />;
break;
default:
component = <MoviesView parentId={searchParamsParentId} />;
}
return component;
};
const { searchParamsParentId, currentTabIndex } = useCurrentTab();
const currentTab = moviesTabMapping[currentTabIndex];
return (
<Page
@ -57,8 +74,11 @@ const Movies: FC = () => {
className='mainAnimatedPage libraryPage backdropPage collectionEditorPage pageWithAbsoluteTabs withTabs'
backDropType='movie'
>
{getTabComponent(currentTabIndex)}
<PageTabContent
key={`${currentTab.viewType} - ${searchParamsParentId}`}
currentTab={currentTab}
parentId={searchParamsParentId}
/>
</Page>
);
};