Comments (10)
So I basically wrapped the s3uploader
in a class that fires events and returns a promise.
Here is the class I called S3FileUploader
:
import Promise from 'bluebird';
import _ from 'lodash';
import klass from 'klass';
import Events from 'events';
import S3Upload from 'react-s3-uploader/s3upload.js';
const EventEmitter = Events.EventEmitter;
const S3FileUploader = klass({
initialize(file, options) {
this.file = file;
this.preview = file.preview || URL.createObjectURL(file);
this.emitter = new EventEmitter();
this.opts = _.defaults(options || {}, {
signingUrl: '/s3/signUpload'
});
},
getFile() {
return this.file;
},
getFileType() {
return this.getFile().type;
},
getPreview() {
return this.preview;
},
getFilename() {
return this.getFile().name;
},
isImage() {
return /^image\//.exec(this.getFileType());
},
getResultS3Filename() {
return this.result && this.result.filename;
},
getPublicUrl() {
return this.result && this.result.publicUrl;
},
on(event, callback) {
this.emitter.addListener(event, callback);
},
off(event, callback) {
this.emitter.removeListener(event, callback);
},
cancel() {
if (this.upload) {
this.upload.abortUpload();
this.emitter.emit('abort');
this.upload = null;
}
},
markFailed() {
this.failed = true;
},
isFailed() {
return !!this.failed;
},
getContentDisposition() {
let isPdf = this.getFileType() == 'application/pdf';
return isPdf ? 'inline' : 'auto';
},
start() {
return new Promise((resolve, reject) => {
this.upload = new S3Upload({
files: [this.file],
signingUrl: this.opts.signingUrl,
signingUrlQueryParams: this.opts.signingUrlQueryParams,
contentDisposition: this.getContentDisposition(),
onProgress: (percent, status) => {
this.emitter.emit('progress', percent, status);
},
onFinishS3Put: (result) => {
this.result = result;
this.emitter.emit('complete', result);
resolve(result);
},
onError: (status) => {
this.emitter.emit('error', status);
this.markFailed();
reject(status);
}
});
this.emitter.once('abort', resolve);
});
}
});
export default S3FileUploader;
And then I'm using this in the onDrop
function called from react-dropzone
:
onDrop(files) {
let existingUploaders = this.state.uploaders;
let existingUploadersByName = _.indexBy(existingUploaders, uploader => uploader.getFilename());
let uploaders = _.map(files, (file) => {
let filename = file.name;
if (existingUploadersByName[filename] || !this.acceptsType(file.type)) {
return null;
}
let uploader = new S3FileUploader(file);
uploader.on('progress', (percent) => {
this.setState({
[`progress-${filename}`]: {
percent: percent,
message: m('common.attachments.uploading')
}
});
});
uploader.on('complete', () => {
this.setState({
[`progress-${filename}`]: {
isComplete: true,
message: m('common.attachments.complete')
}
});
});
uploader.on('error', (status) => {
this.setState({
hasFailedUpload: true,
[`progress-${filename}`]: {
hidePercent: true,
message: status || m('common.attachments.error')
}
});
});
return uploader;
});
uploaders = _.compact(uploaders);
if (!this.props.allowMultiple && uploaders.length) {
_.each(existingUploaders, up => this.removeUpload(up));
existingUploaders = [];
}
this.setState({
uploaders: existingUploaders.concat(uploaders),
uploading: true
});
return Promise.resolve()
.then(() => {
return Promise.each(uploaders, uploader => uploader.start());
})
.finally(() => {
this.setState({ uploading: false });
});
},
from react-s3-uploader.
I am essentially looking for doing the same thing! @seanadkinson do you mind share your solution (after remove all personal credentials of course)?
from react-s3-uploader.
Thank you so much for the explanation!
from react-s3-uploader.
This is great. Thanks!
from react-s3-uploader.
@seanadkinson Could I ask how you are using the progress state from the onProgress event?
What I assumed it was for was being able to show for example a progress bar for each file, until it has completed uploading. So wouldn't it make sense to have an array in the state with progress objects?
from react-s3-uploader.
@sniepoort With this code, I instantiate a new S3FileUploader
to wrap each uploaded file. That means I actually have an array of uploaders (which I keep in this.state.uploaders
), instead of an array of progress objects.
from react-s3-uploader.
Thanks for getting back to me :)
I can see that, but as far as I can tell, the array of uploaders don't have a progress state on them? They don't get updated onProgress, or am I missing something?
from react-s3-uploader.
Sorry, its been awhile since I've looked at this code. It looks like each S3FileUploader
has an emitter that subscribes to the upload events when you call start()
. And there is an on()
method that let's you subscribe to events on the uploader.
So I'd expect you to be able to get updates from the progress of the uploader by doing something like:
let uploader = new S3FileUploader(...);
uploader.on('progress', this.updateProgressBar);
uploader.start();
Does that help?
In my usage, I'm definitely rendering a progress bar per file upload, so let me know if you'd like me to go dig up some code to help.
from react-s3-uploader.
Ah yes, I was also going in that direction. But how do you bind the updateProgressBar with each uploader? I'm guessing in the render you would loop over the uploaders then?
Would be really great if you had a moment to dig up some code :) Always nice to save some time!
from react-s3-uploader.
@sniepoort Actually the code I was thinking about is already pasted above: #43 (comment)
Here is a snippet of how it is used. We actually render a percent, not a progress bar, but it should be easy to modify.
getUploaderStatus(uploader) {
let filename = uploader.getFilename();
let progress = this.state[`progress-${filename}`];
if (progress && progress.isComplete) {
return (
<a className="upload-link" href={uploader.getPublicUrl()} target="_blank">
{filename}
</a>
);
}
let progressMessage = progress ? progress.message : m('common.attachments.waiting');
let progressPercent = progress && !progress.hidePercent ? progress.percent + '%' : '';
return `${filename}: ${progressMessage} ${progressPercent}`;
}
from react-s3-uploader.
Related Issues (20)
- MultipartUpload support? HOT 1
- Method Not Allowed 405 PUT Error
- index.d.ts missing methods/props HOT 1
- ReactS3Uploader.propTypes is undefined when deployed on Heroku HOT 3
- Domentation for all the props
- iPhone camera video quality issue
- Console Warning: getDefaultProps is only used on classic React.createClass...
- Content-Type is blank when uploading HOT 3
- How to notify server of image upload? HOT 1
- Is the "accept" prop even being used? Where can we find a list of valid prop arguments? (Duplication of #220) HOT 2
- Return boolean or Promise on file upload
- Can't limit upload size HOT 1
- Getting CORS error on uploading file on AWS S3 HOT 3
- Unable to generate a valid signed upload URL for Digital Ocean spaces
- Type for signingUrlHeaders is wrong HOT 2
- findDOMNode is deprecated in StrictMode HOT 1
- Uncaught ReferenceError: process is not defined - Chrome browser Console error HOT 2
- Upload error 400 after onProgress reports all the way through 100% HOT 4
- Mime-types modules is not intended to be used with browser HOT 2
- Upload error: Could not contact request signing server
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-s3-uploader.