feat(audiobooks): add narrator card to detail page
Surfaces the narrator as a first-class card with a circular initials avatar. Rendered only when data.narrator is present, so audiobooks without narrator metadata don't introduce empty space. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
9013718b2d
commit
07da12f8f4
@@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Play } from "lucide-react";
|
||||
import AudiobookPlayer from "./player/AudiobookPlayer";
|
||||
import { ChaptersSection } from "./components/ChaptersSection";
|
||||
import { NarratorCard } from "./components/NarratorCard";
|
||||
import DetailHero from "@/pages/ItemDetail/DetailHero";
|
||||
import MetadataBadges from "@/pages/ItemDetail/components/MetadataBadges";
|
||||
import type { AudiobookChapter, AudiobookFile } from "@/lib/audiobooks/types";
|
||||
@@ -229,6 +230,7 @@ export default function AudiobookDetail() {
|
||||
currentPositionSeconds={playerOpen ? startSeconds : resumeSeconds || null}
|
||||
onSelect={(s) => openPlayer(s)}
|
||||
/>
|
||||
{narrator && <NarratorCard narrator={narrator} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
interface NarratorCardProps {
|
||||
narrator: string;
|
||||
}
|
||||
|
||||
function initials(name: string): string {
|
||||
return name
|
||||
.split(/\s+/)
|
||||
.filter(Boolean)
|
||||
.slice(0, 2)
|
||||
.map((w) => w[0]?.toUpperCase() ?? "")
|
||||
.join("");
|
||||
}
|
||||
|
||||
export function NarratorCard({ narrator }: NarratorCardProps) {
|
||||
return (
|
||||
<section className="mt-10">
|
||||
<h2 className="mb-4 text-xl font-semibold tracking-tight">Narrator</h2>
|
||||
<div className="bg-muted/30 flex items-center gap-4 rounded-xl border p-4">
|
||||
<div className="bg-muted text-muted-foreground flex h-16 w-16 shrink-0 items-center justify-center rounded-full text-lg font-medium">
|
||||
{initials(narrator) || "?"}
|
||||
</div>
|
||||
<div className="min-w-0">
|
||||
<p className="truncate text-base font-medium">{narrator}</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user