From 20a83167abe5fac634201c2dd0d550c6083edd9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Tue, 21 Jul 2015 15:05:42 +0200 Subject: [PATCH] slide container works now with browser history --- js/actions/user_actions.js | 2 +- js/components/ascribe_forms/form_login.js | 32 ++++++++----- .../slides_container.js | 48 +++++++++++++++---- js/components/login_container.js | 6 ++- js/components/register_piece.js | 27 ++++++----- 5 files changed, 79 insertions(+), 36 deletions(-) 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..76eb904e 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,25 @@ 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(() => { + /* 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'; + } else if(this.props.onLogin) { + 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_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js index 7e37c6c9..6b4bbe2c 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,38 @@ 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 && !document.referrer) { + + 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/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 50af9082..dc168a35 100644 --- a/js/components/register_piece.js +++ b/js/components/register_piece.js @@ -81,17 +81,6 @@ 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); - // we should also make the fineuploader component editable again - this.setState({ - isFineUploaderActive: true - }); - } }, handleSuccess(response){ @@ -171,6 +160,19 @@ let RegisterPiece = React.createClass( { 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(); + // we should also make the fineuploader component editable again + this.setState({ + isFineUploaderActive: true + }); + } + }, + render() { return ( @@ -195,7 +197,8 @@ let RegisterPiece = React.createClass( { + redirectOnLoginSuccess={false} + onLogin={this.onLogin}/>
);