feat(plex): P1 frontend — Plex feed source, browse/search, show drill-down

- PlexBrowse.tsx: self-contained Plex mode (library scope tabs, own search +
  sort, poster-card grid with watch state + playability tint, paged; show →
  seasons/episodes drill-down). Playback announces (P2 wires the real player).
- Feed source dropdown gains a 'Plex' option (gated on me.plex_enabled); App
  swaps <Feed> for <PlexBrowse> when librarySource==='plex' so the video-feed
  hooks don't run in Plex mode. me exposes plex_enabled.
- api client (plexLibraries/plexBrowse/plexShow/plexImageUrl) + types; librarySource
  union + share-URL restore gain 'plex'; new plex i18n namespace en/hu/de.
- Verified over HTTP (authed): libraries, browse+FTS, image proxy 200 image/jpeg.
This commit is contained in:
npeter83 2026-07-05 02:32:00 +02:00
parent 63c6e782c8
commit 62636319b1
12 changed files with 452 additions and 5 deletions

View file

@ -12,6 +12,7 @@ from app.auth import (
optional_current_user,
purge_user,
)
from app import sysconfig
from app.db import get_db
from app.models import Invite, User
@ -98,6 +99,8 @@ def get_me(
# Instance-wide: whether Google sign-in / YouTube connect is available at all (the UI hides
# YouTube-access affordances and the onboarding nudge when it isn't configured).
"google_enabled": google_enabled(db),
# Whether the optional Plex module is enabled (UI shows the Plex feed source when so).
"plex_enabled": sysconfig.get_bool(db, "plex_enabled"),
"can_read": has_read_scope(user),
"can_write": has_write_scope(user),
"pending_invites": pending_invites,