feat: support uploading folders via drag-and-drop and toolbar button
This commit is contained in:
@@ -21,6 +21,7 @@ import { loadFilesSettings } from "@/components/files/files-settings-dialog";
|
||||
import type { FolderLayout } from "@/components/files/files-settings-dialog";
|
||||
import { FolderTreeSidebar } from "@/components/files/folder-tree-sidebar";
|
||||
import { ResizeHandle } from "@/components/layout/resize-handle";
|
||||
import { getDroppedFilesAndFolders } from "@/lib/webdav/drop-utils";
|
||||
import type { FileResource } from "@/stores/file-store";
|
||||
|
||||
type SortKey = "name" | "size" | "modified";
|
||||
@@ -624,16 +625,20 @@ export function FileBrowser({
|
||||
e.stopPropagation();
|
||||
setIsDraggingOver(false);
|
||||
|
||||
const files = Array.from(e.dataTransfer.files);
|
||||
if (files.length > 0) {
|
||||
setIsUploading(true);
|
||||
try {
|
||||
await onUploadFiles(files);
|
||||
} finally {
|
||||
setIsUploading(false);
|
||||
setIsUploading(true);
|
||||
try {
|
||||
const { files, hasDirectories } = await getDroppedFilesAndFolders(e.dataTransfer);
|
||||
if (files.length > 0) {
|
||||
if (hasDirectories) {
|
||||
await onUploadFolder(files);
|
||||
} else {
|
||||
await onUploadFiles(files);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
setIsUploading(false);
|
||||
}
|
||||
}, [onUploadFiles]);
|
||||
}, [onUploadFiles, onUploadFolder]);
|
||||
|
||||
const handleFileInputChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const files = Array.from(e.target.files || []);
|
||||
@@ -945,6 +950,16 @@ export function FileBrowser({
|
||||
>
|
||||
<Upload className="w-4 h-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-8 w-8"
|
||||
onClick={() => folderInputRef.current?.click()}
|
||||
title={t("upload_folder")}
|
||||
disabled={isUploading}
|
||||
>
|
||||
<FolderUp className="w-4 h-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
@@ -1195,6 +1210,14 @@ export function FileBrowser({
|
||||
setIsUploading(false);
|
||||
}
|
||||
}}
|
||||
onUploadFolder={async (files: File[]) => {
|
||||
setIsUploading(true);
|
||||
try {
|
||||
await onUploadFolder(files);
|
||||
} finally {
|
||||
setIsUploading(false);
|
||||
}
|
||||
}}
|
||||
onCreateFolder={() => setShowNewFolder(true)}
|
||||
onCreateTextFile={() => setShowNewTextFile(true)}
|
||||
/>
|
||||
|
||||
@@ -2,16 +2,18 @@
|
||||
|
||||
import { useCallback, useState } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Upload, FolderPlus, FilePlus } from "lucide-react";
|
||||
import { Upload, FolderPlus, FilePlus, FolderUp } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { getDroppedFilesAndFolders } from "@/lib/webdav/drop-utils";
|
||||
|
||||
interface FileUploadAreaProps {
|
||||
onUpload: (files: File[]) => Promise<void>;
|
||||
onUploadFolder?: (files: File[]) => Promise<void>;
|
||||
onCreateFolder: () => void;
|
||||
onCreateTextFile?: () => void;
|
||||
}
|
||||
|
||||
export function FileUploadArea({ onUpload, onCreateFolder, onCreateTextFile }: FileUploadAreaProps) {
|
||||
export function FileUploadArea({ onUpload, onUploadFolder, onCreateFolder, onCreateTextFile }: FileUploadAreaProps) {
|
||||
const t = useTranslations("files");
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
|
||||
@@ -32,11 +34,15 @@ export function FileUploadArea({ onUpload, onCreateFolder, onCreateTextFile }: F
|
||||
e.stopPropagation();
|
||||
setIsDragging(false);
|
||||
|
||||
const files = Array.from(e.dataTransfer.files);
|
||||
const { files, hasDirectories } = await getDroppedFilesAndFolders(e.dataTransfer);
|
||||
if (files.length > 0) {
|
||||
await onUpload(files);
|
||||
if (hasDirectories && onUploadFolder) {
|
||||
await onUploadFolder(files);
|
||||
} else {
|
||||
await onUpload(files);
|
||||
}
|
||||
}
|
||||
}, [onUpload]);
|
||||
}, [onUpload, onUploadFolder]);
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center h-full p-8">
|
||||
|
||||
Reference in New Issue
Block a user