mirror of
https://github.com/zoriya/Kyoo.git
synced 2026-03-20 08:27:49 -04:00
Properly implement refresh on the home page
This commit is contained in:
parent
f8d935becd
commit
5e83752ec4
@ -6,7 +6,7 @@ import {
|
||||
useQueryClient,
|
||||
useMutation as useRQMutation,
|
||||
} from "@tanstack/react-query";
|
||||
import { useContext } from "react";
|
||||
import { useCallback, useContext, useState } from "react";
|
||||
import { Platform } from "react-native";
|
||||
import type { z } from "zod/v4";
|
||||
import { type KyooError, type Page, Paged } from "~/models";
|
||||
@ -189,6 +189,32 @@ export const useFetch = <Data,>(query: QueryIdentifier<Data>) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const useRefresh = (queries: QueryIdentifier<unknown>[]) => {
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const queryClient = useQueryClient();
|
||||
const { apiUrl } = useContext(AccountContext);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setRefreshing(true);
|
||||
await Promise.all(
|
||||
queries.map((query) =>
|
||||
queryClient.refetchQueries({
|
||||
queryKey: toQueryKey({
|
||||
apiUrl: query.options?.apiUrl ?? apiUrl,
|
||||
path: query.path,
|
||||
params: query.params,
|
||||
}),
|
||||
type: "active",
|
||||
exact: true,
|
||||
}),
|
||||
),
|
||||
);
|
||||
setRefreshing(false);
|
||||
}, [queries, apiUrl, queryClient]);
|
||||
|
||||
return [refreshing, refresh] as const;
|
||||
};
|
||||
|
||||
export const useInfiniteFetch = <Data,>(query: QueryIdentifier<Data>) => {
|
||||
let { apiUrl, authToken } = useContext(AccountContext);
|
||||
if (query.options?.apiUrl) apiUrl = query.options.apiUrl;
|
||||
|
||||
@ -1,27 +1,7 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { useState } from "react";
|
||||
import { RefreshControl, ScrollView } from "react-native";
|
||||
import { Genre } from "~/models";
|
||||
import { Fetch, prefetch } from "~/query";
|
||||
import { Fetch, useRefresh } from "~/query";
|
||||
import { shuffle } from "~/utils";
|
||||
import { GenreGrid } from "./genre";
|
||||
import { Header } from "./header";
|
||||
import { NewsList } from "./news";
|
||||
@ -29,69 +9,39 @@ import { Recommended } from "./recommended";
|
||||
import { VerticalRecommended } from "./vertical";
|
||||
import { WatchlistList } from "./watchlist";
|
||||
|
||||
export async function loader() {
|
||||
const randomItems = [...Object.values(Genre)];
|
||||
await Promise.all([
|
||||
prefetch(Header.query()),
|
||||
prefetch(WatchlistList.query()),
|
||||
prefetch(NewsList.query()),
|
||||
...randomItems.filter((_, i) => i < 6).map((x) => prefetch(GenreGrid.query(x))),
|
||||
prefetch(Recommended.query()),
|
||||
prefetch(VerticalRecommended.query()),
|
||||
]);
|
||||
}
|
||||
|
||||
export const HomePage = () => {
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const randomItems = [...Object.values(Genre)];
|
||||
const genres = shuffle(Object.values(Genre.enum));
|
||||
const [isRefreshing, refresh] = useRefresh(HomePage.queries(genres));
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
onRefresh={async () => {
|
||||
setRefreshing(true);
|
||||
await loader();
|
||||
setRefreshing(false);
|
||||
}}
|
||||
refreshing={refreshing}
|
||||
/>
|
||||
<RefreshControl onRefresh={refresh} refreshing={isRefreshing} />
|
||||
}
|
||||
>
|
||||
<Fetch
|
||||
query={Header.query()}
|
||||
Render={(x) => (
|
||||
<Header
|
||||
isLoading={false}
|
||||
name={x.name}
|
||||
tagline={x.kind !== "collection" && "tagline" in x ? x.tagline : null}
|
||||
tagline={x.kind !== "collection" ? x.tagline : null}
|
||||
description={x.description}
|
||||
thumbnail={x.thumbnail}
|
||||
link={x.kind !== "collection" ? x.playHref : null}
|
||||
infoLink={x.href}
|
||||
/>
|
||||
)}
|
||||
Loader={() => (
|
||||
<Header
|
||||
isLoading={true}
|
||||
name=""
|
||||
tagline={null}
|
||||
description={null}
|
||||
thumbnail={null}
|
||||
link={null}
|
||||
infoLink="#"
|
||||
/>
|
||||
)}
|
||||
Loader={Header.Loader}
|
||||
/>
|
||||
<WatchlistList />
|
||||
<NewsList />
|
||||
{randomItems
|
||||
{genres
|
||||
.filter((_, i) => i < 2)
|
||||
.map((x) => (
|
||||
<GenreGrid key={x} genre={x} />
|
||||
))}
|
||||
<Recommended />
|
||||
{randomItems
|
||||
{genres
|
||||
.filter((_, i) => i >= 2 && i < 6)
|
||||
.map((x) => (
|
||||
<GenreGrid key={x} genre={x} />
|
||||
@ -104,3 +54,12 @@ export const HomePage = () => {
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
HomePage.queries = (randomItems: Genre[]) => [
|
||||
Header.query(),
|
||||
WatchlistList.query(),
|
||||
NewsList.query(),
|
||||
...randomItems.filter((_, i) => i < 6).map((x) => GenreGrid.query(x)),
|
||||
Recommended.query(),
|
||||
VerticalRecommended.query(),
|
||||
];
|
||||
|
||||
@ -48,3 +48,20 @@ export const displayRuntime = (runtime: number | null) => {
|
||||
if (runtime < 60) return `${runtime}min`;
|
||||
return `${Math.floor(runtime / 60)}h${runtime % 60}`;
|
||||
};
|
||||
|
||||
// shuffle an array in place, stolen from https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
|
||||
export function shuffle<T>(array: T[]): T[] {
|
||||
let currentIndex = array.length;
|
||||
|
||||
while (currentIndex !== 0) {
|
||||
const randomIndex = Math.floor(Math.random() * currentIndex);
|
||||
currentIndex--;
|
||||
|
||||
[array[currentIndex], array[randomIndex]] = [
|
||||
array[randomIndex],
|
||||
array[currentIndex],
|
||||
];
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user