From b4c64d3dc0d5efacef3cefb04c07197a05d75fa7 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 22 Aug 2020 22:35:53 -0700 Subject: [PATCH] Better handling of file uploads --- resources/scripts/api/http.ts | 5 ++ .../components/server/files/UploadButton.tsx | 53 ++++++++----------- resources/scripts/plugins/useEventListener.ts | 8 +-- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/resources/scripts/api/http.ts b/resources/scripts/api/http.ts index 9ac1b64f8..a642bb16e 100644 --- a/resources/scripts/api/http.ts +++ b/resources/scripts/api/http.ts @@ -66,6 +66,11 @@ export function httpErrorToHuman (error: any): string { if (data.errors && data.errors[0] && data.errors[0].detail) { return data.errors[0].detail; } + + // Errors from wings directory, mostly just for file uploads. + if (data.error && typeof data.error === 'string') { + return data.error; + } } return error.message; diff --git a/resources/scripts/components/server/files/UploadButton.tsx b/resources/scripts/components/server/files/UploadButton.tsx index 979b0a600..8b48052bd 100644 --- a/resources/scripts/components/server/files/UploadButton.tsx +++ b/resources/scripts/components/server/files/UploadButton.tsx @@ -8,6 +8,8 @@ import styled from 'styled-components/macro'; import { ModalMask } from '@/components/elements/Modal'; import Fade from '@/components/elements/Fade'; import useEventListener from '@/plugins/useEventListener'; +import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; +import useFlash from '@/plugins/useFlash'; const InnerContainer = styled.div` max-width: 600px; @@ -17,6 +19,8 @@ const InnerContainer = styled.div` export default () => { const { uuid } = useServer(); const [ visible, setVisible ] = useState(false); + const [ loading, setLoading ] = useState(false); + const { clearFlashes, clearAndAddHttpError } = useFlash(); useEventListener('dragenter', e => { e.stopPropagation(); @@ -41,42 +45,33 @@ export default () => { const onFileDrop = (e: React.DragEvent) => { e.preventDefault(); + e.stopPropagation(); + setVisible(false); if (e.dataTransfer === undefined || e.dataTransfer === null) { return; } - const files: FileList = e.dataTransfer.files; - console.log(files); - - const formData = new FormData(); - - for (let i = 0; i < files.length; i++) { - console.log(files[i]); - // @ts-ignore - formData.append('files', files[i]); - } + const form = new FormData(); + Array.from(e.dataTransfer.files).forEach(file => form.append('files', file)); + setLoading(true); + clearFlashes('files'); getFileUploadUrl(uuid) - .then(url => { - console.log(url); - - axios.post(url, formData, { - headers: { - 'Content-Type': 'multipart/form-data', - }, - }) - .then(res => { - console.log(res); - setVisible(false); - }) - .catch(error => { - console.error(error); - }); + .then(url => axios.post(url, form, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + })) + .then(res => { + console.log(res); }) .catch(error => { console.error(error); - }); + clearAndAddHttpError({ error, key: 'files' }); + }) + .then(() => setVisible(false)) + .then(() => setLoading(false)); }; return ( @@ -88,10 +83,7 @@ export default () => { key={'upload_modal_mask'} unmountOnExit > - setVisible(false)} - onDrop={onFileDrop} - > + setVisible(false)} onDrop={onFileDrop} onDragOver={e => e.preventDefault()}>

@@ -101,6 +93,7 @@ export default () => {

+ diff --git a/resources/scripts/plugins/useEventListener.ts b/resources/scripts/plugins/useEventListener.ts index 969549339..f73374bf7 100644 --- a/resources/scripts/plugins/useEventListener.ts +++ b/resources/scripts/plugins/useEventListener.ts @@ -8,13 +8,13 @@ export default (eventName: string, handler: (e: Event | CustomEvent | UIEvent | }, [ handler ]); useEffect(() => { - const isSupported = document && document.addEventListener; + const isSupported = window && window.addEventListener; if (!isSupported) return; const eventListener = (event: any) => savedHandler.current(event); - document.addEventListener(eventName, eventListener, options); + window.addEventListener(eventName, eventListener, options); return () => { - document.removeEventListener(eventName, eventListener); + window.removeEventListener(eventName, eventListener); }; - }, [ eventName, document ]); + }, [ eventName, window ]); };