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

View File

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

View File

@ -1,5 +1,5 @@
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 { useShowModal } from './modal'
import { useMe } from './me'
@ -137,8 +137,7 @@ export default function ZoomableImage ({ src, srcSet, ...props }) {
return <ImageOriginal src={originalUrl} onClick={handleClick} {...props} />
}
export function ImageUpload ({ children, className, onSelect, onSuccess, onError }) {
const ref = useRef()
export const ImageUpload = forwardRef(({ children, className, onSelect, onSuccess, onError }, ref) => {
const toaster = useToast()
const [getSignedPOST] = useMutation(
@ -228,4 +227,4 @@ export function ImageUpload ({ children, className, onSelect, onSuccess, onError
</div>
</>
)
}
})