From 2ec8dbdc699f9acfd5ace7a3d64c593b4e6d9ff2 Mon Sep 17 00:00:00 2001 From: florian <> Date: Thu, 28 Mar 2024 20:30:14 +0100 Subject: [PATCH] feat: Added drag drop, progress bar --- src/components/ProgressBar/ProgressBar.tsx | 16 ++++ src/pages/Transfer.tsx | 10 +-- src/pages/Upload.tsx | 97 ++++++++++++++++++---- 3 files changed, 99 insertions(+), 24 deletions(-) create mode 100644 src/components/ProgressBar/ProgressBar.tsx diff --git a/src/components/ProgressBar/ProgressBar.tsx b/src/components/ProgressBar/ProgressBar.tsx new file mode 100644 index 0000000..cd4aa6b --- /dev/null +++ b/src/components/ProgressBar/ProgressBar.tsx @@ -0,0 +1,16 @@ +const ProgressBar = ({ value, max }: { value: number; max: number }) => { + return ( +
+ {max !== undefined && value !== undefined && max > 0 && ( +
+ {Math.floor((value * 100) / max)} % +
+ )} +
+ ); +}; + +export default ProgressBar; diff --git a/src/pages/Transfer.tsx b/src/pages/Transfer.tsx index d3e955c..c9b76fa 100644 --- a/src/pages/Transfer.tsx +++ b/src/pages/Transfer.tsx @@ -15,6 +15,7 @@ import { formatFileSize } from '../utils'; import BlobList from '../components/BlobList/BlobList'; import './Transfer.css'; import { useNavigate, useParams } from 'react-router-dom'; +import ProgressBar from '../components/ProgressBar/ProgressBar'; type TransferStatus = { [key: string]: { @@ -134,14 +135,7 @@ export const Transfer = () => { )}
-
-
- {Math.floor((transferStatus.size * 100) / transferStatus.fullSize)} % -
-
+ {
{formatFileSize(transferStatus.size)} / {formatFileSize(transferStatus.fullSize)} transferred diff --git a/src/pages/Upload.tsx b/src/pages/Upload.tsx index cd5e5cd..a565b78 100644 --- a/src/pages/Upload.tsx +++ b/src/pages/Upload.tsx @@ -1,64 +1,129 @@ -import { useEffect, useRef, useState } from 'react'; +import { ChangeEvent, DragEvent, useEffect, useState } from 'react'; import { useServers } from '../utils/useServers'; import { BlossomClient } from 'blossom-client-sdk'; import { useNDK } from '../ndk'; import { useServerInfo } from '../utils/useServerInfo'; import { useQueryClient } from '@tanstack/react-query'; +import { ArrowUpOnSquareIcon } from '@heroicons/react/24/outline'; +import ProgressBar from '../components/ProgressBar/ProgressBar'; + +type TransferStats = { + enabled: boolean; + size: number; + transferred: number; +}; function Upload() { const servers = useServers(); const { signEventTemplate } = useNDK(); const { serverInfo } = useServerInfo(); - const inputRef = useRef(null); const queryClient = useQueryClient(); - const [uploadTarget, setUploadTarget] = useState<{ [key: string]: boolean }>({}); + const [transfers, setTransfers] = useState<{ [key: string]: TransferStats }>({}); + const [files, setFiles] = useState([]); const upload = async () => { - if (inputRef.current && inputRef.current.files) { + if (files && files.length) { + // sum files sizes + const totalSize = files.reduce((acc, f) => acc + f.size, 0); + + // set all entries size to totalSize + setTransfers(ut => { + const newTransfers = { ...ut }; + for (const server of servers) { + if (newTransfers[server.name].enabled) { + newTransfers[server.name].size = totalSize; + } + } + return newTransfers; + }); + for (const server of servers) { - if (!uploadTarget[server.name]) { + if (!transfers[server.name]?.enabled) { continue; } const serverUrl = serverInfo[server.name].url; - for (const file of inputRef.current.files) { + for (const file of files) { const uploadAuth = await BlossomClient.getUploadAuth(file, signEventTemplate, 'Upload Blob'); const newBlob = await BlossomClient.uploadBlob(serverUrl, file, uploadAuth); + + transfers[server.name].transferred += file.size; console.log(newBlob); } queryClient.invalidateQueries({ queryKey: ['blobs', server.name] }); + setFiles([]); } } }; + const clearTransfers = () => { + setTransfers(servers.reduce((acc, s) => ({ ...acc, [s.name]: { enabled: true, size: 0, transferred: 0 } }), {})); + }; + useEffect(() => { - setUploadTarget(servers.reduce((acc, s) => ({ ...acc, [s.name]: true }), {})); + clearTransfers(); }, [servers]); + const handleFileChange = (event: ChangeEvent) => { + const selectedFiles = event.target.files; + if (selectedFiles && selectedFiles.length > 0) { + const newFiles = Array.from(selectedFiles); + setFiles(prevFiles => [...prevFiles, ...newFiles]); + } + }; + + const handleDrop = (event: DragEvent) => { + event.preventDefault(); + const droppedFiles = event.dataTransfer?.files; + if (droppedFiles && droppedFiles.length > 0) { + const newFiles = Array.from(droppedFiles); + setFiles(prevFiles => [...prevFiles, ...newFiles]); + } + }; + return ( <>

Upload

- + + +
{servers.map(s => ( -
+ <> setUploadTarget(ut => ({ ...ut, [s.name]: e.target.checked }))} + checked={transfers[s.name]?.enabled || false} + onChange={e => + setTransfers(ut => ({ ...ut, [s.name]: { enabled: e.target.checked, transferred: 0, size: 0 } })) + } /> -
+ {transfers[s.name]?.enabled ? ( + + ) : ( +
+ )} + ))} +
- - +
);