| @@ -1,2 +1,3 @@ | |||
| export const FILE_SIZE_LIMIT = 15 * 1024 * 1024 | |||
| export const FILE_URL_REGEX = /^(https?|ftp):\/\// | |||
| @@ -31,8 +31,8 @@ const FileInAttachmentItem = ({ | |||
| onRemove, | |||
| onReUpload, | |||
| }: FileInAttachmentItemProps) => { | |||
| const { id, name, progress, supportFileType, base64Url, url } = file | |||
| const ext = getFileExtension(name) | |||
| const { id, name, type, progress, supportFileType, base64Url, url } = file | |||
| const ext = getFileExtension(name, type) | |||
| const isImageFile = supportFileType === SupportUploadFileTypes.image | |||
| return ( | |||
| @@ -52,7 +52,7 @@ const FileInAttachmentItem = ({ | |||
| { | |||
| !isImageFile && ( | |||
| <FileTypeIcon | |||
| type={getFileAppearanceType(file.type)} | |||
| type={getFileAppearanceType(name, type)} | |||
| size='lg' | |||
| /> | |||
| ) | |||
| @@ -29,8 +29,8 @@ const FileItem = ({ | |||
| onRemove, | |||
| onReUpload, | |||
| }: FileItemProps) => { | |||
| const { id, name, progress } = file | |||
| const ext = getFileExtension(name) | |||
| const { id, name, type, progress } = file | |||
| const ext = getFileExtension(name, type) | |||
| const uploadError = progress === -1 | |||
| return ( | |||
| @@ -59,7 +59,7 @@ const FileItem = ({ | |||
| <div className='flex items-center system-2xs-medium-uppercase text-text-tertiary'> | |||
| <FileTypeIcon | |||
| size='sm' | |||
| type={getFileAppearanceType(name)} | |||
| type={getFileAppearanceType(name, type)} | |||
| className='mr-1' | |||
| /> | |||
| { | |||
| @@ -11,7 +11,6 @@ import type { FileEntity } from './types' | |||
| import { useFileStore } from './store' | |||
| import { | |||
| fileUpload, | |||
| getFileNameFromUrl, | |||
| getSupportFileType, | |||
| isAllowedFileExtension, | |||
| } from './utils' | |||
| @@ -97,16 +96,15 @@ export const useFile = (fileConfig: FileUpload) => { | |||
| const handleLoadFileFromLink = useCallback((url: string) => { | |||
| const allowedFileTypes = fileConfig.allowed_file_types | |||
| const fileName = getFileNameFromUrl(url) | |||
| const uploadingFile = { | |||
| id: uuid4(), | |||
| name: fileName, | |||
| name: url, | |||
| type: '', | |||
| size: 0, | |||
| progress: 0, | |||
| transferMethod: TransferMethod.remote_url, | |||
| supportFileType: getSupportFileType(fileName, allowedFileTypes?.includes(SupportUploadFileTypes.custom)), | |||
| supportFileType: '', | |||
| url, | |||
| } | |||
| handleAddFile(uploadingFile) | |||
| @@ -117,6 +115,7 @@ export const useFile = (fileConfig: FileUpload) => { | |||
| type: res.file_type, | |||
| size: res.file_length, | |||
| progress: 100, | |||
| supportFileType: getSupportFileType(url, res.file_type, allowedFileTypes?.includes(SupportUploadFileTypes.custom)), | |||
| } | |||
| handleUpdateFile(newFile) | |||
| }).catch(() => { | |||
| @@ -137,7 +136,7 @@ export const useFile = (fileConfig: FileUpload) => { | |||
| }, [fileStore]) | |||
| const handleLocalFileUpload = useCallback((file: File) => { | |||
| if (!isAllowedFileExtension(file.name, fileConfig.allowed_file_types || [], fileConfig.allowed_file_extensions || [])) { | |||
| if (!isAllowedFileExtension(file.name, file.type, fileConfig.allowed_file_types || [], fileConfig.allowed_file_extensions || [])) { | |||
| notify({ type: 'error', message: t('common.fileUploader.fileExtensionNotSupport') }) | |||
| return | |||
| } | |||
| @@ -159,7 +158,7 @@ export const useFile = (fileConfig: FileUpload) => { | |||
| size: file.size, | |||
| progress: 0, | |||
| transferMethod: TransferMethod.local_file, | |||
| supportFileType: getSupportFileType(file.name, allowedFileTypes?.includes(SupportUploadFileTypes.custom)), | |||
| supportFileType: getSupportFileType(file.name, file.type, allowedFileTypes?.includes(SupportUploadFileTypes.custom)), | |||
| originalFile: file, | |||
| base64Url: isImage ? reader.result as string : '', | |||
| } | |||
| @@ -1,3 +1,4 @@ | |||
| import mime from 'mime' | |||
| import { FileAppearanceTypeEnum } from './types' | |||
| import type { FileEntity } from './types' | |||
| import { upload } from '@/service/base' | |||
| @@ -39,43 +40,65 @@ export const fileUpload: FileUpload = ({ | |||
| }) | |||
| } | |||
| export const getFileAppearanceType = (fileType: string) => { | |||
| if (!fileType) | |||
| return FileAppearanceTypeEnum.custom | |||
| export const getFileExtension = (fileName: string, fileMimetype: string) => { | |||
| if (fileMimetype) | |||
| return mime.getExtension(fileMimetype) || '' | |||
| if (fileType.includes('image')) | |||
| if (fileName) { | |||
| const fileNamePair = fileName.split('.') | |||
| const fileNamePairLength = fileNamePair.length | |||
| if (fileNamePairLength > 1) | |||
| return fileNamePair[fileNamePairLength - 1] | |||
| } | |||
| return '' | |||
| } | |||
| export const getFileAppearanceType = (fileName: string, fileMimetype: string) => { | |||
| const extension = getFileExtension(fileName, fileMimetype) | |||
| if (extension === 'gif') | |||
| return FileAppearanceTypeEnum.gif | |||
| if (FILE_EXTS.image.includes(extension.toUpperCase())) | |||
| return FileAppearanceTypeEnum.image | |||
| if (fileType.includes('video')) | |||
| if (FILE_EXTS.video.includes(extension.toUpperCase())) | |||
| return FileAppearanceTypeEnum.video | |||
| if (fileType.includes('audio')) | |||
| if (FILE_EXTS.audio.includes(extension.toUpperCase())) | |||
| return FileAppearanceTypeEnum.audio | |||
| if (fileType.includes('pdf')) | |||
| if (extension === 'html') | |||
| return FileAppearanceTypeEnum.code | |||
| if (extension === 'pdf') | |||
| return FileAppearanceTypeEnum.pdf | |||
| return FileAppearanceTypeEnum.custom | |||
| } | |||
| if (extension === 'md' || extension === 'markdown') | |||
| return FileAppearanceTypeEnum.markdown | |||
| export const getFileExtension = (fileName: string) => { | |||
| if (!fileName) | |||
| return '' | |||
| if (extension === 'xlsx' || extension === 'xls') | |||
| return FileAppearanceTypeEnum.excel | |||
| const fileNamePair = fileName.split('.') | |||
| const fileNamePairLength = fileNamePair.length | |||
| if (extension === 'docx' || extension === 'doc') | |||
| return FileAppearanceTypeEnum.word | |||
| if (fileNamePairLength > 1) | |||
| return fileNamePair[fileNamePairLength - 1] | |||
| if (extension === 'pptx' || extension === 'ppt') | |||
| return FileAppearanceTypeEnum.ppt | |||
| return '' | |||
| if (FILE_EXTS.document.includes(extension.toUpperCase())) | |||
| return FileAppearanceTypeEnum.document | |||
| return FileAppearanceTypeEnum.custom | |||
| } | |||
| export const getSupportFileType = (fileName: string, isCustom?: boolean) => { | |||
| export const getSupportFileType = (fileName: string, fileMimetype: string, isCustom?: boolean) => { | |||
| if (isCustom) | |||
| return SupportUploadFileTypes.custom | |||
| const extension = getFileExtension(fileName) | |||
| const extension = getFileExtension(fileName, fileMimetype) | |||
| for (const key in FILE_EXTS) { | |||
| if ((FILE_EXTS[key]).includes(extension.toUpperCase())) | |||
| return key | |||
| @@ -105,6 +128,6 @@ export const getSupportFileExtensionList = (allowFileTypes: string[], allowFileE | |||
| return allowFileTypes.map(type => FILE_EXTS[type]).flat() | |||
| } | |||
| export const isAllowedFileExtension = (fileName: string, allowFileTypes: string[], allowFileExtensions: string[]) => { | |||
| return getSupportFileExtensionList(allowFileTypes, allowFileExtensions).includes(getFileExtension(fileName).toUpperCase()) | |||
| export const isAllowedFileExtension = (fileName: string, fileMimetype: string, allowFileTypes: string[], allowFileExtensions: string[]) => { | |||
| return getSupportFileExtensionList(allowFileTypes, allowFileExtensions).includes(getFileExtension(fileName, fileMimetype).toUpperCase()) | |||
| } | |||
| @@ -60,6 +60,7 @@ | |||
| "lexical": "^0.16.0", | |||
| "lodash-es": "^4.17.21", | |||
| "mermaid": "10.4.0", | |||
| "mime": "^4.0.4", | |||
| "negotiator": "^0.6.3", | |||
| "next": "^14.1.1", | |||
| "next-nprogress-bar": "^2.3.8", | |||
| @@ -7183,6 +7183,11 @@ mime-types@^2.1.12: | |||
| dependencies: | |||
| mime-db "1.52.0" | |||
| mime@^4.0.4: | |||
| version "4.0.4" | |||
| resolved "https://registry.yarnpkg.com/mime/-/mime-4.0.4.tgz#9f851b0fc3c289d063b20a7a8055b3014b25664b" | |||
| integrity sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ== | |||
| mimic-fn@^2.1.0: | |||
| version "2.1.0" | |||
| resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" | |||
| @@ -8816,7 +8821,14 @@ stringify-entities@^4.0.0: | |||
| character-entities-html4 "^2.0.0" | |||
| character-entities-legacy "^3.0.0" | |||
| "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: | |||
| "strip-ansi-cjs@npm:strip-ansi@^6.0.1": | |||
| version "6.0.1" | |||
| resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" | |||
| integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== | |||
| dependencies: | |||
| ansi-regex "^5.0.1" | |||
| strip-ansi@^6.0.0, strip-ansi@^6.0.1: | |||
| version "6.0.1" | |||
| resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" | |||
| integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== | |||
| @@ -9653,8 +9665,7 @@ word-wrap@^1.2.3: | |||
| resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz" | |||
| integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== | |||
| "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: | |||
| name wrap-ansi-cjs | |||
| "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": | |||
| version "7.0.0" | |||
| resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" | |||
| integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== | |||
| @@ -9672,6 +9683,15 @@ wrap-ansi@^6.2.0: | |||
| string-width "^4.1.0" | |||
| strip-ansi "^6.0.0" | |||
| wrap-ansi@^7.0.0: | |||
| version "7.0.0" | |||
| resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" | |||
| integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== | |||
| dependencies: | |||
| ansi-styles "^4.0.0" | |||
| string-width "^4.1.0" | |||
| strip-ansi "^6.0.0" | |||
| wrap-ansi@^8.1.0: | |||
| version "8.1.0" | |||
| resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" | |||