Browse Source

Implementation.

Copied out of existing project.
Herby Vojčík 6 years ago
parent
commit
c4cf5f4628
2 changed files with 80 additions and 1 deletions
  1. 73 0
      index.js
  2. 7 1
      package.json

+ 73 - 0
index.js

@@ -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
+    };
+};

+ 7 - 1
package.json

@@ -16,5 +16,11 @@
     "redux"
   ],
   "author": "Herby Vojčík <herby@mailbox.sk>",
-  "license": "MIT"
+  "license": "MIT",
+  "dependencies": {
+    "react-navigation": "^1.2.1",
+    "react-navigation-redux-helpers": "^1.0.1",
+    "react-redux": "^5.0.7",
+    "redux-sac": "^0.6.0"
+  }
 }