Navigation modal fix (#303)

* Navigation modal fix

* Review feedback
This commit is contained in:
Chris Duarte 2017-02-27 12:11:10 -08:00 committed by Harrison Healey
parent e6547c6970
commit 24e4fb5311
3 changed files with 57 additions and 40 deletions

View file

@ -24,33 +24,41 @@ export default class NavigationModal extends PureComponent {
}
componentWillReceiveProps(nextProps) {
if (this.props.show === nextProps.show) {
return;
}
if (nextProps.show) {
let currentRouteKeys;
const nextRouteKeys = nextProps.children.props.navigationState.routes.map((r) => r.key).join('');
if (this.state.children) {
currentRouteKeys = this.state.children.props.navigationState.routes.map((r) => r.key).join('');
}
// In order for the scene to be shown throughout the
// animated slide down we have to hang on to it by
// storing it in state
if (!this.state.children) {
this.setState({
children: nextProps.children
});
}
const routesDidChange = currentRouteKeys !== nextRouteKeys;
const animateValue = nextProps.show ? 0 : deviceHeight;
Animated.timing(this.state.top, {
toValue: animateValue,
duration: 400
}).start(() => {
// Once the scene has finished sliding down we can release the child scene
// which will unmount the scene correctly.
if (!this.props.show && !nextProps.show) {
// In order for the scene to be shown throughout the
// animated slide down we have to hang on to it by
// storing it in state
if (routesDidChange) {
this.setState({
children: null
children: nextProps.children
});
}
});
}
if (nextProps.show !== this.props.show) {
const animateValue = nextProps.show ? 0 : deviceHeight;
Animated.timing(this.state.top, {
toValue: animateValue,
duration: 400
}).start(() => {
// Once the scene has finished sliding down we can release the child scene
// which will unmount the scene correctly.
if (!this.props.show && !nextProps.show) {
this.setState({
children: null
});
}
});
}
}
render() {

View file

@ -30,26 +30,26 @@ class Router extends React.Component {
headerEventSubscriptions = {};
emitHeaderEvent = (event) => {
const subscription = this.headerEventSubscriptions[event];
emitHeaderEvent = (key) => (event) => {
const subscription = this.headerEventSubscriptions[`${key}-${event}`];
if (subscription) {
subscription();
}
}
subscribeToHeaderEvent = (event, callback) => {
this.headerEventSubscriptions[event] = callback;
subscribeToHeaderEvent = (key) => (event, callback) => {
this.headerEventSubscriptions[`${key}-${event}`] = callback;
}
unsubscribeFromHeaderEvent = (event) => {
unsubscribeFromHeaderEvent = (key) => (event) => {
if (this.headerEventSubscriptions[event]) {
Reflect.deleteProperty(this.headerEventSubscriptions, event);
Reflect.deleteProperty(this.headerEventSubscriptions, `${key}-${event}`);
}
}
wrapHeaderComponent = (fx) => (props) => {
wrapHeaderComponent = (fx, emitter) => (props) => {
if (fx && props.scene.isActive) {
return fx(props, this.emitHeaderEvent, this.props.theme);
return fx(props, emitter, this.props.theme);
}
return null;
@ -63,9 +63,10 @@ class Router extends React.Component {
const navigationProps = this.extractNavigationProps(transitionProps.scene.route);
let navBar = null;
if (!navigationProps.hideNavBar) {
const renderLeftComponent = transitionProps.navigationState.index > 0 ? this.wrapHeaderComponent(navigationProps.renderBackButton) : this.wrapHeaderComponent(navigationProps.renderLeftComponent);
const renderTitleComponent = navigationProps.renderTitleComponent ? this.wrapHeaderComponent(navigationProps.renderTitleComponent) : this.renderTitle;
const renderRightComponent = this.wrapHeaderComponent(navigationProps.renderRightComponent);
const emitter = this.emitHeaderEvent(transitionProps.scene.route.key);
const renderLeftComponent = transitionProps.navigationState.index > 0 ? this.wrapHeaderComponent(navigationProps.renderBackButton, emitter) : this.wrapHeaderComponent(navigationProps.renderLeftComponent, emitter);
const renderTitleComponent = navigationProps.renderTitleComponent ? this.wrapHeaderComponent(navigationProps.renderTitleComponent, emitter) : this.renderTitle;
const renderRightComponent = this.wrapHeaderComponent(navigationProps.renderRightComponent, emitter);
navBar = (
<NavigationExperimental.Header
@ -151,10 +152,13 @@ class Router extends React.Component {
renderRoute = (route) => {
const SceneComponent = route.component;
const emitterSubscriber = this.subscribeToHeaderEvent(route.key);
const emitterUnsubscriber = this.unsubscribeFromHeaderEvent(route.key);
return (
<SceneComponent
subscribeToHeaderEvent={this.subscribeToHeaderEvent}
unsubscribeFromHeaderEvent={this.unsubscribeFromHeaderEvent}
subscribeToHeaderEvent={emitterSubscriber}
unsubscribeFromHeaderEvent={emitterUnsubscriber}
{...route.props}
/>
);

View file

@ -47,13 +47,18 @@ export default function(state = initialState, action) {
}
if (state.isModal) {
const nextModalState = state.modal.routes.length > 1 ?
NavigationExperimental.StateUtils.pop(state.modal) :
{
index: 0,
routes: []
};
const isModal = nextModalState.routes.length > 0;
return {
...state,
modal: {
index: 0,
routes: []
},
isModal: false
modal: nextModalState,
isModal
};
}