mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 17:33:14 +01:00
Implement lazy blob creation routine and increase robustness of upload button template for react-fineuploader
This commit is contained in:
parent
3e22ad1d9d
commit
deceb61c60
@ -2,6 +2,8 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||
|
||||
import ReactS3FineUploader from '../ascribe_uploader/react_s3_fine_uploader';
|
||||
import UploadButton from '../ascribe_uploader/ascribe_upload_button/upload_button';
|
||||
|
||||
@ -29,24 +31,41 @@ const UploadFileButton = React.createClass({
|
||||
fileClassToUpload: shape({
|
||||
singular: string,
|
||||
plural: string
|
||||
}).isRequired
|
||||
}).isRequired,
|
||||
createBlobRoutine: shape({
|
||||
url: string,
|
||||
pieceId: number
|
||||
})
|
||||
},
|
||||
|
||||
submitFile(file) {
|
||||
console.log(file);
|
||||
getInitialState() {
|
||||
return {
|
||||
file: null
|
||||
};
|
||||
},
|
||||
|
||||
handleSubmitFile(file) {
|
||||
this.setState({
|
||||
file
|
||||
});
|
||||
},
|
||||
|
||||
createBlobRoutine() {
|
||||
const { fineuploader } = this.refs;
|
||||
const { file } = this.state;
|
||||
|
||||
fineuploader.createBlob(file);
|
||||
},
|
||||
|
||||
render() {
|
||||
|
||||
const { fileClassToUpload, validation, keyRoutine } = this.props;
|
||||
const { fileClassToUpload, validation, keyRoutine, createBlobRoutine } = this.props;
|
||||
|
||||
return (
|
||||
<ReactS3FineUploader
|
||||
ref="fineuploader"
|
||||
fileInputElement={UploadButton}
|
||||
keyRoutine={keyRoutine}
|
||||
createBlobRoutine={{
|
||||
url: ApiUrls.blob_contracts
|
||||
}}
|
||||
createBlobRoutine={createBlobRoutine}
|
||||
validation={validation}
|
||||
setIsUploadReady={() =>{/* So that ReactS3FineUploader is not complaining */}}
|
||||
signature={{
|
||||
@ -65,9 +84,9 @@ const UploadFileButton = React.createClass({
|
||||
}}
|
||||
fileClassToUpload={fileClassToUpload}
|
||||
isReadyForFormSubmission={formSubmissionValidation.atLeastOneUploadedFile}
|
||||
submitFile={this.submitFile}
|
||||
submitFile={this.handleSubmitFile}
|
||||
location={this.props.location}/>
|
||||
);
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -2,8 +2,11 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||
|
||||
import { displayValidProgressFilesFilter } from '../react_s3_fine_uploader_utils';
|
||||
import { getLangText } from '../../../utils/lang_utils';
|
||||
import { truncateTextAtCharIndex } from '../../../utils/general_utils';
|
||||
|
||||
|
||||
let UploadButton = React.createClass({
|
||||
@ -37,6 +40,10 @@ let UploadButton = React.createClass({
|
||||
return this.props.filesToUpload.filter((file) => file.status === 'uploading');
|
||||
},
|
||||
|
||||
getUploadedFile() {
|
||||
return this.props.filesToUpload.filter((file) => file.status === 'upload successful')[0];
|
||||
},
|
||||
|
||||
handleOnClick() {
|
||||
let uploadingFiles = this.getUploadingFiles();
|
||||
|
||||
@ -57,14 +64,22 @@ let UploadButton = React.createClass({
|
||||
},
|
||||
|
||||
getButtonLabel() {
|
||||
const uploadedFile = this.getUploadedFile();
|
||||
let { filesToUpload, fileClassToUpload } = this.props;
|
||||
|
||||
// filter invalid files that might have been deleted or canceled...
|
||||
filesToUpload = filesToUpload.filter(displayValidProgressFilesFilter);
|
||||
|
||||
// Depending on wether there is an upload going on or not we
|
||||
// display the progress
|
||||
if(filesToUpload.length > 0) {
|
||||
// Depending on whether there is an upload going on or not we
|
||||
// display the progress or the successfully uploaded file's name
|
||||
if(uploadedFile) {
|
||||
return (
|
||||
<span>
|
||||
<Glyphicon glyph="ok" />
|
||||
{' ' + truncateTextAtCharIndex(uploadedFile.name, 20)}
|
||||
</span>
|
||||
);
|
||||
} else if(filesToUpload.length > 0) {
|
||||
return getLangText('Upload progress') + ': ' + Math.ceil(filesToUpload[0].progress) + '%';
|
||||
} else {
|
||||
return fileClassToUpload.singular;
|
||||
@ -74,7 +89,6 @@ let UploadButton = React.createClass({
|
||||
render() {
|
||||
let {
|
||||
multiple,
|
||||
fileClassToUpload,
|
||||
allowedExtensions
|
||||
} = this.props;
|
||||
|
||||
@ -82,7 +96,7 @@ let UploadButton = React.createClass({
|
||||
<button
|
||||
onClick={this.handleOnClick}
|
||||
className="btn btn-default btn-sm margin-left-2px"
|
||||
disabled={this.getUploadingFiles().length !== 0}>
|
||||
disabled={this.getUploadingFiles().length !== 0 || !!this.getUploadedFile()}>
|
||||
{this.getButtonLabel()}
|
||||
<input
|
||||
multiple={multiple}
|
||||
|
@ -308,47 +308,58 @@ let ReactS3FineUploader = React.createClass({
|
||||
},
|
||||
|
||||
createBlob(file) {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
window.fetch(this.props.createBlobRoutine.url, {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': getCookie(AppConstants.csrftoken)
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({
|
||||
'filename': file.name,
|
||||
'key': file.key,
|
||||
'piece_id': this.props.createBlobRoutine.pieceId
|
||||
const { createBlobRoutine } = this.props;
|
||||
|
||||
// returning here without doing anything enables us to
|
||||
// lazy create the blob at any time after the upload
|
||||
if(!createBlobRoutine) {
|
||||
return null;
|
||||
} else {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
window.fetch(createBlobRoutine.url, {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': getCookie(AppConstants.csrftoken)
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({
|
||||
'filename': file.name,
|
||||
'key': file.key,
|
||||
'piece_id': createBlobRoutine.pieceId
|
||||
})
|
||||
})
|
||||
})
|
||||
.then((res) => {
|
||||
return res.json();
|
||||
})
|
||||
.then((res) => {
|
||||
if(res.otherdata) {
|
||||
file.s3Url = res.otherdata.url_safe;
|
||||
file.s3UrlSafe = res.otherdata.url_safe;
|
||||
} else if(res.digitalwork) {
|
||||
file.s3Url = res.digitalwork.url_safe;
|
||||
file.s3UrlSafe = res.digitalwork.url_safe;
|
||||
} else if(res.contractblob) {
|
||||
file.s3Url = res.contractblob.url_safe;
|
||||
file.s3UrlSafe = res.contractblob.url_safe;
|
||||
} else {
|
||||
throw new Error(getLangText('Could not find a url to download.'));
|
||||
}
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err, false, {
|
||||
files: this.state.filesToUpload,
|
||||
chunks: this.state.chunks
|
||||
.then((res) => {
|
||||
return res.json();
|
||||
})
|
||||
.then((res) => {
|
||||
if(res.otherdata) {
|
||||
file.s3Url = res.otherdata.url_safe;
|
||||
file.s3UrlSafe = res.otherdata.url_safe;
|
||||
} else if(res.digitalwork) {
|
||||
file.s3Url = res.digitalwork.url_safe;
|
||||
file.s3UrlSafe = res.digitalwork.url_safe;
|
||||
} else if(res.contractblob) {
|
||||
file.s3Url = res.contractblob.url_safe;
|
||||
file.s3UrlSafe = res.contractblob.url_safe;
|
||||
} else if(res.thumbnail) {
|
||||
file.s3Url = res.thumbnail.url_safe;
|
||||
file.s3UrlSafe = res.thumbnail.url_safe;
|
||||
} else {
|
||||
throw new Error(getLangText('Could not find a url to download.'));
|
||||
}
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err, false, {
|
||||
files: this.state.filesToUpload,
|
||||
chunks: this.state.chunks
|
||||
});
|
||||
reject(err);
|
||||
});
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/* FineUploader specific callback function handlers */
|
||||
@ -404,39 +415,47 @@ let ReactS3FineUploader = React.createClass({
|
||||
let filesToUpload = React.addons.update(this.state.filesToUpload, { $set: files });
|
||||
this.setState({ filesToUpload });
|
||||
|
||||
// Only after the blob has been created server-side, we can make the form submittable.
|
||||
this.createBlob(files[id])
|
||||
.then(() => {
|
||||
// since the form validation props isReadyForFormSubmission, setIsUploadReady and submitFile
|
||||
// are optional, we'll only trigger them when they're actually defined
|
||||
if(this.props.submitFile) {
|
||||
this.props.submitFile(files[id]);
|
||||
} else {
|
||||
console.warn('You didn\'t define submitFile in as a prop in react-s3-fine-uploader');
|
||||
}
|
||||
|
||||
// for explanation, check comment of if statement above
|
||||
if(this.props.isReadyForFormSubmission && this.props.setIsUploadReady) {
|
||||
// also, lets check if after the completion of this upload,
|
||||
// the form is ready for submission or not
|
||||
if(this.props.isReadyForFormSubmission(this.state.filesToUpload)) {
|
||||
// if so, set uploadstatus to true
|
||||
this.props.setIsUploadReady(true);
|
||||
const createBlobResult = this.createBlob(files[id]);
|
||||
if(!createBlobResult) {
|
||||
if(this.props.submitFile) {
|
||||
this.props.submitFile(files[id]);
|
||||
} else {
|
||||
console.warn('You didn\'t define submitFile in as a prop in react-s3-fine-uploader');
|
||||
}
|
||||
} else {
|
||||
// Only after the blob has been created server-side, we can make the form submittable.
|
||||
this.createBlob(files[id])
|
||||
.then(() => {
|
||||
// since the form validation props isReadyForFormSubmission, setIsUploadReady and submitFile
|
||||
// are optional, we'll only trigger them when they're actually defined
|
||||
if(this.props.submitFile) {
|
||||
this.props.submitFile(files[id]);
|
||||
} else {
|
||||
this.props.setIsUploadReady(false);
|
||||
console.warn('You didn\'t define submitFile in as a prop in react-s3-fine-uploader');
|
||||
}
|
||||
} else {
|
||||
console.warn('You didn\'t define the functions isReadyForFormSubmission and/or setIsUploadReady in as a prop in react-s3-fine-uploader');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err, false, {
|
||||
files: this.state.filesToUpload,
|
||||
chunks: this.state.chunks
|
||||
// for explanation, check comment of if statement above
|
||||
if(this.props.isReadyForFormSubmission && this.props.setIsUploadReady) {
|
||||
// also, lets check if after the completion of this upload,
|
||||
// the form is ready for submission or not
|
||||
if(this.props.isReadyForFormSubmission(this.state.filesToUpload)) {
|
||||
// if so, set uploadstatus to true
|
||||
this.props.setIsUploadReady(true);
|
||||
} else {
|
||||
this.props.setIsUploadReady(false);
|
||||
}
|
||||
} else {
|
||||
console.warn('You didn\'t define the functions isReadyForFormSubmission and/or setIsUploadReady in as a prop in react-s3-fine-uploader');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err, false, {
|
||||
files: this.state.filesToUpload,
|
||||
chunks: this.state.chunks
|
||||
});
|
||||
let notification = new GlobalNotificationModel(err.message, 'danger', 5000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
});
|
||||
let notification = new GlobalNotificationModel(err.message, 'danger', 5000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user