Skip to content

feat(user-settings): add a per-user media language setting#2983

Open
0xSysR3ll wants to merge 4 commits intodevelopfrom
feat/0xsysr3ll/media-language-setting
Open

feat(user-settings): add a per-user media language setting#2983
0xSysR3ll wants to merge 4 commits intodevelopfrom
feat/0xsysr3ll/media-language-setting

Conversation

@0xSysR3ll
Copy link
Copy Markdown
Contributor

@0xSysR3ll 0xSysR3ll commented May 1, 2026

Description

This PR introduces a clearer separation between user language preferences by distinguishing the Display Language used for the UI and the Media Language used for media metadata.

To preserve backward compatibility, the content language automatically falls back to the effective locale when it hasn't been explicitly set.

How Has This Been Tested?

  • Set Display Language to English
  • Set Media Language to French

UI is correctly using English as display language whereas media related metadata is displayed in French.

Screenshots / Logs (if applicable)

User settings

image

Result

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
    • Per-user "Media Language" setting to control language used for media metadata independently of the UI language; metadata falls back to display language if unset.
  • Backend / API
    • Setting persisted and returned by user settings endpoints; used as the default language for media-related endpoints when no language query is provided.
  • Documentation
    • Added docs describing the Media Language override.
  • Chores
    • Database migrations to store the new setting.

@0xSysR3ll 0xSysR3ll requested a review from a team as a code owner May 1, 2026 14:37
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

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: 632ff581-20a0-4515-aec8-1c113d310357

📥 Commits

Reviewing files that changed from the base of the PR and between 31936bf and f434e73.

📒 Files selected for processing (6)
  • server/routes/index.ts
  • server/routes/movie.ts
  • server/routes/person.ts
  • server/routes/search.ts
  • server/routes/tv.ts
  • src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • server/routes/search.ts
  • src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
  • server/routes/person.ts
  • server/routes/tv.ts

📝 Walkthrough

Walkthrough

Adds a per-user Media Language setting (mediaLocale) persisted to the database, exposed in the API and OpenAPI schema, surfaced in the UI, and used by server routes as the preferred language for TMDB/provider requests when no language query override is provided.

Changes

Cohort / File(s) Summary
Documentation & OpenAPI
docs/using-seerr/users/editing-users.md, seerr-api.yml
Documented per-user "Media Language" and added components.schemas.UserSettings.mediaLocale (nullable string). Numerous OpenAPI description fields reformatted.
Database Migrations (Postgres)
server/migration/postgres/1777644799789-AddMediaLanguageSetting.ts
Adds reversible mediaLocale column to user_settings.
Database Migrations (SQLite)
server/migration/sqlite/1777644713621-AddMediaLanguageSetting.ts
Rebuilds user_settings to include mediaLocale with index/table copy logic; includes down migration to restore prior schema.
Data Models & Types
server/entity/UserSettings.ts, server/interfaces/api/userSettingsInterfaces.ts, src/hooks/useUser.ts
Adds optional mediaLocale?: string to the persisted entity and TypeScript interfaces.
User Settings API
server/routes/user/usersettings.ts
GET /main and POST /main include and persist mediaLocale.
Server Routes / TMDB Calls
server/routes/index.ts, server/routes/movie.ts, server/routes/person.ts, server/routes/search.ts, server/routes/tv.ts
Compute mediaLocale from `req.user?.settings?.mediaLocale
Frontend UI & i18n
src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx, src/i18n/locale/en.json
Adds "Media Language" select bound to mediaLocale, initializes/submits the field to /settings/main, and a new i18n string for the label.

Sequence Diagram(s)

sequenceDiagram
  participant User as User
  participant Frontend as Frontend
  participant API as API_Server
  participant DB as Database
  participant TMDB as TMDB
  User->>Frontend: change Media Language (mediaLocale)
  Frontend->>API: POST /settings/main { mediaLocale }
  API->>DB: persist user_settings.mediaLocale
  DB-->>API: ack
  API-->>Frontend: 200 OK (settings with mediaLocale)
  Frontend->>API: GET /movie/:id (no ?language)
  API->>DB: read user_settings.mediaLocale
  DB-->>API: mediaLocale
  API->>TMDB: GET /movie/:id?language=mediaLocale_or_req.locale
  TMDB-->>API: localized movie metadata
  API-->>Frontend: movie metadata
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • gauthier-th
  • fallenbagel
  • M0NsTeRRR

Poem

🐰 I nibble settings, soft and sweet,
Two little choices for tongue and tweet.
Buttons in one tongue, movie words in another—
Hopping through locales, I bind them together. 🎩

🚥 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 accurately and specifically describes the primary change: adding a per-user media language setting, which is the core objective of the PR.
Linked Issues check ✅ Passed The PR fully implements the requirements from issue #2308: splits the language setting into separate Display Language and Media Language controls, allowing independent configuration.
Out of Scope Changes check ✅ Passed All code changes are directly related to implementing the media language feature; no unrelated changes are present in the changeset.

✏️ 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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/using-seerr/users/editing-users.md`:
- Around line 36-41: Replace the term "Content Language" with the UI-consistent
phrase "Media Language" throughout this doc: update the heading "Content
Language", the explanatory paragraph "Users can choose a separate content
language..." and the fallback sentence "If no content language is selected..."
to use "Media Language" instead so wording matches the settings UI.

