diff --git a/front/apps/mobile/app/_layout.tsx b/front/apps/mobile/app/_layout.tsx index 595467f3..1664cbbd 100644 --- a/front/apps/mobile/app/_layout.tsx +++ b/front/apps/mobile/app/_layout.tsx @@ -57,7 +57,7 @@ const ThemedStack = () => { headerStyle: { backgroundColor: theme.appbar, }, - headerTintColor: "#fff", + headerTintColor: theme.colors.white, headerTitleStyle: { fontWeight: "bold", }, diff --git a/front/apps/mobile/app/movie/index.tsx b/front/apps/mobile/app/movie/index.tsx deleted file mode 100644 index c19e0d73..00000000 --- a/front/apps/mobile/app/movie/index.tsx +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 { MovieDetails } from "@kyoo/ui"; - -export default MovieDetails; diff --git a/front/apps/web/src/components/person.tsx b/front/apps/web/src/components/person.tsx deleted file mode 100644 index ccbf590f..00000000 --- a/front/apps/web/src/components/person.tsx +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 { Avatar, Box, Skeleton, SxProps, Typography } from "@mui/material"; -import { Person } from "~/models/resources/person"; -import { Link } from "~/utils/link"; - -export const PersonAvatar = ({ person, sx }: { person?: Person; sx?: SxProps }) => { - if (!person) { - return ( - - - - - - - - - - ); - } - return ( - - - {person.name} - {person.role && person.type && ( - - {person.type} ({person.role}) - - )} - {person.role && !person.type && ( - - {person.role} - - )} - - ); -}; diff --git a/front/packages/primitives/src/avatar.tsx b/front/packages/primitives/src/avatar.tsx index 2beb3e99..37fd3156 100644 --- a/front/packages/primitives/src/avatar.tsx +++ b/front/packages/primitives/src/avatar.tsx @@ -18,26 +18,31 @@ * along with Kyoo. If not, see . */ -import { View, ViewStyle } from "react-native"; +import { View } from "react-native"; import { Image } from "./image"; -import { useYoshiki, px } from "yoshiki/native"; +import { useYoshiki, px, Stylable } from "yoshiki/native"; import { Icon } from "./icons"; +import { Skeleton } from "./skeleton"; export const Avatar = ({ src, alt, size = px(24), + isLoading = false, + ...props }: { - src?: string; - alt: string; + src?: string | null; + alt?: string; size?: number; -}) => { + isLoading?: boolean; +} & Stylable) => { const { css } = useYoshiki(); + if (isLoading) return ; return ( - + {src ? ( - {alt} + {alt} ) : ( )} diff --git a/front/packages/primitives/src/container.tsx b/front/packages/primitives/src/container.tsx index 4a4dbbbe..0fcedcd8 100644 --- a/front/packages/primitives/src/container.tsx +++ b/front/packages/primitives/src/container.tsx @@ -18,15 +18,20 @@ * along with Kyoo. If not, see . */ +import { ComponentType } from "react"; import { View, ViewProps } from "react-native"; import { percent, px, useYoshiki } from "yoshiki/native"; -export const Container = (props: ViewProps) => { +export const Container = ({ + as, + ...props +}: { as?: ComponentType } & AsProps) => { const { css } = useYoshiki(); + const As = as ?? View; return ( - { }, }, props, - )} + ) as any)} /> ); }; diff --git a/front/packages/primitives/src/divider.tsx b/front/packages/primitives/src/divider.tsx index 6878226c..ce2f5fef 100644 --- a/front/packages/primitives/src/divider.tsx +++ b/front/packages/primitives/src/divider.tsx @@ -19,8 +19,9 @@ */ import { HR as EHR } from "@expo/html-elements"; -import { percent, px, Stylable, useYoshiki } from "yoshiki/native"; -import { alpha, ts } from "."; +import { px, Stylable, useYoshiki } from "yoshiki/native"; +import { alpha } from "./themes"; +import { ts } from "./utils"; export const HR = ({ orientation, diff --git a/front/packages/primitives/src/icons.tsx b/front/packages/primitives/src/icons.tsx index 69824a0b..f384768a 100644 --- a/front/packages/primitives/src/icons.tsx +++ b/front/packages/primitives/src/icons.tsx @@ -22,7 +22,7 @@ import MIcon from "@expo/vector-icons/MaterialIcons"; import { ComponentProps, ComponentType } from "react"; import { PressableProps } from "react-native"; import { Pressable, px, useYoshiki } from "yoshiki/native"; -import { Breakpoint, ts } from "."; +import { Breakpoint, ts } from "./utils"; export type IconProps = { icon: ComponentProps["name"]; diff --git a/front/packages/primitives/src/index.ts b/front/packages/primitives/src/index.ts index 8e4f47d4..712ae906 100644 --- a/front/packages/primitives/src/index.ts +++ b/front/packages/primitives/src/index.ts @@ -31,13 +31,4 @@ export * from "./container"; export * from "./divider"; export * from "./animated"; - -export * from "./utils/breakpoints"; -export * from "./utils/nojs"; -export * from "./utils/head"; - -import { px } from "yoshiki/native"; - -export const ts = (spacing: number) => { - return px(spacing * 8); -}; +export * from "./utils"; diff --git a/front/packages/primitives/src/links.tsx b/front/packages/primitives/src/links.tsx index 41ddda46..221614c5 100644 --- a/front/packages/primitives/src/links.tsx +++ b/front/packages/primitives/src/links.tsx @@ -18,7 +18,8 @@ * along with Kyoo. If not, see . */ -import { ComponentType, ReactNode } from "react"; +import { ViewStyle } from "@expo/html-elements/build/primitives/View"; +import { ComponentType, Fragment, ReactNode } from "react"; import { Platform, TextProps, @@ -26,6 +27,7 @@ import { TouchableNativeFeedback, View, ViewProps, + StyleSheet, } from "react-native"; import { LinkCore, TextLink } from "solito/link"; import { useYoshiki, Pressable } from "yoshiki/native"; @@ -70,26 +72,35 @@ export const Link = ({ }) => { const { onBlur, onFocus, onPressIn, onPressOut, ...noFocusProps } = props; const focusProps = { onBlur, onFocus, onPressIn, onPressOut }; + const radiusStyle = Platform.select({ + android: { + style: { borderRadius: StyleSheet.flatten(props?.style).borderRadius, overflow: "hidden" }, + }, + default: {}, + }); + const Wrapper = radiusStyle ? View : Fragment; return ( - ({ - web: View, - android: TouchableNativeFeedback, - ios: TouchableOpacity, - default: Pressable, - })} - componentProps={Platform.select({ - android: { useForeground: true, ...focusProps }, - default: props, - })} - > - {Platform.select({ - android: {children}, - ios: {children}, - default: children, - })} - + + ({ + web: View, + android: TouchableNativeFeedback, + ios: TouchableOpacity, + default: Pressable, + })} + componentProps={Platform.select({ + android: { useForeground: true, ...focusProps }, + default: props, + })} + > + {Platform.select({ + android: {children}, + ios: {children}, + default: children, + })} + + ); }; diff --git a/front/packages/primitives/src/text.tsx b/front/packages/primitives/src/text.tsx index db40edb0..05fd8c57 100644 --- a/front/packages/primitives/src/text.tsx +++ b/front/packages/primitives/src/text.tsx @@ -31,7 +31,7 @@ import { P as EP, LI as ELI, } from "@expo/html-elements"; -import { ts } from "."; +import { ts } from "./utils/spacing"; const styleText = ( Component: ComponentType>, @@ -76,7 +76,7 @@ export const LI = ({ children, ...props }: TextProps) => { const { css } = useYoshiki(); return ( -

+

{t("show.genre")}:{" "} {(isLoading ? [...Array(3)] : genres!).map((genre, i) => ( - <> - {i !== 0 && ", "} + +

{i !== 0 && ", "}

{isLoading ? ( - + ) : ( - - {genre.name} - + {genre.name} )} - + ))}

@@ -278,65 +277,52 @@ const Description = ({ ); }; -export const ShowHeader = ({ - query, - slug, -}: { - query: QueryIdentifier; - slug: string; -}) => { - /* const scroll = useScroll(); */ +export const Header = ({ query, slug }: { query: QueryIdentifier; slug: string }) => { const { css } = useYoshiki(); - // TODO: tweek the navbar color with the theme. return ( - <> - - - {({ isLoading, ...data }) => ( -
- - {/* TODO: Add a shadow on navbar items */} - {/* TODO: Put the navbar outside of the scrollbox */} - - - - + {({ isLoading, ...data }) => ( + + + + -
- )} -
- + + + + )} + ); }; diff --git a/front/packages/ui/src/details/index.tsx b/front/packages/ui/src/details/index.tsx index f99e1951..becc4444 100644 --- a/front/packages/ui/src/details/index.tsx +++ b/front/packages/ui/src/details/index.tsx @@ -19,7 +19,10 @@ */ import { Movie, MovieP, QueryIdentifier, QueryPage } from "@kyoo/models"; -import { ShowHeader } from "./header"; +import { Navbar } from "../navbar"; +import { DefaultLayout } from "../layout"; +import { Header } from "./header"; +import { Staff } from "./staff"; const query = (slug: string): QueryIdentifier => ({ parser: MovieP, @@ -32,16 +35,16 @@ const query = (slug: string): QueryIdentifier => ({ export const MovieDetails: QueryPage<{ slug: string }> = ({ slug }) => { return ( <> - {/* */} - {/* {makeTitle(data?.name)} */} - {/* */} - {/* */} - - {/* */} +
+ {/* */} ); }; -MovieDetails.getFetchUrls = ({ slug }) => [//query(slug), - // ShowStaff.query(slug), Navbar.query() +MovieDetails.getFetchUrls = ({ slug }) => [ + query(slug), + // ShowStaff.query(slug), + Navbar.query(), ]; + +MovieDetails.getLayout = DefaultLayout; diff --git a/front/packages/ui/src/details/staff.tsx b/front/packages/ui/src/details/staff.tsx index 1976b648..ec4f44ba 100644 --- a/front/packages/ui/src/details/staff.tsx +++ b/front/packages/ui/src/details/staff.tsx @@ -18,30 +18,40 @@ * along with Kyoo. If not, see . */ -export {} -// export const ShowStaff = ({ slug }: { slug: string }) => { -// const { items, isError, error } = useInfiniteFetch(ShowStaff.query(slug)); -// const { t } = useTranslation("browse"); +import { Person, PersonP, QueryIdentifier } from "@kyoo/models"; +import { useTranslation } from "react-i18next"; +import { InfiniteFetch } from "../fetch-infinite"; +import { PersonAvatar } from "./person"; -// // TODO: handle infinite scroll +export const Staff = ({ slug }: { slug: string }) => { + const { t } = useTranslation(); -// if (isError) return ; + // TODO: handle infinite scroll -// return ( -// -// {(items ?? [...Array(20)]).map((x, i) => ( -// -// ))} -// -// ); -// }; + return ( + + {/* */} + {(item, key) => ( + + )} + + ); +}; -// ShowStaff.query = (slug: string): QueryIdentifier => ({ -// parser: PersonP, -// path: ["shows", slug, "people"], -// infinite: true, -// }); +Staff.query = (slug: string): QueryIdentifier => ({ + parser: PersonP, + path: ["shows", slug, "people"], + infinite: true, +}); diff --git a/front/packages/ui/src/fetch.tsx b/front/packages/ui/src/fetch.tsx index 5718726a..efd3ad26 100644 --- a/front/packages/ui/src/fetch.tsx +++ b/front/packages/ui/src/fetch.tsx @@ -20,6 +20,7 @@ import { Page, QueryIdentifier, useFetch, KyooErrors } from "@kyoo/models"; import { Breakpoint, P } from "@kyoo/primitives"; +import { Fragment } from "react"; import { View } from "react-native"; import { useYoshiki } from "yoshiki/native"; @@ -47,14 +48,12 @@ export const Fetch = ({ const { data, error } = useFetch(query); if (error) return ; + if (placeholderCount === 1 || !isPage(data)) + return children(data ? { ...data, isLoading: false } : ({ isLoading: true } as any), 0); if (!data) return ( <>{[...Array(placeholderCount)].map((_, i) => children({ isLoading: true } as any, i))} ); - if (!isPage(data)) - return ( - <> {children(data ? { ...data, isLoading: false } : ({ isLoading: true } as any), 0)} - ); return <>{data.items.map((item, i) => children({ ...item, isLoading: false } as any, i))}; };