Skip to content

feat(detail): add collapsible Content Advisory section with IMDb criteria - #83

Open
glpc-blaze wants to merge 1 commit into
Harborofficial:beta-branchfrom
glpc-blaze:feat/content-advisory
Open

glpc-blaze wants to merge 1 commit into
Harborofficial:beta-branchfrom
glpc-blaze:feat/content-advisory

Conversation

@glpc-blaze

@glpc-blaze glpc-blaze commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary of Changes

Adds a native, collapsible Content Advisory section to the title details view directly below Cast/Characters, powered by IMDb's public GraphQL endpoint.

  • Criteria & Consensus: Displays advisory breakdown across all 5 standard categories (Sex & Nudity, Violence & Gore, Profanity, Alcohol, Drugs & Smoking, Frightening & Intense Scenes) along with community voting consensus and detailed notes.
  • In-Player Iconography: Adopts the exact icons from Harbor's playback advisory (Heart, Swords, MessageSquareWarning, Wine, Ghost) to the left of each category criterion, removing the dot symbol.
  • Thin Boxy Meter: Implements a 3-bar vertical pill level meter (h-3.5 w-1 rounded-[2px]) matching Harbor's in-player content advisory toast.
  • Player Color Tokens: Aligns with Harbor's in-player advisory colors (text-danger/bg-danger for Severe, text-accent/bg-accent for Moderate, and muted whites for Mild/None), dynamically respecting the user's contentAdvisoryTheme setting.
  • Collapsible Section & Trays: Each category expands to reveal detailed submissions and hidden spoiler notes with smooth CSS grid transitions. The entire section can also be collapsed/expanded via the header toggle beside Open on IMDb.
  • Universal Multi-Source Support: Seamlessly resolves IMDb IDs across Movies, Series, TMDB-keyed titles, and Anime (Kitsu/MAL/AniList).
  • Layout Customization: Integrated into detail-customization.ts default rail ordering right below Cast.

Screenshots

image

Verification & Testing

  • pnpm run check (vp check): Passed with 0 warnings or lint errors.
  • pnpm run typecheck (tsc --noEmit -p tsconfig.json): Passed with 0 errors.
  • cargo check --manifest-path src-tauri/Cargo.toml: Passed with exit code 0.
  • Manual testing: Verified layout rendering, collapsible animation, IMDb external link, and fallback on multiple movies and anime titles.

@glpc-blaze glpc-blaze changed the title feat(detail): add collapsible Content Advisory section with IMDb criteria & ratings feat(detail): add collapsible Content Advisory section with IMDb criteria Nov 6, 2026
@glpc-blaze
glpc-blaze force-pushed the feat/content-advisory branch from f3d8fac to 1ec6299 Compare November 6, 2026 18:33
…eria & ratings

- Fetch parental guide criteria & votes directly from IMDb GraphQL endpoint
- Support movie & series IDs, TMDB inferred IDs, and anime Kitsu/MAL IDs
- Integrate collapsible Content Advisory panel right below Cast/Characters
- Use in-player Lucide icons (Heart, Swords, MessageSquareWarning, Wine, Ghost)
- Implement thin boxy 3-bar level meter matching the playback advisory toast
- Adopt player severity color tokens (danger, accent, muted whites)
- Add section collapse toggle beside Open on IMDb with smooth grid transition
- Ensure section order customization respects content advisory positioning
@glpc-blaze
glpc-blaze force-pushed the feat/content-advisory branch from 1ec6299 to b0e7b2b Compare November 6, 2026 18:38
@Thunderhawkk

Copy link
Copy Markdown
Contributor

Thanks for implementing the Content Advisory section. The collapsible layout, category breakdown, and integration with IMDb's Parents Guide look good overall. I reviewed the full PR and verified that the GraphQL query returns the expected data.

There are a few issues I'd like addressed before merging.

1. [P2] Preserve user-defined layout customization

In detail-customization.ts, orderedSectionKeys() forcibly moves Content Advisory immediately after Cast when certain other sections are present.

This overrides the user's saved layout order. I reproduced a case where moving Content Advisory below another section has no visible effect because the ordering logic moves it back.

Could you keep Content Advisory immediately below Cast in the default layout, while respecting any custom ordering the user has explicitly saved? The section should remain fully movable through Harbor's layout customization controls.

2. [P2] Support fetching advisory data in the web client

In imdb-parents-guide.ts, the GraphQL request goes directly to https://graphql.imdb.com/.

While the endpoint responds correctly to native HTTP requests, IMDb rejects browser CORS preflight requests from Harbor's web origin. Harbor's browser-side safeFetch() also does not currently proxy this host.

Could you route these requests through an appropriate existing backend or proxy mechanism so the section works in both desktop and web environments?

3. [P2] Respect the existing Content Advisory theme setting

Harbor already has a contentAdvisoryTheme setting, supporting both monochrome and colored severity indicators. The default is monochrome.

The new panel always uses fixed green, yellow, orange, and rose severity colors through severityColorStyle(), ignoring this preference.

Could you make the panel follow the same severity styling rules as the existing in-player Content Advisory toast? This would keep the two interfaces visually consistent and respect the user's selected theme.

4. [P2] Avoid permanently caching temporary IMDb failures

The provider currently caches null when IMDb returns an unsuccessful HTTP response.

If IMDb temporarily returns a 429, 500, or another server error, the Content Advisory section can remain unavailable for that title throughout the session, even after the service recovers.

Could you avoid caching transient request failures and use an expiry for genuinely unavailable guide data? The existing in-flight request deduplication can remain.

5. Empty sections and missing IMDb data

The section is added to the layout even when no valid IMDb ID is available or the guide has no content.

Since the layout still renders a lazy-mount wrapper, this can leave unnecessary empty space.

It would be better to avoid rendering the section entirely when no advisory data is available, while retaining a loading state when a valid request is still in progress.

6. IMDb data usage

One additional consideration: IMDb's GraphQL response includes restrictions on public and non-private use of its data. Could you confirm that the intended use of this endpoint is compatible with those requirements, or whether an approved alternative data source would be needed?

I'd also recommend adding focused regression tests for layout ordering, advisory fetching and caching, and theme selection.

Once these are addressed, I'll re-review the updated implementation.

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.

2 participants