From b32f9fa397a025a4e1db1eff3201b5521294b6b6 Mon Sep 17 00:00:00 2001 From: bietiaop <1527109126@qq.com> Date: Mon, 3 Feb 2025 19:56:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=87=E4=BB=B6=E4=B8=8B=E8=BD=BD/?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- napcat.webui/package.json | 2 + .../file_manage/file_preview_modal.tsx | 85 ++++++++ .../src/components/file_manage/file_table.tsx | 129 +++++++++---- napcat.webui/src/controllers/file_manager.ts | 101 ++++++++++ .../src/pages/dashboard/file_manager.tsx | 115 ++++++++++- napcat.webui/src/utils/request.ts | 4 + package.json | 13 +- src/webui/src/api/File.ts | 181 +++++++++++++++--- src/webui/src/router/File.ts | 7 +- 9 files changed, 565 insertions(+), 72 deletions(-) create mode 100644 napcat.webui/src/components/file_manage/file_preview_modal.tsx diff --git a/napcat.webui/package.json b/napcat.webui/package.json index 0ef7e2db..5b38b017 100644 --- a/napcat.webui/package.json +++ b/napcat.webui/package.json @@ -29,6 +29,7 @@ "@heroui/listbox": "2.3.10", "@heroui/modal": "2.2.8", "@heroui/navbar": "2.2.9", + "@heroui/pagination": "^2.2.9", "@heroui/popover": "2.3.10", "@heroui/select": "2.4.10", "@heroui/slider": "2.4.8", @@ -63,6 +64,7 @@ "quill": "^2.0.3", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-dropzone": "^14.3.5", "react-error-boundary": "^5.0.0", "react-hook-form": "^7.54.2", "react-hot-toast": "^2.4.1", diff --git a/napcat.webui/src/components/file_manage/file_preview_modal.tsx b/napcat.webui/src/components/file_manage/file_preview_modal.tsx new file mode 100644 index 00000000..be18f696 --- /dev/null +++ b/napcat.webui/src/components/file_manage/file_preview_modal.tsx @@ -0,0 +1,85 @@ +import { Button } from '@heroui/button' +import { + Modal, + ModalBody, + ModalContent, + ModalFooter, + ModalHeader +} from '@heroui/modal' +import { Spinner } from '@heroui/spinner' +import { useRequest } from 'ahooks' +import path from 'path-browserify' + +import FileManager from '@/controllers/file_manager' + +interface FilePreviewModalProps { + isOpen: boolean + filePath: string + onClose: () => void +} + +const imageExts = ['.png', '.jpg', '.jpeg', '.gif', '.bmp'] +const videoExts = ['.mp4', '.webm'] +const audioExts = ['.mp3', '.wav'] + +const supportedPreviewExts = [...imageExts, ...videoExts, ...audioExts] + +export default function FilePreviewModal({ + isOpen, + filePath, + onClose +}: FilePreviewModalProps) { + const ext = path.extname(filePath).toLowerCase() + const { data, loading, error, run } = useRequest( + async (path: string) => FileManager.downloadToURL(path), + { + refreshDeps: [filePath], + refreshDepsAction: () => { + const ext = path.extname(filePath).toLowerCase() + if (!filePath || !supportedPreviewExts.includes(ext)) { + return + } + run(filePath) + } + } + ) + + let contentElement = null + if (!supportedPreviewExts.includes(ext)) { + contentElement =
暂不支持预览此文件类型
+ } else if (error) { + contentElement =
读取文件失败
+ } else if (loading || !data) { + contentElement = ( +
+ +
+ ) + } else if (imageExts.includes(ext)) { + contentElement = ( + 预览 + ) + } else if (videoExts.includes(ext)) { + contentElement = ( +