diff --git a/src/renderer/hooks/use-list-filter-refresh.ts b/src/renderer/hooks/use-list-filter-refresh.ts new file mode 100644 index 00000000..e9485925 --- /dev/null +++ b/src/renderer/hooks/use-list-filter-refresh.ts @@ -0,0 +1,144 @@ +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'; + +interface UseHandleListFilterChangeProps { + itemType: LibraryItem; + server: ServerListItem | null; +} + +export const useListFilterRefresh = ({ server, itemType }: UseHandleListFilterChangeProps) => { + const queryClient = useQueryClient(); + + const queryKeyFn: + | ((serverId: string, query: Record, 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; + } + + return null; + }, [itemType]); + + const queryFn: ((args: any) => Promise | null | undefined>) | null = + useMemo(() => { + if (itemType === LibraryItem.ALBUM) { + return api.controller.getAlbumList; + } + if (itemType === LibraryItem.ALBUM_ARTIST) { + return api.controller.getAlbumArtistList; + } + if (itemType === LibraryItem.PLAYLIST) { + return api.controller.getPlaylistList; + } + if (itemType === LibraryItem.SONG) { + return api.controller.getSongList; + } + + return null; + }, [itemType]); + + const handleRefreshTable = useCallback( + async (tableRef: MutableRefObject, filter: any) => { + if (!tableRef || !queryKeyFn || !queryFn) { + return; + } + + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; + + const query = filter; + const pagination = { + limit, + startIndex, + }; + + const queryKey = queryKeyFn(server?.id || '', query, pagination); + + const res = await queryClient.fetchQuery({ + queryFn: async ({ signal }) => { + return queryFn({ + apiClientProps: { + server, + signal, + }, + query, + }); + }, + queryKey, + }); + + params.successCallback(res?.items || [], res?.totalRecordCount || 0); + }, + + rowCount: undefined, + }; + + tableRef.current?.api.setDatasource(dataSource); + tableRef.current?.api.purgeInfiniteCache(); + tableRef.current?.api.ensureIndexVisible(0, 'top'); + }, + [queryClient, queryFn, queryKeyFn, server], + ); + + const handleRefreshGrid = useCallback( + async (gridRef: MutableRefObject, filter: any) => { + if (!gridRef || !queryKeyFn || !queryFn) { + return; + } + + gridRef.current?.scrollTo(0); + gridRef.current?.resetLoadMoreItemsCache(); + gridRef.current?.setItemData([]); + + const query = filter; + const pagination = { + limit: 200, + startIndex: 0, + }; + + const queryKey = queryKeyFn(server?.id || '', query, pagination); + + const res = await queryClient.fetchQuery({ + queryFn: async ({ signal }) => { + return queryFn({ + apiClientProps: { + server, + signal, + }, + query, + }); + }, + queryKey, + }); + + if (!res?.items) { + return; + } + + gridRef.current?.setItemData(res.items); + }, + [queryClient, queryFn, queryKeyFn, server], + ); + + return { + handleRefreshGrid, + handleRefreshTable, + }; +};