Support drag the folder and drop here to upload files.

pull/17026/head
Silow9 1 year ago
parent 5d72003ebb
commit bef400ab01

@ -196,22 +196,68 @@ const FileUploader = ({
e.stopPropagation() e.stopPropagation()
e.target === dragRef.current && setDragging(false) e.target === dragRef.current && setDragging(false)
} }
type FileWithPath = {
relativePath?: string
} & File
const traverseFileEntry = useCallback(
(entry: any, prefix = ''): Promise<FileWithPath[]> => {
return new Promise((resolve) => {
if (entry.isFile) {
entry.file((file: FileWithPath) => {
file.relativePath = `${prefix}${file.name}` // 保留相对路径
resolve([file])
})
}
else if (entry.isDirectory) {
const reader = entry.createReader()
const entries: any[] = []
const read = () => {
reader.readEntries(async (results: FileSystemEntry[]) => {
if (!results.length) {
const files = await Promise.all(
entries.map(ent =>
traverseFileEntry(ent, `${prefix}${entry.name}/`),
),
)
resolve(files.flat())
}
else {
entries.push(...results)
read()
}
})
}
read()
}
else {
resolve([])
}
})
},
[], // ← 依赖为空,引用稳定
)
const handleDrop = useCallback((e: DragEvent) => { const handleDrop = useCallback(
e.preventDefault() async (e: DragEvent) => {
e.stopPropagation() e.preventDefault()
setDragging(false) e.stopPropagation()
if (!e.dataTransfer) setDragging(false)
return if (!e.dataTransfer) return
const nested = await Promise.all(
let files = [...e.dataTransfer.files] as File[] Array.from(e.dataTransfer.items).map((it) => {
if (notSupportBatchUpload) const entry = (it as any).webkitGetAsEntry?.()
files = files.slice(0, 1) if (entry) return traverseFileEntry(entry)
const f = it.getAsFile?.()
const validFiles = files.filter(isValid) return f ? Promise.resolve([f]) : Promise.resolve([])
initialUpload(validFiles) }),
}, [initialUpload, isValid, notSupportBatchUpload]) )
let files = nested.flat()
if (notSupportBatchUpload) files = files.slice(0, 1)
const valid = files.filter(isValid)
initialUpload(valid)
},
[initialUpload, isValid, notSupportBatchUpload, traverseFileEntry],
)
const selectHandle = () => { const selectHandle = () => {
if (fileUploader.current) if (fileUploader.current)
fileUploader.current.click() fileUploader.current.click()

Loading…
Cancel
Save