Fixed file uploads to still upload other files when one is too large

Этот коммит содержится в:
hmhealey
2015-09-03 10:25:52 -04:00
родитель f3d3658ef4
Коммит 63c7ff75ee

Просмотреть файл

@@ -10,6 +10,7 @@ export default class FileUpload extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.uploadFiles = this.uploadFiles.bind(this);
this.handleChange = this.handleChange.bind(this); this.handleChange = this.handleChange.bind(this);
this.handleDrop = this.handleDrop.bind(this); this.handleDrop = this.handleDrop.bind(this);
@@ -33,39 +34,28 @@ export default class FileUpload extends React.Component {
this.props.onUploadError(err, clientId); this.props.onUploadError(err, clientId);
} }
handleChange() { uploadFiles(files) {
var element = $(React.findDOMNode(this.refs.fileInput)); // clear any existing errors
var files = element.prop('files'); this.props.onUploadError(null);
var channelId = this.props.channelId || ChannelStore.getCurrentId(); var channelId = this.props.channelId || ChannelStore.getCurrentId();
this.props.onUploadError(null); var uploadsRemaining = Constants.MAX_UPLOAD_FILES - this.props.getFileCount(channelId);
var numUploads = 0;
// This looks redundant, but must be done this way due to // keep track of how many files have been too large
// setState being an asynchronous call var tooLargeFiles = [];
var numFiles = 0;
for (let i = 0; i < files.length; i++) {
if (files[i].size <= Constants.MAX_FILE_SIZE) {
numFiles++;
}
}
var numToUpload = Math.min(Constants.MAX_UPLOAD_FILES - this.props.getFileCount(channelId), numFiles); for (let i = 0; i < files.length && numUploads < uploadsRemaining; i++) {
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++) {
if (files[i].size > Constants.MAX_FILE_SIZE) { 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; 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(); var clientId = utils.generateId();
// Prepare data to be uploaded. // prepare data to be uploaded
var formData = new FormData(); var formData = new FormData();
formData.append('channel_id', channelId); formData.append('channel_id', channelId);
formData.append('files', files[i], files[i].name); formData.append('files', files[i], files[i].name);
@@ -81,8 +71,26 @@ export default class FileUpload extends React.Component {
this.setState({requests: requests}); this.setState({requests: requests});
this.props.onUploadStart([clientId], channelId); 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 // clear file input for all modern browsers
try { try {
element[0].value = ''; element[0].value = '';
@@ -99,43 +107,9 @@ export default class FileUpload extends React.Component {
this.props.onUploadError(null); this.props.onUploadError(null);
var files = e.originalEvent.dataTransfer.files; var files = e.originalEvent.dataTransfer.files;
var channelId = this.props.channelId || ChannelStore.getCurrentId();
if (typeof files !== 'string' && files.length) { if (typeof files !== 'string' && files.length) {
var numFiles = files.length; this.uploadFiles(files);
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);
}
} else { } else {
this.props.onUploadError('Invalid file upload', -1); this.props.onUploadError('Invalid file upload', -1);
} }