Skip to content

feat(details): click poster open lightbox fullscreen#3047

Closed
Gauvino wants to merge 2 commits into
seerr-team:developfrom
Gauvino:feature/poster-lightbox
Closed

feat(details): click poster open lightbox fullscreen#3047
Gauvino wants to merge 2 commits into
seerr-team:developfrom
Gauvino:feature/poster-lightbox

Conversation

@Gauvino

@Gauvino Gauvino commented May 19, 2026

Copy link
Copy Markdown
Contributor

Description

Small QoL addition: clicking the poster on /movie/[id] or /tv/[id] opens it fullscreen instead of doing nothing. I was browsing details pages on a 4K monitor and the 600x900 poster felt cramped, wanted a quick way to see the artwork properly.

It's a new PosterLightbox component (React portal + black backdrop + Esc-to-close + body scroll lock) that pulls the TMDB original size image. Wired into MovieDetails and TvDetails — the poster <div> becomes a <button> that opens the lightbox.

No new deps. No API or DB changes. Behavior elsewhere untouched (TitleCards in grids still navigate to the details page like before).

Not linked to a specific issue — scratching my own itch, happy to drop it if it's out of scope.

How Has This Been Tested?

  • Built and ran the prod image (docker build from Dockerfile, node 22.22.2-alpine) on a Proxmox CT — opened a handful of movie and TV pages, clicked posters, tested Esc, X button, and click-outside-image to close
  • next build (which runs ESLint) and tsc (server + client) both green on the final commit
  • prettier --check clean on the three touched files
  • Manual a11y pass: backdrop is a proper <button> so jsx-a11y rules pass without role hacks; image wrapper is pointer-events-none so clicks pass through to the backdrop button
  • No new translation strings added — aria-labels stay in English to match the existing pattern (SlideOver, ButtonWithDropdown, pagination nav, etc.)

Tested on Chrome and on the phone work's like expected.

Screenshots / Logs (if applicable)

chrome_ZPucz8H9TJ chrome_KXToziWDHf

Checklist:

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy) — Claude Code helped me scaffold the component and the integration; I reviewed every line and made the a11y refactor myself.
  • I have updated the documentation accordingly. — no docs changes needed
  • All new and existing tests passed.
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract — no new strings
  • Database migration (if required) — n/a

Summary by CodeRabbit

  • New Features
    • Poster expand functionality: Click movie and TV show posters to open a fullscreen lightbox overlay with a larger preview.
    • Improved usability: The overlay locks background scrolling and supports multiple close methods (Escape key, click outside, or a dedicated close button).
    • Accessibility: Added clear aria labels for the poster expand control and the lightbox dialog content.

Copilot AI review requested due to automatic review settings May 19, 2026 13:40
@Gauvino Gauvino requested a review from a team as a code owner May 19, 2026 13:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a poster lightbox feature that lets users click the poster on movie and TV detail pages to view a larger version in a modal overlay.

Changes:

  • Introduces a new shared PosterLightbox component rendered via a React portal with keyboard (Escape) and click-to-close support.
  • Wires the lightbox into MovieDetails and TvDetails, converting the poster <div> into a <button> trigger.
  • Adds body scroll locking and a transition while the lightbox is open.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
src/components/Common/PosterLightbox/index.tsx New lightbox component with portal, transition, and close affordances.
src/components/MovieDetails/index.tsx Renders the lightbox and turns the poster container into a clickable button.
src/components/TvDetails/index.tsx Same integration as MovieDetails for the TV page.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +49 to +62
aria-label={alt || 'Poster preview'}
>
<button
type="button"
className="absolute inset-0 z-0 cursor-zoom-out bg-black/90 focus:outline-none"
onClick={onClose}
aria-label="Close poster preview"
/>
<button
type="button"
className="absolute right-4 top-4 z-20 rounded-full bg-gray-800/80 p-2 text-white hover:bg-gray-700/80 focus:outline-none focus:ring-2 focus:ring-white"
onClick={onClose}
aria-label="Close poster preview"
>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I need to make the aria-label react-intl or could I keep it this way since the other one and the repo are also hardcoded?

Comment thread src/components/MovieDetails/index.tsx
Comment thread src/components/Common/PosterLightbox/index.tsx
Comment thread src/components/MovieDetails/index.tsx
Comment thread src/components/Common/PosterLightbox/index.tsx
@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: af60dfe7-3178-4a7c-b4ed-d39696893e3f

📥 Commits

Reviewing files that changed from the base of the PR and between aa20544 and ac8e845.

