import { useRef } from 'react' import { gql, useMutation } from '@apollo/client' import { UPLOAD_TYPES_ALLOW } from '../lib/constants' export default function Upload ({ as: Component, onSelect, onStarted, onError, onSuccess }) { const [getSignedPOST] = useMutation( gql` mutation getSignedPOST($type: String!, $size: Int!, $width: Int!, $height: Int!) { getSignedPOST(type: $type, size: $size, width: $width, height: $height) { url fields } }`) const ref = useRef() const upload = file => { onStarted && onStarted() const img = new Image() img.src = window.URL.createObjectURL(file) img.onload = async () => { let data try { ({ data } = await getSignedPOST({ variables: { type: file.type, size: file.size, width: img.width, height: img.height } })) } catch (e) { onError && onError(e.toString()) return } const form = new FormData() Object.keys(data.getSignedPOST.fields).forEach(key => form.append(key, data.getSignedPOST.fields[key])) form.append('Content-Type', file.type) form.append('Cache-Control', 'max-age=31536000') form.append('acl', 'public-read') form.append('file', file) const res = await fetch(data.getSignedPOST.url, { method: 'POST', body: form }) if (!res.ok) { onError && onError(res.statusText) return } onSuccess && onSuccess(data.getSignedPOST.fields.key) } } return ( <> { if (e.target.files.length === 0) { return } const file = e.target.files[0] if (UPLOAD_TYPES_ALLOW.indexOf(file.type) === -1) { onError && onError(`image must be ${UPLOAD_TYPES_ALLOW.map(t => t.replace('image/', '')).join(', ')}`) return } if (onSelect) { onSelect(file, upload) } else { upload(file) } e.target.value = null }} /> ref.current?.click()} /> ) }