mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-15 04:51:06 +02:00
Prevent double fetching when force refreshing paginated views (#1637)
* Prevent double fetching when force refreshing paginated views * remove await from infinite list loader query invalidation * add mutation and loading state to list refresh * add non-suspense query to list genre filters to add loading state * remove list count data set on random queries --------- Co-authored-by: jeffvli <jeffvictorli@gmail.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
useMutation,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
useSuspenseQuery,
|
||||
@@ -11,6 +12,7 @@ import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { useListContext } from '/@/renderer/context/list-context';
|
||||
import { eventEmitter } from '/@/renderer/events/event-emitter';
|
||||
import { UserFavoriteEventPayload, UserRatingEventPayload } from '/@/renderer/events/events';
|
||||
import { getListRefreshMutationKey } from '/@/renderer/features/shared/components/list-refresh-button';
|
||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
||||
|
||||
export const getListQueryKeyName = (itemType: LibraryItem): string => {
|
||||
@@ -293,10 +295,10 @@ export const useItemListInfiniteLoader = ({
|
||||
[onRangeChangedBase],
|
||||
);
|
||||
|
||||
const refresh = useCallback(
|
||||
async (force?: boolean) => {
|
||||
const refreshMutation = useMutation({
|
||||
mutationFn: async (force?: boolean) => {
|
||||
// Invalidate all queries to ensure fresh data
|
||||
await queryClient.invalidateQueries();
|
||||
queryClient.invalidateQueries();
|
||||
|
||||
// Reset the infinite list data
|
||||
const currentData = queryClient.getQueryData<{
|
||||
@@ -320,7 +322,7 @@ export const useItemListInfiniteLoader = ({
|
||||
}
|
||||
|
||||
// Add a delay to make the refresh visually clear
|
||||
await new Promise((resolve) => setTimeout(resolve, 150));
|
||||
// await new Promise((resolve) => setTimeout(resolve, 150));
|
||||
|
||||
// Determine which page to refetch based on current visible range
|
||||
let pageToFetch = 0;
|
||||
@@ -344,7 +346,12 @@ export const useItemListInfiniteLoader = ({
|
||||
stopIndex,
|
||||
});
|
||||
},
|
||||
[queryClient, itemsPerPage, onRangeChangedBase, dataQueryKey, totalItemCount, fetchPage],
|
||||
mutationKey: getListRefreshMutationKey(eventKey),
|
||||
});
|
||||
|
||||
const refresh = useCallback(
|
||||
async (force?: boolean) => refreshMutation.mutateAsync(force),
|
||||
[refreshMutation],
|
||||
);
|
||||
|
||||
const updateItems = useCallback(
|
||||
@@ -376,7 +383,7 @@ export const useItemListInfiniteLoader = ({
|
||||
return;
|
||||
}
|
||||
|
||||
return refresh(true);
|
||||
refreshMutation.mutate(true);
|
||||
};
|
||||
|
||||
eventEmitter.on('ITEM_LIST_REFRESH', handleRefresh);
|
||||
@@ -384,7 +391,7 @@ export const useItemListInfiniteLoader = ({
|
||||
return () => {
|
||||
eventEmitter.off('ITEM_LIST_REFRESH', handleRefresh);
|
||||
};
|
||||
}, [eventKey, refresh]);
|
||||
}, [eventKey, refreshMutation]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleFavorite = (payload: UserFavoriteEventPayload) => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
useMutation,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
useSuspenseQuery,
|
||||
@@ -10,6 +11,7 @@ import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { useListContext } from '/@/renderer/context/list-context';
|
||||
import { eventEmitter } from '/@/renderer/events/event-emitter';
|
||||
import { UserFavoriteEventPayload, UserRatingEventPayload } from '/@/renderer/events/events';
|
||||
import { getListRefreshMutationKey } from '/@/renderer/features/shared/components/list-refresh-button';
|
||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
||||
|
||||
const getQueryKeyName = (itemType: LibraryItem): string => {
|
||||
@@ -83,7 +85,7 @@ export const useItemListPaginatedLoader = ({
|
||||
[itemsPerPage, startIndex, query],
|
||||
);
|
||||
|
||||
const { data, refetch: queryRefetch } = useQuery({
|
||||
const { data } = useQuery({
|
||||
gcTime: 1000 * 15,
|
||||
placeholderData: { items: getInitialData(itemsPerPage) },
|
||||
queryFn: async ({ signal }) => {
|
||||
@@ -98,22 +100,20 @@ export const useItemListPaginatedLoader = ({
|
||||
staleTime: 1000 * 15,
|
||||
});
|
||||
|
||||
const refresh = useCallback(
|
||||
async (force?: boolean) => {
|
||||
const refreshMutation = useMutation({
|
||||
mutationFn: async (force?: boolean) => {
|
||||
const queryKey = queryKeys[getQueryKeyName(itemType)].list(serverId, queryParams);
|
||||
|
||||
await queryClient.invalidateQueries();
|
||||
|
||||
if (force) {
|
||||
queryClient.setQueryData(queryKey, {
|
||||
items: getInitialData(itemsPerPage),
|
||||
});
|
||||
}
|
||||
|
||||
return queryRefetch();
|
||||
await queryClient.invalidateQueries();
|
||||
},
|
||||
[queryClient, queryRefetch, queryParams, serverId, itemType, itemsPerPage],
|
||||
);
|
||||
mutationKey: getListRefreshMutationKey(eventKey ?? 'paginated'),
|
||||
});
|
||||
|
||||
const updateItems = useCallback(
|
||||
(indexes: number[], value: object) => {
|
||||
@@ -153,7 +153,7 @@ export const useItemListPaginatedLoader = ({
|
||||
return;
|
||||
}
|
||||
|
||||
return refresh(true);
|
||||
refreshMutation.mutate(true);
|
||||
};
|
||||
|
||||
const handleFavorite = (payload: UserFavoriteEventPayload) => {
|
||||
@@ -220,7 +220,7 @@ export const useItemListPaginatedLoader = ({
|
||||
eventEmitter.off('USER_FAVORITE', handleFavorite);
|
||||
eventEmitter.off('USER_RATING', handleRating);
|
||||
};
|
||||
}, [data, eventKey, itemType, serverId, refresh, updateItems]);
|
||||
}, [data, eventKey, itemType, refreshMutation, serverId, updateItems]);
|
||||
|
||||
return { data: data?.items || [], pageCount, totalItemCount };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user