@paroicms/bo-media-gallery
Version:
Basic media gallery react component for Paroi CMS.
70 lines (69 loc) • 2.7 kB
JavaScript
import { useAppLogger } from "@paroicms/bo-app-log";
import { useShowToast } from "@paroicms/internal-bo-lib";
import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
let uploadIdSeq = 0;
export function useUploadHandler(props) {
const { t } = useTranslation();
const logger = useAppLogger();
const [uploadingFiles, setUploadingFiles] = useState([]);
const [medias, setMedias] = useState([]);
const propsRef = useRef(props);
const showToast = useShowToast();
useEffect(() => {
propsRef.current = props; // if one of the props changes, update the ref
}, Object.values(props));
const refreshMediasRef = useRef(async () => {
const { mediaHandle, getMedias, limitManager } = propsRef.current;
const medias = await getMedias(mediaHandle);
setMedias(medias);
limitManager?.updateMediaCount({ handle: mediaHandle, count: medias.length });
});
const uploadFilesRef = useRef((fileList) => {
const { mediaHandle, httpUploadMedia, acceptFilter } = propsRef.current;
const list = (acceptFilter ? fileList.filter(acceptFilter) : fileList).map(uploadFileItem);
const promises = list.map((f) => f.promise);
setUploadingFiles((oldFiles) => [
...oldFiles,
...list.map((f) => ({
uploadId: f.uploadId,
file: f.file,
handler: f.uploadingHandler,
})),
]);
return Promise.all(promises);
function uploadFileItem(file) {
const uploadId = ++uploadIdSeq;
const uploadingHandler = httpUploadMedia({ file, handle: mediaHandle });
const promise = uploadingHandler.promise
.catch(() => {
showToast(t("DocumentEditPanel.uploadError", { fileName: file.name }), {
severity: "error",
});
})
.finally(() => {
setUploadingFiles((oldFiles) => oldFiles.filter((f) => f.uploadId !== uploadId));
})
.catch((error) => {
logger.error("[media-gallery]", error);
});
const fileState = {
uploadId,
file,
uploadingHandler,
progress: 0,
promise,
};
uploadingHandler.onProgress = (progress) => {
fileState.progress = progress;
};
return fileState;
}
});
return {
uploadFiles: uploadFilesRef.current,
uploadingFiles,
medias,
refreshMedias: refreshMediasRef.current,
};
}