import { getMediaDetails } from '@assist/lib/media'; import { addCustomMediaViewsCss, removeCustomMediaViewsCss, } from '@shared/lib/media-views'; import apiFetch from '@wordpress/api-fetch'; import { isBlobURL } from '@wordpress/blob'; import { Button, DropZone, ResponsiveWrapper, Spinner, } from '@wordpress/components'; import { store as coreStore } from '@wordpress/core-data'; import { useSelect } from '@wordpress/data'; import { useEffect, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { MediaUpload, uploadMedia } from '@wordpress/media-utils'; import classnames from 'classnames'; const allowedTypes = ['image']; const getSettings = (signal) => { return apiFetch({ path: '/wp/v2/settings', signal, }); }; export const ImageUploader = ({ type, onSave, onCancel, onSelect, title, actionLabel, }) => { const [isLoading, setIsLoading] = useState(false); const [isSaving, setIsSaving] = useState(false); const [savedImageId, setSavedImageId] = useState(null); const [selectedImageId, setSelectedImageId] = useState(null); const imageId = selectedImageId || savedImageId; const media = useSelect( (select) => { return select(coreStore).getEntityRecord( 'postType', 'attachment', imageId, ); }, [imageId], ); const { mediaWidth, mediaHeight, mediaSourceUrl } = getMediaDetails(media); useEffect(() => { addCustomMediaViewsCss(); return () => removeCustomMediaViewsCss(); }, []); useEffect(() => { const controller = new AbortController(); setIsLoading(true); getSettings(controller.signal) .then((settings) => { if (settings[type]) setSavedImageId(Number(settings[type])); }) .finally(() => setIsLoading(false)); return () => controller.abort(); }, [type]); const handleOnSelectImage = (image) => { if (image.id === imageId) { return; } setSelectedImageId(image.id); onSelect?.(image); }; const onRemoveImage = () => { setSelectedImageId(null); setSavedImageId(null); onCancel(); }; const handleOnSave = async () => { setIsSaving(true); try { await onSave?.({ imageId: selectedImageId }); } catch (error) { console.error(error); } finally { setIsSaving(false); } }; const onDropFiles = (filesList) => { uploadMedia({ allowedTypes, filesList, onFileChange([image]) { if (isBlobURL(image?.url)) { setIsLoading(true); return; } handleOnSelectImage(image); setIsLoading(false); }, onError(message) { console.error({ message }); }, }); }; return (
(
)} />
{!selectedImageId && ( ( )} /> )} {selectedImageId && ( )}
); }; const MediaUploadCheck = ({ fallback = null, children }) => { const { checkingPermissions, hasUploadPermissions } = useSelect((select) => { const core = select('core'); return { hasUploadPermissions: core.canUser('read', 'media'), checkingPermissions: !core.hasFinishedResolution('canUser', [ 'read', 'media', ]), }; }); return ( <> {checkingPermissions && } {!checkingPermissions && hasUploadPermissions ? children : fallback} ); };