You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.9 KiB
133 lines
3.9 KiB
import PersonCard from '@app/components/PersonCard';
|
|
import TitleCard from '@app/components/TitleCard';
|
|
import TmdbTitleCard from '@app/components/TitleCard/TmdbTitleCard';
|
|
import useVerticalScroll from '@app/hooks/useVerticalScroll';
|
|
import globalMessages from '@app/i18n/globalMessages';
|
|
import type { WatchlistItem } from '@server/interfaces/api/discoverInterfaces';
|
|
import type {
|
|
CollectionResult,
|
|
MovieResult,
|
|
PersonResult,
|
|
TvResult,
|
|
} from '@server/models/Search';
|
|
import { useIntl } from 'react-intl';
|
|
|
|
type ListViewProps = {
|
|
items?: (TvResult | MovieResult | PersonResult | CollectionResult)[];
|
|
plexItems?: WatchlistItem[];
|
|
isEmpty?: boolean;
|
|
isLoading?: boolean;
|
|
isReachingEnd?: boolean;
|
|
onScrollBottom: () => void;
|
|
};
|
|
|
|
const ListView = ({
|
|
items,
|
|
isEmpty,
|
|
isLoading,
|
|
onScrollBottom,
|
|
isReachingEnd,
|
|
plexItems,
|
|
}: ListViewProps) => {
|
|
const intl = useIntl();
|
|
useVerticalScroll(onScrollBottom, !isLoading && !isEmpty && !isReachingEnd);
|
|
return (
|
|
<>
|
|
{isEmpty && (
|
|
<div className="mt-64 w-full text-center text-2xl text-gray-400">
|
|
{intl.formatMessage(globalMessages.noresults)}
|
|
</div>
|
|
)}
|
|
<ul className="cards-vertical">
|
|
{plexItems?.map((title, index) => {
|
|
return (
|
|
<li key={`${title.ratingKey}-${index}`}>
|
|
<TmdbTitleCard
|
|
id={title.tmdbId}
|
|
tmdbId={title.tmdbId}
|
|
type={title.mediaType}
|
|
canExpand
|
|
/>
|
|
</li>
|
|
);
|
|
})}
|
|
{items?.map((title, index) => {
|
|
let titleCard: React.ReactNode;
|
|
|
|
switch (title.mediaType) {
|
|
case 'movie':
|
|
titleCard = (
|
|
<TitleCard
|
|
id={title.id}
|
|
image={title.posterPath}
|
|
status={title.mediaInfo?.status}
|
|
summary={title.overview}
|
|
title={title.title}
|
|
userScore={title.voteAverage}
|
|
year={title.releaseDate}
|
|
mediaType={title.mediaType}
|
|
inProgress={
|
|
(title.mediaInfo?.downloadStatus ?? []).length > 0
|
|
}
|
|
canExpand
|
|
/>
|
|
);
|
|
break;
|
|
case 'tv':
|
|
titleCard = (
|
|
<TitleCard
|
|
id={title.id}
|
|
image={title.posterPath}
|
|
status={title.mediaInfo?.status}
|
|
summary={title.overview}
|
|
title={title.name}
|
|
userScore={title.voteAverage}
|
|
year={title.firstAirDate}
|
|
mediaType={title.mediaType}
|
|
inProgress={
|
|
(title.mediaInfo?.downloadStatus ?? []).length > 0
|
|
}
|
|
canExpand
|
|
/>
|
|
);
|
|
break;
|
|
case 'collection':
|
|
titleCard = (
|
|
<TitleCard
|
|
id={title.id}
|
|
image={title.posterPath}
|
|
summary={title.overview}
|
|
title={title.title}
|
|
mediaType={title.mediaType}
|
|
canExpand
|
|
/>
|
|
);
|
|
break;
|
|
case 'person':
|
|
titleCard = (
|
|
<PersonCard
|
|
personId={title.id}
|
|
name={title.name}
|
|
profilePath={title.profilePath}
|
|
canExpand
|
|
/>
|
|
);
|
|
break;
|
|
}
|
|
|
|
return <li key={`${title.id}-${index}`}>{titleCard}</li>;
|
|
})}
|
|
{isLoading &&
|
|
!isReachingEnd &&
|
|
[...Array(20)].map((_item, i) => (
|
|
<li key={`placeholder-${i}`}>
|
|
<TitleCard.Placeholder canExpand />
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default ListView;
|