Instantly share code, notes, and snippets.
Last active
August 11, 2016 00:05
-
Star
(1)
1
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save mmazzarolo/5a4f235b6b07fa14247c0fb081b1f13f to your computer and use it in GitHub Desktop.
NavigationExperimental setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Redux navigations tore | |
{ | |
key: '1', | |
index: 0, | |
children: [{ key: 'museumList', title: 'I musei' }], | |
isDrawerOpen: false | |
} | |
// Navigation structure | |
src | |
├── actions | |
│ ├── types.js | |
│ ├── navigationActions.js | |
│ └── index.js | |
├── components | |
│ ├── NavBar.ios.js | |
│ └── NavBar.android.js | |
├── navigation | |
│ ├── Drawer.js // In my opinion the Drawer should be tied to the navigation | |
│ ├── index.js // Connects Redux to navigation experimental | |
│ ├── NavigationRouter.js // The Navigator Experimental component | |
│ └── routes.js // Routes with each property (should be seen in drawer? etc...) | |
└──reducers | |
├── index.js | |
└── NavigationReducer.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import createAction from '../actions/createAction' | |
import Types from '../actions/types' | |
import routes from '../navigation/routes' | |
const navigatePush = (child) => { | |
child = typeof child === 'string' ? { key: child, title: child } : child | |
return createAction(Types.NAV_PUSH, { child }) | |
} | |
const navigatePop = () => | |
createAction(Types.NAV_POP) | |
const navigateJumpToKey = (key) => | |
createAction(Types.NAV_JUMP_TO_KEY, { key }) | |
const navigateJumpToIndex = (index) => | |
createAction(Types.NAV_JUMP_TO_INDEX, { index }) | |
const navigateReset = (children, index) => | |
createAction(Types.NAV_RESET, { children, index }) | |
const openDrawer = () => | |
createAction(Types.SET_DRAWER_OPEN, { isDrawerOpen: true }) | |
const closeDrawer = () => | |
createAction(Types.SET_DRAWER_OPEN, { isDrawerOpen: false }) | |
const navigateToMuseumList = () => | |
navigatePush(routes.museumList) | |
const navigateToMuseumDetail = () => | |
navigatePush(routes.museumDetail) | |
export default { | |
navigatePush, | |
navigatePop, | |
navigateJumpToKey, | |
navigateJumpToIndex, | |
navigateReset, | |
openDrawer, | |
closeDrawer, | |
navigateToMuseumList, | |
navigateToMuseumDetail, | |
navigateToArtifactDetail, | |
navigateToBookmarkedArtifacts | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
import { StyleSheet } from 'react-native' | |
import Colors from '../theme/colors' | |
import Metrics from '../theme/metrics' | |
import Icon from 'react-native-vector-icons/Ionicons' | |
export default class NavBar extends Component { | |
static propTypes = { | |
title: React.PropTypes.string, | |
onLeftPress: React.PropTypes.func, | |
showDrawer: React.PropTypes.bool | |
} | |
render () { | |
const { title, onLeftPress, showDrawer } = this.props | |
return ( | |
<Icon.ToolbarAndroid | |
navIconName={showDrawer ? 'navicon-round' : 'android-arrow-back'} | |
onIconClicked={onLeftPress} | |
style={styles.toolbar} | |
titleColor='white' | |
title={title} | |
/> | |
) | |
} | |
} | |
const styles = StyleSheet.create({ | |
toolbar: { | |
backgroundColor: Colors.PRIMARY, | |
height: Metrics.NAVBAR_HEIGHT, | |
position: 'absolute', top: 0, left: 0, width: Metrics.DEVICE_WIDTH // TO-DO | |
} | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, PropTypes } from 'react' | |
import { NavigationExperimental, StyleSheet } from 'react-native' | |
import Colors from '../theme/colors' | |
import Icon from 'react-native-vector-icons/Ionicons' | |
import TouchableView from '../components/TouchableView' | |
const { Header } = NavigationExperimental | |
export default class NavigationHeader extends Component { | |
static propTypes = { | |
title: PropTypes.string, | |
onLeftPress: PropTypes.func, | |
showDrawer: PropTypes.bool | |
} | |
_renderTitleComponent = () => { | |
const { title } = this.props | |
return ( | |
<Header.Title textStyle={styles.titleText}> | |
{title} | |
</Header.Title> | |
) | |
} | |
_renderLeftComponent = () => { | |
const { onLeftPress, showDrawer } = this.props | |
return ( | |
<TouchableView onPress={onLeftPress} style={styles.leftButton}> | |
<Icon name={showDrawer ? 'navicon-round' : 'chevron-left'} size={18} color='white' /> | |
</TouchableView> | |
) | |
} | |
render () { | |
return ( | |
<Header | |
{...this.props} | |
style={styles.container} | |
renderTitleComponent={this._renderTitleComponent} | |
renderLeftComponent={this._renderLeftComponent} | |
/> | |
) | |
} | |
} | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1, | |
backgroundColor: Colors.PRIMARY | |
}, | |
titleText: { | |
color: 'white' | |
}, | |
leftButton: { | |
padding: 14 | |
} | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, PropTypes } from 'react' | |
import { Image, StyleSheet, View } from 'react-native' | |
import R from 'ramda' | |
import { connect } from 'react-redux' | |
import ReactNativeDrawer from 'react-native-drawer' | |
import Actions from '../actions' | |
import DrawerItem from '../components/DrawerItem' | |
import Colors from '../theme/colors' | |
import Metrics from '../theme/metrics' | |
import drawerSelector from '../selectors/drawerSelector' | |
import routes from '../navigation/routes' | |
class Drawer extends Component { | |
static propTypes = { | |
navigationState: PropTypes.object, | |
currentRoute: PropTypes.string, | |
isDrawerOpen: PropTypes.bool, | |
isDrawerEnabled: PropTypes.bool, | |
navigateReset: PropTypes.func, | |
navigatePush: PropTypes.func, | |
openDrawer: PropTypes.func, | |
closeDrawer: PropTypes.func, | |
children: PropTypes.any | |
} | |
_renderContent = () => { | |
return ( | |
<View style={styles.container}> | |
<View style={styles.header}> | |
</View> | |
<View style={styles.body}> | |
{this._createDrawerItems()} | |
</View> | |
</View> | |
) | |
} | |
_createDrawerItems = () => { | |
const { currentRoute, navigateReset } = this.props | |
const drawerItems = [] | |
R.values(routes).forEach(r => { | |
if (!r.showInDrawer) return | |
drawerItems.push( | |
<DrawerItem | |
key={r.key} | |
text={r.title} | |
iconName={r.drawerIcon} | |
onPress={() => { | |
// SAD SAD SAD :( NOT WORKING AS INTENDED | |
navigateReset([{ key: r.key, title: r.title }], 0) | |
// this.props.navigateToMuseumList() | |
// navigateReset([{ key: r.key, title: r.title }], 0) | |
// navigateJumpToIndex(0) | |
// // navigatePush() | |
}} | |
isSelected={r.key === currentRoute} | |
/> | |
) | |
}) | |
return drawerItems | |
} | |
render () { | |
const { children, isDrawerOpen, isDrawerEnabled, openDrawer, closeDrawer } = this.props | |
const style = { | |
drawer: { shadowColor: '#000000', shadowOpacity: 0.8, shadowRadius: 3 }, | |
main: { paddingLeft: 3 }, | |
mainOverlay: { backgroundColor: 'black', opacity: 0 } | |
} | |
const tweenHandler = (ratio) => ({ mainOverlay: { opacity: (ratio / 2) } }) | |
return ( | |
<ReactNativeDrawer | |
ref='drawer' | |
type='overlay' | |
content={this._renderContent()} | |
captureGestures='open' | |
tapToClose={true} | |
acceptPan={true} | |
openDrawerOffset={0.2} | |
closedDrawerOffset={-3} | |
panOpenMask={0.2} | |
negotiatePan={true} | |
styles={style} | |
tweenHandler={tweenHandler} | |
open={isDrawerOpen} | |
onOpen={openDrawer} | |
onClose={closeDrawer} | |
disabled={!isDrawerEnabled} | |
> | |
{children} | |
</ReactNativeDrawer> | |
) | |
} | |
} | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1, | |
backgroundColor: 'white' | |
}, | |
header: { | |
backgroundColor: Colors.PRIMARY_LIGHTER, | |
height: Metrics.DEVICE_HEIGHT / 4 | |
} | |
}) | |
export default connect(drawerSelector, Actions)(Drawer) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { NavigationExperimental } from 'react-native' | |
import { connect } from 'react-redux' | |
import NavigationRouter from './NavigationRouter' | |
import Actions from '../actions' | |
const { Card, RootContainer } = NavigationExperimental | |
const mapStateToProps = (state) => ({ state.navigation }) | |
const mapDispatchToProps = (dispatch) => ({ | |
onNavigate: (action) => { | |
console.log('mapDispatchToProps', action) | |
// Two types of actions are likely to be passed, both representing "back" | |
// style actions. Check if a type has been indicated, and try to match it. | |
if (action.type && ( | |
action.type === RootContainer.getBackAction().type || | |
action.type === Card.CardStackPanResponder.Actions.BACK.type) | |
) { | |
dispatch(Actions.navigatePop()) | |
} else { | |
// Currently unused by NavigationExperimental (only passes back actions), | |
// but could potentially be used by custom components. | |
dispatch(Actions.navigatePush(action)) | |
} | |
}, | |
openDrawer: () => dispatch(Actions.openDrawer()), | |
closeDrawer: () => dispatch(Actions.closeDrawer()), | |
enableDrawer: () => dispatch(Actions.enableDrawer()), | |
disableDrawer: () => dispatch(Actions.disableDrawer()) | |
}) | |
export default connect(mapStateToProps, mapDispatchToProps)(NavigationRouter) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, PropTypes } from 'react' | |
import { NavigationExperimental, StyleSheet } from 'react-native' | |
import routes from './routes' | |
import NavBar from '../components/NavBar' | |
import Metrics from '../theme/metrics' | |
import Drawer from './Drawer' | |
import MuseumListScreen from '../containers/MuseumListScreen' | |
import MuseumDetailScreen from '../containers/MuseumDetailScreen' | |
const { AnimatedView, Card, RootContainer } = NavigationExperimental | |
export default class NavigationRouter extends Component { | |
static propTypes = { | |
navigationState: PropTypes.object, | |
onNavigate: PropTypes.func.isRequired, | |
openDrawer: PropTypes.func.isRequired | |
} | |
_renderScene = (navigatorProps) => { | |
const { navigationState } = navigatorProps.scene | |
const key = navigationState.key | |
switch (key) { | |
case 'museumList': return <MuseumListScreen /> | |
case 'museumDetail': return <MuseumDetailScreen /> | |
} | |
} | |
_renderToolbar = (navigatorProps) => { | |
const { key, title } = navigatorProps.scene.navigationState | |
const { openDrawer, onNavigate } = this.props | |
const showDrawer = routes[key] && routes[key].showInDrawer | |
const onLeftPress = () => { | |
showDrawer ? openDrawer() : onNavigate(RootContainer.getBackAction()) | |
} | |
return ( | |
<NavBar title={title} onLeftPress={onLeftPress} {...navigatorProps} showDrawer={showDrawer} /> | |
) | |
} | |
render () { | |
const { navigationState, onNavigate } = this.props | |
return ( | |
// Note that we are not using a NavigationRootContainer here because Redux is handling | |
// the reduction of our state for us. Instead, we grab the navigationState we have in | |
// our Redux store and pass it directly to the <NavigationAnimatedView />. | |
<Drawer> | |
<AnimatedView | |
navigationState={navigationState} | |
style={styles.container} | |
onNavigate={onNavigate} | |
renderOverlay={this._renderToolbar} | |
renderScene={props => ( | |
// Again, we pass our navigationState from the Redux store to <NavigationCard />. | |
// Finally, we'll render out our scene based on navigationState in _renderScene(). | |
<Card | |
{...props} | |
panHandlers={null} | |
renderScene={this._renderScene} | |
key={props.scene.navigationState.key} | |
/> | |
)} | |
/> | |
</Drawer> | |
) | |
} | |
} | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1, | |
paddingTop: Metrics.NAVBAR_HEIGHT | |
} | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import i18n from '../i18n' | |
export default { | |
museumList: { | |
key: 'museumList', | |
title: i18n.t('SCREEN_TITLE_MUSEUM_LIST'), | |
showInDrawer: true, | |
drawerIcon: 'home' | |
}, | |
museumDetail: { | |
key: 'museumDetail', | |
title: i18n.t('SCREEN_TITLE_MUSEUM_DETAIL'), | |
showInDrawer: false | |
}, | |
news: { | |
key: 'news', | |
title: i18n.t('SCREEN_TITLE_NEWS'), | |
showInDrawer: true, | |
drawerIcon: 'speakerphone' | |
}, | |
settings: { | |
key: 'settings', | |
title: i18n.t('SCREEN_TITLE_SETTINGS'), | |
showInDrawer: true, | |
drawerIcon: 'android-settings' | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Immutable from 'seamless-immutable' | |
import * as NavigationStateUtils from 'NavigationStateUtils' | |
import Types from '../actions/types' | |
import createReducer from '../reducers/createReducer' | |
export const INITIAL_STATE = Immutable({ | |
key: 'MAIN', | |
index: 0, | |
children: [{ key: 'museumList', title: 'Museums' }], | |
isDrawerOpen: false | |
}) | |
const navPush = (state, { child }) => { | |
if (state.children[state.index].key === (child && child.key)) return state | |
const newState = NavigationStateUtils.push(state.asMutable({ deep: true }), child) | |
return Immutable(newState) | |
} | |
const navPop = (state) => { | |
if (state.index === 0 || state.children.length === 1) return state | |
const newState = NavigationStateUtils.pop(state.asMutable({ deep: true })) | |
return Immutable(newState) | |
} | |
const navJumpToKey = (state, { key }) => { | |
const newState = NavigationStateUtils.jumpTo(state.asMutable({ deep: true }), key) | |
return Immutable(newState) | |
} | |
const navJumpToIndex = (state, { index }) => { | |
const newState = NavigationStateUtils.jumpTo(state.asMutable({ deep: true }), index) | |
return Immutable(newState) | |
} | |
const navReset = (state, { index, children }) => { | |
// SAD SAD SAD :( NOT WORKING AS INTENDED | |
// const emptyState = R.clone(INITIAL_STATE) | |
// emptyState.children = children | |
// return Immutable(NavigationStateUtils.set(null, (parseInt(state.key) + 1).toString(), children, 0)) | |
// return Immutable(NavigationStateUtils.set(null, 'MainNavigation', children, 0)) | |
// const newState = ({ ...state, index, children }) | |
// console.log(newState) | |
// return newState | |
} | |
const setDrawerOpen = (state, { isDrawerOpen }) => | |
state.merge({ isDrawerOpen }) | |
const ACTION_HANDLERS = { | |
[Types.NAV_PUSH]: navPush, | |
[Types.NAV_POP]: navPop, | |
[Types.NAV_JUMP_TO_KEY]: navJumpToKey, | |
[Types.NAV_JUMP_TO_INDEX]: navJumpToIndex, | |
[Types.NAV_RESET]: navReset, | |
[Types.SET_DRAWER_OPEN]: setDrawerOpen | |
} | |
export default createReducer(INITIAL_STATE, ACTION_HANDLERS) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Any work around for the sad, sad, sad state of reset?