Fix incremental queries

This commit is contained in:
Zoe Roux 2023-06-13 12:11:54 +09:00
parent 47a22b6540
commit 3e140e4f43
5 changed files with 20 additions and 17 deletions

View File

@ -19,7 +19,7 @@
*/
import { SearchPage } from "@kyoo/ui";
import { Stack } from "expo-router";
import { Stack, useLocalSearchParams } from "expo-router";
import { useTranslation } from "react-i18next";
import { createParam } from "solito";
import { useRouter } from "solito/router";
@ -27,11 +27,12 @@ import { useTheme } from "yoshiki/native";
const { useParam } = createParam<{ q?: string }>();
const Search = ({ route }: { route: any }) => {
const Search = () => {
const theme = useTheme();
const { back } = useRouter();
const { t } = useTranslation();
const [query, setQuery] = useParam("q");
const routeParams = useLocalSearchParams();
return (
<>
@ -51,7 +52,7 @@ const Search = ({ route }: { route: any }) => {
},
}}
/>
<SearchPage {...route.params} />
<SearchPage {...routeParams} />
</>
);
};

View File

@ -21,13 +21,13 @@
import { Page, QueryIdentifier, useInfiniteFetch } from "@kyoo/models";
import { useBreakpointMap, HR } from "@kyoo/primitives";
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";
export const InfiniteFetch = <Data, Props>({
query,
placeholderCount = 15,
suspense = false,
incremental = false,
horizontal = false,
children,
layout,
@ -46,7 +46,7 @@ export const InfiniteFetch = <Data, Props>({
i: number,
) => ReactElement | null;
empty?: string | JSX.Element;
suspense?: boolean;
incremental?: boolean;
divider?: boolean | ComponentType;
Header?: ComponentType<Props & { children: JSX.Element }> | ReactElement;
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.");
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,
{
suspense: suspense,
useErrorBoundary: false,
},
);
if (incremental && items) oldItems.current = items;
if (error) return <ErrorView error={error} />;
if (empty && items && items.length === 0) {
@ -68,6 +69,8 @@ export const InfiniteFetch = <Data, Props>({
return <EmptyView message={empty} />;
}
if (incremental)
items ??= oldItems.current;
const count = items ? numColumns - (items.length % numColumns) : placeholderCount;
const placeholders = [...Array(count === 0 ? numColumns : count)].map(
(_, i) => ({ id: `gen${i}`, isLoading: true } as Data),

View File

@ -103,7 +103,7 @@ const InfiniteScroll = <Props,>({
export const InfiniteFetch = <Data,>({
query,
suspense = false,
incremental = false,
placeholderCount = 15,
children,
layout,
@ -114,7 +114,7 @@ export const InfiniteFetch = <Data,>({
...props
}: {
query: QueryIdentifier<Data>;
suspense?: boolean;
incremental?: boolean;
placeholderCount?: number;
layout: Layout;
horizontal?: boolean;
@ -128,12 +128,14 @@ export const InfiniteFetch = <Data,>({
}): JSX.Element | null => {
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, {
suspense: suspense,
useErrorBoundary: false,
});
const grid = layout.numColumns !== 1;
if (incremental && items) oldItems.current = items;
if (error) return addHeader(Header, <ErrorView error={error} />);
if (empty && items && items.length === 0) {
if (typeof empty !== "string") return empty;
@ -155,7 +157,7 @@ export const InfiniteFetch = <Data,>({
Header={Header}
{...props}
>
{items?.map((item, i) => (
{(items ?? oldItems.current)?.map((item, i) => (
<Fragment key={(item as any).id?.toString()}>
{Divider && i !== 0 && (Divider === true ? <HR /> : <Divider />)}
{children({ ...item, isLoading: false } as any, i)}

View File

@ -28,7 +28,6 @@ import {
Skeleton,
tooltip,
ts,
Link,
Menu,
} from "@kyoo/primitives";
import { Platform, TextInput, View, ViewProps } from "react-native";
@ -72,7 +71,7 @@ const SearchBar = forwardRef<
onChangeText={(q) => {
if (Platform.OS === "web") {
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();
}
}}

View File

@ -19,8 +19,6 @@
*/
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 { ItemGrid } from "../browse/grid";
import { itemMap } from "../browse/index";
@ -44,7 +42,7 @@ export const SearchPage: QueryPage<{ q?: string }> = ({ q }) => {
<InfiniteFetch
query={query(q)}
// TODO: Understand why it does not work.
// suspense={true} //{!isFirst}
incremental={true}
layout={ItemGrid.layout}
placeholderCount={15}
empty={empty}