diff --git a/src/index.js b/src/index.js index 0be472a..2a9ce67 100644 --- a/src/index.js +++ b/src/index.js @@ -37,7 +37,10 @@ userFactory(store) ReactDOM.render( - + { + restoreScroll(); + stopLoading(); + }}> {routesFactory(store)} @@ -45,7 +48,6 @@ userFactory(store) document.getElementById('app') ); - document.getElementById('loader').classList.remove('is-active'); }); /** @@ -66,7 +68,13 @@ function restoreScroll() { }, 100); } +function stopLoading() { + document.getElementById('loader').classList.remove('is-active'); +} + if (process.env.NODE_ENV !== 'production') { // some shortcuts for testing on localhost window.testOAuth = () => location.href = '/oauth?client_id=ely&redirect_uri=http%3A%2F%2Fely.by&response_type=code&scope=minecraft_server_session'; + window.testOAuthStatic = () => location.href = '/oauth?client_id=ely&redirect_uri=static_page_with_code&response_type=code&scope=minecraft_server_session'; + window.testOAuthStaticCode = () => location.href = '/oauth?client_id=ely&redirect_uri=static_page&response_type=code&scope=minecraft_server_session'; } diff --git a/src/routes.js b/src/routes.js index 4368711..17a5180 100644 --- a/src/routes.js +++ b/src/routes.js @@ -30,7 +30,7 @@ export default function routesFactory(store) { authFlow.setStore(store); const startAuthFlow = { - onEnter: ({location}, replace) => authFlow.handleRequest(location.pathname, replace) + onEnter: ({location}, replace, callback) => authFlow.handleRequest(location.pathname, replace, callback) }; const userOnly = { diff --git a/src/services/authFlow/AuthFlow.js b/src/services/authFlow/AuthFlow.js index a766630..a505d76 100644 --- a/src/services/authFlow/AuthFlow.js +++ b/src/services/authFlow/AuthFlow.js @@ -77,11 +77,20 @@ export default class AuthFlow { this.state && this.state.leave(this); this.state = state; - this.state.enter(this); + const resp = this.state.enter(this); + + if (resp && resp.then) { + // this is a state with an async enter phase + // block route components from mounting, till promise will be resolved + const callback = this.onReady; + this.onReady = () => {}; + return resp.then(callback); + } } - handleRequest(path, replace) { + handleRequest(path, replace, callback) { this.replace = replace; + this.onReady = callback; if (path === '/') { // reset oauth data if user tried to navigate to index route @@ -125,5 +134,7 @@ export default class AuthFlow { throw new Error(`Unsupported request: ${path}`); } } + + this.onReady(); } } diff --git a/src/services/authFlow/CompleteState.js b/src/services/authFlow/CompleteState.js index 8ce170c..d7ab333 100644 --- a/src/services/authFlow/CompleteState.js +++ b/src/services/authFlow/CompleteState.js @@ -32,13 +32,15 @@ export default class CompleteState extends AbstractState { context.setState(new PermissionsState()); return; } - context.run('oAuthComplete', data).then((resp) => { + // TODO: it seams that oAuthComplete may be a separate state + return context.run('oAuthComplete', data).then((resp) => { // TODO: пусть в стейт попадает флаг или тип авторизации // вместо волшебства над редирект урлой if (resp.redirectUri.indexOf('static_page') === 0) { context.setState(new FinishState()); } else { context.run('redirect', resp.redirectUri); + return Promise.reject(); // do not allow loader to be hidden and app to be rendered } }, (resp) => { if (resp.unauthorized) { diff --git a/src/services/authFlow/OAuthState.js b/src/services/authFlow/OAuthState.js index de788b6..e33a35e 100644 --- a/src/services/authFlow/OAuthState.js +++ b/src/services/authFlow/OAuthState.js @@ -5,7 +5,7 @@ export default class OAuthState extends AbstractState { enter(context) { const query = context.getState().routing.location.query; - context.run('oAuthValidate', { + return context.run('oAuthValidate', { clientId: query.client_id, redirectUrl: query.redirect_uri, responseType: query.response_type,