From 63c7ff75ee140bab1adf57bb9e2dd5fc8c30e459 Mon Sep 17 00:00:00 2001 From: hmhealey Date: Thu, 3 Sep 2015 10:25:52 -0400 Subject: Fixed file uploads to still upload other files when one is too large --- web/react/components/file_upload.jsx | 88 +++++++++++++----------------------- 1 file changed, 31 insertions(+), 57 deletions(-) (limited to 'web/react') diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index dcb938cbf..534f0136e 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -10,6 +10,7 @@ export default class FileUpload extends React.Component { constructor(props) { super(props); + this.uploadFiles = this.uploadFiles.bind(this); this.handleChange = this.handleChange.bind(this); this.handleDrop = this.handleDrop.bind(this); @@ -33,39 +34,28 @@ export default class FileUpload extends React.Component { this.props.onUploadError(err, clientId); } - handleChange() { - var element = $(React.findDOMNode(this.refs.fileInput)); - var files = element.prop('files'); + uploadFiles(files) { + // clear any existing errors + this.props.onUploadError(null); var channelId = this.props.channelId || ChannelStore.getCurrentId(); - this.props.onUploadError(null); - - // This looks redundant, but must be done this way due to - // setState being an asynchronous call - var numFiles = 0; - for (let i = 0; i < files.length; i++) { - if (files[i].size <= Constants.MAX_FILE_SIZE) { - numFiles++; - } - } + var uploadsRemaining = Constants.MAX_UPLOAD_FILES - this.props.getFileCount(channelId); + var numUploads = 0; - var numToUpload = Math.min(Constants.MAX_UPLOAD_FILES - this.props.getFileCount(channelId), numFiles); + // keep track of how many files have been too large + var tooLargeFiles = []; - if (numFiles > numToUpload) { - this.props.onUploadError('Uploads limited to ' + Constants.MAX_UPLOAD_FILES + ' files maximum. Please use additional posts for more files.'); - } - - for (let i = 0; i < files.length && i < numToUpload; i++) { + for (let i = 0; i < files.length && numUploads < uploadsRemaining; i++) { if (files[i].size > Constants.MAX_FILE_SIZE) { - this.props.onUploadError('Files must be no more than ' + Constants.MAX_FILE_SIZE / 1000000 + ' MB'); + tooLargeFiles.push(files[i]); continue; } - // generate a unique id that can be used by other components to refer back to this file upload + // generate a unique id that can be used by other components to refer back to this upload var clientId = utils.generateId(); - // Prepare data to be uploaded. + // prepare data to be uploaded var formData = new FormData(); formData.append('channel_id', channelId); formData.append('files', files[i], files[i].name); @@ -81,8 +71,26 @@ export default class FileUpload extends React.Component { this.setState({requests: requests}); this.props.onUploadStart([clientId], channelId); + + numUploads += 1; } + if (files.length > uploadsRemaining) { + this.props.onUploadError(`Uploads limited to ${Constants.MAX_UPLOAD_FILES} files maximum. Please use additional posts for more files.`); + } else if (tooLargeFiles.length > 1) { + var tooLargeFilenames = tooLargeFiles.map((file) => file.name).join(', '); + + this.props.onUploadError(`Files above ${Constants.MAX_FILE_SIZE / 1000000}MB could not be uploaded: ${tooLargeFilenames}`); + } else if (tooLargeFiles.length > 0) { + this.props.onUploadError(`File above ${Constants.MAX_FILE_SIZE / 1000000}MB could not be uploaded: ${tooLargeFiles[0].name}`); + } + } + + handleChange() { + var element = $(React.findDOMNode(this.refs.fileInput)); + + this.uploadFiles(element.prop('files')); + // clear file input for all modern browsers try { element[0].value = ''; @@ -99,43 +107,9 @@ export default class FileUpload extends React.Component { this.props.onUploadError(null); var files = e.originalEvent.dataTransfer.files; - var channelId = this.props.channelId || ChannelStore.getCurrentId(); if (typeof files !== 'string' && files.length) { - var numFiles = files.length; - - var numToUpload = Math.min(Constants.MAX_UPLOAD_FILES - this.props.getFileCount(channelId), numFiles); - - if (numFiles > numToUpload) { - this.props.onUploadError('Uploads limited to ' + Constants.MAX_UPLOAD_FILES + ' files maximum. Please use additional posts for more files.'); - } - - for (var i = 0; i < files.length && i < numToUpload; i++) { - if (files[i].size > Constants.MAX_FILE_SIZE) { - this.props.onUploadError('Files must be no more than ' + Constants.MAX_FILE_SIZE / 1000000 + ' MB'); - continue; - } - - // generate a unique id that can be used by other components to refer back to this file upload - var clientId = utils.generateId(); - - // Prepare data to be uploaded. - var formData = new FormData(); - formData.append('channel_id', channelId); - formData.append('files', files[i], files[i].name); - formData.append('client_ids', clientId); - - var request = client.uploadFile(formData, - this.fileUploadSuccess.bind(this, channelId), - this.fileUploadFail.bind(this, clientId) - ); - - var requests = this.state.requests; - requests[clientId] = request; - this.setState({requests: requests}); - - this.props.onUploadStart([clientId], channelId); - } + this.uploadFiles(files); } else { this.props.onUploadError('Invalid file upload', -1); } -- cgit v1.2.3-1-g7c22