import { useState } from 'react' import { toast } from '@redwoodjs/web/toast' import Popover from '@material-ui/core/Popover' import Svg from 'src/components/Svg/Svg' import Button from 'src/components/Button/Button' import { useIdeContext } from 'src/helpers/hooks/useIdeContext' import { canvasToBlob, blobTo64 } from 'src/helpers/canvasToBlob' import { useUpdateProject } from 'src/helpers/hooks/useUpdateProject' import { useUpdateSocialCard, makeSocialPublicId, } from 'src/helpers/hooks/useUpdateSocialCard' import { uploadToCloudinary, serverVerifiedImageUpload, } from 'src/helpers/cloudinary' import SocialCardCell from 'src/components/SocialCardCell/SocialCardCell' import { toJpeg } from 'html-to-image' import { useAuth } from '@redwoodjs/auth' const anchorOrigin = { vertical: 'bottom', horizontal: 'center', } const transformOrigin = { vertical: 'top', horizontal: 'center', } const CaptureButton = ({ canEdit, TheButton, shouldUpdateImage, projectTitle, userName, }) => { const [captureState, setCaptureState] = useState({}) const [anchorEl, setAnchorEl] = useState(null) const [whichPopup, setWhichPopup] = useState(null) const { state, project } = useIdeContext() const ref = React.useRef(null) const { updateProject } = useUpdateProject({ onCompleted: () => toast.success('Image updated'), }) const { updateSocialCard } = useUpdateSocialCard({}) const { getToken } = useAuth() const getSocialBlob = async (): Promise => { const tokenPromise = getToken() const blob = await toJpeg(ref.current, { cacheBust: true, quality: 0.75 }) const token = await tokenPromise const { publicId } = await serverVerifiedImageUpload( blob, project?.id, token, makeSocialPublicId(userName, projectTitle) ) return publicId } const onCapture = async () => { const threeInstance = state.threeInstance const isOpenScadImage = state?.objectData?.type === 'png' let imgBlob let image64 if (!isOpenScadImage) { imgBlob = canvasToBlob(threeInstance, { width: 500, height: 375 }) image64 = blobTo64( await canvasToBlob(threeInstance, { width: 500, height: 522 }) ) } else { imgBlob = state.objectData.data image64 = blobTo64(state.objectData.data) } const config = { image: await imgBlob, currImage: project?.mainImage, imageObjectURL: window.URL.createObjectURL(await imgBlob), callback: uploadAndUpdateImage, cloudinaryImgURL: '', updated: false, image64: await image64, } setCaptureState(config) async function uploadAndUpdateImage() { const [cloudinaryImgURL, socialCloudinaryURL] = await Promise.all([ uploadToCloudinary(config.image), getSocialBlob(), ]) updateSocialCard({ variables: { projectId: project?.id, url: socialCloudinaryURL, }, }) // Save the screenshot as the mainImage updateProject({ variables: { id: project?.id, input: { mainImage: cloudinaryImgURL.public_id, }, }, }) return cloudinaryImgURL } // if there isn't a screenshot saved yet, just go ahead and save right away if (shouldUpdateImage) { config.cloudinaryImgURL = (await uploadAndUpdateImage()).public_id config.updated = true setCaptureState(config) } } const handleDownload = (url) => { const aTag = document.createElement('a') document.body.appendChild(aTag) aTag.href = url aTag.style.display = 'none' aTag.download = `${project?.title}-${new Date().toISOString()}.jpg` aTag.click() document.body.removeChild(aTag) } const handleClick = ({ event, whichPopup }) => { setAnchorEl(event.currentTarget) setWhichPopup(whichPopup) } const handleClose = () => { setAnchorEl(null) setWhichPopup(null) } return (
{canEdit && (
{ handleClick({ event, whichPopup: 'capture' }) onCapture() }} />
{!captureState ? ( 'Loading...' ) : (
{captureState.currImage && !captureState.updated ? ( ) : (
{' '} Part Image Updated
)}
)}
)}
) } export default CaptureButton