UNPKG

@memori.ai/memori-react

Version:

[![npm version](https://img.shields.io/github/package-json/v/memori-ai/memori-react)](https://www.npmjs.com/package/@memori.ai/memori-react) ![Tests](https://github.com/memori-ai/memori-react/workflows/CI/badge.svg?branch=main) ![TypeScript Support](https

169 lines 10.2 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useState, useRef, useEffect } from 'react'; import cx from 'classnames'; import Spin from '../../ui/Spin'; import { ImageIcon } from '../../icons/Image'; import Modal from '../../ui/Modal'; import { useTranslation } from 'react-i18next'; import Button from '../../ui/Button'; const UploadImages = ({ authToken = '', sessionID = '', client, isMediaAccepted = false, setDocumentPreviewFiles, documentPreviewFiles, onLoadingChange, maxImages = 5, memoriID = '', onImageError, onValidateImageFile, }) => { var _a, _b, _c; const { t, i18n } = useTranslation(); const { backend, dialog } = client || { backend: { uploadAsset: null, uploadAssetUnlogged: null }, dialog: { postMediumSelectedEvent: null, postMediumDeselectedEvent: null }, }; const [isLoading, setIsLoading] = useState(false); const [selectedFile, setSelectedFile] = useState(null); const [filePreview, setFilePreview] = useState(null); const [imageTitle, setImageTitle] = useState(''); const [showUploadModal, setShowUploadModal] = useState(false); const imageInputRef = useRef(null); useEffect(() => { if (onLoadingChange) { onLoadingChange(isLoading); } }, [isLoading, onLoadingChange]); const currentImageCount = documentPreviewFiles.filter((file) => file.type === 'image').length; const validateImageFile = (file) => { if (onValidateImageFile) { return onValidateImageFile(file); } return true; }; const handleImageUpload = async (e) => { var _a; const files = Array.from(e.target.files || []); if (files.length === 0) return; if (currentImageCount >= maxImages) { onImageError === null || onImageError === void 0 ? void 0 : onImageError({ message: (_a = t('upload.maxImagesReached')) !== null && _a !== void 0 ? _a : `Maximum ${maxImages} images allowed.`, severity: 'error', }); return; } const file = files[0]; if (!validateImageFile(file)) { if (imageInputRef.current) { imageInputRef.current.value = ''; } return; } setSelectedFile(file); setFilePreview(URL.createObjectURL(file)); const fileName = file.name.split('.').slice(0, -1).join('.'); setImageTitle(fileName); setShowUploadModal(true); if (imageInputRef.current) { imageInputRef.current.value = ''; } }; const handleTitleSubmit = async () => { var _a; if (!selectedFile || !imageTitle.trim()) return; setIsLoading(true); setShowUploadModal(false); try { const reader = new FileReader(); reader.onload = async (e) => { var _a, _b, _c, _d, _e; const fileDataUrl = (_a = e.target) === null || _a === void 0 ? void 0 : _a.result; const fileId = Math.random().toString(36).substr(2, 9); if (client) { try { let asset; let response; if (authToken && (backend === null || backend === void 0 ? void 0 : backend.uploadAsset)) { response = await backend.uploadAsset(selectedFile.name, fileDataUrl, authToken); } else if (memoriID && sessionID && (backend === null || backend === void 0 ? void 0 : backend.uploadAssetUnlogged)) { response = await backend.uploadAssetUnlogged(selectedFile.name, fileDataUrl, memoriID, sessionID); if (!response) { throw new Error('Upload failed'); } } else { throw new Error('Missing required parameters for upload'); } asset = response.asset; if (response.resultCode !== 0) { throw new Error(response.resultMessage || 'Upload failed'); } let medium = null; if ((dialog === null || dialog === void 0 ? void 0 : dialog.postMediumSelectedEvent) && sessionID) { medium = await dialog.postMediumSelectedEvent(sessionID, { url: asset.assetURL, mimeType: asset.mimeType, }); } let finalMediumID = undefined; if ((_b = medium === null || medium === void 0 ? void 0 : medium.currentState) === null || _b === void 0 ? void 0 : _b.currentMedia) { const existingMediumIDs = new Set(documentPreviewFiles.map((file) => file.mediumID)); finalMediumID = (_c = medium.currentState.currentMedia.find((media) => !existingMediumIDs.has(media.mediumID))) === null || _c === void 0 ? void 0 : _c.mediumID; } setDocumentPreviewFiles((prevFiles) => [ ...prevFiles, { name: imageTitle, id: fileId, url: asset.assetURL, content: asset.assetURL, type: 'image', mediumID: finalMediumID, mimeType: asset.mimeType, }, ]); } catch (error) { onImageError === null || onImageError === void 0 ? void 0 : onImageError({ message: (_d = t('upload.uploadFailed')) !== null && _d !== void 0 ? _d : 'Upload failed', severity: 'error', }); } } else { onImageError === null || onImageError === void 0 ? void 0 : onImageError({ message: (_e = t('upload.apiClientNotConfigured')) !== null && _e !== void 0 ? _e : 'API client not configured properly for media upload', severity: 'warning', }); } setIsLoading(false); }; reader.onerror = () => { var _a; onImageError === null || onImageError === void 0 ? void 0 : onImageError({ message: (_a = t('upload.fileReadingFailed')) !== null && _a !== void 0 ? _a : 'File reading failed', severity: 'error', }); setIsLoading(false); }; reader.readAsDataURL(selectedFile); } catch (error) { onImageError === null || onImageError === void 0 ? void 0 : onImageError({ message: (_a = t('upload.uploadFailed')) !== null && _a !== void 0 ? _a : 'Upload failed', severity: 'error', }); setIsLoading(false); } }; const handleCancelUpload = () => { setShowUploadModal(false); setSelectedFile(null); setFilePreview(null); setImageTitle(''); }; return (_jsxs("div", { className: "memori--image-upload-wrapper", children: [_jsx("input", { ref: imageInputRef, type: "file", accept: ".jpg,.jpeg,.png", className: "memori--upload-file-input", onChange: handleImageUpload, disabled: isLoading || !isMediaAccepted || currentImageCount >= maxImages }), _jsx("button", { className: cx('memori-button', 'memori-button--circle', 'memori-button--icon-only', 'memori-share-button--button', 'memori--conversation-button', 'memori--image-upload-button'), onClick: () => { var _a; return (_a = imageInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, disabled: isLoading || !isMediaAccepted || currentImageCount >= maxImages, children: isLoading ? (_jsx(Spin, { spinning: true, className: "memori--upload-icon" })) : (_jsx(ImageIcon, { className: "memori--upload-icon" })) }), _jsx(Modal, { width: "80%", widthMd: "80%", open: showUploadModal && !!selectedFile, className: "memori--modal-preview-file", onClose: handleCancelUpload, closable: true, title: t('upload.titleImage', { title: imageTitle }), children: _jsxs("div", { className: "memori--preview-content", style: { maxHeight: '70vh', overflowY: 'auto', textAlign: 'center', }, children: [filePreview && (_jsx("img", { src: filePreview, alt: (selectedFile === null || selectedFile === void 0 ? void 0 : selectedFile.name) || 'Preview', style: { maxWidth: '100%', maxHeight: '40vh', marginBottom: '20px', } })), _jsxs("div", { style: { maxWidth: '400px', margin: '0 auto', textAlign: 'left' }, children: [_jsx("p", { style: { marginBottom: '10px', color: '#666' }, children: t('upload.titleHelp') }), _jsx("input", { value: imageTitle, onChange: e => setImageTitle(e.target.value), placeholder: (_a = t('upload.titlePlaceholder')) !== null && _a !== void 0 ? _a : 'Enter image title', style: { width: '90%', marginBottom: '20px' }, className: "memori--upload-title-input" }), _jsxs("div", { style: { display: 'flex', gap: '10px' }, children: [_jsx(Button, { onClick: handleTitleSubmit, disabled: !selectedFile || !imageTitle.trim(), className: "memori-button memori-button--primary", children: (_b = t('confirm')) !== null && _b !== void 0 ? _b : 'Confirm' }), _jsx(Button, { onClick: handleCancelUpload, className: "memori-button memori-button--primary", children: (_c = t('cancel')) !== null && _c !== void 0 ? _c : 'Cancel' })] })] })] }) })] })); }; export default UploadImages; //# sourceMappingURL=UploadImages.js.map