import type { Body, Meta, State, Uppy, UppyFile } from '@uppy/core' import type { I18n } from '@uppy/utils' // @ts-ignore untyped import { VirtualList } from '@uppy/utils' import { useMemo } from 'preact/hooks' import type { DashboardState } from '../Dashboard.js' import FileItem from './FileItem/index.js' type FileListProps = { id: string i18n: I18n uppy: Uppy files: State['files'] resumableUploads: boolean hideRetryButton: boolean hidePauseResumeButton: boolean hideCancelButton: boolean showLinkToFileUploadResult: boolean showRemoveButtonAfterComplete: boolean metaFields: DashboardState['metaFields'] isSingleFile: boolean toggleFileCard: (show: boolean, fileId: string) => void handleRequestThumbnail: (file: UppyFile) => void handleCancelThumbnail: (file: UppyFile) => void recoveredState: State['recoveredState'] individualCancellation: boolean itemsPerRow: number openFileEditor: (file: UppyFile) => void canEditFile: (file: UppyFile) => boolean toggleAddFilesPanel: (show: boolean) => void containerWidth: number containerHeight: number } function chunks(list: T[], size: number): T[][] { const chunked: T[][] = [] let currentChunk: T[] = [] list.forEach((item: T) => { if (currentChunk.length < size) { currentChunk.push(item) } else { chunked.push(currentChunk) currentChunk = [item] } }) if (currentChunk.length) chunked.push(currentChunk) return chunked } export default function FileList({ id, i18n, uppy, files, resumableUploads, hideRetryButton, hidePauseResumeButton, hideCancelButton, showLinkToFileUploadResult, showRemoveButtonAfterComplete, metaFields, isSingleFile, toggleFileCard, handleRequestThumbnail, handleCancelThumbnail, recoveredState, individualCancellation, itemsPerRow, openFileEditor, canEditFile, toggleAddFilesPanel, containerWidth, containerHeight, }: FileListProps) { // It's not great that this is hardcoded! // It's ESPECIALLY not great that this is checking against `itemsPerRow`! const rowHeight = itemsPerRow === 1 ? // Mobile 71 : // 190px height + 2 * 5px margin 200 // Sort files by file.isGhost, ghost files first, only if recoveredState is present const rows = useMemo(() => { const sortByGhostComesFirst = (file1: string, file2: string) => Number(files[file2].isGhost) - Number(files[file1].isGhost) const fileIds = Object.keys(files) if (recoveredState) fileIds.sort(sortByGhostComesFirst) return chunks(fileIds, itemsPerRow) }, [files, itemsPerRow, recoveredState]) const renderRow = (row: string[]) => (
{row.map((fileID: string) => ( ))}
) if (isSingleFile) { return
{renderRow(rows[0])}
} return ( ) }