fix: episode cards navigate to season detail + anchor (API SeasonId) (#220) #223
Closed
timothy
wants to merge 0 commits from
fix/220-episode-nav into main
pull from: fix/220-episode-nav
merge into: :main
:main
:renovate/lucene.net
:renovate/dotnet-monorepo
:renovate/sqlitepclraw.bundle_e_sqlite3-3.x
:renovate/meziantou.analyzer-3.x
:renovate/cliwrap-3.x
:913-scripted-playout-401
:release/v26.15.0-notes
:issue-806-guard-populations
:scratch/767b-poisoned
:scratch/767b-control
:release/v26.14.0-notes
:release/v26.14.0
:docs/510-skill-logo-bug-policy
:fix/510-watermark-resolution-policy
:fix/629-verdict-classifier-falseopens
:fix/609-decisions-edit-token-scope
:issue-135-clear-to-none
:release/v26.12.0-notes
:fix/409b-lastscan-api-parity
:fix/401-updatechannel-mirror-422
:fix/327-playlist-rename-validation
:fix/410-scancancel-log-level
:fix/409-447-librariesscreen-neverscanned
:fix/338-zap-exit-code
:fix/367-plex-budget-message
:fix/310-debom-legacy-cs
:ci/604-lane-rebalance
:feat/388-design-mirror
:feat/247-test-ownership
:feat/247-primary-action
:feat/357-player-owned-playback
:feat/357-jellyfin-plugin-poc
:fix/289-mcp-hardening
:issue58-mcp
:feat/244-channels-extract
:ci/auto-bump-prod-compose
:feat/multi-rerun-collections-api
:feat/collections-api
:feat/quick-wins
:feat/185-docs-part2
:feat/140-collections-screen
:feat/146-channel-edit
:feat/147-classic-ui-link
:issue22-renovate-dashboard
:feat/91-cutover
:feat/63-composite-create
:feat/65-library-browse
:feat/85-epg
:feat/86-schedule-editor
:feat/109-dashboard-data
:feat/99-session-tracking
:fix/dockerfile-node-tag
:feat/59-spa-foundation
:docs/59-ui-redesign-brief
:feat/102-json-guide
:feat/111-schedule-durations
:feat/104-artwork-upload
:feat/103-media-sources-api
:feat/playouts-read-api
:feat/108-health-api
:feat/105-picker-list-endpoints
:issue-97-channel-state-api
:issue42-jellyfin-musicvideos
:issue46-rest-api-error-contract
:dependabot/nuget/ErsatzTV.FFmpeg.Tests/multi-d307a2e06f
:qsv-improvements
:hdr-vulkan-cuda-test
No Reviewers
Labels
Clear labels
ad-hoc
api
bug
ci-cd
content
dependencies
enhancement
frontend
in-progress
jellyfin
parked
priority: high
priority: low
priority: medium
review
security
One-off / ad-hoc work not tracked by a dedicated issue
REST API / HTTP endpoints
Something isn't working
Build, test, deploy pipeline
Channel content / schedules / playlists
Dependency updates (Renovate)
New feature or improvement
ChicoryTV React SPA frontend
Claimed by an active session — do not pick up
Jellyfin tuner / IPTV integration
Excluded from automatic queue pickup; work only when explicitly selected
Adversarial review finding
Security / vulnerability fix
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: timothy/ersatztv#223
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #220 (adversarial-reviewer#18 MUST-FIX gate for #91 phase b).
LibraryBrowseItemResponseModelgains optionalSeasonId, populated at the single shared episode hydration site (LibraryBrowseItemMapper.GetEpisodes); OpenAPI + generated TS types regenerated.mediaDetailPath: Episode →/app/media/seasons/{seasonId}#episode-{id}(BlazorSearch.razor:241parity); episode cards in Search, top-level episode browse, and season drill-in now navigate.ChildGrid: stableepisode-{id}anchors, hash-driven scroll-into-view + fade highlight.🤖 Generated with Claude Code
Episode cards in the SPA search and media-browse screens were inert (mediaDetailPath had no Episode case, and LibraryBrowseItemResponseModel carried no parent-season id to route with). - API: add nullable SeasonId to LibraryBrowseItemResponseModel; populate it in LibraryBrowseItemMapper.GetEpisodes (the single shared hydration site used by both the library-browse search/browse handler and the season episode drill-in), leave it null for every other kind. Regenerated v1.json + v1.d.ts per docs/api-conventions.md §5. - SPA: mediaDetailPath now routes Episode items with a seasonId to /app/media/seasons/{seasonId}#episode-{id} (matching Blazor's Search.razor:241 link), null otherwise. MediaPosterCard accepts an id/highlighted pair; SeasonDetailScreen's episode grid gives each card a stable `episode-{id}` anchor and scrolls/highlights it on mount and on hashchange (deep-link support). - Tests: GetLibraryBrowseItemsHandlerTests asserts SeasonId is populated for episode drill-in results and null for other kinds; web tests cover mediaDetailPath's episode cases and the anchor/scroll/highlight behavior (jsdom scrollIntoView stub). - Docs: blazor-route-parity.md's episode-browse row and the Search cluster verdict updated — the standalone SPA episode browse exists and episode cards now navigate, closing the adversarial-reviewer#18 finding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>Merged to main via integration PR #239 (all six gate-batch branches integrated in one CI round after pairwise doc conflicts; this PR's commits are reachable from main — see the merge commits there). Closing manually since Gitea did not auto-detect the branch merge.
Pull request closed