import React, { useEffect, useState } from 'react'; // Third Party Libraries import { observer } from 'mobx-react-lite'; import type { StoreType } from 'polotno/model/store'; import { ImagesGrid, UploadSection as DefaultUploadSection, SectionTab, } from 'polotno/side-panel'; import { getImageSize, getCrop } from 'polotno/utils/image'; // Hooks import { useDispatch, useSelector } from 'react-redux'; // Actions import { uploadFile } from '../../../redux/actions/templateActions'; import { failure } from '../../../redux/actions/snackbarActions'; import { SET_UPLOADED_IMAGES } from '../../../redux/actions/action-types'; import { AppDispatch, RootState } from '../../../redux/store'; // Utils import { getType } from '../../../utils/helper'; import { allowedImageTypes } from '../../../utils/constants'; import { MESSAGES } from '../../../utils/message'; // V2 Component import CustomUploadsV2 from './V2'; interface UploadPanelProps { store: StoreType; } export const UploadPanel = observer(({ store }: UploadPanelProps) => { const [images, setImages] = useState< Array<{ url: string; type: string; }> >([]); const [isUploading, setUploading] = useState(false); const [isLoading, setLoading] = useState(false); const dispatch: AppDispatch = useDispatch(); const uploadedImages = useSelector( (state: RootState) => state.templates.uploadedImages ); const load = async () => { if (uploadedImages) { setLoading(true); setImages(uploadedImages); setLoading(false); } }; const validateFile = (file: File) => { if (!file || !allowedImageTypes.includes(file?.type)) { dispatch( failure(MESSAGES.TEMPLATE.CUSTOM_UPLOAD_SECTION.TYPE_VALIDATION) ); return false; } if (file.size >= 7300000) { // 5MB limit dispatch( failure(MESSAGES.TEMPLATE.CUSTOM_UPLOAD_SECTION.SIZE_VALIDATION) ); return false; } return true; }; const handleFileInput = async (e: any) => { try { const { target } = e; for (const file of target.files) { const type = getType(file); const validate = validateFile(file); if (!validate) { target.value = null; return; } setUploading(true); const uploadedFile = await uploadFile(file); const allImages = [...images, { url: uploadedFile, type }]; setImages(allImages); dispatch({ type: SET_UPLOADED_IMAGES, payload: allImages }); } setUploading(false); target.value = null; } catch (error) { return error; } finally { setUploading(false); } }; useEffect(() => { load(); }, []); return (
{MESSAGES.TEMPLATE.CUSTOM_UPLOAD_SECTION.HEADING}
{MESSAGES.TEMPLATE.CUSTOM_UPLOAD_SECTION.ACCEPTED_FORMATS}
{MESSAGES.TEMPLATE.CUSTOM_UPLOAD_SECTION.MAX_SIZE}
Note: {MESSAGES.TEMPLATE.CUSTOM_UPLOAD_SECTION.NOTE}
image?.url} crossOrigin={undefined} isLoading={isLoading} onSelect={async (item, pos, element) => { const image = item?.url; const type = item?.type; let { width, height } = await getImageSize(image); if ( element && element.type === 'svg' && element.contentEditable && type === 'image' ) { element.set({ maskSrc: image }); return; } if ( element && element.type === 'image' && element.contentEditable && type == 'image' ) { const crop = getCrop(element, { width, height, }); element.set({ src: image, ...crop }); return; } const scale = Math.min(store.width / width, store.height / height, 1); width = width * scale; height = height * scale; const x = (pos?.x || store.width / 2) - width / 2; const y = (pos?.y || store.height / 2) - height / 2; store.activePage?.addElement({ type, // @ts-ignore src: image, x, y, width, height, }); }} />
); }); DefaultUploadSection.Panel = UploadPanel; // V2 Component with callback-based functionality interface CustomUploadsV2Props { store: StoreType; onGetBrandingImages?: (payload: any) => Promise; onDeleteBrandingImage?: (id: string | number) => Promise; onUploadBrandingImage?: (payload: any) => Promise; } export const CustomUploadsV2Panel = observer(({ store, onGetBrandingImages, onDeleteBrandingImage, onUploadBrandingImage, }: CustomUploadsV2Props) => { return ( onGetBrandingImages ? : ); }); // V2 Section Configuration export const CustomUploadsV2Section = { name: 'uploads', Tab: (props: any) => ( ), Panel: CustomUploadsV2Panel, }; export default UploadPanel; export { CustomUploadsV2 };