Skip to content

feat(requests): allow users to view requester on media details page - #2866

Open
danielkinahan wants to merge 11 commits into
seerr-team:developfrom
danielkinahan:develop
Open

feat(requests): allow users to view requester on media details page#2866
danielkinahan wants to merge 11 commits into
seerr-team:developfrom
danielkinahan:develop

Conversation

@danielkinahan

@danielkinahan danielkinahan commented Apr 12, 2026

Copy link
Copy Markdown

Description

This change adds the ability for a user with View Requests permission to view the requests of other users on the media details page (both TV and movies). I added it as a seperate card under the media-facts card, but I'd like feedback on the placement. I will include screenshots.

Disclaimer on AI

I used AI to search the codebase and review this code for feedback.

How Has This Been Tested?

I copied my db of my instance and ran tests with it, so I could have data. I have only run this in dev mode. I have tried this with a piece of media that has no requests, one and multiple (creates new cards for each).

Screenshots / Logs (if applicable)

One request
image

Multiple requests
image

No requests (card doesnt show)
image

Mobile view of multiple requests
image

Checklist:

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy)
  • I have updated the documentation accordingly.
  • All new and existing tests passed.
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required)

Summary by CodeRabbit

  • New Features
    • Added a media request summary to the movie and TV detail pages, showing the requester (with avatar), formatted request date, and status badges, including a 4K indicator when applicable.
    • Request visibility now respects permissions: authorized users see all requests; others see only their own.
  • Documentation
    • Added new localized UI strings for the request summary (requester, request date, and status).

@danielkinahan
danielkinahan requested a review from a team as a code owner April 12, 2026 19:01
@coderabbitai

coderabbitai Bot commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Movie and TV detail pages now render a media request summary with permission-gated request data and the current user id. English locale strings were added for the summary’s date, requester, and status labels.

Changes

Media request detail integration

Layer / File(s) Summary
Detail page integration
src/components/MovieDetails/index.tsx, src/components/TvDetails/index.tsx
Imported MediaRequestSummary and rendered it in the media overview area; each page passes either the full request list for MANAGE_REQUESTS/REQUEST_VIEW or a user-filtered list, plus currentUserId={user?.id}.
English labels
src/i18n/locale/en.json
Added English strings for components.MediaRequestSummary.requestDate, requester, and status.

Sequence Diagram(s)

sequenceDiagram
    participant Browser
    participant MovieDetails
    participant TvDetails
    participant AuthPermissions
    participant MediaRequestSummary
    Browser->>MovieDetails: open movie page
    Browser->>TvDetails: open TV page
    MovieDetails->>AuthPermissions: check MANAGE_REQUESTS / REQUEST_VIEW
    TvDetails->>AuthPermissions: check MANAGE_REQUESTS / REQUEST_VIEW
    AuthPermissions-->>MovieDetails: permission scope
    AuthPermissions-->>TvDetails: permission scope
    MovieDetails->>MediaRequestSummary: render requests + currentUserId
    TvDetails->>MediaRequestSummary: render requests + currentUserId
    MediaRequestSummary-->>Browser: display requester, date, and status
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 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 summarizes the main change: exposing requester info on media details pages.
Linked Issues check ✅ Passed The PR matches #2865 by showing requester details on movie and TV pages for users with View Requests permission.
Out of Scope Changes check ✅ Passed The changes stay focused on requester visibility, UI rendering, and needed translations with no obvious unrelated scope.

✏️ 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

🐇 I hopped to the media page with cheer,
Saw requester names and dates appear.
Badges and links now line the trail,
A little rabbit grin sets sail.

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

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
src/components/MediaRequestSummary/index.tsx (1)

44-70: Consolidate status mapping to prevent future drift.

statusMessage and statusBadgeType are derived from duplicate switch logic on the same enum. Centralizing this in one map/helper will keep status text and badge color in sync as statuses evolve.

