mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 04:20:12 +02:00
optimize list refresh functions
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
||||
UseSuspenseQueryOptions,
|
||||
} from '@tanstack/react-query';
|
||||
import throttle from 'lodash/throttle';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { useListContext } from '/@/renderer/context/list-context';
|
||||
@@ -61,6 +61,8 @@ export const useItemListInfiniteLoader = ({
|
||||
serverId,
|
||||
}: UseItemListInfiniteLoaderProps) => {
|
||||
const queryClient = useQueryClient();
|
||||
const lastFetchedPageRef = useRef<number>(-1);
|
||||
const currentVisibleRangeRef = useRef<null | { startIndex: number; stopIndex: number }>(null);
|
||||
|
||||
const { data: totalItemCount } = useSuspenseQuery<number, any, number, any>(listCountQuery);
|
||||
|
||||
@@ -88,6 +90,8 @@ export const useItemListInfiniteLoader = ({
|
||||
pagesLoaded: {},
|
||||
};
|
||||
});
|
||||
lastFetchedPageRef.current = -1;
|
||||
currentVisibleRangeRef.current = null;
|
||||
}, [query, queryClient, dataQueryKey]);
|
||||
|
||||
const { data } = useQuery<{ data: unknown[]; pagesLoaded: Record<string, boolean> }>({
|
||||
@@ -144,12 +148,18 @@ export const useItemListInfiniteLoader = ({
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
// Track the last fetched page
|
||||
lastFetchedPageRef.current = Math.max(lastFetchedPageRef.current, pageNumber);
|
||||
},
|
||||
[itemsPerPage, query, queryClient, serverId, dataQueryKey, listQueryFn, itemType],
|
||||
);
|
||||
|
||||
const onRangeChangedBase = useCallback(
|
||||
async (range: { startIndex: number; stopIndex: number }) => {
|
||||
// Track the current visible range
|
||||
currentVisibleRangeRef.current = range;
|
||||
|
||||
const pageNumber = Math.floor(range.startIndex / itemsPerPage);
|
||||
|
||||
const currentData = queryClient.getQueryData<{
|
||||
@@ -204,18 +214,54 @@ export const useItemListInfiniteLoader = ({
|
||||
|
||||
const refresh = useCallback(
|
||||
async (force?: boolean) => {
|
||||
// Invalidate all queries to ensure fresh data
|
||||
await queryClient.invalidateQueries();
|
||||
|
||||
if (force) {
|
||||
await queryClient.setQueryData(dataQueryKey, getInitialData(totalItemCount));
|
||||
// Reset the infinite list data
|
||||
const currentData = queryClient.getQueryData<{
|
||||
data: unknown[];
|
||||
pagesLoaded: Record<string, boolean>;
|
||||
}>(dataQueryKey);
|
||||
|
||||
if (force || currentData) {
|
||||
// Reset data to initial state and clear all loaded pages
|
||||
await queryClient.setQueryData(dataQueryKey, (oldData: any) => {
|
||||
if (!oldData) return getInitialData(totalItemCount);
|
||||
return {
|
||||
...oldData,
|
||||
data: Array.from({ length: totalItemCount }, () => undefined),
|
||||
pagesLoaded: {},
|
||||
};
|
||||
});
|
||||
lastFetchedPageRef.current = -1;
|
||||
}
|
||||
|
||||
// await onRangeChanged({
|
||||
// endIndex: currentPageRef.current * itemsPerPage,
|
||||
// startIndex: currentPageRef.current * itemsPerPage,
|
||||
// });
|
||||
// Add a delay to make the refresh visually clear
|
||||
await new Promise((resolve) => setTimeout(resolve, 150));
|
||||
|
||||
// Determine which page to refetch based on current visible range
|
||||
let pageToFetch = 0;
|
||||
if (currentVisibleRangeRef.current) {
|
||||
// Calculate the page from the current visible range
|
||||
pageToFetch = Math.floor(currentVisibleRangeRef.current.startIndex / itemsPerPage);
|
||||
} else if (lastFetchedPageRef.current >= 0) {
|
||||
// Fallback to last fetched page if no visible range is tracked
|
||||
pageToFetch = lastFetchedPageRef.current;
|
||||
}
|
||||
|
||||
// Refetch the current page
|
||||
await fetchPage(pageToFetch);
|
||||
|
||||
// Trigger range changed to ensure adjacent pages are prefetched if needed
|
||||
const startIndex = pageToFetch * itemsPerPage;
|
||||
const stopIndex = Math.min((pageToFetch + 1) * itemsPerPage, totalItemCount);
|
||||
|
||||
await onRangeChangedBase({
|
||||
startIndex,
|
||||
stopIndex,
|
||||
});
|
||||
},
|
||||
[queryClient, totalItemCount, dataQueryKey],
|
||||
[queryClient, itemsPerPage, onRangeChangedBase, dataQueryKey, totalItemCount, fetchPage],
|
||||
);
|
||||
|
||||
const updateItems = useCallback(
|
||||
|
||||
@@ -98,9 +98,22 @@ export const useItemListPaginatedLoader = ({
|
||||
staleTime: 1000 * 15,
|
||||
});
|
||||
|
||||
const refresh = useCallback(() => {
|
||||
return queryRefetch();
|
||||
}, [queryRefetch]);
|
||||
const refresh = useCallback(
|
||||
async (force?: boolean) => {
|
||||
const queryKey = queryKeys[getQueryKeyName(itemType)].list(serverId, queryParams);
|
||||
|
||||
await queryClient.invalidateQueries();
|
||||
|
||||
if (force) {
|
||||
queryClient.setQueryData(queryKey, {
|
||||
items: getInitialData(itemsPerPage),
|
||||
});
|
||||
}
|
||||
|
||||
return queryRefetch();
|
||||
},
|
||||
[queryClient, queryRefetch, queryParams, serverId, itemType, itemsPerPage],
|
||||
);
|
||||
|
||||
const updateItems = useCallback(
|
||||
(indexes: number[], value: object) => {
|
||||
@@ -140,7 +153,7 @@ export const useItemListPaginatedLoader = ({
|
||||
return;
|
||||
}
|
||||
|
||||
return refresh();
|
||||
return refresh(true);
|
||||
};
|
||||
|
||||
const handleFavorite = (payload: UserFavoriteEventPayload) => {
|
||||
|
||||
@@ -46,6 +46,7 @@ export const AlbumListPaginatedGrid = forwardRef<any, AlbumListPaginatedGridProp
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.ALBUM,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.ALBUM,
|
||||
listCountQuery,
|
||||
|
||||
@@ -54,6 +54,7 @@ export const AlbumListPaginatedTable = forwardRef<any, AlbumListPaginatedTablePr
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.ALBUM,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.ALBUM,
|
||||
listCountQuery,
|
||||
|
||||
@@ -47,6 +47,7 @@ export const AlbumArtistListPaginatedGrid = forwardRef<any, AlbumArtistListPagin
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.ALBUM_ARTIST,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.ALBUM_ARTIST,
|
||||
listCountQuery,
|
||||
|
||||
@@ -55,6 +55,7 @@ export const AlbumArtistListPaginatedTable = forwardRef<any, AlbumArtistListPagi
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.ALBUM_ARTIST,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.ALBUM_ARTIST,
|
||||
listCountQuery,
|
||||
|
||||
@@ -46,6 +46,7 @@ export const ArtistListPaginatedGrid = forwardRef<any, ArtistListPaginatedGridPr
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.ARTIST,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.ARTIST,
|
||||
listCountQuery,
|
||||
|
||||
@@ -54,6 +54,7 @@ export const ArtistListPaginatedTable = forwardRef<any, ArtistListPaginatedTable
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.ARTIST,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.ARTIST,
|
||||
listCountQuery,
|
||||
|
||||
@@ -46,6 +46,7 @@ export const GenreListPaginatedGrid = forwardRef<any, GenreListPaginatedGridProp
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.GENRE,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.GENRE,
|
||||
listCountQuery,
|
||||
|
||||
@@ -54,6 +54,7 @@ export const GenreListPaginatedTable = forwardRef<any, GenreListPaginatedTablePr
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.GENRE,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.GENRE,
|
||||
listCountQuery,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useLocation, useParams } from 'react-router';
|
||||
import { useParams } from 'react-router';
|
||||
|
||||
import { ListContext } from '/@/renderer/context/list-context';
|
||||
import { useGenreList } from '/@/renderer/features/genres/api/genres-api';
|
||||
@@ -30,9 +30,6 @@ const GenreDetailRoute = () => {
|
||||
return genres?.items.find((g) => g.id === genreId)?.name || '—';
|
||||
}, [genreId, genres]);
|
||||
|
||||
const location = useLocation();
|
||||
console.log('location', location.pathname);
|
||||
|
||||
return (
|
||||
<AnimatedPage>
|
||||
<ListContext.Provider value={providerValue}>
|
||||
|
||||
@@ -46,6 +46,7 @@ export const PlaylistListPaginatedGrid = forwardRef<any, PlaylistListPaginatedGr
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.PLAYLIST,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.PLAYLIST,
|
||||
listCountQuery,
|
||||
|
||||
@@ -54,6 +54,7 @@ export const PlaylistListPaginatedTable = forwardRef<any, PlaylistListPaginatedT
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.PLAYLIST,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.PLAYLIST,
|
||||
listCountQuery,
|
||||
|
||||
@@ -39,6 +39,7 @@ export const SongListPaginatedGrid = forwardRef<any, SongListPaginatedGridProps>
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.SONG,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.SONG,
|
||||
listCountQuery,
|
||||
|
||||
@@ -49,6 +49,7 @@ export const SongListPaginatedTable = forwardRef<any, SongListPaginatedTableProp
|
||||
|
||||
const { data, pageCount, totalItemCount } = useItemListPaginatedLoader({
|
||||
currentPage,
|
||||
eventKey: ItemListKey.SONG,
|
||||
itemsPerPage,
|
||||
itemType: LibraryItem.SONG,
|
||||
listCountQuery,
|
||||
|
||||
Reference in New Issue
Block a user