support query key override on infinite carousels

This commit is contained in:
jeffvli
2026-01-16 04:34:44 -08:00
parent 2827b2ae01
commit a59e57572c
5 changed files with 54 additions and 31 deletions
@@ -1,4 +1,4 @@
import { useSuspenseInfiniteQuery } from '@tanstack/react-query'; import { QueryFunctionContext, useSuspenseInfiniteQuery } from '@tanstack/react-query';
import { Suspense, useCallback, useMemo } from 'react'; import { Suspense, useCallback, useMemo } from 'react';
import { api } from '/@/renderer/api'; import { api } from '/@/renderer/api';
@@ -27,6 +27,7 @@ interface AlbumCarouselProps {
enableRefresh?: boolean; enableRefresh?: boolean;
excludeIds?: string[]; excludeIds?: string[];
query?: Partial<Omit<AlbumListQuery, 'startIndex'>>; query?: Partial<Omit<AlbumListQuery, 'startIndex'>>;
queryKey?: QueryFunctionContext['queryKey'];
rowCount?: number; rowCount?: number;
sortBy: AlbumListSort; sortBy: AlbumListSort;
sortOrder: SortOrder; sortOrder: SortOrder;
@@ -39,6 +40,7 @@ const BaseAlbumInfiniteCarousel = (props: AlbumCarouselProps & { rows: DataRow[]
enableRefresh, enableRefresh,
excludeIds, excludeIds,
query: additionalQuery, query: additionalQuery,
queryKey,
rowCount = 1, rowCount = 1,
rows, rows,
sortBy, sortBy,
@@ -51,7 +53,7 @@ const BaseAlbumInfiniteCarousel = (props: AlbumCarouselProps & { rows: DataRow[]
hasNextPage, hasNextPage,
isFetchingNextPage, isFetchingNextPage,
refetch, refetch,
} = useAlbumListInfinite(sortBy, sortOrder, 20, additionalQuery); } = useAlbumListInfinite(sortBy, sortOrder, 20, additionalQuery, queryKey);
const controls = useDefaultItemListControls(); const controls = useDefaultItemListControls();
@@ -137,9 +139,16 @@ function useAlbumListInfinite(
sortOrder: SortOrder, sortOrder: SortOrder,
itemLimit: number, itemLimit: number,
additionalQuery?: Partial<Omit<AlbumListQuery, 'startIndex'>>, additionalQuery?: Partial<Omit<AlbumListQuery, 'startIndex'>>,
overrideQueryKey?: QueryFunctionContext['queryKey'],
) { ) {
const serverId = useCurrentServerId(); const serverId = useCurrentServerId();
const defaultQueryKey = queryKeys.albums.infiniteList(serverId, {
sortBy,
sortOrder,
...additionalQuery,
});
const query = useSuspenseInfiniteQuery<AlbumListResponse>({ const query = useSuspenseInfiniteQuery<AlbumListResponse>({
getNextPageParam: (lastPage, _allPages, lastPageParam) => { getNextPageParam: (lastPage, _allPages, lastPageParam) => {
if (lastPage.items.length < itemLimit) { if (lastPage.items.length < itemLimit) {
@@ -163,11 +172,7 @@ function useAlbumListInfinite(
}, },
}); });
}, },
queryKey: queryKeys.albums.infiniteList(serverId, { queryKey: overrideQueryKey || defaultQueryKey,
sortBy,
sortOrder,
...additionalQuery,
}),
}); });
return query; return query;
@@ -1,4 +1,4 @@
import { useSuspenseInfiniteQuery } from '@tanstack/react-query'; import { QueryFunctionContext, useSuspenseInfiniteQuery } from '@tanstack/react-query';
import { Suspense, useCallback, useMemo } from 'react'; import { Suspense, useCallback, useMemo } from 'react';
import { api } from '/@/renderer/api'; import { api } from '/@/renderer/api';
@@ -26,6 +26,7 @@ interface AlbumArtistCarouselProps {
containerQuery?: ReturnType<typeof useGridCarouselContainerQuery>; containerQuery?: ReturnType<typeof useGridCarouselContainerQuery>;
excludeIds?: string[]; excludeIds?: string[];
query?: Partial<Omit<AlbumArtistListQuery, 'startIndex'>>; query?: Partial<Omit<AlbumArtistListQuery, 'startIndex'>>;
queryKey?: QueryFunctionContext['queryKey'];
rowCount?: number; rowCount?: number;
sortBy: AlbumArtistListSort; sortBy: AlbumArtistListSort;
sortOrder: SortOrder; sortOrder: SortOrder;
@@ -37,6 +38,7 @@ const BaseAlbumArtistInfiniteCarousel = (props: AlbumArtistCarouselProps & { row
containerQuery, containerQuery,
excludeIds, excludeIds,
query: additionalQuery, query: additionalQuery,
queryKey,
rowCount = 1, rowCount = 1,
rows, rows,
sortBy, sortBy,
@@ -49,7 +51,7 @@ const BaseAlbumArtistInfiniteCarousel = (props: AlbumArtistCarouselProps & { row
hasNextPage, hasNextPage,
isFetchingNextPage, isFetchingNextPage,
refetch, refetch,
} = useAlbumArtistListInfinite(sortBy, sortOrder, 20, additionalQuery); } = useAlbumArtistListInfinite(sortBy, sortOrder, 20, additionalQuery, queryKey);
const controls = useDefaultItemListControls(); const controls = useDefaultItemListControls();
@@ -137,9 +139,16 @@ function useAlbumArtistListInfinite(
sortOrder: SortOrder, sortOrder: SortOrder,
itemLimit: number, itemLimit: number,
additionalQuery?: Partial<Omit<AlbumArtistListQuery, 'startIndex'>>, additionalQuery?: Partial<Omit<AlbumArtistListQuery, 'startIndex'>>,
overrideQueryKey?: QueryFunctionContext['queryKey'],
) { ) {
const serverId = useCurrentServerId(); const serverId = useCurrentServerId();
const defaultQueryKey = queryKeys.albumArtists.infiniteList(serverId, {
sortBy,
sortOrder,
...additionalQuery,
});
const query = useSuspenseInfiniteQuery<AlbumArtistListResponse>({ const query = useSuspenseInfiniteQuery<AlbumArtistListResponse>({
getNextPageParam: (lastPage, _allPages, lastPageParam) => { getNextPageParam: (lastPage, _allPages, lastPageParam) => {
if (lastPage.items.length < itemLimit) { if (lastPage.items.length < itemLimit) {
@@ -163,11 +172,7 @@ function useAlbumArtistListInfinite(
}, },
}); });
}, },
queryKey: queryKeys.albumArtists.infiniteList(serverId, { queryKey: overrideQueryKey || defaultQueryKey,
sortBy,
sortOrder,
...additionalQuery,
}),
}); });
return query; return query;
@@ -1,4 +1,4 @@
import { useSuspenseInfiniteQuery } from '@tanstack/react-query'; import { QueryFunctionContext, useSuspenseInfiniteQuery } from '@tanstack/react-query';
import { useEffect, useMemo, useRef } from 'react'; import { useEffect, useMemo, useRef } from 'react';
import { api } from '/@/renderer/api'; import { api } from '/@/renderer/api';
@@ -9,14 +9,21 @@ import { Album, AlbumListResponse, AlbumListSort, SortOrder } from '/@/shared/ty
interface InfiniteAlbumFeatureCarouselProps { interface InfiniteAlbumFeatureCarouselProps {
itemLimit?: number; itemLimit?: number;
queryKey?: QueryFunctionContext['queryKey'];
} }
export const AlbumInfiniteFeatureCarousel = ({ export const AlbumInfiniteFeatureCarousel = ({
itemLimit = 20, itemLimit = 20,
queryKey,
}: InfiniteAlbumFeatureCarouselProps) => { }: InfiniteAlbumFeatureCarouselProps) => {
const serverId = useCurrentServerId(); const serverId = useCurrentServerId();
const loadMoreTriggeredRef = useRef(false); const loadMoreTriggeredRef = useRef(false);
const defaultQueryKey = queryKeys.albums.infiniteList(serverId, {
sortBy: AlbumListSort.RANDOM,
sortOrder: SortOrder.DESC,
});
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
useSuspenseInfiniteQuery<AlbumListResponse>({ useSuspenseInfiniteQuery<AlbumListResponse>({
getNextPageParam: (lastPage, _allPages, lastPageParam) => { getNextPageParam: (lastPage, _allPages, lastPageParam) => {
@@ -40,10 +47,7 @@ export const AlbumInfiniteFeatureCarousel = ({
}, },
}); });
}, },
queryKey: queryKeys.albums.infiniteList(serverId, { queryKey: queryKey || defaultQueryKey,
sortBy: AlbumListSort.RANDOM,
sortOrder: SortOrder.DESC,
}),
}); });
// Flatten all pages and filter for albums with images // Flatten all pages and filter for albums with images
@@ -1,4 +1,4 @@
import { useSuspenseInfiniteQuery } from '@tanstack/react-query'; import { QueryFunctionContext, useSuspenseInfiniteQuery } from '@tanstack/react-query';
import { useEffect, useMemo, useRef } from 'react'; import { useEffect, useMemo, useRef } from 'react';
import { api } from '/@/renderer/api'; import { api } from '/@/renderer/api';
@@ -9,14 +9,21 @@ import { Album, AlbumListResponse, AlbumListSort, SortOrder } from '/@/shared/ty
interface InfiniteAlbumSingleFeatureCarouselProps { interface InfiniteAlbumSingleFeatureCarouselProps {
itemLimit?: number; itemLimit?: number;
queryKey?: QueryFunctionContext['queryKey'];
} }
export const AlbumInfiniteSingleFeatureCarousel = ({ export const AlbumInfiniteSingleFeatureCarousel = ({
itemLimit = 20, itemLimit = 20,
queryKey,
}: InfiniteAlbumSingleFeatureCarouselProps) => { }: InfiniteAlbumSingleFeatureCarouselProps) => {
const serverId = useCurrentServerId(); const serverId = useCurrentServerId();
const loadMoreTriggeredRef = useRef(false); const loadMoreTriggeredRef = useRef(false);
const defaultQueryKey = queryKeys.albums.infiniteList(serverId, {
sortBy: AlbumListSort.RANDOM,
sortOrder: SortOrder.DESC,
});
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
useSuspenseInfiniteQuery<AlbumListResponse>({ useSuspenseInfiniteQuery<AlbumListResponse>({
getNextPageParam: (lastPage, _allPages, lastPageParam) => { getNextPageParam: (lastPage, _allPages, lastPageParam) => {
@@ -40,10 +47,7 @@ export const AlbumInfiniteSingleFeatureCarousel = ({
}, },
}); });
}, },
queryKey: queryKeys.albums.infiniteList(serverId, { queryKey: queryKey || defaultQueryKey,
sortBy: AlbumListSort.RANDOM,
sortOrder: SortOrder.DESC,
}),
}); });
// Flatten all pages and filter for albums with images // Flatten all pages and filter for albums with images
@@ -1,4 +1,4 @@
import { useSuspenseInfiniteQuery } from '@tanstack/react-query'; import { QueryFunctionContext, useSuspenseInfiniteQuery } from '@tanstack/react-query';
import { Suspense, useCallback, useMemo } from 'react'; import { Suspense, useCallback, useMemo } from 'react';
import { api } from '/@/renderer/api'; import { api } from '/@/renderer/api';
@@ -29,6 +29,7 @@ interface SongCarouselProps {
enableRefresh?: boolean; enableRefresh?: boolean;
excludeIds?: string[]; excludeIds?: string[];
query?: Partial<Omit<SongListQuery, 'startIndex'>>; query?: Partial<Omit<SongListQuery, 'startIndex'>>;
queryKey?: QueryFunctionContext['queryKey'];
rowCount?: number; rowCount?: number;
sortBy: SongListSort; sortBy: SongListSort;
sortOrder: SortOrder; sortOrder: SortOrder;
@@ -41,6 +42,7 @@ const BaseSongInfiniteCarousel = (props: SongCarouselProps & { rows: DataRow[] }
enableRefresh, enableRefresh,
excludeIds, excludeIds,
query: additionalQuery, query: additionalQuery,
queryKey,
rowCount = 1, rowCount = 1,
rows, rows,
sortBy, sortBy,
@@ -53,7 +55,7 @@ const BaseSongInfiniteCarousel = (props: SongCarouselProps & { rows: DataRow[] }
hasNextPage, hasNextPage,
isFetchingNextPage, isFetchingNextPage,
refetch, refetch,
} = useSongListInfinite(sortBy, sortOrder, 20, additionalQuery); } = useSongListInfinite(sortBy, sortOrder, 20, additionalQuery, queryKey);
const player = usePlayer(); const player = usePlayer();
const baseControls = useDefaultItemListControls(); const baseControls = useDefaultItemListControls();
@@ -153,9 +155,16 @@ function useSongListInfinite(
sortOrder: SortOrder, sortOrder: SortOrder,
itemLimit: number, itemLimit: number,
additionalQuery?: Partial<Omit<SongListQuery, 'startIndex'>>, additionalQuery?: Partial<Omit<SongListQuery, 'startIndex'>>,
overrideQueryKey?: QueryFunctionContext['queryKey'],
) { ) {
const serverId = useCurrentServerId(); const serverId = useCurrentServerId();
const defaultQueryKey = queryKeys.songs.infiniteList(serverId, {
sortBy,
sortOrder,
...additionalQuery,
});
const query = useSuspenseInfiniteQuery<SongListResponse>({ const query = useSuspenseInfiniteQuery<SongListResponse>({
getNextPageParam: (lastPage, _allPages, lastPageParam) => { getNextPageParam: (lastPage, _allPages, lastPageParam) => {
if (lastPage.items.length < itemLimit) { if (lastPage.items.length < itemLimit) {
@@ -179,11 +188,7 @@ function useSongListInfinite(
}, },
}); });
}, },
queryKey: queryKeys.songs.infiniteList(serverId, { queryKey: overrideQueryKey || defaultQueryKey,
sortBy,
sortOrder,
...additionalQuery,
}),
}); });
return query; return query;