UNPKG

@paroicms/bo-media-gallery

Version:

Basic media gallery react component for Paroi CMS.

70 lines (67 loc) 3.27 kB
import { useAsyncEffect } from "@paroi/use-async-effect"; import { useShowToast } 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); const showToast = useShowToast(); 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>); }