From af6072a6e929e2efc97b1c54ecac74c9c09ad831 Mon Sep 17 00:00:00 2001 From: Onyela Udochukwuka Date: Sat, 24 Aug 2024 15:50:05 +0100 Subject: [PATCH 1/5] chore: installed missing packages --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index b55307b..f91facd 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "dependencies": { "@chakra-ui/icons": "^2.1.1", "@chakra-ui/react": "^2.8.2", + "@dnd-kit/core": "^6.1.0", + "@dnd-kit/sortable": "^8.0.0", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@fortawesome/fontawesome-svg-core": "^6.5.1", From 8fc212be19b4b58653f711ccd48d9de008fd94c7 Mon Sep 17 00:00:00 2001 From: Onyela Udochukwuka Date: Sat, 24 Aug 2024 15:51:00 +0100 Subject: [PATCH 2/5] improvements: added nme extract to top level --- src/components/FileUpload.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/FileUpload.tsx b/src/components/FileUpload.tsx index 23117c5..118c374 100644 --- a/src/components/FileUpload.tsx +++ b/src/components/FileUpload.tsx @@ -5,15 +5,15 @@ import { Track } from '../../types/types'; interface FileUploadProps { onUploadSuccess: () => void; } - - const FileUpload: React.FC = ({ onUploadSuccess }) => { - const [uploading, setUploading] = useState(false); +export const extractTitleFromFileName = (fileName: string) => { + // Remove file extension and replace underscores/dashes with spaces + return fileName.replace(/\.[^/.]+$/, '').replace(/[_-]/g, ' '); +}; +const FileUpload: React.FC = ({ onUploadSuccess }) => { + const [uploading, setUploading] = useState(false); const { uploadTrack } = useTracks(); // Use the `useTracks` hook - const extractTitleFromFileName = (fileName: string) => { - // Remove file extension and replace underscores/dashes with spaces - return fileName.replace(/\.[^/.]+$/, '').replace(/[_-]/g, ' '); - }; + const handleFileUpload = async (file: File) => { setUploading(true); @@ -56,7 +56,7 @@ interface FileUploadProps { - ); + ); }; export default FileUpload; \ No newline at end of file From 6ab6f4145e8735d9b369e57178710a65adb62fa5 Mon Sep 17 00:00:00 2001 From: Onyela Udochukwuka Date: Sat, 24 Aug 2024 15:51:27 +0100 Subject: [PATCH 3/5] feat: added logic for drag and drop logic --- src/components/layout/DragAndDropWrapper.tsx | 79 ++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/components/layout/DragAndDropWrapper.tsx diff --git a/src/components/layout/DragAndDropWrapper.tsx b/src/components/layout/DragAndDropWrapper.tsx new file mode 100644 index 0000000..6c18d5c --- /dev/null +++ b/src/components/layout/DragAndDropWrapper.tsx @@ -0,0 +1,79 @@ +import React, { FC, useRef, useState } from "react" +import { FaUpload } from "react-icons/fa"; +import { extractTitleFromFileName } from "../FileUpload"; +import { useTracks } from "@/hooks/UseTracks"; +interface IProps { + +} +const DragAndDropWrapper: FC = () => { + const wrapperRef = useRef(null); + const fileInputRef = useRef(null); + const [showModal, setShowModal] = useState(false); + const [uploading, setUploading] = useState(false) + const { uploadTrack, fetchTracks } = useTracks(); + const onDragEnter = () => setShowModal(true) + const onDragLeave = () => setShowModal(false) + const onDrop = async (event: React.DragEvent) => { + event.preventDefault(); + setShowModal(false) + const files = event.dataTransfer.files; + if (files.length > 0) { + if (fileInputRef.current) { + fileInputRef.current.files = files + setUploading(true); + for (let i = 0; i < files.length; i++) { + const file: File = files[i] + const formData = new FormData(); + formData.append('file', file); + formData.append('name', extractTitleFromFileName(file.name)); + try { + const success = await uploadTrack(formData); // Use the uploadTrack function from the hook + if (success) { + console.log('Track uploaded successfully'); + await fetchTracks(); + // Optionally, refetch tracks to update the list + } else { + console.error('Track upload failed with no error thrown'); + } + + } catch (error) { + console.error('Error during file upload:', error); + } + } + setUploading(false); + } + } + }; + + const handlePreventDefault = (e: React.DragEvent) => e.preventDefault() + return ( + +
+ +
+ {(showModal || uploading) && ( +
+ + {uploading ? "File uploading" : "Drop file To upload"} +
+ )} +
+ + ) +} +export default DragAndDropWrapper \ No newline at end of file From 518331d96fcf826700b09bab8393b47a8121c49c Mon Sep 17 00:00:00 2001 From: Onyela Udochukwuka Date: Sat, 24 Aug 2024 15:51:51 +0100 Subject: [PATCH 4/5] feat: referenced drag and drop handler --- src/pages/index.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 83dddfc..2c16576 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -10,6 +10,7 @@ import Modal from '@/components/Modal'; import NavBar from '@/components/layout/NavBar'; import { useRouter } from 'next/router'; import { useTracks } from '@/hooks/UseTracks'; +import DragAndDropWrapper from '@/components/layout/DragAndDropWrapper'; const HomePage: React.FC = () => { const [error, setError] = useState(''); @@ -79,6 +80,10 @@ const HomePage: React.FC = () => {
+ + + + From 5a784ea3b9f6959e6951410a147c9024d52efb0d Mon Sep 17 00:00:00 2001 From: Udochukwuka Onyela Date: Tue, 10 Sep 2024 23:17:03 +0100 Subject: [PATCH 5/5] improvements: added portal handler for drag and drop, moved file catcher to windows instance --- src/components/layout/DragAndDropWrapper.tsx | 70 ++++++++++++-------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/src/components/layout/DragAndDropWrapper.tsx b/src/components/layout/DragAndDropWrapper.tsx index 6c18d5c..8838272 100644 --- a/src/components/layout/DragAndDropWrapper.tsx +++ b/src/components/layout/DragAndDropWrapper.tsx @@ -1,28 +1,38 @@ -import React, { FC, useRef, useState } from "react" -import { FaUpload } from "react-icons/fa"; -import { extractTitleFromFileName } from "../FileUpload"; -import { useTracks } from "@/hooks/UseTracks"; +import React, {FC, useLayoutEffect, useRef, useState} from "react" +import {FaUpload} from "react-icons/fa"; +import {extractTitleFromFileName} from "../FileUpload"; +import {useTracks} from "@/hooks/UseTracks"; +import {createPortal} from "react-dom"; + interface IProps { } + const DragAndDropWrapper: FC = () => { const wrapperRef = useRef(null); const fileInputRef = useRef(null); const [showModal, setShowModal] = useState(false); const [uploading, setUploading] = useState(false) - const { uploadTrack, fetchTracks } = useTracks(); - const onDragEnter = () => setShowModal(true) + const {uploadTrack, fetchTracks} = useTracks(); + const [portal, setPortal] = useState(null); + const onDragEnter = (e: DragEvent) => { + e.preventDefault() + setShowModal(true) + } const onDragLeave = () => setShowModal(false) - const onDrop = async (event: React.DragEvent) => { + const onDrop = async (event: DragEvent) => { event.preventDefault(); - setShowModal(false) - const files = event.dataTransfer.files; - if (files.length > 0) { - if (fileInputRef.current) { + setShowModal(true) + const files = event.dataTransfer?.files || null; + const itemLength = event.dataTransfer?.items.length || 0; + setShowModal(true) + if (itemLength > 0) { + if (fileInputRef.current?.files) { fileInputRef.current.files = files setUploading(true); - for (let i = 0; i < files.length; i++) { - const file: File = files[i] + for (let i = 0; i < itemLength; i++) { + const file: File | undefined = files?.[i] + if (!file) continue; const formData = new FormData(); formData.append('file', file); formData.append('name', extractTitleFromFileName(file.name)); @@ -43,18 +53,27 @@ const DragAndDropWrapper: FC = () => { setUploading(false); } } - }; + setShowModal(false) - const handlePreventDefault = (e: React.DragEvent) => e.preventDefault() - return ( - + }; + useLayoutEffect(() => { + setPortal(document.body) + window.addEventListener('drop', onDrop) + window.addEventListener('dragover', onDragEnter) + window.addEventListener('dragenter', onDragEnter) + window.addEventListener('dragleave', onDragLeave) + return () => { + window.removeEventListener('drop', onDrop) + window.removeEventListener('dragover', onDragEnter) + window.removeEventListener('dragenter', onDragEnter) + window.removeEventListener('dragleave', onDragLeave) + } + }, []) + return portal && createPortal( +
= () => {
{(showModal || uploading) && (
- + {uploading ? "File uploading" : "Drop file To upload"}
)}
- - ) + , portal) } export default DragAndDropWrapper \ No newline at end of file