Use Drag and Drop API for image upload

This commit is contained in:
ekzyis 2023-10-26 00:30:14 +02:00
parent e9b3ac43dc
commit d6f6cd8b0b
3 changed files with 28 additions and 4 deletions

View File

@ -100,6 +100,7 @@ export function MarkdownInput ({ label, topLevel, groupClassName, onChange, onKe
const [, meta, helpers] = useField(props) const [, meta, helpers] = useField(props)
const [selectionRange, setSelectionRange] = useState({ start: 0, end: 0 }) const [selectionRange, setSelectionRange] = useState({ start: 0, end: 0 })
innerRef = innerRef || useRef(null) innerRef = innerRef || useRef(null)
const imageUploadRef = useRef(null)
const previousTab = useRef(tab) const previousTab = useRef(tab)
const formik = useFormikContext() const formik = useFormikContext()
const toaster = useToast() const toaster = useToast()
@ -228,6 +229,21 @@ export function MarkdownInput ({ label, topLevel, groupClassName, onChange, onKe
} }
}, [innerRef, helpers?.setValue, setSelectionRange, onKeyDown]) }, [innerRef, helpers?.setValue, setSelectionRange, onKeyDown])
const onDrop = useCallback((event) => {
event.preventDefault()
const changeEvent = new Event('change', { bubbles: true })
imageUploadRef.current.files = event.dataTransfer.files
imageUploadRef.current.dispatchEvent(changeEvent)
}, [imageUploadRef])
const [dragStyle, setDragStyle] = useState(null)
const onDragEnter = useCallback((e) => {
setDragStyle('over')
}, [setDragStyle])
const onDragLeave = useCallback((e) => {
setDragStyle(null)
}, [setDragStyle])
return ( return (
<FormGroup label={label} className={groupClassName}> <FormGroup label={label} className={groupClassName}>
<div className={`${styles.markdownInput} ${tab === 'write' ? styles.noTopLeftRadius : ''}`}> <div className={`${styles.markdownInput} ${tab === 'write' ? styles.noTopLeftRadius : ''}`}>
@ -240,6 +256,7 @@ export function MarkdownInput ({ label, topLevel, groupClassName, onChange, onKe
</Nav.Item> </Nav.Item>
<span className='ms-auto text-muted d-flex align-items-center'> <span className='ms-auto text-muted d-flex align-items-center'>
<ImageUpload <ImageUpload
ref={imageUploadRef}
className='d-flex align-items-center me-1' className='d-flex align-items-center me-1'
onSelect={file => { onSelect={file => {
let text = innerRef.current.value let text = innerRef.current.value
@ -287,6 +304,10 @@ export function MarkdownInput ({ label, topLevel, groupClassName, onChange, onKe
updateImageFees({ variables: { s3Keys } }) updateImageFees({ variables: { s3Keys } })
setTimeout(resetSuggestions, 100) setTimeout(resetSuggestions, 100)
}} }}
onDragEnter={onDragEnter}
onDragLeave={onDragLeave}
onDrop={onDrop}
className={dragStyle === 'over' ? styles.dragOver : ''}
/>)} />)}
</UserSuggest> </UserSuggest>
</div> </div>

View File

@ -19,6 +19,10 @@
height: auto; height: auto;
} }
.dragOver {
box-shadow: 0 0 10px var(--bs-info);
}
.appendButton { .appendButton {
border-left: 0 !important; border-left: 0 !important;
border-top-left-radius: 0; border-top-left-radius: 0;

View File

@ -1,5 +1,5 @@
import styles from './text.module.css' import styles from './text.module.css'
import { Fragment, useState, useEffect, useMemo, useCallback, useRef } from 'react' import { Fragment, useState, useEffect, useMemo, useCallback, forwardRef } from 'react'
import { IMGPROXY_URL_REGEXP } from '../lib/url' import { IMGPROXY_URL_REGEXP } from '../lib/url'
import { useShowModal } from './modal' import { useShowModal } from './modal'
import { useMe } from './me' import { useMe } from './me'
@ -137,8 +137,7 @@ export default function ZoomableImage ({ src, srcSet, ...props }) {
return <ImageOriginal src={originalUrl} onClick={handleClick} {...props} /> return <ImageOriginal src={originalUrl} onClick={handleClick} {...props} />
} }
export function ImageUpload ({ children, className, onSelect, onSuccess, onError }) { export const ImageUpload = forwardRef(({ children, className, onSelect, onSuccess, onError }, ref) => {
const ref = useRef()
const toaster = useToast() const toaster = useToast()
const [getSignedPOST] = useMutation( const [getSignedPOST] = useMutation(
@ -228,4 +227,4 @@ export function ImageUpload ({ children, className, onSelect, onSuccess, onError
</div> </div>
</> </>
) )
} })