mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 04:04:21 -04:00
Add header props on infinite lists
This commit is contained in:
parent
58040f8f49
commit
4bb992fc67
@ -27,14 +27,16 @@ import { episodeDisplayNumber, EpisodeLine } from "./episode";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { ComponentType } from "react";
|
import { ComponentType } from "react";
|
||||||
|
|
||||||
export const EpisodeList = ({
|
export const EpisodeList = <Props,>({
|
||||||
slug,
|
slug,
|
||||||
season,
|
season,
|
||||||
Header,
|
Header,
|
||||||
|
headerProps,
|
||||||
}: {
|
}: {
|
||||||
slug: string;
|
slug: string;
|
||||||
season: string | number;
|
season: string | number;
|
||||||
Header: ComponentType<{ children: JSX.Element }>;
|
Header: ComponentType<Props & { children: JSX.Element }>;
|
||||||
|
headerProps: Props
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -46,6 +48,7 @@ export const EpisodeList = ({
|
|||||||
empty={t("show.episode-none")}
|
empty={t("show.episode-none")}
|
||||||
divider
|
divider
|
||||||
Header={Header}
|
Header={Header}
|
||||||
|
headerProps={headerProps}
|
||||||
>
|
>
|
||||||
{(item) => (
|
{(item) => (
|
||||||
<EpisodeLine
|
<EpisodeLine
|
||||||
|
@ -26,7 +26,7 @@ import { EpisodeList } from "./season";
|
|||||||
import { Header } from "./header";
|
import { Header } from "./header";
|
||||||
import Svg, { Path, SvgProps } from "react-native-svg";
|
import Svg, { Path, SvgProps } from "react-native-svg";
|
||||||
import { Container, SwitchVariant } from "@kyoo/primitives";
|
import { Container, SwitchVariant } from "@kyoo/primitives";
|
||||||
import { forwardRef } from "react";
|
import { forwardRef, useCallback } from "react";
|
||||||
|
|
||||||
const SvgWave = (props: SvgProps) => {
|
const SvgWave = (props: SvgProps) => {
|
||||||
const { css } = useYoshiki();
|
const { css } = useYoshiki();
|
||||||
@ -42,6 +42,44 @@ const SvgWave = (props: SvgProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ShowHeader = forwardRef<View, ViewProps & { slug: string }>(function _ShowHeader({ children, slug, ...props }, ref) {
|
||||||
|
const { css, theme } = useYoshiki();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
ref={ref}
|
||||||
|
{...css(
|
||||||
|
[
|
||||||
|
{ bg: (theme) => theme.background },
|
||||||
|
Platform.OS === "web" && {
|
||||||
|
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",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
props,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{/* TODO: Remove the slug quickfix for the play button */}
|
||||||
|
<Header slug={`${slug}-s1e1`} query={query(slug)} />
|
||||||
|
{/* <Staff slug={slug} /> */}
|
||||||
|
<SvgWave
|
||||||
|
fill={theme.variant.background}
|
||||||
|
{...css({ flexShrink: 0, flexGrow: 1, display: "flex" })}
|
||||||
|
/>
|
||||||
|
{/* <SeasonTab slug={slug} season={season} /> */}
|
||||||
|
<View {...css({ bg: theme.variant.background })}>
|
||||||
|
<Container>{children}</Container>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const query = (slug: string): QueryIdentifier<Show> => ({
|
const query = (slug: string): QueryIdentifier<Show> => ({
|
||||||
parser: ShowP,
|
parser: ShowP,
|
||||||
path: ["shows", slug],
|
path: ["shows", slug],
|
||||||
@ -51,49 +89,11 @@ const query = (slug: string): QueryIdentifier<Show> => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const ShowDetails: QueryPage<{ slug: string; season: string }> = ({ slug, season }) => {
|
export const ShowDetails: QueryPage<{ slug: string; season: string }> = ({ slug, season }) => {
|
||||||
const { css, theme } = useYoshiki();
|
|
||||||
|
|
||||||
const ShowHeader = forwardRef<View, ViewProps>(function _ShowHeader({ children, ...props }, ref) {
|
|
||||||
return (
|
|
||||||
<View
|
|
||||||
ref={ref}
|
|
||||||
{...css(
|
|
||||||
[
|
|
||||||
{ bg: (theme) => theme.background },
|
|
||||||
Platform.OS === "web" && {
|
|
||||||
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",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
props,
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{/* TODO: Remove the slug quickfix for the play button */}
|
|
||||||
<Header slug={`${slug}-s1e1`} query={query(slug)} />
|
|
||||||
{/* <Staff slug={slug} /> */}
|
|
||||||
<SvgWave
|
|
||||||
fill={theme.variant.background}
|
|
||||||
{...css({ flexShrink: 0, flexGrow: 1, display: "flex" })}
|
|
||||||
/>
|
|
||||||
{/* <SeasonTab slug={slug} season={season} /> */}
|
|
||||||
<View {...css({ bg: theme.variant.background })}>
|
|
||||||
<Container>{children}</Container>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SwitchVariant>
|
<SwitchVariant>
|
||||||
{({ css, theme }) => (
|
{({ css, theme }) => (
|
||||||
<View {...css({ bg: theme.background, flex: 1 })}>
|
<View {...css({ bg: theme.background, flex: 1 })}>
|
||||||
<EpisodeList slug={slug} season={season} Header={ShowHeader} />
|
<EpisodeList slug={slug} season={season} Header={ShowHeader} headerProps={{slug}} />
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</SwitchVariant>
|
</SwitchVariant>
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
import { Page, QueryIdentifier, useInfiniteFetch } from "@kyoo/models";
|
import { Page, QueryIdentifier, useInfiniteFetch } from "@kyoo/models";
|
||||||
import { useBreakpointMap, HR } from "@kyoo/primitives";
|
import { useBreakpointMap, HR } from "@kyoo/primitives";
|
||||||
import { FlashList } from "@shopify/flash-list";
|
import { FlashList } from "@shopify/flash-list";
|
||||||
import { ComponentType, ReactElement } from "react";
|
import { ComponentType, isValidElement, ReactElement } from "react";
|
||||||
import { EmptyView, ErrorView, Layout, WithLoading } from "./fetch";
|
import { EmptyView, ErrorView, Layout, WithLoading } from "./fetch";
|
||||||
|
|
||||||
export const InfiniteFetch = <Data,>({
|
export const InfiniteFetch = <Data, Props>({
|
||||||
query,
|
query,
|
||||||
placeholderCount = 15,
|
placeholderCount = 15,
|
||||||
suspense = false,
|
suspense = false,
|
||||||
@ -34,6 +34,7 @@ export const InfiniteFetch = <Data,>({
|
|||||||
empty,
|
empty,
|
||||||
divider = false,
|
divider = false,
|
||||||
Header,
|
Header,
|
||||||
|
headerProps,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
query: QueryIdentifier<Data>;
|
query: QueryIdentifier<Data>;
|
||||||
@ -47,7 +48,8 @@ export const InfiniteFetch = <Data,>({
|
|||||||
empty?: string | JSX.Element;
|
empty?: string | JSX.Element;
|
||||||
suspense?: boolean;
|
suspense?: boolean;
|
||||||
divider?: boolean | ComponentType;
|
divider?: boolean | ComponentType;
|
||||||
Header?: ComponentType<{ children: JSX.Element }> | ReactElement;
|
Header?: ComponentType<Props & { children: JSX.Element }> | ReactElement;
|
||||||
|
headerProps?: Props
|
||||||
}): JSX.Element | null => {
|
}): JSX.Element | null => {
|
||||||
if (!query.infinite) console.warn("A non infinite query was passed to an InfiniteFetch.");
|
if (!query.infinite) console.warn("A non infinite query was passed to an InfiniteFetch.");
|
||||||
|
|
||||||
@ -71,6 +73,8 @@ export const InfiniteFetch = <Data,>({
|
|||||||
(_, i) => ({ id: `gen${i}`, isLoading: true } as Data),
|
(_, i) => ({ id: `gen${i}`, isLoading: true } as Data),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
if (headerProps && !isValidElement(Header)) Header = <Header {...headerProps} />
|
||||||
return (
|
return (
|
||||||
<FlashList
|
<FlashList
|
||||||
renderItem={({ item, index }) => children({ isLoading: false, ...item } as any, index)}
|
renderItem={({ item, index }) => children({ isLoading: false, ...item } as any, index)}
|
||||||
|
@ -24,7 +24,7 @@ import { ComponentType, Fragment, isValidElement, ReactElement, useRef } from "r
|
|||||||
import { Stylable, useYoshiki } from "yoshiki";
|
import { Stylable, useYoshiki } from "yoshiki";
|
||||||
import { EmptyView, ErrorView, Layout, WithLoading } from "./fetch";
|
import { EmptyView, ErrorView, Layout, WithLoading } from "./fetch";
|
||||||
|
|
||||||
const InfiniteScroll = ({
|
const InfiniteScroll = <Props,>({
|
||||||
children,
|
children,
|
||||||
loader,
|
loader,
|
||||||
layout = "vertical",
|
layout = "vertical",
|
||||||
@ -32,6 +32,7 @@ const InfiniteScroll = ({
|
|||||||
hasMore = true,
|
hasMore = true,
|
||||||
isFetching,
|
isFetching,
|
||||||
Header,
|
Header,
|
||||||
|
headerProps,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
children?: ReactElement | (ReactElement | null)[] | null;
|
children?: ReactElement | (ReactElement | null)[] | null;
|
||||||
@ -40,7 +41,8 @@ const InfiniteScroll = ({
|
|||||||
loadMore: () => void;
|
loadMore: () => void;
|
||||||
hasMore: boolean;
|
hasMore: boolean;
|
||||||
isFetching: boolean;
|
isFetching: boolean;
|
||||||
Header: ComponentType<{ children: JSX.Element }> | ReactElement | undefined;
|
Header?: ComponentType<Props & { children: JSX.Element }> | ReactElement;
|
||||||
|
headerProps?: Props
|
||||||
} & Stylable) => {
|
} & Stylable) => {
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
const { css } = useYoshiki();
|
const { css } = useYoshiki();
|
||||||
@ -89,7 +91,8 @@ const InfiniteScroll = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!Header) return list({ ...scrollProps, ...props });
|
if (!Header) return list({ ...scrollProps, ...props });
|
||||||
if (!isValidElement(Header)) return <Header {...scrollProps}>{list(props)}</Header>;
|
// @ts-ignore
|
||||||
|
if (!isValidElement(Header)) return <Header {...scrollProps} {...headerProps}>{list(props)}</Header>;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{Header}
|
{Header}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user