import { keepPreviousData, useInfiniteQuery } from '@tanstack/react-query'; import { FileIcon } from 'lucide-react'; import { Skeleton } from '#/components/atoms/skeleton.jsx'; import { EmptyState } from '#/components/molecules/empty-state.jsx'; import { ErrorNotice } from '#/components/molecules/error-notice.jsx'; import { FileCard } from '#/components/molecules/file-card.jsx'; import { TextLink } from '#/components/molecules/text-link.jsx'; import { FilesHeader } from '#/components/organisms/files-header.jsx'; import { ImageGrid } from '#/components/organisms/image-grid.jsx'; import { get } from '#/lib/api.js'; import { queryKeys } from '#/lib/query.js'; import { cn } from '#/lib/utils.js'; function buildQuery(filters) { const query = new URLSearchParams(); if (filters.kind) query.set('kind', filters.kind); if (filters.app) query.set('app', filters.app); if (filters.unused) query.set('unused', '1'); if (filters.sort === 'largest') query.set('sort', 'largest'); const qs = query.toString(); return qs ? `/blobs?${qs}` : '/blobs'; } export function FilesPage({ filters, filesHref, recordHref, onNavigate }) { const query = buildQuery(filters); const { data, error, isPending, hasNextPage, fetchNextPage, isFetchingNextPage, isPlaceholderData, } = useInfiniteQuery({ queryKey: queryKeys.blobs(filters), queryFn: ({ pageParam }) => get( pageParam ? `${query}${query.includes('?') ? '&' : '?'}cursor=${encodeURIComponent(pageParam)}` : query, ), initialPageParam: null, getNextPageParam: (last) => last.cursor ?? undefined, // Keep the current list (and header) in place while a filter change loads. placeholderData: keepPreviousData, }); const pages = data?.pages ?? []; const blobs = pages.flatMap((page) => page.blobs); const blobBase = pages[0]?.blobBase || null; const facets = pages[0]?.facets || null; return (