mirror of
https://github.com/ascribe/onion.git
synced 2024-12-23 01:39:36 +01:00
Merge remote-tracking branch 'remotes/origin/AD-456-ikonotv-branded-page-for-registra' into AD-943-add-custom-additional-fields
This commit is contained in:
commit
d4799318a8
@ -37,11 +37,11 @@ class ContractAgreementListActions {
|
||||
|
||||
fetchAvailableContractAgreementList(issuer){
|
||||
return Q.Promise((resolve, reject) => {
|
||||
this.actions.fetchContractAgreementList(issuer, 'True', null)
|
||||
this.actions.fetchContractAgreementList(issuer, true, null)
|
||||
.then((contractAgreementListAccepted) => {
|
||||
if (!contractAgreementListAccepted) {
|
||||
// fetch pending agreements if no accepted ones
|
||||
return this.actions.fetchContractAgreementList(issuer, null, 'True');
|
||||
return this.actions.fetchContractAgreementList(issuer, null, true);
|
||||
}
|
||||
else {
|
||||
resolve(contractAgreementListAccepted);
|
||||
|
@ -46,7 +46,6 @@ requests.defaults({
|
||||
|
||||
|
||||
class AppGateway {
|
||||
|
||||
start() {
|
||||
let settings;
|
||||
let subdomain = window.location.host.split('.')[0];
|
||||
|
@ -21,7 +21,7 @@ let AclProxy = React.createClass({
|
||||
},
|
||||
|
||||
getChildren() {
|
||||
if (this.props.children.length && this.props.children.length > 1){
|
||||
if (React.Children.count(this.props.children) > 1){
|
||||
/*
|
||||
This might ruin styles for header items in the navbar etc
|
||||
*/
|
||||
|
@ -65,12 +65,12 @@ let Form = React.createClass({
|
||||
reset() {
|
||||
// If onReset prop is defined from outside,
|
||||
// notify component that a form reset is happening.
|
||||
if(this.props.onReset && typeof this.props.onReset === 'function') {
|
||||
if(typeof this.props.onReset === 'function') {
|
||||
this.props.onReset();
|
||||
}
|
||||
|
||||
for(let ref in this.refs) {
|
||||
if (this.refs[ref].reset && typeof this.refs[ref].reset === 'function'){
|
||||
if(typeof this.refs[ref].reset === 'function') {
|
||||
this.refs[ref].reset();
|
||||
}
|
||||
}
|
||||
@ -123,11 +123,12 @@ let Form = React.createClass({
|
||||
|
||||
getFormData() {
|
||||
let data = {};
|
||||
for(let ref in this.refs){
|
||||
|
||||
for(let ref in this.refs) {
|
||||
data[this.refs[ref].props.name] = this.refs[ref].state.value;
|
||||
}
|
||||
|
||||
if (this.props.getFormData && typeof this.props.getFormData === 'function'){
|
||||
if(typeof this.props.getFormData === 'function') {
|
||||
data = mergeOptionsWithDuplicates(data, this.props.getFormData());
|
||||
}
|
||||
|
||||
@ -135,16 +136,16 @@ let Form = React.createClass({
|
||||
},
|
||||
|
||||
handleChangeChild(){
|
||||
this.setState({edited: true});
|
||||
this.setState({ edited: true });
|
||||
},
|
||||
|
||||
handleSuccess(response){
|
||||
if(this.props.handleSuccess && typeof this.props.handleSuccess === 'function') {
|
||||
if(typeof this.props.handleSuccess === 'function') {
|
||||
this.props.handleSuccess(response);
|
||||
}
|
||||
|
||||
for(let ref in this.refs) {
|
||||
if(this.refs[ref] && this.refs[ref].handleSuccess && typeof this.refs[ref].handleSuccess === 'function'){
|
||||
if(this.refs[ref] && typeof this.refs[ref].handleSuccess === 'function'){
|
||||
this.refs[ref].handleSuccess();
|
||||
}
|
||||
}
|
||||
@ -163,8 +164,7 @@ let Form = React.createClass({
|
||||
this.setState({errors: this.state.errors.concat(err.json.errors[input])});
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let formData = this.getFormData();
|
||||
|
||||
// sentry shouldn't post the user's password
|
||||
@ -187,7 +187,7 @@ let Form = React.createClass({
|
||||
|
||||
clearErrors(){
|
||||
for(let ref in this.refs){
|
||||
if (this.refs[ref] && this.refs[ref].clearErrors && typeof this.refs[ref].clearErrors === 'function'){
|
||||
if (this.refs[ref] && typeof this.refs[ref].clearErrors === 'function'){
|
||||
this.refs[ref].clearErrors();
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,15 @@ let LoanForm = React.createClass({
|
||||
this.getContractAgreementsOrCreatePublic(this.props.email);
|
||||
},
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// however, it can also be that at the time the component is mounting,
|
||||
// the email is not defined (because it's asynchronously fetched from the server).
|
||||
// Then we need to update it as soon as it is included into LoanForm's props.
|
||||
if(nextProps && nextProps.email) {
|
||||
this.getContractAgreementsOrCreatePublic(nextProps.email);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
ContractAgreementListStore.unlisten(this.onChange);
|
||||
},
|
||||
@ -66,11 +75,12 @@ let LoanForm = React.createClass({
|
||||
},
|
||||
|
||||
getContractAgreementsOrCreatePublic(email){
|
||||
ContractAgreementListActions.flushContractAgreementList();
|
||||
if (email) {
|
||||
ContractAgreementListActions.fetchAvailableContractAgreementList(email).then(
|
||||
(contractAgreementList) => {
|
||||
if (!contractAgreementList) {
|
||||
ContractAgreementListActions.createContractAgreementFromPublicContract.defer(email);
|
||||
ContractAgreementListActions.createContractAgreementFromPublicContract(email);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -13,7 +13,7 @@ import ApiUrls from '../../constants/api_urls';
|
||||
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
import { mergeOptions } from '../../utils/general_utils';
|
||||
import { isReadyForFormSubmission } from '../ascribe_uploader/react_s3_fine_uploader_utils';
|
||||
import { formSubmissionValidation } from '../ascribe_uploader/react_s3_fine_uploader_utils';
|
||||
|
||||
|
||||
let RegisterPieceForm = React.createClass({
|
||||
@ -100,7 +100,7 @@ let RegisterPieceForm = React.createClass({
|
||||
ignoreFocus={true}>
|
||||
<InputFineUploader
|
||||
setIsUploadReady={this.setIsUploadReady}
|
||||
isReadyForFormSubmission={isReadyForFormSubmission}
|
||||
isReadyForFormSubmission={formSubmissionValidation.atLeastOneUploadedFile}
|
||||
isFineUploaderActive={this.props.isFineUploaderActive}
|
||||
onLoggedOut={this.props.onLoggedOut}
|
||||
editable={this.props.isFineUploaderEditable}
|
||||
|
@ -6,8 +6,11 @@ import ReactAddons from 'react/addons';
|
||||
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
|
||||
import Tooltip from 'react-bootstrap/lib/Tooltip';
|
||||
|
||||
import AppConstants from '../../constants/application_constants';
|
||||
|
||||
import { mergeOptions } from '../../utils/general_utils';
|
||||
|
||||
|
||||
let Property = React.createClass({
|
||||
propTypes: {
|
||||
hidden: React.PropTypes.bool,
|
||||
@ -90,31 +93,41 @@ let Property = React.createClass({
|
||||
},
|
||||
|
||||
reset() {
|
||||
let input = this.refs.input;
|
||||
|
||||
// maybe do reset by reload instead of front end state?
|
||||
this.setState({value: this.state.initialValue});
|
||||
|
||||
if (this.refs.input.state && this.refs.input.state.value) {
|
||||
if(input.state && input.state.value) {
|
||||
// resets the value of a custom react component input
|
||||
this.refs.input.state.value = this.state.initialValue;
|
||||
input.state.value = this.state.initialValue;
|
||||
}
|
||||
|
||||
// resets the value of a plain HTML5 input
|
||||
this.refs.input.getDOMNode().value = this.state.initialValue;
|
||||
// For some reason, if we set the value of a non HTML element (but a custom input),
|
||||
// after a reset, the value will be be propagated to this component.
|
||||
//
|
||||
// Therefore we have to make sure only to reset the initial value
|
||||
// of HTML inputs (which we determine by checking if there 'type' attribute matches
|
||||
// the ones included in AppConstants.possibleInputTypes).
|
||||
let inputDOMNode = input.getDOMNode();
|
||||
if(inputDOMNode.type && typeof inputDOMNode.type === 'string' &&
|
||||
AppConstants.possibleInputTypes.indexOf(inputDOMNode.type.toLowerCase()) > -1) {
|
||||
inputDOMNode.value = this.state.initialValue;
|
||||
}
|
||||
|
||||
// For some inputs, reseting state.value is not enough to visually reset the
|
||||
// component.
|
||||
//
|
||||
// So if the input actually needs a visual reset, it needs to implement
|
||||
// a dedicated reset method.
|
||||
if(this.refs.input.reset && typeof this.refs.input.reset === 'function') {
|
||||
this.refs.input.reset();
|
||||
if(typeof input.reset === 'function') {
|
||||
input.reset();
|
||||
}
|
||||
},
|
||||
|
||||
handleChange(event) {
|
||||
|
||||
this.props.handleChange(event);
|
||||
if (this.props.onChange && typeof this.props.onChange === 'function') {
|
||||
if (typeof this.props.onChange === 'function') {
|
||||
this.props.onChange(event);
|
||||
}
|
||||
|
||||
@ -130,7 +143,7 @@ let Property = React.createClass({
|
||||
|
||||
// if onClick is defined from the outside,
|
||||
// just call it
|
||||
if(this.props.onClick && typeof this.props.onClick === 'function') {
|
||||
if(typeof this.props.onClick === 'function') {
|
||||
this.props.onClick();
|
||||
}
|
||||
|
||||
@ -145,7 +158,7 @@ let Property = React.createClass({
|
||||
isFocused: false
|
||||
});
|
||||
|
||||
if(this.props.onBlur && typeof this.props.onBlur === 'function') {
|
||||
if(typeof this.props.onBlur === 'function') {
|
||||
this.props.onBlur(event);
|
||||
}
|
||||
},
|
||||
@ -237,7 +250,7 @@ let Property = React.createClass({
|
||||
overlay={tooltip}>
|
||||
<div className={'ascribe-settings-property ' + this.props.className}>
|
||||
{this.state.errors}
|
||||
<span>{ this.props.label}</span>
|
||||
<span>{this.props.label}</span>
|
||||
{this.renderChildren(style)}
|
||||
{footer}
|
||||
</div>
|
||||
|
@ -208,7 +208,8 @@ let MediaPlayer = React.createClass({
|
||||
<br />You can leave this page and check back on the status later.</em>
|
||||
</p>
|
||||
<ProgressBar now={this.props.encodingStatus}
|
||||
label='%(percent)s%' />
|
||||
label="%(percent)s%"
|
||||
className="ascribe-progress-bar" />
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
|
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import ProgressBar from 'react-progressbar';
|
||||
import ProgressBar from 'react-bootstrap/lib/ProgressBar';
|
||||
|
||||
import FileDragAndDropDialog from './file_drag_and_drop_dialog';
|
||||
import FileDragAndDropPreviewIterator from './file_drag_and_drop_preview_iterator';
|
||||
@ -169,12 +169,16 @@ let FileDragAndDrop = React.createClass({
|
||||
if(this.props.hashingProgress !== -2) {
|
||||
return (
|
||||
<div className={className}>
|
||||
<p>{getLangText('Computing hash(es)... This may take a few minutes.')}</p>
|
||||
<p>
|
||||
<span>{Math.ceil(this.props.hashingProgress)}%</span>
|
||||
<a onClick={this.props.handleCancelHashing}> {getLangText('Cancel hashing')}</a>
|
||||
</p>
|
||||
<ProgressBar completed={this.props.hashingProgress} color="#48DACB"/>
|
||||
<div className="file-drag-and-drop-hashing-dialog">
|
||||
<p>{getLangText('Computing hash(es)... This may take a few minutes.')}</p>
|
||||
<p>
|
||||
<a onClick={this.props.handleCancelHashing}> {getLangText('Cancel hashing')}</a>
|
||||
</p>
|
||||
<ProgressBar
|
||||
now={Math.ceil(this.props.hashingProgress)}
|
||||
label="%(percent)s%"
|
||||
className="ascribe-progress-bar"/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
|
@ -32,7 +32,7 @@ let FileDragAndDropDialog = React.createClass({
|
||||
queryParamsUpload.method = 'upload';
|
||||
|
||||
return (
|
||||
<span className="file-drag-and-drop-dialog present-options">
|
||||
<div className="file-drag-and-drop-dialog present-options">
|
||||
<p>{getLangText('Would you rather')}</p>
|
||||
<Link
|
||||
to={this.getPath()}
|
||||
@ -51,12 +51,12 @@ let FileDragAndDropDialog = React.createClass({
|
||||
{getLangText('Upload and hash your work')}
|
||||
</span>
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
if(this.props.multipleFiles) {
|
||||
return (
|
||||
<span className="file-drag-and-drop-dialog">
|
||||
<div className="file-drag-and-drop-dialog">
|
||||
<p>{getLangText('Drag files here')}</p>
|
||||
<p>{getLangText('or')}</p>
|
||||
<span
|
||||
@ -64,13 +64,13 @@ let FileDragAndDropDialog = React.createClass({
|
||||
onClick={this.props.onClick}>
|
||||
{getLangText('choose files to upload')}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
let dialog = queryParams.method === 'hash' ? getLangText('choose a file to hash') : getLangText('choose a file to upload');
|
||||
|
||||
return (
|
||||
<span className="file-drag-and-drop-dialog">
|
||||
<div className="file-drag-and-drop-dialog">
|
||||
<p>{getLangText('Drag a file here')}</p>
|
||||
<p>{getLangText('or')}</p>
|
||||
<span
|
||||
@ -78,7 +78,7 @@ let FileDragAndDropDialog = React.createClass({
|
||||
onClick={this.props.onClick}>
|
||||
{dialog}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import ProgressBar from 'react-progressbar';
|
||||
import ProgressBar from 'react-bootstrap/lib/ProgressBar';
|
||||
|
||||
import AppConstants from '../../constants/application_constants';
|
||||
import { getLangText } from '../../utils/lang_utils.js';
|
||||
@ -60,7 +60,9 @@ let FileDragAndDropPreviewImage = React.createClass({
|
||||
<div
|
||||
className="file-drag-and-drop-preview-image"
|
||||
style={imageStyle}>
|
||||
<ProgressBar completed={this.props.progress} color="black"/>
|
||||
<ProgressBar
|
||||
now={Math.ceil(this.props.progress)}
|
||||
className="ascribe-progress-bar ascribe-progress-bar-xs"/>
|
||||
{actionSymbol}
|
||||
</div>
|
||||
);
|
||||
|
@ -3,6 +3,10 @@
|
||||
import React from 'react';
|
||||
|
||||
import FileDragAndDropPreview from './file_drag_and_drop_preview';
|
||||
import FileDragAndDropPreviewProgress from './file_drag_and_drop_preview_progress';
|
||||
|
||||
import { displayValidFilesFilter } from './react_s3_fine_uploader_utils';
|
||||
|
||||
|
||||
let FileDragAndDropPreviewIterator = React.createClass({
|
||||
propTypes: {
|
||||
@ -16,26 +20,37 @@ let FileDragAndDropPreviewIterator = React.createClass({
|
||||
},
|
||||
|
||||
render() {
|
||||
if(this.props.files) {
|
||||
let {
|
||||
files,
|
||||
handleDeleteFile,
|
||||
handleCancelFile,
|
||||
handlePauseFile,
|
||||
handleResumeFile,
|
||||
areAssetsDownloadable,
|
||||
areAssetsEditable
|
||||
} = this.props;
|
||||
|
||||
files = files.filter(displayValidFilesFilter);
|
||||
|
||||
if(files && files.length > 0) {
|
||||
return (
|
||||
<div>
|
||||
{this.props.files.map((file, i) => {
|
||||
if(file.status !== 'deleted' && file.status !== 'canceled' && file.size !== -1) {
|
||||
<div className="file-drag-and-drop-preview-iterator">
|
||||
<div className="file-drag-and-drop-preview-iterator-spacing">
|
||||
{files.map((file, i) => {
|
||||
return (
|
||||
<FileDragAndDropPreview
|
||||
key={i}
|
||||
file={file}
|
||||
handleDeleteFile={this.props.handleDeleteFile}
|
||||
handleCancelFile={this.props.handleCancelFile}
|
||||
handlePauseFile={this.props.handlePauseFile}
|
||||
handleResumeFile={this.props.handleResumeFile}
|
||||
areAssetsDownloadable={this.props.areAssetsDownloadable}
|
||||
areAssetsEditable={this.props.areAssetsEditable}/>
|
||||
handleDeleteFile={handleDeleteFile}
|
||||
handleCancelFile={handleCancelFile}
|
||||
handlePauseFile={handlePauseFile}
|
||||
handleResumeFile={handleResumeFile}
|
||||
areAssetsDownloadable={areAssetsDownloadable}
|
||||
areAssetsEditable={areAssetsEditable}/>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
})}
|
||||
</div>
|
||||
<FileDragAndDropPreviewProgress files={files} />
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
|
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import ProgressBar from 'react-progressbar';
|
||||
import ProgressBar from 'react-bootstrap/lib/ProgressBar';
|
||||
|
||||
import AppConstants from '../../constants/application_constants';
|
||||
import { getLangText } from '../../utils/lang_utils.js';
|
||||
@ -55,7 +55,9 @@ let FileDragAndDropPreviewOther = React.createClass({
|
||||
return (
|
||||
<div
|
||||
className="file-drag-and-drop-preview">
|
||||
<ProgressBar completed={this.props.progress} color="black"/>
|
||||
<ProgressBar
|
||||
now={Math.ceil(this.props.progress)}
|
||||
className="ascribe-progress-bar ascribe-progress-bar-xs"/>
|
||||
<div className="file-drag-and-drop-preview-table-wrapper">
|
||||
<div className="file-drag-and-drop-preview-other">
|
||||
{actionSymbol}
|
||||
|
@ -0,0 +1,64 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import ProgressBar from 'react-bootstrap/lib/ProgressBar';
|
||||
|
||||
import { displayValidProgressFilesFilter } from './react_s3_fine_uploader_utils';
|
||||
|
||||
|
||||
let FileDragAndDropPreviewProgress = React.createClass({
|
||||
propTypes: {
|
||||
files: React.PropTypes.array
|
||||
},
|
||||
|
||||
calcOverallFileSize() {
|
||||
let overallFileSize = 0;
|
||||
let files = this.props.files.filter(displayValidProgressFilesFilter);
|
||||
|
||||
// We just sum up all files' sizes
|
||||
for(let i = 0; i < files.length; i++) {
|
||||
overallFileSize += files[i].size;
|
||||
}
|
||||
|
||||
return overallFileSize;
|
||||
},
|
||||
|
||||
calcOverallProgress() {
|
||||
let overallProgress = 0;
|
||||
let overallFileSize = this.calcOverallFileSize();
|
||||
let files = this.props.files.filter(displayValidProgressFilesFilter);
|
||||
|
||||
// We calculate the overall progress by summing the individuals
|
||||
// files' progresses in relation to their size
|
||||
for(let i = 0; i < files.length; i++) {
|
||||
overallProgress += files[i].size / overallFileSize * files[i].progress;
|
||||
}
|
||||
|
||||
return overallProgress;
|
||||
},
|
||||
|
||||
render() {
|
||||
let overallProgress = this.calcOverallProgress();
|
||||
let overallFileSize = this.calcOverallFileSize();
|
||||
let style = {
|
||||
visibility: 'hidden'
|
||||
};
|
||||
|
||||
// only visible if overallProgress is over zero
|
||||
// or the overallFileSize is greater than 10MB
|
||||
if(overallProgress !== 0 && overallFileSize > 10000000) {
|
||||
style.visibility = 'visible';
|
||||
}
|
||||
|
||||
return (
|
||||
<ProgressBar
|
||||
now={Math.ceil(overallProgress)}
|
||||
label="Overall progress: %(percent)s%"
|
||||
className="ascribe-progress-bar"
|
||||
style={style} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default FileDragAndDropPreviewProgress;
|
@ -4,9 +4,6 @@ import React from 'react/addons';
|
||||
import Router from 'react-router';
|
||||
import Q from 'q';
|
||||
|
||||
import { getCookie } from '../../utils/fetch_api_utils';
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
|
||||
import S3Fetcher from '../../fetchers/s3_fetcher';
|
||||
|
||||
import fineUploader from 'fineUploader';
|
||||
@ -18,8 +15,11 @@ import GlobalNotificationActions from '../../actions/global_notification_actions
|
||||
import AppConstants from '../../constants/application_constants';
|
||||
|
||||
import { computeHashOfFile } from '../../utils/file_utils';
|
||||
import { displayValidFilesFilter } from './react_s3_fine_uploader_utils';
|
||||
import { getCookie } from '../../utils/fetch_api_utils';
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
|
||||
var ReactS3FineUploader = React.createClass({
|
||||
let ReactS3FineUploader = React.createClass({
|
||||
propTypes: {
|
||||
keyRoutine: React.PropTypes.shape({
|
||||
url: React.PropTypes.string,
|
||||
@ -343,11 +343,9 @@ var ReactS3FineUploader = React.createClass({
|
||||
completed: false
|
||||
};
|
||||
|
||||
let newState = React.addons.update(this.state, {
|
||||
startedChunks: { $set: chunks }
|
||||
});
|
||||
let startedChunks = React.addons.update(this.state.startedChunks, { $set: chunks });
|
||||
|
||||
this.setState(newState);
|
||||
this.setState({ startedChunks });
|
||||
},
|
||||
|
||||
onUploadChunkSuccess(id, chunkData, responseJson, xhr) {
|
||||
@ -360,11 +358,9 @@ var ReactS3FineUploader = React.createClass({
|
||||
chunks[chunkKey].responseJson = responseJson;
|
||||
chunks[chunkKey].xhr = xhr;
|
||||
|
||||
let newState = React.addons.update(this.state, {
|
||||
startedChunks: { $set: chunks }
|
||||
});
|
||||
let startedChunks = React.addons.update(this.state.startedChunks, { $set: chunks });
|
||||
|
||||
this.setState(newState);
|
||||
this.setState({ startedChunks });
|
||||
}
|
||||
|
||||
},
|
||||
@ -384,11 +380,8 @@ var ReactS3FineUploader = React.createClass({
|
||||
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);
|
||||
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])
|
||||
@ -470,15 +463,17 @@ var ReactS3FineUploader = React.createClass({
|
||||
} else {
|
||||
console.warn('You didn\'t define the functions isReadyForFormSubmission and/or setIsUploadReady in as a prop in react-s3-fine-uploader');
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
onProgress(id, name, uploadedBytes, totalBytes) {
|
||||
let newState = React.addons.update(this.state, {
|
||||
filesToUpload: { [id]: {
|
||||
progress: { $set: (uploadedBytes / totalBytes) * 100} }
|
||||
let filesToUpload = React.addons.update(this.state.filesToUpload, {
|
||||
[id]: {
|
||||
progress: { $set: (uploadedBytes / totalBytes) * 100}
|
||||
}
|
||||
});
|
||||
this.setState(newState);
|
||||
this.setState({ filesToUpload });
|
||||
},
|
||||
|
||||
onSessionRequestComplete(response, success) {
|
||||
@ -500,8 +495,9 @@ var ReactS3FineUploader = React.createClass({
|
||||
return file;
|
||||
});
|
||||
|
||||
let newState = React.addons.update(this.state, {filesToUpload: {$set: updatedFilesToUpload}});
|
||||
this.setState(newState);
|
||||
let filesToUpload = React.addons.update(this.state.filesToUpload, {$set: updatedFilesToUpload});
|
||||
|
||||
this.setState({filesToUpload });
|
||||
} else {
|
||||
// server has to respond with 204
|
||||
//let notification = new GlobalNotificationModel('Could not load attached files (Further data)', 'danger', 10000);
|
||||
@ -513,13 +509,11 @@ var ReactS3FineUploader = React.createClass({
|
||||
|
||||
onDeleteComplete(id, xhr, isError) {
|
||||
if(isError) {
|
||||
let notification = new GlobalNotificationModel(getLangText('Couldn\'t delete file'), 'danger', 10000);
|
||||
this.setStatusOfFile(id, 'online');
|
||||
|
||||
let notification = new GlobalNotificationModel(getLangText('There was an error deleting your file.'), 'danger', 10000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
} else {
|
||||
|
||||
// To hide the file in this component, we need to set it's status to "deleted"
|
||||
this.setStatusOfFile(id, 'deleted');
|
||||
|
||||
let notification = new GlobalNotificationModel(getLangText('File deleted'), 'success', 5000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
}
|
||||
@ -541,6 +535,13 @@ var ReactS3FineUploader = React.createClass({
|
||||
},
|
||||
|
||||
handleDeleteFile(fileId) {
|
||||
// We set the files state to 'deleted' immediately, so that the user is not confused with
|
||||
// the unresponsiveness of the UI
|
||||
//
|
||||
// If there is an error during the deletion, we will just change the status back to 'online'
|
||||
// and display an error message
|
||||
this.setStatusOfFile(fileId, 'deleted');
|
||||
|
||||
// In some instances (when the file was already uploaded and is just displayed to the user
|
||||
// - for example in the contract or additional files dialog)
|
||||
// fineuploader does not register an id on the file (we do, don't be confused by this!).
|
||||
@ -558,8 +559,6 @@ var ReactS3FineUploader = React.createClass({
|
||||
// promise
|
||||
} else {
|
||||
let fileToDelete = this.state.filesToUpload[fileId];
|
||||
fileToDelete.status = 'deleted';
|
||||
|
||||
S3Fetcher
|
||||
.deleteFile(fileToDelete.s3Key, fileToDelete.s3Bucket)
|
||||
.then(() => this.onDeleteComplete(fileToDelete.id, null, false))
|
||||
@ -591,7 +590,7 @@ var ReactS3FineUploader = React.createClass({
|
||||
handleUploadFile(files) {
|
||||
// If multiple set and user already uploaded its work,
|
||||
// cancel upload
|
||||
if(!this.props.multiple && this.state.filesToUpload.filter((file) => file.status !== 'deleted' && file.status !== 'canceled').length > 0) {
|
||||
if(!this.props.multiple && this.state.filesToUpload.filter(displayValidFilesFilter).length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -606,7 +605,7 @@ var ReactS3FineUploader = React.createClass({
|
||||
files = validFiles;
|
||||
|
||||
// Call this method to signal the outside component that an upload is in progress
|
||||
if(this.props.uploadStarted && typeof this.props.uploadStarted === 'function' && files.length > 0) {
|
||||
if(typeof this.props.uploadStarted === 'function' && files.length > 0) {
|
||||
this.props.uploadStarted();
|
||||
}
|
||||
|
||||
@ -747,6 +746,7 @@ var ReactS3FineUploader = React.createClass({
|
||||
synchronizeFileLists(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++) {
|
||||
@ -761,6 +761,22 @@ var ReactS3FineUploader = React.createClass({
|
||||
// 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++) {
|
||||
|
||||
// EXCEPTION:
|
||||
//
|
||||
// Files do not necessarily come from the user's hard drive but can also be fetched
|
||||
// from Amazon S3. This is handled in onSessionRequestComplete.
|
||||
//
|
||||
// If the user deletes one of those files, then fineuploader will still keep it in his
|
||||
// files array but with key, progress undefined and size === -1 but
|
||||
// status === 'upload successful'.
|
||||
// This poses a problem as we depend on the amount of files that have
|
||||
// status === 'upload successful', therefore once the file is synced,
|
||||
// we need to tag its status as 'deleted' (which basically happens here)
|
||||
if(oldAndNewFiles[i].size === -1 && (!oldAndNewFiles[i].progress || oldAndNewFiles[i].progress === 0)) {
|
||||
oldAndNewFiles[i].status = 'deleted';
|
||||
}
|
||||
|
||||
if(oldAndNewFiles[i].originalName === oldFiles[j].name) {
|
||||
oldAndNewFiles[i].progress = oldFiles[j].progress;
|
||||
oldAndNewFiles[i].type = oldFiles[j].type;
|
||||
@ -771,30 +787,23 @@ var ReactS3FineUploader = React.createClass({
|
||||
}
|
||||
|
||||
// set the new file array
|
||||
let newState = React.addons.update(this.state, {
|
||||
filesToUpload: { $set: oldAndNewFiles }
|
||||
});
|
||||
this.setState(newState);
|
||||
let filesToUpload = React.addons.update(this.state.filesToUpload, { $set: oldAndNewFiles });
|
||||
|
||||
this.setState({ filesToUpload });
|
||||
},
|
||||
|
||||
setStatusOfFile(fileId, status) {
|
||||
// also, sync files from state with the ones from fineuploader
|
||||
let filesToUpload = JSON.parse(JSON.stringify(this.state.filesToUpload));
|
||||
let changeSet = {};
|
||||
|
||||
filesToUpload[fileId].status = status;
|
||||
|
||||
// is status is set to deleted or canceled, we also need to reset the progress
|
||||
// back to zero
|
||||
if(status === 'deleted' || status === 'canceled') {
|
||||
filesToUpload[fileId].progress = 0;
|
||||
changeSet.progress = { $set: 0 };
|
||||
}
|
||||
|
||||
// set state
|
||||
let newState = React.addons.update(this.state, {
|
||||
filesToUpload: { $set: filesToUpload }
|
||||
});
|
||||
changeSet.status = { $set: status };
|
||||
|
||||
this.setState(newState);
|
||||
let filesToUpload = React.addons.update(this.state.filesToUpload, { [fileId]: changeSet });
|
||||
|
||||
this.setState({ filesToUpload });
|
||||
},
|
||||
|
||||
isDropzoneInactive() {
|
||||
|
@ -32,3 +32,23 @@ export const formSubmissionValidation = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Filter function for filtering all deleted and canceled files
|
||||
* @param {object} file A file from filesToUpload that has status as a prop.
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function displayValidFilesFilter(file) {
|
||||
return file.status !== 'deleted' && file.status !== 'canceled';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filter function for which files to integrate in the progress process
|
||||
* @param {object} file A file from filesToUpload, that has a status as a prop.
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function displayValidProgressFilesFilter(file) {
|
||||
return file.status !== 'deleted' && file.status !== 'canceled' && file.status !== 'online';
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright 2015, Widen Enterprises, Inc. info@fineuploader.com
|
||||
*
|
||||
* Version: 5.2.2
|
||||
* Version: 5.3.0
|
||||
*
|
||||
* Homepage: http://fineuploader.com
|
||||
*
|
||||
@ -894,7 +894,7 @@ var qq = function(element) {
|
||||
}());
|
||||
|
||||
/*global qq */
|
||||
qq.version = "5.2.2";
|
||||
qq.version = "5.3.0";
|
||||
|
||||
/* globals qq */
|
||||
qq.supportedFeatures = (function() {
|
||||
@ -1928,6 +1928,10 @@ qq.status = {
|
||||
this._endpointStore.set(endpoint, id);
|
||||
},
|
||||
|
||||
setForm: function(elementOrId) {
|
||||
this._updateFormSupportAndParams(elementOrId);
|
||||
},
|
||||
|
||||
setItemLimit: function(newItemLimit) {
|
||||
this._currentItemLimit = newItemLimit;
|
||||
},
|
||||
@ -1945,16 +1949,11 @@ qq.status = {
|
||||
},
|
||||
|
||||
uploadStoredFiles: function() {
|
||||
var idToUpload;
|
||||
|
||||
if (this._storedIds.length === 0) {
|
||||
this._itemError("noFilesError");
|
||||
}
|
||||
else {
|
||||
while (this._storedIds.length) {
|
||||
idToUpload = this._storedIds.shift();
|
||||
this._uploadFile(idToUpload);
|
||||
}
|
||||
this._uploadStoredFiles();
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -2038,10 +2037,11 @@ qq.status = {
|
||||
});
|
||||
},
|
||||
|
||||
_createStore: function(initialValue, readOnlyValues) {
|
||||
_createStore: function(initialValue, _readOnlyValues_) {
|
||||
var store = {},
|
||||
catchall = initialValue,
|
||||
perIdReadOnlyValues = {},
|
||||
readOnlyValues = _readOnlyValues_,
|
||||
copy = function(orig) {
|
||||
if (qq.isObject(orig)) {
|
||||
return qq.extend({}, orig);
|
||||
@ -2095,8 +2095,20 @@ qq.status = {
|
||||
addReadOnly: function(id, values) {
|
||||
// Only applicable to Object stores
|
||||
if (qq.isObject(store)) {
|
||||
perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};
|
||||
qq.extend(perIdReadOnlyValues[id], values);
|
||||
// If null ID, apply readonly values to all files
|
||||
if (id === null) {
|
||||
if (qq.isFunction(values)) {
|
||||
readOnlyValues = values;
|
||||
}
|
||||
else {
|
||||
readOnlyValues = readOnlyValues || {};
|
||||
qq.extend(readOnlyValues, values);
|
||||
}
|
||||
}
|
||||
else {
|
||||
perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};
|
||||
qq.extend(perIdReadOnlyValues[id], values);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -2882,7 +2894,7 @@ qq.status = {
|
||||
_onBeforeManualRetry: function(id) {
|
||||
var itemLimit = this._currentItemLimit,
|
||||
fileName;
|
||||
console.log(this._handler.isValid(id));
|
||||
|
||||
if (this._preventRetries[id]) {
|
||||
this.log("Retries are forbidden for id " + id, "warn");
|
||||
return false;
|
||||
@ -3005,13 +3017,14 @@ qq.status = {
|
||||
this._onSubmit.apply(this, arguments);
|
||||
this._uploadData.setStatus(id, qq.status.SUBMITTED);
|
||||
this._onSubmitted.apply(this, arguments);
|
||||
this._options.callbacks.onSubmitted.apply(this, arguments);
|
||||
|
||||
if (this._options.autoUpload) {
|
||||
this._options.callbacks.onSubmitted.apply(this, arguments);
|
||||
this._uploadFile(id);
|
||||
}
|
||||
else {
|
||||
this._storeForLater(id);
|
||||
this._options.callbacks.onSubmitted.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
|
||||
@ -3238,6 +3251,23 @@ qq.status = {
|
||||
}
|
||||
},
|
||||
|
||||
_updateFormSupportAndParams: function(formElementOrId) {
|
||||
this._options.form.element = formElementOrId;
|
||||
|
||||
this._formSupport = qq.FormSupport && new qq.FormSupport(
|
||||
this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)
|
||||
);
|
||||
|
||||
if (this._formSupport && this._formSupport.attachedToForm) {
|
||||
this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);
|
||||
|
||||
this._options.autoUpload = this._formSupport.newAutoUpload;
|
||||
if (this._formSupport.newEndpoint) {
|
||||
this.setEndpoint(this._formSupport.newEndpoint);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_upload: function(id, params, endpoint) {
|
||||
var name = this.getName(id);
|
||||
|
||||
@ -3264,6 +3294,25 @@ qq.status = {
|
||||
}
|
||||
},
|
||||
|
||||
_uploadStoredFiles: function() {
|
||||
var idToUpload, stillSubmitting,
|
||||
self = this;
|
||||
|
||||
while (this._storedIds.length) {
|
||||
idToUpload = this._storedIds.shift();
|
||||
this._uploadFile(idToUpload);
|
||||
}
|
||||
|
||||
// If we are still waiting for some files to clear validation, attempt to upload these again in a bit
|
||||
stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;
|
||||
if (stillSubmitting) {
|
||||
qq.log("Still waiting for " + stillSubmitting + " files to clear submit queue. Will re-parse stored IDs array shortly.");
|
||||
setTimeout(function() {
|
||||
self._uploadStoredFiles();
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Performs some internal validation checks on an item, defined in the `validation` option.
|
||||
*
|
||||
@ -5271,6 +5320,7 @@ qq.XhrUploadHandler = function(spec) {
|
||||
*/
|
||||
getResumableFilesData: function() {
|
||||
var resumableFilesData = [];
|
||||
|
||||
handler._iterateResumeRecords(function(key, uploadData) {
|
||||
handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);
|
||||
|
||||
@ -5461,7 +5511,7 @@ qq.XhrUploadHandler = function(spec) {
|
||||
_iterateResumeRecords: function(callback) {
|
||||
if (resumeEnabled) {
|
||||
qq.each(localStorage, function(key, item) {
|
||||
if (key.indexOf(qq.format("qq{}resume-", namespace)) === 0) {
|
||||
if (key.indexOf(qq.format("qq{}resume", namespace)) === 0) {
|
||||
var uploadData = JSON.parse(item);
|
||||
callback(key, uploadData);
|
||||
}
|
||||
@ -5728,7 +5778,9 @@ qq.WindowReceiveMessage = function(o) {
|
||||
},
|
||||
|
||||
getItemByFileId: function(id) {
|
||||
return this._templating.getFileContainer(id);
|
||||
if (!this._templating.isHiddenForever(id)) {
|
||||
return this._templating.getFileContainer(id);
|
||||
}
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
@ -6238,11 +6290,6 @@ qq.WindowReceiveMessage = function(o) {
|
||||
dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,
|
||||
record;
|
||||
|
||||
// If we don't want this file to appear in the UI, skip all of this UI-related logic.
|
||||
if (dontDisplay) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._options.display.prependFiles) {
|
||||
if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {
|
||||
prependIndex = this._filesInBatchAddedToUi - 1;
|
||||
@ -6274,7 +6321,7 @@ qq.WindowReceiveMessage = function(o) {
|
||||
}
|
||||
}
|
||||
|
||||
this._templating.addFile(id, this._options.formatFileName(name), prependData);
|
||||
this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);
|
||||
|
||||
if (canned) {
|
||||
this._thumbnailUrls[id] && this._templating.updateThumbnail(id, this._thumbnailUrls[id], true);
|
||||
@ -6638,6 +6685,7 @@ qq.Templating = function(spec) {
|
||||
HIDE_DROPZONE_ATTR = "qq-hide-dropzone",
|
||||
DROPZPONE_TEXT_ATTR = "qq-drop-area-text",
|
||||
IN_PROGRESS_CLASS = "qq-in-progress",
|
||||
HIDDEN_FOREVER_CLASS = "qq-hidden-forever",
|
||||
isCancelDisabled = false,
|
||||
generatedThumbnails = 0,
|
||||
thumbnailQueueMonitorRunning = false,
|
||||
@ -7273,7 +7321,7 @@ qq.Templating = function(spec) {
|
||||
isCancelDisabled = true;
|
||||
},
|
||||
|
||||
addFile: function(id, name, prependInfo) {
|
||||
addFile: function(id, name, prependInfo, hideForever) {
|
||||
var fileEl = qq.toElement(templateHtml.fileTemplate),
|
||||
fileNameEl = getTemplateEl(fileEl, selectorClasses.file),
|
||||
uploaderEl = getTemplateEl(container, selectorClasses.uploader),
|
||||
@ -7296,30 +7344,36 @@ qq.Templating = function(spec) {
|
||||
fileList.appendChild(fileEl);
|
||||
}
|
||||
|
||||
hide(getProgress(id));
|
||||
hide(getSize(id));
|
||||
hide(getDelete(id));
|
||||
hide(getRetry(id));
|
||||
hide(getPause(id));
|
||||
hide(getContinue(id));
|
||||
|
||||
if (isCancelDisabled) {
|
||||
this.hideCancel(id);
|
||||
if (hideForever) {
|
||||
fileEl.style.display = "none";
|
||||
qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);
|
||||
}
|
||||
else {
|
||||
hide(getProgress(id));
|
||||
hide(getSize(id));
|
||||
hide(getDelete(id));
|
||||
hide(getRetry(id));
|
||||
hide(getPause(id));
|
||||
hide(getContinue(id));
|
||||
|
||||
thumb = getThumbnail(id);
|
||||
if (thumb && !thumb.src) {
|
||||
cachedWaitingForThumbnailImg.then(function(waitingImg) {
|
||||
thumb.src = waitingImg.src;
|
||||
if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {
|
||||
qq(thumb).css({
|
||||
maxHeight: waitingImg.style.maxHeight,
|
||||
maxWidth: waitingImg.style.maxWidth
|
||||
});
|
||||
}
|
||||
if (isCancelDisabled) {
|
||||
this.hideCancel(id);
|
||||
}
|
||||
|
||||
show(thumb);
|
||||
});
|
||||
thumb = getThumbnail(id);
|
||||
if (thumb && !thumb.src) {
|
||||
cachedWaitingForThumbnailImg.then(function(waitingImg) {
|
||||
thumb.src = waitingImg.src;
|
||||
if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {
|
||||
qq(thumb).css({
|
||||
maxHeight: waitingImg.style.maxHeight,
|
||||
maxWidth: waitingImg.style.maxWidth
|
||||
});
|
||||
}
|
||||
|
||||
show(thumb);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -7413,6 +7467,10 @@ qq.Templating = function(spec) {
|
||||
icon && qq(icon).addClass(options.classes.editable);
|
||||
},
|
||||
|
||||
isHiddenForever: function(id) {
|
||||
return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);
|
||||
},
|
||||
|
||||
hideEditIcon: function(id) {
|
||||
var icon = getEditIcon(id);
|
||||
|
||||
@ -7572,13 +7630,17 @@ qq.Templating = function(spec) {
|
||||
},
|
||||
|
||||
generatePreview: function(id, optFileOrBlob) {
|
||||
thumbGenerationQueue.push({id: id, optFileOrBlob: optFileOrBlob});
|
||||
!thumbnailQueueMonitorRunning && generateNextQueuedPreview();
|
||||
if (!this.isHiddenForever(id)) {
|
||||
thumbGenerationQueue.push({id: id, optFileOrBlob: optFileOrBlob});
|
||||
!thumbnailQueueMonitorRunning && generateNextQueuedPreview();
|
||||
}
|
||||
},
|
||||
|
||||
updateThumbnail: function(id, thumbnailUrl, showWaitingImg) {
|
||||
thumbGenerationQueue.push({update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});
|
||||
!thumbnailQueueMonitorRunning && generateNextQueuedPreview();
|
||||
if (!this.isHiddenForever(id)) {
|
||||
thumbGenerationQueue.push({update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});
|
||||
!thumbnailQueueMonitorRunning && generateNextQueuedPreview();
|
||||
}
|
||||
},
|
||||
|
||||
hasDialog: function(type) {
|
||||
@ -9489,12 +9551,6 @@ qq.s3.XhrUploadHandler = function(spec, proxy) {
|
||||
result.success,
|
||||
|
||||
function failure(reason, xhr) {
|
||||
console.logGlobal(reason + 'in chunked.combine', false, {
|
||||
uploadId,
|
||||
etagMap,
|
||||
result
|
||||
});
|
||||
|
||||
result.failure(upload.done(id, xhr).response, xhr);
|
||||
}
|
||||
);
|
||||
@ -12335,7 +12391,7 @@ qq.Scaler = function(spec, log) {
|
||||
"use strict";
|
||||
|
||||
var self = this,
|
||||
includeReference = spec.sendOriginal,
|
||||
includeOriginal = spec.sendOriginal,
|
||||
orient = spec.orient,
|
||||
defaultType = spec.defaultType,
|
||||
defaultQuality = spec.defaultQuality / 100,
|
||||
@ -12385,16 +12441,18 @@ qq.Scaler = function(spec, log) {
|
||||
});
|
||||
});
|
||||
|
||||
includeReference && records.push({
|
||||
records.push({
|
||||
uuid: originalFileUuid,
|
||||
name: originalFileName,
|
||||
blob: originalBlob
|
||||
size: originalBlob.size,
|
||||
blob: includeOriginal ? originalBlob : null
|
||||
});
|
||||
}
|
||||
else {
|
||||
records.push({
|
||||
uuid: originalFileUuid,
|
||||
name: originalFileName,
|
||||
size: originalBlob.size,
|
||||
blob: originalBlob
|
||||
});
|
||||
}
|
||||
@ -12413,19 +12471,17 @@ qq.Scaler = function(spec, log) {
|
||||
proxyGroupId = qq.getUniqueId();
|
||||
|
||||
qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {
|
||||
var relatedBlob = file,
|
||||
relatedSize = size,
|
||||
var blobSize = record.size,
|
||||
id;
|
||||
|
||||
if (record.blob instanceof qq.BlobProxy) {
|
||||
relatedBlob = record.blob;
|
||||
relatedSize = -1;
|
||||
blobSize = -1;
|
||||
}
|
||||
|
||||
id = uploadData.addFile({
|
||||
uuid: record.uuid,
|
||||
name: record.name,
|
||||
size: relatedSize,
|
||||
size: blobSize,
|
||||
batchId: batchId,
|
||||
proxyGroupId: proxyGroupId
|
||||
});
|
||||
@ -12437,10 +12493,13 @@ qq.Scaler = function(spec, log) {
|
||||
originalId = id;
|
||||
}
|
||||
|
||||
addFileToHandler(id, relatedBlob);
|
||||
|
||||
fileList.push({id: id, file: relatedBlob});
|
||||
|
||||
if (record.blob) {
|
||||
addFileToHandler(id, record.blob);
|
||||
fileList.push({id: id, file: record.blob});
|
||||
}
|
||||
else {
|
||||
uploadData.setStatus(id, qq.status.REJECTED);
|
||||
}
|
||||
});
|
||||
|
||||
// If we are potentially uploading an original file and some scaled versions,
|
||||
@ -12453,8 +12512,8 @@ qq.Scaler = function(spec, log) {
|
||||
qqparentsize: uploadData.retrieve({id: originalId}).size
|
||||
};
|
||||
|
||||
// Make SURE the UUID for each scaled image is sent with the upload request,
|
||||
// to be consistent (since we need to ensure it is sent for the original file as well).
|
||||
// Make sure the UUID for each scaled image is sent with the upload request,
|
||||
// to be consistent (since we may need to ensure it is sent for the original file as well).
|
||||
params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;
|
||||
|
||||
uploadData.setParentId(scaledId, originalId);
|
||||
@ -14411,4 +14470,4 @@ code.google.com/p/crypto-js/wiki/License
|
||||
C.HmacSHA1 = Hasher._createHmacHelper(SHA1);
|
||||
}());
|
||||
|
||||
/*! 2015-06-09 */
|
||||
/*! 2015-08-26 */
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import Router from 'react-router';
|
||||
|
||||
import AccordionListItemPiece from '../../../../../ascribe_accordion_list/accordion_list_item_piece';
|
||||
|
||||
@ -17,8 +16,6 @@ import IkonotvSubmitButton from '../ascribe_buttons/ikonotv_submit_button';
|
||||
|
||||
import AclProxy from '../../../../../acl_proxy';
|
||||
|
||||
import AclButton from '../../../../../ascribe_buttons/acl_button';
|
||||
|
||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||
import { mergeOptions } from '../../../../../../utils/general_utils';
|
||||
|
||||
|
@ -53,6 +53,10 @@ let constants = {
|
||||
'ga': 'UA-60614729-2'
|
||||
},
|
||||
|
||||
// These are all possible types that are currently supported in HTML5 for the input element
|
||||
// Source: http://www.w3schools.com/tags/att_input_type.asp
|
||||
'possibleInputTypes': ['button', 'checkbox', 'color', 'date', 'datetime', 'datetime-local', 'email', 'file', 'hidden', 'image', 'month', 'number', 'password', 'radio', 'range', 'reset', 'search', 'submit', 'tel', 'text', 'time', 'url', 'week'],
|
||||
|
||||
// in case of whitelabel customization, we store stuff here
|
||||
'whitelabel': {},
|
||||
'raven': {
|
||||
|
1
js/third_party/ga.js
vendored
1
js/third_party/ga.js
vendored
@ -3,7 +3,6 @@
|
||||
import alt from '../alt';
|
||||
import EventActions from '../actions/event_actions';
|
||||
|
||||
|
||||
class GoogleAnalyticsHandler {
|
||||
constructor() {
|
||||
this.bindActions(EventActions);
|
||||
|
@ -73,9 +73,8 @@
|
||||
"q": "^1.4.1",
|
||||
"raven-js": "^1.1.19",
|
||||
"react": "^0.13.2",
|
||||
"react-bootstrap": "^0.24.3",
|
||||
"react-bootstrap": "^0.25.1",
|
||||
"react-datepicker": "^0.12.0",
|
||||
"react-progressbar": "^1.1.0",
|
||||
"react-router": "^0.13.3",
|
||||
"react-router-bootstrap": "~0.16.0",
|
||||
"react-star-rating": "~1.3.2",
|
||||
|
@ -6,9 +6,9 @@
|
||||
margin-top: 1em;
|
||||
outline: 1px dashed #9e9e9e;
|
||||
overflow: auto;
|
||||
padding: 1.5em 0;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
cursor: default !important;
|
||||
|
||||
.file-drag-and-drop-dialog > p:first-child {
|
||||
font-size: 1.5em !important;
|
||||
@ -34,6 +34,34 @@
|
||||
}
|
||||
}
|
||||
|
||||
.file-drag-and-drop-preview-iterator {
|
||||
margin: 2.5em 0 0 0;
|
||||
text-align: right;
|
||||
|
||||
> div:first-child {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.file-drag-and-drop-preview-iterator-spacing {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.file-drag-and-drop-dialog {
|
||||
margin: 1.5em 0 1.5em 0;
|
||||
}
|
||||
|
||||
.file-drag-and-drop-hashing-dialog {
|
||||
margin: 1.5em 0 0 0;
|
||||
}
|
||||
|
||||
.file-drag-and-drop .file-drag-and-drop-dialog > p:first-child {
|
||||
font-size: 1.5em !important;
|
||||
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.file-drag-and-drop-position {
|
||||
display: inline-block;
|
||||
|
@ -448,3 +448,14 @@ hr {
|
||||
padding-top: 30%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ascribe-progress-bar {
|
||||
margin-bottom: 0;
|
||||
> .progress-bar {
|
||||
background-color: $ascribe-color-green;
|
||||
}
|
||||
}
|
||||
|
||||
.ascribe-progress-bar-xs {
|
||||
height: 12px;
|
||||
}
|
Loading…
Reference in New Issue
Block a user