import { FSFileData, CHUNK_SIZE } from "./FSFileData.js"; /** * File uploader on FileServer. * @returns {{files: Array, section: string, init(): void, readonly numberOfFiles: number, readonly isUploading: boolean, readonly hasErrors: boolean, readonly allFilesUploaded: boolean, totalChunksNumber(*): number, handleSubmitFile(Event): Promise, handleRetryFile(number): Promise, removeFile(number): void}|boolean|this is FSFileData[]|number|boolean} * @constructor */ export function FSUploader(){ return { /** * Array of uploaded files. * @type {Array} */ files: [], /** * Section that files must be uploaded. * @type {string} */ section: document.querySelector("meta[name='fs-section']")?.content ?? '', /** * Triggered in fs-upload.blade.php * Refresh icons. * * @param {Array} oldFilesArray */ init( oldFilesArray ){ this.$watch('files', () =>{ this.$nextTick(() => window.refreshIcons(this.$el) ) }) if( oldFilesArray !== undefined && oldFilesArray.length > 0) this.files = oldFilesArray; }, /** * Shortcut to files.length. * @returns {number} */ get numberOfFiles(){ return this.files.length }, /** * Look if some files are currently in upload. * @returns {boolean} */ get isUploading(){ return this.files.some( file => file.isUploading ); }, /** * Check if some files have an error or not. * @returns {boolean} */ get hasErrors(){ return this.files.some( file => file.error ); }, /** * Check if all files are uploaded. * True if all files are uploaded or no one. * * @returns {boolean} */ get allFilesUploaded(){ return ( this.numberOfFiles === 0 || this.files.every(file => file.done) ); }, /** * Get total chunks size of a raw file. * @param rawFile * @returns {number} */ totalChunksNumber( rawFile ){ return Math.ceil( rawFile.size / CHUNK_SIZE ); }, /** * Handle file submission. * You can submit multiple files at once. * * @param {Event} e * @returns {Promise} */ async handleSubmitFile( e ){ const RAW_FILES_FROM_EVENT = Array.from( e.target.files ); e.target.value = ''; // Default. for( const RAW_FILE of RAW_FILES_FROM_EVENT ){ const TOTAL_CHUNKS = this.totalChunksNumber(RAW_FILE); let fsData = FSFileData( RAW_FILE.name, TOTAL_CHUNKS, RAW_FILE ); this.files.push( fsData ); await this.files[this.files.length - 1].upload(this.section); } }, /** * Retry file uploading. * * @param {number} index FSFileData index in this.files. * @returns {Promise} */ handleRetryFile( index ){ const OLDFSFILE = this.files[index]; let fsData = FSFileData(OLDFSFILE.name, this.totalChunksNumber(OLDFSFILE.rawFile), OLDFSFILE.rawFile ); this.files[index] = fsData; this.files[index].upload(this.section); }, /** * Remove a file. * @param {number} index FSFileData index in this.files. */ handleRemoveFile( index ){ this.files.splice(index, 1); }, changeFileState( index, newState ){ this.files[index].state = newState; } } }