Added the ability to cancel file uploads on posts

Этот коммит содержится в:
hmhealey
2015-08-10 08:41:18 -04:00
родитель 20d755f3dd
Коммит 4e8af44370
4 изменённых файлов: 62 добавлений и 10 удалений

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

@@ -180,12 +180,21 @@ module.exports = React.createClass({
}, },
removePreview: function(filename) { removePreview: function(filename) {
var previews = this.state.previews; var previews = this.state.previews;
for (var i = 0; i < previews.length; i++) { var uploadsInProgress = this.state.uploadsInProgress;
if (previews[i] === filename) {
previews.splice(i, 1); // this can be either an uploaded file or an in progress upload that we need to remove
break; 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(); var draft = PostStore.getCurrentDraft();
if (!draft) { if (!draft) {
draft = {} draft = {}
@@ -193,8 +202,10 @@ module.exports = React.createClass({
draft['uploadsInProgress'] = []; draft['uploadsInProgress'] = [];
} }
draft['previews'] = previews; draft['previews'] = previews;
draft['uploadsInProgress'] = uploadsInProgress;
PostStore.storeCurrentDraft(draft); PostStore.storeCurrentDraft(draft);
this.setState({previews: previews});
this.setState({previews: previews, uploadsInProgress: uploadsInProgress});
}, },
componentDidMount: function() { componentDidMount: function() {
ChannelStore.addChangeListener(this._onChange); ChannelStore.addChangeListener(this._onChange);
@@ -270,6 +281,7 @@ module.exports = React.createClass({
id="post_textbox" id="post_textbox"
ref="textbox" /> ref="textbox" />
<FileUpload <FileUpload
ref='fileUpload'
getFileCount={this.getFileCount} getFileCount={this.getFileCount}
onUploadStart={this.handleUploadStart} onUploadStart={this.handleUploadStart}
onFileUpload={this.handleFileUploadComplete} onFileUpload={this.handleFileUploadComplete}

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

@@ -45,8 +45,9 @@ module.exports = React.createClass({
this.props.uploadsInProgress.forEach(function(filename) { this.props.uploadsInProgress.forEach(function(filename) {
previews.push( previews.push(
<div className="preview-div"> <div className="preview-div" data-filename={filename}>
<img className="spinner" src="/static/images/load.gif"/> <img className="spinner" src="/static/images/load.gif"/>
<a className="remove-preview" onClick={this.handleRemove}><i className="glyphicon glyphicon-remove"/></a>
</div> </div>
); );
}.bind(this)); }.bind(this));

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

@@ -4,8 +4,12 @@
var client = require('../utils/client.jsx'); var client = require('../utils/client.jsx');
var Constants = require('../utils/constants.jsx'); var Constants = require('../utils/constants.jsx');
var ChannelStore = require('../stores/channel_store.jsx'); var ChannelStore = require('../stores/channel_store.jsx');
var utils = require('../utils/utils.jsx');
module.exports = React.createClass({ module.exports = React.createClass({
getInitialState: function() {
return {requests: {}};
},
handleChange: function() { handleChange: function() {
var element = $(this.refs.fileInput.getDOMNode()); var element = $(this.refs.fileInput.getDOMNode());
var files = element.prop('files'); var files = element.prop('files');
@@ -40,16 +44,26 @@ module.exports = React.createClass({
formData.append('channel_id', channel_id); formData.append('channel_id', channel_id);
formData.append('files', files[i], files[i].name); formData.append('files', files[i], files[i].name);
client.uploadFile(formData, var request = client.uploadFile(formData,
function(data) { function(data) {
parsedData = $.parseJSON(data); parsedData = $.parseJSON(data);
this.props.onFileUpload(parsedData['filenames'], channel_id); 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), }.bind(this),
function(err) { function(err) {
this.props.onUploadError(err); this.props.onUploadError(err);
}.bind(this) }.bind(this)
); );
var requests = this.state.requests;
requests[files[i].name] = request;
this.setState({requests: requests});
this.props.onUploadStart([files[i].name], channel_id); this.props.onUploadStart([files[i].name], channel_id);
} }
@@ -121,18 +135,39 @@ module.exports = React.createClass({
function(data) { function(data) {
parsedData = $.parseJSON(data); parsedData = $.parseJSON(data);
self.props.onFileUpload(parsedData['filenames'], channel_id); 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) { function(err) {
self.props.onUploadError(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); 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() { render: function() {
return ( 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"></i></span><input ref="fileInput" type="file" onChange={this.handleChange} multiple/></span>

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

@@ -762,7 +762,7 @@ module.exports.getProfiles = function(success, error) {
}; };
module.exports.uploadFile = function(formData, success, error) { module.exports.uploadFile = function(formData, success, error) {
$.ajax({ var request = $.ajax({
url: "/api/v1/files/upload", url: "/api/v1/files/upload",
type: 'POST', type: 'POST',
data: formData, data: formData,
@@ -771,12 +771,16 @@ module.exports.uploadFile = function(formData, success, error) {
processData: false, processData: false,
success: success, success: success,
error: function(xhr, status, err) { error: function(xhr, status, err) {
e = handleError("uploadFile", xhr, status, err); if (err !== 'abort') {
error(e); e = handleError("uploadFile", xhr, status, err);
error(e);
}
} }
}); });
module.exports.track('api', 'api_files_upload'); module.exports.track('api', 'api_files_upload');
return request;
}; };
module.exports.getPublicLink = function(data, success, error) { module.exports.getPublicLink = function(data, success, error) {