@@ -644,71 +644,44 @@ const hasHeicOrHeifExtension = (file: FileObject) => {
644644 * Otherwise, it attempts to fetch the file via its URI and reconstruct a File
645645 * with full metadata (name, size, type).
646646 */
647- const normalizeFileObject = ( file : FileObject ) : Promise < FileObject > => {
647+ const normalizeFileObject = async ( file : FileObject ) : Promise < FileObject > => {
648648 if ( file instanceof File || file instanceof Blob ) {
649- return Promise . resolve ( file ) ;
649+ return file ;
650650 }
651651
652652 const isAndroidNative = getPlatform ( ) === CONST . PLATFORM . ANDROID ;
653653 const isIOSNative = getPlatform ( ) === CONST . PLATFORM . IOS ;
654654 const isNativePlatform = isAndroidNative || isIOSNative ;
655655
656656 if ( ! isNativePlatform || 'size' in file ) {
657- return Promise . resolve ( file ) ;
657+ return file ;
658658 }
659659
660660 if ( typeof file . uri !== 'string' ) {
661- return Promise . resolve ( file ) ;
661+ return file ;
662662 }
663663
664- return fetch ( file . uri )
665- . then ( ( response ) => response . blob ( ) )
666- . then ( ( blob ) => {
667- const name = file . name ?? 'unknown' ;
668- const type = file . type ?? blob . type ?? 'application/octet-stream' ;
669- const normalizedFile = new File ( [ blob ] , name , { type} ) ;
670- return normalizedFile ;
671- } )
672- . catch ( ( error ) => {
673- return Promise . reject ( error ) ;
674- } ) ;
664+ const response = await fetch ( file . uri ) ;
665+ const blob = await response . blob ( ) ;
666+ const name = file . name ?? 'unknown' ;
667+ const type = file . type ?? blob . type ?? 'application/octet-stream' ;
668+ return new File ( [ blob ] , name , { type} ) ;
675669} ;
676670
677- type ValidateAttachmentOptions = {
678- isValidatingReceipts ?: boolean ;
671+ type FileValidationError = {
672+ error : ValueOf < typeof CONST . FILE_VALIDATION_ERRORS > ;
679673 isValidatingMultipleFiles ?: boolean ;
674+ fileType ?: string ;
680675} ;
681676
682- const validateAttachment = ( file : FileObject , validationOptions ?: ValidateAttachmentOptions ) => {
683- const maxFileSize = validationOptions ?. isValidatingReceipts ? CONST . API_ATTACHMENT_VALIDATIONS . RECEIPT_MAX_SIZE : CONST . API_ATTACHMENT_VALIDATIONS . MAX_SIZE ;
684-
685- if ( validationOptions ?. isValidatingReceipts && ! isValidReceiptExtension ( file ) ) {
686- return validationOptions ?. isValidatingMultipleFiles ? CONST . FILE_VALIDATION_ERRORS . WRONG_FILE_TYPE_MULTIPLE : CONST . FILE_VALIDATION_ERRORS . WRONG_FILE_TYPE ;
687- }
688-
689- // Images are exempt from file size check since they will be resized
690- if ( ! Str . isImage ( file . name ?? '' ) && ! hasHeicOrHeifExtension ( file ) && ( file ?. size ?? 0 ) > maxFileSize ) {
691- return validationOptions ?. isValidatingMultipleFiles ? CONST . FILE_VALIDATION_ERRORS . FILE_TOO_LARGE_MULTIPLE : CONST . FILE_VALIDATION_ERRORS . FILE_TOO_LARGE ;
692- }
693-
694- if ( validationOptions ?. isValidatingReceipts && ( file ?. size ?? 0 ) < CONST . API_ATTACHMENT_VALIDATIONS . MIN_SIZE ) {
695- return CONST . FILE_VALIDATION_ERRORS . FILE_TOO_SMALL ;
696- }
697-
698- return '' ;
699- } ;
700-
701- type TranslationAdditionalData = {
702- maxUploadSizeInMB ?: number ;
703- fileLimit ?: number ;
704- fileType ?: string ;
677+ type GetFileValidationErrorTextOptions = {
678+ isValidatingReceipt ?: boolean ;
705679} ;
706680
707681const getFileValidationErrorText = (
708682 translate : LocalizedTranslate ,
709- validationError : ValueOf < typeof CONST . FILE_VALIDATION_ERRORS > | null ,
710- additionalData : TranslationAdditionalData = { } ,
711- isValidatingReceipt = false ,
683+ validationError : FileValidationError | null ,
684+ options : GetFileValidationErrorTextOptions = { } ,
712685) : {
713686 title : string ;
714687 reason : string ;
@@ -719,45 +692,51 @@ const getFileValidationErrorText = (
719692 reason : '' ,
720693 } ;
721694 }
722- const maxSize = isValidatingReceipt ? CONST . API_ATTACHMENT_VALIDATIONS . RECEIPT_MAX_SIZE : CONST . API_ATTACHMENT_VALIDATIONS . MAX_SIZE ;
723- switch ( validationError ) {
695+ const maxSize = options . isValidatingReceipt ? CONST . API_ATTACHMENT_VALIDATIONS . RECEIPT_MAX_SIZE : CONST . API_ATTACHMENT_VALIDATIONS . MAX_SIZE ;
696+
697+ if ( validationError . isValidatingMultipleFiles ) {
698+ switch ( validationError . error ) {
699+ case CONST . FILE_VALIDATION_ERRORS . WRONG_FILE_TYPE :
700+ return {
701+ title : translate ( 'attachmentPicker.someFilesCantBeUploaded' ) ,
702+ reason : translate ( 'attachmentPicker.unsupportedFileType' , validationError . fileType ?? '' ) ,
703+ } ;
704+ case CONST . FILE_VALIDATION_ERRORS . FILE_TOO_LARGE :
705+ return {
706+ title : translate ( 'attachmentPicker.someFilesCantBeUploaded' ) ,
707+ reason : translate ( 'attachmentPicker.sizeLimitExceeded' , maxSize / 1024 / 1024 ) ,
708+ } ;
709+ case CONST . FILE_VALIDATION_ERRORS . FOLDER_NOT_ALLOWED :
710+ return {
711+ title : translate ( 'attachmentPicker.attachmentError' ) ,
712+ reason : translate ( 'attachmentPicker.folderNotAllowedMessage' ) ,
713+ } ;
714+ case CONST . FILE_VALIDATION_ERRORS . MAX_FILE_LIMIT_EXCEEDED :
715+ return {
716+ title : translate ( 'attachmentPicker.someFilesCantBeUploaded' ) ,
717+ reason : translate ( 'attachmentPicker.maxFileLimitExceeded' ) ,
718+ } ;
719+ default :
720+ break ;
721+ }
722+ }
723+
724+ switch ( validationError . error ) {
724725 case CONST . FILE_VALIDATION_ERRORS . WRONG_FILE_TYPE :
725726 return {
726727 title : translate ( 'attachmentPicker.wrongFileType' ) ,
727728 reason : translate ( 'attachmentPicker.notAllowedExtension' ) ,
728729 } ;
729- case CONST . FILE_VALIDATION_ERRORS . WRONG_FILE_TYPE_MULTIPLE :
730- return {
731- title : translate ( 'attachmentPicker.someFilesCantBeUploaded' ) ,
732- reason : translate ( 'attachmentPicker.unsupportedFileType' , additionalData . fileType ?? '' ) ,
733- } ;
734730 case CONST . FILE_VALIDATION_ERRORS . FILE_TOO_LARGE :
735731 return {
736732 title : translate ( 'attachmentPicker.attachmentTooLarge' ) ,
737- reason : isValidatingReceipt
738- ? translate ( 'attachmentPicker.sizeExceededWithLimit' , additionalData . maxUploadSizeInMB ?? CONST . API_ATTACHMENT_VALIDATIONS . RECEIPT_MAX_SIZE / 1024 / 1024 )
739- : translate ( 'attachmentPicker.sizeExceeded' ) ,
740- } ;
741- case CONST . FILE_VALIDATION_ERRORS . FILE_TOO_LARGE_MULTIPLE :
742- return {
743- title : translate ( 'attachmentPicker.someFilesCantBeUploaded' ) ,
744- reason : translate ( 'attachmentPicker.sizeLimitExceeded' , additionalData . maxUploadSizeInMB ?? maxSize / 1024 / 1024 ) ,
733+ reason : options . isValidatingReceipt ? translate ( 'attachmentPicker.sizeExceededWithLimit' , maxSize / 1024 / 1024 ) : translate ( 'attachmentPicker.sizeExceeded' ) ,
745734 } ;
746735 case CONST . FILE_VALIDATION_ERRORS . FILE_TOO_SMALL :
747736 return {
748737 title : translate ( 'attachmentPicker.attachmentTooSmall' ) ,
749738 reason : translate ( 'attachmentPicker.sizeNotMet' ) ,
750739 } ;
751- case CONST . FILE_VALIDATION_ERRORS . FOLDER_NOT_ALLOWED :
752- return {
753- title : translate ( 'attachmentPicker.attachmentError' ) ,
754- reason : translate ( 'attachmentPicker.folderNotAllowedMessage' ) ,
755- } ;
756- case CONST . FILE_VALIDATION_ERRORS . MAX_FILE_LIMIT_EXCEEDED :
757- return {
758- title : translate ( 'attachmentPicker.someFilesCantBeUploaded' ) ,
759- reason : translate ( 'attachmentPicker.maxFileLimitExceeded' ) ,
760- } ;
761740 case CONST . FILE_VALIDATION_ERRORS . FILE_CORRUPTED :
762741 return {
763742 title : translate ( 'attachmentPicker.attachmentError' ) ,
@@ -774,21 +753,13 @@ const getFileValidationErrorText = (
774753 reason : translate ( 'attachmentPicker.imageDimensionsTooLarge' ) ,
775754 } ;
776755 default :
777- return {
778- title : translate ( 'attachmentPicker.attachmentError' ) ,
779- reason : translate ( 'attachmentPicker.errorWhileSelectingCorruptedAttachment' ) ,
780- } ;
756+ break ;
781757 }
782- } ;
783758
784- const getConfirmModalPrompt = ( translate : LocalizedTranslate , attachmentInvalidReason : TranslationPaths | undefined ) => {
785- if ( ! attachmentInvalidReason ) {
786- return '' ;
787- }
788- if ( attachmentInvalidReason === 'attachmentPicker.sizeExceededWithLimit' ) {
789- return translate ( attachmentInvalidReason , CONST . API_ATTACHMENT_VALIDATIONS . RECEIPT_MAX_SIZE / ( 1024 * 1024 ) ) ;
790- }
791- return translate ( attachmentInvalidReason ) ;
759+ return {
760+ title : translate ( 'attachmentPicker.attachmentError' ) ,
761+ reason : translate ( 'attachmentPicker.errorWhileSelectingCorruptedAttachment' ) ,
762+ } ;
792763} ;
793764
794765const MAX_CANVAS_SIZE = 4096 ;
@@ -902,16 +873,13 @@ export {
902873 resizeImageIfNeeded ,
903874 createFile ,
904875 validateReceipt ,
905- validateAttachment ,
906876 normalizeFileObject ,
907877 isValidReceiptExtension ,
908878 getFileValidationErrorText ,
909879 hasHeicOrHeifExtension ,
910- getConfirmModalPrompt ,
911880 canvasFallback ,
912881 getFilesFromClipboardEvent ,
913882 cleanFileObject ,
914883 cleanFileObjectName ,
915884} ;
916-
917- export type { ValidateAttachmentOptions } ;
885+ export type { FileValidationError } ;
0 commit comments