@paroicms/front-media-gallery
Version:
Basic media gallery react component for Paroi CMS.
105 lines (99 loc) • 4.88 kB
JSX
import { useWrapAsync } from "@paroicms/front-app-log";
import { ActionButton, Spinner, openModalDialog, useSizeFormatter, } from "@paroicms/internal-front-lib";
import { Button } from "primereact/button";
import { Image as PRImage } from "primereact/image";
import { InputText } from "primereact/inputtext";
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import makeConfirmDeleteDialog from "./ConfirmDeleteDialog";
export default function makeViewMediaPropertiesDialog({ closeDialog, parameter: { getMediaProperties, updateCaption, onDelete, mediaUid, contentLanguage }, }) {
const [mediaProperties, setMediaProperties] = useState();
const captionRef = useRef();
const [caption, setCaption] = useState("");
const wrapAsync = useWrapAsync();
const sizeFormatter = useSizeFormatter();
const { t } = useTranslation();
useEffect(wrapAsync(async () => {
const data = await getMediaProperties(mediaUid);
setMediaProperties(data);
}), []);
useEffect(() => {
if (!mediaProperties || !contentLanguage)
return;
if (!mediaProperties.attachedData?.caption) {
captionRef.current = { [contentLanguage]: "" };
return;
}
const parsedCaption = JSON.parse(mediaProperties.attachedData.caption);
captionRef.current = parsedCaption;
setCaption(captionRef.current[contentLanguage]);
}, [mediaProperties, contentLanguage]);
const isMediaImage = (media) => {
return media.mediaType.startsWith("image");
};
const formatImageSize = (media) => {
const image = media;
return `${image.originalWidth} × ${image.originalHeight}`;
};
const deleteMedia = async () => {
if (!onDelete)
return;
const response = await openModalDialog(makeConfirmDeleteDialog, {
onDelete,
});
if (response?.deletionCompleted)
closeDialog();
};
const updateMediaCaption = async () => {
if (!caption || !contentLanguage || !updateCaption)
return;
captionRef.current = { ...captionRef.current, [contentLanguage]: caption };
await updateCaption(mediaUid, JSON.stringify(captionRef.current));
closeDialog();
};
if (!mediaProperties)
return { header: <></>, content: <Spinner />, footer: <></> };
const header = isMediaImage(mediaProperties)
? t("frontMediaGallery.mediaProperties.imageProperties")
: t("frontMediaGallery.mediaProperties.fileProperties");
const content = (<div className="MediaProperties">
<div className="flex justify-content-between gap-5 mt-2">
{isMediaImage(mediaProperties) && (<PRImage src={mediaProperties.url} alt="media" width="200" className="mb-5" zoomSrc={mediaProperties.url} preview/>)}
<div>
<div className="row">
<div className="label">
{isMediaImage(mediaProperties)
? t("frontMediaGallery.mediaProperties.imageStored")
: t("frontMediaGallery.mediaProperties.fileStored")}
</div>
<div>
{<span className="info">{sizeFormatter(mediaProperties.weightB)},</span>}
{isMediaImage(mediaProperties) && (<span className="info">{formatImageSize(mediaProperties)},</span>)}
<span className="info">
{t("frontMediaGallery.mediaProperties.format")} {mediaProperties.mediaType}
</span>
</div>
<a href={mediaProperties.url} target="_blank" rel="noreferrer" className="p-button no-underline">
<i className="pi pi-download"/>
</a>
</div>
<div className="row">
<div className="label">{t("frontMediaGallery.mediaProperties.originalFileName")}</div>
<div>{mediaProperties.originalName}</div>
</div>
</div>
</div>
{isMediaImage(mediaProperties) && (<div className="row">
<div className="label">{t("frontMediaGallery.mediaProperties.caption")}</div>
<InputText className="MediaProperties-captionField" value={caption} onChange={(e) => setCaption(e.target.value)}/>
</div>)}
</div>);
const footer = (<>
{onDelete && (<ActionButton outlined severity="danger" label={t("frontMediaGallery.delete")} action={deleteMedia}/>)}
<Button severity={!isMediaImage(mediaProperties) ? undefined : "secondary"} label={isMediaImage(mediaProperties)
? t("frontMediaGallery.mediaProperties.cancel")
: t("frontMediaGallery.mediaProperties.close")} onClick={() => closeDialog()}/>
{updateCaption && isMediaImage(mediaProperties) && (<ActionButton label={t("frontMediaGallery.save")} action={updateMediaCaption}/>)}
</>);
return { header, content, footer };
}