diff --git a/front/apps/mobile/app/collection/[slug]/index.tsx b/front/apps/mobile/app/collection/[slug]/index.tsx new file mode 100644 index 00000000..58686664 --- /dev/null +++ b/front/apps/mobile/app/collection/[slug]/index.tsx @@ -0,0 +1,27 @@ +/* + * 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 { CollectionPage } from "@kyoo/ui"; +import { withRoute } from "../../../utils"; + +export default withRoute(CollectionPage, { + options: { headerTransparent: true, headerStyle: { backgroundColor: "transparent" } }, + statusBar: { barStyle: "light-content" }, +}); diff --git a/front/apps/web/src/pages/collection/[slug]/index.tsx b/front/apps/web/src/pages/collection/[slug]/index.tsx new file mode 100644 index 00000000..afc0749b --- /dev/null +++ b/front/apps/web/src/pages/collection/[slug]/index.tsx @@ -0,0 +1,24 @@ +/* + * 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 { CollectionPage } from "@kyoo/ui"; +import { withRoute } from "~/router"; + +export default withRoute(CollectionPage); diff --git a/front/packages/ui/src/collection/index.tsx b/front/packages/ui/src/collection/index.tsx new file mode 100644 index 00000000..7a24e8eb --- /dev/null +++ b/front/packages/ui/src/collection/index.tsx @@ -0,0 +1,171 @@ +/* + * 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 { + Collection, + CollectionP, + ItemKind, + LibraryItem, + LibraryItemP, + QueryIdentifier, + QueryPage, + getDisplayDate, +} from "@kyoo/models"; +import { Header as ShowHeader, TitleLine } from "../details/header"; +import { Container, ImageBackground, P, Skeleton, ts } from "@kyoo/primitives"; +import { percent, px, useYoshiki } from "yoshiki/native"; +import { useTranslation } from "react-i18next"; +import { forwardRef } from "react"; +import { Platform, View, ViewProps } from "react-native"; +import { Fetch } from "../fetch"; +import { InfiniteFetch } from "../fetch-infinite"; +import { DefaultLayout } from "../layout"; +import { ItemDetails } from "../home/recommanded"; +import { SvgWave } from "../details/show"; + +const Header = ({ slug }: { slug: string }) => { + const { css } = useYoshiki(); + const { t } = useTranslation(); + + return ( + + {({ isLoading, ...data }) => ( + <> + + + + + + + {isLoading || ( +

{data.overview ?? t("show.noOverview")}

+ )} +
+
+ + )} +
+ ); +}; + +Header.query = (slug: string): QueryIdentifier => ({ + parser: CollectionP, + path: ["collections", slug], +}); + +const CollectionHeader = forwardRef(function ShowHeader( + { children, slug, ...props }, + ref, +) { + const { css, theme } = useYoshiki(); + + return ( + theme.variant.background }, + Platform.OS === "web" && { + flexGrow: 1, + flexShrink: 1, + // @ts-ignore Web only property + overflowY: "auto" as any, + }, + ], + props, + )} + > +
+ + + + {children} + + + + ); +}); + +const query = (slug: string): QueryIdentifier => ({ + parser: LibraryItemP, + path: ["collections", slug, "items"], + infinite: true, +}); + +export const CollectionPage: QueryPage<{ slug: string }> = ({ slug }) => { + const { css } = useYoshiki(); + + return ( + + {(x) => ( + + )} + + ); +}; + +CollectionPage.getLayout = { Layout: DefaultLayout, props: { transparent: true } }; + +CollectionPage.getFetchUrls = ({ slug }) => [query(slug), Header.query(slug)]; diff --git a/front/packages/ui/src/details/header.tsx b/front/packages/ui/src/details/header.tsx index 2c1fce5b..d02a79d8 100644 --- a/front/packages/ui/src/details/header.tsx +++ b/front/packages/ui/src/details/header.tsx @@ -70,7 +70,7 @@ import Theaters from "@material-symbols/svg-400/rounded/theaters-fill.svg"; import { Rating } from "../components/rating"; import { displayRuntime } from "./episode"; -const TitleLine = ({ +export const TitleLine = ({ isLoading, playHref, name, @@ -89,12 +89,12 @@ const TitleLine = ({ name?: string; tagline?: string | null; date?: string | null; - rating?: number; + rating?: number | null; runtime?: number | null; poster?: KyooImage | null; studio?: Studio | null; trailerUrl?: string | null; - type: "movie" | "show"; + type: "movie" | "show" | "collection"; } & Stylable) => { const { css, theme } = useYoshiki(); const { t } = useTranslation(); @@ -222,8 +222,12 @@ const TitleLine = ({ {...tooltip(t("show.trailer"))} /> )} - - + {rating !== null && ( + <> + + + + )} {runtime && ( <> diff --git a/front/packages/ui/src/details/show.tsx b/front/packages/ui/src/details/show.tsx index 612fa860..f4f45d2c 100644 --- a/front/packages/ui/src/details/show.tsx +++ b/front/packages/ui/src/details/show.tsx @@ -28,7 +28,7 @@ import Svg, { Path, SvgProps } from "react-native-svg"; import { Container } from "@kyoo/primitives"; import { forwardRef } from "react"; -const SvgWave = (props: SvgProps) => { +export const SvgWave = (props: SvgProps) => { const { css } = useYoshiki(); const width = 612; const height = 52.771; @@ -58,11 +58,7 @@ const ShowHeader = forwardRef(function ShowH flexGrow: 1, flexShrink: 1, // @ts-ignore Web only property - overflow: "auto" as any, - // @ts-ignore Web only property - overflowX: "hidden", - // @ts-ignore Web only property - overflowY: "overlay", + overflowY: "auto" as any, }, ], props, diff --git a/front/packages/ui/src/home/recommanded.tsx b/front/packages/ui/src/home/recommanded.tsx index 77e97504..742f72fd 100644 --- a/front/packages/ui/src/home/recommanded.tsx +++ b/front/packages/ui/src/home/recommanded.tsx @@ -176,7 +176,6 @@ export const Recommanded = () => { > {(x, i) => (