UNPKG

@chayns-components/gallery

Version:

A set of beautiful React components for developing your own applications with chayns.

319 lines (307 loc) • 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _core = require("@chayns-components/core"); var _chaynsApi = require("chayns-api"); var _react = _interopRequireWildcard(require("react")); var _uuid = require("uuid"); var _gallery = require("../types/gallery"); var _file = require("../utils/file"); var _AddFile = _interopRequireDefault(require("./add-file/AddFile")); var _GalleryItem = _interopRequireDefault(require("./gallery-item/GalleryItem")); var _Gallery = require("./Gallery.styles"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const Gallery = ({ allowDragAndDrop = false, doubleFileDialogMessage = 'Diese Datei ist bereits vorhanden', isEditMode = false, fileMinWidth = 100, files, maxFiles, onAdd, onFileCountChange, onRemove, viewMode = _gallery.GalleryViewMode.GRID }) => { const [fileItems, setFileItems] = (0, _react.useState)([]); /** * This function adds a previewUrl to fileItems */ const handlePreviewUrlCallback = (previewUrl, file) => { setFileItems(prevState => prevState.map(prevFile => { if (prevFile.id === file.id) { return { ...prevFile, previewUrl }; } return prevFile; })); }; const callDuplicateFileDialog = (0, _react.useCallback)(() => { (0, _chaynsApi.createDialog)({ type: _chaynsApi.DialogType.ALERT, text: doubleFileDialogMessage }); }, [doubleFileDialogMessage]); /** * This function adds uploaded files to fileItems */ const handleUploadFileCallback = (0, _react.useCallback)((file, uploadedFile) => { setFileItems(prevState => { const updatedState = prevState.map(prevFile => { var _prevFile$uploadedFil; if (((_prevFile$uploadedFil = prevFile.uploadedFile) === null || _prevFile$uploadedFil === void 0 ? void 0 : _prevFile$uploadedFil.url) === uploadedFile.url) { callDuplicateFileDialog(); return undefined; } if (prevFile.id === file.id) { if (typeof onAdd === 'function') { const prevElement = prevState.find(({ uploadedFile: newUploadedFile }) => (newUploadedFile === null || newUploadedFile === void 0 ? void 0 : newUploadedFile.url) === (uploadedFile === null || uploadedFile === void 0 ? void 0 : uploadedFile.url)); if (!prevElement) { onAdd({ file: uploadedFile, id: file.id }); } } return { ...prevFile, uploadedFile, state: 'uploaded' }; } return prevFile; }); const tmp = []; updatedState.forEach(updatedFile => { if (updatedFile !== undefined) { tmp.push(updatedFile); } }); return tmp ?? []; }); }, [callDuplicateFileDialog, onAdd]); /** * Returns the current count to check if all files are uploaded */ (0, _react.useEffect)(() => { if (typeof onFileCountChange === 'function') { onFileCountChange(fileItems.length); } }, [fileItems.length, onFileCountChange]); /** * Prepares files for previewUrl and upload */ (0, _react.useEffect)(() => { const filesToGeneratePreview = fileItems.filter(file => file.file && !file.previewUrl && (file.state === 'none' || !file.state)); const filesToUpload = fileItems.filter(file => !file.uploadedFile && file.state !== 'uploading'); filesToGeneratePreview.forEach(file => { if (!file.file) { return; } if (file.file.type.includes('video/')) { (0, _file.generateVideoThumbnail)({ file: file.file, callback: previewUrl => handlePreviewUrlCallback(previewUrl, file) }); return; } (0, _file.generatePreviewUrl)({ file: file.file, callback: previewUrl => handlePreviewUrlCallback(previewUrl, file) }); }); filesToUpload.forEach(file => { setFileItems(prevState => prevState.map(prevFile => { if (prevFile.id === file.id) { return { ...prevFile, state: 'uploading' }; } return prevFile; })); void (0, _core.uploadFile)({ fileToUpload: file, callback: UploadedFile => handleUploadFileCallback(file, UploadedFile) }); }); }, [fileItems, handleUploadFileCallback]); /** * This function formats and adds files to fileItems */ const handleAddFiles = (0, _react.useCallback)(filesToAdd => { const newFileItems = []; filesToAdd.forEach(file => { if (file && !(0, _file.filterDuplicateFile)({ files: fileItems, newFile: file })) { newFileItems.push({ id: (0, _uuid.v4)(), file, state: 'none' }); } }); let tmp = newFileItems; if (maxFiles) { tmp = newFileItems.slice(0, maxFiles - (fileItems.length + filesToAdd.length - 1)); } setFileItems(prevState => [...prevState, ...tmp]); }, [fileItems, maxFiles]); /** * This function adds external files to fileItems */ (0, _react.useEffect)(() => { if (files) { const newFileItems = []; files.forEach(file => { newFileItems.push({ id: file.id ?? (0, _uuid.v4)(), uploadedFile: file.file, file: undefined, state: 'uploaded', previewUrl: undefined }); }); setFileItems(prevState => { const updatedItems = prevState.map(prevItem => { const newItem = newFileItems.find(item => item.uploadedFile && item.uploadedFile.url === (prevItem.uploadedFile && prevItem.uploadedFile.url)); return newItem || prevItem; }); return updatedItems.concat(newFileItems.filter(newItem => !prevState.some(prevItem => prevItem.uploadedFile && newItem.uploadedFile && prevItem.uploadedFile.url === newItem.uploadedFile.url))); }); } }, [files]); /** * This function deletes a selected file from the file list */ const handleDeleteFile = (0, _react.useCallback)(id => { let fileToDelete; const filteredFiles = fileItems.filter(file => { const fileId = file.id; if (fileId === id && file.uploadedFile) { fileToDelete = { file: file.uploadedFile, id }; } return fileId !== id; }); setFileItems(filteredFiles); if (!fileToDelete || typeof onRemove !== 'function') { return; } onRemove(fileToDelete); }, [fileItems, onRemove]); /** * This function handles the drag and drop */ const handleDrop = (0, _react.useCallback)(e => { if (!allowDragAndDrop) { return; } e.preventDefault(); const draggedFiles = Array.from(e.dataTransfer.files); handleAddFiles(draggedFiles); }, [allowDragAndDrop, handleAddFiles]); /** * Opens the files in a slideShow */ const openFiles = (0, _react.useCallback)(file => { const startIndex = fileItems.findIndex(item => item.id === file.id); const items = fileItems.map(item => { var _item$uploadedFile; return { url: ((_item$uploadedFile = item.uploadedFile) === null || _item$uploadedFile === void 0 ? void 0 : _item$uploadedFile.url.replace('_0.mp4', '.mp4')) ?? '', mediaType: item.uploadedFile && 'thumbnailUrl' in item.uploadedFile ? _chaynsApi.MediaType.VIDEO : _chaynsApi.MediaType.IMAGE }; }); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore void (0, _chaynsApi.openMedia)({ items, startIndex }); }, [fileItems]); /** * Returns the ratio of the single file */ const ratio = (0, _react.useMemo)(() => { var _fileItems$; switch (fileItems.length) { case 0: return 0; case 1: return Math.max(((_fileItems$ = fileItems[0]) === null || _fileItems$ === void 0 || (_fileItems$ = _fileItems$.uploadedFile) === null || _fileItems$ === void 0 ? void 0 : _fileItems$.ratio) ?? 1, 1); case 2: return 2; case 3: return 3; default: return 1; } }, [fileItems]); const galleryContent = (0, _react.useMemo)(() => { const combinedFilesLength = fileItems.length; if (isEditMode) { const items = fileItems.map(file => /*#__PURE__*/_react.default.createElement(_GalleryItem.default, { key: file.id, fileItem: file, isEditMode: true, onClick: openFiles, handleDeleteFile: handleDeleteFile })); if (maxFiles && maxFiles <= combinedFilesLength) { return items; } items.push(/*#__PURE__*/_react.default.createElement(_AddFile.default, { key: "add_file", onAdd: handleAddFiles })); return items; } const shortedFiles = fileItems.slice(0, 4); return shortedFiles.map((file, index) => { let imageRatio = 1; if (viewMode === _gallery.GalleryViewMode.GRID) { if (combinedFilesLength === 1) { var _fileItems$2; imageRatio = ((_fileItems$2 = fileItems[0]) === null || _fileItems$2 === void 0 || (_fileItems$2 = _fileItems$2.uploadedFile) === null || _fileItems$2 === void 0 ? void 0 : _fileItems$2.ratio) ?? 1; } else if (combinedFilesLength === 2 && (index === 0 || index === 1)) { imageRatio = 0.5; } else if (index === 0 && combinedFilesLength > 2 || combinedFilesLength === 3 && (index === 1 || index === 2)) { imageRatio = 1.5; } } return /*#__PURE__*/_react.default.createElement(_GalleryItem.default, { key: file.id, fileItem: file, isEditMode: false, handleDeleteFile: handleDeleteFile, onClick: openFiles, ratio: imageRatio, remainingItemsLength: combinedFilesLength > 4 && index === 3 ? combinedFilesLength : undefined }); }); }, [fileItems, isEditMode, maxFiles, handleAddFiles, openFiles, handleDeleteFile, viewMode]); return (0, _react.useMemo)(() => /*#__PURE__*/_react.default.createElement(_Gallery.StyledGallery, null, isEditMode ? /*#__PURE__*/_react.default.createElement(_Gallery.StyledGalleryEditModeWrapper, { $fileMinWidth: fileMinWidth, onDragOver: e => e.preventDefault(), onDrop: e => void handleDrop(e) }, galleryContent) : /*#__PURE__*/_react.default.createElement(_Gallery.StyledGalleryItemWrapper, { $ratio: ratio, $uploadedFileLength: fileItems.length, $viewMode: viewMode }, galleryContent)), [isEditMode, fileMinWidth, galleryContent, ratio, fileItems.length, viewMode, handleDrop]); }; Gallery.displayName = 'Gallery'; var _default = exports.default = Gallery; //# sourceMappingURL=Gallery.js.map