From e4562648ba0d874d89885e7c762c8fe4fd3b1078 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Wed, 18 Oct 2023 22:56:07 +0200 Subject: [PATCH] Finish a basic recommanded card --- front/packages/models/src/query.tsx | 6 +- .../primitives/src/themes/catppuccin.ts | 2 + .../packages/primitives/src/themes/theme.tsx | 8 +- front/packages/ui/src/home/genre.tsx | 41 +++++----- front/packages/ui/src/home/recommanded.tsx | 74 +++++++++++++++---- 5 files changed, 93 insertions(+), 38 deletions(-) diff --git a/front/packages/models/src/query.tsx b/front/packages/models/src/query.tsx index 5bfe7c30..021a0007 100644 --- a/front/packages/models/src/query.tsx +++ b/front/packages/models/src/query.tsx @@ -162,12 +162,14 @@ export type QueryIdentifier = { getNext?: (item: unknown) => string | undefined; }; -export type QueryPage = ComponentType & { +export type QueryPage = ComponentType< + Props & { randomItems: Items[] } +> & { getFetchUrls?: (route: { [key: string]: string }) => QueryIdentifier[]; getLayout?: | QueryPage<{ page: ReactElement }> | { Layout: QueryPage<{ page: ReactElement }>; props: object }; - randomItems?: Items[] + randomItems?: Items[]; }; const toQueryKey = (query: QueryIdentifier) => { diff --git a/front/packages/primitives/src/themes/catppuccin.ts b/front/packages/primitives/src/themes/catppuccin.ts index e8f7045f..d09286d4 100644 --- a/front/packages/primitives/src/themes/catppuccin.ts +++ b/front/packages/primitives/src/themes/catppuccin.ts @@ -26,6 +26,7 @@ export const catppuccin: ThemeBuilder = { // Catppuccin latte overlay0: "#9ca0b0", overlay1: "#7c7f93", + lightOverlay: "#eff1f599", darkOverlay: "#4c4f6999", link: "#1e66f5", default: { @@ -57,6 +58,7 @@ export const catppuccin: ThemeBuilder = { // Catppuccin mocha overlay0: "#6c7086", overlay1: "#9399b2", + lightOverlay: "#f5f0f899", darkOverlay: "#11111b99", link: "#89b4fa", default: { diff --git a/front/packages/primitives/src/themes/theme.tsx b/front/packages/primitives/src/themes/theme.tsx index 768c2619..a34e8fa6 100644 --- a/front/packages/primitives/src/themes/theme.tsx +++ b/front/packages/primitives/src/themes/theme.tsx @@ -38,7 +38,9 @@ type Mode = { mode: "light" | "dark" | "auto"; overlay0: Property.Color; overlay1: Property.Color; + lightOverlay: Property.Color; darkOverlay: Property.Color; + themeOverlay: Property.Color; link: Property.Color; contrast: Property.Color; variant: Variant; @@ -73,8 +75,8 @@ declare module "yoshiki" { export type { Theme } from "yoshiki"; export type ThemeBuilder = { - light: Omit & { default: Variant }; - dark: Omit & { default: Variant }; + light: Omit & { default: Variant }; + dark: Omit & { default: Variant }; }; const selectMode = ( @@ -86,12 +88,14 @@ const selectMode = ( ...lightBuilder, ...lightBuilder.default, contrast: lightBuilder.colors.black, + themeOverlay: lightBuilder.lightOverlay, mode: "light", }; const dark: Mode & Variant = { ...darkBuilder, ...darkBuilder.default, contrast: darkBuilder.colors.white, + themeOverlay: darkBuilder.darkOverlay, mode: "dark", }; if (Platform.OS !== "web" || mode !== "auto") { diff --git a/front/packages/ui/src/home/genre.tsx b/front/packages/ui/src/home/genre.tsx index cf8bd8ee..8a9b4c83 100644 --- a/front/packages/ui/src/home/genre.tsx +++ b/front/packages/ui/src/home/genre.tsx @@ -36,6 +36,7 @@ import { Fetch } from "../fetch"; import { ItemGrid } from "../browse/grid"; import ChevronLeft from "@material-symbols/svg-400/rounded/chevron_left-fill.svg"; import ChevronRight from "@material-symbols/svg-400/rounded/chevron_right-fill.svg"; +import { InfiniteFetch } from "../fetch-infinite"; export const GenreGrid = ({ genre }: { genre: Genre }) => { const ref = useRef(null); @@ -43,7 +44,7 @@ export const GenreGrid = ({ genre }: { genre: Genre }) => { return ( - +

{genre}

{ />
- - - {(x, i) => ( - - )} - - + + {(x, i) => ( + + )} +
); }; -GenreGrid.query = (genre: Genre): QueryIdentifier> => ({ - parser: Paged(LibraryItemP) as any, +GenreGrid.query = (genre: Genre): QueryIdentifier => ({ + parser: LibraryItemP, + infinite: true, path: ["items"], params: { genres: genre, diff --git a/front/packages/ui/src/home/recommanded.tsx b/front/packages/ui/src/home/recommanded.tsx index 834d7bfe..001c7435 100644 --- a/front/packages/ui/src/home/recommanded.tsx +++ b/front/packages/ui/src/home/recommanded.tsx @@ -19,6 +19,7 @@ */ import { + Genre, ItemKind, KyooImage, LibraryItem, @@ -28,11 +29,12 @@ import { QueryIdentifier, getDisplayDate, } from "@kyoo/models"; -import { Container, H3, ImageBackground, P, Poster, SubP, ts } from "@kyoo/primitives"; +import { Chip, Container, H3, ImageBackground, P, Poster, SubP, alpha, ts } from "@kyoo/primitives"; import { useTranslation } from "react-i18next"; -import { View } from "react-native"; -import { percent, useYoshiki } from "yoshiki/native"; -import { Fetch, WithLoading } from "../fetch"; +import { ScrollView, View } from "react-native"; +import { percent, px, useYoshiki } from "yoshiki/native"; +import { Fetch, Layout, WithLoading } from "../fetch"; +import { InfiniteFetch } from "../fetch-infinite"; export const ItemDetails = ({ isLoading, @@ -41,35 +43,76 @@ export const ItemDetails = ({ subtitle, overview, poster, + genres, ...props }: WithLoading<{ name: string; tagline: string | null; subtitle: string; poster: KyooImage | null; + genres: Genre[] | null; overview: string | null; }>) => { const { css } = useYoshiki(); return ( - theme.variant.background }, props)}> + theme.variant.background, + borderRadius: 6, + overflow: "hidden", + }, + props, + )} + > -

{name}

- {subtitle && {subtitle}} + theme.darkOverlay, + position: "absolute", + left: 0, + right: 0, + bottom: 0, + p: ts(1), + })} + > +

{name}

+ {subtitle && {subtitle}} +
- - {tagline &&

{tagline}

} - {overview && {overview}} + + {tagline &&

{tagline}

} + {overview && ( + + {overview} + + )} + theme.themeOverlay, flexDirection: "row" })}> + {genres?.map((x) => ( + + ))} +
); }; +ItemDetails.layout = { + size: ts(36), + numColumns: { xs: 1, md: 2, xl: 3 }, + layout: "grid", + gap: ts(8), +} satisfies Layout; + export const Recommanded = () => { const { t } = useTranslation(); const { css } = useYoshiki(); @@ -77,7 +120,7 @@ export const Recommanded = () => { return (

{t("home.recommanded")}

- + {(x, i) => ( { subtitle={ x.kind !== ItemKind.Collection && !x.isLoading ? getDisplayDate(x) : undefined } - {...css({ height: { xs: ts(15), md: ts(20) } })} + genres={"genres" in x ? x.genres : null} /> )} - +
); }; -Recommanded.query = (): QueryIdentifier> => ({ - parser: Paged(LibraryItemP) as any, +Recommanded.query = (): QueryIdentifier => ({ + parser: LibraryItemP, + infinite: true, path: ["items"], params: { sortBy: "random",