Add header props on infinite lists

This commit is contained in:
Zoe Roux 2023-06-12 00:50:55 +09:00
parent 58040f8f49
commit 4bb992fc67
4 changed files with 58 additions and 48 deletions

View File

@ -27,14 +27,16 @@ import { episodeDisplayNumber, EpisodeLine } from "./episode";
import { useTranslation } from "react-i18next";
import { ComponentType } from "react";
export const EpisodeList = ({
export const EpisodeList = <Props,>({
slug,
season,
Header,
headerProps,
}: {
slug: string;
season: string | number;
Header: ComponentType<{ children: JSX.Element }>;
Header: ComponentType<Props & { children: JSX.Element }>;
headerProps: Props
}) => {
const { t } = useTranslation();
@ -46,6 +48,7 @@ export const EpisodeList = ({
empty={t("show.episode-none")}
divider
Header={Header}
headerProps={headerProps}
>
{(item) => (
<EpisodeLine

View File

@ -26,7 +26,7 @@ import { EpisodeList } from "./season";
import { Header } from "./header";
import Svg, { Path, SvgProps } from "react-native-svg";
import { Container, SwitchVariant } from "@kyoo/primitives";
import { forwardRef } from "react";
import { forwardRef, useCallback } from "react";
const SvgWave = (props: SvgProps) => {
const { css } = useYoshiki();
@ -42,18 +42,9 @@ const SvgWave = (props: SvgProps) => {
);
};
const query = (slug: string): QueryIdentifier<Show> => ({
parser: ShowP,
path: ["shows", slug],
params: {
fields: ["genres", "studio"],
},
});
export const ShowDetails: QueryPage<{ slug: string; season: string }> = ({ slug, season }) => {
const ShowHeader = forwardRef<View, ViewProps & { slug: string }>(function _ShowHeader({ children, slug, ...props }, ref) {
const { css, theme } = useYoshiki();
const ShowHeader = forwardRef<View, ViewProps>(function _ShowHeader({ children, ...props }, ref) {
return (
<View
ref={ref}
@ -89,11 +80,20 @@ export const ShowDetails: QueryPage<{ slug: string; season: string }> = ({ slug,
);
});
const query = (slug: string): QueryIdentifier<Show> => ({
parser: ShowP,
path: ["shows", slug],
params: {
fields: ["genres", "studio"],
},
});
export const ShowDetails: QueryPage<{ slug: string; season: string }> = ({ slug, season }) => {
return (
<SwitchVariant>
{({ css, theme }) => (
<View {...css({ bg: theme.background, flex: 1 })}>
<EpisodeList slug={slug} season={season} Header={ShowHeader} />
<EpisodeList slug={slug} season={season} Header={ShowHeader} headerProps={{slug}} />
</View>
)}
</SwitchVariant>

View File

@ -21,10 +21,10 @@
import { Page, QueryIdentifier, useInfiniteFetch } from "@kyoo/models";
import { useBreakpointMap, HR } from "@kyoo/primitives";
import { FlashList } from "@shopify/flash-list";
import { ComponentType, ReactElement } from "react";
import { ComponentType, isValidElement, ReactElement } from "react";
import { EmptyView, ErrorView, Layout, WithLoading } from "./fetch";
export const InfiniteFetch = <Data,>({
export const InfiniteFetch = <Data, Props>({
query,
placeholderCount = 15,
suspense = false,
@ -34,6 +34,7 @@ export const InfiniteFetch = <Data,>({
empty,
divider = false,
Header,
headerProps,
...props
}: {
query: QueryIdentifier<Data>;
@ -47,7 +48,8 @@ export const InfiniteFetch = <Data,>({
empty?: string | JSX.Element;
suspense?: boolean;
divider?: boolean | ComponentType;
Header?: ComponentType<{ children: JSX.Element }> | ReactElement;
Header?: ComponentType<Props & { children: JSX.Element }> | ReactElement;
headerProps?: Props
}): JSX.Element | null => {
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),
);
// @ts-ignore
if (headerProps && !isValidElement(Header)) Header = <Header {...headerProps} />
return (
<FlashList
renderItem={({ item, index }) => children({ isLoading: false, ...item } as any, index)}

View File

@ -24,7 +24,7 @@ import { ComponentType, Fragment, isValidElement, ReactElement, useRef } from "r
import { Stylable, useYoshiki } from "yoshiki";
import { EmptyView, ErrorView, Layout, WithLoading } from "./fetch";
const InfiniteScroll = ({
const InfiniteScroll = <Props,>({
children,
loader,
layout = "vertical",
@ -32,6 +32,7 @@ const InfiniteScroll = ({
hasMore = true,
isFetching,
Header,
headerProps,
...props
}: {
children?: ReactElement | (ReactElement | null)[] | null;
@ -40,7 +41,8 @@ const InfiniteScroll = ({
loadMore: () => void;
hasMore: boolean;
isFetching: boolean;
Header: ComponentType<{ children: JSX.Element }> | ReactElement | undefined;
Header?: ComponentType<Props & { children: JSX.Element }> | ReactElement;
headerProps?: Props
} & Stylable) => {
const ref = useRef<HTMLDivElement>(null);
const { css } = useYoshiki();
@ -89,7 +91,8 @@ const InfiniteScroll = ({
);
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 (
<>
{Header}