fix(tv): prevent phantom specials from blocking season request - #3351
fix(tv): prevent phantom specials from blocking season request#3351fallenbagel wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughThe scanner normalizes seasons with zero reported episodes. TV request controls now evaluate completion from requestable and unrequested seasons instead of season-count comparisons. ChangesTV season handling
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR addresses an edge case where “phantom” Specials (season 0) entries with zero provider episodes could incorrectly affect TV request/availability behavior, causing the UI to disagree about whether a series is requestable and, on the server, allowing scanned files to incorrectly influence season availability.
Changes:
- Aligns
TvDetails“complete” computation with the same season filtering logic used by the request modal (excluding zero-episode seasons and optionally excluding specials). - Updates
TvRequestModalto determine “Already Requested” based on whether any requestable seasons remain unrequested (instead of comparing season counts). - Adjusts the scanner
processShowlogic to zero episode counts for seasons the metadata provider reports as empty, preventing files from promoting those seasons’ availability.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/components/TvDetails/index.tsx | Reworks “series complete” logic to use a requestable-season set consistent with the modal. |
| src/components/RequestModal/TvRequestModal.tsx | Switches “already requested / disable” logic to use unrequestedSeasons.length === 0. |
| server/lib/scanners/baseScanner.ts | Prevents empty-provider seasons from being promoted by scanned files by zeroing episode counts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Caution CodeRabbit couldn't update its existing comment. The review summary may be out of date. Error details |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/TvDetails/index.tsx`:
- Around line 322-330: Update isSeasonSetComplete to remove the
requestableSeasons.length > 0 guard, allowing every() to mark an empty
requestable season set as complete and keeping RequestButton consistent with
TvRequestModal.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: bf490254-7967-40fb-a182-77d13a5966c6
📒 Files selected for processing (3)
server/lib/scanners/baseScanner.tssrc/components/RequestModal/TvRequestModal.tsxsrc/components/TvDetails/index.tsx
ccd9adb to
972fe27
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/components/RequestModal/TvRequestModal.tsx:447
- There is still a remaining
getAllRequestedSeasons().length < getAllSeasons().lengthcomparison later in this component (around line 487) that uses the same count-based logic this change is replacing. In the phantom-specials scenario described in the PR, that check will still evaluate incorrectly (season 0 can inflategetAllRequestedSeasons()whilegetAllSeasons()drops it), which can make the admin-only alert logic disagree with the newunrequestedSeasonscompletion logic. Update that remaining comparison to useunrequestedSeasons.length(or an equivalent “any season still unrequested” predicate) so all code paths use the same definition of completeness.
: hasPermission(Permission.MANAGE_REQUESTS)
? intl.formatMessage(messages.approve)
: intl.formatMessage(messages.edit)
: unrequestedSeasons.length === 0
? intl.formatMessage(messages.alreadyrequested)
: !settings.currentSettings.partialRequestsEnabled
? intl.formatMessage(
is4k ? globalMessages.request4k : globalMessages.request
)
: selectedSeasons.length === 0
? intl.formatMessage(messages.selectseason)
: intl.formatMessage(
is4k ? messages.requestseasons4k : messages.requestseasons,
{
seasonCount: selectedSeasons.length,
}
)
}
okDisabled={
editRequest
? false
: !settings.currentSettings.partialRequestsEnabled &&
quota?.tv.limit &&
unrequestedSeasons.length > quota.tv.limit &&
!requestOverrides?.ignoreQuota
? true
: unrequestedSeasons.length === 0 ||
(settings.currentSettings.partialRequestsEnabled &&
selectedSeasons.length === 0)
}
Description
Adding a Specials folder in Plex for a show whose TMDB specials entry has no episodes made the rest of the series unrequestable. The scanner sees one file against zero expected episodes and writes a season 0 row as PARTIALLY_AVAILABLE, which flips the whole series to Partially Available because the PARTIALLY_AVAILABLE branch of the rollup does not exclude specials the way the AVAILABLE branch does.
TvRequestModaldecided whether a show was fully requested by comparing how many seasons are requested or available against how many seasons it offers. That season 0 counts toward the first number but is dropped from the second by theepisodeCount !== 0filter, so a show with one real season looked fully requested: the button read "Already Requested" and was disabled while the season row still said "Not Requested" and its toggle still worked.TvDetailscounted seasons too but added one for specials, so it still rendered "Request More" and users could open a modal whose button was already dead. Shows whose specials entry has at least one episode were never affected.Both now check whether any offered season is still unrequested instead of comparing counts, and
TvDetailsreads the same filtered season list the modal renders. On the server,processShowzeroes the episode counts for a season the provider reports as empty so files can no longer promote it. This PR does not deliberately add downgrading an existing status toprocessShow: one scanner only sees one source, and demoting there would reintroduce the race the AVAILABLE stickiness already guards against. Existing records keep their season 0 row and can be fixed with Clear Data followed by a rescan.How Has This Been Tested?
Did not test myself, waiting to beTested by original reporter on discord and confirmed to be working (preview-phantom-specialsfor testing).Screenshots / Logs (if applicable)
Checklist:
pnpm buildpnpm i18n:extractSummary by CodeRabbit