1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-22 17:33:14 +01:00

Add file-format-specific call to action for thumbnail generation

This commit is contained in:
Tim Daubenschütz 2015-11-17 15:46:46 +01:00
parent 2ffc26d703
commit 971d42b36d
6 changed files with 106 additions and 57 deletions

View File

@ -7,6 +7,7 @@ import UserActions from '../../actions/user_actions';
import Form from './form';
import Property from './property';
import PropertyCollapsible from './property_collapsible';
import InputFineUploader from './input_fineuploader';
import UploadButton from '../ascribe_uploader/ascribe_upload_button/upload_button';
@ -16,7 +17,7 @@ import AscribeSpinner from '../ascribe_spinner';
import { getLangText } from '../../utils/lang_utils';
import { mergeOptions } from '../../utils/general_utils';
import { formSubmissionValidation } from '../ascribe_uploader/react_s3_fine_uploader_utils';
import { formSubmissionValidation, displayValidFilesFilter } from '../ascribe_uploader/react_s3_fine_uploader_utils';
let RegisterPieceForm = React.createClass({
@ -50,7 +51,8 @@ let RegisterPieceForm = React.createClass({
return mergeOptions(
{
digitalWorkKeyReady: false,
thumbnailKeyReady: true
thumbnailKeyReady: true,
thumbnailKeyDialogExpanded: false
},
UserStore.getState()
);
@ -82,6 +84,20 @@ let RegisterPieceForm = React.createClass({
};
},
handleSelectFiles(files) {
const validFiles = files.filter(displayValidFilesFilter);
if(validFiles.length > 0) {
const { type: fileType } = validFiles[0].type;
const fileExtension = fileType && fileType.split('/').length ? fileType.split('/')[1]
: 'unknown';
const thumbnailKeyDialogExpanded = AppConstants.supportedThumbnailFileFormats.indexOf(fileExtension) === -1;
this.setState({ thumbnailKeyDialogExpanded });
} else {
this.setState({ thumbnailKeyDialogExpanded: false });
}
},
render() {
const { disabled,
handleSuccess,
@ -95,7 +111,8 @@ let RegisterPieceForm = React.createClass({
enableLocalHashing } = this.props;
const { currentUser,
digitalWorkKeyReady,
thumbnailKeyReady } = this.state;
thumbnailKeyReady,
thumbnailKeyDialogExpanded } = this.state;
const profileHashLocally = currentUser && currentUser.profile ? currentUser.profile.hash_locally : false;
const hashLocally = profileHashLocally && enableLocalHashing;
@ -141,10 +158,12 @@ let RegisterPieceForm = React.createClass({
onLoggedOut={onLoggedOut}
disabled={!isFineUploaderEditable}
enableLocalHashing={hashLocally}
uploadMethod={location.query.method} />
uploadMethod={location.query.method}
handleSelectFiles={this.handleSelectFiles}/>
</Property>
<Property
name="thumbnail_file">
name="thumbnail_file"
expanded={thumbnailKeyDialogExpanded}>
<InputFineUploader
fileInputElement={UploadButton({ className: 'btn btn-secondary btn-sm' })}
createBlobRoutine={{

View File

@ -51,7 +51,8 @@ const InputFineUploader = React.createClass({
fileClassToUpload: shape({
singular: string,
plural: string
})
}),
handleSelectFiles: func
},
getDefaultProps() {
@ -104,7 +105,8 @@ const InputFineUploader = React.createClass({
onLoggedOut,
enableLocalHashing,
fileClassToUpload,
uploadMethod } = this.props;
uploadMethod,
handleSelectFiles } = this.props;
let editable = this.props.isFineUploaderActive;
// if disabled is actually set by property, we want to override
@ -142,7 +144,8 @@ const InputFineUploader = React.createClass({
onInactive={onLoggedOut}
enableLocalHashing={enableLocalHashing}
uploadMethod={uploadMethod}
fileClassToUpload={fileClassToUpload} />
fileClassToUpload={fileClassToUpload}
handleSelectFiles={handleSelectFiles}/>
);
}
});

View File

@ -3,52 +3,54 @@
import React from 'react';
import ReactAddons from 'react/addons';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
import Tooltip from 'react-bootstrap/lib/Tooltip';
import Panel from 'react-bootstrap/lib/Panel';
import AppConstants from '../../constants/application_constants';
import { mergeOptions } from '../../utils/general_utils';
let Property = React.createClass({
propTypes: {
hidden: React.PropTypes.bool,
const { bool, element, string, oneOfType, func, object, arrayOf } = React.PropTypes;
editable: React.PropTypes.bool,
const Property = React.createClass({
propTypes: {
hidden: bool,
editable: bool,
// If we want Form to have a different value for disabled as Property has one for
// editable, we need to set overrideForm to true, as it will then override Form's
// disabled value for individual Properties
overrideForm: React.PropTypes.bool,
overrideForm: bool,
tooltip: React.PropTypes.element,
label: React.PropTypes.string,
value: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.element
label: string,
value: oneOfType([
string,
element
]),
footer: React.PropTypes.element,
handleChange: React.PropTypes.func,
ignoreFocus: React.PropTypes.bool,
name: React.PropTypes.string.isRequired,
className: React.PropTypes.string,
footer: element,
handleChange: func,
ignoreFocus: bool,
name: string.isRequired,
className: string,
onClick: React.PropTypes.func,
onChange: React.PropTypes.func,
onBlur: React.PropTypes.func,
onClick: func,
onChange: func,
onBlur: func,
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
children: oneOfType([
arrayOf(element),
element
]),
style: React.PropTypes.object
style: object,
expanded: bool
},
getDefaultProps() {
return {
editable: true,
hidden: false,
expanded: true,
className: ''
};
},
@ -190,7 +192,7 @@ let Property = React.createClass({
},
getClassName() {
if(this.props.hidden){
if(this.props.hidden || !this.props.expanded){
return 'is-hidden';
}
if(!this.props.editable){
@ -235,16 +237,8 @@ let Property = React.createClass({
render() {
let footer = null;
let tooltip = <span/>;
let style = this.props.style ? mergeOptions({}, this.props.style) : {};
if(this.props.tooltip){
tooltip = (
<Tooltip>
{this.props.tooltip}
</Tooltip>);
}
if(this.props.footer){
footer = (
<div className="ascribe-property-footer">
@ -261,16 +255,16 @@ let Property = React.createClass({
className={'ascribe-property-wrapper ' + this.getClassName()}
onClick={this.handleFocus}
style={style}>
<OverlayTrigger
delay={500}
placement="top"
overlay={tooltip}>
<Panel
collapsible
expanded={this.props.expanded}
className="bs-custom-panel">
<div className={'ascribe-property ' + this.props.className}>
{this.getLabelAndErrors()}
{this.renderChildren(style)}
{footer}
</div>
</OverlayTrigger>
</Panel>
</div>
);
}

View File

@ -48,7 +48,8 @@ const ReactS3FineUploader = React.createClass({
number
])
}),
submitFile: func,
handleSelectFiles: func, // is for when a file is dropped or selected
submitFile: func, // is for when a file has been successfully uploaded, TODO: rename to handleSubmitFile
autoUpload: bool,
debug: bool,
objectProperties: shape({
@ -522,7 +523,12 @@ const ReactS3FineUploader = React.createClass({
onCancel(id) {
// when a upload is canceled, we need to update this components file array
this.setStatusOfFile(id, 'canceled');
this.setStatusOfFile(id, 'canceled')
.then(() => {
if(typeof this.props.handleSelectFiles === 'function') {
this.props.handleSelectFiles(this.state.filesToUpload);
}
});
let notification = new GlobalNotificationModel(getLangText('File upload canceled'), 'success', 5000);
GlobalNotificationActions.appendGlobalNotification(notification);
@ -616,7 +622,12 @@ const ReactS3FineUploader = React.createClass({
//
// 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');
this.setStatusOfFile(fileId, 'deleted')
.then(() => {
if(typeof this.props.handleSelectFiles === 'function') {
this.props.handleSelectFiles(this.state.filesToUpload);
}
});
// 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)
@ -856,10 +867,23 @@ const ReactS3FineUploader = React.createClass({
// set the new file array
let filesToUpload = React.addons.update(this.state.filesToUpload, { $set: oldAndNewFiles });
this.setState({ filesToUpload });
this.setState({ filesToUpload }, () => {
// when files have been dropped or selected by a user, we want to propagate that
// information to the outside components, so they can act on it (in our case, because
// we want the user to define a thumbnail when the actual work is not renderable
// (like e.g. a .zip file))
if(typeof this.props.handleSelectFiles === 'function') {
this.props.handleSelectFiles(this.state.filesToUpload);
}
});
},
// This method has been made promise-based to immediately afterwards
// call a callback function (instantly after this.setState went through)
// This is e.g. needed when showing/hiding the optional thumbnail upload
// field in the registration form
setStatusOfFile(fileId, status) {
return Q.Promise((resolve) => {
let changeSet = {};
if(status === 'deleted' || status === 'canceled') {
@ -870,7 +894,8 @@ const ReactS3FineUploader = React.createClass({
let filesToUpload = React.addons.update(this.state.filesToUpload, { [fileId]: changeSet });
this.setState({ filesToUpload });
this.setState({ filesToUpload }, resolve);
});
},
isDropzoneInactive() {

View File

@ -85,8 +85,11 @@ const constants = {
'Bildrecht GmbH', 'SABAM', 'AUTVIS', 'CREAIMAGEN', 'SONECA', 'Copydan', 'EAU', 'Kuvasto', 'GCA', 'HUNGART',
'IVARO', 'SIAE', 'JASPAR-SPDA', 'AKKA/LAA', 'LATGA-A', 'SOMAAP', 'ARTEGESTION', 'CARIER', 'BONO', 'APSAV',
'SPA', 'GESTOR', 'VISaRTA', 'RAO', 'LITA', 'DALRO', 'VeGaP', 'BUS', 'ProLitteris', 'AGADU', 'AUTORARTE', 'BUBEDRA', 'BBDA', 'BCDA', 'BURIDA', 'ADAVIS', 'BSDA'],
'searchThreshold': 500,
'supportedThumbnailFileFormats': ['png', 'jpg', 'jpeg', 'gif', 'mp4'],
// in case of whitelabel customization, we store stuff here
'whitelabel': {},

View File

@ -1,3 +1,8 @@
.panel {
/* Here we are overriding bootstrap to show the is-focused background color */
background-color: transparent;
}
.ascribe-panel-wrapper {
border: 1px solid #ddd;
height: 5em;