Feat/continue watching card affordance (#120)
* feat(web): improve Continue Watching card affordances Add hover/active feedback to the play button (scale, brightness, shadow) and make the episode meta and time-left lines link to the item page like the heading. The blank time-left placeholder stays a plain div so card heights align without an invisible link. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(web): cover audiobook-only continue sections using poster cards Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
co-authored by
Claude Fable 5
parent
46540dfec3
commit
79c749b9a7
@@ -252,7 +252,7 @@ export default function ContinueWatchingCard(props: ContinueWatchingCardProps) {
|
||||
to={card.watchHref}
|
||||
onClick={handleWatchClick}
|
||||
aria-label={`Play ${heading}`}
|
||||
className="bg-primary text-primary-foreground absolute top-1/2 left-1/2 flex h-11 w-11 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full opacity-100 shadow-lg transition-all duration-200 pointer-fine:pointer-events-none pointer-fine:opacity-0 pointer-fine:group-hover/media:pointer-events-auto pointer-fine:group-hover/media:opacity-100 pointer-fine:focus-visible:pointer-events-auto pointer-fine:focus-visible:opacity-100"
|
||||
className="bg-primary text-primary-foreground absolute top-1/2 left-1/2 flex h-11 w-11 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full opacity-100 shadow-lg transition-all duration-200 hover:scale-110 hover:shadow-xl hover:brightness-110 active:scale-95 pointer-fine:pointer-events-none pointer-fine:opacity-0 pointer-fine:group-hover/media:pointer-events-auto pointer-fine:group-hover/media:opacity-100 pointer-fine:focus-visible:pointer-events-auto pointer-fine:focus-visible:opacity-100"
|
||||
>
|
||||
<Play className="ml-0.5 h-5 w-5" fill="currentColor" />
|
||||
</ViewTransitionLink>
|
||||
@@ -283,7 +283,14 @@ export default function ContinueWatchingCard(props: ContinueWatchingCardProps) {
|
||||
>
|
||||
{heading}
|
||||
</ViewTransitionLink>
|
||||
{episodeMeta && <div className="text-muted-foreground truncate text-xs">{episodeMeta}</div>}
|
||||
{episodeMeta && (
|
||||
<ViewTransitionLink
|
||||
to={card.itemHref}
|
||||
className="text-muted-foreground block truncate text-xs hover:underline"
|
||||
>
|
||||
{episodeMeta}
|
||||
</ViewTransitionLink>
|
||||
)}
|
||||
{premiereBadge && (
|
||||
<div className="mt-1">
|
||||
<span
|
||||
@@ -295,7 +302,17 @@ export default function ContinueWatchingCard(props: ContinueWatchingCardProps) {
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{timeLeftLabel && <div className="text-muted-foreground text-xs">{timeLeftLabel}</div>}
|
||||
{timeLeftLabel &&
|
||||
(timeLeftLabel === "\u00A0" ? (
|
||||
<div className="text-muted-foreground text-xs">{timeLeftLabel}</div>
|
||||
) : (
|
||||
<ViewTransitionLink
|
||||
to={card.itemHref}
|
||||
className="text-muted-foreground block w-fit text-xs hover:underline"
|
||||
>
|
||||
{timeLeftLabel}
|
||||
</ViewTransitionLink>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -121,6 +121,50 @@ describe("SectionRow", () => {
|
||||
expect(markup).toContain("More actions");
|
||||
});
|
||||
|
||||
it("renders all-audiobook continue sections as square poster cards", () => {
|
||||
const queryClient = new QueryClient();
|
||||
const section: ResolvedSection = {
|
||||
id: "continue-listening",
|
||||
section_type: "continue_watching",
|
||||
title: "Continue Listening",
|
||||
featured: false,
|
||||
item_limit: 10,
|
||||
total_count: 1,
|
||||
is_custom: false,
|
||||
customized: false,
|
||||
items: [
|
||||
{
|
||||
content_id: "book-001",
|
||||
type: "audiobook",
|
||||
title: "Project Hail Mary",
|
||||
position_seconds: 600,
|
||||
duration_seconds: 58000,
|
||||
year: 2021,
|
||||
genres: [],
|
||||
status: "matched",
|
||||
rating_imdb: null,
|
||||
overview: "",
|
||||
poster_url: "/book-cover.jpg",
|
||||
poster_thumbhash: "",
|
||||
backdrop_url: "",
|
||||
backdrop_thumbhash: "",
|
||||
logo_url: "",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const markup = renderToStaticMarkup(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<MemoryRouter>
|
||||
<SectionRow section={section} />
|
||||
</MemoryRouter>
|
||||
</QueryClientProvider>,
|
||||
);
|
||||
|
||||
expect(markup).toContain("aspect-square");
|
||||
expect(markup).not.toContain("aspect-video");
|
||||
});
|
||||
|
||||
it("routes supported section view-all actions to browse destinations", () => {
|
||||
const queryClient = new QueryClient();
|
||||
const section: ResolvedSection = {
|
||||
|
||||
Reference in New Issue
Block a user