In `@server/routes/index.ts`:
- Around line 261-265: The current fallback uses the nullish coalescing operator
which treats empty strings as valid, so replace usages like "const mediaLocale =
req.user?.settings?.mediaLocale ?? req.locale" and language assignments such as
"language: (req.query.language as string) ?? mediaLocale" with a check that
treats empty strings as missing (e.g., use (req.user?.settings?.mediaLocale &&
req.user.settings.mediaLocale.trim()) ? req.user.settings.mediaLocale :
req.locale or a small helper normalizeLocale(value, fallback) that returns
fallback if value is null/undefined/''/only-whitespace), then update all call
sites (including the tmdb.getMovieGenres call and other routes using
mediaLocale, req.query.language, and language: ...) to pass the normalized
locale so TMDB never receives an empty language string.

In `@src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx`:
- Around line 414-418: The "Default (...)" option currently uses
availableLanguages[currentSettings.locale].display which shows the
display-language override instead of the effective fallback for media; change
that to use the media locale when set and otherwise the effective locale used by
the backend (e.g., availableLanguages[currentSettings.mediaLocale ??
effectiveLocale].display). Update the intl.formatMessage call in the <option>
inside UserGeneralSettings (index.tsx) to reference currentSettings.mediaLocale
?? effectiveLocale and ensure effectiveLocale is obtained from the component
props/context (the same source that represents req.locale/effective user
locale).
🪄 Autofix (Beta)

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

Run ID: 3741fa9a-610d-43ac-a820-91634fc2899d

📥 Commits

Reviewing files that changed from the base of the PR and between 3ad2d09 and c2a55af.

📒 Files selected for processing (15)
  • docs/using-seerr/users/editing-users.md
  • seerr-api.yml
  • server/entity/UserSettings.ts
  • server/interfaces/api/userSettingsInterfaces.ts
  • server/migration/postgres/1777644799789-AddMediaLanguageSetting.ts
  • server/migration/sqlite/1777644713621-AddMediaLanguageSetting.ts
  • server/routes/index.ts
  • server/routes/movie.ts
  • server/routes/person.ts
  • server/routes/search.ts
  • server/routes/tv.ts
  • server/routes/user/usersettings.ts
  • src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx
  • src/hooks/useUser.ts
  • src/i18n/locale/en.json

Comment thread docs/using-seerr/users/editing-users.md Outdated
Comment thread server/routes/index.ts Outdated
@0xSysR3ll 0xSysR3ll force-pushed the feat/0xsysr3ll/media-language-setting branch from c2a55af to 31936bf Compare May 1, 2026 14:49
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.

Separate UI language from media data language

1 participant