From 872639dab9746d951b84e5e3200d9bef6bae30db Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sat, 21 Oct 2023 14:55:57 +0200 Subject: [PATCH] Add play button on the recommanded card --- .../models/src/resources/collection.ts | 25 ++++++----- .../models/src/resources/library-item.ts | 15 ++----- front/packages/models/src/resources/movie.ts | 7 +++- front/packages/models/src/resources/show.ts | 8 +++- front/packages/primitives/src/links.tsx | 4 +- front/packages/ui/src/details/header.tsx | 10 ++--- front/packages/ui/src/details/show.tsx | 3 +- front/packages/ui/src/home/index.tsx | 18 ++++---- front/packages/ui/src/home/recommanded.tsx | 42 ++++++++++++++++--- 9 files changed, 85 insertions(+), 47 deletions(-) diff --git a/front/packages/models/src/resources/collection.ts b/front/packages/models/src/resources/collection.ts index eb481db7..548b88ca 100644 --- a/front/packages/models/src/resources/collection.ts +++ b/front/packages/models/src/resources/collection.ts @@ -21,16 +21,21 @@ import { z } from "zod"; import { ImagesP, ResourceP } from "../traits"; -export const CollectionP = ResourceP.merge(ImagesP).extend({ - /** - * The title of this collection. - */ - name: z.string(), - /** - * The summary of this show. - */ - overview: z.string().nullable(), -}); +export const CollectionP = ResourceP.merge(ImagesP) + .extend({ + /** + * The title of this collection. + */ + name: z.string(), + /** + * The summary of this show. + */ + overview: z.string().nullable(), + }) + .transform((x) => ({ + ...x, + href: `/collection/${x.slug}`, + })); /** * A class representing collections of show or movies. diff --git a/front/packages/models/src/resources/library-item.ts b/front/packages/models/src/resources/library-item.ts index 01c2c08b..d3f648b7 100644 --- a/front/packages/models/src/resources/library-item.ts +++ b/front/packages/models/src/resources/library-item.ts @@ -36,24 +36,15 @@ export const LibraryItemP = z.union([ /* * Either a Show */ - ShowP.and(z.object({ kind: z.literal(ItemKind.Show) })).transform((x) => ({ - ...x, - href: `/show/${x.slug}`, - })), + ShowP.and(z.object({ kind: z.literal(ItemKind.Show) })), /* * Or a Movie */ - MovieP.and(z.object({ kind: z.literal(ItemKind.Movie) })).transform((x) => ({ - ...x, - href: `/movie/${x.slug}`, - })), + MovieP.and(z.object({ kind: z.literal(ItemKind.Movie) })), /* * Or a Collection */ - CollectionP.and(z.object({ kind: z.literal(ItemKind.Collection) })).transform((x) => ({ - ...x, - href: `/collection/${x.slug}`, - })), + CollectionP.and(z.object({ kind: z.literal(ItemKind.Collection) })), ]); /** diff --git a/front/packages/models/src/resources/movie.ts b/front/packages/models/src/resources/movie.ts index ca3d99fb..e3643af4 100644 --- a/front/packages/models/src/resources/movie.ts +++ b/front/packages/models/src/resources/movie.ts @@ -92,7 +92,12 @@ export const MovieP = ResourceP.merge(ImagesP) } } return x; - }); + }) + .transform((x) => ({ + ...x, + href: `/movie/${x.slug}`, + playHref: `/movie/${x.slug}/watch`, + })); /** * A Movie type diff --git a/front/packages/models/src/resources/show.ts b/front/packages/models/src/resources/show.ts index 3b1b2d5b..dd685520 100644 --- a/front/packages/models/src/resources/show.ts +++ b/front/packages/models/src/resources/show.ts @@ -95,7 +95,13 @@ export const ShowP = ResourceP.merge(ImagesP) } } return x; - }); + }) + .transform((x) => ({ + href: `/show/${x.slug}`, + playHref: `/watch/${x.slug}-s1e1`, + ...x, + })) +; /** * A tv serie or an anime. diff --git a/front/packages/primitives/src/links.tsx b/front/packages/primitives/src/links.tsx index 4abca546..152c259b 100644 --- a/front/packages/primitives/src/links.tsx +++ b/front/packages/primitives/src/links.tsx @@ -86,9 +86,9 @@ export const Link = ({ target, children, ...props -}: { href: string; target?: string; replace?: boolean } & PressableProps) => { +}: { href?: string; target?: string; replace?: boolean } & PressableProps) => { const linkProps = useLink({ - href, + href: href ?? "#", replace, experimental: { nativeBehavior: "stack-replace", isNestedNavigator: false }, }); diff --git a/front/packages/ui/src/details/header.tsx b/front/packages/ui/src/details/header.tsx index a697de9f..83145656 100644 --- a/front/packages/ui/src/details/header.tsx +++ b/front/packages/ui/src/details/header.tsx @@ -69,7 +69,7 @@ import Theaters from "@material-symbols/svg-400/rounded/theaters-fill.svg"; const TitleLine = ({ isLoading, - slug, + playHref, name, tagline, date, @@ -80,7 +80,7 @@ const TitleLine = ({ ...props }: { isLoading: boolean; - slug: string; + playHref?: string; name?: string; tagline?: string | null; date?: string | null; @@ -195,7 +195,7 @@ const TitleLine = ({ ; type: "movie" | "show"; - slug: string; }) => { const { css } = useYoshiki(); @@ -376,7 +374,7 @@ export const Header = ({ (function ShowH props, )} > - {/* TODO: Remove the slug quickfix for the play button */} -
+
{/* */} = ({ randomItems }) => { tagline={"tagline" in x ? x.tagline : null} overview={x.overview} thumbnail={x.thumbnail} - link={x.kind === ItemKind.Show ? `/watch/${x.slug}-s1e1` : `/movie/${x.slug}/watch`} + link={x.kind !== ItemKind.Collection && !x.isLoading ? x.playHref : undefined} infoLink={x.href} /> )} {/* */} - {randomItems.filter((_, i) => i < 2).map((x) => - , - )} + {randomItems + .filter((_, i) => i < 2) + .map((x) => ( + + ))} - {randomItems.filter((_, i) => i >= 2).map((x) => - , - )} + {randomItems + .filter((_, i) => i >= 2) + .map((x) => ( + + ))} ); }; diff --git a/front/packages/ui/src/home/recommanded.tsx b/front/packages/ui/src/home/recommanded.tsx index 001c7435..bb035bcb 100644 --- a/front/packages/ui/src/home/recommanded.tsx +++ b/front/packages/ui/src/home/recommanded.tsx @@ -29,12 +29,25 @@ import { QueryIdentifier, getDisplayDate, } from "@kyoo/models"; -import { Chip, Container, H3, ImageBackground, P, Poster, SubP, alpha, ts } from "@kyoo/primitives"; +import { + Chip, + Container, + H3, + IconFab, + ImageBackground, + Link, + P, + Poster, + SubP, + alpha, + ts, +} from "@kyoo/primitives"; import { useTranslation } from "react-i18next"; import { ScrollView, View } from "react-native"; -import { percent, px, useYoshiki } from "yoshiki/native"; +import { calc, percent, px, rem, useYoshiki } from "yoshiki/native"; import { Fetch, Layout, WithLoading } from "../fetch"; import { InfiniteFetch } from "../fetch-infinite"; +import PlayArrow from "@material-symbols/svg-400/rounded/play_arrow-fill.svg"; export const ItemDetails = ({ isLoading, @@ -44,6 +57,7 @@ export const ItemDetails = ({ overview, poster, genres, + playHref, ...props }: WithLoading<{ name: string; @@ -52,6 +66,7 @@ export const ItemDetails = ({ poster: KyooImage | null; genres: Genre[] | null; overview: string | null; + playHref: string; }>) => { const { css } = useYoshiki(); @@ -96,10 +111,24 @@ export const ItemDetails = ({ {overview} )} - theme.themeOverlay, flexDirection: "row" })}> - {genres?.map((x) => ( - - ))} + theme.themeOverlay, + flexDirection: "row", + justifyContent: "space-between", + minHeight: px(50), + })} + > + + {genres?.slice(0, 2).map((x) => )} + + @@ -133,6 +162,7 @@ export const Recommanded = () => { x.kind !== ItemKind.Collection && !x.isLoading ? getDisplayDate(x) : undefined } genres={"genres" in x ? x.genres : null} + playHref={x.kind !== ItemKind.Collection && !x.isLoading ? x.playHref : undefined} /> )}