import { InfiniteData, useInfiniteQuery, UseInfiniteQueryResult } from '@tanstack/react-query'; import { usePlHooksApiClient } from '@/contexts/api-client'; import { queryClient, usePlHooksQueryClient } from '@/contexts/query-client'; import { importEntities } from '@/importer'; import { deduplicateNotifications } from '@/normalizers/notification'; import { flattenPages } from '@/utils/queries'; import type { Notification as BaseNotification, PaginatedResponse, PlApiClient } from 'pl-api'; type UseNotificationParams = { types?: Array; excludeTypes?: Array; }; const getQueryKey = (params: UseNotificationParams) => [ 'notifications', 'lists', params.types ? params.types.join('|') : params.excludeTypes ? 'exclude:' + params.excludeTypes.join('|') : 'all', ]; const importNotifications = (response: PaginatedResponse) => { const deduplicatedNotifications = deduplicateNotifications(response.items); importEntities({ notifications: deduplicatedNotifications, }); return { items: deduplicatedNotifications.filter(({ duplicate }) => !duplicate).map(({ id }) => id), previous: response.previous, next: response.next, }; }; const useNotificationList = ( params: UseNotificationParams, ): Omit< UseInfiniteQueryResult< InfiniteData< { items: string[]; previous: (() => Promise>) | null; next: (() => Promise>) | null; }, unknown >, Error >, 'data' > & { data: string[] } => { const { client } = usePlHooksApiClient(); const queryClient = usePlHooksQueryClient(); const notificationsQuery = useInfiniteQuery( { queryKey: getQueryKey(params), queryFn: ({ pageParam }) => (pageParam.next ? pageParam.next() : client.notifications.getNotifications({ types: params.types, exclude_types: params.excludeTypes, }) ).then(importNotifications), initialPageParam: { next: null as (() => Promise>) | null }, getNextPageParam: (response) => response, }, queryClient, ); const data: string[] = flattenPages(notificationsQuery.data) || []; return { ...notificationsQuery, data, }; }; const prefetchNotifications = (client: PlApiClient, params: UseNotificationParams) => queryClient.prefetchInfiniteQuery({ queryKey: getQueryKey(params), queryFn: () => client.notifications .getNotifications({ types: params.types, exclude_types: params.excludeTypes, }) .then(importNotifications), initialPageParam: { next: null as (() => Promise>) | null }, }); export { useNotificationList, prefetchNotifications };