Skip to content

Commit b4c64d3

Browse files
committed
Better handling of file uploads
1 parent f561089 commit b4c64d3

File tree

3 files changed

+32
-34
lines changed

3 files changed

+32
-34
lines changed

resources/scripts/api/http.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ export function httpErrorToHuman (error: any): string {
6666
if (data.errors && data.errors[0] && data.errors[0].detail) {
6767
return data.errors[0].detail;
6868
}
69+
70+
// Errors from wings directory, mostly just for file uploads.
71+
if (data.error && typeof data.error === 'string') {
72+
return data.error;
73+
}
6974
}
7075

7176
return error.message;

resources/scripts/components/server/files/UploadButton.tsx

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import styled from 'styled-components/macro';
88
import { ModalMask } from '@/components/elements/Modal';
99
import Fade from '@/components/elements/Fade';
1010
import useEventListener from '@/plugins/useEventListener';
11+
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
12+
import useFlash from '@/plugins/useFlash';
1113

1214
const InnerContainer = styled.div`
1315
max-width: 600px;
@@ -17,6 +19,8 @@ const InnerContainer = styled.div`
1719
export default () => {
1820
const { uuid } = useServer();
1921
const [ visible, setVisible ] = useState(false);
22+
const [ loading, setLoading ] = useState(false);
23+
const { clearFlashes, clearAndAddHttpError } = useFlash();
2024

2125
useEventListener('dragenter', e => {
2226
e.stopPropagation();
@@ -41,42 +45,33 @@ export default () => {
4145

4246
const onFileDrop = (e: React.DragEvent<HTMLDivElement>) => {
4347
e.preventDefault();
48+
e.stopPropagation();
4449

50+
setVisible(false);
4551
if (e.dataTransfer === undefined || e.dataTransfer === null) {
4652
return;
4753
}
4854

49-
const files: FileList = e.dataTransfer.files;
50-
console.log(files);
51-
52-
const formData = new FormData();
53-
54-
for (let i = 0; i < files.length; i++) {
55-
console.log(files[i]);
56-
// @ts-ignore
57-
formData.append('files', files[i]);
58-
}
55+
const form = new FormData();
56+
Array.from(e.dataTransfer.files).forEach(file => form.append('files', file));
5957

58+
setLoading(true);
59+
clearFlashes('files');
6060
getFileUploadUrl(uuid)
61-
.then(url => {
62-
console.log(url);
63-
64-
axios.post(url, formData, {
65-
headers: {
66-
'Content-Type': 'multipart/form-data',
67-
},
68-
})
69-
.then(res => {
70-
console.log(res);
71-
setVisible(false);
72-
})
73-
.catch(error => {
74-
console.error(error);
75-
});
61+
.then(url => axios.post(url, form, {
62+
headers: {
63+
'Content-Type': 'multipart/form-data',
64+
},
65+
}))
66+
.then(res => {
67+
console.log(res);
7668
})
7769
.catch(error => {
7870
console.error(error);
79-
});
71+
clearAndAddHttpError({ error, key: 'files' });
72+
})
73+
.then(() => setVisible(false))
74+
.then(() => setLoading(false));
8075
};
8176

8277
return (
@@ -88,10 +83,7 @@ export default () => {
8883
key={'upload_modal_mask'}
8984
unmountOnExit
9085
>
91-
<ModalMask
92-
onClick={() => setVisible(false)}
93-
onDrop={onFileDrop}
94-
>
86+
<ModalMask onClick={() => setVisible(false)} onDrop={onFileDrop} onDragOver={e => e.preventDefault()}>
9587
<div css={tw`w-full flex items-center justify-center`} style={{ pointerEvents: 'none' }}>
9688
<InnerContainer>
9789
<p css={tw`text-lg text-neutral-200 text-center`}>
@@ -101,6 +93,7 @@ export default () => {
10193
</div>
10294
</ModalMask>
10395
</Fade>
96+
<SpinnerOverlay visible={loading} size={'large'}/>
10497
<Button css={tw`mr-2`} onClick={() => setVisible(true)}>
10598
Upload
10699
</Button>

resources/scripts/plugins/useEventListener.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ export default (eventName: string, handler: (e: Event | CustomEvent | UIEvent |
88
}, [ handler ]);
99

1010
useEffect(() => {
11-
const isSupported = document && document.addEventListener;
11+
const isSupported = window && window.addEventListener;
1212
if (!isSupported) return;
1313

1414
const eventListener = (event: any) => savedHandler.current(event);
15-
document.addEventListener(eventName, eventListener, options);
15+
window.addEventListener(eventName, eventListener, options);
1616
return () => {
17-
document.removeEventListener(eventName, eventListener);
17+
window.removeEventListener(eventName, eventListener);
1818
};
19-
}, [ eventName, document ]);
19+
}, [ eventName, window ]);
2020
};

0 commit comments

Comments
 (0)