fix: filter specials from modal all seasons and watchlist (#4108)

* fix: filter specials from modal all seasons and watchlist

* fix: skip specials when marking available

* fix: edge case where specials were marked as completed
This commit is contained in:
Brandon Cohen
2025-04-19 19:30:58 -05:00
committed by GitHub
parent 208d31180c
commit 7f868f38e6
5 changed files with 59 additions and 53 deletions

View File

@@ -247,7 +247,9 @@ export class MediaRequest {
>; >;
const requestedSeasons = const requestedSeasons =
requestBody.seasons === 'all' requestBody.seasons === 'all'
? tmdbMediaShow.seasons.map((season) => season.season_number) ? tmdbMediaShow.seasons
.filter((season) => season.season_number !== 0)
.map((season) => season.season_number)
: (requestBody.seasons as number[]); : (requestBody.seasons as number[]);
let existingSeasons: number[] = []; let existingSeasons: number[] = [];

View File

@@ -69,11 +69,7 @@ export class MediaRequestSubscriber
availableSeasons.length > 0 && availableSeasons.length > 0 &&
availableSeasons.length === requestedSeasons.length; availableSeasons.length === requestedSeasons.length;
if ( if (isMediaAvailable) {
entity.media[entity.is4k ? 'status4k' : 'status'] ===
MediaStatus.AVAILABLE ||
isMediaAvailable
) {
const tmdb = new TheMovieDb(); const tmdb = new TheMovieDb();
try { try {

View File

@@ -55,57 +55,59 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
if (relatedRequests.length > 0) { if (relatedRequests.length > 0) {
const completedRequests: MediaRequest[] = []; const completedRequests: MediaRequest[] = [];
relatedRequests.forEach((request) => { for (const request of relatedRequests) {
let shouldComplete = false; let shouldComplete = false;
if ( if (
event[request.is4k ? 'status4k' : 'status'] === (event[request.is4k ? 'status4k' : 'status'] ===
MediaStatus.AVAILABLE || MediaStatus.AVAILABLE ||
event[request.is4k ? 'status4k' : 'status'] === MediaStatus.DELETED event[request.is4k ? 'status4k' : 'status'] ===
MediaStatus.DELETED) &&
event.mediaType === MediaType.MOVIE
) { ) {
shouldComplete = true; shouldComplete = true;
} else if (event.mediaType === 'tv') { } else if (event.mediaType === 'tv') {
// For TV, check if all requested seasons are available or deleted const allSeasonResults = await Promise.all(
const allSeasonsReady = request.seasons.every((requestSeason) => { request.seasons.map(async (requestSeason) => {
const matchingSeason = event.seasons.find( const matchingSeason = event.seasons.find(
(mediaSeason) => (mediaSeason) =>
mediaSeason.seasonNumber === requestSeason.seasonNumber mediaSeason.seasonNumber === requestSeason.seasonNumber
); );
const matchingOldSeason = databaseEvent.seasons.find( const matchingOldSeason = databaseEvent.seasons.find(
(oldSeason) => (oldSeason) =>
oldSeason.seasonNumber === requestSeason.seasonNumber oldSeason.seasonNumber === requestSeason.seasonNumber
); );
if (!matchingSeason) {
return false;
}
const currentSeasonStatus =
matchingSeason[request.is4k ? 'status4k' : 'status'];
const previousSeasonStatus =
matchingOldSeason?.[request.is4k ? 'status4k' : 'status'];
const hasStatusChanged =
currentSeasonStatus !== previousSeasonStatus;
const shouldUpdate =
(hasStatusChanged ||
requestSeason.status === MediaRequestStatus.COMPLETED) &&
(currentSeasonStatus === MediaStatus.AVAILABLE ||
currentSeasonStatus === MediaStatus.DELETED);
if (shouldUpdate) {
requestSeason.status = MediaRequestStatus.COMPLETED;
await seasonRequestRepository.save(requestSeason);
return true;
}
if (!matchingSeason) {
return false; return false;
} })
);
const currentSeasonStatus =
matchingSeason[request.is4k ? 'status4k' : 'status'];
const previousSeasonStatus =
matchingOldSeason?.[request.is4k ? 'status4k' : 'status'];
const hasStatusChanged =
currentSeasonStatus !== previousSeasonStatus;
const shouldUpdate =
(hasStatusChanged ||
requestSeason.status === MediaRequestStatus.COMPLETED) &&
(currentSeasonStatus === MediaStatus.AVAILABLE ||
currentSeasonStatus === MediaStatus.DELETED);
if (shouldUpdate) {
// Handle season requests and mark them completed when
// that specific season becomes available
seasonRequestRepository.update(requestSeason.id, {
status: MediaRequestStatus.COMPLETED,
});
return true;
}
return false;
});
const allSeasonsReady = allSeasonResults.every((result) => result);
shouldComplete = allSeasonsReady; shouldComplete = allSeasonsReady;
} }
@@ -113,7 +115,7 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
request.status = MediaRequestStatus.COMPLETED; request.status = MediaRequestStatus.COMPLETED;
completedRequests.push(request); completedRequests.push(request);
} }
}); }
await requestRepository.save(completedRequests); await requestRepository.save(completedRequests);
} }

View File

@@ -96,7 +96,9 @@ const ManageSlideOver = ({
if (data.mediaInfo) { if (data.mediaInfo) {
await axios.post(`/api/v1/media/${data.mediaInfo?.id}/available`, { await axios.post(`/api/v1/media/${data.mediaInfo?.id}/available`, {
is4k, is4k,
...(mediaType === 'tv' && { seasons: data.seasons }), ...(mediaType === 'tv' && {
seasons: data.seasons.filter((season) => season.seasonNumber !== 0),
}),
}); });
revalidate(); revalidate();
} }

View File

@@ -309,12 +309,16 @@ const TvRequestModal = ({
return; return;
} }
const standardUnrequestedSeasons = unrequestedSeasons.filter(
(seasonNumber) => seasonNumber !== 0
);
if ( if (
data && data &&
selectedSeasons.length >= 0 && selectedSeasons.length >= 0 &&
selectedSeasons.length < unrequestedSeasons.length selectedSeasons.length < standardUnrequestedSeasons.length
) { ) {
setSelectedSeasons(unrequestedSeasons); setSelectedSeasons(standardUnrequestedSeasons);
} else { } else {
setSelectedSeasons([]); setSelectedSeasons([]);
} }
@@ -325,9 +329,9 @@ const TvRequestModal = ({
return false; return false;
} }
return ( return (
selectedSeasons.length === selectedSeasons.filter((season) => season !== 0).length ===
getAllSeasons().filter( getAllSeasons().filter(
(season) => !getAllRequestedSeasons().includes(season) (season) => !getAllRequestedSeasons().includes(season) && season !== 0
).length ).length
); );
}; };