@lifesg/web-frontend-engine 2.0.0-alpha.19 → 2.0.0-alpha.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/chunks/{file-upload-manager.6091aa9e.js → file-upload-manager.72d3bd38.js} +2 -2
  2. package/chunks/{file-upload-manager.6091aa9e.js.map → file-upload-manager.72d3bd38.js.map} +1 -1
  3. package/chunks/{index.dcdbe23e.js → index.1d69a8ce.js} +2 -2
  4. package/chunks/{index.dcdbe23e.js.map → index.1d69a8ce.js.map} +1 -1
  5. package/chunks/{index.cb4c93a5.js → index.51b5c59f.js} +9 -7
  6. package/chunks/{index.cb4c93a5.js.map → index.51b5c59f.js.map} +1 -1
  7. package/chunks/{index.df1ee6f5.js → index.5768de6a.js} +2 -2
  8. package/chunks/{index.df1ee6f5.js.map → index.5768de6a.js.map} +1 -1
  9. package/chunks/{location-modal.b47d92b7.js → location-modal.c01d866b.js} +2 -2
  10. package/chunks/{location-modal.b47d92b7.js.map → location-modal.c01d866b.js.map} +1 -1
  11. package/cjs/chunks/{file-upload-manager.858f342f.js → file-upload-manager.eefe00f1.js} +2 -2
  12. package/cjs/chunks/{file-upload-manager.858f342f.js.map → file-upload-manager.eefe00f1.js.map} +1 -1
  13. package/cjs/chunks/{index.3cfca5cf.js → index.08664f90.js} +2 -2
  14. package/cjs/chunks/{index.3cfca5cf.js.map → index.08664f90.js.map} +1 -1
  15. package/cjs/chunks/{index.ade37699.js → index.c08ef3b5.js} +2 -2
  16. package/cjs/chunks/{index.ade37699.js.map → index.c08ef3b5.js.map} +1 -1
  17. package/cjs/chunks/{index.7db1a25b.js → index.c2b20a79.js} +64 -62
  18. package/cjs/chunks/{index.7db1a25b.js.map → index.c2b20a79.js.map} +1 -1
  19. package/cjs/chunks/{location-modal.ff0cd21c.js → location-modal.13ffc73e.js} +2 -2
  20. package/cjs/chunks/{location-modal.ff0cd21c.js.map → location-modal.13ffc73e.js.map} +1 -1
  21. package/cjs/index.js +1 -1
  22. package/components/custom/array-field/array-field.styles.d.ts +5 -2
  23. package/components/custom/array-field/types.d.ts +14 -5
  24. package/components/custom/types.d.ts +1 -1
  25. package/components/shared/error-messages.d.ts +2 -0
  26. package/index.js +1 -1
  27. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- import{useContext as e,useRef as t,useEffect as i}from"react";import{F as s,u as a,a as r,b as l,g as o,E as n,c as m,d as p,A as c,I as d}from"./index.cb4c93a5.js";import"react/jsx-runtime";import"@lifesg/react-design-system/theme";import"styled-components";import"@lifesg/react-design-system/markup";import"react-dom/server";import"@lifesg/react-design-system/typography";import"@lifesg/react-design-system/button";import"@lifesg/react-design-system/modal";import"@lifesg/react-design-system/alert";import"@lifesg/react-design-system/layout";import"@lifesg/react-design-system/box-container";import"@lifesg/react-design-system/divider";import"@lifesg/react-design-system/v2_media";import"@lifesg/react-design-system/text-list";import"@lifesg/react-design-system/popover-v2";import"@lifesg/react-icons";import"@lifesg/react-design-system/tab";import"@lifesg/react-icons/plus-circle-fill";import"@lifesg/react-design-system/button-with-icon";import"@lifesg/react-design-system/error-display";import"@lifesg/react-design-system/filter";import"@lifesg/react-design-system/uneditable-section";import"@lifesg/react-design-system/timeline";import"@lifesg/react-design-system/form";import"@lifesg/react-design-system/checkbox";import"@lifesg/react-design-system/toggle";import"@lifesg/react-design-system/file-upload";import"@lifesg/react-icons/cross";import"@lifesg/react-design-system/icon-button";import"@lifesg/react-icons/bin";import"@lifesg/react-icons/eraser";import"@lifesg/react-icons/pencil";import"@lifesg/react-icons/pencil-stroke";import"@lifesg/react-icons/plus";import"@lifesg/react-icons/exclamation-triangle";import"@lifesg/react-icons/pin-fill";import"@lifesg/react-design-system/image-button";import"@lifesg/react-design-system/radio-button";import"@lifesg/react-design-system/v2_layout";const f=["image/jpeg","image/gif","image/png"],g=g=>{const{compressImages:u,fileTypeRule:y,hideThumbnail:w,id:I,maxFileSizeRule:F,upload:U,uploadRule:b,value:R}=g,{files:T,setFiles:E,setCurrentFileIds:h}=e(s),D=a(R),{setValue:L}=r(),{dispatchFieldEvent:x}=l(),z=t();i((()=>{z.current=o()}),[]),i((()=>{T.forEach((async(e,t)=>{try{switch(e.status){case n.INJECTED:await P(e,t);break;case n.NONE:await S(e,t);break;case n.UPLOAD_READY:await _(e,t);break;case n.TO_DELETE:k(t)}}catch(e){M(t)}}));const e=T.filter((({status:e})=>e===n.UPLOADED)),t=e.filter((({addedFrom:e})=>"schema"!==e)).length>0,i=T.filter((({status:e})=>e===n.TO_DELETE)).length>0,s=t||i;h(e.map((({fileItem:e})=>e.id))),L(I,e.map((({dataURL:e,fileItem:t,fileUrl:i,uploadResponse:s})=>({..."base64"===U.type?{dataURL:e}:{},fileId:t.id,fileName:t.name,fileUrl:i,uploadResponse:s}))),{shouldDirty:s,shouldTouch:t})}),[T.map((({fileItem:e,status:t})=>`${e?.id}-${t}`)).join(",")]),i((()=>{void 0!==D&&void 0===R&&T.length&&E([])}),[T,D,E,R]);const M=e=>{E((t=>{const i=[...t],s=t[e];return i[e]={...s,fileItem:{...s.fileItem,id:s.fileItem?.id||o(),name:s.rawFile.name,errorMessage:b?.errorMessage||m.UPLOAD().GENERIC},status:n.ERROR_GENERIC},i}))},O=async(e,t)=>{if(!0!==w&&f.includes(t||e.fileItem?.type)){const t=await d.dataUrlToImage(e.dataURL),i=await d.resampleImage(t,{width:94,height:94,crop:!0});return await p.fileToDataUrl(i)}return""},v=async e=>{const{addedFrom:t,dataURL:i,rawFile:s}=e,a=await p.getType(s),r=A(a);if(r?.status<0)return r;const l="base64"===U.type?p.getFilesizeFromBase64(i):s.size,{errorMessage:o,status:m}=N(l);return m<0?{errorMessage:o,fileType:a,status:m}:"schema"===t?{fileType:a,status:n.UPLOADED}:{fileType:a,status:n.UPLOAD_READY}},A=e=>!y.fileType?.length||y.fileType?.includes(e.ext)?{}:{errorMessage:y.errorMessage||m.UPLOAD().FILE_TYPE(y.fileType||[]),fileType:e,status:n.ERROR_FORMAT},N=e=>{if(F.maxSizeInKb>0){if(e>1024*F.maxSizeInKb)return{errorMessage:F.errorMessage||m.UPLOAD().MAX_FILE_SIZE(F.maxSizeInKb),status:n.ERROR_SIZE}}return{}},P=async(e,t)=>{let i;if(E((e=>{const i=[...e];return i[t]={...e[t],status:n.INJECTING},i})),e.dataURL){const t=await p.dataUrlToBlob(e.dataURL);i=new File([t],e.rawFile.name)}else if(e.fileUrl){const t=await new c("",void 0,void 0,!1,{responseType:"blob"}).get(e.fileUrl),s=await p.getType(new File([t],e.rawFile.name));i=new File([t],e.rawFile.name,{type:s.mime}),e.dataURL=await p.fileToDataUrl(i)}const s=e.uploadResponse?.data||e.uploadResponse,{errorMessage:a,fileType:r}=i?await v({...e,rawFile:i}):A({mime:s?.mimeType,ext:s?.ext});let l=i?.size||s?.fileSize||0;isNaN(l)&&(l=0);const{errorMessage:m}=N(l),d=i?await O(e,r?.mime):void 0;E((c=>{const f=[...c];return f[t]={...e,fileItem:{errorMessage:a||m,id:e.fileItem?.id||o(),name:p.deduplicateFileName(T.map((({fileItem:e})=>e.name)),t,i?.name||e.rawFile.name),progress:1,size:l,type:r?.mime||s?.mimeType,thumbnailImageDataUrl:d},rawFile:i,status:n.UPLOADED},f}))},S=async(e,t)=>{const i=await C(e),s=await p.fileToDataUrl(i.rawFile),{errorMessage:a,fileType:r,status:l}=await v({dataURL:s,...i});E((e=>{const n=[...e];return n[t]={...i,dataURL:s,fileItem:{errorMessage:a,id:o(),name:p.deduplicateFileName(T.map((({fileItem:e})=>e?.name)),t,p.sanitizeFileName(i.rawFile.name)),size:i.rawFile.size,type:r.mime,progress:0},status:l},n}))},_=async(e,t)=>{E((e=>{const i=[...e];return i[t]={...e[t],status:n.UPLOADING},i}));const i=new FormData;i.append("sessionId",U?.sessionId||z.current||""),i.append("fileId",e.fileItem.id),i.append("slot",e.slot.toString()),"base64"===U.type?i.append("dataURL",e.dataURL):"multipart"===U.type&&i.append("file",e.rawFile,e.fileItem?.name);try{const s=await new c("",void 0,void 0,!0).post(U.url,i,{headers:{"Content-Type":"base64"===U.type?"application/json":"multipart/form-data",...U.headers},onUploadProgress:e=>{const{loaded:i,total:s}=e;E((e=>{if(!e[t])return e;const a=[...e];return a[t]={...e[t],fileItem:{...e[t].fileItem,progress:i/s}},a}))}}),a=await O(e);E((e=>{if(!e[t])return e;const i=[...e];return i[t]={...e[t],fileItem:{...e[t].fileItem,progress:1,thumbnailImageDataUrl:a},fileUrl:s?.data?.fileUrl,status:n.UPLOADED,uploadResponse:s},i}))}catch(t){throw x("upload-error",I,{fileId:e.fileItem.id,errorData:t?.response?.data}),t}},k=e=>{E((t=>t.filter(((t,i)=>i!==e))))},C=async e=>{if(F.maxSizeInKb>0&&u){const t=1024*F.maxSizeInKb;if(e.rawFile.size>t){const t=await p.getType(e.rawFile);if(f.includes(t.mime)){let t=await d.compressImage(e.rawFile,{fileSize:F.maxSizeInKb});return t instanceof Blob&&(t=p.blobToFile(t,{name:e.rawFile.name,lastModified:e.rawFile.lastModified})),{...e,rawFile:t}}}}return e};return null};export{g as default};
