diff --git a/overseerr-api.yml b/overseerr-api.yml index c4c1e97b7..e23b97c36 100644 --- a/overseerr-api.yml +++ b/overseerr-api.yml @@ -5018,7 +5018,7 @@ paths: - type: array items: type: number - minimum: 1 + minimum: 0 - type: string enum: [all] is4k: @@ -5124,7 +5124,7 @@ paths: type: array items: type: number - minimum: 1 + minimum: 0 is4k: type: boolean example: false diff --git a/server/entity/MediaRequest.ts b/server/entity/MediaRequest.ts index ba67ab7be..bf4eb6df4 100644 --- a/server/entity/MediaRequest.ts +++ b/server/entity/MediaRequest.ts @@ -246,9 +246,7 @@ export class MediaRequest { >; const requestedSeasons = requestBody.seasons === 'all' - ? tmdbMediaShow.seasons - .map((season) => season.season_number) - .filter((sn) => sn > 0) + ? tmdbMediaShow.seasons.map((season) => season.season_number) : (requestBody.seasons as number[]); let existingSeasons: number[] = []; diff --git a/server/lib/scanners/plex/index.ts b/server/lib/scanners/plex/index.ts index f074872bb..58a948a86 100644 --- a/server/lib/scanners/plex/index.ts +++ b/server/lib/scanners/plex/index.ts @@ -278,9 +278,7 @@ class PlexScanner const seasons = tvShow.seasons; const processableSeasons: ProcessableSeason[] = []; - const filteredSeasons = seasons.filter((sn) => sn.season_number !== 0); - - for (const season of filteredSeasons) { + for (const season of seasons) { const matchedPlexSeason = metadata.Children?.Metadata.find( (md) => Number(md.index) === season.season_number ); diff --git a/server/lib/scanners/sonarr/index.ts b/server/lib/scanners/sonarr/index.ts index 3256c9482..5d28e0144 100644 --- a/server/lib/scanners/sonarr/index.ts +++ b/server/lib/scanners/sonarr/index.ts @@ -103,10 +103,8 @@ class SonarrScanner const tmdbId = tvShow.id; - const filteredSeasons = sonarrSeries.seasons.filter( - (sn) => - sn.seasonNumber !== 0 && - tvShow.seasons.find((s) => s.season_number === sn.seasonNumber) + const filteredSeasons = sonarrSeries.seasons.filter((sn) => + tvShow.seasons.find((s) => s.season_number === sn.seasonNumber) ); for (const season of filteredSeasons) { diff --git a/src/components/RequestBlock/index.tsx b/src/components/RequestBlock/index.tsx index ed4c3ec35..fda54499c 100644 --- a/src/components/RequestBlock/index.tsx +++ b/src/components/RequestBlock/index.tsx @@ -243,7 +243,11 @@ const RequestBlock = ({ request, onUpdate }: RequestBlockProps) => { key={`season-${season.id}`} className="mb-1 mr-2 inline-block" > - {season.seasonNumber} + + {season.seasonNumber === 0 + ? intl.formatMessage(globalMessages.specials) + : season.seasonNumber} + ))} diff --git a/src/components/RequestCard/index.tsx b/src/components/RequestCard/index.tsx index 44abd555a..d971548f4 100644 --- a/src/components/RequestCard/index.tsx +++ b/src/components/RequestCard/index.tsx @@ -381,8 +381,7 @@ const RequestCard = ({ request, onTitleData }: RequestCardProps) => { {intl.formatMessage(messages.seasons, { seasonCount: - title.seasons.filter((season) => season.seasonNumber !== 0) - .length === request.seasons.length + title.seasons.length === request.seasons.length ? 0 : request.seasons.length, })} @@ -390,7 +389,11 @@ const RequestCard = ({ request, onTitleData }: RequestCardProps) => {
{request.seasons.map((season) => ( - {season.seasonNumber} + + {season.seasonNumber === 0 + ? intl.formatMessage(globalMessages.specials) + : season.seasonNumber} + ))}
diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx index a42483abe..e48f75245 100644 --- a/src/components/RequestList/RequestItem/index.tsx +++ b/src/components/RequestList/RequestItem/index.tsx @@ -440,9 +440,7 @@ const RequestItem = ({ request, revalidateList }: RequestItemProps) => { {intl.formatMessage(messages.seasons, { seasonCount: - title.seasons.filter( - (season) => season.seasonNumber !== 0 - ).length === request.seasons.length + title.seasons.length === request.seasons.length ? 0 : request.seasons.length, })} @@ -450,7 +448,11 @@ const RequestItem = ({ request, revalidateList }: RequestItemProps) => {
{request.seasons.map((season) => ( - {season.seasonNumber} + + {season.seasonNumber === 0 + ? intl.formatMessage(globalMessages.specials) + : season.seasonNumber} + ))}
diff --git a/src/components/RequestModal/TvRequestModal.tsx b/src/components/RequestModal/TvRequestModal.tsx index 25c8fd3c2..723aa273c 100644 --- a/src/components/RequestModal/TvRequestModal.tsx +++ b/src/components/RequestModal/TvRequestModal.tsx @@ -41,7 +41,6 @@ const messages = defineMessages({ season: 'Season', numberofepisodes: '# of Episodes', seasonnumber: 'Season {number}', - extras: 'Extras', errorediting: 'Something went wrong while editing the request.', requestedited: 'Request for {title} edited successfully!', requestApproved: 'Request for {title} approved!', @@ -232,9 +231,7 @@ const TvRequestModal = ({ const getAllSeasons = (): number[] => { return (data?.seasons ?? []) - .filter( - (season) => season.seasonNumber !== 0 && season.episodeCount !== 0 - ) + .filter((season) => season.episodeCount !== 0) .map((season) => season.seasonNumber); }; @@ -557,10 +554,7 @@ const TvRequestModal = ({ {data?.seasons - .filter( - (season) => - season.seasonNumber !== 0 && season.episodeCount !== 0 - ) + .filter((season) => season.episodeCount !== 0) .map((season) => { const seasonRequest = getSeasonRequest( season.seasonNumber @@ -637,7 +631,7 @@ const TvRequestModal = ({ {season.seasonNumber === 0 - ? intl.formatMessage(messages.extras) + ? intl.formatMessage(globalMessages.specials) : intl.formatMessage(messages.seasonnumber, { number: season.seasonNumber, })} diff --git a/src/components/TvDetails/index.tsx b/src/components/TvDetails/index.tsx index 2f44a7d8c..1b0b3c667 100644 --- a/src/components/TvDetails/index.tsx +++ b/src/components/TvDetails/index.tsx @@ -200,6 +200,7 @@ const TvDetails = ({ tv }: TvDetailsProps) => { ); } + // Does NOT include "Specials" const seasonCount = data.seasons.filter( (season) => season.seasonNumber !== 0 && season.episodeCount !== 0 ).length; @@ -257,9 +258,17 @@ const TvDetails = ({ tv }: TvDetailsProps) => { return [...requestedSeasons, ...availableSeasons]; }; - const isComplete = seasonCount <= getAllRequestedSeasons(false).length; + const showHasSpecials = data.seasons.some( + (season) => season.seasonNumber === 0 + ); - const is4kComplete = seasonCount <= getAllRequestedSeasons(true).length; + const isComplete = + (showHasSpecials ? seasonCount + 1 : seasonCount) <= + getAllRequestedSeasons(false).length; + + const is4kComplete = + (showHasSpecials ? seasonCount + 1 : seasonCount) <= + getAllRequestedSeasons(true).length; const streamingProviders = data?.watchProviders?.find((provider) => provider.iso_3166_1 === region) @@ -522,7 +531,6 @@ const TvDetails = ({ tv }: TvDetailsProps) => { {data.seasons .slice() .reverse() - .filter((season) => season.seasonNumber !== 0) .map((season) => { const show4k = settings.currentSettings.series4kEnabled && @@ -576,9 +584,11 @@ const TvDetails = ({ tv }: TvDetailsProps) => { >
- {intl.formatMessage(messages.seasonnumber, { - seasonNumber: season.seasonNumber, - })} + {season.seasonNumber === 0 + ? intl.formatMessage(globalMessages.specials) + : intl.formatMessage(messages.seasonnumber, { + seasonNumber: season.seasonNumber, + })} {intl.formatMessage(messages.episodeCount, { diff --git a/src/i18n/globalMessages.ts b/src/i18n/globalMessages.ts index ca66a891f..64ae16c1c 100644 --- a/src/i18n/globalMessages.ts +++ b/src/i18n/globalMessages.ts @@ -55,6 +55,7 @@ const globalMessages = defineMessages({ noresults: 'No results.', open: 'Open', resolved: 'Resolved', + specials: 'Specials', }); export default globalMessages; diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json index 60a2d46bc..568895313 100644 --- a/src/i18n/locale/en.json +++ b/src/i18n/locale/en.json @@ -471,7 +471,6 @@ "components.RequestModal.cancel": "Cancel Request", "components.RequestModal.edit": "Edit Request", "components.RequestModal.errorediting": "Something went wrong while editing the request.", - "components.RequestModal.extras": "Extras", "components.RequestModal.numberofepisodes": "# of Episodes", "components.RequestModal.pending4krequest": "Pending 4K Request", "components.RequestModal.pendingapproval": "Your request is pending approval.",