feat(api): decouple media requests from media info

This commit is contained in:
sct
2020-09-21 00:01:38 +09:00
parent 4aa74319e0
commit 8577db1be1
21 changed files with 409 additions and 264 deletions

View File

@@ -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;

View File

@@ -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}
/>
))}
/>

View File

@@ -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}
/>
))}
/>

View File

@@ -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}
/>
);
};

View File

@@ -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"

View File

@@ -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}
/>
))}
/>