diff --git a/js/actions/user_actions.js b/js/actions/user_actions.js
index 1ea0c560..44682f17 100644
--- a/js/actions/user_actions.js
+++ b/js/actions/user_actions.js
@@ -13,7 +13,7 @@ class UserActions {
}
fetchCurrentUser() {
- UserFetcher.fetchOne()
+ return UserFetcher.fetchOne()
.then((res) => {
this.actions.updateCurrentUser(res.users[0]);
})
diff --git a/js/components/ascribe_forms/form_login.js b/js/components/ascribe_forms/form_login.js
index ee6efb54..24b0eb93 100644
--- a/js/components/ascribe_forms/form_login.js
+++ b/js/components/ascribe_forms/form_login.js
@@ -25,7 +25,8 @@ let LoginForm = React.createClass({
headerMessage: React.PropTypes.string,
submitMessage: React.PropTypes.string,
redirectOnLoggedIn: React.PropTypes.bool,
- redirectOnLoginSuccess: React.PropTypes.bool
+ redirectOnLoginSuccess: React.PropTypes.bool,
+ onLogin: React.PropTypes.func
},
mixins: [Router.Navigation],
@@ -70,18 +71,29 @@ let LoginForm = React.createClass({
// The easiest way to check if the user was successfully logged in is to fetch the user
// in the user store (which is obviously only possible if the user is logged in), since
// register_piece is listening to the changes of the user_store.
- UserActions.fetchCurrentUser();
+ UserActions.fetchCurrentUser()
+ .then(() => {
+ if(this.props.redirectOnLoginSuccess) {
+ /* Taken from http://stackoverflow.com/a/14916411 */
+ /*
+ We actually have to trick the Browser into showing the "save password" dialog
+ as Chrome expects the login page to be reloaded after the login.
+ Users on Stack Overflow claim this is a bug in chrome and should be fixed in the future.
+ Until then, we redirect the HARD way, but reloading the whole page using window.location
+ */
+ window.location = AppConstants.baseUrl + 'collection';
+ } else if(this.props.onLogin) {
+ // In some instances we want to give a callback to an outer container,
+ // to show that the one login action the user triggered actually went through.
+ // We can not do this by listening on a store's state as it wouldn't really tell us
+ // if the user did log in or was just fetching the user's data again
+ this.props.onLogin();
+ }
+ })
+ .catch((err) => {
+ console.logGlobal(err);
+ });
- /* Taken from http://stackoverflow.com/a/14916411 */
- /*
- We actually have to trick the Browser into showing the "save password" dialog
- as Chrome expects the login page to be reloaded after the login.
- Users on Stack Overflow claim this is a bug in chrome and should be fixed in the future.
- Until then, we redirect the HARD way, but reloading the whole page using window.location
- */
- if(this.props.redirectOnLoginSuccess) {
- window.location = AppConstants.baseUrl + 'collection';
- }
},
render() {
diff --git a/js/components/ascribe_forms/form_register_piece.js b/js/components/ascribe_forms/form_register_piece.js
index 00d3c4d4..9e513558 100644
--- a/js/components/ascribe_forms/form_register_piece.js
+++ b/js/components/ascribe_forms/form_register_piece.js
@@ -21,8 +21,9 @@ let RegisterPieceForm = React.createClass({
headerMessage: React.PropTypes.string,
submitMessage: React.PropTypes.string,
handleSuccess: React.PropTypes.func,
- isFineUploaderEditable: React.PropTypes.bool,
- children: React.PropTypes.element
+ isFineUploaderActive: React.PropTypes.bool,
+ children: React.PropTypes.element,
+ onLoggedOut: React.PropTypes.func
},
getDefaultProps() {
@@ -94,7 +95,8 @@ let RegisterPieceForm = React.createClass({
submitKey={this.submitKey}
setIsUploadReady={this.setIsUploadReady}
isReadyForFormSubmission={this.isReadyForFormSubmission}
- editable={this.props.isFineUploaderEditable}/>
+ isFineUploaderActive={this.props.isFineUploaderActive}
+ onLoggedOut={this.props.onLoggedOut}/>
+ }}
+ onInactive={this.props.onLoggedOut}/>
);
}
});
diff --git a/js/components/ascribe_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js
index 7e37c6c9..ad883d0c 100644
--- a/js/components/ascribe_slides_container/slides_container.js
+++ b/js/components/ascribe_slides_container/slides_container.js
@@ -17,7 +17,7 @@ let SlidesContainer = React.createClass({
getInitialState() {
// handle queryParameters
let queryParams = this.getQuery();
- let slideNum = 0;
+ let slideNum = -1;
if(queryParams && 'slide_num' in queryParams) {
slideNum = parseInt(queryParams.slide_num, 10);
@@ -26,17 +26,12 @@ let SlidesContainer = React.createClass({
return {
containerWidth: 0,
- slideNum: slideNum
+ slideNum: slideNum,
+ historyLength: window.history.length
};
},
componentDidMount() {
- // check if slide_num was defined, and if not then default to 0
- let queryParams = this.getQuery();
- if(!('slide_num' in queryParams)) {
- this.replaceWith(this.getPathname(), null, {slide_num: 0});
- }
-
// init container width
this.handleContainerResize();
@@ -45,6 +40,12 @@ let SlidesContainer = React.createClass({
window.addEventListener('resize', this.handleContainerResize);
},
+ componentDidUpdate() {
+ // check if slide_num was defined, and if not then default to 0
+ let queryParams = this.getQuery();
+ this.setSlideNum(queryParams.slide_num);
+ },
+
componentWillUnmount() {
window.removeEventListener('resize', this.handleContainerResize);
},
@@ -58,9 +59,45 @@ let SlidesContainer = React.createClass({
// We let every one from the outsite set the page number of the slider,
// though only if the slideNum is actually in the range of our children-list.
setSlideNum(slideNum) {
- if(slideNum < 0 || slideNum < React.Children.count(this.props.children)) {
+
+ // slideNum can in some instances be not a number,
+ // therefore we have to parse it to one and make sure that its not NaN
+ slideNum = parseInt(slideNum, 10);
+
+ // if slideNum is not a number (even after we parsed it to one) and there has
+ // never been a transition to another slide (this.state.slideNum ==== -1 indicates that)
+ // then we want to "replace" (in this case append) the current url with ?slide_num=0
+ if(isNaN(slideNum) && this.state.slideNum === -1) {
+ slideNum = 0;
this.replaceWith(this.getPathname(), null, {slide_num: slideNum});
+ this.setState({slideNum: slideNum});
+ return;
+
+ // slideNum always represents the future state. So if slideNum and
+ // this.state.slideNum are equal, there is no sense in redirecting
+ } else if(slideNum === this.state.slideNum) {
+ return;
+
+ // if slideNum is within the range of slides and none of the previous cases
+ // where matched, we can actually do transitions
+ } else if(slideNum >= 0 || slideNum < React.Children.count(this.props.children)) {
+
+ if(slideNum !== this.state.slideNum - 1) {
+ // Bootstrapping the component, getInitialState is called once to save
+ // the tabs history length.
+ // In order to know if we already pushed a new state on the history stack or not,
+ // we're comparing the old history length with the new one and if it didn't change then
+ // we push a new state on it ONCE (ever).
+ // Otherwise, we're able to use the browsers history.forward() method
+ // to keep the stack clean
+ if(this.state.historyLength === window.history.length) {
+ this.transitionTo(this.getPathname(), null, {slide_num: slideNum});
+ } else {
+ window.history.forward();
+ }
+ }
+
this.setState({
slideNum: slideNum
});
diff --git a/js/components/ascribe_uploader/file_drag_and_drop.js b/js/components/ascribe_uploader/file_drag_and_drop.js
index b95d4a19..36b83c62 100644
--- a/js/components/ascribe_uploader/file_drag_and_drop.js
+++ b/js/components/ascribe_uploader/file_drag_and_drop.js
@@ -18,6 +18,7 @@ let FileDragAndDrop = React.createClass({
onDragLeave: React.PropTypes.func,
onDragOver: React.PropTypes.func,
onDragEnd: React.PropTypes.func,
+ onInactive: React.PropTypes.func,
filesToUpload: React.PropTypes.array,
handleDeleteFile: React.PropTypes.func,
handleCancelFile: React.PropTypes.func,
@@ -72,6 +73,15 @@ let FileDragAndDrop = React.createClass({
event.stopPropagation();
let files;
+ if(this.props.dropzoneInactive) {
+ // if there is a handle function for doing stuff
+ // when the dropzone is inactive, then call it
+ if(this.props.onInactive) {
+ this.props.onInactive();
+ }
+ return;
+ }
+
// handle Drag and Drop
if(event.dataTransfer && event.dataTransfer.files.length > 0) {
files = event.dataTransfer.files;
@@ -113,10 +123,15 @@ let FileDragAndDrop = React.createClass({
this.props.handleResumeFile(fileId);
},
- handleOnClick(event) {
+ handleOnClick() {
// when multiple is set to false and the user already uploaded a piece,
// do not propagate event
if(this.props.dropzoneInactive) {
+ // if there is a handle function for doing stuff
+ // when the dropzone is inactive, then call it
+ if(this.props.onInactive) {
+ this.props.onInactive();
+ }
return;
}
diff --git a/js/components/ascribe_uploader/react_s3_fine_uploader.js b/js/components/ascribe_uploader/react_s3_fine_uploader.js
index b4726a98..7b570c2c 100644
--- a/js/components/ascribe_uploader/react_s3_fine_uploader.js
+++ b/js/components/ascribe_uploader/react_s3_fine_uploader.js
@@ -95,7 +95,8 @@ var ReactS3FineUploader = React.createClass({
isReadyForFormSubmission: React.PropTypes.func,
areAssetsDownloadable: React.PropTypes.bool,
areAssetsEditable: React.PropTypes.bool,
- defaultErrorMessage: React.PropTypes.string
+ defaultErrorMessage: React.PropTypes.string,
+ onInactive: React.PropTypes.func
},
getDefaultProps() {
@@ -560,7 +561,8 @@ var ReactS3FineUploader = React.createClass({
multiple={this.props.multiple}
areAssetsDownloadable={this.props.areAssetsDownloadable}
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}
+ onInactive={this.props.onInactive}/>
);
}
diff --git a/js/components/login_container.js b/js/components/login_container.js
index a8d5c1b1..f050014b 100644
--- a/js/components/login_container.js
+++ b/js/components/login_container.js
@@ -14,7 +14,8 @@ let LoginContainer = React.createClass({
propTypes: {
message: React.PropTypes.string,
redirectOnLoggedIn: React.PropTypes.bool,
- redirectOnLoginSuccess: React.PropTypes.bool
+ redirectOnLoginSuccess: React.PropTypes.bool,
+ onLogin: React.PropTypes.func
},
getDefaultProps() {
@@ -31,7 +32,8 @@ let LoginContainer = React.createClass({
+ message={this.props.message}
+ onLogin={this.props.onLogin}/>
{getLangText('Not an ascribe user')}? {getLangText('Sign up')}...
{getLangText('Forgot my password')}? {getLangText('Rescue me')}...
diff --git a/js/components/register_piece.js b/js/components/register_piece.js
index 37d496a8..20826b7d 100644
--- a/js/components/register_piece.js
+++ b/js/components/register_piece.js
@@ -59,7 +59,7 @@ let RegisterPiece = React.createClass( {
PieceListStore.getState(),
{
selectedLicense: 0,
- isFineUploaderEditable: false
+ isFineUploaderActive: false
});
},
@@ -82,14 +82,10 @@ let RegisterPiece = React.createClass( {
onChange(state) {
this.setState(state);
- // once the currentUser object from UserStore is defined (eventually the user was transitioned
- // to the login form via the slider and successfully logged in), we can direct him back to the
- // register_piece slide
- if(state.currentUser && state.currentUser.email || this.state.currentUser && this.state.currentUser.email) {
- this.refs.slidesContainer.setSlideNum(0);
+ if(this.state.currentUser && this.state.currentUser.email) {
// we should also make the fineuploader component editable again
this.setState({
- isFineUploaderEditable: true
+ isFineUploaderActive: true
});
}
},
@@ -105,7 +101,8 @@ let RegisterPiece = React.createClass( {
this.state.pageSize,
this.state.searchTerm,
this.state.orderBy,
- this.state.orderAsc);
+ this.state.orderAsc
+ );
this.transitionTo('piece', {pieceId: response.piece.id});
},
@@ -160,11 +157,25 @@ let RegisterPiece = React.createClass( {
changeSlide() {
// only transition to the login store, if user is not logged in
// ergo the currentUser object is not properly defined
- if(!this.state.currentUser.email) {
+ if(this.state.currentUser && !this.state.currentUser.email) {
this.refs.slidesContainer.setSlideNum(1);
}
},
+ // basically redirects to the second slide (index: 1), when the user is not logged in
+ onLoggedOut() {
+ this.refs.slidesContainer.setSlideNum(1);
+ },
+
+ onLogin() {
+ // once the currentUser object from UserStore is defined (eventually the user was transitioned
+ // to the login form via the slider and successfully logged in), we can direct him back to the
+ // register_piece slide
+ if(this.state.currentUser && this.state.currentUser.email) {
+ window.history.back();
+ }
+ },
+
render() {
return (
@@ -175,8 +186,9 @@ let RegisterPiece = React.createClass( {