import ButtonWithDropdown from '@app/components/Common/ButtonWithDropdown'; import CachedImage from '@app/components/Common/CachedImage'; import LoadingSpinner from '@app/components/Common/LoadingSpinner'; import PageTitle from '@app/components/Common/PageTitle'; import RequestModal from '@app/components/RequestModal'; import Slider from '@app/components/Slider'; import StatusBadge from '@app/components/StatusBadge'; import TitleCard from '@app/components/TitleCard'; import useSettings from '@app/hooks/useSettings'; import { Permission, useUser } from '@app/hooks/useUser'; import globalMessages from '@app/i18n/globalMessages'; import Error from '@app/pages/_error'; import { DownloadIcon } from '@heroicons/react/outline'; import { MediaStatus } from '@server/constants/media'; import type { Collection } from '@server/models/Collection'; import { uniq } from 'lodash'; import Link from 'next/link'; import { useRouter } from 'next/router'; import { useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import useSWR from 'swr'; const messages = defineMessages({ overview: 'Overview', numberofmovies: '{count} Movies', requestcollection: 'Request Collection', requestcollection4k: 'Request Collection in 4K', }); interface CollectionDetailsProps { collection?: Collection; } const CollectionDetails = ({ collection }: CollectionDetailsProps) => { const intl = useIntl(); const router = useRouter(); const settings = useSettings(); const { hasPermission } = useUser(); const [requestModal, setRequestModal] = useState(false); const [is4k, setIs4k] = useState(false); const { data, error, mutate: revalidate, } = useSWR(`/api/v1/collection/${router.query.collectionId}`, { fallbackData: collection, revalidateOnMount: true, }); const { data: genres } = useSWR<{ id: number; name: string }[]>(`/api/v1/genres/movie`); if (!data && !error) { return ; } if (!data) { return ; } let collectionStatus = MediaStatus.UNKNOWN; let collectionStatus4k = MediaStatus.UNKNOWN; if ( data.parts.every( (part) => part.mediaInfo && part.mediaInfo.status === MediaStatus.AVAILABLE ) ) { collectionStatus = MediaStatus.AVAILABLE; } else if ( data.parts.some( (part) => part.mediaInfo && part.mediaInfo.status === MediaStatus.AVAILABLE ) ) { collectionStatus = MediaStatus.PARTIALLY_AVAILABLE; } if ( data.parts.every( (part) => part.mediaInfo && part.mediaInfo.status4k === MediaStatus.AVAILABLE ) ) { collectionStatus4k = MediaStatus.AVAILABLE; } else if ( data.parts.some( (part) => part.mediaInfo && part.mediaInfo.status4k === MediaStatus.AVAILABLE ) ) { collectionStatus4k = MediaStatus.PARTIALLY_AVAILABLE; } const hasRequestable = hasPermission([Permission.REQUEST, Permission.REQUEST_MOVIE], { type: 'or', }) && data.parts.filter( (part) => !part.mediaInfo || part.mediaInfo.status === MediaStatus.UNKNOWN ).length > 0; const hasRequestable4k = settings.currentSettings.movie4kEnabled && hasPermission([Permission.REQUEST_4K, Permission.REQUEST_4K_MOVIE], { type: 'or', }) && data.parts.filter( (part) => !part.mediaInfo || part.mediaInfo.status4k === MediaStatus.UNKNOWN ).length > 0; const collectionAttributes: React.ReactNode[] = []; collectionAttributes.push( intl.formatMessage(messages.numberofmovies, { count: data.parts.length, }) ); if (genres && data.parts.some((part) => part.genreIds.length)) { collectionAttributes.push( uniq( data.parts.reduce( (genresList: number[], curr) => genresList.concat(curr.genreIds), [] ) ) .map((genreId) => ( {genres.find((g) => g.id === genreId)?.name} )) .reduce((prev, curr) => ( <> {intl.formatMessage(globalMessages.delimitedlist, { a: prev, b: curr, })} )) ); } return (
{data.backdropPath && (
)} { revalidate(); setRequestModal(false); }} onCancel={() => setRequestModal(false)} />
(part.mediaInfo?.downloadStatus ?? []).length > 0 )} /> {settings.currentSettings.movie4kEnabled && hasPermission( [Permission.REQUEST_4K, Permission.REQUEST_4K_MOVIE], { type: 'or', } ) && ( (part.mediaInfo?.downloadStatus4k ?? []).length > 0 )} /> )}

{data.name}

{collectionAttributes.length > 0 && collectionAttributes .map((t, k) => {t}) .reduce((prev, curr) => ( <> {prev} | {curr} ))}
{(hasRequestable || hasRequestable4k) && ( { setRequestModal(true); setIs4k(!hasRequestable); }} text={ <> {intl.formatMessage( hasRequestable ? messages.requestcollection : messages.requestcollection4k )} } > {hasRequestable && hasRequestable4k && ( { setRequestModal(true); setIs4k(true); }} > {intl.formatMessage(messages.requestcollection4k)} )} )}
{data.overview && (

{intl.formatMessage(messages.overview)}

{data.overview}

)}
{intl.formatMessage(globalMessages.movies)}
( ))} />
); }; export default CollectionDetails;