fineuploader + register

This commit is contained in:
ddejongh 2015-06-23 13:55:05 +02:00
parent 3f3e9a273f
commit 6dd3e582df
9 changed files with 171 additions and 100 deletions

View File

@ -4,4 +4,5 @@ node_modules
js/**/__tests__
server.js
server.js
js/components/ascribe_uploader/vendor

View File

@ -81,8 +81,8 @@ var FileDragAndDrop = React.createClass({
handleOnClick() {
// Simulate click on hidden file input
var event = document.createEvent("HTMLEvents");
event.initEvent("click", false, true);
var event = document.createEvent('HTMLEvents');
event.initEvent('click', false, true);
this.refs.fileinput.getDOMNode().dispatchEvent(event);
},
@ -101,17 +101,17 @@ var FileDragAndDrop = React.createClass({
onDrop={this.handleDrop}
onDragEnd={this.handleDragEnd}>
{hasFiles ? null : <span>Click or drag to add files</span>}
<FileDragAndDropPreviewIterator
<FileDragAndDropPreviewIterator
files={this.props.filesToUpload}
handleDeleteFile={this.handleDeleteFile}/>
<input
multiple
ref="fileinput"
type="file"
type="file"
style={{
display: 'none',
height:0,
width:0
height: 0,
width: 0
}}
onChange={this.handleDrop} />
</div>

View File

@ -12,24 +12,15 @@ import FileDragAndDrop from './file_drag_and_drop';
var ReactS3FineUploader = React.createClass({
getInitialState() {
return {
filesToUpload: [],
uploader: new fineUploader.s3.FineUploaderBasic(this.propsToConfig())
};
},
componentDidMount() {
//console.log(JSON.stringify(this.propsToConfig()));
//let file = this.state.uploader.getResumableFilesData()[0];
//this.state.uploader.retry('1RKieODp_EBoDPNhISXBDNuA1JKdVuXCWhyk44DTK81WUQvpu3M8TXsKPLkjm3ICSvbbyR2KaHhEysvRQ_s4qHNFCbBiYrZ0Q8clXGCYtzk-');
},
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({
@ -84,9 +75,16 @@ var ReactS3FineUploader = React.createClass({
})
},
getInitialState() {
return {
filesToUpload: [],
uploader: new fineUploader.s3.FineUploaderBasic(this.propsToConfig())
};
},
propsToConfig() {
let objectProperties = this.props.objectProperties;
objectProperties['key'] = this.requestKey;
objectProperties.key = this.requestKey;
return {
autoUpload: this.props.autoUpload,
@ -109,7 +107,7 @@ var ReactS3FineUploader = React.createClass({
onSubmit: this.onSubmit,
onComplete: this.onComplete,
onDelete: this.onDelete,
onSessionRequestComplete: this.onSessionRequestComplete,
onSessionRequestComplete: this.onSessionRequestComplete,
onProgress: this.onProgress,
onRetry: this.onRetry,
onAutoRetry: this.onAutoRetry,
@ -118,6 +116,7 @@ var ReactS3FineUploader = React.createClass({
}
};
},
getCookie(name) {
console.log(document.cookie);
let value = '; ' + document.cookie;
@ -160,8 +159,45 @@ var ReactS3FineUploader = React.createClass({
console.log('submit');
},
onComplete() {
console.log('complete');
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() {
@ -193,13 +229,14 @@ var ReactS3FineUploader = React.createClass({
// 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(fileId, 1);
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
}
},
@ -207,7 +244,7 @@ var ReactS3FineUploader = React.createClass({
onProgress(id, name, uploadedBytes, totalBytes) {
var newState = React.addons.update(this.state, {
filesToUpload: { [id]: {
progress: { $set: (uploadedBytes/totalBytes)*100} }
progress: { $set: (uploadedBytes / totalBytes) * 100} }
}
});
this.setState(newState);
@ -216,7 +253,7 @@ var ReactS3FineUploader = React.createClass({
handleDeleteFile(fileId) {
// delete file from server
this.state.uploader.deleteFile(fileId);
// this is being continues in onDeleteFile, as
// this is being continues in onDeleteFile, as
// fineuploaders deleteFile does not return a correct callback or
// promise
},
@ -241,7 +278,7 @@ var ReactS3FineUploader = React.createClass({
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 = 0;
oldAndNewFiles[i].progress = oldFiles[j].progress;
oldAndNewFiles[i].type = oldFiles[j].type;
oldAndNewFiles[i].url = oldFiles[j].url;
}
@ -256,7 +293,7 @@ var ReactS3FineUploader = React.createClass({
render() {
return (
<FileDragAndDrop
<FileDragAndDrop
onDrop={this.handleUploadFile}
filesToUpload={this.state.filesToUpload}
handleDeleteFile={this.handleDeleteFile}/>

View File

@ -20,16 +20,94 @@ import ReactS3FineUploader from './ascribe_uploader/react_s3_fine_uploader';
import DatePicker from 'react-datepicker/dist/react-datepicker';
let RegisterPiece = React.createClass( {
render() {
mixins: [Router.Navigation],
getInitialState(){
return {digital_work_key: null};
},
handleSuccess(){
let notification = new GlobalNotificationModel('Login successsful', 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
this.transitionTo('pieces');
},
getFormData(){
let data = {};
for (let ref in this.refs.form.refs){
data[this.refs.form.refs[ref].props.name] = this.refs.form.refs[ref].state.value;
}
data.digital_work_key = this.state.digital_work_key;
return data;
},
handleChange(){
this.setState({digital_work_key: this.refs.uploader.refs.fineuploader.state.filesToUpload[0].key})
},
render() {
let buttons = null;
if (this.refs.uploader && this.refs.uploader.refs.fineuploader.state.filesToUpload[0].status === 'upload successful'){
buttons = (
<button type="submit" className="btn ascribe-btn ascribe-btn-login">
Register your artwork
</button>);
}
return (
<div className="row ascribe-row">
<div className="col-md-6">
<FileUploader />
<div className="col-md-5">
<FileUploader
ref='uploader'
handleChange={this.handleChange}/>
<br />
</div>
<div className="col-md-6">
<RegisterPieceForm />
<div className="col-md-7">
<h3 style={{'marginTop': 0}}>Lock down title</h3>
<Form
ref='form'
url={apiUrls.pieces_list}
getFormData={this.getFormData}
handleSuccess={this.handleSuccess}
buttons={buttons}
spinner={
<button className="btn ascribe-btn ascribe-btn-login ascribe-btn-login-spinner">
<img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif" />
</button>
}>
<Property
name='artist_name'
label="Artist Name">
<input
type="text"
placeholder="The name of the creator"
required/>
</Property>
<Property
name='title'
label="Artwork title">
<input
type="text"
placeholder="The title of the artwork"
required/>
</Property>
<Property
name='date_created'
label="Year Created">
<input
type="number"
placeholder="Year Created (e.g. 2015)"
min={0}
required/>
</Property>
<Property
name='num_editions'
label="Number of editions">
<input
type="number"
placeholder="Specify the number of unique editions for this artwork"
min={1}
required/>
</Property>
<hr />
</Form>
</div>
</div>
);
@ -39,13 +117,17 @@ let RegisterPiece = React.createClass( {
let FileUploader = React.createClass( {
render() {
return (
<ReactS3FineUploader
ref='fineuploader'
keyRoutine={{
url: AppConstants.serverUrl + 's3/key/',
fileClass: 'digitalwork'
}}
createBlobRoutine={{
url: apiUrls.blob_digitalworks
}}
handleChange={this.props.handleChange}
autoUpload={true}
debug={false}
objectProperties={{
@ -97,71 +179,11 @@ let FileUploader = React.createClass( {
}
return name;
}}
multiple={true}/>
multiple={false}/>
);
}
});
let RegisterPieceForm = React.createClass({
mixins: [Router.Navigation],
handleSuccess(){
let notification = new GlobalNotificationModel('Login successsful', 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
this.transitionTo('pieces');
},
render() {
return (
<Form
url={apiUrls.pieces_list}
handleSuccess={this.handleSuccess}
buttons={
<button type="submit" className="btn ascribe-btn ascribe-btn-login">
Register your artwork
</button>}
spinner={
<button className="btn ascribe-btn ascribe-btn-login ascribe-btn-login-spinner">
<img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif" />
</button>
}>
<Property
name='artist_name'
label="Artist Name">
<input
type="text"
placeholder="The name of the creator"
required/>
</Property>
<Property
name='title'
label="Artwork title">
<input
type="text"
placeholder="The title of the artwork"
required/>
</Property>
<Property
name='date_created'
label="Year Created">
<InputDate
placeholderText="Year Created (e.g. 2015)" />
</Property>
<Property
name='num_editions'
label="Number of editions">
<input
type="number"
placeholder="Specify the number of unique editions for this artwork"
min={1}
required/>
</Property>
<hr />
</Form>
);
}
});
let InputDate = React.createClass({
propTypes: {
@ -179,6 +201,11 @@ let InputDate = React.createClass({
this.setState({
value: date,
value_formatted: date.format('YYYY')});
let event = document.createEvent('HTMLEvents');
event.initEvent('click', false, true);
document.dispatchEvent(event);
event.target.value = date;
this.props.onChange(event);
},
render: function () {

View File

@ -202,7 +202,7 @@ let APISettings = React.createClass({
},
render() {
let content = <img src={AppConstants.baseUrl + 'static/img/ascribe_animated_medium.gif'} />;
if (this.state.applications.length > 0) {
if (this.state.applications.length > -1) {
content = this.state.applications.map(function(app) {
return (
<Property

View File

@ -5,6 +5,7 @@ import AppConstants from './application_constants';
let apiUrls = {
'applications': AppConstants.apiEndpoint + 'applications/',
'application_token_refresh': AppConstants.apiEndpoint + 'applications/refresh_token/',
'blob_digitalworks': AppConstants.apiEndpoint + 'blob/digitalworks/',
'edition': AppConstants.apiEndpoint + 'editions/${bitcoin_id}/',
'edition_delete': AppConstants.apiEndpoint + 'editions/${edition_id}/',
'edition_remove_from_collection': AppConstants.apiEndpoint + 'ownership/shares/${edition_id}/',

View File

@ -1,7 +1,13 @@
$break-small: 764px;
$break-medium: 991px;
.ascribe-row {
max-width: 600px;
@media screen and (max-width: $break-medium) {
max-width: 600px;
}
@media screen and (min-width: $break-medium) {
max-width: 1200px;
}
margin: 0 auto
}

View File

@ -89,7 +89,6 @@
}
input, pre, textarea {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-weight: 400;
font-size: 1.1em;
width:100%;
@ -97,6 +96,7 @@
border: 0;
background-color: rgba(0,0,0,0);
color: #38BAAD;
padding-left: 0;
&:focus {
border:0;

View File

@ -22,7 +22,6 @@ $BASE_URL: '<%= BASE_URL %>';
@import 'ascribe_piece_register';
@import 'offset_right';
@import 'ascribe_settings';
@import '../node_modules/react-s3-fineuploader/scss/ascribe-theme';
body {
background-color: #FDFDFD;