|
@@ -0,0 +1,73 @@
|
|
|
|
+"use strict";
|
|
|
|
+
|
|
|
|
+import {addNavigationHelpers, NavigationActions} from 'react-navigation';
|
|
|
|
+import {createReactNavigationReduxMiddleware, createReduxBoundAddListener} from 'react-navigation-redux-helpers';
|
|
|
|
+import {subReducer, cowValueModel as cow} from 'redux-sac';
|
|
|
|
+import {connect} from 'react-redux';
|
|
|
|
+
|
|
|
|
+const {navigate, back, reset} = NavigationActions;
|
|
|
|
+
|
|
|
|
+export default navigationStateKey => {
|
|
|
|
+ const accessNavigationState = cow(navigationStateKey);
|
|
|
|
+
|
|
|
|
+ const createNavigationReduxConnector = name => ({
|
|
|
|
+ middleware: createReactNavigationReduxMiddleware(name, accessNavigationState),
|
|
|
|
+ connectNavigation: connect(
|
|
|
|
+ state => ({state: accessNavigationState(state)}),
|
|
|
|
+ null,
|
|
|
|
+ ({state}, {dispatch}, ownProps) => ({
|
|
|
|
+ navigation: addNavigationHelpers({dispatch, state, addListener: createReduxBoundAddListener(name)}),
|
|
|
|
+ ...ownProps
|
|
|
|
+ })
|
|
|
|
+ )
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ const backButtonHandler = ({dispatch, getState}) => {
|
|
|
|
+ if (accessNavigationState(getState()).index === 0) return false;
|
|
|
|
+ dispatch(back());
|
|
|
|
+ return true;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const topOfNavigationStack = state => {
|
|
|
|
+ const {routes} = accessNavigationState(state);
|
|
|
|
+ return routes[routes.length - 1] || {};
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const createConnectedNavigatorPieces = (BareNavigator, name = "root") => {
|
|
|
|
+ const {middleware, connectNavigation} = createNavigationReduxConnector(name);
|
|
|
|
+ const bareReducer = (state, action) => BareNavigator.router.getStateForAction(action, state);
|
|
|
|
+ return {
|
|
|
|
+ Navigator: connectNavigation(BareNavigator),
|
|
|
|
+ reducer: subReducer(navigationStateKey, bareReducer),
|
|
|
|
+ middleware
|
|
|
|
+ };
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const resetRoutes = routeNames => reset({
|
|
|
|
+ actions: routeNames.map(routeName => navigate({routeName})),
|
|
|
|
+ index: routeNames.length - 1
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ const isRoute = expected => ({routeName}) => routeName === expected;
|
|
|
|
+
|
|
|
|
+ const isTopRoute = expected => state => isRoute(expected)(topOfNavigationStack(state));
|
|
|
|
+
|
|
|
|
+ const goBackFrom = routeName => ({dispatch, getState}) => {
|
|
|
|
+ if (isTopRoute(routeName)(getState())) {
|
|
|
|
+ dispatch(back());
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const getNavigationState = state => accessNavigationState(state);
|
|
|
|
+
|
|
|
|
+ return {
|
|
|
|
+ backButtonHandler,
|
|
|
|
+ getNavigationState,
|
|
|
|
+ topOfNavigationStack,
|
|
|
|
+ resetRoutes,
|
|
|
|
+ isRoute,
|
|
|
|
+ isTopRoute,
|
|
|
|
+ goBackFrom,
|
|
|
|
+ createConnectedNavigatorPieces
|
|
|
|
+ };
|
|
|
|
+};
|