import { FileItem , FileStatus , RequestOption , UploadRequest , } from './interfaces' ; import { NOOP } from '../_utils/dom' ; import { isArray , isFunction } from '../_utils/is' ; const getResponse = ( xhr ) => { const res = xhr . responseText || xhr . response ; if ( ! res ) { return undefined ; } const contentType = xhr . getResponseHeader ( 'Content-Type' ) ; if ( contentType && contentType . includes ( 'json' ) ) { try { return JSON . parse ( res ) ; } catch { return res ; } } return res ; } ; export const getProgressStatus = ( status ? ) => { switch ( status ) { case 'done' : return 'success' ; case 'error' : return 'danger' ; default : return 'normal' ; } } ; param fileList export const processFileList = ( fileList ? ) : FileItem [ ] => { if ( isArray ( fileList ) ) { return fileList . map ( ( file , index ) => { return { uid : `${ Date . now ( ) }${ index }` , status : 'done' , percent : 1 , ... file } ; } ) ; } return [ ] ; } ; const getValue = ( obj , fileItem ) => { if ( isFunction ( obj ) ) { return obj ( fileItem ) ; } return obj ; } ; export const uploadRequest = ( { fileItem , action , name : originName , data : originData , headers = { } , withCredentials = false , onProgress = NOOP , onSuccess = NOOP , onError = NOOP , } ) : UploadRequest => { const name = getValue ( originName , fileItem ) || 'file' ; const data = getValue ( originData , fileItem ) ; const xhr = new XMLHttpRequest ( ) ; if ( withCredentials ) { xhr . withCredentials = true ; } xhr . upload . onprogress = ( e ) => { const percent = e . total > 0 ? Math . round ( e . loaded / e . total ) : 0 ; onProgress ( percent , e ) ; } ; xhr . onerror = function error ( e ) { onError ( e ) ; } ; xhr . onload = ( ) => { if ( xhr . status < 200 || xhr . status >= 300 ) { onError ( getResponse ( xhr ) ) ; return ; } onSuccess ( getResponse ( xhr ) ) ; } ; const formData = new FormData ( ) ; if ( fileItem . file ) { formData . append ( name , fileItem . file ) ; } if ( data ) { for ( const key of Object . keys ( data ) ) { formData . append ( key , data [ key ] ) ; } } xhr . open ( 'post' , action ?? '' , true ) ; for ( const key of Object . keys ( headers ) ) { xhr . setRequestHeader ( key , headers [ key ] ) ; } xhr . send ( formData ) ; return { abort ( ) { xhr . abort ( ) ; } } ; } ; const isAcceptFile = ( file , accept ? ) : boolean => { if ( accept && file ) { const accepts = isArray ( accept ) ? accept : accept . split ( ',' ) . map ( ( x ) => x . trim ( ) ) . filter ( ( x ) => x ) ; const fileExtension = file . name . indexOf ( '.' ) > - 1 ? file . name . split ( '.' ) . pop ( ) : '' ; return accepts . some ( ( type ) => { const text = type && type . toLowerCase ( ) ; const fileType = ( file . type || '' ) . toLowerCase ( ) ; if ( text === fileType ) { return true ; } if ( /\/\*/ . test ( text ) ) { return fileType . replace ( /\/.*$/ , '' ) === text . replace ( /\/.*$/ , '' ) ; } if ( /\..*/ . test ( text ) ) { return text === `.${ fileExtension && fileExtension . toLowerCase ( ) }` ; } return false ; } ) ; } return Boolean ( file ) ; } ; export const loopDirectory = ( itemList , accept , callback ) => { const files = [ ] ; let restFileCount = 0 ; const onFinish = ( ) => { ! restFileCount && callback ( files ) ; } ; const _loopDirectory = ( item ) => { restFileCount += 1 ; if ( item ?. isFile ) { ( item as FileSystemFileEntry ) . file ( ( file ) => { restFileCount -= 1 ; if ( isAcceptFile ( file , accept ) ) { Object . defineProperty ( file , 'webkitRelativePath' , { value : item . fullPath . replace ( /^\// , '' ) } ) ; files . push ( file ) ; } onFinish ( ) ; } ) ; return ; } if ( item ?. isDirectory ) { const reader = ( item as FileSystemDirectoryEntry ) . createReader ( ) ; let flag = false ; const readEntries = ( ) => { reader . readEntries ( ( entries ) => { if ( ! flag ) { restFileCount -= 1 ; flag = true ; } if ( entries . length === 0 ) { onFinish ( ) ; } else { readEntries ( ) ; entries . forEach ( _loopDirectory ) ; } } ) ; } ; readEntries ( ) ; return ; } restFileCount -= 1 ; onFinish ( ) ; } ; [ ] . slice . call ( itemList ) . forEach ( ( item ) => item . webkitGetAsEntry && _loopDirectory ( item . webkitGetAsEntry ( ) ) ) ; } ; export const getDataURLFromFile = async ( file ) : Promise < string > => { return new Promise ( ( resolve ) => { const reader = new FileReader ( ) ; reader . onload = ( e ) => { resolve ( e . target ?. result as string ) ; } ; reader . readAsDataURL ( file ) ; } ) ; } ; export const getFiles = ( fileList ? , accept ? ) : File [ ] => { if ( ! fileList ) { return [ ] ; } const files = Array . from ( fileList ) ; if ( accept ) { return files . filter ( ( file ) => { return isAcceptFile ( file , accept ) ; } ) ; } return files ; } ;