♻️ Suggested refactor
+const requestStatusMeta = {
+  [MediaRequestStatus.APPROVED]: {
+    message: globalMessages.approved,
+    badgeType: 'success',
+  },
+  [MediaRequestStatus.DECLINED]: {
+    message: globalMessages.declined,
+    badgeType: 'danger',
+  },
+  [MediaRequestStatus.FAILED]: {
+    message: globalMessages.failed,
+    badgeType: 'danger',
+  },
+  [MediaRequestStatus.COMPLETED]: {
+    message: globalMessages.completed,
+    badgeType: 'success',
+  },
+  [MediaRequestStatus.PENDING]: {
+    message: globalMessages.pending,
+    badgeType: 'warning',
+  },
+} as const;
...
-        const statusMessage = (() => {
-          switch (request.status) {
-            case MediaRequestStatus.APPROVED:
-              return intl.formatMessage(globalMessages.approved);
-            case MediaRequestStatus.DECLINED:
-              return intl.formatMessage(globalMessages.declined);
-            case MediaRequestStatus.FAILED:
-              return intl.formatMessage(globalMessages.failed);
-            case MediaRequestStatus.COMPLETED:
-              return intl.formatMessage(globalMessages.completed);
-            default:
-              return intl.formatMessage(globalMessages.pending);
-          }
-        })();
-
-        const statusBadgeType = (() => {
-          switch (request.status) {
-            case MediaRequestStatus.APPROVED:
-            case MediaRequestStatus.COMPLETED:
-              return 'success';
-            case MediaRequestStatus.DECLINED:
-            case MediaRequestStatus.FAILED:
-              return 'danger';
-            default:
-              return 'warning';
-          }
-        })();
+        const statusMeta =
+          requestStatusMeta[request.status] ?? requestStatusMeta[MediaRequestStatus.PENDING];
+        const statusMessage = intl.formatMessage(statusMeta.message);
+        const statusBadgeType = statusMeta.badgeType;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/MediaRequestSummary/index.tsx` around lines 44 - 70, The
duplicate switch logic for computing statusMessage and statusBadgeType from
MediaRequestStatus should be centralized: create a single helper (e.g.,
getMediaRequestStatusInfo or STATUS_MAP) that accepts a MediaRequestStatus and
returns both the localized message (using intl + globalMessages) and the badge
type string; replace the current statusMessage and statusBadgeType computed
blocks with calls to that helper (use its .message and .badgeType), ensuring you
reference MediaRequestStatus, intl, and globalMessages inside the helper so both
values stay in sync as statuses change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/components/MediaRequestSummary/index.tsx`:
- Around line 44-70: The duplicate switch logic for computing statusMessage and
statusBadgeType from MediaRequestStatus should be centralized: create a single
helper (e.g., getMediaRequestStatusInfo or STATUS_MAP) that accepts a
MediaRequestStatus and returns both the localized message (using intl +
globalMessages) and the badge type string; replace the current statusMessage and
statusBadgeType computed blocks with calls to that helper (use its .message and
.badgeType), ensuring you reference MediaRequestStatus, intl, and globalMessages
inside the helper so both values stay in sync as statuses change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5f10119d-f175-4952-a1a5-27805527278f

📥 Commits

Reviewing files that changed from the base of the PR and between 43eff25 and d1076e6.

📒 Files selected for processing (3)
  • src/components/MediaRequestSummary/index.tsx
  • src/components/MovieDetails/index.tsx
  • src/components/TvDetails/index.tsx

@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.

What's the point of this PR?
You can already see the requests on the right sidebar (displayed when you click on the settings icon).

@danielkinahan

Copy link
Copy Markdown
Author

Only admins have access to that settings icon. My users are often asking who requested the movies they go to look up.

@fallenbagel

Copy link
Copy Markdown
Member

Only admins have access to that settings icon. My users are often asking who requested the movies they go to look up.

You can already grant a user to view requests from other users...

@danielkinahan

