Use Drag and Drop API for image upload
This commit is contained in:
parent
e9b3ac43dc
commit
d6f6cd8b0b
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user