Fix the unholy hell that is drag events
This commit is contained in:
parent
56475d89bb
commit
f561089cad
3 changed files with 53 additions and 50 deletions
|
@ -20,7 +20,7 @@ export interface ModalProps extends RequiredModalProps {
|
||||||
showSpinnerOverlay?: boolean;
|
showSpinnerOverlay?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ModalMask = styled.div`
|
export const ModalMask = styled.div`
|
||||||
${tw`fixed z-50 overflow-auto flex w-full inset-0`};
|
${tw`fixed z-50 overflow-auto flex w-full inset-0`};
|
||||||
background: rgba(0, 0, 0, 0.70);
|
background: rgba(0, 0, 0, 0.70);
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -5,39 +5,41 @@ import tw from 'twin.macro';
|
||||||
import Button from '@/components/elements/Button';
|
import Button from '@/components/elements/Button';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import styled from 'styled-components/macro';
|
import styled from 'styled-components/macro';
|
||||||
|
import { ModalMask } from '@/components/elements/Modal';
|
||||||
|
import Fade from '@/components/elements/Fade';
|
||||||
|
import useEventListener from '@/plugins/useEventListener';
|
||||||
|
|
||||||
const ModalMask = styled.div`
|
const InnerContainer = styled.div`
|
||||||
${tw`fixed z-50 overflow-auto flex w-full inset-0`};
|
max-width: 600px;
|
||||||
background: rgba(0, 0, 0, 0.70);
|
${tw`bg-black w-full border-4 border-primary-500 border-dashed rounded p-10 mx-10`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const { uuid } = useServer();
|
const { uuid } = useServer();
|
||||||
const [ visible, setVisible ] = useState(false);
|
const [ visible, setVisible ] = useState(false);
|
||||||
|
|
||||||
const handleEscapeEvent = () => {
|
useEventListener('dragenter', e => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setVisible(true);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
useEventListener('dragexit', e => {
|
||||||
|
e.stopPropagation();
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
};
|
}, true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.addEventListener('keydown', handleEscapeEvent);
|
if (!visible) return;
|
||||||
|
|
||||||
return () => window.removeEventListener('keydown', handleEscapeEvent);
|
const hide = () => setVisible(false);
|
||||||
|
|
||||||
|
window.addEventListener('keydown', hide);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('keydown', hide);
|
||||||
|
};
|
||||||
}, [ visible ]);
|
}, [ visible ]);
|
||||||
|
|
||||||
const onDragOver = (e: any) => {
|
const onFileDrop = (e: React.DragEvent<HTMLDivElement>) => {
|
||||||
e.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDragEnter = (e: any) => {
|
|
||||||
e.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDragLeave = (e: any) => {
|
|
||||||
e.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFileDrop = (e: any) => {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (e.dataTransfer === undefined || e.dataTransfer === null) {
|
if (e.dataTransfer === undefined || e.dataTransfer === null) {
|
||||||
|
@ -55,12 +57,10 @@ export default () => {
|
||||||
formData.append('files', files[i]);
|
formData.append('files', files[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('getFileUploadUrl');
|
|
||||||
getFileUploadUrl(uuid)
|
getFileUploadUrl(uuid)
|
||||||
.then(url => {
|
.then(url => {
|
||||||
console.log(url);
|
console.log(url);
|
||||||
|
|
||||||
// `${url}&directory=`
|
|
||||||
axios.post(url, formData, {
|
axios.post(url, formData, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data',
|
'Content-Type': 'multipart/form-data',
|
||||||
|
@ -81,20 +81,26 @@ export default () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{
|
<Fade
|
||||||
visible ?
|
appear
|
||||||
<ModalMask>
|
in={visible}
|
||||||
<div css={tw`w-full flex items-center justify-center`} onDragOver={onDragOver} onDragEnter={onDragEnter} onDragLeave={onDragLeave} onDrop={onFileDrop}>
|
timeout={75}
|
||||||
<div css={tw`w-full md:w-3/4 lg:w-3/5 xl:w-2/5 flex flex-col items-center border-2 border-dashed border-neutral-400 rounded py-8 px-12 mx-8 md:mx-0`}>
|
key={'upload_modal_mask'}
|
||||||
<img src={'/assets/svgs/file_upload.svg'} css={tw`h-auto w-full select-none`}/>
|
unmountOnExit
|
||||||
<p css={tw`text-lg text-neutral-200 font-normal mt-8`}>Drag and drop files to upload</p>
|
>
|
||||||
</div>
|
<ModalMask
|
||||||
</div>
|
onClick={() => setVisible(false)}
|
||||||
</ModalMask>
|
onDrop={onFileDrop}
|
||||||
:
|
>
|
||||||
null
|
<div css={tw`w-full flex items-center justify-center`} style={{ pointerEvents: 'none' }}>
|
||||||
}
|
<InnerContainer>
|
||||||
|
<p css={tw`text-lg text-neutral-200 text-center`}>
|
||||||
|
Drag and drop files to upload.
|
||||||
|
</p>
|
||||||
|
</InnerContainer>
|
||||||
|
</div>
|
||||||
|
</ModalMask>
|
||||||
|
</Fade>
|
||||||
<Button css={tw`mr-2`} onClick={() => setVisible(true)}>
|
<Button css={tw`mr-2`} onClick={() => setVisible(true)}>
|
||||||
Upload
|
Upload
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
export default (eventName: string, handler: (e: Event | CustomEvent | UIEvent | any) => void, element: any = window) => {
|
export default (eventName: string, handler: (e: Event | CustomEvent | UIEvent | any) => void, options?: boolean | EventListenerOptions) => {
|
||||||
const savedHandler = useRef<any>(null);
|
const savedHandler = useRef<any>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
savedHandler.current = handler;
|
savedHandler.current = handler;
|
||||||
}, [ handler ]);
|
}, [ handler ]);
|
||||||
|
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() => {
|
const isSupported = document && document.addEventListener;
|
||||||
const isSupported = element && element.addEventListener;
|
if (!isSupported) return;
|
||||||
if (!isSupported) return;
|
|
||||||
|
|
||||||
const eventListener = (event: any) => savedHandler.current(event);
|
const eventListener = (event: any) => savedHandler.current(event);
|
||||||
element.addEventListener(eventName, eventListener);
|
document.addEventListener(eventName, eventListener, options);
|
||||||
return () => {
|
return () => {
|
||||||
element.removeEventListener(eventName, eventListener);
|
document.removeEventListener(eventName, eventListener);
|
||||||
};
|
};
|
||||||
},
|
}, [ eventName, document ]);
|
||||||
[ eventName, element ],
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue