2017-01-26 11:49:39 -08:00
|
|
|
import React from 'react';
|
2017-05-14 12:14:12 -07:00
|
|
|
import PropTypes from 'prop-types';
|
2017-01-26 11:49:39 -08:00
|
|
|
|
2017-02-01 16:27:51 -05:00
|
|
|
import { NavigationActions, addNavigationHelpers } from 'react-navigation';
|
2017-01-26 11:49:39 -08:00
|
|
|
|
|
|
|
function getAction(router, path, params) {
|
|
|
|
const action = router.getActionForPathAndParams(path, params);
|
|
|
|
if (action) {
|
|
|
|
return action;
|
|
|
|
}
|
2017-02-01 16:27:51 -05:00
|
|
|
return NavigationActions.navigate({
|
2017-01-26 11:49:39 -08:00
|
|
|
params: { path },
|
|
|
|
routeName: 'NotFound',
|
2017-02-01 16:27:51 -05:00
|
|
|
});
|
2017-01-26 11:49:39 -08:00
|
|
|
}
|
|
|
|
|
2017-05-14 12:14:12 -07:00
|
|
|
export default NavigationAwareView => {
|
|
|
|
const initialAction = getAction(
|
|
|
|
NavigationAwareView.router,
|
|
|
|
window.location.pathname.substr(1)
|
|
|
|
);
|
|
|
|
const initialState = NavigationAwareView.router.getStateForAction(
|
|
|
|
initialAction
|
|
|
|
);
|
|
|
|
console.log({ initialAction, initialState });
|
2017-01-26 11:49:39 -08:00
|
|
|
|
|
|
|
class NavigationContainer extends React.Component {
|
|
|
|
state = initialState;
|
|
|
|
componentDidMount() {
|
2017-05-14 12:14:12 -07:00
|
|
|
const navigation = addNavigationHelpers({
|
|
|
|
state: this.state.routes[this.state.index],
|
|
|
|
dispatch: this.dispatch,
|
|
|
|
});
|
|
|
|
document.title = NavigationAwareView.router.getScreenOptions(
|
|
|
|
navigation
|
|
|
|
).title;
|
|
|
|
window.onpopstate = e => {
|
2017-01-26 11:49:39 -08:00
|
|
|
e.preventDefault();
|
2017-05-14 12:14:12 -07:00
|
|
|
const action = getAction(
|
|
|
|
NavigationAwareView.router,
|
|
|
|
window.location.pathname.substr(1)
|
|
|
|
);
|
2017-01-26 11:49:39 -08:00
|
|
|
if (action) this.dispatch(action);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
componentWillUpdate(props, state) {
|
2017-05-14 12:14:12 -07:00
|
|
|
const {
|
|
|
|
path,
|
|
|
|
params,
|
|
|
|
} = NavigationAwareView.router.getPathAndParamsForState(state);
|
2017-04-18 15:25:12 +02:00
|
|
|
const maybeHash = params && params.hash ? `#${params.hash}` : '';
|
|
|
|
const uri = `/${path}${maybeHash}`;
|
2017-01-26 11:49:39 -08:00
|
|
|
if (window.location.pathname !== uri) {
|
|
|
|
window.history.pushState({}, state.title, uri);
|
|
|
|
}
|
2017-05-14 12:14:12 -07:00
|
|
|
const navigation = addNavigationHelpers({
|
|
|
|
state: state.routes[state.index],
|
|
|
|
dispatch: this.dispatch,
|
|
|
|
});
|
|
|
|
document.title = NavigationAwareView.router.getScreenOptions(
|
|
|
|
navigation
|
|
|
|
).title;
|
2017-01-26 11:49:39 -08:00
|
|
|
}
|
2017-04-18 15:25:12 +02:00
|
|
|
componentDidUpdate() {
|
2017-05-14 12:14:12 -07:00
|
|
|
const { params } = NavigationAwareView.router.getPathAndParamsForState(
|
|
|
|
this.state
|
|
|
|
);
|
2017-04-18 15:25:12 +02:00
|
|
|
if (params && params.hash) {
|
|
|
|
document.getElementById(params.hash).scrollIntoView();
|
|
|
|
}
|
|
|
|
}
|
2017-05-14 12:14:12 -07:00
|
|
|
dispatch = action => {
|
|
|
|
const state = NavigationAwareView.router.getStateForAction(
|
|
|
|
action,
|
|
|
|
this.state
|
|
|
|
);
|
2017-01-26 11:49:39 -08:00
|
|
|
|
|
|
|
if (!state) {
|
2017-05-14 12:14:12 -07:00
|
|
|
console.log('Dispatched action did not change state: ', { action });
|
2017-01-26 11:49:39 -08:00
|
|
|
} else if (console.group) {
|
|
|
|
console.group('Navigation Dispatch: ');
|
|
|
|
console.log('Action: ', action);
|
|
|
|
console.log('New State: ', state);
|
|
|
|
console.log('Last State: ', this.state);
|
|
|
|
console.groupEnd();
|
|
|
|
} else {
|
2017-05-14 12:14:12 -07:00
|
|
|
console.log('Navigation Dispatch: ', {
|
|
|
|
action,
|
|
|
|
newState: state,
|
|
|
|
lastState: this.state,
|
|
|
|
});
|
2017-01-26 11:49:39 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!state) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state !== this.state) {
|
|
|
|
this.setState(state);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
render() {
|
2017-05-14 12:14:12 -07:00
|
|
|
return (
|
|
|
|
<NavigationAwareView
|
|
|
|
navigation={addNavigationHelpers({
|
|
|
|
state: this.state,
|
|
|
|
dispatch: this.dispatch,
|
|
|
|
})}
|
|
|
|
/>
|
|
|
|
);
|
2017-01-26 11:49:39 -08:00
|
|
|
}
|
2017-05-14 12:14:12 -07:00
|
|
|
getURIForAction = action => {
|
|
|
|
const state =
|
|
|
|
NavigationAwareView.router.getStateForAction(action, this.state) ||
|
|
|
|
this.state;
|
|
|
|
const { path } = NavigationAwareView.router.getPathAndParamsForState(
|
|
|
|
state
|
|
|
|
);
|
2017-01-26 11:49:39 -08:00
|
|
|
return `/${path}`;
|
2017-05-14 12:14:12 -07:00
|
|
|
};
|
2017-01-26 11:49:39 -08:00
|
|
|
getActionForPathAndParams = (path, params) => {
|
|
|
|
return NavigationAwareView.router.getActionForPathAndParams(path, params);
|
2017-05-14 12:14:12 -07:00
|
|
|
};
|
2017-01-26 11:49:39 -08:00
|
|
|
static childContextTypes = {
|
2017-05-14 12:14:12 -07:00
|
|
|
getActionForPathAndParams: PropTypes.func.isRequired,
|
|
|
|
getURIForAction: PropTypes.func.isRequired,
|
|
|
|
dispatch: PropTypes.func.isRequired,
|
2017-01-26 11:49:39 -08:00
|
|
|
};
|
|
|
|
getChildContext() {
|
|
|
|
return {
|
|
|
|
getActionForPathAndParams: this.getActionForPathAndParams,
|
|
|
|
getURIForAction: this.getURIForAction,
|
|
|
|
dispatch: this.dispatch,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NavigationContainer;
|
|
|
|
};
|