diff --git a/Example/Example.js b/Example/Example.js index 2928d6aea..e26f8a3c0 100644 --- a/Example/Example.js +++ b/Example/Example.js @@ -78,7 +78,7 @@ const Example = () => ( - + { console.log('Drawer closed') }} onEnter={() => { console.log('Drawer opened') }} contentComponent={DrawerContent} drawerImage={MenuIcon} drawerWidth={300}> {/* Wrapper Scene needed to fix a bug where the tabs would reload as a modal ontop of itself diff --git a/src/State.js b/src/State.js index c50d0fc23..012128ff4 100644 --- a/src/State.js +++ b/src/State.js @@ -22,6 +22,19 @@ export function isActiveRoute(state, routeName) { return isActiveRoute(state.routes[state.index], routeName); } +export function getRouteNameByKey(state, key) { + if (state.key === key) { + return state.routeName; + } + if (!state.routes) { + return state.routeName; + } + if (state.routes[state.index].key === key) { + return state.routes[state.index].routeName; + } + return getRouteNameByKey(state.routes[state.index], key); +} + export function getActiveState(param, parent) { const state = param; if (!state.routes) { diff --git a/src/navigationStore.js b/src/navigationStore.js index c5abb4dd7..e91c60b66 100644 --- a/src/navigationStore.js +++ b/src/navigationStore.js @@ -20,7 +20,7 @@ import { LeftButton, RightButton, BackButton } from './NavBar'; import LightboxRenderer from './LightboxRenderer'; import _drawerImage from '../images/menu_burger.png'; import Scene from './Scene'; -import { getActiveState, getParent } from './State'; +import { getActiveState, getParent, getRouteNameByKey } from './State'; import Modal from './Modal'; import Lightbox from './Lightbox'; import Drawer from './Drawer'; @@ -512,6 +512,42 @@ class NavigationStore { Navigator.router.getStateForAction = (cmd, state) => (this.reducer ? this.reducer(state, cmd) : reducer(state, cmd)); }; + onEnterHandler = async (currentScene) => { + if (this.states[currentScene]) { + const handler = this[currentScene + OnEnter]; + const success = this.states[currentScene].success || defaultSuccess; + const failure = this.states[currentScene].failure || defaultFailure; + if (handler) { + try { + const res = await handler(this.currentParams, this.state); + if (res) { + success(res); + } else { + failure(); + } + } catch (e) { + failure({ error: e.message }); + } + } + } + } + + onExitHandler = (prevScene) => { + if (prevScene) { + const exitHandler = this[prevScene + OnExit]; + if (exitHandler) { + try { + const res = exitHandler(this.state); + if (res instanceof Promise) { + res.then(defaultSuccess, defaultFailure); + } + } catch (e) { + console.error('Error during onExit handler:', e); + } + } + } + } + onNavigationStateChange = async (prevState, currentState, action) => { this.state = currentState; this.prevState = prevState; @@ -522,41 +558,19 @@ class NavigationStore { this.prevScene = this.prevState ? getActiveState(this.prevState).routeName : null; if (this.currentScene !== this.prevScene) { // run onExit for old scene - if (this.prevScene) { - const exitHandler = this[this.prevScene + OnExit]; - if (exitHandler) { - try { - const res = exitHandler(this.state); - if (res instanceof Promise) { - res.then(defaultSuccess, defaultFailure); - } - } catch (e) { - console.error('Error during onExit handler:', e); - } - } - } + this.onExitHandler(this.prevScene); setTimeout(() => this.dispatch({ type: ActionConst.FOCUS, routeName: this.currentScene, params: this.currentParams, })); - if (this.states[currentScene]) { - const handler = this[currentScene + OnEnter]; - const success = this.states[currentScene].success || defaultSuccess; - const failure = this.states[currentScene].failure || defaultFailure; - // call onEnter handler - if (handler) { - try { - const res = await handler(this.currentParams, this.state); - if (res) { - success(res); - } else { - failure(); - } - } catch (e) { - failure({ error: e.message }); - } - } + this.onEnterHandler(currentScene); + } else { + const routeName = getRouteNameByKey(this.state, action.key); + if (action.type === 'Navigation/DRAWER_OPENED') { + this.onEnterHandler(routeName); + } else if (action.type === 'Navigation/DRAWER_CLOSED') { + this.onExitHandler(routeName); } } if (this.onStateChange) { @@ -749,6 +763,7 @@ class NavigationStore { )(this, { error: '', ...commonProps, ...props }, type); } + if ((onEnter || on || (component && component.onEnter)) && !this[key + OnEnter]) { this[key + OnEnter] = onEnter || on || component.onEnter; }