import { useState, useEffect } from '@wordpress/element';
|
import { MediaUpload, MediaUploadCheck } from '@wordpress/media-utils';
|
import { Button } from '@wordpress/components';
|
import apiFetch from '@wordpress/api-fetch';
|
|
const SUBTYPE_MAP = { image: 'image', video: 'video', document: 'application', all: '' };
|
|
const Thumbnail = ({ id, onRemove }) => {
|
const [media, setMedia] = useState(null);
|
|
useEffect(() => {
|
let cancelled = false;
|
if (!id) return;
|
apiFetch({ path: `/wp/v2/media/${id}` })
|
.then((data) => !cancelled && setMedia(data))
|
.catch(() => {});
|
return () => { cancelled = true; };
|
}, [id]);
|
|
const thumb = media?.media_details?.sizes?.thumbnail?.source_url || media?.source_url;
|
const isImage = media?.media_type === 'image';
|
|
return (
|
<div className="jvb-upload-thumb">
|
{isImage && thumb ? (
|
<img src={thumb} alt={media?.alt_text || ''} />
|
) : (
|
<div className="jvb-upload-thumb-placeholder">
|
{media?.title?.rendered || `#${id}`}
|
</div>
|
)}
|
<Button variant="link" isDestructive onClick={() => onRemove(id)}>
|
Remove
|
</Button>
|
</div>
|
);
|
};
|
|
const UploadField = ({ field, value, onChange }) => {
|
const multiple = field.multiple || field.type === 'gallery';
|
const ids = multiple ? (Array.isArray(value) ? value : []) : value;
|
const allowedTypes = SUBTYPE_MAP[field.subtype] ? [SUBTYPE_MAP[field.subtype]] : undefined;
|
|
const onSelect = (media) => onChange(multiple ? media.map((m) => m.id) : media.id);
|
|
const onRemove = (id) => {
|
onChange(multiple ? ids.filter((existing) => existing !== id) : 0);
|
};
|
|
return (
|
<div className="jvb-upload-field">
|
<p className="jvb-field-label">{field.label}</p>
|
|
<div className={multiple ? 'jvb-upload-grid' : 'jvb-upload-single'}>
|
{multiple
|
? ids.map((id) => <Thumbnail key={id} id={id} onRemove={onRemove} />)
|
: !!ids && <Thumbnail id={ids} onRemove={onRemove} />}
|
</div>
|
|
<MediaUploadCheck>
|
<MediaUpload
|
onSelect={onSelect}
|
allowedTypes={allowedTypes}
|
multiple={multiple}
|
value={multiple ? ids : ids || undefined}
|
render={({ open }) => (
|
<Button variant="secondary" onClick={open}>
|
{(multiple ? ids.length : ids) ? 'Change' : 'Select'} {field.label}
|
</Button>
|
)}
|
/>
|
</MediaUploadCheck>
|
</div>
|
);
|
};
|
|
export default UploadField;
|