Add play button on the recommanded card

This commit is contained in:
Zoe Roux 2023-10-21 14:55:57 +02:00
parent e4562648ba
commit 872639dab9
9 changed files with 85 additions and 47 deletions

View File

@ -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.

View File

@ -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) })),
]);
/**

View File

@ -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

View File

@ -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.

View File

@ -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 },
});

View File

@ -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 = ({
<IconFab
icon={PlayArrow}
as={Link}
href={type === "show" ? `/watch/${slug}` : `/movie/${slug}/watch`}
href={playHref}
color={{ xs: theme.user.colors.black, md: theme.colors.black }}
{...css({
bg: theme.user.accent,
@ -346,11 +346,9 @@ const Description = ({
export const Header = ({
query,
type,
slug,
}: {
query: QueryIdentifier<Show | Movie>;
type: "movie" | "show";
slug: string;
}) => {
const { css } = useYoshiki();
@ -376,7 +374,7 @@ export const Header = ({
<TitleLine
isLoading={isLoading}
type={type}
slug={slug}
playHref={data?.playHref}
name={data?.name}
tagline={data?.tagline}
date={data ? getDisplayDate(data as any) : undefined}

View File

@ -68,8 +68,7 @@ const ShowHeader = forwardRef<View, ViewProps & { slug: string }>(function ShowH
props,
)}
>
{/* TODO: Remove the slug quickfix for the play button */}
<Header slug={`${slug}-s1e1`} type="show" query={query(slug)} />
<Header type="show" query={query(slug)} />
{/* <Staff slug={slug} /> */}
<SvgWave
fill={theme.variant.background}

View File

@ -37,19 +37,23 @@ export const HomePage: QueryPage<{}, Genre> = ({ 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}
/>
)}
</Fetch>
{/* <News /> */}
{randomItems.filter((_, i) => i < 2).map((x) =>
<GenreGrid key={x} genre={x} />,
)}
{randomItems
.filter((_, i) => i < 2)
.map((x) => (
<GenreGrid key={x} genre={x} />
))}
<Recommanded />
{randomItems.filter((_, i) => i >= 2).map((x) =>
<GenreGrid key={x} genre={x} />,
)}
{randomItems
.filter((_, i) => i >= 2)
.map((x) => (
<GenreGrid key={x} genre={x} />
))}
</ScrollView>
);
};

View File

@ -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 = ({
<SubP {...css({ pX: ts(1) })}>{overview}</SubP>
</ScrollView>
)}
<View {...css({ bg: (theme) => theme.themeOverlay, flexDirection: "row" })}>
{genres?.map((x) => (
<Chip key={x} label={x} {...css({ mX: ts(.5) })} />
))}
<View
{...css({
bg: (theme) => theme.themeOverlay,
flexDirection: "row",
justifyContent: "space-between",
minHeight: px(50),
})}
>
<View {...css({ flexDirection: "row" })}>
{genres?.slice(0, 2).map((x) => <Chip key={x} label={x} {...css({ mX: ts(0.5) })} />)}
</View>
<IconFab
icon={PlayArrow}
size={20}
as={Link}
href={playHref ?? "#"}
{...css({ fover: { self: { transform: "scale(1.2)" as any, mX: ts(0.5) } } })}
/>
</View>
</View>
</View>
@ -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}
/>
)}
</InfiniteFetch>