"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, api: { getNavigationState, topOfNavigationStack, resetRoutes, isRoute, isTopRoute, goBackFrom }, createConnectedNavigatorPieces }; };