diff options
Diffstat (limited to 'web/react/components/file_upload.jsx')
-rw-r--r-- | web/react/components/file_upload.jsx | 163 |
1 files changed, 121 insertions, 42 deletions
diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index aee089dbc..b90fa4fd3 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -4,12 +4,18 @@ var client = require('../utils/client.jsx'); var Constants = require('../utils/constants.jsx'); var ChannelStore = require('../stores/channel_store.jsx'); +var utils = require('../utils/utils.jsx'); module.exports = React.createClass({ + getInitialState: function() { + return {requests: {}}; + }, handleChange: function() { var element = $(this.refs.fileInput.getDOMNode()); var files = element.prop('files'); + var channelId = ChannelStore.getCurrentId(); + this.props.onUploadError(null); // This looks redundant, but must be done this way due to @@ -21,50 +27,67 @@ module.exports = React.createClass({ } } - var numToUpload = this.props.setUploads(numFiles); + 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"); + this.props.onUploadError('Files must be no more than ' + Constants.MAX_FILE_SIZE / 1000000 + ' MB'); continue; } - var channel_id = ChannelStore.getCurrentId(); + // 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. - formData = new FormData(); - formData.append('channel_id', channel_id); + var formData = new FormData(); + formData.append('channel_id', channelId); formData.append('files', files[i], files[i].name); + formData.append('client_ids', clientId); - client.uploadFile(formData, + var request = client.uploadFile(formData, function(data) { - parsedData = $.parseJSON(data); - this.props.onFileUpload(parsedData['filenames'], channel_id); + var parsedData = $.parseJSON(data); + this.props.onFileUpload(parsedData['filenames'], parsedData['client_ids'], channelId); + + var requests = this.state.requests; + for (var i = 0; i < parsedData['client_ids'].length; i++) { + delete requests[parsedData['client_ids'][i]]; + } + this.setState({requests: requests}); }.bind(this), function(err) { - this.props.setUploads(-1); - this.props.onUploadError(err); + this.props.onUploadError(err, clientId); }.bind(this) ); + + var requests = this.state.requests; + requests[clientId] = request; + this.setState({requests: requests}); + + this.props.onUploadStart([clientId], channelId); } // clear file input for all modern browsers - try{ + try { element[0].value = ''; - if(element.value){ - element[0].type = "text"; - element[0].type = "file"; + if (element.value) { + element[0].type = 'text'; + element[0].type = 'file'; } - }catch(e){} + } catch(e) {} }, componentDidMount: function() { var inputDiv = this.refs.input.getDOMNode(); var self = this; - document.addEventListener("paste", function(e) { + document.addEventListener('paste', function(e) { var textarea = $(inputDiv.parentNode.parentNode).find('.custom-textarea')[0]; - if (textarea != e.target && !$.contains(textarea,e.target)) { + if (textarea !== e.target && !$.contains(textarea, e.target)) { return; } @@ -76,54 +99,110 @@ module.exports = React.createClass({ var numItems = 0; if (items) { for (var i = 0; i < items.length; i++) { - if (items[i].type.indexOf("image") !== -1) { + if (items[i].type.indexOf('image') !== -1) { + var ext = items[i].type.split('/')[1].toLowerCase(); + if (ext === 'jpeg') { + ext = 'jpg'; + } - ext = items[i].type.split("/")[1].toLowerCase(); - ext = ext == 'jpeg' ? 'jpg' : ext; + if (Constants.IMAGE_TYPES.indexOf(ext) < 0) { + continue; + } - if (Constants.IMAGE_TYPES.indexOf(ext) < 0) return; - - numItems++ + numItems++; } } - var numToUpload = self.props.setUploads(numItems); + var numToUpload = Math.min(Constants.MAX_UPLOAD_FILES - self.props.getFileCount(channelId), numItems); + + if (numItems > numToUpload) { + self.props.onUploadError('Uploads limited to ' + Constants.MAX_UPLOAD_FILES + ' files maximum. Please use additional posts for more files.'); + } for (var i = 0; i < items.length && i < numToUpload; i++) { - if (items[i].type.indexOf("image") !== -1) { + if (items[i].type.indexOf('image') !== -1) { var file = items[i].getAsFile(); - ext = items[i].type.split("/")[1].toLowerCase(); - ext = ext == 'jpeg' ? 'jpg' : ext; + var ext = items[i].type.split('/')[1].toLowerCase(); + if (ext === 'jpeg') { + ext = 'jpg'; + } - if (Constants.IMAGE_TYPES.indexOf(ext) < 0) return; + if (Constants.IMAGE_TYPES.indexOf(ext) < 0) { + continue; + } - var channel_id = ChannelStore.getCurrentId(); + var channelId = ChannelStore.getCurrentId(); - formData = new FormData(); - formData.append('channel_id', channel_id); - var d = new Date(); - var hour = d.getHours() < 10 ? "0" + d.getHours() : String(d.getHours()); - var min = d.getMinutes() < 10 ? "0" + d.getMinutes() : String(d.getMinutes()); - formData.append('files', file, "Image Pasted at "+d.getFullYear()+"-"+d.getMonth()+"-"+d.getDate()+" "+hour+"-"+min+"." + ext); + // generate a unique id that can be used by other components to refer back to this file upload + var clientId = utils.generateId(); + + var formData = new FormData(); + formData.append('channel_id', channelId); - client.uploadFile(formData, + var d = new Date(); + var hour; + if (d.getHours() < 10) { + hour = '0' + d.getHours(); + } else { + hour = String(d.getHours()); + } + var min; + if (d.getMinutes() < 10) { + min = '0' + d.getMinutes(); + } else { + min = String(d.getMinutes()); + } + + var name = 'Image Pasted at ' + d.getFullYear() + '-' + d.getMonth() + '-' + d.getDate() + ' ' + hour + '-' + min + '.' + ext; + formData.append('files', file, name); + formData.append('client_ids', clientId); + + var request = client.uploadFile(formData, function(data) { - parsedData = $.parseJSON(data); - self.props.onFileUpload(parsedData['filenames'], channel_id); - }.bind(this), + var parsedData = $.parseJSON(data); + self.props.onFileUpload(parsedData['filenames'], parsedData['client_ids'], channelId); + + var requests = self.state.requests; + for (var i = 0; i < parsedData['client_ids'].length; i++) { + delete requests[parsedData['client_ids'][i]]; + } + self.setState({requests: requests}); + }, function(err) { - self.props.onUploadError(err); - }.bind(this) + self.props.onUploadError(err, clientId); + } ); + + var requests = self.state.requests; + requests[clientId] = request; + self.setState({requests: requests}); + + self.props.onUploadStart([clientId], channelId); } } } }); }, + cancelUpload: function(clientId) { + var requests = this.state.requests; + var request = requests[clientId]; + + if (request) { + request.abort(); + + delete requests[clientId]; + this.setState({requests: requests}); + } + }, render: function() { return ( - <span ref="input" className="btn btn-file"><span><i className="glyphicon glyphicon-paperclip"></i></span><input ref="fileInput" type="file" onChange={this.handleChange} multiple/></span> + <span ref='input' className='btn btn-file'> + <span> + <i className='glyphicon glyphicon-paperclip' /> + </span> + <input ref='fileInput' type='file' onChange={this.handleChange} multiple/> + </span> ); } }); |