import { queryClient } from 'soapbox/queries/client'; import type { InfiniteData, QueryKey, UseInfiniteQueryResult } from '@tanstack/react-query'; export interface PaginatedResult { result: T[], hasMore: boolean, link?: string, } /** Flatten paginated results into a single array. */ const flattenPages = (queryInfo: UseInfiniteQueryResult>) => { return queryInfo.data?.pages.reduce( (prev: T[], curr) => [...prev, ...curr.result], [], ); }; /** Traverse pages and update the item inside if found. */ const updatePageItem = (queryKey: QueryKey, newItem: T, isItem: (item: T, newItem: T) => boolean) => { queryClient.setQueriesData>>(queryKey, (data) => { if (data) { const pages = data.pages.map(page => { const result = page.result.map(item => isItem(item, newItem) ? newItem : item); return { ...page, result }; }); return { ...data, pages }; } }); }; /** Insert the new item at the beginning of the first page. */ const appendPageItem = (queryKey: QueryKey, newItem: T) => { queryClient.setQueryData>>(queryKey, (data) => { if (data) { const pages = [...data.pages]; pages[0] = { ...pages[0], result: [...pages[0].result, newItem] }; return { ...data, pages }; } }); }; /** Remove an item inside if found. */ const removePageItem = (queryKey: QueryKey, itemToRemove: T, isItem: (item: T, newItem: T) => boolean) => { queryClient.setQueriesData>>(queryKey, (data) => { if (data) { const pages = data.pages.map(page => { const result = page.result.filter(item => !isItem(item, itemToRemove)); return { ...page, result }; }); return { ...data, pages }; } }); }; export { flattenPages, updatePageItem, appendPageItem, removePageItem, };