mirror of
https://github.com/ascribe/onion.git
synced 2025-01-03 10:25:08 +01:00
implement feedback for hashing functionalitxy
This commit is contained in:
parent
4ec8f6b718
commit
2f24ad8352
@ -5,6 +5,9 @@ import React from 'react';
|
|||||||
import FileDragAndDropDialog from './file_drag_and_drop_dialog';
|
import FileDragAndDropDialog from './file_drag_and_drop_dialog';
|
||||||
import FileDragAndDropPreviewIterator from './file_drag_and_drop_preview_iterator';
|
import FileDragAndDropPreviewIterator from './file_drag_and_drop_preview_iterator';
|
||||||
|
|
||||||
|
import AppConstants from '../../constants/application_constants';
|
||||||
|
|
||||||
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
// Taken from: https://github.com/fedosejev/react-file-drag-and-drop
|
// Taken from: https://github.com/fedosejev/react-file-drag-and-drop
|
||||||
let FileDragAndDrop = React.createClass({
|
let FileDragAndDrop = React.createClass({
|
||||||
@ -26,7 +29,10 @@ let FileDragAndDrop = React.createClass({
|
|||||||
multiple: React.PropTypes.bool,
|
multiple: React.PropTypes.bool,
|
||||||
dropzoneInactive: React.PropTypes.bool,
|
dropzoneInactive: React.PropTypes.bool,
|
||||||
areAssetsDownloadable: React.PropTypes.bool,
|
areAssetsDownloadable: React.PropTypes.bool,
|
||||||
areAssetsEditable: React.PropTypes.bool
|
areAssetsEditable: React.PropTypes.bool,
|
||||||
|
|
||||||
|
// triggers a FileDragAndDrop-global spinner
|
||||||
|
isLoading: React.PropTypes.bool
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDragStart(event) {
|
handleDragStart(event) {
|
||||||
@ -113,7 +119,7 @@ let FileDragAndDrop = React.createClass({
|
|||||||
this.props.handleResumeFile(fileId);
|
this.props.handleResumeFile(fileId);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleOnClick(event) {
|
handleOnClick() {
|
||||||
// when multiple is set to false and the user already uploaded a piece,
|
// when multiple is set to false and the user already uploaded a piece,
|
||||||
// do not propagate event
|
// do not propagate event
|
||||||
if(this.props.dropzoneInactive) {
|
if(this.props.dropzoneInactive) {
|
||||||
@ -140,40 +146,53 @@ let FileDragAndDrop = React.createClass({
|
|||||||
className += this.props.dropzoneInactive ? 'inactive-dropzone' : 'active-dropzone';
|
className += this.props.dropzoneInactive ? 'inactive-dropzone' : 'active-dropzone';
|
||||||
className += this.props.className ? ' ' + this.props.className : '';
|
className += this.props.className ? ' ' + this.props.className : '';
|
||||||
|
|
||||||
return (
|
// if true: triggers a FileDragAndDrop-global spinner
|
||||||
<div
|
if(this.props.isLoading) {
|
||||||
className={className}
|
return (
|
||||||
onDragStart={this.handleDragStart}
|
<div className={className}>
|
||||||
onDrag={this.handleDrop}
|
<p>{getLangText('Computing hashes... This may take a few minutes.')}</p>
|
||||||
onDragEnter={this.handleDragEnter}
|
<img
|
||||||
onDragLeave={this.handleDragLeave}
|
height={35}
|
||||||
onDragOver={this.handleDragOver}
|
className="action-file"
|
||||||
onDrop={this.handleDrop}
|
src={AppConstants.baseUrl + 'static/img/ascribe_animated_medium.gif'} />
|
||||||
onDragEnd={this.handleDragEnd}>
|
</div>
|
||||||
<FileDragAndDropDialog
|
);
|
||||||
multipleFiles={this.props.multiple}
|
} else {
|
||||||
hasFiles={hasFiles}
|
return (
|
||||||
onClick={this.handleOnClick}/>
|
<div
|
||||||
<FileDragAndDropPreviewIterator
|
className={className}
|
||||||
files={this.props.filesToUpload}
|
onDragStart={this.handleDragStart}
|
||||||
handleDeleteFile={this.handleDeleteFile}
|
onDrag={this.handleDrop}
|
||||||
handleCancelFile={this.handleCancelFile}
|
onDragEnter={this.handleDragEnter}
|
||||||
handlePauseFile={this.handlePauseFile}
|
onDragLeave={this.handleDragLeave}
|
||||||
handleResumeFile={this.handleResumeFile}
|
onDragOver={this.handleDragOver}
|
||||||
areAssetsDownloadable={this.props.areAssetsDownloadable}
|
onDrop={this.handleDrop}
|
||||||
areAssetsEditable={this.props.areAssetsEditable}/>
|
onDragEnd={this.handleDragEnd}>
|
||||||
<input
|
<FileDragAndDropDialog
|
||||||
multiple={this.props.multiple}
|
multipleFiles={this.props.multiple}
|
||||||
ref="fileinput"
|
hasFiles={hasFiles}
|
||||||
type="file"
|
onClick={this.handleOnClick}/>
|
||||||
style={{
|
<FileDragAndDropPreviewIterator
|
||||||
display: 'none',
|
files={this.props.filesToUpload}
|
||||||
height: 0,
|
handleDeleteFile={this.handleDeleteFile}
|
||||||
width: 0
|
handleCancelFile={this.handleCancelFile}
|
||||||
}}
|
handlePauseFile={this.handlePauseFile}
|
||||||
onChange={this.handleDrop} />
|
handleResumeFile={this.handleResumeFile}
|
||||||
</div>
|
areAssetsDownloadable={this.props.areAssetsDownloadable}
|
||||||
);
|
areAssetsEditable={this.props.areAssetsEditable}/>
|
||||||
|
<input
|
||||||
|
multiple={this.props.multiple}
|
||||||
|
ref="fileinput"
|
||||||
|
type="file"
|
||||||
|
style={{
|
||||||
|
display: 'none',
|
||||||
|
height: 0,
|
||||||
|
width: 0
|
||||||
|
}}
|
||||||
|
onChange={this.handleDrop} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import React from 'react';
|
|||||||
import ProgressBar from 'react-progressbar';
|
import ProgressBar from 'react-progressbar';
|
||||||
|
|
||||||
import AppConstants from '../../constants/application_constants';
|
import AppConstants from '../../constants/application_constants';
|
||||||
import { getLangText } from '../../utils/lang_utils.js'
|
import { getLangText } from '../../utils/lang_utils.js';
|
||||||
|
|
||||||
let FileDragAndDropPreviewImage = React.createClass({
|
let FileDragAndDropPreviewImage = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -159,7 +159,8 @@ var ReactS3FineUploader = React.createClass({
|
|||||||
return {
|
return {
|
||||||
filesToUpload: [],
|
filesToUpload: [],
|
||||||
uploader: new fineUploader.s3.FineUploaderBasic(this.propsToConfig()),
|
uploader: new fineUploader.s3.FineUploaderBasic(this.propsToConfig()),
|
||||||
csrfToken: getCookie(AppConstants.csrftoken)
|
csrfToken: getCookie(AppConstants.csrftoken),
|
||||||
|
isLoading: false // for hashing feedback
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -495,7 +496,10 @@ var ReactS3FineUploader = React.createClass({
|
|||||||
// md5 hash of a file locally and just upload a txt file containing that hash.
|
// md5 hash of a file locally and just upload a txt file containing that hash.
|
||||||
// This if statement essentially takes care of that solution.
|
// This if statement essentially takes care of that solution.
|
||||||
if(this.props.localHashing) {
|
if(this.props.localHashing) {
|
||||||
|
|
||||||
|
// hashing is very computationally heavy, therefore we're displaying the user a little
|
||||||
|
// spinner
|
||||||
|
this.setState({ isLoading: true });
|
||||||
|
|
||||||
let convertedFilePromises = [];
|
let convertedFilePromises = [];
|
||||||
// "files" is not a classical Javascript array but a Javascript FileList, therefore
|
// "files" is not a classical Javascript array but a Javascript FileList, therefore
|
||||||
@ -514,6 +518,7 @@ var ReactS3FineUploader = React.createClass({
|
|||||||
// with their txt representative
|
// with their txt representative
|
||||||
Promise.all(convertedFilePromises)
|
Promise.all(convertedFilePromises)
|
||||||
.then((convertedFiles) => {
|
.then((convertedFiles) => {
|
||||||
|
|
||||||
// actually replacing all files with their txt-hash representative
|
// actually replacing all files with their txt-hash representative
|
||||||
files = convertedFiles;
|
files = convertedFiles;
|
||||||
|
|
||||||
@ -521,6 +526,10 @@ var ReactS3FineUploader = React.createClass({
|
|||||||
// to the server
|
// to the server
|
||||||
this.state.uploader.addFiles(files);
|
this.state.uploader.addFiles(files);
|
||||||
this.synchronizeFileLists(files);
|
this.synchronizeFileLists(files);
|
||||||
|
|
||||||
|
// we're done hashing so we can show the user his uploads
|
||||||
|
this.setState({ isLoading: false });
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
// if we're running into an error during the hash creation, we'll tell the user
|
// if we're running into an error during the hash creation, we'll tell the user
|
||||||
@ -623,7 +632,8 @@ var ReactS3FineUploader = React.createClass({
|
|||||||
multiple={this.props.multiple}
|
multiple={this.props.multiple}
|
||||||
areAssetsDownloadable={this.props.areAssetsDownloadable}
|
areAssetsDownloadable={this.props.areAssetsDownloadable}
|
||||||
areAssetsEditable={this.props.areAssetsEditable}
|
areAssetsEditable={this.props.areAssetsEditable}
|
||||||
dropzoneInactive={!this.props.areAssetsEditable || !this.props.multiple && this.state.filesToUpload.filter((file) => file.status !== 'deleted' && file.status !== 'canceled' && file.size !== -1).length > 0} />
|
dropzoneInactive={!this.props.areAssetsEditable || !this.props.multiple && this.state.filesToUpload.filter((file) => file.status !== 'deleted' && file.status !== 'canceled' && file.size !== -1).length > 0}
|
||||||
|
isLoading={this.state.isLoading} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
import SparkMD5 from 'spark-md5';
|
import SparkMD5 from 'spark-md5';
|
||||||
|
|
||||||
|
import { getLangText } from './lang_utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a string, creates a text file and returns the URL
|
* Takes a string, creates a text file and returns the URL
|
||||||
*
|
*
|
||||||
@ -55,7 +57,7 @@ export function computeHashOfFile(file) {
|
|||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
fileReader.onerror = function () {
|
fileReader.onerror = function () {
|
||||||
reject(new Error('We weren\'t able to hash your file locally. Try to upload it manually or consider contact us.'));
|
reject(new Error(getLangText('We weren\'t able to hash your file locally. Try to upload it manually or consider contact us.')));
|
||||||
};
|
};
|
||||||
|
|
||||||
function loadNext() {
|
function loadNext() {
|
||||||
|
Loading…
Reference in New Issue
Block a user