2
- //# sourceMappingURL=file-upload-manager.6091aa9e.js.map
1
+ import{useContext as e,useRef as t,useEffect as i}from"react";import{F as s,u as a,a as r,b as l,g as o,E as n,c as m,d as p,A as c,I as d}from"./index.51b5c59f.js";import"react/jsx-runtime";import"@lifesg/react-design-system/theme";import"styled-components";import"@lifesg/react-design-system/markup";import"react-dom/server";import"@lifesg/react-design-system/typography";import"@lifesg/react-design-system/button";import"@lifesg/react-design-system/modal";import"@lifesg/react-design-system/alert";import"@lifesg/react-design-system/layout";import"@lifesg/react-design-system/box-container";import"@lifesg/react-design-system/divider";import"@lifesg/react-design-system/v2_media";import"@lifesg/react-design-system/text-list";import"@lifesg/react-design-system/popover-v2";import"@lifesg/react-icons";import"@lifesg/react-design-system/tab";import"@lifesg/react-icons/plus-circle-fill";import"@lifesg/react-design-system/button-with-icon";import"@lifesg/react-design-system/error-display";import"@lifesg/react-design-system/filter";import"@lifesg/react-design-system/uneditable-section";import"@lifesg/react-design-system/timeline";import"@lifesg/react-design-system/form";import"@lifesg/react-design-system/checkbox";import"@lifesg/react-design-system/toggle";import"@lifesg/react-design-system/file-upload";import"@lifesg/react-icons/cross";import"@lifesg/react-design-system/icon-button";import"@lifesg/react-icons/bin";import"@lifesg/react-icons/eraser";import"@lifesg/react-icons/pencil";import"@lifesg/react-icons/pencil-stroke";import"@lifesg/react-icons/plus";import"@lifesg/react-icons/exclamation-triangle";import"@lifesg/react-icons/pin-fill";import"@lifesg/react-design-system/image-button";import"@lifesg/react-design-system/radio-button";import"@lifesg/react-design-system/v2_layout";const f=["image/jpeg","image/gif","image/png"],g=g=>{const{compressImages:u,fileTypeRule:y,hideThumbnail:w,id:I,maxFileSizeRule:F,upload:U,uploadRule:b,value:R}=g,{files:T,setFiles:E,setCurrentFileIds:h}=e(s),D=a(R),{setValue:L}=r(),{dispatchFieldEvent:x}=l(),z=t();i((()=>{z.current=o()}),[]),i((()=>{T.forEach((async(e,t)=>{try{switch(e.status){case n.INJECTED:await P(e,t);break;case n.NONE:await S(e,t);break;case n.UPLOAD_READY:await _(e,t);break;case n.TO_DELETE:k(t)}}catch(e){M(t)}}));const e=T.filter((({status:e})=>e===n.UPLOADED)),t=e.filter((({addedFrom:e})=>"schema"!==e)).length>0,i=T.filter((({status:e})=>e===n.TO_DELETE)).length>0,s=t||i;h(e.map((({fileItem:e})=>e.id))),L(I,e.map((({dataURL:e,fileItem:t,fileUrl:i,uploadResponse:s})=>({..."base64"===U.type?{dataURL:e}:{},fileId:t.id,fileName:t.name,fileUrl:i,uploadResponse:s}))),{shouldDirty:s,shouldTouch:t})}),[T.map((({fileItem:e,status:t})=>`${e?.id}-${t}`)).join(",")]),i((()=>{void 0!==D&&void 0===R&&T.length&&E([])}),[T,D,E,R]);const M=e=>{E((t=>{const i=[...t],s=t[e];return i[e]={...s,fileItem:{...s.fileItem,id:s.fileItem?.id||o(),name:s.rawFile.name,errorMessage:b?.errorMessage||m.UPLOAD().GENERIC},status:n.ERROR_GENERIC},i}))},O=async(e,t)=>{if(!0!==w&&f.includes(t||e.fileItem?.type)){const t=await d.dataUrlToImage(e.dataURL),i=await d.resampleImage(t,{width:94,height:94,crop:!0});return await p.fileToDataUrl(i)}return""},v=async e=>{const{addedFrom:t,dataURL:i,rawFile:s}=e,a=await p.getType(s),r=A(a);if(r?.status<0)return r;const l="base64"===U.type?p.getFilesizeFromBase64(i):s.size,{errorMessage:o,status:m}=N(l);return m<0?{errorMessage:o,fileType:a,status:m}:"schema"===t?{fileType:a,status:n.UPLOADED}:{fileType:a,status:n.UPLOAD_READY}},A=e=>!y.fileType?.length||y.fileType?.includes(e.ext)?{}:{errorMessage:y.errorMessage||m.UPLOAD().FILE_TYPE(y.fileType||[]),fileType:e,status:n.ERROR_FORMAT},N=e=>{if(F.maxSizeInKb>0){if(e>1024*F.maxSizeInKb)return{errorMessage:F.errorMessage||m.UPLOAD().MAX_FILE_SIZE(F.maxSizeInKb),status:n.ERROR_SIZE}}return{}},P=async(e,t)=>{let i;if(E((e=>{const i=[...e];return i[t]={...e[t],status:n.INJECTING},i})),e.dataURL){const t=await p.dataUrlToBlob(e.dataURL);i=new File([t],e.rawFile.name)}else if(e.fileUrl){const t=await new c("",void 0,void 0,!1,{responseType:"blob"}).get(e.fileUrl),s=await p.getType(new File([t],e.rawFile.name));i=new File([t],e.rawFile.name,{type:s.mime}),e.dataURL=await p.fileToDataUrl(i)}const s=e.uploadResponse?.data||e.uploadResponse,{errorMessage:a,fileType:r}=i?await v({...e,rawFile:i}):A({mime:s?.mimeType,ext:s?.ext});let l=i?.size||s?.fileSize||0;isNaN(l)&&(l=0);const{errorMessage:m}=N(l),d=i?await O(e,r?.mime):void 0;E((c=>{const f=[...c];return f[t]={...e,fileItem:{errorMessage:a||m,id:e.fileItem?.id||o(),name:p.deduplicateFileName(T.map((({fileItem:e})=>e.name)),t,i?.name||e.rawFile.name),progress:1,size:l,type:r?.mime||s?.mimeType,thumbnailImageDataUrl:d},rawFile:i,status:n.UPLOADED},f}))},S=async(e,t)=>{const i=await C(e),s=await p.fileToDataUrl(i.rawFile),{errorMessage:a,fileType:r,status:l}=await v({dataURL:s,...i});E((e=>{const n=[...e];return n[t]={...i,dataURL:s,fileItem:{errorMessage:a,id:o(),name:p.deduplicateFileName(T.map((({fileItem:e})=>e?.name)),t,p.sanitizeFileName(i.rawFile.name)),size:i.rawFile.size,type:r.mime,progress:0},status:l},n}))},_=async(e,t)=>{E((e=>{const i=[...e];return i[t]={...e[t],status:n.UPLOADING},i}));const i=new FormData;i.append("sessionId",U?.sessionId||z.current||""),i.append("fileId",e.fileItem.id),i.append("slot",e.slot.toString()),"base64"===U.type?i.append("dataURL",e.dataURL):"multipart"===U.type&&i.append("file",e.rawFile,e.fileItem?.name);try{const s=await new c("",void 0,void 0,!0).post(U.url,i,{headers:{"Content-Type":"base64"===U.type?"application/json":"multipart/form-data",...U.headers},onUploadProgress:e=>{const{loaded:i,total:s}=e;E((e=>{if(!e[t])return e;const a=[...e];return a[t]={...e[t],fileItem:{...e[t].fileItem,progress:i/s}},a}))}}),a=await O(e);E((e=>{if(!e[t])return e;const i=[...e];return i[t]={...e[t],fileItem:{...e[t].fileItem,progress:1,thumbnailImageDataUrl:a},fileUrl:s?.data?.fileUrl,status:n.UPLOADED,uploadResponse:s},i}))}catch(t){throw x("upload-error",I,{fileId:e.fileItem.id,errorData:t?.response?.data}),t}},k=e=>{E((t=>t.filter(((t,i)=>i!==e))))},C=async e=>{if(F.maxSizeInKb>0&&u){const t=1024*F.maxSizeInKb;if(e.rawFile.size>t){const t=await p.getType(e.rawFile);if(f.includes(t.mime)){let t=await d.compressImage(e.rawFile,{fileSize:F.maxSizeInKb});return t instanceof Blob&&(t=p.blobToFile(t,{name:e.rawFile.name,lastModified:e.rawFile.lastModified})),{...e,rawFile:t}}}}return e};return null};export{g as default};
2
+ //# sourceMappingURL=file-upload-manager.72d3bd38.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-upload-manager.6091aa9e.js","sources":["../../src/components/fields/file-upload/file-upload-manager.ts"],"sourcesContent":["import { AxiosError } from \"axios\";\nimport { useContext, useEffect, useRef } from \"react\";\nimport { useFormContext } from \"react-hook-form\";\nimport { AxiosApiClient, FileHelper, ImageHelper, generateRandomId } from \"../../../utils\";\nimport { useFieldEvent, usePrevious } from \"../../../utils/hooks\";\nimport { ERROR_MESSAGES } from \"../../shared\";\nimport { FileUploadContext } from \"./file-upload-context\";\nimport {\n\tEFileStatus,\n\tIFile,\n\tIFileUploadSchema,\n\tIFileUploadValidationRule,\n\tIFileUploadValue,\n\tTUploadErrorDetail,\n} from \"./types\";\n\ninterface IProps {\n\tcompressImages: boolean;\n\tfileTypeRule: IFileUploadValidationRule;\n\thideThumbnail?: boolean | undefined;\n\tid: string;\n\tmaxFileSizeRule: IFileUploadValidationRule;\n\tupload: IFileUploadSchema[\"uploadOnAddingFile\"];\n\tuploadRule: IFileUploadValidationRule;\n\tvalue: IFileUploadValue[];\n}\n\nconst RESIZEABLE_IMAGE_TYPES = [\"image/jpeg\", \"image/gif\", \"image/png\"];\n\nconst FileUploadManager = (props: IProps) => {\n\t// =============================================================================\n\t// CONST, STATE, REFS\n\t// =============================================================================\n\tconst { compressImages, fileTypeRule, hideThumbnail, id, maxFileSizeRule, upload, uploadRule, value } = props;\n\tconst { files, setFiles, setCurrentFileIds } = useContext(FileUploadContext);\n\tconst previousValue = usePrevious(value);\n\tconst { setValue } = useFormContext();\n\tconst { dispatchFieldEvent } = useFieldEvent();\n\tconst sessionId = useRef<string>();\n\n\t// =============================================================================\n\t// EFFECTS\n\t// =============================================================================\n\tuseEffect(() => {\n\t\tsessionId.current = generateRandomId();\n\t}, []);\n\n\tuseEffect(\n\t\t() => {\n\t\t\t// handle file status\n\t\t\tfiles.forEach(async (file, index) => {\n\t\t\t\ttry {\n\t\t\t\t\tswitch (file.status) {\n\t\t\t\t\t\tcase EFileStatus.INJECTED:\n\t\t\t\t\t\t\tawait injectFile(file, index);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EFileStatus.NONE:\n\t\t\t\t\t\t\tawait parseFile(file, index);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EFileStatus.UPLOAD_READY:\n\t\t\t\t\t\t\tawait uploadFile(file, index);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EFileStatus.TO_DELETE:\n\t\t\t\t\t\t\tdeleteFile(index);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\thandleGenericError(index);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// track / update values\n\t\t\tconst uploadedFiles = files.filter(({ status }) => status === EFileStatus.UPLOADED);\n\t\t\tconst notPrefilledFiles = uploadedFiles.filter(({ addedFrom }) => addedFrom !== \"schema\");\n\t\t\tconst hasNotPrefilledFiles = notPrefilledFiles.length > 0;\n\t\t\tconst gotDeleteFiles = files.filter(({ status }) => status === EFileStatus.TO_DELETE).length > 0;\n\n\t\t\t/**\n\t\t\t * should dirty if\n\t\t\t * - it is dirty in the first place\n\t\t\t * - there are non-prefilled files\n\t\t\t * - user deleted file (differentiated from reset)\n\t\t\t */\n\t\t\tconst shouldDirty = hasNotPrefilledFiles || gotDeleteFiles;\n\n\t\t\tsetCurrentFileIds(uploadedFiles.map(({ fileItem }) => fileItem.id));\n\n\t\t\tsetValue(\n\t\t\t\tid,\n\t\t\t\tuploadedFiles.map(({ dataURL, fileItem, fileUrl, uploadResponse }) => ({\n\t\t\t\t\t...(upload.type === \"base64\" ? { dataURL } : {}),\n\t\t\t\t\tfileId: fileItem.id,\n\t\t\t\t\tfileName: fileItem.name,\n\t\t\t\t\tfileUrl,\n\t\t\t\t\tuploadResponse,\n\t\t\t\t})),\n\t\t\t\t{ shouldDirty, shouldTouch: hasNotPrefilledFiles }\n\t\t\t);\n\t\t}, // eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[files.map(({ fileItem, status }) => `${fileItem?.id}-${status}`).join(\",\")]\n\t);\n\n\t// for reset\n\tuseEffect(() => {\n\t\tif (previousValue !== undefined && value === undefined && files.length) {\n\t\t\tsetFiles([]);\n\t\t}\n\t}, [files, previousValue, setFiles, value]);\n\n\t// =============================================================================\n\t// HELPER FUNCTIONS\n\t// =============================================================================\n\n\tconst handleGenericError = (index: number) => {\n\t\tsetFiles((prev) => {\n\t\t\tconst updatedFiles = [...prev];\n\t\t\tconst file = prev[index];\n\t\t\tupdatedFiles[index] = {\n\t\t\t\t...file,\n\t\t\t\tfileItem: {\n\t\t\t\t\t...file.fileItem,\n\t\t\t\t\tid: file.fileItem?.id || generateRandomId(),\n\t\t\t\t\tname: file.rawFile.name,\n\t\t\t\t\terrorMessage: uploadRule?.errorMessage || ERROR_MESSAGES.UPLOAD().GENERIC,\n\t\t\t\t},\n\t\t\t\tstatus: EFileStatus.ERROR_GENERIC,\n\t\t\t};\n\t\t\treturn updatedFiles;\n\t\t});\n\t};\n\n\tconst generateThumbnail = async (file: IFile, fileType?: string | undefined) => {\n\t\tif (hideThumbnail !== true && RESIZEABLE_IMAGE_TYPES.includes(fileType || file.fileItem?.type)) {\n\t\t\tconst image = await ImageHelper.dataUrlToImage(file.dataURL);\n\t\t\tconst thumbnail = await ImageHelper.resampleImage(image, { width: 94, height: 94, crop: true });\n\t\t\treturn await FileHelper.fileToDataUrl(thumbnail);\n\t\t}\n\t\treturn \"\";\n\t};\n\n\tconst readFile = async (fileToRead: IFile) => {\n\t\tconst { addedFrom, dataURL, rawFile } = fileToRead;\n\t\tconst fileType = await FileHelper.getType(rawFile);\n\t\tconst fileTypeResult = validateFileType(fileType);\n\n\t\tif (fileTypeResult?.status < 0) {\n\t\t\treturn fileTypeResult;\n\t\t}\n\n\t\tconst fileSize = upload.type === \"base64\" ? FileHelper.getFilesizeFromBase64(dataURL) : rawFile.size;\n\t\tconst { errorMessage, status } = validateFileSize(fileSize);\n\t\tif (status < 0) {\n\t\t\treturn { errorMessage, fileType, status };\n\t\t}\n\n\t\tif (addedFrom === \"schema\") {\n\t\t\treturn {\n\t\t\t\tfileType,\n\t\t\t\tstatus: EFileStatus.UPLOADED,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tfileType,\n\t\t\tstatus: EFileStatus.UPLOAD_READY,\n\t\t};\n\t};\n\n\tconst validateFileType = (fileType: { mime: string; ext: string }) => {\n\t\tconst validFileType = fileTypeRule.fileType?.length ? fileTypeRule.fileType?.includes(fileType.ext) : true;\n\n\t\tif (!validFileType) {\n\t\t\treturn {\n\t\t\t\terrorMessage:\n\t\t\t\t\tfileTypeRule.errorMessage || ERROR_MESSAGES.UPLOAD().FILE_TYPE(fileTypeRule.fileType || []),\n\t\t\t\tfileType,\n\t\t\t\tstatus: EFileStatus.ERROR_FORMAT,\n\t\t\t};\n\t\t}\n\n\t\treturn {};\n\t};\n\n\tconst validateFileSize = (fileSizeInKb: number) => {\n\t\tif (maxFileSizeRule.maxSizeInKb > 0) {\n\t\t\tconst maxSizeInB = maxFileSizeRule.maxSizeInKb * 1024;\n\t\t\tif (fileSizeInKb > maxSizeInB) {\n\t\t\t\treturn {\n\t\t\t\t\terrorMessage:\n\t\t\t\t\t\tmaxFileSizeRule.errorMessage ||\n\t\t\t\t\t\tERROR_MESSAGES.UPLOAD().MAX_FILE_SIZE(maxFileSizeRule.maxSizeInKb),\n\t\t\t\t\tstatus: EFileStatus.ERROR_SIZE,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn {};\n\t};\n\n\t// =============================================================================\n\t// FILE STATUS HANDLERS\n\t// =============================================================================\n\tconst injectFile = async (fileToInject: IFile, index: number) => {\n\t\tsetFiles((prev) => {\n\t\t\tconst updatedFiles = [...prev];\n\t\t\tupdatedFiles[index] = {\n\t\t\t\t...prev[index],\n\t\t\t\tstatus: EFileStatus.INJECTING,\n\t\t\t};\n\t\t\treturn updatedFiles;\n\t\t});\n\n\t\tlet rawFile: File;\n\t\tif (fileToInject.dataURL) {\n\t\t\tconst blob = await FileHelper.dataUrlToBlob(fileToInject.dataURL);\n\t\t\trawFile = new File([blob], fileToInject.rawFile.name);\n\t\t} else if (fileToInject.fileUrl) {\n\t\t\tconst response: Blob = await new AxiosApiClient(\"\", undefined, undefined, false, {\n\t\t\t\tresponseType: \"blob\",\n\t\t\t}).get(fileToInject.fileUrl);\n\t\t\tconst fileType = await FileHelper.getType(new File([response], fileToInject.rawFile.name));\n\t\t\trawFile = new File([response], fileToInject.rawFile.name, { type: fileType.mime });\n\t\t\tfileToInject.dataURL = await FileHelper.fileToDataUrl(rawFile);\n\t\t}\n\n\t\t// rawFile may not be available because some use cases is not able to return dataURL / fileUrl due to security concerns\n\t\t// in such cases, we will rely on the uploadResponse for file info\n\t\tconst uploadData = fileToInject.uploadResponse?.[\"data\"] || fileToInject.uploadResponse;\n\t\tconst { errorMessage, fileType } = rawFile\n\t\t\t? await readFile({ ...fileToInject, rawFile })\n\t\t\t: validateFileType({\n\t\t\t\t\tmime: uploadData?.[\"mimeType\"],\n\t\t\t\t\text: uploadData?.[\"ext\"],\n\t\t\t });\n\n\t\tlet size = rawFile?.size || uploadData?.[\"fileSize\"] || 0;\n\t\tif (isNaN(size)) {\n\t\t\tsize = 0;\n\t\t}\n\t\tconst { errorMessage: filesizeErrorMessage } = validateFileSize(size);\n\n\t\tconst thumbnailImageDataUrl = rawFile ? await generateThumbnail(fileToInject, fileType?.mime) : undefined;\n\n\t\tsetFiles((prev) => {\n\t\t\tconst updatedFiles = [...prev];\n\t\t\tupdatedFiles[index] = {\n\t\t\t\t...fileToInject,\n\t\t\t\tfileItem: {\n\t\t\t\t\terrorMessage: errorMessage || filesizeErrorMessage,\n\t\t\t\t\tid: fileToInject.fileItem?.id || generateRandomId(),\n\t\t\t\t\tname: FileHelper.deduplicateFileName(\n\t\t\t\t\t\tfiles.map(({ fileItem }) => fileItem.name),\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\trawFile?.name || fileToInject.rawFile.name\n\t\t\t\t\t),\n\t\t\t\t\tprogress: 1,\n\t\t\t\t\tsize,\n\t\t\t\t\ttype: fileType?.mime || uploadData?.[\"mimeType\"],\n\t\t\t\t\tthumbnailImageDataUrl,\n\t\t\t\t},\n\t\t\t\trawFile,\n\t\t\t\tstatus: EFileStatus.UPLOADED,\n\t\t\t};\n\t\t\treturn updatedFiles;\n\t\t});\n\t};\n\n\tconst parseFile = async (fileToParse: IFile, index: number) => {\n\t\tconst compressedFile = await compressImageFile(fileToParse);\n\t\tconst dataURL = await FileHelper.fileToDataUrl(compressedFile.rawFile);\n\t\tconst { errorMessage, fileType, status } = await readFile({ dataURL, ...compressedFile });\n\n\t\tsetFiles((prev) => {\n\t\t\tconst updatedFiles = [...prev];\n\t\t\tupdatedFiles[index] = {\n\t\t\t\t...compressedFile,\n\t\t\t\tdataURL,\n\t\t\t\tfileItem: {\n\t\t\t\t\terrorMessage,\n\t\t\t\t\tid: generateRandomId(),\n\t\t\t\t\tname: FileHelper.deduplicateFileName(\n\t\t\t\t\t\tfiles.map(({ fileItem }) => fileItem?.name),\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\tFileHelper.sanitizeFileName(compressedFile.rawFile.name)\n\t\t\t\t\t),\n\t\t\t\t\tsize: compressedFile.rawFile.size,\n\t\t\t\t\ttype: fileType.mime,\n\t\t\t\t\tprogress: 0,\n\t\t\t\t},\n\t\t\t\tstatus,\n\t\t\t};\n\t\t\treturn updatedFiles;\n\t\t});\n\t};\n\n\tconst uploadFile = async (fileToUpload: IFile, index: number) => {\n\t\tsetFiles((prev) => {\n\t\t\tconst updatedFiles = [...prev];\n\t\t\tupdatedFiles[index] = {\n\t\t\t\t...prev[index],\n\t\t\t\tstatus: EFileStatus.UPLOADING,\n\t\t\t};\n\t\t\treturn updatedFiles;\n\t\t});\n\n\t\tconst formData = new FormData();\n\t\tformData.append(\"sessionId\", upload?.sessionId || sessionId.current || \"\");\n\t\tformData.append(\"fileId\", fileToUpload.fileItem.id);\n\t\tformData.append(\"slot\", fileToUpload.slot.toString());\n\t\tif (upload.type === \"base64\") {\n\t\t\tformData.append(\"dataURL\", fileToUpload.dataURL);\n\t\t} else if (upload.type === \"multipart\") {\n\t\t\tformData.append(\"file\", fileToUpload.rawFile, fileToUpload.fileItem?.name);\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await new AxiosApiClient(\"\", undefined, undefined, true).post(upload.url, formData, {\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": upload.type === \"base64\" ? \"application/json\" : \"multipart/form-data\",\n\t\t\t\t\t...upload.headers,\n\t\t\t\t},\n\t\t\t\tonUploadProgress: (progressEvent) => {\n\t\t\t\t\tconst { loaded, total } = progressEvent;\n\t\t\t\t\tsetFiles((prev) => {\n\t\t\t\t\t\tif (!prev[index]) return prev;\n\t\t\t\t\t\tconst updatedFiles = [...prev];\n\t\t\t\t\t\tupdatedFiles[index] = {\n\t\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\t\tfileItem: {\n\t\t\t\t\t\t\t\t...prev[index].fileItem,\n\t\t\t\t\t\t\t\tprogress: loaded / total,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\treturn updatedFiles;\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst thumbnailImageDataUrl = await generateThumbnail(fileToUpload);\n\t\t\tsetFiles((prev) => {\n\t\t\t\tif (!prev[index]) return prev;\n\t\t\t\tconst updatedFiles = [...prev];\n\t\t\t\tupdatedFiles[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tfileItem: {\n\t\t\t\t\t\t...prev[index].fileItem,\n\t\t\t\t\t\tprogress: 1,\n\t\t\t\t\t\tthumbnailImageDataUrl,\n\t\t\t\t\t},\n\t\t\t\t\tfileUrl: response?.[\"data\"]?.[\"fileUrl\"],\n\t\t\t\t\tstatus: EFileStatus.UPLOADED,\n\t\t\t\t\tuploadResponse: response,\n\t\t\t\t};\n\t\t\t\treturn updatedFiles;\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tdispatchFieldEvent<TUploadErrorDetail>(\"upload-error\", id, {\n\t\t\t\tfileId: fileToUpload.fileItem.id,\n\t\t\t\terrorData: (err as AxiosError)?.response?.data,\n\t\t\t});\n\n\t\t\tthrow err;\n\t\t}\n\t};\n\n\tconst deleteFile = (index: number) => {\n\t\tsetFiles((prev) => prev.filter((_file, i) => i !== index));\n\t};\n\n\tconst compressImageFile = async (fileToCompress: IFile) => {\n\t\tif (maxFileSizeRule.maxSizeInKb > 0 && compressImages) {\n\t\t\tconst maxSizeInB = maxFileSizeRule.maxSizeInKb * 1024;\n\t\t\tif (fileToCompress.rawFile.size > maxSizeInB) {\n\t\t\t\tconst fileType = await FileHelper.getType(fileToCompress.rawFile);\n\t\t\t\tif (RESIZEABLE_IMAGE_TYPES.includes(fileType.mime)) {\n\t\t\t\t\tlet fileOrBlob = await ImageHelper.compressImage(fileToCompress.rawFile, {\n\t\t\t\t\t\tfileSize: maxFileSizeRule.maxSizeInKb,\n\t\t\t\t\t});\n\t\t\t\t\tif (fileOrBlob instanceof Blob) {\n\t\t\t\t\t\tfileOrBlob = FileHelper.blobToFile(fileOrBlob, {\n\t\t\t\t\t\t\tname: fileToCompress.rawFile.name,\n\t\t\t\t\t\t\tlastModified: fileToCompress.rawFile.lastModified,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...fileToCompress,\n\t\t\t\t\t\trawFile: fileOrBlob,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn fileToCompress;\n\t};\n\n\t// =============================================================================\n\t// RENDER FUNCTIONS\n\t// =============================================================================\n\treturn null;\n};\n\nexport default FileUploadManager;\n"],"names":["RESIZEABLE_IMAGE_TYPES","FileUploadManager","props","compressImages","fileTypeRule","hideThumbnail","id","maxFileSizeRule","upload","uploadRule","value","files","setFiles","setCurrentFileIds","useContext","FileUploadContext","previousValue","usePrevious","setValue","useFormContext","dispatchFieldEvent","useFieldEvent","sessionId","useRef","useEffect","current","generateRandomId","forEach","async","file","index","status","EFileStatus","INJECTED","injectFile","NONE","parseFile","UPLOAD_READY","uploadFile","TO_DELETE","deleteFile","err","handleGenericError","uploadedFiles","filter","UPLOADED","hasNotPrefilledFiles","addedFrom","length","gotDeleteFiles","shouldDirty","map","fileItem","dataURL","fileUrl","uploadResponse","type","fileId","fileName","name","shouldTouch","join","undefined","prev","updatedFiles","rawFile","errorMessage","ERROR_MESSAGES","UPLOAD","GENERIC","ERROR_GENERIC","generateThumbnail","fileType","includes","image","ImageHelper","dataUrlToImage","thumbnail","resampleImage","width","height","crop","FileHelper","fileToDataUrl","readFile","fileToRead","getType","fileTypeResult","validateFileType","fileSize","getFilesizeFromBase64","size","validateFileSize","ext","FILE_TYPE","ERROR_FORMAT","fileSizeInKb","maxSizeInKb","MAX_FILE_SIZE","ERROR_SIZE","fileToInject","INJECTING","blob","dataUrlToBlob","File","response","AxiosApiClient","responseType","get","mime","uploadData","isNaN","filesizeErrorMessage","thumbnailImageDataUrl","deduplicateFileName","progress","fileToParse","compressedFile","compressImageFile","sanitizeFileName","fileToUpload","UPLOADING","formData","FormData","append","slot","toString","post","url","headers","onUploadProgress","progressEvent","loaded","total","errorData","data","_file","i","fileToCompress","maxSizeInB","fileOrBlob","compressImage","Blob","blobToFile","lastModified"],"mappings":"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"}
1
+ {"version":3,"file":"file-upload-manager.72d3bd38.js","sources":["../../src/components/fields/file-upload/file-upload-manager.ts"],"sourcesContent":["import { AxiosError } from \"axios\";\nimport { useContext, useEffect, useRef } from \"react\";\nimport { useFormContext } from \"react-hook-form\";\nimport { AxiosApiClient, FileHelper, ImageHelper, generateRandomId } from \"../../../utils\";\nimport { useFieldEvent, usePrevious } from \"../../../utils/hooks\";\nimport { ERROR_MESSAGES } from \"../../shared\";\nimport { FileUploadContext } from \"./file-upload-context\";\nimport {\n\tEFileStatus,\n\tIFile,\n\tIFileUploadSchema,\n\tIFileUploadValidationRule,\n\tIFileUploadValue,\n\tTUploadErrorDetail,\n} from \"./types\";\n\ninterface IProps {\n\tcompressImages: boolean;\n\tfileTypeRule: IFileUploadValidationRule;\n\thideThumbnail?: boolean | undefined;\n\tid: string;\n\tmaxFileSizeRule: IFileUploadValidationRule;\n\tupload: IFileUploadSchema[\"uploadOnAddingFile\"];\n\tuploadRule: IFileUploadValidationRule;\n\tvalue: IFileUploadValue[];\n}\n\nconst RESIZEABLE_IMAGE_TYPES = [\"image/jpeg\", \"image/gif\", \"image/png\"];\n\nconst FileUploadManager = (props: IProps) => {\n\t// =============================================================================\n\t// CONST, STATE, REFS\n\t// =============================================================================\n\tconst { compressImages, fileTypeRule, hideThumbnail, id, maxFileSizeRule, upload, uploadRule, value } = props;\n\tconst { files, setFiles, setCurrentFileIds } = useContext(FileUploadContext);\n\tconst previousValue = usePrevious(value);\n\tconst { setValue } = useFormContext();\n\tconst { dispatchFieldEvent } = useFieldEvent();\n\tconst sessionId = useRef<string>();\n\n\t// =============================================================================\n\t// EFFECTS\n\t// =============================================================================\n\tuseEffect(() => {\n\t\tsessionId.current = generateRandomId();\n\t}, []);\n\n\tuseEffect(\n\t\t() => {\n\t\t\t// handle file status\n\t\t\tfiles.forEach(async (file, index) => {\n\t\t\t\ttry {\n\t\t\t\t\tswitch (file.status) {\n\t\t\t\t\t\tcase EFileStatus.INJECTED:\n\t\t\t\t\t\t\tawait injectFile(file, index);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EFileStatus.NONE:\n\t\t\t\t\t\t\tawait parseFile(file, index);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EFileStatus.UPLOAD_READY:\n\t\t\t\t\t\t\tawait uploadFile(file, index);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase EFileStatus.TO_DELETE:\n\t\t\t\t\t\t\tdeleteFile(index);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\thandleGenericError(index);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// track / update values\n\t\t\tconst uploadedFiles = files.filter(({ status }) => status === EFileStatus.UPLOADED);\n\t\t\tconst notPrefilledFiles = uploadedFiles.filter(({ addedFrom }) => addedFrom !== \"schema\");\n\t\t\tconst hasNotPrefilledFiles = notPrefilledFiles.length > 0;\n\t\t\tconst gotDeleteFiles = files.filter(({ status }) => status === EFileStatus.TO_DELETE).length > 0;\n\n\t\t\t/**\n\t\t\t * should dirty if\n\t\t\t * - it is dirty in the first place\n\t\t\t * - there are non-prefilled files\n\t\t\t * - user deleted file (differentiated from reset)\n\t\t\t */\n\t\t\tconst shouldDirty = hasNotPrefilledFiles || gotDeleteFiles;\n\n\t\t\tsetCurrentFileIds(uploadedFiles.map(({ fileItem }) => fileItem.id));\n\n\t\t\tsetValue(\n\t\t\t\tid,\n\t\t\t\tuploadedFiles.map(({ dataURL, fileItem, fileUrl, uploadResponse }) => ({\n\t\t\t\t\t...(upload.type === \"base64\" ? { dataURL } : {}),\n\t\t\t\t\tfileId: fileItem.id,\n\t\t\t\t\tfileName: fileItem.name,\n\t\t\t\t\tfileUrl,\n\t\t\t\t\tuploadResponse,\n\t\t\t\t})),\n\t\t\t\t{ shouldDirty, shouldTouch: hasNotPrefilledFiles }\n\t\t\t);\n\t\t}, // eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[files.map(({ fileItem, status }) => `${fileItem?.id}-${status}`).join(\",\")]\n\t);\n\n\t// for reset\n\tuseEffect(() => {\n\t\tif (previousValue !== undefined && value === undefined && files.length) {\n\t\t\tsetFiles([]);\n\t\t}\n\t}, [files, previousValue, setFiles, value]);\n\n\t// =============================================================================\n\t// HELPER FUNCTIONS\n\t// =============================================================================\n\n\tconst handleGenericError = (index: number) => {\n\t\tsetFiles((prev) => {\n\t\t\tconst updatedFiles = [...prev];\n\t\t\tconst file = prev[index];\n\t\t\tupdatedFiles[index] = {\n\t\t\t\t...file,\n\t\t\t\tfileItem: {\n\t\t\t\t\t...file.fileItem,\n\t\t\t\t\tid: file.fileItem?.id || generateRandomId(),\n\t\t\t\t\tname: file.rawFile.name,\n\t\t\t\t\terrorMessage: uploadRule?.errorMessage || ERROR_MESSAGES.UPLOAD().GENERIC,\n\t\t\t\t},\n\t\t\t\tstatus: EFileStatus.ERROR_GENERIC,\n\t\t\t};\n\t\t\treturn updatedFiles;\n\t\t});\n\t};\n\n\tconst generateThumbnail = async (file: IFile, fileType?: string | undefined) => {\n\t\tif (hideThumbnail !== true && RESIZEABLE_IMAGE_TYPES.includes(fileType || file.fileItem?.type)) {\n\t\t\tconst image = await ImageHelper.dataUrlToImage(file.dataURL);\n\t\t\tconst thumbnail = await ImageHelper.resampleImage(image, { width: 94, height: 94, crop: true });\n\t\t\treturn await FileHelper.fileToDataUrl(thumbnail);\n\t\t}\n\t\treturn \"\";\n\t};\n\n\tconst readFile = async (fileToRead: IFile) => {\n\t\tconst { addedFrom, dataURL, rawFile } = fileToRead;\n\t\tconst fileType = await FileHelper.getType(rawFile);\n\t\tconst fileTypeResult = validateFileType(fileType);\n\n\t\tif (fileTypeResult?.status < 0) {\n\t\t\treturn fileTypeResult;\n\t\t}\n\n\t\tconst fileSize = upload.type === \"base64\" ? FileHelper.getFilesizeFromBase64(dataURL) : rawFile.size;\n\t\tconst { errorMessage, status } = validateFileSize(fileSize);\n\t\tif (status < 0) {\n\t\t\treturn { errorMessage, fileType, status };\n\t\t}\n\n\t\tif (addedFrom === \"schema\") {\n\t\t\treturn {\n\t\t\t\tfileType,\n\t\t\t\tstatus: EFileStatus.UPLOADED,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tfileType,\n\t\t\tstatus: EFileStatus.UPLOAD_READY,\n\t\t};\n\t};\n\n\tconst validateFileType = (fileType: { mime: string; ext: string }) => {\n\t\tconst validFileType = fileTypeRule.fileType?.length ? fileTypeRule.fileType?.includes(fileType.ext) : true;\n\n\t\tif (!validFileType) {\n\t\t\treturn {\n\t\t\t\terrorMessage:\n\t\t\t\t\tfileTypeRule.errorMessage || ERROR_MESSAGES.UPLOAD().FILE_TYPE(fileTypeRule.fileType || []),\n\t\t\t\tfileType,\n\t\t\t\tstatus: EFileStatus.ERROR_FORMAT,\n\t\t\t};\n\t\t}\n\n\t\treturn {};\n\t};\n\n\tconst validateFileSize = (fileSizeInKb: number) => {\n\t\tif (maxFileSizeRule.maxSizeInKb > 0) {\n\t\t\tconst maxSizeInB = maxFileSizeRule.maxSizeInKb * 1024;\n\t\t\tif (fileSizeInKb > maxSizeInB) {\n\t\t\t\treturn {\n\t\t\t\t\terrorMessage:\n\t\t\t\t\t\tmaxFileSizeRule.errorMessage ||\n\t\t\t\t\t\tERROR_MESSAGES.UPLOAD().MAX_FILE_SIZE(maxFileSizeRule.maxSizeInKb),\n\t\t\t\t\tstatus: EFileStatus.ERROR_SIZE,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn {};\n\t};\n\n\t// =============================================================================\n\t// FILE STATUS HANDLERS\n\t// =============================================================================\n\tconst injectFile = async (fileToInject: IFile, index: number) => {\n\t\tsetFiles((prev) => {\n\t\t\tconst updatedFiles = [...prev];\n\t\t\tupdatedFiles[index] = {\n\t\t\t\t...prev[index],\n\t\t\t\tstatus: EFileStatus.INJECTING,\n\t\t\t};\n\t\t\treturn updatedFiles;\n\t\t});\n\n\t\tlet rawFile: File;\n\t\tif (fileToInject.dataURL) {\n\t\t\tconst blob = await FileHelper.dataUrlToBlob(fileToInject.dataURL);\n\t\t\trawFile = new File([blob], fileToInject.rawFile.name);\n\t\t} else if (fileToInject.fileUrl) {\n\t\t\tconst response: Blob = await new AxiosApiClient(\"\", undefined, undefined, false, {\n\t\t\t\tresponseType: \"blob\",\n\t\t\t}).get(fileToInject.fileUrl);\n\t\t\tconst fileType = await FileHelper.getType(new File([response], fileToInject.rawFile.name));\n\t\t\trawFile = new File([response], fileToInject.rawFile.name, { type: fileType.mime });\n\t\t\tfileToInject.dataURL = await FileHelper.fileToDataUrl(rawFile);\n\t\t}\n\n\t\t// rawFile may not be available because some use cases is not able to return dataURL / fileUrl due to security concerns\n\t\t// in such cases, we will rely on the uploadResponse for file info\n\t\tconst uploadData = fileToInject.uploadResponse?.[\"data\"] || fileToInject.uploadResponse;\n\t\tconst { errorMessage, fileType } = rawFile\n\t\t\t? await readFile({ ...fileToInject, rawFile })\n\t\t\t: validateFileType({\n\t\t\t\t\tmime: uploadData?.[\"mimeType\"],\n\t\t\t\t\text: uploadData?.[\"ext\"],\n\t\t\t });\n\n\t\tlet size = rawFile?.size || uploadData?.[\"fileSize\"] || 0;\n\t\tif (isNaN(size)) {\n\t\t\tsize = 0;\n\t\t}\n\t\tconst { errorMessage: filesizeErrorMessage } = validateFileSize(size);\n\n\t\tconst thumbnailImageDataUrl = rawFile ? await generateThumbnail(fileToInject, fileType?.mime) : undefined;\n\n\t\tsetFiles((prev) => {\n\t\t\tconst updatedFiles = [...prev];\n\t\t\tupdatedFiles[index] = {\n\t\t\t\t...fileToInject,\n\t\t\t\tfileItem: {\n\t\t\t\t\terrorMessage: errorMessage || filesizeErrorMessage,\n\t\t\t\t\tid: fileToInject.fileItem?.id || generateRandomId(),\n\t\t\t\t\tname: FileHelper.deduplicateFileName(\n\t\t\t\t\t\tfiles.map(({ fileItem }) => fileItem.name),\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\trawFile?.name || fileToInject.rawFile.name\n\t\t\t\t\t),\n\t\t\t\t\tprogress: 1,\n\t\t\t\t\tsize,\n\t\t\t\t\ttype: fileType?.mime || uploadData?.[\"mimeType\"],\n\t\t\t\t\tthumbnailImageDataUrl,\n\t\t\t\t},\n\t\t\t\trawFile,\n\t\t\t\tstatus: EFileStatus.UPLOADED,\n\t\t\t};\n\t\t\treturn updatedFiles;\n\t\t});\n\t};\n\n\tconst parseFile = async (fileToParse: IFile, index: number) => {\n\t\tconst compressedFile = await compressImageFile(fileToParse);\n\t\tconst dataURL = await FileHelper.fileToDataUrl(compressedFile.rawFile);\n\t\tconst { errorMessage, fileType, status } = await readFile({ dataURL, ...compressedFile });\n\n\t\tsetFiles((prev) => {\n\t\t\tconst updatedFiles = [...prev];\n\t\t\tupdatedFiles[index] = {\n\t\t\t\t...compressedFile,\n\t\t\t\tdataURL,\n\t\t\t\tfileItem: {\n\t\t\t\t\terrorMessage,\n\t\t\t\t\tid: generateRandomId(),\n\t\t\t\t\tname: FileHelper.deduplicateFileName(\n\t\t\t\t\t\tfiles.map(({ fileItem }) => fileItem?.name),\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\tFileHelper.sanitizeFileName(compressedFile.rawFile.name)\n\t\t\t\t\t),\n\t\t\t\t\tsize: compressedFile.rawFile.size,\n\t\t\t\t\ttype: fileType.mime,\n\t\t\t\t\tprogress: 0,\n\t\t\t\t},\n\t\t\t\tstatus,\n\t\t\t};\n\t\t\treturn updatedFiles;\n\t\t});\n\t};\n\n\tconst uploadFile = async (fileToUpload: IFile, index: number) => {\n\t\tsetFiles((prev) => {\n\t\t\tconst updatedFiles = [...prev];\n\t\t\tupdatedFiles[index] = {\n\t\t\t\t...prev[index],\n\t\t\t\tstatus: EFileStatus.UPLOADING,\n\t\t\t};\n\t\t\treturn updatedFiles;\n\t\t});\n\n\t\tconst formData = new FormData();\n\t\tformData.append(\"sessionId\", upload?.sessionId || sessionId.current || \"\");\n\t\tformData.append(\"fileId\", fileToUpload.fileItem.id);\n\t\tformData.append(\"slot\", fileToUpload.slot.toString());\n\t\tif (upload.type === \"base64\") {\n\t\t\tformData.append(\"dataURL\", fileToUpload.dataURL);\n\t\t} else if (upload.type === \"multipart\") {\n\t\t\tformData.append(\"file\", fileToUpload.rawFile, fileToUpload.fileItem?.name);\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await new AxiosApiClient(\"\", undefined, undefined, true).post(upload.url, formData, {\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": upload.type === \"base64\" ? \"application/json\" : \"multipart/form-data\",\n\t\t\t\t\t...upload.headers,\n\t\t\t\t},\n\t\t\t\tonUploadProgress: (progressEvent) => {\n\t\t\t\t\tconst { loaded, total } = progressEvent;\n\t\t\t\t\tsetFiles((prev) => {\n\t\t\t\t\t\tif (!prev[index]) return prev;\n\t\t\t\t\t\tconst updatedFiles = [...prev];\n\t\t\t\t\t\tupdatedFiles[index] = {\n\t\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\t\tfileItem: {\n\t\t\t\t\t\t\t\t...prev[index].fileItem,\n\t\t\t\t\t\t\t\tprogress: loaded / total,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\treturn updatedFiles;\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst thumbnailImageDataUrl = await generateThumbnail(fileToUpload);\n\t\t\tsetFiles((prev) => {\n\t\t\t\tif (!prev[index]) return prev;\n\t\t\t\tconst updatedFiles = [...prev];\n\t\t\t\tupdatedFiles[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tfileItem: {\n\t\t\t\t\t\t...prev[index].fileItem,\n\t\t\t\t\t\tprogress: 1,\n\t\t\t\t\t\tthumbnailImageDataUrl,\n\t\t\t\t\t},\n\t\t\t\t\tfileUrl: response?.[\"data\"]?.[\"fileUrl\"],\n\t\t\t\t\tstatus: EFileStatus.UPLOADED,\n\t\t\t\t\tuploadResponse: response,\n\t\t\t\t};\n\t\t\t\treturn updatedFiles;\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tdispatchFieldEvent<TUploadErrorDetail>(\"upload-error\", id, {\n\t\t\t\tfileId: fileToUpload.fileItem.id,\n\t\t\t\terrorData: (err as AxiosError)?.response?.data,\n\t\t\t});\n\n\t\t\tthrow err;\n\t\t}\n\t};\n\n\tconst deleteFile = (index: number) => {\n\t\tsetFiles((prev) => prev.filter((_file, i) => i !== index));\n\t};\n\n\tconst compressImageFile = async (fileToCompress: IFile) => {\n\t\tif (maxFileSizeRule.maxSizeInKb > 0 && compressImages) {\n\t\t\tconst maxSizeInB = maxFileSizeRule.maxSizeInKb * 1024;\n\t\t\tif (fileToCompress.rawFile.size > maxSizeInB) {\n\t\t\t\tconst fileType = await FileHelper.getType(fileToCompress.rawFile);\n\t\t\t\tif (RESIZEABLE_IMAGE_TYPES.includes(fileType.mime)) {\n\t\t\t\t\tlet fileOrBlob = await ImageHelper.compressImage(fileToCompress.rawFile, {\n\t\t\t\t\t\tfileSize: maxFileSizeRule.maxSizeInKb,\n\t\t\t\t\t});\n\t\t\t\t\tif (fileOrBlob instanceof Blob) {\n\t\t\t\t\t\tfileOrBlob = FileHelper.blobToFile(fileOrBlob, {\n\t\t\t\t\t\t\tname: fileToCompress.rawFile.name,\n\t\t\t\t\t\t\tlastModified: fileToCompress.rawFile.lastModified,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...fileToCompress,\n\t\t\t\t\t\trawFile: fileOrBlob,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn fileToCompress;\n\t};\n\n\t// =============================================================================\n\t// RENDER FUNCTIONS\n\t// =============================================================================\n\treturn null;\n};\n\nexport default FileUploadManager;\n"],"names":["RESIZEABLE_IMAGE_TYPES","FileUploadManager","props","compressImages","fileTypeRule","hideThumbnail","id","maxFileSizeRule","upload","uploadRule","value","files","setFiles","setCurrentFileIds","useContext","FileUploadContext","previousValue","usePrevious","setValue","useFormContext","dispatchFieldEvent","useFieldEvent","sessionId","useRef","useEffect","current","generateRandomId","forEach","async","file","index","status","EFileStatus","INJECTED","injectFile","NONE","parseFile","UPLOAD_READY","uploadFile","TO_DELETE","deleteFile","err","handleGenericError","uploadedFiles","filter","UPLOADED","hasNotPrefilledFiles","addedFrom","length","gotDeleteFiles","shouldDirty","map","fileItem","dataURL","fileUrl","uploadResponse","type","fileId","fileName","name","shouldTouch","join","undefined","prev","updatedFiles","rawFile","errorMessage","ERROR_MESSAGES","UPLOAD","GENERIC","ERROR_GENERIC","generateThumbnail","fileType","includes","image","ImageHelper","dataUrlToImage","thumbnail","resampleImage","width","height","crop","FileHelper","fileToDataUrl","readFile","fileToRead","getType","fileTypeResult","validateFileType","fileSize","getFilesizeFromBase64","size","validateFileSize","ext","FILE_TYPE","ERROR_FORMAT","fileSizeInKb","maxSizeInKb","MAX_FILE_SIZE","ERROR_SIZE","fileToInject","INJECTING","blob","dataUrlToBlob","File","response","AxiosApiClient","responseType","get","mime","uploadData","isNaN","filesizeErrorMessage","thumbnailImageDataUrl","deduplicateFileName","progress","fileToParse","compressedFile","compressImageFile","sanitizeFileName","fileToUpload","UPLOADING","formData","FormData","append","slot","toString","post","url","headers","onUploadProgress","progressEvent","loaded","total","errorData","data","_file","i","fileToCompress","maxSizeInB","fileOrBlob","compressImage","Blob","blobToFile","lastModified"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{useContext as t,useRef as e,useEffect as s}from"react";import{e as a,u as i,a as r,b as o,g as n,f as c,d as l,I as m,A as d}from"./index.cb4c93a5.js";import"react/jsx-runtime";import"@lifesg/react-design-system/theme";import"styled-components";import"@lifesg/react-design-system/typography";import"@lifesg/react-design-system/button";import"@lifesg/react-design-system/modal";import"@lifesg/react-design-system/markup";import"react-dom/server";import"@lifesg/react-design-system/alert";import"@lifesg/react-design-system/layout";import"@lifesg/react-design-system/box-container";import"@lifesg/react-design-system/divider";import"@lifesg/react-design-system/v2_media";import"@lifesg/react-design-system/text-list";import"@lifesg/react-design-system/popover-v2";import"@lifesg/react-icons";import"@lifesg/react-design-system/tab";import"@lifesg/react-icons/plus-circle-fill";import"@lifesg/react-design-system/button-with-icon";import"@lifesg/react-design-system/error-display";import"@lifesg/react-design-system/filter";import"@lifesg/react-design-system/uneditable-section";import"@lifesg/react-design-system/timeline";import"@lifesg/react-design-system/form";import"@lifesg/react-design-system/checkbox";import"@lifesg/react-design-system/toggle";import"@lifesg/react-design-system/file-upload";import"@lifesg/react-icons/cross";import"@lifesg/react-design-system/icon-button";import"@lifesg/react-icons/bin";import"@lifesg/react-icons/eraser";import"@lifesg/react-icons/pencil";import"@lifesg/react-icons/pencil-stroke";import"@lifesg/react-icons/plus";import"@lifesg/react-icons/exclamation-triangle";import"@lifesg/react-icons/pin-fill";import"@lifesg/react-design-system/image-button";import"@lifesg/react-design-system/radio-button";import"@lifesg/react-design-system/v2_layout";const g=g=>{const{accepts:p,compress:u,crop:f,dimensions:E,editImage:R,id:h,maxSizeInKb:y,outputType:D,upload:w,value:O}=g,{images:U,setImages:I,setErrorCount:T,setCurrentFileIds:L}=t(a),b=i(U),_=i(O),{setValue:v}=r(),S=e(),M=e(0),{dispatchFieldEvent:N,addFieldEventListener:C,removeFieldEventListener:P}=o();s((()=>{const t=t=>{I((e=>{const s=e.findIndex((e=>e.id===t.detail.id)),a={...e[s]};a.status=t.detail.updatedStatus,a.customErrorMessage=t.detail.errorMessage;const i=[...e];return i.splice(s,1,a),i}))};return C("update-image-status",h,t),()=>P("update-image-status",h,t)}),[C,h,P,I]),s((()=>{S.current=n()}),[]),s((()=>{U.forEach(((t,e)=>{const s=b?.[e];if(t.status!==s?.status||t.dataURL!==s.dataURL)switch(t.status){case c.INJECTED:l.dataUrlToBlob(t.dataURL).then((s=>{I((a=>{const i=[...a];return i[e]={...t,file:new File([s],t.name),status:c.NONE},i}))})).catch((()=>{I((t=>t.filter(((t,s)=>s!==e))))}));break;case c.NONE:l.getType(t.file).then((s=>{const a=s.mime;a&&p.map(l.fileExtensionToMimeType).includes(a)?(I((s=>{const i=[...s];return i[e]={...t,name:l.deduplicateFileName(U.map((({name:t})=>t)),e,l.sanitizeFileName(t.name)),type:a,status:"schema"!==t.addedFrom?t.status:c.UPLOADED},i})),"schema"!==t.addedFrom&&(u?A(e,t):F(e,t))):I((s=>{const a=[...s];return a[e]={...t,status:c.ERROR_FORMAT},a}))}));break;case c.TO_RECOMPRESS:k(e,t);break;case c.COMPRESSED:case c.CONVERTED:case c.RECOMPRESSED:if(!R){const s=!N("upload-ready",h,{imageData:t});I((t=>{const a=[...t];return a[e]={...a[e],status:s?c.PENDING:c.UPLOAD_READY},a}))}break;case c.UPLOAD_READY:z(e,t);break;case c.TO_DELETE:I((t=>t.filter((({status:t})=>t!==c.TO_DELETE))));break;case c.UPLOADED:N("uploaded",h,{imageData:t})}}))}),[U.map((({status:t})=>t)).join(","),U.map((({dataURL:t})=>t)).join(",")]),s((()=>{let t=0;U.forEach((e=>{(e.type&&!p.map(l.fileExtensionToMimeType).includes(e.type)||[c.ERROR_GENERIC,c.ERROR_SIZE].includes(e.status))&&t++})),T((e=>Math.max(0,e+t-M.current))),M.current=t;const e=U.filter((({status:t})=>t===c.UPLOADED||t===c.ERROR_CUSTOM_MUTED)),s=e.filter((({addedFrom:t})=>"schema"!==t)),a=U.filter((({status:t})=>t===c.TO_DELETE)).length>0,i=s.length>0,r=i||a;L(e.map((({id:t})=>t))),v(h,e.map((({id:t,dataURL:e,drawingDataURL:s,name:a,metadata:i,uploadResponse:r})=>({fileId:t,fileName:a,dataURL:s||e,metadata:i,uploadResponse:r}))),{shouldDirty:r,shouldTouch:i})}),[p,h,U,T,v]),s((()=>{void 0!==_&&void 0===O&&U.length&&I([])}),[void 0===_,void 0===O,U.length]);const x=(t,e)=>{let s=E.width/t;return e*s>E.height&&(s=E.height/e),s},F=async(t,e)=>{try{const s=await m.convertBlob(e.file,l.fileExtensionToMimeType(D)),a=l.getFilesizeFromBase64(s);if(y&&a>1024*y)I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_SIZE},s}));else{const a=await m.getMetadata(e.file);I((e=>{const i=[...e];return i[t]={...e[t],dataURL:s,metadata:a,status:c.CONVERTED},i}))}}catch(e){I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_GENERIC},s}))}},A=async(t,e)=>{try{const s=await m.convertBlob(e.file,l.fileExtensionToMimeType(D)),a=await m.dataUrlToImage(s),i={w:a.naturalWidth,h:a.naturalHeight};let r;if(f)r=await m.resampleImage(a,{width:E.width,height:E.height,crop:!0});else{const t=x(i.w,i.h);r=await m.resampleImage(a,{scale:t})}if(y&&(r=await m.compressImage(r,{fileSize:y})),y&&r.size>1024*y)I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_SIZE},s}));else{const s=await m.getMetadata(e.file),a=await l.fileToDataUrl(r);I((e=>{const i=[...e];return i[t]={...e[t],dataURL:a,metadata:s,status:c.COMPRESSED},i}))}}catch(e){I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_GENERIC},s}))}},k=async(t,e)=>{if(e.drawingDataURL)try{const s=await m.dataUrlToImage(e.drawingDataURL),a={w:s.naturalWidth,h:s.naturalHeight};let i;if(f)i=await m.resampleImage(s,{width:E.width,height:E.height,crop:!0});else{const t=x(a.w,a.h);i=await m.resampleImage(s,{scale:t})}if(i=await m.compressImage(i,{fileSize:y}),i.size>1024*y){const e=[...U];e[t]={...U[t],status:c.ERROR_SIZE},I(e)}else{const e=await l.fileToDataUrl(i),s=[...U];s[t]={...U[t],drawingDataURL:e,status:c.RECOMPRESSED},I(s)}}catch(e){I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_GENERIC},s}))}},z=async(t,e)=>{try{let s;if(I((e=>{const s=[...e];return s[t]={...e[t],status:c.UPLOADING},s})),w?.method&&w?.url){const a=new FormData;a.append("dataURL",e.drawingDataURL||e.dataURL||""),a.append("sessionId",w?.sessionId||S.current||""),a.append("slot",`${e.slot}`),s=await new d("",void 0,void 0,!0)[w.method](w.url,a,{onUploadProgress:e=>{const{loaded:s,total:a}=e,i=Math.floor(100*s/a);I((e=>{const s=[...e];return s[t]={...e[t],uploadProgress:i},s}))}})}I((e=>{const a=[...e];return a[t]={...e[t],uploadResponse:s,status:c.UPLOADED},a}))}catch(e){I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_GENERIC},s}))}};return null};export{g as default};
2
- //# sourceMappingURL=index.dcdbe23e.js.map
1
+ import{useContext as t,useRef as e,useEffect as s}from"react";import{e as a,u as i,a as r,b as o,g as n,f as c,d as l,I as m,A as d}from"./index.51b5c59f.js";import"react/jsx-runtime";import"@lifesg/react-design-system/theme";import"styled-components";import"@lifesg/react-design-system/typography";import"@lifesg/react-design-system/button";import"@lifesg/react-design-system/modal";import"@lifesg/react-design-system/markup";import"react-dom/server";import"@lifesg/react-design-system/alert";import"@lifesg/react-design-system/layout";import"@lifesg/react-design-system/box-container";import"@lifesg/react-design-system/divider";import"@lifesg/react-design-system/v2_media";import"@lifesg/react-design-system/text-list";import"@lifesg/react-design-system/popover-v2";import"@lifesg/react-icons";import"@lifesg/react-design-system/tab";import"@lifesg/react-icons/plus-circle-fill";import"@lifesg/react-design-system/button-with-icon";import"@lifesg/react-design-system/error-display";import"@lifesg/react-design-system/filter";import"@lifesg/react-design-system/uneditable-section";import"@lifesg/react-design-system/timeline";import"@lifesg/react-design-system/form";import"@lifesg/react-design-system/checkbox";import"@lifesg/react-design-system/toggle";import"@lifesg/react-design-system/file-upload";import"@lifesg/react-icons/cross";import"@lifesg/react-design-system/icon-button";import"@lifesg/react-icons/bin";import"@lifesg/react-icons/eraser";import"@lifesg/react-icons/pencil";import"@lifesg/react-icons/pencil-stroke";import"@lifesg/react-icons/plus";import"@lifesg/react-icons/exclamation-triangle";import"@lifesg/react-icons/pin-fill";import"@lifesg/react-design-system/image-button";import"@lifesg/react-design-system/radio-button";import"@lifesg/react-design-system/v2_layout";const g=g=>{const{accepts:p,compress:u,crop:f,dimensions:E,editImage:R,id:h,maxSizeInKb:y,outputType:D,upload:w,value:O}=g,{images:U,setImages:I,setErrorCount:T,setCurrentFileIds:L}=t(a),b=i(U),_=i(O),{setValue:v}=r(),S=e(),M=e(0),{dispatchFieldEvent:N,addFieldEventListener:C,removeFieldEventListener:P}=o();s((()=>{const t=t=>{I((e=>{const s=e.findIndex((e=>e.id===t.detail.id)),a={...e[s]};a.status=t.detail.updatedStatus,a.customErrorMessage=t.detail.errorMessage;const i=[...e];return i.splice(s,1,a),i}))};return C("update-image-status",h,t),()=>P("update-image-status",h,t)}),[C,h,P,I]),s((()=>{S.current=n()}),[]),s((()=>{U.forEach(((t,e)=>{const s=b?.[e];if(t.status!==s?.status||t.dataURL!==s.dataURL)switch(t.status){case c.INJECTED:l.dataUrlToBlob(t.dataURL).then((s=>{I((a=>{const i=[...a];return i[e]={...t,file:new File([s],t.name),status:c.NONE},i}))})).catch((()=>{I((t=>t.filter(((t,s)=>s!==e))))}));break;case c.NONE:l.getType(t.file).then((s=>{const a=s.mime;a&&p.map(l.fileExtensionToMimeType).includes(a)?(I((s=>{const i=[...s];return i[e]={...t,name:l.deduplicateFileName(U.map((({name:t})=>t)),e,l.sanitizeFileName(t.name)),type:a,status:"schema"!==t.addedFrom?t.status:c.UPLOADED},i})),"schema"!==t.addedFrom&&(u?A(e,t):F(e,t))):I((s=>{const a=[...s];return a[e]={...t,status:c.ERROR_FORMAT},a}))}));break;case c.TO_RECOMPRESS:k(e,t);break;case c.COMPRESSED:case c.CONVERTED:case c.RECOMPRESSED:if(!R){const s=!N("upload-ready",h,{imageData:t});I((t=>{const a=[...t];return a[e]={...a[e],status:s?c.PENDING:c.UPLOAD_READY},a}))}break;case c.UPLOAD_READY:z(e,t);break;case c.TO_DELETE:I((t=>t.filter((({status:t})=>t!==c.TO_DELETE))));break;case c.UPLOADED:N("uploaded",h,{imageData:t})}}))}),[U.map((({status:t})=>t)).join(","),U.map((({dataURL:t})=>t)).join(",")]),s((()=>{let t=0;U.forEach((e=>{(e.type&&!p.map(l.fileExtensionToMimeType).includes(e.type)||[c.ERROR_GENERIC,c.ERROR_SIZE].includes(e.status))&&t++})),T((e=>Math.max(0,e+t-M.current))),M.current=t;const e=U.filter((({status:t})=>t===c.UPLOADED||t===c.ERROR_CUSTOM_MUTED)),s=e.filter((({addedFrom:t})=>"schema"!==t)),a=U.filter((({status:t})=>t===c.TO_DELETE)).length>0,i=s.length>0,r=i||a;L(e.map((({id:t})=>t))),v(h,e.map((({id:t,dataURL:e,drawingDataURL:s,name:a,metadata:i,uploadResponse:r})=>({fileId:t,fileName:a,dataURL:s||e,metadata:i,uploadResponse:r}))),{shouldDirty:r,shouldTouch:i})}),[p,h,U,T,v]),s((()=>{void 0!==_&&void 0===O&&U.length&&I([])}),[void 0===_,void 0===O,U.length]);const x=(t,e)=>{let s=E.width/t;return e*s>E.height&&(s=E.height/e),s},F=async(t,e)=>{try{const s=await m.convertBlob(e.file,l.fileExtensionToMimeType(D)),a=l.getFilesizeFromBase64(s);if(y&&a>1024*y)I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_SIZE},s}));else{const a=await m.getMetadata(e.file);I((e=>{const i=[...e];return i[t]={...e[t],dataURL:s,metadata:a,status:c.CONVERTED},i}))}}catch(e){I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_GENERIC},s}))}},A=async(t,e)=>{try{const s=await m.convertBlob(e.file,l.fileExtensionToMimeType(D)),a=await m.dataUrlToImage(s),i={w:a.naturalWidth,h:a.naturalHeight};let r;if(f)r=await m.resampleImage(a,{width:E.width,height:E.height,crop:!0});else{const t=x(i.w,i.h);r=await m.resampleImage(a,{scale:t})}if(y&&(r=await m.compressImage(r,{fileSize:y})),y&&r.size>1024*y)I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_SIZE},s}));else{const s=await m.getMetadata(e.file),a=await l.fileToDataUrl(r);I((e=>{const i=[...e];return i[t]={...e[t],dataURL:a,metadata:s,status:c.COMPRESSED},i}))}}catch(e){I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_GENERIC},s}))}},k=async(t,e)=>{if(e.drawingDataURL)try{const s=await m.dataUrlToImage(e.drawingDataURL),a={w:s.naturalWidth,h:s.naturalHeight};let i;if(f)i=await m.resampleImage(s,{width:E.width,height:E.height,crop:!0});else{const t=x(a.w,a.h);i=await m.resampleImage(s,{scale:t})}if(i=await m.compressImage(i,{fileSize:y}),i.size>1024*y){const e=[...U];e[t]={...U[t],status:c.ERROR_SIZE},I(e)}else{const e=await l.fileToDataUrl(i),s=[...U];s[t]={...U[t],drawingDataURL:e,status:c.RECOMPRESSED},I(s)}}catch(e){I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_GENERIC},s}))}},z=async(t,e)=>{try{let s;if(I((e=>{const s=[...e];return s[t]={...e[t],status:c.UPLOADING},s})),w?.method&&w?.url){const a=new FormData;a.append("dataURL",e.drawingDataURL||e.dataURL||""),a.append("sessionId",w?.sessionId||S.current||""),a.append("slot",`${e.slot}`),s=await new d("",void 0,void 0,!0)[w.method](w.url,a,{onUploadProgress:e=>{const{loaded:s,total:a}=e,i=Math.floor(100*s/a);I((e=>{const s=[...e];return s[t]={...e[t],uploadProgress:i},s}))}})}I((e=>{const a=[...e];return a[t]={...e[t],uploadResponse:s,status:c.UPLOADED},a}))}catch(e){I((e=>{const s=[...e];return s[t]={...e[t],status:c.ERROR_GENERIC},s}))}};return null};export{g as default};
2
+ //# sourceMappingURL=index.1d69a8ce.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.dcdbe23e.js","sources":["../../src/components/fields/image-upload/image-manager/image-manager.ts"],"sourcesContent":["import { useContext, useEffect, useRef } from \"react\";\nimport { useFormContext } from \"react-hook-form\";\nimport { AxiosApiClient, FileHelper, ImageHelper, generateRandomId } from \"../../../../utils\";\nimport { useFieldEvent, usePrevious } from \"../../../../utils/hooks\";\nimport { ImageContext } from \"../image-context\";\nimport {\n\tEImageStatus,\n\tIImage,\n\tISharedImageProps,\n\tIUpdateImageStatus,\n\tTImageUploadOutputFileType,\n\tTUploadMethod,\n} from \"../types\";\n\ninterface IProps extends Omit<ISharedImageProps, \"maxFiles\"> {\n\teditImage: boolean;\n\tcompress: boolean;\n\tcrop: boolean;\n\tdimensions: { width: number; height: number };\n\toutputType: TImageUploadOutputFileType;\n\tupload?: {\n\t\tmethod: TUploadMethod;\n\t\turl: string;\n\t\tsessionId?: string | undefined;\n\t};\n\tvalue: any;\n}\n\n/**\n * manages selected images by listening to images from context provider\n * rename / compress / upload\n */\nexport const ImageManager = (props: IProps) => {\n\t// =============================================================================\n\t// CONST, STATE, REFS\n\t// =============================================================================\n\tconst { accepts, compress, crop, dimensions, editImage, id, maxSizeInKb, outputType, upload, value } = props;\n\tconst { images, setImages, setErrorCount, setCurrentFileIds } = useContext(ImageContext);\n\tconst previousImages = usePrevious(images);\n\tconst previousValue = usePrevious(value);\n\tconst { setValue } = useFormContext();\n\tconst sessionId = useRef<string>();\n\tconst managerErrorCount = useRef(0);\n\n\tconst { dispatchFieldEvent, addFieldEventListener, removeFieldEventListener } = useFieldEvent();\n\n\t// =============================================================================\n\t// EFFECTS\n\t// =============================================================================\n\tuseEffect(() => {\n\t\tconst handleUpdateImageStatus = (e: CustomEvent<IUpdateImageStatus>) => {\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst imageIndex = prev.findIndex((image) => image.id === e.detail.id);\n\t\t\t\tconst updatedImage = { ...prev[imageIndex] };\n\t\t\t\tupdatedImage.status = e.detail.updatedStatus;\n\t\t\t\tupdatedImage.customErrorMessage = e.detail.errorMessage;\n\n\t\t\t\tconst newImages = [...prev];\n\t\t\t\tnewImages.splice(imageIndex, 1, updatedImage);\n\t\t\t\treturn newImages;\n\t\t\t});\n\t\t};\n\n\t\taddFieldEventListener(\"update-image-status\", id, handleUpdateImageStatus);\n\t\treturn () => removeFieldEventListener(\"update-image-status\", id, handleUpdateImageStatus);\n\t}, [addFieldEventListener, id, removeFieldEventListener, setImages]);\n\n\t// generate pseudo-random session id\n\tuseEffect(() => {\n\t\tsessionId.current = generateRandomId();\n\t}, []);\n\n\tuseEffect(() => {\n\t\timages.forEach((image, index) => {\n\t\t\tconst previousFile = previousImages?.[index];\n\t\t\tif (image.status !== previousFile?.status || image.dataURL !== previousFile.dataURL) {\n\t\t\t\tswitch (image.status) {\n\t\t\t\t\tcase EImageStatus.INJECTED:\n\t\t\t\t\t\tFileHelper.dataUrlToBlob(image.dataURL)\n\t\t\t\t\t\t\t.then((blob) => {\n\t\t\t\t\t\t\t\tsetImages((prev) => {\n\t\t\t\t\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\tfile: new File([blob], image.name),\n\t\t\t\t\t\t\t\t\t\tstatus: EImageStatus.NONE,\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\treturn updatedImages;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\t\t\tsetImages((prev) => prev.filter((prev, i) => i !== index));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.NONE:\n\t\t\t\t\t\tFileHelper.getType(image.file).then((fileType) => {\n\t\t\t\t\t\t\tconst mimeType = fileType.mime;\n\t\t\t\t\t\t\tif (mimeType && accepts.map(FileHelper.fileExtensionToMimeType).includes(mimeType)) {\n\t\t\t\t\t\t\t\tsetImages((prev) => {\n\t\t\t\t\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\tname: FileHelper.deduplicateFileName(\n\t\t\t\t\t\t\t\t\t\t\timages.map(({ name }) => name),\n\t\t\t\t\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t\t\t\t\t\tFileHelper.sanitizeFileName(image.name)\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\ttype: mimeType,\n\t\t\t\t\t\t\t\t\t\tstatus: image.addedFrom !== \"schema\" ? image.status : EImageStatus.UPLOADED,\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\treturn updatedImages;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tif (image.addedFrom !== \"schema\") {\n\t\t\t\t\t\t\t\t\tcompress ? compressImage(index, image) : convertImage(index, image);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsetImages((prev) => {\n\t\t\t\t\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\tstatus: EImageStatus.ERROR_FORMAT,\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\treturn updatedImages;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.TO_RECOMPRESS:\n\t\t\t\t\t\trecompressImage(index, image);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.COMPRESSED:\n\t\t\t\t\tcase EImageStatus.CONVERTED:\n\t\t\t\t\tcase EImageStatus.RECOMPRESSED:\n\t\t\t\t\t\tif (!editImage) {\n\t\t\t\t\t\t\tconst shouldPreventDefault = !dispatchFieldEvent(\"upload-ready\", id, { imageData: image });\n\n\t\t\t\t\t\t\tsetImages((prev) => {\n\t\t\t\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t\t\t\t...updatedImages[index],\n\t\t\t\t\t\t\t\t\tstatus: shouldPreventDefault ? EImageStatus.PENDING : EImageStatus.UPLOAD_READY,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\treturn updatedImages;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.UPLOAD_READY:\n\t\t\t\t\t\tuploadImage(index, image);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.TO_DELETE:\n\t\t\t\t\t\tsetImages((prev) => prev.filter(({ status }) => status !== EImageStatus.TO_DELETE));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.UPLOADED:\n\t\t\t\t\t\tdispatchFieldEvent(\"uploaded\", id, { imageData: image });\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [images.map(({ status }) => status).join(\",\"), images.map(({ dataURL }) => dataURL).join(\",\")]);\n\n\t// track / update errors and values\n\tuseEffect(() => {\n\t\tlet updatedManagerErrorCount = 0;\n\t\timages.forEach((image) => {\n\t\t\tif (\n\t\t\t\t(image.type && !accepts.map(FileHelper.fileExtensionToMimeType).includes(image.type)) ||\n\t\t\t\t[EImageStatus.ERROR_GENERIC, EImageStatus.ERROR_SIZE].includes(image.status)\n\t\t\t) {\n\t\t\t\tupdatedManagerErrorCount++;\n\t\t\t}\n\t\t});\n\t\tsetErrorCount((prev) => Math.max(0, prev + updatedManagerErrorCount - managerErrorCount.current));\n\t\tmanagerErrorCount.current = updatedManagerErrorCount;\n\n\t\tconst uploadedImages = images.filter(\n\t\t\t({ status }) => status === EImageStatus.UPLOADED || status === EImageStatus.ERROR_CUSTOM_MUTED\n\t\t);\n\t\tconst notPrefilledImages = uploadedImages.filter(({ addedFrom }) => addedFrom !== \"schema\");\n\t\tconst gotDeleteImages = images.filter(({ status }) => status === EImageStatus.TO_DELETE).length > 0;\n\n\t\t/**\n\t\t * should dirty if\n\t\t * - it is dirty in the first place\n\t\t * - there are non-prefilled images\n\t\t * - user deleted image (differentiated from reset)\n\t\t */\n\t\tconst hasNotPrefilledImages = notPrefilledImages.length > 0;\n\t\tconst shouldDirty = hasNotPrefilledImages || gotDeleteImages;\n\n\t\tsetCurrentFileIds(uploadedImages.map(({ id }) => id));\n\n\t\tsetValue(\n\t\t\tid,\n\t\t\tuploadedImages.map(({ id, dataURL, drawingDataURL, name, metadata, uploadResponse }) => ({\n\t\t\t\tfileId: id,\n\t\t\t\tfileName: name,\n\t\t\t\tdataURL: drawingDataURL || dataURL,\n\t\t\t\tmetadata,\n\t\t\t\tuploadResponse,\n\t\t\t})),\n\t\t\t{ shouldDirty, shouldTouch: hasNotPrefilledImages }\n\t\t);\n\t}, [accepts, id, images, setErrorCount, setValue]);\n\n\tuseEffect(() => {\n\t\tif (previousValue !== undefined && value === undefined && images.length) {\n\t\t\tsetImages([]);\n\t\t}\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [previousValue === undefined, value === undefined, images.length]);\n\n\t// =============================================================================\n\t// HELPER FUNCTIONS\n\t// =============================================================================\n\tconst getScale = (origWidth: number, origHeight: number): number => {\n\t\tlet scale = dimensions.width / origWidth;\n\t\tif (origHeight * scale > dimensions.height) {\n\t\t\tscale = dimensions.height / origHeight;\n\t\t}\n\t\treturn scale;\n\t};\n\n\tconst convertImage = async (index: number, image: IImage) => {\n\t\ttry {\n\t\t\tconst dataURL = await ImageHelper.convertBlob(image.file, FileHelper.fileExtensionToMimeType(outputType));\n\t\t\tconst filesize = FileHelper.getFilesizeFromBase64(dataURL);\n\n\t\t\tif (maxSizeInKb && filesize > maxSizeInKb * 1024) {\n\t\t\t\tsetImages((prev) => {\n\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\tstatus: EImageStatus.ERROR_SIZE,\n\t\t\t\t\t};\n\t\t\t\t\treturn updatedImages;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst metadata = await ImageHelper.getMetadata(image.file);\n\t\t\t\tsetImages((prev) => {\n\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\tdataURL,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\tstatus: EImageStatus.CONVERTED,\n\t\t\t\t\t};\n\t\t\t\t\treturn updatedImages;\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tstatus: EImageStatus.ERROR_GENERIC,\n\t\t\t\t};\n\t\t\t\treturn updatedImages;\n\t\t\t});\n\t\t}\n\t};\n\n\tconst compressImage = async (index: number, imageToCompress: IImage) => {\n\t\ttry {\n\t\t\tconst dataURL = await ImageHelper.convertBlob(\n\t\t\t\timageToCompress.file,\n\t\t\t\tFileHelper.fileExtensionToMimeType(outputType)\n\t\t\t);\n\t\t\tconst image = await ImageHelper.dataUrlToImage(dataURL);\n\t\t\tconst origDim = { w: image.naturalWidth, h: image.naturalHeight };\n\t\t\tlet compressed: Blob;\n\t\t\tif (crop) {\n\t\t\t\tcompressed = await ImageHelper.resampleImage(image, {\n\t\t\t\t\twidth: dimensions.width,\n\t\t\t\t\theight: dimensions.height,\n\t\t\t\t\tcrop: true,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst scale = getScale(origDim.w, origDim.h);\n\t\t\t\tcompressed = await ImageHelper.resampleImage(image, { scale });\n\t\t\t}\n\t\t\tif (maxSizeInKb) {\n\t\t\t\tcompressed = (await ImageHelper.compressImage(compressed, {\n\t\t\t\t\tfileSize: maxSizeInKb,\n\t\t\t\t})) as File;\n\t\t\t}\n\n\t\t\tif (maxSizeInKb && compressed.size > maxSizeInKb * 1024) {\n\t\t\t\tsetImages((prev) => {\n\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\tstatus: EImageStatus.ERROR_SIZE,\n\t\t\t\t\t};\n\t\t\t\t\treturn updatedImages;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst metadata = await ImageHelper.getMetadata(imageToCompress.file);\n\t\t\t\tconst dataURL = await FileHelper.fileToDataUrl(compressed);\n\t\t\t\tsetImages((prev) => {\n\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\tdataURL,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\tstatus: EImageStatus.COMPRESSED,\n\t\t\t\t\t};\n\t\t\t\t\treturn updatedImages;\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tstatus: EImageStatus.ERROR_GENERIC,\n\t\t\t\t};\n\t\t\t\treturn updatedImages;\n\t\t\t});\n\t\t}\n\t};\n\n\tconst recompressImage = async (index: number, imageToCompress: IImage) => {\n\t\tif (imageToCompress.drawingDataURL) {\n\t\t\ttry {\n\t\t\t\tconst image = await ImageHelper.dataUrlToImage(imageToCompress.drawingDataURL);\n\t\t\t\tconst origDim = { w: image.naturalWidth, h: image.naturalHeight };\n\t\t\t\tlet scaledFile: Blob;\n\t\t\t\tif (crop) {\n\t\t\t\t\tscaledFile = await ImageHelper.resampleImage(image, {\n\t\t\t\t\t\twidth: dimensions.width,\n\t\t\t\t\t\theight: dimensions.height,\n\t\t\t\t\t\tcrop: true,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconst scale = getScale(origDim.w, origDim.h);\n\t\t\t\t\tscaledFile = await ImageHelper.resampleImage(image, { scale });\n\t\t\t\t}\n\t\t\t\tscaledFile = (await ImageHelper.compressImage(scaledFile, { fileSize: maxSizeInKb })) as File;\n\n\t\t\t\tif (scaledFile.size > maxSizeInKb * 1024) {\n\t\t\t\t\tconst updatedImages = [...images];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...images[index],\n\t\t\t\t\t\tstatus: EImageStatus.ERROR_SIZE,\n\t\t\t\t\t};\n\t\t\t\t\tsetImages(updatedImages);\n\t\t\t\t} else {\n\t\t\t\t\tconst dataURL = await FileHelper.fileToDataUrl(scaledFile);\n\t\t\t\t\tconst updatedImages = [...images];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...images[index],\n\t\t\t\t\t\tdrawingDataURL: dataURL,\n\t\t\t\t\t\tstatus: EImageStatus.RECOMPRESSED,\n\t\t\t\t\t};\n\t\t\t\t\tsetImages(updatedImages);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tsetImages((prev) => {\n\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\tstatus: EImageStatus.ERROR_GENERIC,\n\t\t\t\t\t};\n\t\t\t\t\treturn updatedImages;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\n\tconst uploadImage = async (index: number, iFile: IImage) => {\n\t\ttry {\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tstatus: EImageStatus.UPLOADING,\n\t\t\t\t};\n\t\t\t\treturn updatedImages;\n\t\t\t});\n\n\t\t\tlet response: unknown;\n\t\t\tif (upload?.method && upload?.url) {\n\t\t\t\tconst formData = new FormData();\n\t\t\t\tformData.append(\"dataURL\", iFile.drawingDataURL || iFile.dataURL || \"\");\n\t\t\t\tformData.append(\"sessionId\", upload?.sessionId || sessionId.current || \"\");\n\t\t\t\tformData.append(\"slot\", `${iFile.slot}`);\n\t\t\t\tresponse = await new AxiosApiClient(\"\", undefined, undefined, true)[upload.method](\n\t\t\t\t\tupload.url,\n\t\t\t\t\tformData,\n\t\t\t\t\t{\n\t\t\t\t\t\tonUploadProgress: (progressEvent) => {\n\t\t\t\t\t\t\tconst { loaded, total } = progressEvent;\n\t\t\t\t\t\t\tconst percent = Math.floor((loaded * 100) / total);\n\t\t\t\t\t\t\tsetImages((prev) => {\n\t\t\t\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\t\t\t\tuploadProgress: percent,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\treturn updatedImages;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tuploadResponse: response,\n\t\t\t\t\tstatus: EImageStatus.UPLOADED,\n\t\t\t\t};\n\t\t\t\treturn updatedImages;\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tstatus: EImageStatus.ERROR_GENERIC,\n\t\t\t\t};\n\t\t\t\treturn updatedImages;\n\t\t\t});\n\t\t}\n\t};\n\n\treturn null;\n};\n"],"names":["ImageManager","props","accepts","compress","crop","dimensions","editImage","id","maxSizeInKb","outputType","upload","value","images","setImages","setErrorCount","setCurrentFileIds","useContext","ImageContext","previousImages","usePrevious","previousValue","setValue","useFormContext","sessionId","useRef","managerErrorCount","dispatchFieldEvent","addFieldEventListener","removeFieldEventListener","useFieldEvent","useEffect","handleUpdateImageStatus","e","prev","imageIndex","findIndex","image","detail","updatedImage","status","updatedStatus","customErrorMessage","errorMessage","newImages","splice","current","generateRandomId","forEach","index","previousFile","dataURL","EImageStatus","INJECTED","FileHelper","dataUrlToBlob","then","blob","updatedImages","file","File","name","NONE","catch","filter","i","getType","fileType","mimeType","mime","map","fileExtensionToMimeType","includes","deduplicateFileName","sanitizeFileName","type","addedFrom","UPLOADED","compressImage","convertImage","ERROR_FORMAT","TO_RECOMPRESS","recompressImage","COMPRESSED","CONVERTED","RECOMPRESSED","shouldPreventDefault","imageData","PENDING","UPLOAD_READY","uploadImage","TO_DELETE","join","updatedManagerErrorCount","ERROR_GENERIC","ERROR_SIZE","Math","max","uploadedImages","ERROR_CUSTOM_MUTED","notPrefilledImages","gotDeleteImages","length","hasNotPrefilledImages","shouldDirty","drawingDataURL","metadata","uploadResponse","fileId","fileName","shouldTouch","undefined","getScale","origWidth","origHeight","scale","width","height","async","ImageHelper","convertBlob","filesize","getFilesizeFromBase64","getMetadata","imageToCompress","dataUrlToImage","origDim","w","naturalWidth","h","naturalHeight","compressed","resampleImage","fileSize","size","fileToDataUrl","scaledFile","iFile","response","UPLOADING","method","url","formData","FormData","append","slot","AxiosApiClient","onUploadProgress","progressEvent","loaded","total","percent","floor","uploadProgress","err"],"mappings":"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"}
1
+ {"version":3,"file":"index.1d69a8ce.js","sources":["../../src/components/fields/image-upload/image-manager/image-manager.ts"],"sourcesContent":["import { useContext, useEffect, useRef } from \"react\";\nimport { useFormContext } from \"react-hook-form\";\nimport { AxiosApiClient, FileHelper, ImageHelper, generateRandomId } from \"../../../../utils\";\nimport { useFieldEvent, usePrevious } from \"../../../../utils/hooks\";\nimport { ImageContext } from \"../image-context\";\nimport {\n\tEImageStatus,\n\tIImage,\n\tISharedImageProps,\n\tIUpdateImageStatus,\n\tTImageUploadOutputFileType,\n\tTUploadMethod,\n} from \"../types\";\n\ninterface IProps extends Omit<ISharedImageProps, \"maxFiles\"> {\n\teditImage: boolean;\n\tcompress: boolean;\n\tcrop: boolean;\n\tdimensions: { width: number; height: number };\n\toutputType: TImageUploadOutputFileType;\n\tupload?: {\n\t\tmethod: TUploadMethod;\n\t\turl: string;\n\t\tsessionId?: string | undefined;\n\t};\n\tvalue: any;\n}\n\n/**\n * manages selected images by listening to images from context provider\n * rename / compress / upload\n */\nexport const ImageManager = (props: IProps) => {\n\t// =============================================================================\n\t// CONST, STATE, REFS\n\t// =============================================================================\n\tconst { accepts, compress, crop, dimensions, editImage, id, maxSizeInKb, outputType, upload, value } = props;\n\tconst { images, setImages, setErrorCount, setCurrentFileIds } = useContext(ImageContext);\n\tconst previousImages = usePrevious(images);\n\tconst previousValue = usePrevious(value);\n\tconst { setValue } = useFormContext();\n\tconst sessionId = useRef<string>();\n\tconst managerErrorCount = useRef(0);\n\n\tconst { dispatchFieldEvent, addFieldEventListener, removeFieldEventListener } = useFieldEvent();\n\n\t// =============================================================================\n\t// EFFECTS\n\t// =============================================================================\n\tuseEffect(() => {\n\t\tconst handleUpdateImageStatus = (e: CustomEvent<IUpdateImageStatus>) => {\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst imageIndex = prev.findIndex((image) => image.id === e.detail.id);\n\t\t\t\tconst updatedImage = { ...prev[imageIndex] };\n\t\t\t\tupdatedImage.status = e.detail.updatedStatus;\n\t\t\t\tupdatedImage.customErrorMessage = e.detail.errorMessage;\n\n\t\t\t\tconst newImages = [...prev];\n\t\t\t\tnewImages.splice(imageIndex, 1, updatedImage);\n\t\t\t\treturn newImages;\n\t\t\t});\n\t\t};\n\n\t\taddFieldEventListener(\"update-image-status\", id, handleUpdateImageStatus);\n\t\treturn () => removeFieldEventListener(\"update-image-status\", id, handleUpdateImageStatus);\n\t}, [addFieldEventListener, id, removeFieldEventListener, setImages]);\n\n\t// generate pseudo-random session id\n\tuseEffect(() => {\n\t\tsessionId.current = generateRandomId();\n\t}, []);\n\n\tuseEffect(() => {\n\t\timages.forEach((image, index) => {\n\t\t\tconst previousFile = previousImages?.[index];\n\t\t\tif (image.status !== previousFile?.status || image.dataURL !== previousFile.dataURL) {\n\t\t\t\tswitch (image.status) {\n\t\t\t\t\tcase EImageStatus.INJECTED:\n\t\t\t\t\t\tFileHelper.dataUrlToBlob(image.dataURL)\n\t\t\t\t\t\t\t.then((blob) => {\n\t\t\t\t\t\t\t\tsetImages((prev) => {\n\t\t\t\t\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\tfile: new File([blob], image.name),\n\t\t\t\t\t\t\t\t\t\tstatus: EImageStatus.NONE,\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\treturn updatedImages;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.catch(() => {\n\t\t\t\t\t\t\t\tsetImages((prev) => prev.filter((prev, i) => i !== index));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.NONE:\n\t\t\t\t\t\tFileHelper.getType(image.file).then((fileType) => {\n\t\t\t\t\t\t\tconst mimeType = fileType.mime;\n\t\t\t\t\t\t\tif (mimeType && accepts.map(FileHelper.fileExtensionToMimeType).includes(mimeType)) {\n\t\t\t\t\t\t\t\tsetImages((prev) => {\n\t\t\t\t\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\tname: FileHelper.deduplicateFileName(\n\t\t\t\t\t\t\t\t\t\t\timages.map(({ name }) => name),\n\t\t\t\t\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t\t\t\t\t\tFileHelper.sanitizeFileName(image.name)\n\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\ttype: mimeType,\n\t\t\t\t\t\t\t\t\t\tstatus: image.addedFrom !== \"schema\" ? image.status : EImageStatus.UPLOADED,\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\treturn updatedImages;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tif (image.addedFrom !== \"schema\") {\n\t\t\t\t\t\t\t\t\tcompress ? compressImage(index, image) : convertImage(index, image);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsetImages((prev) => {\n\t\t\t\t\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t\t\t\t\t...image,\n\t\t\t\t\t\t\t\t\t\tstatus: EImageStatus.ERROR_FORMAT,\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\treturn updatedImages;\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.TO_RECOMPRESS:\n\t\t\t\t\t\trecompressImage(index, image);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.COMPRESSED:\n\t\t\t\t\tcase EImageStatus.CONVERTED:\n\t\t\t\t\tcase EImageStatus.RECOMPRESSED:\n\t\t\t\t\t\tif (!editImage) {\n\t\t\t\t\t\t\tconst shouldPreventDefault = !dispatchFieldEvent(\"upload-ready\", id, { imageData: image });\n\n\t\t\t\t\t\t\tsetImages((prev) => {\n\t\t\t\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t\t\t\t...updatedImages[index],\n\t\t\t\t\t\t\t\t\tstatus: shouldPreventDefault ? EImageStatus.PENDING : EImageStatus.UPLOAD_READY,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\treturn updatedImages;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.UPLOAD_READY:\n\t\t\t\t\t\tuploadImage(index, image);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.TO_DELETE:\n\t\t\t\t\t\tsetImages((prev) => prev.filter(({ status }) => status !== EImageStatus.TO_DELETE));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase EImageStatus.UPLOADED:\n\t\t\t\t\t\tdispatchFieldEvent(\"uploaded\", id, { imageData: image });\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [images.map(({ status }) => status).join(\",\"), images.map(({ dataURL }) => dataURL).join(\",\")]);\n\n\t// track / update errors and values\n\tuseEffect(() => {\n\t\tlet updatedManagerErrorCount = 0;\n\t\timages.forEach((image) => {\n\t\t\tif (\n\t\t\t\t(image.type && !accepts.map(FileHelper.fileExtensionToMimeType).includes(image.type)) ||\n\t\t\t\t[EImageStatus.ERROR_GENERIC, EImageStatus.ERROR_SIZE].includes(image.status)\n\t\t\t) {\n\t\t\t\tupdatedManagerErrorCount++;\n\t\t\t}\n\t\t});\n\t\tsetErrorCount((prev) => Math.max(0, prev + updatedManagerErrorCount - managerErrorCount.current));\n\t\tmanagerErrorCount.current = updatedManagerErrorCount;\n\n\t\tconst uploadedImages = images.filter(\n\t\t\t({ status }) => status === EImageStatus.UPLOADED || status === EImageStatus.ERROR_CUSTOM_MUTED\n\t\t);\n\t\tconst notPrefilledImages = uploadedImages.filter(({ addedFrom }) => addedFrom !== \"schema\");\n\t\tconst gotDeleteImages = images.filter(({ status }) => status === EImageStatus.TO_DELETE).length > 0;\n\n\t\t/**\n\t\t * should dirty if\n\t\t * - it is dirty in the first place\n\t\t * - there are non-prefilled images\n\t\t * - user deleted image (differentiated from reset)\n\t\t */\n\t\tconst hasNotPrefilledImages = notPrefilledImages.length > 0;\n\t\tconst shouldDirty = hasNotPrefilledImages || gotDeleteImages;\n\n\t\tsetCurrentFileIds(uploadedImages.map(({ id }) => id));\n\n\t\tsetValue(\n\t\t\tid,\n\t\t\tuploadedImages.map(({ id, dataURL, drawingDataURL, name, metadata, uploadResponse }) => ({\n\t\t\t\tfileId: id,\n\t\t\t\tfileName: name,\n\t\t\t\tdataURL: drawingDataURL || dataURL,\n\t\t\t\tmetadata,\n\t\t\t\tuploadResponse,\n\t\t\t})),\n\t\t\t{ shouldDirty, shouldTouch: hasNotPrefilledImages }\n\t\t);\n\t}, [accepts, id, images, setErrorCount, setValue]);\n\n\tuseEffect(() => {\n\t\tif (previousValue !== undefined && value === undefined && images.length) {\n\t\t\tsetImages([]);\n\t\t}\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [previousValue === undefined, value === undefined, images.length]);\n\n\t// =============================================================================\n\t// HELPER FUNCTIONS\n\t// =============================================================================\n\tconst getScale = (origWidth: number, origHeight: number): number => {\n\t\tlet scale = dimensions.width / origWidth;\n\t\tif (origHeight * scale > dimensions.height) {\n\t\t\tscale = dimensions.height / origHeight;\n\t\t}\n\t\treturn scale;\n\t};\n\n\tconst convertImage = async (index: number, image: IImage) => {\n\t\ttry {\n\t\t\tconst dataURL = await ImageHelper.convertBlob(image.file, FileHelper.fileExtensionToMimeType(outputType));\n\t\t\tconst filesize = FileHelper.getFilesizeFromBase64(dataURL);\n\n\t\t\tif (maxSizeInKb && filesize > maxSizeInKb * 1024) {\n\t\t\t\tsetImages((prev) => {\n\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\tstatus: EImageStatus.ERROR_SIZE,\n\t\t\t\t\t};\n\t\t\t\t\treturn updatedImages;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst metadata = await ImageHelper.getMetadata(image.file);\n\t\t\t\tsetImages((prev) => {\n\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\tdataURL,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\tstatus: EImageStatus.CONVERTED,\n\t\t\t\t\t};\n\t\t\t\t\treturn updatedImages;\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tstatus: EImageStatus.ERROR_GENERIC,\n\t\t\t\t};\n\t\t\t\treturn updatedImages;\n\t\t\t});\n\t\t}\n\t};\n\n\tconst compressImage = async (index: number, imageToCompress: IImage) => {\n\t\ttry {\n\t\t\tconst dataURL = await ImageHelper.convertBlob(\n\t\t\t\timageToCompress.file,\n\t\t\t\tFileHelper.fileExtensionToMimeType(outputType)\n\t\t\t);\n\t\t\tconst image = await ImageHelper.dataUrlToImage(dataURL);\n\t\t\tconst origDim = { w: image.naturalWidth, h: image.naturalHeight };\n\t\t\tlet compressed: Blob;\n\t\t\tif (crop) {\n\t\t\t\tcompressed = await ImageHelper.resampleImage(image, {\n\t\t\t\t\twidth: dimensions.width,\n\t\t\t\t\theight: dimensions.height,\n\t\t\t\t\tcrop: true,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst scale = getScale(origDim.w, origDim.h);\n\t\t\t\tcompressed = await ImageHelper.resampleImage(image, { scale });\n\t\t\t}\n\t\t\tif (maxSizeInKb) {\n\t\t\t\tcompressed = (await ImageHelper.compressImage(compressed, {\n\t\t\t\t\tfileSize: maxSizeInKb,\n\t\t\t\t})) as File;\n\t\t\t}\n\n\t\t\tif (maxSizeInKb && compressed.size > maxSizeInKb * 1024) {\n\t\t\t\tsetImages((prev) => {\n\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\tstatus: EImageStatus.ERROR_SIZE,\n\t\t\t\t\t};\n\t\t\t\t\treturn updatedImages;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst metadata = await ImageHelper.getMetadata(imageToCompress.file);\n\t\t\t\tconst dataURL = await FileHelper.fileToDataUrl(compressed);\n\t\t\t\tsetImages((prev) => {\n\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\tdataURL,\n\t\t\t\t\t\tmetadata,\n\t\t\t\t\t\tstatus: EImageStatus.COMPRESSED,\n\t\t\t\t\t};\n\t\t\t\t\treturn updatedImages;\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tstatus: EImageStatus.ERROR_GENERIC,\n\t\t\t\t};\n\t\t\t\treturn updatedImages;\n\t\t\t});\n\t\t}\n\t};\n\n\tconst recompressImage = async (index: number, imageToCompress: IImage) => {\n\t\tif (imageToCompress.drawingDataURL) {\n\t\t\ttry {\n\t\t\t\tconst image = await ImageHelper.dataUrlToImage(imageToCompress.drawingDataURL);\n\t\t\t\tconst origDim = { w: image.naturalWidth, h: image.naturalHeight };\n\t\t\t\tlet scaledFile: Blob;\n\t\t\t\tif (crop) {\n\t\t\t\t\tscaledFile = await ImageHelper.resampleImage(image, {\n\t\t\t\t\t\twidth: dimensions.width,\n\t\t\t\t\t\theight: dimensions.height,\n\t\t\t\t\t\tcrop: true,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconst scale = getScale(origDim.w, origDim.h);\n\t\t\t\t\tscaledFile = await ImageHelper.resampleImage(image, { scale });\n\t\t\t\t}\n\t\t\t\tscaledFile = (await ImageHelper.compressImage(scaledFile, { fileSize: maxSizeInKb })) as File;\n\n\t\t\t\tif (scaledFile.size > maxSizeInKb * 1024) {\n\t\t\t\t\tconst updatedImages = [...images];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...images[index],\n\t\t\t\t\t\tstatus: EImageStatus.ERROR_SIZE,\n\t\t\t\t\t};\n\t\t\t\t\tsetImages(updatedImages);\n\t\t\t\t} else {\n\t\t\t\t\tconst dataURL = await FileHelper.fileToDataUrl(scaledFile);\n\t\t\t\t\tconst updatedImages = [...images];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...images[index],\n\t\t\t\t\t\tdrawingDataURL: dataURL,\n\t\t\t\t\t\tstatus: EImageStatus.RECOMPRESSED,\n\t\t\t\t\t};\n\t\t\t\t\tsetImages(updatedImages);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tsetImages((prev) => {\n\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\tstatus: EImageStatus.ERROR_GENERIC,\n\t\t\t\t\t};\n\t\t\t\t\treturn updatedImages;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n\n\tconst uploadImage = async (index: number, iFile: IImage) => {\n\t\ttry {\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tstatus: EImageStatus.UPLOADING,\n\t\t\t\t};\n\t\t\t\treturn updatedImages;\n\t\t\t});\n\n\t\t\tlet response: unknown;\n\t\t\tif (upload?.method && upload?.url) {\n\t\t\t\tconst formData = new FormData();\n\t\t\t\tformData.append(\"dataURL\", iFile.drawingDataURL || iFile.dataURL || \"\");\n\t\t\t\tformData.append(\"sessionId\", upload?.sessionId || sessionId.current || \"\");\n\t\t\t\tformData.append(\"slot\", `${iFile.slot}`);\n\t\t\t\tresponse = await new AxiosApiClient(\"\", undefined, undefined, true)[upload.method](\n\t\t\t\t\tupload.url,\n\t\t\t\t\tformData,\n\t\t\t\t\t{\n\t\t\t\t\t\tonUploadProgress: (progressEvent) => {\n\t\t\t\t\t\t\tconst { loaded, total } = progressEvent;\n\t\t\t\t\t\t\tconst percent = Math.floor((loaded * 100) / total);\n\t\t\t\t\t\t\tsetImages((prev) => {\n\t\t\t\t\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\t\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t\t\t\t\t...prev[index],\n\t\t\t\t\t\t\t\t\tuploadProgress: percent,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\treturn updatedImages;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tuploadResponse: response,\n\t\t\t\t\tstatus: EImageStatus.UPLOADED,\n\t\t\t\t};\n\t\t\t\treturn updatedImages;\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tsetImages((prev) => {\n\t\t\t\tconst updatedImages = [...prev];\n\t\t\t\tupdatedImages[index] = {\n\t\t\t\t\t...prev[index],\n\t\t\t\t\tstatus: EImageStatus.ERROR_GENERIC,\n\t\t\t\t};\n\t\t\t\treturn updatedImages;\n\t\t\t});\n\t\t}\n\t};\n\n\treturn null;\n};\n"],"names":["ImageManager","props","accepts","compress","crop","dimensions","editImage","id","maxSizeInKb","outputType","upload","value","images","setImages","setErrorCount","setCurrentFileIds","useContext","ImageContext","previousImages","usePrevious","previousValue","setValue","useFormContext","sessionId","useRef","managerErrorCount","dispatchFieldEvent","addFieldEventListener","removeFieldEventListener","useFieldEvent","useEffect","handleUpdateImageStatus","e","prev","imageIndex","findIndex","image","detail","updatedImage","status","updatedStatus","customErrorMessage","errorMessage","newImages","splice","current","generateRandomId","forEach","index","previousFile","dataURL","EImageStatus","INJECTED","FileHelper","dataUrlToBlob","then","blob","updatedImages","file","File","name","NONE","catch","filter","i","getType","fileType","mimeType","mime","map","fileExtensionToMimeType","includes","deduplicateFileName","sanitizeFileName","type","addedFrom","UPLOADED","compressImage","convertImage","ERROR_FORMAT","TO_RECOMPRESS","recompressImage","COMPRESSED","CONVERTED","RECOMPRESSED","shouldPreventDefault","imageData","PENDING","UPLOAD_READY","uploadImage","TO_DELETE","join","updatedManagerErrorCount","ERROR_GENERIC","ERROR_SIZE","Math","max","uploadedImages","ERROR_CUSTOM_MUTED","notPrefilledImages","gotDeleteImages","length","hasNotPrefilledImages","shouldDirty","drawingDataURL","metadata","uploadResponse","fileId","fileName","shouldTouch","undefined","getScale","origWidth","origHeight","scale","width","height","async","ImageHelper","convertBlob","filesize","getFilesizeFromBase64","getMetadata","imageToCompress","dataUrlToImage","origDim","w","naturalWidth","h","naturalHeight","compressed","resampleImage","fileSize","size","fileToDataUrl","scaledFile","iFile","response","UPLOADING","method","url","formData","FormData","append","slot","AxiosApiClient","onUploadProgress","progressEvent","loaded","total","percent","floor","uploadProgress","err"],"mappings":"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"}