From a825912ad3340b9cb8bd7ce6de044286f44abc65 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 3 Nov 2023 14:33:03 +0100 Subject: [PATCH] Add part of collection card on details page --- front/packages/models/src/resources/movie.ts | 6 +- front/packages/models/src/resources/show.ts | 5 ++ front/packages/ui/src/details/collection.tsx | 71 ++++++++++++++++++++ front/packages/ui/src/details/header.tsx | 14 ++++ front/packages/ui/src/details/movie.tsx | 2 +- front/packages/ui/src/details/show.tsx | 2 +- front/packages/ui/src/navbar/index.tsx | 2 +- front/translations/en.json | 3 +- front/translations/fr.json | 3 +- 9 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 front/packages/ui/src/details/collection.tsx diff --git a/front/packages/models/src/resources/movie.ts b/front/packages/models/src/resources/movie.ts index 024adca1..f6247d4f 100644 --- a/front/packages/models/src/resources/movie.ts +++ b/front/packages/models/src/resources/movie.ts @@ -24,6 +24,7 @@ import { withImages, ResourceP, imageFn } from "../traits"; import { Genre } from "./genre"; import { StudioP } from "./studio"; import { Status } from "./show"; +import { CollectionP } from "./collection"; export const MovieP = withImages( ResourceP.extend({ @@ -75,7 +76,10 @@ export const MovieP = withImages( * The studio that made this movie. */ studio: StudioP.optional().nullable(), - + /** + * The collection this movie is part of. + */ + collections: z.array(CollectionP).optional(), /** * The links to see a movie or an episode. */ diff --git a/front/packages/models/src/resources/show.ts b/front/packages/models/src/resources/show.ts index 66394ed8..0c77a35d 100644 --- a/front/packages/models/src/resources/show.ts +++ b/front/packages/models/src/resources/show.ts @@ -25,6 +25,7 @@ import { Genre } from "./genre"; import { SeasonP } from "./season"; import { StudioP } from "./studio"; import { BaseEpisodeP } from "./episode.base"; +import { CollectionP } from "./collection"; /** * The enum containing show's status. @@ -86,6 +87,10 @@ export const ShowP = withImages( * The studio that made this show. */ studio: StudioP.optional().nullable(), + /** + * The collection this movie is part of. + */ + collections: z.array(CollectionP).optional(), /** * The list of seasons of this show. */ diff --git a/front/packages/ui/src/details/collection.tsx b/front/packages/ui/src/details/collection.tsx new file mode 100644 index 00000000..e05bdc5b --- /dev/null +++ b/front/packages/ui/src/details/collection.tsx @@ -0,0 +1,71 @@ +/* + * Kyoo - A portable and vast media library solution. + * Copyright (c) Kyoo. + * + * See AUTHORS.md and LICENSE file in the project root for full license information. + * + * Kyoo is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * Kyoo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Kyoo. If not, see . + */ + +import { KyooImage } from "@kyoo/models"; +import { H2, ImageBackground, Link, P, focusReset, ts } from "@kyoo/primitives"; +import { useTranslation } from "react-i18next"; +import { Theme, useYoshiki } from "yoshiki/native"; + +export const PartOf = ({ + name, + overview, + thumbnail, + href, +}: { + name: string; + overview: string | null; + thumbnail: KyooImage | null; + href: string; +}) => { + const { css, theme } = useYoshiki("part-of-collection"); + const { t } = useTranslation(); + + return ( + theme.background, + fover: { + self: { ...focusReset, borderColor: (theme: Theme) => theme.accent }, + title: { textDecorationLine: "underline" }, + }, + })} + > + +

+ {t("show.partOf")} {name} +

+

{overview}

+
+ + ); +}; diff --git a/front/packages/ui/src/details/header.tsx b/front/packages/ui/src/details/header.tsx index d02a79d8..6539461a 100644 --- a/front/packages/ui/src/details/header.tsx +++ b/front/packages/ui/src/details/header.tsx @@ -69,6 +69,7 @@ import PlayArrow from "@material-symbols/svg-400/rounded/play_arrow-fill.svg"; import Theaters from "@material-symbols/svg-400/rounded/theaters-fill.svg"; import { Rating } from "../components/rating"; import { displayRuntime } from "./episode"; +import { PartOf } from "./collection"; export const TitleLine = ({ isLoading, @@ -406,6 +407,19 @@ export const Header = ({ tags={data?.tags} {...css({ paddingTop: { xs: 0, md: ts(2) } })} /> + {data?.collections && ( + + {data.collections.map((x) => ( + + ))} + + )} )} diff --git a/front/packages/ui/src/details/movie.tsx b/front/packages/ui/src/details/movie.tsx index c82d7219..f730ba12 100644 --- a/front/packages/ui/src/details/movie.tsx +++ b/front/packages/ui/src/details/movie.tsx @@ -28,7 +28,7 @@ const query = (slug: string): QueryIdentifier => ({ parser: MovieP, path: ["movies", slug], params: { - fields: ["studio"], + fields: ["studio", "collections"], }, }); diff --git a/front/packages/ui/src/details/show.tsx b/front/packages/ui/src/details/show.tsx index f4f45d2c..298d778b 100644 --- a/front/packages/ui/src/details/show.tsx +++ b/front/packages/ui/src/details/show.tsx @@ -81,7 +81,7 @@ const query = (slug: string): QueryIdentifier => ({ parser: ShowP, path: ["shows", slug], params: { - fields: ["studio", "firstEpisode"], + fields: ["studio", "firstEpisode", "collections"], }, }); diff --git a/front/packages/ui/src/navbar/index.tsx b/front/packages/ui/src/navbar/index.tsx index 6bddde31..249ffc6a 100644 --- a/front/packages/ui/src/navbar/index.tsx +++ b/front/packages/ui/src/navbar/index.tsx @@ -224,7 +224,7 @@ export const Navbar = (props: Stylable) => { props, )} > - +