summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhmhealey <harrisonmhealey@gmail.com>2015-08-10 08:41:18 -0400
committerhmhealey <harrisonmhealey@gmail.com>2015-08-10 14:04:23 -0400
commit4e8af44370bfb4276e009526045a4983d5ff245a (patch)
tree901e39bc69433a9c77325923cfcb08da93ab3dd5
parent20d755f3dd5c797413177752884d8589c1f46931 (diff)
downloadchat-4e8af44370bfb4276e009526045a4983d5ff245a.tar.gz
chat-4e8af44370bfb4276e009526045a4983d5ff245a.tar.bz2
chat-4e8af44370bfb4276e009526045a4983d5ff245a.zip
Added the ability to cancel file uploads on posts
-rw-r--r--web/react/components/create_post.jsx22
-rw-r--r--web/react/components/file_preview.jsx3
-rw-r--r--web/react/components/file_upload.jsx37
-rw-r--r--web/react/utils/client.jsx10
4 files changed, 62 insertions, 10 deletions
diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx
index 09d7acd9c..b32b53749 100644
--- a/web/react/components/create_post.jsx
+++ b/web/react/components/create_post.jsx
@@ -180,12 +180,21 @@ module.exports = React.createClass({
},
removePreview: function(filename) {
var previews = this.state.previews;
- for (var i = 0; i < previews.length; i++) {
- if (previews[i] === filename) {
- previews.splice(i, 1);
- break;
+ var uploadsInProgress = this.state.uploadsInProgress;
+
+ // this can be either an uploaded file or an in progress upload that we need to remove
+ var index = previews.indexOf(filename);
+ if (index !== -1) {
+ previews.splice(index, 1);
+ } else {
+ index = uploadsInProgress.indexOf(filename);
+
+ if (index !== -1) {
+ uploadsInProgress.splice(index, 1);
+ this.refs.fileUpload.cancelUpload(filename);
}
}
+
var draft = PostStore.getCurrentDraft();
if (!draft) {
draft = {}
@@ -193,8 +202,10 @@ module.exports = React.createClass({
draft['uploadsInProgress'] = [];
}
draft['previews'] = previews;
+ draft['uploadsInProgress'] = uploadsInProgress;
PostStore.storeCurrentDraft(draft);
- this.setState({previews: previews});
+
+ this.setState({previews: previews, uploadsInProgress: uploadsInProgress});
},
componentDidMount: function() {
ChannelStore.addChangeListener(this._onChange);
@@ -270,6 +281,7 @@ module.exports = React.createClass({
id="post_textbox"
ref="textbox" />
<FileUpload
+ ref='fileUpload'
getFileCount={this.getFileCount}
onUploadStart={this.handleUploadStart}
onFileUpload={this.handleFileUploadComplete}
diff --git a/web/react/components/file_preview.jsx b/web/react/components/file_preview.jsx
index 2b4e459f1..8218429fd 100644
--- a/web/react/components/file_preview.jsx
+++ b/web/react/components/file_preview.jsx
@@ -45,8 +45,9 @@ module.exports = React.createClass({
this.props.uploadsInProgress.forEach(function(filename) {
previews.push(
- <div className="preview-div">
+ <div className="preview-div" data-filename={filename}>
<img className="spinner" src="/static/images/load.gif"/>
+ <a className="remove-preview" onClick={this.handleRemove}><i className="glyphicon glyphicon-remove"/></a>
</div>
);
}.bind(this));
diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx
index c02afc5e9..11b3b3cee 100644
--- a/web/react/components/file_upload.jsx
+++ b/web/react/components/file_upload.jsx
@@ -4,8 +4,12 @@
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');
@@ -40,16 +44,26 @@ module.exports = React.createClass({
formData.append('channel_id', channel_id);
formData.append('files', files[i], files[i].name);
- client.uploadFile(formData,
+ var request = client.uploadFile(formData,
function(data) {
parsedData = $.parseJSON(data);
this.props.onFileUpload(parsedData['filenames'], channel_id);
+
+ var requests = this.state.requests;
+ for (var i = 0; i < parsedData['filenames'].length; i++) {
+ delete requests[utils.getFileName(parsedData['filenames'][i])];
+ }
+ this.setState({requests: requests});
}.bind(this),
function(err) {
this.props.onUploadError(err);
}.bind(this)
);
+ var requests = this.state.requests;
+ requests[files[i].name] = request;
+ this.setState({requests: requests});
+
this.props.onUploadStart([files[i].name], channel_id);
}
@@ -121,18 +135,39 @@ module.exports = React.createClass({
function(data) {
parsedData = $.parseJSON(data);
self.props.onFileUpload(parsedData['filenames'], channel_id);
+
+ var requests = self.state.requests;
+ for (var i = 0; i < parsedData['filenames'].length; i++) {
+ delete requests[utils.getFileName(parsedData['filenames'][i])];
+ }
+ self.setState({requests: requests});
},
function(err) {
self.props.onUploadError(err);
}
);
+ var requests = self.state.requests;
+ requests[files[i].name] = request;
+ self.setState({requests: requests});
+
self.props.onUploadStart([name], channel_id);
}
}
}
});
},
+ cancelUpload: function(filename) {
+ var requests = this.state.requests;
+ var request = requests[filename];
+
+ if (request) {
+ request.abort();
+
+ delete requests[filename];
+ 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>
diff --git a/web/react/utils/client.jsx b/web/react/utils/client.jsx
index b8eda0075..d979515ef 100644
--- a/web/react/utils/client.jsx
+++ b/web/react/utils/client.jsx
@@ -762,7 +762,7 @@ module.exports.getProfiles = function(success, error) {
};
module.exports.uploadFile = function(formData, success, error) {
- $.ajax({
+ var request = $.ajax({
url: "/api/v1/files/upload",
type: 'POST',
data: formData,
@@ -771,12 +771,16 @@ module.exports.uploadFile = function(formData, success, error) {
processData: false,
success: success,
error: function(xhr, status, err) {
- e = handleError("uploadFile", xhr, status, err);
- error(e);
+ if (err !== 'abort') {
+ e = handleError("uploadFile", xhr, status, err);
+ error(e);
+ }
}
});
module.exports.track('api', 'api_files_upload');
+
+ return request;
};
module.exports.getPublicLink = function(data, success, error) {