diff --git a/gulpfile.js b/gulpfile.js index 1db34af4..6f82da83 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -53,10 +53,12 @@ var config = { ] }; +var SERVER_URL = process.env.ONION_SERVER_URL || 'http://staging.ascribe.io/'; + var constants = { BASE_URL: (function () { var baseUrl = process.env.ONION_BASE_URL || '/'; return baseUrl + (baseUrl.match(/\/$/) ? '' : '/'); })(), - SERVER_URL: process.env.ONION_SERVER_URL || 'http://staging.ascribe.io/', - API_ENDPOINT: process.env.ONION_SERVER_URL + 'api/' || 'http://staging.ascribe.io/api/', + SERVER_URL: SERVER_URL, + API_ENDPOINT: SERVER_URL + 'api/' || 'http://staging.ascribe.io/api/', DEBUG: !argv.production, CREDENTIALS: 'ZGltaUBtYWlsaW5hdG9yLmNvbTowMDAwMDAwMDAw' // dimi@mailinator:0000000000 }; diff --git a/index.html b/index.html index fe4a2a4b..af9deda9 100644 --- a/index.html +++ b/index.html @@ -11,8 +11,8 @@ diff --git a/js/components/ascribe_uploader/file_drag_and_drop.js b/js/components/ascribe_uploader/file_drag_and_drop.js index a4d1781b..49fd69f9 100644 --- a/js/components/ascribe_uploader/file_drag_and_drop.js +++ b/js/components/ascribe_uploader/file_drag_and_drop.js @@ -1,3 +1,5 @@ +'use strict'; + import React from 'react'; import FileDragAndDropPreviewIterator from './file_drag_and_drop_preview_iterator'; @@ -7,12 +9,16 @@ var FileDragAndDrop = React.createClass({ propTypes: { onDragStart: React.PropTypes.func, onDrop: React.PropTypes.func.isRequired, + onDrag: React.PropTypes.func, onDragEnter: React.PropTypes.func, onLeave: React.PropTypes.func, + onDragLeave: React.PropTypes.func, onDragOver: React.PropTypes.func, onDragEnd: React.PropTypes.func, filesToUpload: React.PropTypes.array, - handleDeleteFile: React.PropTypes.func + handleDeleteFile: React.PropTypes.func, + multiple: React.PropTypes.bool, + dropzoneInactive: React.PropTypes.bool }, handleDragStart(event) { @@ -80,6 +86,12 @@ var FileDragAndDrop = React.createClass({ }, handleOnClick() { + // when multiple is set to false and the user already uploaded a piece, + // do not propagate event + if(this.props.dropzoneInactive) { + return; + } + // Simulate click on hidden file input var event = document.createEvent('HTMLEvents'); event.initEvent('click', false, true); @@ -87,11 +99,14 @@ var FileDragAndDrop = React.createClass({ }, render: function () { + console.log(this.props.dropzoneInactive); let hasFiles = this.props.filesToUpload.length > 0; + let className = hasFiles ? 'file-drag-and-drop has-files ' : 'file-drag-and-drop '; + className += this.props.dropzoneInactive ? 'inactive-dropzone' : 'active-dropzone'; return (
- {hasFiles ? null : Click or drag to add files} + {hasFiles ? null : this.props.multiple ? Click or drag to add files : Click or drag to add a file} { fetch(this.props.keyRoutine.url, { @@ -261,6 +262,26 @@ var ReactS3FineUploader = React.createClass({ }, handleUploadFile(files) { + + // If multiple set and user already uploaded its work, + // cancel upload + if(!this.props.multiple && this.state.filesToUpload.length > 0) { + return; + } + + // if multiple is set to false and user drops multiple files into the dropzone, + // take the first one and notify user that only one file can be submitted + if(!this.props.multiple && files.length > 1) { + let tempFilesList = []; + tempFilesList.push(files[0]); + + // replace filelist with first-element file list + files = tempFilesList; + + let notification = new GlobalNotificationModel('Only one file allowed (took first one)', 'danger', 10000); + GlobalNotificationActions.appendGlobalNotification(notification); + } + this.state.uploader.addFiles(files); let oldFiles = this.state.filesToUpload; let oldAndNewFiles = this.state.uploader.getUploads(); @@ -298,7 +319,9 @@ var ReactS3FineUploader = React.createClass({ + handleDeleteFile={this.handleDeleteFile} + multiple={this.props.multiple} + dropzoneInactive={!this.props.multiple && this.state.filesToUpload.length > 0} /> ); } diff --git a/js/components/login_container.js b/js/components/login_container.js index 24b63ce7..9e6dd10a 100644 --- a/js/components/login_container.js +++ b/js/components/login_container.js @@ -6,6 +6,8 @@ import Router from 'react-router'; import GlobalNotificationModel from '../models/global_notification_model'; import GlobalNotificationActions from '../actions/global_notification_actions'; +import UserStore from '../stores/user_store'; + import Form from './ascribe_forms/form'; import Property from './ascribe_forms/property'; @@ -16,6 +18,27 @@ import AppConstants from '../constants/application_constants'; let LoginContainer = React.createClass({ mixins: [Router.Navigation], + getInitialState() { + return UserStore.getState(); + }, + + componentDidMount() { + UserStore.listen(this.onChange); + }, + + componentWillUnmount() { + UserStore.unlisten(this.onChange); + }, + + onChange(state) { + this.setState(state); + + // if user is already logged in, redirect him to piece list + if(this.state.currentUser && this.state.currentUser.email) { + this.transitionTo('pieces'); + } + }, + render() { return (
@@ -32,9 +55,6 @@ let LoginContainer = React.createClass({ let LoginForm = React.createClass({ - mixins: [Router.Navigation], - - handleSuccess(){ let notification = new GlobalNotificationModel('Login successsful', 'success', 10000); GlobalNotificationActions.appendGlobalNotification(notification); diff --git a/js/components/register_piece.js b/js/components/register_piece.js index 693c43be..b12d2c2b 100644 --- a/js/components/register_piece.js +++ b/js/components/register_piece.js @@ -187,7 +187,8 @@ let FileUploader = React.createClass( { let InputDate = React.createClass({ propTypes: { - placeholderText: React.PropTypes.string + placeholderText: React.PropTypes.string, + onChange: React.PropTypes.func }, getInitialState() { diff --git a/js/components/signup_container.js b/js/components/signup_container.js index 65dfe217..145df41f 100644 --- a/js/components/signup_container.js +++ b/js/components/signup_container.js @@ -3,6 +3,9 @@ import React from 'react'; import Router from 'react-router'; +import { mergeOptions } from '../utils/general_utils'; + +import UserStore from '../stores/user_store'; import GlobalNotificationModel from '../models/global_notification_model'; import GlobalNotificationActions from '../actions/global_notification_actions'; @@ -17,18 +20,37 @@ import apiUrls from '../constants/api_urls'; let SignupContainer = React.createClass({ mixins: [Router.Navigation], - getInitialState(){ - return ({ + getInitialState() { + return mergeOptions({ submitted: false, message: null - }); + }, UserStore.getState()); }, + + componentDidMount() { + UserStore.listen(this.onChange); + }, + + componentWillUnmount() { + UserStore.unlisten(this.onChange); + }, + + onChange(state) { + this.setState(state); + + // if user is already logged in, redirect him to piece list + if(this.state.currentUser && this.state.currentUser.email) { + this.transitionTo('pieces'); + } + }, + handleSuccess(message){ this.setState({ submitted: true, message: message }); }, + render() { if (this.state.submitted){ return ( diff --git a/sass/ascribe_uploader.scss b/sass/ascribe_uploader.scss index e6583313..487aa1b0 100644 --- a/sass/ascribe_uploader.scss +++ b/sass/ascribe_uploader.scss @@ -10,6 +10,14 @@ transition: .1s linear background-color; } +.inactive-dropzone { + cursor: default !important; +} + +.inactive-dropzone:hover { + background-color: #FAFAFA !important; +} + .file-drag-and-drop:hover { background-color: rgba(72, 218, 203, 0.2); }