📒 Files selected for processing (3)
  • src/components/Common/PosterLightbox/index.tsx
  • src/components/MovieDetails/index.tsx
  • src/components/TvDetails/index.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/components/TvDetails/index.tsx
  • src/components/MovieDetails/index.tsx
  • src/components/Common/PosterLightbox/index.tsx

📝 Walkthrough

Walkthrough

This PR introduces a poster lightbox modal component that displays full-size poster images in an overlay portal. The new PosterLightbox component manages body scroll locking, Escape key dismissal, and SSR safety, then integrates into MovieDetails and TvDetails pages with state-driven visibility and clickable expand buttons.

Changes

Poster Lightbox Modal

Layer / File(s) Summary
PosterLightbox component
src/components/Common/PosterLightbox/index.tsx
New component with PosterLightboxProps interface. Locks body scroll when show is true, listens for Escape key press to trigger onClose, and guards against SSR by returning null when window is undefined. Renders a portal-based modal overlay with Transition animations, close button, background click handler, and a CachedImage displaying the poster from posterPath with a fallback image.
MovieDetails and TvDetails integration
src/components/MovieDetails/index.tsx, src/components/TvDetails/index.tsx
Both components import PosterLightbox and add showPosterLightbox state. Each renders the lightbox component controlled by that state and wraps the poster display area in a clickable button to set showPosterLightbox to true, with an aria-label for accessibility. The lightbox closes via onClose callback setting the state back to false.

Sequence Diagram

sequenceDiagram
  participant DetailPage as MovieDetails/<br/>TvDetails
  participant LightboxComp as PosterLightbox
  participant Portal as Document Portal
  participant User

  User->>DetailPage: clicks expand poster button
  DetailPage->>DetailPage: setState showPosterLightbox true
  DetailPage->>LightboxComp: render with show=true
  LightboxComp->>LightboxComp: lock body scroll
  LightboxComp->>Portal: createPortal overlay
  Portal->>User: display poster in modal
  User->>LightboxComp: click close button / background /<br/>press Escape
  LightboxComp->>DetailPage: call onClose()
  DetailPage->>DetailPage: setState showPosterLightbox false
  DetailPage->>LightboxComp: render with show=false
  LightboxComp->>LightboxComp: unlock body scroll
  Portal->>User: close overlay
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A lightbox springs to life, with posters bold and bright,
Portal magic opens portals, dimming out the night,
Click to peek, press Escape, or close the glowing frame,
MovieDetails and TvDetails now dance the spotlight game! ✨

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding a fullscreen lightbox feature triggered by clicking on movie/TV show posters.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Gauvino Gauvino changed the title feat(details): clic poster open lightbox fullscreen feat(details): click poster open lightbox fullscreen May 19, 2026
Gauvino added 2 commits June 18, 2026 17:26
Add PosterLightbox component (portal + backdrop + Esc + body scroll lock).
Wire to MovieDetails and TvDetails poster: clic ouvre l'image en grand
(TMDB original size).

- src/components/Common/PosterLightbox/index.tsx (nouveau)
- src/components/MovieDetails/index.tsx
- src/components/TvDetails/index.tsx
Remplace div onClick + role=dialog par:
- container role=dialog sans handler
- button absolute inset-0 = backdrop cliquable (cursor-zoom-out)
- image wrapper pointer-events-none

Vire les 4 erreurs jsx-a11y/click-events-have-key-events et
no-noninteractive-element-interactions sans changer le comportement.
@Gauvino Gauvino force-pushed the feature/poster-lightbox branch from aa20544 to ac8e845 Compare June 18, 2026 15:26
@Gauvino

Gauvino commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Any possibility to get this into the next release or 3.5.0 ?

@gauthier-th gauthier-th left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest I'm not sure to get what is the added value in this PR.
You literally can just right click on the image, choose the "open image in new tab" menu and see it fullscreen in another tab??

We aim to keep Seerr as simple as possible, and avoid adding unnecessary features whenever it is possible. IMO it includes this one.

@Gauvino

Gauvino commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

To be honest I'm not sure to get what is the added value in this PR. You literally can just right click on the image, choose the "open image in new tab" menu and see it fullscreen in another tab??

We aim to keep Seerr as simple as possible, and avoid adding unnecessary features whenever it is possible. IMO it includes this one.

I can understand, i will close it

@Gauvino Gauvino closed this Jun 19, 2026
@gauthier-th

Copy link
Copy Markdown
Member

Thank you for your contribution anyway 🙂

@Gauvino Gauvino deleted the feature/poster-lightbox branch June 19, 2026 15:11
@Gauvino

Gauvino commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for your contribution anyway 🙂

Have a good day !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants