mirror of
https://github.com/sct/overseerr.git
synced 2025-12-31 18:20:13 +01:00
feat(api): decouple media requests from media info
This commit is contained in:
@@ -39,13 +39,12 @@ const ListView: React.FC<ListViewProps> = ({
|
||||
<TitleCard
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
status={title.mediaInfo?.status}
|
||||
summary={title.overview}
|
||||
title={title.title}
|
||||
userScore={title.voteAverage}
|
||||
year={title.releaseDate}
|
||||
mediaType={title.mediaType}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
@@ -54,13 +53,12 @@ const ListView: React.FC<ListViewProps> = ({
|
||||
<TitleCard
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
status={title.mediaInfo?.status}
|
||||
summary={title.overview}
|
||||
title={title.name}
|
||||
userScore={title.voteAverage}
|
||||
year={title.firstAirDate}
|
||||
mediaType={title.mediaType}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -76,8 +76,8 @@ const Discover: React.FC = () => {
|
||||
items={requests?.map((request) => (
|
||||
<RequestCard
|
||||
key={`request-slider-item-${request.id}`}
|
||||
tmdbId={request.mediaId}
|
||||
type={request.mediaType}
|
||||
tmdbId={request.media.tmdbId}
|
||||
type={request.media.mediaType}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
@@ -115,13 +115,12 @@ const Discover: React.FC = () => {
|
||||
key={`popular-movie-slider-${title.id}`}
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
status={title.mediaInfo?.status}
|
||||
summary={title.overview}
|
||||
title={title.title}
|
||||
userScore={title.voteAverage}
|
||||
year={title.releaseDate}
|
||||
mediaType={title.mediaType}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
@@ -159,13 +158,12 @@ const Discover: React.FC = () => {
|
||||
key={`popular-tv-slider-${title.id}`}
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
status={title.mediaInfo?.status}
|
||||
summary={title.overview}
|
||||
title={title.name}
|
||||
userScore={title.voteAverage}
|
||||
year={title.firstAirDate}
|
||||
mediaType={title.mediaType}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
|
||||
@@ -23,6 +23,7 @@ import { LanguageContext } from '../../context/LanguageContext';
|
||||
import LoadingSpinner from '../Common/LoadingSpinner';
|
||||
import { useUser, Permission } from '../../hooks/useUser';
|
||||
import PendingRequest from '../PendingRequest';
|
||||
import { MediaStatus } from '../../../server/constants/media';
|
||||
|
||||
const messages = defineMessages({
|
||||
releasedate: 'Release Date',
|
||||
@@ -101,13 +102,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
};
|
||||
|
||||
const cancelRequest = async () => {
|
||||
const response = await axios.delete<MediaRequest>(
|
||||
`/api/v1/request/${data?.request?.id}`
|
||||
);
|
||||
|
||||
if (response.data.id) {
|
||||
revalidate();
|
||||
}
|
||||
// fix this
|
||||
};
|
||||
|
||||
if (!data && !error) {
|
||||
@@ -167,7 +162,8 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1 flex justify-end mt-4 md:mt-0">
|
||||
{!data.request && (
|
||||
{(!data.mediaInfo ||
|
||||
data.mediaInfo?.status === MediaStatus.UNKNOWN) && (
|
||||
<Button
|
||||
buttonType="primary"
|
||||
onClick={() => setShowRequestModal(true)}
|
||||
@@ -189,14 +185,8 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
<FormattedMessage {...messages.request} />
|
||||
</Button>
|
||||
)}
|
||||
{data.request?.status === MediaRequestStatus.PENDING && (
|
||||
<Button
|
||||
buttonType="warning"
|
||||
onClick={() => {
|
||||
if (data.request?.requestedBy.id === user?.id)
|
||||
setShowCancelModal(true);
|
||||
}}
|
||||
>
|
||||
{data.mediaInfo?.status === MediaStatus.PENDING && (
|
||||
<Button buttonType="warning">
|
||||
<svg
|
||||
className="w-4 mr-2"
|
||||
fill="none"
|
||||
@@ -211,12 +201,10 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
|
||||
/>
|
||||
</svg>
|
||||
{data.request?.requestedBy.id === user?.id
|
||||
? intl.formatMessage(messages.cancelrequest)
|
||||
: intl.formatMessage(messages.pending)}
|
||||
<FormattedMessage {...messages.pending} />
|
||||
</Button>
|
||||
)}
|
||||
{data.request?.status === MediaRequestStatus.APPROVED && (
|
||||
{data.mediaInfo?.status === MediaStatus.PROCESSING && (
|
||||
<Button buttonType="danger">
|
||||
<svg
|
||||
className="w-5 mr-1"
|
||||
@@ -235,7 +223,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
<FormattedMessage {...messages.unavailable} />
|
||||
</Button>
|
||||
)}
|
||||
{data.request?.status === MediaRequestStatus.AVAILABLE && (
|
||||
{data.mediaInfo?.status === MediaStatus.AVAILABLE && (
|
||||
<Button buttonType="success">
|
||||
<svg
|
||||
className="w-5 mr-1"
|
||||
@@ -300,13 +288,13 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
</div>
|
||||
<div className="flex pt-8 text-white flex-col md:flex-row pb-4">
|
||||
<div className="flex-1 md:mr-8">
|
||||
{data.request?.status === MediaRequestStatus.PENDING &&
|
||||
{/* {data.mediaInfo?.status === MediaStatus.PENDING &&
|
||||
hasPermission(Permission.MANAGE_REQUESTS) && (
|
||||
<PendingRequest
|
||||
request={data.request}
|
||||
onUpdate={() => revalidate()}
|
||||
/>
|
||||
)}
|
||||
)} */}
|
||||
<h2 className="text-xl md:text-2xl">
|
||||
<FormattedMessage {...messages.overview} />
|
||||
</h2>
|
||||
@@ -463,13 +451,12 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
key={`recommended-${title.id}`}
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
status={title.mediaInfo?.status}
|
||||
summary={title.overview}
|
||||
title={title.title}
|
||||
userScore={title.voteAverage}
|
||||
year={title.releaseDate}
|
||||
mediaType={title.mediaType}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
@@ -510,13 +497,12 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
key={`recommended-${title.id}`}
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
status={title.mediaInfo?.status}
|
||||
summary={title.overview}
|
||||
title={title.title}
|
||||
userScore={title.voteAverage}
|
||||
year={title.releaseDate}
|
||||
mediaType={title.mediaType}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
|
||||
@@ -34,25 +34,23 @@ const RequestCard: React.FC<TmdbTitleCardProps> = ({ tmdbId, type }) => {
|
||||
<TitleCard
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
status={title.mediaInfo?.status}
|
||||
summary={title.overview}
|
||||
title={title.title}
|
||||
userScore={title.voteAverage}
|
||||
year={title.releaseDate}
|
||||
mediaType={'movie'}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
) : (
|
||||
<TitleCard
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
status={title.mediaInfo?.status}
|
||||
summary={title.overview}
|
||||
title={title.name}
|
||||
userScore={title.voteAverage}
|
||||
year={title.firstAirDate}
|
||||
mediaType={'tv'}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@ import axios from 'axios';
|
||||
import { MediaRequest } from '../../../server/entity/MediaRequest';
|
||||
import MovieRequestModal from '../RequestModal/MovieRequestModal';
|
||||
import Link from 'next/link';
|
||||
import { MediaStatus } from '../../../server/constants/media';
|
||||
|
||||
interface TitleCardProps {
|
||||
id: number;
|
||||
@@ -20,17 +21,10 @@ interface TitleCardProps {
|
||||
title: string;
|
||||
userScore: number;
|
||||
mediaType: MediaType;
|
||||
status?: MediaRequestStatus;
|
||||
status?: MediaStatus;
|
||||
requestId?: number;
|
||||
}
|
||||
|
||||
enum MediaRequestStatus {
|
||||
PENDING = 1,
|
||||
APPROVED,
|
||||
DECLINED,
|
||||
AVAILABLE,
|
||||
}
|
||||
|
||||
const TitleCard: React.FC<TitleCardProps> = ({
|
||||
id,
|
||||
image,
|
||||
@@ -56,7 +50,7 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
||||
});
|
||||
|
||||
if (response.data) {
|
||||
setCurrentStatus(response.data.status);
|
||||
setCurrentStatus(response.data.media.status);
|
||||
addToast(
|
||||
<span>
|
||||
<strong>{title}</strong> succesfully requested!
|
||||
@@ -131,13 +125,13 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
||||
right: '-1px',
|
||||
}}
|
||||
>
|
||||
{currentStatus === MediaRequestStatus.AVAILABLE && (
|
||||
{currentStatus === MediaStatus.AVAILABLE && (
|
||||
<Available className="rounded-tr-md" />
|
||||
)}
|
||||
{currentStatus === MediaRequestStatus.PENDING && (
|
||||
{currentStatus === MediaStatus.PENDING && (
|
||||
<Requested className="rounded-tr-md" />
|
||||
)}
|
||||
{currentStatus === MediaRequestStatus.APPROVED && (
|
||||
{currentStatus === MediaStatus.PROCESSING && (
|
||||
<Unavailable className="rounded-tr-md" />
|
||||
)}
|
||||
</div>
|
||||
@@ -251,7 +245,7 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
{currentStatus === MediaRequestStatus.PENDING && (
|
||||
{currentStatus === MediaStatus.PENDING && (
|
||||
<button
|
||||
onClick={() => setShowCancelModal(true)}
|
||||
className="w-full h-7 text-center text-white bg-orange-400 hover:bg-orange-300 rounded-sm ml-1 focus:border-orange-700 focus:shadow-outline-orange active:bg-orange-700 transition ease-in-out duration-150"
|
||||
@@ -272,7 +266,7 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
{currentStatus === MediaRequestStatus.APPROVED && (
|
||||
{currentStatus === MediaStatus.AVAILABLE && (
|
||||
<button className="w-full h-7 text-center text-white bg-red-500 rounded-sm ml-1">
|
||||
<svg
|
||||
className="w-4 mx-auto"
|
||||
@@ -290,7 +284,7 @@ const TitleCard: React.FC<TitleCardProps> = ({
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
{currentStatus === MediaRequestStatus.AVAILABLE && (
|
||||
{currentStatus === MediaStatus.AVAILABLE && (
|
||||
<button className="w-full h-7 text-center text-white bg-green-400 rounded-sm ml-1">
|
||||
<svg
|
||||
className="w-4 mx-auto"
|
||||
|
||||
@@ -17,6 +17,7 @@ import LoadingSpinner from '../Common/LoadingSpinner';
|
||||
import { useUser, Permission } from '../../hooks/useUser';
|
||||
import PendingRequest from '../PendingRequest';
|
||||
import { TvDetails as TvDetailsType } from '../../../server/models/Tv';
|
||||
import { MediaStatus } from '../../../server/constants/media';
|
||||
|
||||
const messages = defineMessages({
|
||||
userrating: 'User Rating',
|
||||
@@ -76,7 +77,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
const request = async () => {
|
||||
const response = await axios.post<MediaRequest>('/api/v1/request', {
|
||||
mediaId: data?.id,
|
||||
mediaType: 'movie',
|
||||
mediaType: 'tv',
|
||||
});
|
||||
|
||||
if (response.data) {
|
||||
@@ -91,13 +92,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
};
|
||||
|
||||
const cancelRequest = async () => {
|
||||
const response = await axios.delete<MediaRequest>(
|
||||
`/api/v1/request/${data?.request?.id}`
|
||||
);
|
||||
|
||||
if (response.data.id) {
|
||||
revalidate();
|
||||
}
|
||||
// fix me
|
||||
};
|
||||
|
||||
if (!data && !error) {
|
||||
@@ -148,7 +143,8 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-1 flex justify-end mt-4 md:mt-0">
|
||||
{!data.request && (
|
||||
{(!data.mediaInfo ||
|
||||
data.mediaInfo.status === MediaStatus.UNKNOWN) && (
|
||||
<Button
|
||||
buttonType="primary"
|
||||
onClick={() => setShowRequestModal(true)}
|
||||
@@ -170,14 +166,8 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
<FormattedMessage {...messages.request} />
|
||||
</Button>
|
||||
)}
|
||||
{data.request?.status === MediaRequestStatus.PENDING && (
|
||||
<Button
|
||||
buttonType="warning"
|
||||
onClick={() => {
|
||||
if (data.request?.requestedBy.id === user?.id)
|
||||
setShowCancelModal(true);
|
||||
}}
|
||||
>
|
||||
{data.mediaInfo?.status === MediaStatus.PENDING && (
|
||||
<Button buttonType="warning">
|
||||
<svg
|
||||
className="w-4 mr-2"
|
||||
fill="none"
|
||||
@@ -192,12 +182,10 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
|
||||
/>
|
||||
</svg>
|
||||
{data.request?.requestedBy.id === user?.id
|
||||
? intl.formatMessage(messages.cancelrequest)
|
||||
: intl.formatMessage(messages.pending)}
|
||||
<FormattedMessage {...messages.pending} />
|
||||
</Button>
|
||||
)}
|
||||
{data.request?.status === MediaRequestStatus.APPROVED && (
|
||||
{data.mediaInfo?.status === MediaStatus.PROCESSING && (
|
||||
<Button buttonType="danger">
|
||||
<svg
|
||||
className="w-5 mr-1"
|
||||
@@ -216,7 +204,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
<FormattedMessage {...messages.unavailable} />
|
||||
</Button>
|
||||
)}
|
||||
{data.request?.status === MediaRequestStatus.AVAILABLE && (
|
||||
{data.mediaInfo?.status === MediaStatus.AVAILABLE && (
|
||||
<Button buttonType="success">
|
||||
<svg
|
||||
className="w-5 mr-1"
|
||||
@@ -281,13 +269,13 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
</div>
|
||||
<div className="flex pt-8 text-white flex-col md:flex-row pb-4">
|
||||
<div className="flex-1 md:mr-8">
|
||||
{data.request?.status === MediaRequestStatus.PENDING &&
|
||||
{/* {data.mediaInfo?.status === MediaStatus.PENDING &&
|
||||
hasPermission(Permission.MANAGE_REQUESTS) && (
|
||||
<PendingRequest
|
||||
request={data.request}
|
||||
onUpdate={() => revalidate()}
|
||||
/>
|
||||
)}
|
||||
)} */}
|
||||
<h2 className="text-xl md:text-2xl">
|
||||
<FormattedMessage {...messages.overview} />
|
||||
</h2>
|
||||
@@ -403,13 +391,12 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
key={`recommended-${title.id}`}
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
status={title.mediaInfo?.status}
|
||||
summary={title.overview}
|
||||
title={title.name}
|
||||
userScore={title.voteAverage}
|
||||
year={title.firstAirDate}
|
||||
mediaType={title.mediaType}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
@@ -447,13 +434,12 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
key={`recommended-${title.id}`}
|
||||
id={title.id}
|
||||
image={title.posterPath}
|
||||
status={title.request?.status}
|
||||
status={title.mediaInfo?.status}
|
||||
summary={title.overview}
|
||||
title={title.name}
|
||||
userScore={title.voteAverage}
|
||||
year={title.firstAirDate}
|
||||
mediaType={title.mediaType}
|
||||
requestId={title.request?.id}
|
||||
/>
|
||||
))}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user