@paroicms/bo-media-gallery
Version:
Basic media gallery react component for Paroi CMS.
69 lines (66 loc) • 3.23 kB
JSX
import { useAsyncEffect } from "@paroi/use-async-effect";
import { showToast } from "@paroicms/internal-bo-lib";
import { classNames } from "primereact/utils";
import { useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { FileDrop } from "./FileDrop.jsx";
import GalleryItem from "./GalleryItem/GalleryItem.jsx";
import { ImagePicker } from "./ImagePicker/ImagePicker.jsx";
import UploadPlaceholder from "./UploadPlaceholder/UploadPlaceholder.jsx";
import { useUploadHandler } from "./helpers/upload-handler.js";
export function SingleMedia({ mediaHandle, getMedia, getMediaByUid, httpUploadMedia, deleteMedia, accept, acceptFilter, label, limitManager, isMobile, updateMediaAttachedData, contentLanguage, }) {
const { t } = useTranslation();
const [initialized, setInitialized] = useState(false);
const imagePickerRef = useRef(undefined);
useAsyncEffect(async () => {
setInitialized(false);
await refreshMedias();
setInitialized(true);
}, [mediaHandle]);
const { uploadFiles, uploadingFiles, medias, refreshMedias } = useUploadHandler({
mediaHandle,
httpUploadMedia,
acceptFilter,
limitManager,
getMedias: async () => {
const media = await getMedia(mediaHandle);
return media ? [media] : [];
},
});
const updateMediaCaption = async (mediaUid, caption) => {
await updateMediaAttachedData(mediaUid, { caption });
await refreshMedias();
};
const uploadSelectedFile = async (files) => {
await uploadFiles([files[0]]);
await refreshMedias();
};
const hasMedia = () => medias.length > 0;
const hasUploads = () => uploadingFiles.length > 0;
const handleReplace = () => {
imagePickerRef.current?.open();
};
const handleDeleteMedia = async () => {
if (!hasMedia() || !deleteMedia)
return;
await deleteMedia(mediaHandle);
await refreshMedias();
limitManager?.updateMediaCount({ handle: mediaHandle, count: 0 });
};
function onDropFiles(files) {
if (limitManager?.remainingMediaPlaces === 0) {
showToast(t("frontMediaGallery.mediaLimitReached"), { severity: "warn" });
return;
}
uploadSelectedFile([...files]);
}
return (<FileDrop onDropFiles={onDropFiles}>
<div className="SingleMedia w-8rem">
<ImagePicker className={classNames("single", {
hidden: (initialized && hasMedia()) || hasUploads(),
})} ref={imagePickerRef} label={label ?? t("frontMediaGallery.chooseAFile")} accept={accept} multiple={false} onFilesSelect={uploadSelectedFile} disabled={limitManager?.remainingMediaPlaces === 0}/>
{hasUploads() && (<UploadPlaceholder localMedia={uploadingFiles[0].file} handler={uploadingFiles[0].handler}/>)}
{!hasUploads() && hasMedia() && (<GalleryItem key={medias[0].uid} media={medias[0]} attachedData={medias[0].attachedData} onReplace={handleReplace} onDelete={handleDeleteMedia} isMobile={isMobile} getMediaProperties={getMediaByUid} updateCaption={updateMediaCaption} contentLanguage={contentLanguage}/>)}
</div>
</FileDrop>);
}