fix(ui): the Plex detail poster keeps its 2:3, and a long crew shows its first names
The hero's grid row is as tall as the crew column beside the text, and the poster, a flex child, stretched to it: a 2:3 picture drawn ~175x590 and cropped. It now aligns to the top, and a wide hero gives the movie and show poster a bigger rung (w-56). The crew, the hero's tallest part, shows its first 6 names and a 'Show N more' toggle; a list of 8 or fewer shows whole.
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { useState, type ReactNode } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import type { PlexFilters } from "../lib/api";
|
||||
import { formatMoney, formatRuntime } from "../lib/format";
|
||||
import type { AsideSection, DetailAsideState, DetailFacts } from "../lib/plexDetail";
|
||||
import { regionName, vocab } from "../lib/vocab";
|
||||
import { Filterable, PrefToggle } from "./plexDetailUi";
|
||||
import { Button } from "./ui/Button";
|
||||
import { Pressable } from "./ui/Pressable";
|
||||
|
||||
// The detail pages' second column (E31, the owner's pick "A"): the TMDB facts and key crew of a movie or
|
||||
@@ -180,6 +181,12 @@ export function DetailKeywords({
|
||||
);
|
||||
}
|
||||
|
||||
// The crew shows its first CREW_SHOWN names and a "Show N more" that opens the rest: the column beside the
|
||||
// text is the hero's tallest part, and twelve names ran it ~170px past the text (E31, the owner's call).
|
||||
// A list only a little longer than that shows whole: a toggle that hides one or two names saves no room.
|
||||
export const CREW_SHOWN = 6;
|
||||
const CREW_FOLD_OVER = CREW_SHOWN + 2;
|
||||
|
||||
// The TMDB key crew (E5 S5) — Director / Writer / Producer / …, each opening their person page. It
|
||||
// complements the hero's Director line (which comes from Plex directly).
|
||||
function CrewSection({
|
||||
@@ -190,12 +197,15 @@ function CrewSection({
|
||||
onOpenPerson?: (name: string) => void;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [all, setAll] = useState(false);
|
||||
const folds = crew.length > CREW_FOLD_OVER;
|
||||
const shown = folds && !all ? crew.slice(0, CREW_SHOWN) : crew;
|
||||
return (
|
||||
<section>
|
||||
<h2 className="mb-3 text-sm font-semibold">{t("plex.info.crew")}</h2>
|
||||
{/* As many name columns as the column holds: two in the hero's side column, one when narrow. */}
|
||||
<div className="grid grid-cols-[repeat(auto-fill,minmax(10rem,1fr))] gap-x-3 gap-y-1.5">
|
||||
{crew.map((c, i) => (
|
||||
{shown.map((c, i) => (
|
||||
<div key={`${c.name}:${c.job}:${i}`} className="min-w-0">
|
||||
{onOpenPerson ? (
|
||||
<Pressable
|
||||
@@ -213,6 +223,18 @@ function CrewSection({
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{folds && (
|
||||
<Button
|
||||
variant={all ? "link-muted" : "link"}
|
||||
aria-expanded={all}
|
||||
onClick={() => setAll((v) => !v)}
|
||||
className="mt-2 text-sm"
|
||||
>
|
||||
{all
|
||||
? t("plex.info.crewLess")
|
||||
: t("plex.info.crewMore", { count: crew.length - CREW_SHOWN })}
|
||||
</Button>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user