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:
parent
4882d9c8cc
commit
d370afd0b2
17 changed files with 437 additions and 216 deletions
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue