mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 04:04:21 -04:00
Fix incremental queries
This commit is contained in:
parent
47a22b6540
commit
3e140e4f43
@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { SearchPage } from "@kyoo/ui";
|
import { SearchPage } from "@kyoo/ui";
|
||||||
import { Stack } from "expo-router";
|
import { Stack, useLocalSearchParams } from "expo-router";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { createParam } from "solito";
|
import { createParam } from "solito";
|
||||||
import { useRouter } from "solito/router";
|
import { useRouter } from "solito/router";
|
||||||
@ -27,11 +27,12 @@ import { useTheme } from "yoshiki/native";
|
|||||||
|
|
||||||
const { useParam } = createParam<{ q?: string }>();
|
const { useParam } = createParam<{ q?: string }>();
|
||||||
|
|
||||||
const Search = ({ route }: { route: any }) => {
|
const Search = () => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { back } = useRouter();
|
const { back } = useRouter();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [query, setQuery] = useParam("q");
|
const [query, setQuery] = useParam("q");
|
||||||
|
const routeParams = useLocalSearchParams();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -51,7 +52,7 @@ const Search = ({ route }: { route: any }) => {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<SearchPage {...route.params} />
|
<SearchPage {...routeParams} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -21,13 +21,13 @@
|
|||||||
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, isValidElement, ReactElement } from "react";
|
import { ComponentType, isValidElement, ReactElement, useRef } from "react";
|
||||||
import { EmptyView, ErrorView, Layout, WithLoading } from "./fetch";
|
import { EmptyView, ErrorView, Layout, WithLoading } from "./fetch";
|
||||||
|
|
||||||
export const InfiniteFetch = <Data, Props>({
|
export const InfiniteFetch = <Data, Props>({
|
||||||
query,
|
query,
|
||||||
placeholderCount = 15,
|
placeholderCount = 15,
|
||||||
suspense = false,
|
incremental = false,
|
||||||
horizontal = false,
|
horizontal = false,
|
||||||
children,
|
children,
|
||||||
layout,
|
layout,
|
||||||
@ -46,7 +46,7 @@ export const InfiniteFetch = <Data, Props>({
|
|||||||
i: number,
|
i: number,
|
||||||
) => ReactElement | null;
|
) => ReactElement | null;
|
||||||
empty?: string | JSX.Element;
|
empty?: string | JSX.Element;
|
||||||
suspense?: boolean;
|
incremental?: boolean;
|
||||||
divider?: boolean | ComponentType;
|
divider?: boolean | ComponentType;
|
||||||
Header?: ComponentType<Props & { children: JSX.Element }> | ReactElement;
|
Header?: ComponentType<Props & { children: JSX.Element }> | ReactElement;
|
||||||
headerProps?: Props
|
headerProps?: Props
|
||||||
@ -54,13 +54,14 @@ export const InfiniteFetch = <Data, Props>({
|
|||||||
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.");
|
||||||
|
|
||||||
const { numColumns, size } = useBreakpointMap(layout);
|
const { numColumns, size } = useBreakpointMap(layout);
|
||||||
const { items, error, fetchNextPage, hasNextPage, refetch, isRefetching } = useInfiniteFetch(
|
const oldItems = useRef<Data[] | undefined>();
|
||||||
|
let { items, error, fetchNextPage, hasNextPage, refetch, isRefetching } = useInfiniteFetch(
|
||||||
query,
|
query,
|
||||||
{
|
{
|
||||||
suspense: suspense,
|
|
||||||
useErrorBoundary: false,
|
useErrorBoundary: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
if (incremental && items) oldItems.current = items;
|
||||||
|
|
||||||
if (error) return <ErrorView error={error} />;
|
if (error) return <ErrorView error={error} />;
|
||||||
if (empty && items && items.length === 0) {
|
if (empty && items && items.length === 0) {
|
||||||
@ -68,6 +69,8 @@ export const InfiniteFetch = <Data, Props>({
|
|||||||
return <EmptyView message={empty} />;
|
return <EmptyView message={empty} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (incremental)
|
||||||
|
items ??= oldItems.current;
|
||||||
const count = items ? numColumns - (items.length % numColumns) : placeholderCount;
|
const count = items ? numColumns - (items.length % numColumns) : placeholderCount;
|
||||||
const placeholders = [...Array(count === 0 ? numColumns : count)].map(
|
const placeholders = [...Array(count === 0 ? numColumns : count)].map(
|
||||||
(_, i) => ({ id: `gen${i}`, isLoading: true } as Data),
|
(_, i) => ({ id: `gen${i}`, isLoading: true } as Data),
|
||||||
|
@ -103,7 +103,7 @@ const InfiniteScroll = <Props,>({
|
|||||||
|
|
||||||
export const InfiniteFetch = <Data,>({
|
export const InfiniteFetch = <Data,>({
|
||||||
query,
|
query,
|
||||||
suspense = false,
|
incremental = false,
|
||||||
placeholderCount = 15,
|
placeholderCount = 15,
|
||||||
children,
|
children,
|
||||||
layout,
|
layout,
|
||||||
@ -114,7 +114,7 @@ export const InfiniteFetch = <Data,>({
|
|||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
query: QueryIdentifier<Data>;
|
query: QueryIdentifier<Data>;
|
||||||
suspense?: boolean;
|
incremental?: boolean;
|
||||||
placeholderCount?: number;
|
placeholderCount?: number;
|
||||||
layout: Layout;
|
layout: Layout;
|
||||||
horizontal?: boolean;
|
horizontal?: boolean;
|
||||||
@ -128,12 +128,14 @@ export const InfiniteFetch = <Data,>({
|
|||||||
}): 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.");
|
||||||
|
|
||||||
|
const oldItems = useRef<Data[] | undefined>();
|
||||||
const { items, error, fetchNextPage, hasNextPage, isFetching } = useInfiniteFetch(query, {
|
const { items, error, fetchNextPage, hasNextPage, isFetching } = useInfiniteFetch(query, {
|
||||||
suspense: suspense,
|
|
||||||
useErrorBoundary: false,
|
useErrorBoundary: false,
|
||||||
});
|
});
|
||||||
const grid = layout.numColumns !== 1;
|
const grid = layout.numColumns !== 1;
|
||||||
|
|
||||||
|
if (incremental && items) oldItems.current = items;
|
||||||
|
|
||||||
if (error) return addHeader(Header, <ErrorView error={error} />);
|
if (error) return addHeader(Header, <ErrorView error={error} />);
|
||||||
if (empty && items && items.length === 0) {
|
if (empty && items && items.length === 0) {
|
||||||
if (typeof empty !== "string") return empty;
|
if (typeof empty !== "string") return empty;
|
||||||
@ -155,7 +157,7 @@ export const InfiniteFetch = <Data,>({
|
|||||||
Header={Header}
|
Header={Header}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{items?.map((item, i) => (
|
{(items ?? oldItems.current)?.map((item, i) => (
|
||||||
<Fragment key={(item as any).id?.toString()}>
|
<Fragment key={(item as any).id?.toString()}>
|
||||||
{Divider && i !== 0 && (Divider === true ? <HR /> : <Divider />)}
|
{Divider && i !== 0 && (Divider === true ? <HR /> : <Divider />)}
|
||||||
{children({ ...item, isLoading: false } as any, i)}
|
{children({ ...item, isLoading: false } as any, i)}
|
||||||
|
@ -28,7 +28,6 @@ import {
|
|||||||
Skeleton,
|
Skeleton,
|
||||||
tooltip,
|
tooltip,
|
||||||
ts,
|
ts,
|
||||||
Link,
|
|
||||||
Menu,
|
Menu,
|
||||||
} from "@kyoo/primitives";
|
} from "@kyoo/primitives";
|
||||||
import { Platform, TextInput, View, ViewProps } from "react-native";
|
import { Platform, TextInput, View, ViewProps } from "react-native";
|
||||||
@ -72,7 +71,7 @@ const SearchBar = forwardRef<
|
|||||||
onChangeText={(q) => {
|
onChangeText={(q) => {
|
||||||
if (Platform.OS === "web") {
|
if (Platform.OS === "web") {
|
||||||
const action = window.location.pathname.startsWith("/search") ? replace : push;
|
const action = window.location.pathname.startsWith("/search") ? replace : push;
|
||||||
if (q) action(`/search?q=${q}`, undefined, { shallow: true });
|
if (q) action(`/search?q=${encodeURI(q)}`, undefined, { shallow: true });
|
||||||
else back();
|
else back();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { LibraryItem, LibraryItemP, QueryIdentifier, QueryPage } from "@kyoo/models";
|
import { LibraryItem, LibraryItemP, QueryIdentifier, QueryPage } from "@kyoo/models";
|
||||||
import { P } from "@kyoo/primitives";
|
|
||||||
import { Suspense, useRef, useDeferredValue } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { ItemGrid } from "../browse/grid";
|
import { ItemGrid } from "../browse/grid";
|
||||||
import { itemMap } from "../browse/index";
|
import { itemMap } from "../browse/index";
|
||||||
@ -44,7 +42,7 @@ export const SearchPage: QueryPage<{ q?: string }> = ({ q }) => {
|
|||||||
<InfiniteFetch
|
<InfiniteFetch
|
||||||
query={query(q)}
|
query={query(q)}
|
||||||
// TODO: Understand why it does not work.
|
// TODO: Understand why it does not work.
|
||||||
// suspense={true} //{!isFirst}
|
incremental={true}
|
||||||
layout={ItemGrid.layout}
|
layout={ItemGrid.layout}
|
||||||
placeholderCount={15}
|
placeholderCount={15}
|
||||||
empty={empty}
|
empty={empty}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user