mirror of
https://github.com/ascribe/onion.git
synced 2024-11-15 09:35:10 +01:00
307 lines
9.3 KiB
JavaScript
307 lines
9.3 KiB
JavaScript
'use strict';
|
|
|
|
import React from 'react/addons';
|
|
|
|
import promise from 'es6-promise';
|
|
promise.polyfill();
|
|
|
|
import fetch from 'isomorphic-fetch';
|
|
|
|
import fineUploader from 'fineUploader';
|
|
import FileDragAndDrop from './file_drag_and_drop';
|
|
|
|
var ReactS3FineUploader = React.createClass({
|
|
|
|
propTypes: {
|
|
keyRoutine: React.PropTypes.shape({
|
|
url: React.PropTypes.string,
|
|
fileClass: React.PropTypes.string
|
|
}),
|
|
createBlobRoutine: React.PropTypes.shape({
|
|
url: React.PropTypes.string
|
|
}),
|
|
handleChange: React.PropTypes.func,
|
|
autoUpload: React.PropTypes.bool,
|
|
debug: React.PropTypes.bool,
|
|
objectProperties: React.PropTypes.shape({
|
|
acl: React.PropTypes.string
|
|
}),
|
|
request: React.PropTypes.shape({
|
|
endpoint: React.PropTypes.string,
|
|
accessKey: React.PropTypes.string,
|
|
params: React.PropTypes.shape({
|
|
csrfmiddlewaretoken: React.PropTypes.string
|
|
})
|
|
}),
|
|
signature: React.PropTypes.shape({
|
|
endpoint: React.PropTypes.string
|
|
}),
|
|
uploadSuccess: React.PropTypes.shape({
|
|
method: React.PropTypes.string,
|
|
endpoint: React.PropTypes.string,
|
|
params: React.PropTypes.shape({
|
|
isBrowserPreviewCapable: React.PropTypes.any, // maybe fix this later
|
|
bitcoin_ID_noPrefix: React.PropTypes.string
|
|
})
|
|
}),
|
|
cors: React.PropTypes.shape({
|
|
expected: React.PropTypes.bool
|
|
}),
|
|
chunking: React.PropTypes.shape({
|
|
enabled: React.PropTypes.bool
|
|
}),
|
|
resume: React.PropTypes.shape({
|
|
enabled: React.PropTypes.bool
|
|
}),
|
|
deleteFile: React.PropTypes.shape({
|
|
enabled: React.PropTypes.bool,
|
|
method: React.PropTypes.string,
|
|
endpoint: React.PropTypes.string
|
|
}),
|
|
session: React.PropTypes.shape({
|
|
endpoint: React.PropTypes.bool
|
|
}),
|
|
validation: React.PropTypes.shape({
|
|
itemLimit: React.PropTypes.number,
|
|
sizeLimit: React.PropTypes.string
|
|
}),
|
|
messages: React.PropTypes.shape({
|
|
unsupportedBrowser: React.PropTypes.string
|
|
}),
|
|
formatFileName: React.PropTypes.func,
|
|
multiple: React.PropTypes.bool,
|
|
retry: React.PropTypes.shape({
|
|
enableAuto: React.PropTypes.bool
|
|
})
|
|
},
|
|
|
|
getInitialState() {
|
|
return {
|
|
filesToUpload: [],
|
|
uploader: new fineUploader.s3.FineUploaderBasic(this.propsToConfig())
|
|
};
|
|
},
|
|
|
|
propsToConfig() {
|
|
let objectProperties = this.props.objectProperties;
|
|
objectProperties.key = this.requestKey;
|
|
|
|
return {
|
|
autoUpload: this.props.autoUpload,
|
|
debug: this.props.debug,
|
|
objectProperties: objectProperties, // do a special key handling here
|
|
request: this.props.request,
|
|
signature: this.props.signature,
|
|
uploadSuccess: this.props.uploadSuccess,
|
|
cors: this.props.cors,
|
|
chunking: this.props.chunking,
|
|
resume: this.props.resume,
|
|
deleteFile: this.props.deleteFile,
|
|
session: this.props.session,
|
|
validation: this.props.validation,
|
|
messages: this.props.messages,
|
|
formatFileName: this.props.formatFileName,
|
|
multiple: this.props.multiple,
|
|
retry: this.props.retry,
|
|
callbacks: {
|
|
onSubmit: this.onSubmit,
|
|
onComplete: this.onComplete,
|
|
onDelete: this.onDelete,
|
|
onSessionRequestComplete: this.onSessionRequestComplete,
|
|
onProgress: this.onProgress,
|
|
onRetry: this.onRetry,
|
|
onAutoRetry: this.onAutoRetry,
|
|
onManualRetry: this.onManualRetry,
|
|
onDeleteComplete: this.onDeleteComplete
|
|
}
|
|
};
|
|
},
|
|
|
|
getCookie(name) {
|
|
console.log(document.cookie);
|
|
let value = '; ' + document.cookie;
|
|
let parts = value.split('; ' + name + '=');
|
|
if (parts.length === 2) {
|
|
return parts.pop().split(';').shift();
|
|
}
|
|
},
|
|
requestKey(fileId) {
|
|
let filename = this.state.uploader.getName(fileId);
|
|
let defer = new fineUploader.Promise();
|
|
fetch(this.props.keyRoutine.url, {
|
|
method: 'post',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'X-CSRFToken': this.getCookie('csrftoken')
|
|
},
|
|
credentials: 'include',
|
|
body: JSON.stringify({
|
|
'filename': filename,
|
|
'file_class': 'digitalwork'
|
|
})
|
|
})
|
|
.then((res) => {
|
|
return res.json();
|
|
})
|
|
.then((res) =>{
|
|
defer.success(res.key);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
});
|
|
return defer;
|
|
},
|
|
|
|
/* FineUploader specific callback function handlers */
|
|
|
|
onSubmit() {
|
|
console.log('submit');
|
|
},
|
|
|
|
onComplete(id) {
|
|
let files = this.state.filesToUpload;
|
|
files[id].status = 'upload successful';
|
|
files[id].key = this.state.uploader.getKey(id);
|
|
|
|
let newState = React.addons.update(this.state, {
|
|
filesToUpload: { $set: files }
|
|
});
|
|
this.setState(newState);
|
|
this.createBlob(files[id]);
|
|
this.props.handleChange();
|
|
console.log('completed ' + files[id].name);
|
|
},
|
|
|
|
createBlob(file) {
|
|
let defer = new fineUploader.Promise();
|
|
fetch(this.props.createBlobRoutine.url, {
|
|
method: 'post',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'X-CSRFToken': this.getCookie('csrftoken')
|
|
},
|
|
credentials: 'include',
|
|
body: JSON.stringify({
|
|
'filename': file.name,
|
|
'key': file.key
|
|
})
|
|
})
|
|
.then((res) => {
|
|
return res.json();
|
|
})
|
|
.then((res) =>{
|
|
defer.success(res.key);
|
|
})
|
|
.catch((err) => {
|
|
console.error(err);
|
|
});
|
|
return defer;
|
|
},
|
|
|
|
onRetry() {
|
|
console.log('retry');
|
|
},
|
|
|
|
onAutoRetry() {
|
|
console.log('autoretry');
|
|
},
|
|
|
|
onManualRetry() {
|
|
console.log('manualretry');
|
|
},
|
|
|
|
onDelete() {
|
|
console.log('delete');
|
|
},
|
|
|
|
onCancel() {
|
|
console.log('cancel');
|
|
},
|
|
|
|
onSessionRequestComplete() {
|
|
console.log('sessionrequestcomplete');
|
|
},
|
|
|
|
onDeleteComplete(id, xhr, isError) {
|
|
if(isError) {
|
|
// also, sync files from state with the ones from fineuploader
|
|
let filesToUpload = JSON.parse(JSON.stringify(this.state.filesToUpload));
|
|
// splice because I can
|
|
filesToUpload.splice(id, 1);
|
|
|
|
// set state
|
|
this.setState({
|
|
filesToUpload: React.addons.update(this.state.filesToUpload, {$set: filesToUpload})
|
|
});
|
|
} else {
|
|
console.log(id);
|
|
// TODO: add global notification
|
|
}
|
|
},
|
|
|
|
onProgress(id, name, uploadedBytes, totalBytes) {
|
|
var newState = React.addons.update(this.state, {
|
|
filesToUpload: { [id]: {
|
|
progress: { $set: (uploadedBytes / totalBytes) * 100} }
|
|
}
|
|
});
|
|
this.setState(newState);
|
|
},
|
|
|
|
handleDeleteFile(fileId) {
|
|
// delete file from server
|
|
this.state.uploader.deleteFile(fileId);
|
|
// this is being continues in onDeleteFile, as
|
|
// fineuploaders deleteFile does not return a correct callback or
|
|
// promise
|
|
},
|
|
|
|
handleUploadFile(files) {
|
|
this.state.uploader.addFiles(files);
|
|
let oldFiles = this.state.filesToUpload;
|
|
let oldAndNewFiles = this.state.uploader.getUploads();
|
|
|
|
// Add fineuploader specific information to new files
|
|
for(let i = 0; i < oldAndNewFiles.length; i++) {
|
|
for(let j = 0; j < files.length; j++) {
|
|
if(oldAndNewFiles[i].originalName === files[j].name) {
|
|
oldAndNewFiles[i].progress = 0;
|
|
oldAndNewFiles[i].type = files[j].type;
|
|
oldAndNewFiles[i].url = URL.createObjectURL(files[j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// and re-add fineuploader specific information for old files as well
|
|
for(let i = 0; i < oldAndNewFiles.length; i++) {
|
|
for(let j = 0; j < oldFiles.length; j++) {
|
|
if(oldAndNewFiles[i].originalName === oldFiles[j].name) {
|
|
oldAndNewFiles[i].progress = oldFiles[j].progress;
|
|
oldAndNewFiles[i].type = oldFiles[j].type;
|
|
oldAndNewFiles[i].url = oldFiles[j].url;
|
|
}
|
|
}
|
|
}
|
|
|
|
let newState = React.addons.update(this.state, {
|
|
filesToUpload: { $set: oldAndNewFiles }
|
|
});
|
|
this.setState(newState);
|
|
},
|
|
|
|
render() {
|
|
return (
|
|
<FileDragAndDrop
|
|
onDrop={this.handleUploadFile}
|
|
filesToUpload={this.state.filesToUpload}
|
|
handleDeleteFile={this.handleDeleteFile}/>
|
|
);
|
|
}
|
|
|
|
});
|
|
|
|
|
|
export default ReactS3FineUploader;
|