Copy link
Copy Markdown
Author

I'm aware of that user privilege, which grants view access to the requests tab. I used the same one in the code in this PR. However there is no search bar on that tab. A user would need to scroll to the approximate date when it was created which they wouldnt know. I have over 1300 requests on my instance and scrolling through those is not convenient.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

This PR is stale because it has been open 30 days with no activity. Please address the feedback or provide an update to keep it open.

@github-actions github-actions Bot added the stale label Aug 7, 2026
Copilot AI lite review requested due to automatic review settings August 7, 2026 21:16
@danielkinahan

Copy link
Copy Markdown
Author

I've addressed the feedback and im waiting for the maintainers response

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

Adds a “Media Request Summary” section to Movie/TV detail pages that displays requester, request date, and status (including a 4K badge), with visibility intended to depend on the viewer’s permissions.

Changes:

  • Introduces a new MediaRequestSummary component that renders per-request requester/date/status rows.
  • Renders MediaRequestSummary on both Movie and TV detail pages with permission-based filtering for what is displayed.
  • Adds new English i18n keys for the summary labels.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/i18n/locale/en.json Adds i18n strings for the new request summary labels.
src/components/TvDetails/index.tsx Renders the new request summary card on TV detail pages with permission-based display filtering.
src/components/MovieDetails/index.tsx Renders the new request summary card on Movie detail pages with permission-based display filtering.
src/components/MediaRequestSummary/index.tsx New UI component that lists requests with requester info, request date, and status badges.

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

Comment on lines +1110 to +1114
hasPermission(
[Permission.MANAGE_REQUESTS, Permission.REQUEST_VIEW],
{ type: 'or' }
)
? data.mediaInfo?.requests
Comment on lines +1330 to +1334
hasPermission(
[Permission.MANAGE_REQUESTS, Permission.REQUEST_VIEW],
{ type: 'or' }
)
? data.mediaInfo?.requests
@github-actions github-actions Bot removed the stale label Aug 8, 2026
Copilot AI review requested due to automatic review settings August 23, 2026 02:05

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

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/components/TvDetails/index.tsx:1338

  • This permission check only hides other users’ requests in the UI. The movie/TV details APIs still return mediaInfo.requests (and requestedBy) for everyone via Media.getMedia(..., { relations: { requests: true } }), and MediaRequest.requestedBy is eager-loaded, so a user without REQUEST_VIEW can still see other requesters by inspecting the network response. Consider enforcing this authorization server-side (e.g., filter mediaInfo.requests to the current user unless the requester has MANAGE_REQUESTS or REQUEST_VIEW, or omit requestedBy entirely when not authorized).
            requests={
              hasPermission(
                [Permission.MANAGE_REQUESTS, Permission.REQUEST_VIEW],
                { type: 'or' }
              )
                ? data.mediaInfo?.requests
                : data.mediaInfo?.requests?.filter(
                    (r) => r.requestedBy?.id === user?.id
                  )
            }

src/components/MovieDetails/index.tsx:1118

  • This permission check only hides other users’ requests in the UI. The movie/TV details APIs still return mediaInfo.requests (and requestedBy) for everyone via Media.getMedia(..., { relations: { requests: true } }), and MediaRequest.requestedBy is eager-loaded, so a user without REQUEST_VIEW can still see other requesters by inspecting the network response. Consider enforcing this authorization server-side (e.g., filter mediaInfo.requests to the current user unless the requester has MANAGE_REQUESTS or REQUEST_VIEW, or omit requestedBy entirely when not authorized).
            requests={
              hasPermission(
                [Permission.MANAGE_REQUESTS, Permission.REQUEST_VIEW],
                { type: 'or' }
              )
                ? data.mediaInfo?.requests
                : data.mediaInfo?.requests?.filter(
                    (r) => r.requestedBy?.id === user?.id
                  )
            }

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add the ability to view requester on media page if user has "View Requests" permission

4 participants