Split key pagination in central handler
This commit is contained in:
parent
1cb0a1d72a
commit
6821735f65
4 changed files with 91 additions and 103 deletions
|
@ -20,14 +20,21 @@ import type {
|
|||
} from './types';
|
||||
|
||||
export const splitPaginatedQuery = (key: any) => {
|
||||
const { startIndex, limit, ...query } = key;
|
||||
const { startIndex, limit, ...filter } = key;
|
||||
|
||||
if (startIndex === undefined || limit === undefined) {
|
||||
return {
|
||||
filter,
|
||||
pagination: {
|
||||
limit,
|
||||
startIndex,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
pagination: {
|
||||
limit,
|
||||
startIndex,
|
||||
},
|
||||
query,
|
||||
filter,
|
||||
pagination: undefined,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -45,14 +52,12 @@ export const queryKeys: Record<
|
|||
if (query) return [serverId, 'albumArtists', 'detail', query] as const;
|
||||
return [serverId, 'albumArtists', 'detail'] as const;
|
||||
},
|
||||
list: (
|
||||
serverId: string,
|
||||
query?: Omit<AlbumArtistListQuery, 'startIndex' | 'limit'>,
|
||||
pagination?: QueryPagination,
|
||||
) => {
|
||||
if (query && pagination)
|
||||
return [serverId, 'albumArtists', 'list', query, pagination] as const;
|
||||
if (query) return [serverId, 'albumArtists', 'list', query] as const;
|
||||
list: (serverId: string, query?: AlbumArtistListQuery) => {
|
||||
if (query) {
|
||||
const { pagination, filter } = splitPaginatedQuery(query);
|
||||
return [serverId, 'albumArtists', 'list', filter, pagination] as const;
|
||||
}
|
||||
|
||||
return [serverId, 'albumArtists', 'list'] as const;
|
||||
},
|
||||
root: (serverId: string) => [serverId, 'albumArtists'] as const,
|
||||
|
@ -64,13 +69,11 @@ export const queryKeys: Record<
|
|||
albums: {
|
||||
detail: (serverId: string, query?: AlbumDetailQuery) =>
|
||||
[serverId, 'albums', 'detail', query] as const,
|
||||
list: (
|
||||
serverId: string,
|
||||
query?: Omit<AlbumListQuery, 'startIndex' | 'limit'>,
|
||||
pagination?: QueryPagination,
|
||||
) => {
|
||||
if (query && pagination)
|
||||
return [serverId, 'albums', 'list', query, pagination] as const;
|
||||
list: (serverId: string, query?: AlbumListQuery) => {
|
||||
if (query) {
|
||||
const { pagination, filter } = splitPaginatedQuery(query);
|
||||
return [serverId, 'albums', 'list', filter, pagination] as const;
|
||||
}
|
||||
if (query) return [serverId, 'albums', 'list', query] as const;
|
||||
return [serverId, 'albums', 'list'] as const;
|
||||
},
|
||||
|
@ -80,14 +83,11 @@ export const queryKeys: Record<
|
|||
[serverId, 'albums', 'songs', query] as const,
|
||||
},
|
||||
artists: {
|
||||
list: (
|
||||
serverId: string,
|
||||
query?: Omit<ArtistListQuery, 'startIndex' | 'limit'>,
|
||||
pagination?: QueryPagination,
|
||||
) => {
|
||||
if (query && pagination)
|
||||
return [serverId, 'artists', 'list', query, pagination] as const;
|
||||
if (query) return [serverId, 'artists', 'list', query] as const;
|
||||
list: (serverId: string, query?: ArtistListQuery) => {
|
||||
if (query) {
|
||||
const { pagination, filter } = splitPaginatedQuery(query);
|
||||
return [serverId, 'artists', 'list', filter, pagination] as const;
|
||||
}
|
||||
return [serverId, 'artists', 'list'] as const;
|
||||
},
|
||||
root: (serverId: string) => [serverId, 'artists'] as const,
|
||||
|
@ -100,26 +100,19 @@ export const queryKeys: Record<
|
|||
list: (serverId: string) => [serverId, 'musicFolders', 'list'] as const,
|
||||
},
|
||||
playlists: {
|
||||
detail: (
|
||||
serverId: string,
|
||||
id?: string,
|
||||
query?: Omit<PlaylistDetailQuery, 'startIndex' | 'limit'>,
|
||||
pagination?: QueryPagination,
|
||||
) => {
|
||||
if (query && pagination)
|
||||
return [serverId, 'playlists', id, 'detail', query, pagination] as const;
|
||||
if (query) return [serverId, 'playlists', id, 'detail', query] as const;
|
||||
detail: (serverId: string, id?: string, query?: PlaylistDetailQuery) => {
|
||||
if (query) {
|
||||
const { pagination, filter } = splitPaginatedQuery(query);
|
||||
return [serverId, 'playlists', id, 'detail', filter, pagination] as const;
|
||||
}
|
||||
if (id) return [serverId, 'playlists', id, 'detail'] as const;
|
||||
return [serverId, 'playlists', 'detail'] as const;
|
||||
},
|
||||
detailSongList: (
|
||||
serverId: string,
|
||||
id: string,
|
||||
query?: Omit<PlaylistSongListQuery, 'startIndex' | 'limit'>,
|
||||
pagination?: QueryPagination,
|
||||
) => {
|
||||
if (query && pagination)
|
||||
return [serverId, 'playlists', id, 'detailSongList', query, pagination] as const;
|
||||
detailSongList: (serverId: string, id: string, query?: PlaylistSongListQuery) => {
|
||||
if (query) {
|
||||
const { pagination, filter } = splitPaginatedQuery(query);
|
||||
return [serverId, 'playlists', id, 'detailSongList', filter, pagination] as const;
|
||||
}
|
||||
if (query && id) return [serverId, 'playlists', id, 'detailSongList', query] as const;
|
||||
if (id) return [serverId, 'playlists', id, 'detailSongList'] as const;
|
||||
return [serverId, 'playlists', 'detailSongList'] as const;
|
||||
|
@ -129,15 +122,11 @@ export const queryKeys: Record<
|
|||
return [serverId, 'playlists', 'list'] as const;
|
||||
},
|
||||
root: (serverId: string) => [serverId, 'playlists'] as const,
|
||||
songList: (
|
||||
serverId: string,
|
||||
id?: string,
|
||||
query?: Omit<PlaylistSongListQuery, 'startIndex' | 'limit'>,
|
||||
pagination?: QueryPagination,
|
||||
) => {
|
||||
if (query && id && pagination)
|
||||
return [serverId, 'playlists', id, 'songList', query, pagination] as const;
|
||||
if (query && id) return [serverId, 'playlists', id, 'songList', query] as const;
|
||||
songList: (serverId: string, id?: string, query?: PlaylistSongListQuery) => {
|
||||
if (query && id) {
|
||||
const { pagination, filter } = splitPaginatedQuery(query);
|
||||
return [serverId, 'playlists', id, 'songList', filter, pagination] as const;
|
||||
}
|
||||
if (id) return [serverId, 'playlists', id, 'songList'] as const;
|
||||
return [serverId, 'playlists', 'songList'] as const;
|
||||
},
|
||||
|
@ -157,12 +146,11 @@ export const queryKeys: Record<
|
|||
if (query) return [serverId, 'songs', 'detail', query] as const;
|
||||
return [serverId, 'songs', 'detail'] as const;
|
||||
},
|
||||
list: (
|
||||
serverId: string,
|
||||
query?: Omit<SongListQuery, 'startIndex' | 'limit'>,
|
||||
pagination?: QueryPagination,
|
||||
) => {
|
||||
if (query && pagination) return [serverId, 'songs', 'list', query, pagination] as const;
|
||||
list: (serverId: string, query?: SongListQuery) => {
|
||||
if (query) {
|
||||
const { pagination, filter } = splitPaginatedQuery(query);
|
||||
return [serverId, 'songs', 'list', filter, pagination] as const;
|
||||
}
|
||||
if (query) return [serverId, 'songs', 'list', query] as const;
|
||||
return [serverId, 'songs', 'list'] as const;
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useCallback, useMemo } from 'react';
|
|||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import { ListOnScrollProps } from 'react-window';
|
||||
import { controller } from '/@/renderer/api/controller';
|
||||
import { queryKeys, splitPaginatedQuery } from '/@/renderer/api/query-keys';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import {
|
||||
Album,
|
||||
AlbumListQuery,
|
||||
|
@ -169,16 +169,14 @@ export const AlbumListGridView = ({ gridRef, itemCount }: any) => {
|
|||
return [];
|
||||
}
|
||||
|
||||
const listQuery: AlbumListQuery = {
|
||||
const query: AlbumListQuery = {
|
||||
limit: take,
|
||||
startIndex: skip,
|
||||
...filter,
|
||||
...customFilters,
|
||||
};
|
||||
|
||||
const { query, pagination } = splitPaginatedQuery(listQuery);
|
||||
|
||||
const queryKey = queryKeys.albums.list(server?.id || '', query, pagination);
|
||||
const queryKey = queryKeys.albums.list(server?.id || '', query);
|
||||
|
||||
const albums = await queryClient.fetchQuery(queryKey, async ({ signal }) =>
|
||||
controller.getAlbumList({
|
||||
|
@ -186,7 +184,7 @@ export const AlbumListGridView = ({ gridRef, itemCount }: any) => {
|
|||
server,
|
||||
signal,
|
||||
},
|
||||
query: listQuery,
|
||||
query,
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
RiAddBoxFill,
|
||||
RiAddCircleFill,
|
||||
RiFilterFill,
|
||||
RiFolder2Line,
|
||||
RiFolder2Fill,
|
||||
RiMoreFill,
|
||||
RiPlayFill,
|
||||
RiRefreshLine,
|
||||
|
@ -275,6 +275,10 @@ export const AlbumListHeaderFilters = ({ gridRef, tableRef }: AlbumListHeaderFil
|
|||
return isNavidromeFilterApplied || isJellyfinFilterApplied;
|
||||
}, [filter?._custom?.jellyfin, filter?._custom?.navidrome, server?.type]);
|
||||
|
||||
const isFolderFilterApplied = useMemo(() => {
|
||||
return filter.musicFolderId !== undefined;
|
||||
}, [filter.musicFolderId]);
|
||||
|
||||
return (
|
||||
<Flex justify="space-between">
|
||||
<Group
|
||||
|
@ -320,9 +324,16 @@ export const AlbumListHeaderFilters = ({ gridRef, tableRef }: AlbumListHeaderFil
|
|||
compact
|
||||
fw={600}
|
||||
size="md"
|
||||
sx={{
|
||||
svg: {
|
||||
fill: isFolderFilterApplied
|
||||
? 'var(--primary-color) !important'
|
||||
: undefined,
|
||||
},
|
||||
}}
|
||||
variant="subtle"
|
||||
>
|
||||
{cq.isSm ? 'Folder' : <RiFolder2Line size="1.3rem" />}
|
||||
<RiFolder2Fill size="1.3rem" />
|
||||
</Button>
|
||||
</DropdownMenu.Target>
|
||||
<DropdownMenu.Dropdown>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { MutableRefObject, useCallback, useMemo } from 'react';
|
||||
import { IDatasource } from '@ag-grid-community/core';
|
||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys, QueryPagination } from '/@/renderer/api/query-keys';
|
||||
import { LibraryItem, ServerListItem, BasePaginatedResponse } from '/@/renderer/api/types';
|
||||
import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid';
|
||||
import { QueryKey, useQueryClient } from '@tanstack/react-query';
|
||||
import { MutableRefObject, useCallback, useMemo } from 'react';
|
||||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { BasePaginatedResponse, LibraryItem, ServerListItem } from '/@/renderer/api/types';
|
||||
import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid';
|
||||
|
||||
interface UseHandleListFilterChangeProps {
|
||||
itemType: LibraryItem;
|
||||
|
@ -15,24 +15,23 @@ interface UseHandleListFilterChangeProps {
|
|||
export const useListFilterRefresh = ({ server, itemType }: UseHandleListFilterChangeProps) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const queryKeyFn:
|
||||
| ((serverId: string, query: Record<any, any>, pagination: QueryPagination) => QueryKey)
|
||||
| null = useMemo(() => {
|
||||
if (itemType === LibraryItem.ALBUM) {
|
||||
return queryKeys.albums.list;
|
||||
}
|
||||
if (itemType === LibraryItem.ALBUM_ARTIST) {
|
||||
return queryKeys.albumArtists.list;
|
||||
}
|
||||
if (itemType === LibraryItem.PLAYLIST) {
|
||||
return queryKeys.playlists.list;
|
||||
}
|
||||
if (itemType === LibraryItem.SONG) {
|
||||
return queryKeys.songs.list;
|
||||
}
|
||||
const queryKeyFn: ((serverId: string, query: Record<any, any>) => QueryKey) | null =
|
||||
useMemo(() => {
|
||||
if (itemType === LibraryItem.ALBUM) {
|
||||
return queryKeys.albums.list;
|
||||
}
|
||||
if (itemType === LibraryItem.ALBUM_ARTIST) {
|
||||
return queryKeys.albumArtists.list;
|
||||
}
|
||||
if (itemType === LibraryItem.PLAYLIST) {
|
||||
return queryKeys.playlists.list;
|
||||
}
|
||||
if (itemType === LibraryItem.SONG) {
|
||||
return queryKeys.songs.list;
|
||||
}
|
||||
|
||||
return null;
|
||||
}, [itemType]);
|
||||
return null;
|
||||
}, [itemType]);
|
||||
|
||||
const queryFn: ((args: any) => Promise<BasePaginatedResponse<any> | null | undefined>) | null =
|
||||
useMemo(() => {
|
||||
|
@ -63,13 +62,9 @@ export const useListFilterRefresh = ({ server, itemType }: UseHandleListFilterCh
|
|||
const limit = params.endRow - params.startRow;
|
||||
const startIndex = params.startRow;
|
||||
|
||||
const query = filter;
|
||||
const pagination = {
|
||||
limit,
|
||||
startIndex,
|
||||
};
|
||||
const query = { ...filter, limit, startIndex };
|
||||
|
||||
const queryKey = queryKeyFn(server?.id || '', query, pagination);
|
||||
const queryKey = queryKeyFn(server?.id || '', query);
|
||||
|
||||
const res = await queryClient.fetchQuery({
|
||||
queryFn: async ({ signal }) => {
|
||||
|
@ -107,13 +102,9 @@ export const useListFilterRefresh = ({ server, itemType }: UseHandleListFilterCh
|
|||
gridRef.current?.resetLoadMoreItemsCache();
|
||||
gridRef.current?.setItemData([]);
|
||||
|
||||
const query = filter;
|
||||
const pagination = {
|
||||
limit: 200,
|
||||
startIndex: 0,
|
||||
};
|
||||
const query = { ...filter, limit: 200, startIndex: 0 };
|
||||
|
||||
const queryKey = queryKeyFn(server?.id || '', query, pagination);
|
||||
const queryKey = queryKeyFn(server?.id || '', query);
|
||||
|
||||
const res = await queryClient.fetchQuery({
|
||||
queryFn: async ({ signal }) => {
|
||||
|
|
Reference in a new issue