+ );
+}
+
// --- Series drill-down: show detail page → season subpage → player -------------------------------
// Both the show page and the season page read the SAME cached qk.plexShow(showId) payload (the
// season page just picks its season out of it), so opening a season is instant and PlexPlaylistAdd's
@@ -832,11 +979,14 @@ function SeasonCard({
function CastStrip({
cast,
onFilter,
+ onOpenPerson,
}: {
cast: PlexCastMember[];
onFilter?: (patch: Partial) => void;
+ onOpenPerson?: (name: string) => void;
}) {
const { t } = useTranslation();
+ const clickable = !!(onOpenPerson || onFilter);
return (
{c.thumb ? (
@@ -859,18 +1009,24 @@ function CastStrip({
)}
{c.name}
{c.role &&
{c.role}
}
>
);
- return onFilter ? (
+ return clickable ? (
- {show.cast.length > 0 && showCast && }
+ {show.cast.length > 0 && showCast && (
+
+ )}
{d.related.length > 0 && showRelated && (
)}
diff --git a/frontend/src/components/PlexInfo.tsx b/frontend/src/components/PlexInfo.tsx
index 9440fdf4..d320bb85 100644
--- a/frontend/src/components/PlexInfo.tsx
+++ b/frontend/src/components/PlexInfo.tsx
@@ -31,6 +31,8 @@ type Props = {
// When provided, metadata (year/genre/director/cast/studio/rating) becomes clickable and sets
// the corresponding Plex filter (then the opener navigates to the filtered grid).
onFilter?: (patch: Partial) => void;
+ // When provided, a cast member's photo/name opens their filmography page instead of filtering.
+ onOpenPerson?: (name: string) => void;
// Play a sibling title from a collection strip (opens its player).
onPlayItem?: (id: string) => void;
// The item's library key — enables the admin "Manage collections" editor (page variant, movies).
@@ -44,6 +46,7 @@ export default function PlexInfo({
onClose,
onStateChange,
onFilter,
+ onOpenPerson,
onPlayItem,
library,
}: Props) {
@@ -341,12 +344,13 @@ export default function PlexInfo({