2026-07-05 02:32:00 +02:00
{
2026-07-05 03:29:20 +02:00
"navLabel" : "Plex" ,
2026-07-05 02:32:00 +02:00
"backToFeed" : "YouTube feed" ,
"backToLibrary" : "Back to library" ,
"searchPlaceholder" : "Search Plex…" ,
"sort" : {
"added" : "Recently added" ,
feat(plex): expanded metadata filters, clickable info page, image disk cache
Backend (migration 0045_plex_filter_meta): plex_items gains rating (audienceRating
~IMDb), content_rating, studio, originally_available_at, and GIN-indexed genres /
directors / cast_names — all mirrored from the cheap section listing (no per-item API
calls; they also seed a future watch-habit recommender). /browse gains genre / content-
rating / year / rating / duration / added-within / director / actor / studio filters
(@> containment, GIN) + sort by year|rating|duration|release; new /facets endpoint
returns available genres+ratings (with counts) and the year/rating/duration bounds. A
thin on-disk image cache (.plex-img-cache) serves posters/art/cast photos from local
disk after first fetch (~7-14x faster repeat loads).
Frontend: PlexSidebar grows the full filter set (facet-driven genre/age chips, rating
steps, year range inputs, duration buckets, added-within, active people/studio chips,
clear-all); filters persist per-account as one JSON blob. PlexInfo metadata (year,
genre, director, cast, studio, IMDb score) is clickable → sets the matching filter and
returns to the filtered grid (page variant only; the in-player overlay stays read-only
so a stray click can't stop playback). i18n en/hu/de.
2026-07-05 23:45:55 +02:00
"title" : "Title" ,
"year" : "Year" ,
"rating" : "IMDb rating" ,
"duration" : "Length" ,
"release" : "Release date"
2026-07-05 02:32:00 +02:00
} ,
2026-07-05 03:29:20 +02:00
"filter" : {
"library" : "Library" ,
"show" : "Show" ,
"showOpt" : {
"all" : "All" ,
"unwatched" : "Unwatched" ,
"in_progress" : "In progress" ,
"watched" : "Watched"
} ,
feat(plex): expanded metadata filters, clickable info page, image disk cache
Backend (migration 0045_plex_filter_meta): plex_items gains rating (audienceRating
~IMDb), content_rating, studio, originally_available_at, and GIN-indexed genres /
directors / cast_names — all mirrored from the cheap section listing (no per-item API
calls; they also seed a future watch-habit recommender). /browse gains genre / content-
rating / year / rating / duration / added-within / director / actor / studio filters
(@> containment, GIN) + sort by year|rating|duration|release; new /facets endpoint
returns available genres+ratings (with counts) and the year/rating/duration bounds. A
thin on-disk image cache (.plex-img-cache) serves posters/art/cast photos from local
disk after first fetch (~7-14x faster repeat loads).
Frontend: PlexSidebar grows the full filter set (facet-driven genre/age chips, rating
steps, year range inputs, duration buckets, added-within, active people/studio chips,
clear-all); filters persist per-account as one JSON blob. PlexInfo metadata (year,
genre, director, cast, studio, IMDb score) is clickable → sets the matching filter and
returns to the filtered grid (page variant only; the in-player overlay stays read-only
so a stray click can't stop playback). i18n en/hu/de.
2026-07-05 23:45:55 +02:00
"sort" : "Sort" ,
"clearAll" : "Clear filters" ,
"active" : "Active" ,
"any" : "Any" ,
"rating" : "IMDb rating" ,
"genre" : "Genre" ,
"year" : "Year" ,
"duration" : "Length" ,
"durationOpt" : { "short" : "Under 90m" , "mid" : "90– 120m" , "long" : "Over 2h" } ,
"added" : "Added to Plex" ,
"addedOpt" : { "24h" : "24h" , "1w" : "1 week" , "1m" : "1 month" , "6m" : "6 months" , "1y" : "1 year" } ,
2026-07-06 00:15:31 +02:00
"contentRating" : "Age rating" ,
"match" : { "any" : "Any" , "all" : "All" } ,
"dir" : { "desc" : "↓ Descending" , "asc" : "↑ Ascending" }
2026-07-05 03:29:20 +02:00
} ,
2026-07-05 02:32:00 +02:00
"count" : "{{count}} titles" ,
"searchCount" : "{{count}} matches" ,
2026-07-05 03:29:20 +02:00
"noMatches" : "No matches." ,
2026-07-05 02:32:00 +02:00
"loading" : "Loading…" ,
"empty" : "Nothing here yet. Run a Plex sync from the admin Config page." ,
"loadMore" : "Load more" ,
"watched" : "Watched" ,
2026-07-05 05:26:16 +02:00
"play" : "Play" ,
"resume" : "Resume" ,
"openShow" : "Open show" ,
"markWatched" : "Mark watched" ,
"markUnwatched" : "Mark unwatched" ,
2026-07-05 02:32:00 +02:00
"seasons" : "{{count}} seasons" ,
"playerSoon" : "Player coming soon — “{{title}}”" ,
feat(plex): P2 player — rich full-page HLS/direct player + watch-state
- backend: GET /api/plex/item/{rk} detail (metadata, cast + intro/credit markers
from Plex, episode prev/next, per-user resume+status); POST /item/{rk}/progress
(resume checkpoint, near-end→watched) + /state (new|watched|hidden).
- frontend PlexPlayer.tsx (lazy, pulls hls.js): full-page player over the Plex
module. Direct files stream raw <video>; remux via hls.js on the seek-restart
session — custom controls map the ABSOLUTE timeline over the session offset, and a
seek beyond the loaded region restarts the session at the target. Play/pause/resume
/restart, ±10s seek, prev/next episode (Shift+←/→), volume, windowed/fullscreen,
full keyboard, Skip intro/Skip credits from markers (shaded on the seekbar),
auto-advance + watched-on-end, resume from saved position, 10s progress checkpoints.
- PlexBrowse: card/episode click opens the player as a history subview (browser Back
returns to the grid/show). api client (plexItem/plexSession/plexProgress/plexSetState)
+ types; plex.player.* i18n en/hu/de. hls.js@^1.6.16.
- Verified over HTTP: detail w/ markers+cast+episode-nav, progress persist. Video
playback itself is pending browser UAT. Subtitle/audio track SELECTION deferred.
2026-07-05 04:28:00 +02:00
"player" : {
"loading" : "Loading…" ,
"back" : "Back" ,
"skipIntro" : "Skip intro" ,
"skipCredits" : "Skip credits" ,
"playPause" : "Play / pause (space)" ,
"restart" : "Restart from beginning" ,
"prev" : "Previous episode" ,
"next" : "Next episode" ,
"mute" : "Mute (m)" ,
2026-07-05 05:26:16 +02:00
"fullscreen" : "Fullscreen (f)" ,
2026-07-05 06:08:44 +02:00
"download" : "Download original file" ,
"tracks" : "Audio & subtitles" ,
"audio" : "Audio" ,
"subtitles" : "Subtitles" ,
2026-07-05 06:58:34 +02:00
"subOff" : "Off" ,
"errNotFound" : "This file can't be played — the media isn't reachable on the server (the Plex media mount is missing or the path map is wrong). Ask the admin to check the Plex configuration." ,
"errTranscode" : "This file's format needs transcoding, which isn't supported yet." ,
2026-07-05 21:27:02 +02:00
"errGeneric" : "Playback couldn't start. Please try again." ,
"stop" : "Stop" ,
"help" : "Keyboard shortcuts" ,
feat(plex): rich media info — info page, in-player info overlay, IMDb + cast photos
Backend (no migration): item_detail now also returns IMDb score + id/url (from the
Plex Rating/Guid arrays), content rating, genres, director(s), studio, tagline, and
cast as {name, role, photo}. New host-whitelisted /person-image proxy serves cast
photos from Plex's public metadata CDN (keeps third-party requests off the browser).
Frontend: reusable PlexInfo component in two forms — a full info page opened from a
card's 'i' button (history subview, art backdrop, Play/Resume + watch controls) and a
lean overlay in the player toggled with 'I' (video keeps playing). Two per-user view
prefs (faint backdrop, cast row) persisted in preferences. Mark-unwatched / clear-resume
cover the watched-reset gap. i18n en/hu/de.
2026-07-05 22:57:18 +02:00
"infoBtn" : "Media info" ,
2026-07-05 21:27:02 +02:00
"keys" : {
"playPause" : "Play / pause" ,
"seek" : "Seek 10 seconds" ,
"episode" : "Previous / next episode" ,
"volume" : "Volume up / down" ,
"mute" : "Mute" ,
"fullscreen" : "Fullscreen" ,
feat(plex): rich media info — info page, in-player info overlay, IMDb + cast photos
Backend (no migration): item_detail now also returns IMDb score + id/url (from the
Plex Rating/Guid arrays), content rating, genres, director(s), studio, tagline, and
cast as {name, role, photo}. New host-whitelisted /person-image proxy serves cast
photos from Plex's public metadata CDN (keeps third-party requests off the browser).
Frontend: reusable PlexInfo component in two forms — a full info page opened from a
card's 'i' button (history subview, art backdrop, Play/Resume + watch controls) and a
lean overlay in the player toggled with 'I' (video keeps playing). Two per-user view
prefs (faint backdrop, cast row) persisted in preferences. Mark-unwatched / clear-resume
cover the watched-reset gap. i18n en/hu/de.
2026-07-05 22:57:18 +02:00
"info" : "Media info" ,
2026-07-05 21:27:02 +02:00
"back" : "Stop & back to feed" ,
"help" : "Show this help"
}
feat(plex): P2 player — rich full-page HLS/direct player + watch-state
- backend: GET /api/plex/item/{rk} detail (metadata, cast + intro/credit markers
from Plex, episode prev/next, per-user resume+status); POST /item/{rk}/progress
(resume checkpoint, near-end→watched) + /state (new|watched|hidden).
- frontend PlexPlayer.tsx (lazy, pulls hls.js): full-page player over the Plex
module. Direct files stream raw <video>; remux via hls.js on the seek-restart
session — custom controls map the ABSOLUTE timeline over the session offset, and a
seek beyond the loaded region restarts the session at the target. Play/pause/resume
/restart, ±10s seek, prev/next episode (Shift+←/→), volume, windowed/fullscreen,
full keyboard, Skip intro/Skip credits from markers (shaded on the seekbar),
auto-advance + watched-on-end, resume from saved position, 10s progress checkpoints.
- PlexBrowse: card/episode click opens the player as a history subview (browser Back
returns to the grid/show). api client (plexItem/plexSession/plexProgress/plexSetState)
+ types; plex.player.* i18n en/hu/de. hls.js@^1.6.16.
- Verified over HTTP: detail w/ markers+cast+episode-nav, progress persist. Video
playback itself is pending browser UAT. Subtitle/audio track SELECTION deferred.
2026-07-05 04:28:00 +02:00
} ,
feat(plex): rich media info — info page, in-player info overlay, IMDb + cast photos
Backend (no migration): item_detail now also returns IMDb score + id/url (from the
Plex Rating/Guid arrays), content rating, genres, director(s), studio, tagline, and
cast as {name, role, photo}. New host-whitelisted /person-image proxy serves cast
photos from Plex's public metadata CDN (keeps third-party requests off the browser).
Frontend: reusable PlexInfo component in two forms — a full info page opened from a
card's 'i' button (history subview, art backdrop, Play/Resume + watch controls) and a
lean overlay in the player toggled with 'I' (video keeps playing). Two per-user view
prefs (faint backdrop, cast row) persisted in preferences. Mark-unwatched / clear-resume
cover the watched-reset gap. i18n en/hu/de.
2026-07-05 22:57:18 +02:00
"info" : {
"title" : "Media info" ,
"customize" : "Customize view" ,
"prefArtBg" : "Faint backdrop" ,
"prefCast" : "Cast & crew" ,
"openImdb" : "Open on IMDb" ,
"director" : "Director" ,
"cast" : "Cast & crew" ,
"markWatched" : "Mark watched" ,
"markUnwatched" : "Mark unwatched" ,
feat(plex): expanded metadata filters, clickable info page, image disk cache
Backend (migration 0045_plex_filter_meta): plex_items gains rating (audienceRating
~IMDb), content_rating, studio, originally_available_at, and GIN-indexed genres /
directors / cast_names — all mirrored from the cheap section listing (no per-item API
calls; they also seed a future watch-habit recommender). /browse gains genre / content-
rating / year / rating / duration / added-within / director / actor / studio filters
(@> containment, GIN) + sort by year|rating|duration|release; new /facets endpoint
returns available genres+ratings (with counts) and the year/rating/duration bounds. A
thin on-disk image cache (.plex-img-cache) serves posters/art/cast photos from local
disk after first fetch (~7-14x faster repeat loads).
Frontend: PlexSidebar grows the full filter set (facet-driven genre/age chips, rating
steps, year range inputs, duration buckets, added-within, active people/studio chips,
clear-all); filters persist per-account as one JSON blob. PlexInfo metadata (year,
genre, director, cast, studio, IMDb score) is clickable → sets the matching filter and
returns to the filtered grid (page variant only; the in-player overlay stays read-only
so a stray click can't stop playback). i18n en/hu/de.
2026-07-05 23:45:55 +02:00
"clearResume" : "Clear resume position" ,
"filterYear" : "Show titles from {{year}}" ,
"filterRating" : "Show titles rated {{n}}+" ,
"filterActor" : "Show titles with {{name}}"
feat(plex): rich media info — info page, in-player info overlay, IMDb + cast photos
Backend (no migration): item_detail now also returns IMDb score + id/url (from the
Plex Rating/Guid arrays), content rating, genres, director(s), studio, tagline, and
cast as {name, role, photo}. New host-whitelisted /person-image proxy serves cast
photos from Plex's public metadata CDN (keeps third-party requests off the browser).
Frontend: reusable PlexInfo component in two forms — a full info page opened from a
card's 'i' button (history subview, art backdrop, Play/Resume + watch controls) and a
lean overlay in the player toggled with 'I' (video keeps playing). Two per-user view
prefs (faint backdrop, cast row) persisted in preferences. Mark-unwatched / clear-resume
cover the watched-reset gap. i18n en/hu/de.
2026-07-05 22:57:18 +02:00
} ,
2026-07-05 02:32:00 +02:00
"playable" : {
"direct" : "Plays directly in the browser" ,
"remux" : "Needs a light remux (no video re-encode)" ,
"transcode" : "Needs transcoding (heavier)"
}
}