From e4eaa0b7964bc5da29275f1f21417519dcd5c526 Mon Sep 17 00:00:00 2001 From: Gant Laborde Date: Wed, 22 Mar 2017 09:53:11 -0500 Subject: [PATCH 1/5] attempt at moving to new nav --- boilerplate/App/Containers/RootContainer.js | 4 +- boilerplate/App/Navigation/AppNavigation.js | 26 +++++ boilerplate/App/Navigation/CustomNavBar.js | 110 ------------------ boilerplate/App/Navigation/NavItems.js | 52 --------- .../App/Navigation/NavigationDrawer.js | 53 --------- .../App/Navigation/NavigationRouter.js | 27 ----- .../Navigation/Styles/CustomNavBarStyles.js | 41 ------- .../App/Navigation/Styles/NavItemsStyles.js | 21 ---- .../Styles/NavigationContainerStyles.js | 19 --- .../Styles/NavigationDrawerStyles.js | 10 -- .../App/Navigation/Styles/NavigationStyles.js | 8 ++ boilerplate/App/Redux/OpenScreenRedux.js | 10 -- boilerplate/App/Sagas/OpenScreenSagas.js | 11 -- boilerplate/App/Sagas/index.js | 3 - boilerplate/package.json.ejs | 2 +- package.json | 4 +- 16 files changed, 39 insertions(+), 362 deletions(-) create mode 100644 boilerplate/App/Navigation/AppNavigation.js delete mode 100644 boilerplate/App/Navigation/CustomNavBar.js delete mode 100644 boilerplate/App/Navigation/NavItems.js delete mode 100644 boilerplate/App/Navigation/NavigationDrawer.js delete mode 100644 boilerplate/App/Navigation/NavigationRouter.js delete mode 100644 boilerplate/App/Navigation/Styles/CustomNavBarStyles.js delete mode 100644 boilerplate/App/Navigation/Styles/NavItemsStyles.js delete mode 100644 boilerplate/App/Navigation/Styles/NavigationContainerStyles.js delete mode 100644 boilerplate/App/Navigation/Styles/NavigationDrawerStyles.js create mode 100644 boilerplate/App/Navigation/Styles/NavigationStyles.js delete mode 100644 boilerplate/App/Redux/OpenScreenRedux.js delete mode 100644 boilerplate/App/Sagas/OpenScreenSagas.js diff --git a/boilerplate/App/Containers/RootContainer.js b/boilerplate/App/Containers/RootContainer.js index 3e46e04..bcf679c 100644 --- a/boilerplate/App/Containers/RootContainer.js +++ b/boilerplate/App/Containers/RootContainer.js @@ -1,6 +1,6 @@ import React, { Component } from 'react' import { View, StatusBar } from 'react-native' -import NavigationRouter from '../Navigation/NavigationRouter' +import Navigation from '../Navigation/AppNavigation' import { connect } from 'react-redux' import StartupActions from '../Redux/StartupRedux' import ReduxPersist from '../Config/ReduxPersist' @@ -21,7 +21,7 @@ class RootContainer extends Component { return ( - + ) } diff --git a/boilerplate/App/Navigation/AppNavigation.js b/boilerplate/App/Navigation/AppNavigation.js new file mode 100644 index 0000000..a9d1e0e --- /dev/null +++ b/boilerplate/App/Navigation/AppNavigation.js @@ -0,0 +1,26 @@ +import { StackNavigator } from 'react-navigation' + +import LaunchScreen from '../Containers/LaunchScreen' +import LoginScreen from '../Containers/LoginScreen' + +import styles from './Styles/NavigationStyles' + +const PrimaryNav = StackNavigator({ + // Manifest of possible screens + LaunchScreen: { screen: LaunchScreen }, + LoginScreen: { + screen: LoginScreen, + navigationOptions: { title: 'Login' } + } +}, { + // Default config for all screens + headerMode: 'none', + initialRouteName: 'LaunchScreen', + navigationOptions: { + header: { + style: styles.header + } + } +}) + +export default PrimaryNav diff --git a/boilerplate/App/Navigation/CustomNavBar.js b/boilerplate/App/Navigation/CustomNavBar.js deleted file mode 100644 index 9659e8d..0000000 --- a/boilerplate/App/Navigation/CustomNavBar.js +++ /dev/null @@ -1,110 +0,0 @@ -import React, { PropTypes } from 'react' -import { View, Image, LayoutAnimation } from 'react-native' -import NavItems from './NavItems' -import styles from './Styles/CustomNavBarStyles' -import SearchBar from '../Components/SearchBar' -import { connect } from 'react-redux' -import { Metrics, Images } from '../Themes' -import SearchActions from '../Redux/SearchRedux' - -class CustomNavBar extends React.Component { - - constructor (props) { - super(props) - this.state = { - showSearchBar: false - } - } - - showSearchBar = () => { - this.setState({showSearchBar: true}) - } - - cancelSearch = () => { - this.setState({showSearchBar: false}) - this.props.cancelSearch() - } - - onSearch = (searchTerm) => { - this.props.performSearch(searchTerm) - } - - renderMiddle () { - LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) - if (this.state.showSearchBar) { - return - } else { - return ( - - ) - } - } - - renderRightButtons () { - if (this.state.showSearchBar) { - return - } else { - return ( - - {NavItems.searchButton(this.showSearchBar)} - - ) - } - } - - renderLeftButtons () { - if (this.state.showSearchBar) { - return null - } else { - return ( - - {NavItems.backButton()} - - ) - } - } - - render () { - let state = this.props.navigationState - let selected = state.children[state.index] - while (selected.hasOwnProperty('children')) { - state = selected - selected = selected.children[selected.index] - } - - const containerStyle = [ - styles.container, - this.props.navigationBarStyle, - state.navigationBarStyle, - selected.navigationBarStyle - ] - - return ( - - {this.renderLeftButtons()} - {this.renderMiddle()} - {this.renderRightButtons()} - - ) - } -} - -CustomNavBar.propTypes = { - navigationState: PropTypes.object, - navigationBarStyle: View.propTypes.style -} - -const mapStateToProps = (state) => { - return { - searchTerm: state.search.searchTerm - } -} - -const mapDispatchToProps = (dispatch) => { - return { - performSearch: (searchTerm) => dispatch(SearchActions.search(searchTerm)), - cancelSearch: () => dispatch(SearchActions.cancelSearch()) - } -} - -export default connect(mapStateToProps, mapDispatchToProps)(CustomNavBar) diff --git a/boilerplate/App/Navigation/NavItems.js b/boilerplate/App/Navigation/NavItems.js deleted file mode 100644 index dcfbfb4..0000000 --- a/boilerplate/App/Navigation/NavItems.js +++ /dev/null @@ -1,52 +0,0 @@ -import React from 'react' -import { TouchableOpacity } from 'react-native' -import styles from './Styles/NavItemsStyles' -import { Actions as NavigationActions } from 'react-native-router-flux' -import Icon from 'react-native-vector-icons/FontAwesome' -import { Colors, Metrics } from '../Themes' - -const openDrawer = () => { - NavigationActions.refresh({ - key: 'drawer', - open: true - }) -} - -export default { - backButton () { - return ( - - - - ) - }, - - hamburgerButton () { - return ( - - - - ) - }, - - searchButton (callback) { - return ( - - - - ) - } - -} diff --git a/boilerplate/App/Navigation/NavigationDrawer.js b/boilerplate/App/Navigation/NavigationDrawer.js deleted file mode 100644 index f2233f8..0000000 --- a/boilerplate/App/Navigation/NavigationDrawer.js +++ /dev/null @@ -1,53 +0,0 @@ -import React, { PropTypes, Component } from 'react' -import Drawer from 'react-native-drawer' -import { DefaultRenderer, Actions as NavigationActions } from 'react-native-router-flux' -import DrawerContent from '../Containers/DrawerContent' -import { connect } from 'react-redux' -import Styles from './Styles/NavigationDrawerStyles' - -/* ******************* -* Documentation: https://github.com/root-two/react-native-drawer -********************/ - -class NavigationDrawer extends Component { - render () { - const state = this.props.navigationState - const children = state.children - return ( - NavigationActions.refresh({key: state.key, open: true})} - onClose={() => NavigationActions.refresh({key: state.key, open: false})} - content={} - styles={Styles} - tapToClose - openDrawerOffset={0.2} - panCloseMask={0.2} - negotiatePan - tweenHandler={(ratio) => ({ - main: { opacity: Math.max(0.54, 1 - ratio) } - })} - > - - - ) - } -} - -NavigationDrawer.propTypes = { - navigationState: PropTypes.object -} - -const mapStateToProps = (state) => { - return { - } -} - -const mapDispatchToProps = (dispatch) => { - return { - } -} - -export default connect(mapStateToProps, mapDispatchToProps)(NavigationDrawer) diff --git a/boilerplate/App/Navigation/NavigationRouter.js b/boilerplate/App/Navigation/NavigationRouter.js deleted file mode 100644 index c8cec83..0000000 --- a/boilerplate/App/Navigation/NavigationRouter.js +++ /dev/null @@ -1,27 +0,0 @@ -import React, { Component } from 'react' -import { Scene, Router } from 'react-native-router-flux' -import Styles from './Styles/NavigationContainerStyles' -import NavigationDrawer from './NavigationDrawer' - -// screens identified by the router -import LaunchScreen from '../Containers/LaunchScreen' - -/* ************************** -* Documentation: https://github.com/aksonov/react-native-router-flux -***************************/ - -class NavigationRouter extends Component { - render () { - return ( - - - - - - - - ) - } -} - -export default NavigationRouter diff --git a/boilerplate/App/Navigation/Styles/CustomNavBarStyles.js b/boilerplate/App/Navigation/Styles/CustomNavBarStyles.js deleted file mode 100644 index f1c9908..0000000 --- a/boilerplate/App/Navigation/Styles/CustomNavBarStyles.js +++ /dev/null @@ -1,41 +0,0 @@ -import { Colors, Metrics, Fonts } from '../../Themes/' - -export default { - container: { - position: 'absolute', - top: 0, - left: 0, - right: 0, - height: Metrics.navBarHeight, - paddingTop: Metrics.smallMargin, - paddingHorizontal: 5, - backgroundColor: Colors.background, - flexDirection: 'row', - justifyContent: 'space-between' - }, - title: { - flex: 1, - textAlign: 'center', - color: Colors.snow, - marginTop: Metrics.doubleBaseMargin, - backgroundColor: Colors.transparent, - fontWeight: 'bold', - fontSize: Fonts.size.input - }, - logo: { - alignSelf: 'center', - marginTop: Metrics.baseMargin, - height: Metrics.icons.large, - width: Metrics.icons.large - }, - rightButtons: { - flex: 1, - justifyContent: 'flex-end', - flexDirection: 'row' - }, - leftButtons: { - flex: 1, - justifyContent: 'flex-start', - flexDirection: 'row' - } -} diff --git a/boilerplate/App/Navigation/Styles/NavItemsStyles.js b/boilerplate/App/Navigation/Styles/NavItemsStyles.js deleted file mode 100644 index 4fed01c..0000000 --- a/boilerplate/App/Navigation/Styles/NavItemsStyles.js +++ /dev/null @@ -1,21 +0,0 @@ -import {StyleSheet} from 'react-native' -import { Metrics, Colors } from '../../Themes/' - -const navButton = { - backgroundColor: Colors.transparent, - justifyContent: 'center' -} - -export default StyleSheet.create({ - backButton: { - ...navButton, - marginTop: Metrics.baseMargin, - marginLeft: Metrics.baseMargin - }, - searchButton: { - ...navButton, - marginTop: Metrics.section, - marginRight: Metrics.baseMargin, - alignItems: 'center' - } -}) diff --git a/boilerplate/App/Navigation/Styles/NavigationContainerStyles.js b/boilerplate/App/Navigation/Styles/NavigationContainerStyles.js deleted file mode 100644 index ed6da73..0000000 --- a/boilerplate/App/Navigation/Styles/NavigationContainerStyles.js +++ /dev/null @@ -1,19 +0,0 @@ -import {Colors} from '../../Themes/' - -export default { - container: { - flex: 1 - }, - navBar: { - backgroundColor: Colors.background - }, - title: { - color: Colors.snow - }, - leftButton: { - tintColor: Colors.snow - }, - rightButton: { - color: Colors.snow - } -} diff --git a/boilerplate/App/Navigation/Styles/NavigationDrawerStyles.js b/boilerplate/App/Navigation/Styles/NavigationDrawerStyles.js deleted file mode 100644 index 4f3db11..0000000 --- a/boilerplate/App/Navigation/Styles/NavigationDrawerStyles.js +++ /dev/null @@ -1,10 +0,0 @@ -import {Colors} from '../../Themes/' - -export default { - drawer: { - backgroundColor: Colors.background - }, - main: { - backgroundColor: Colors.clear - } -} diff --git a/boilerplate/App/Navigation/Styles/NavigationStyles.js b/boilerplate/App/Navigation/Styles/NavigationStyles.js new file mode 100644 index 0000000..e338485 --- /dev/null +++ b/boilerplate/App/Navigation/Styles/NavigationStyles.js @@ -0,0 +1,8 @@ +import { StyleSheet } from 'react-native' +import { Colors } from '../../Themes/' + +export default StyleSheet.create({ + header: { + backgroundColor: Colors.backgroundColor + } +}) diff --git a/boilerplate/App/Redux/OpenScreenRedux.js b/boilerplate/App/Redux/OpenScreenRedux.js deleted file mode 100644 index 67d1c1a..0000000 --- a/boilerplate/App/Redux/OpenScreenRedux.js +++ /dev/null @@ -1,10 +0,0 @@ -import { createActions } from 'reduxsauce' - -/* ------------- Types and Action Creators ------------- */ - -const { Types, Creators } = createActions({ - openScreen: ['screen', 'options'] -}) - -export const OpenScreenTypes = Types -export default Creators diff --git a/boilerplate/App/Sagas/OpenScreenSagas.js b/boilerplate/App/Sagas/OpenScreenSagas.js deleted file mode 100644 index 168f2c6..0000000 --- a/boilerplate/App/Sagas/OpenScreenSagas.js +++ /dev/null @@ -1,11 +0,0 @@ -import { call } from 'redux-saga/effects' -import { Actions as NavigationActions, ActionConst } from 'react-native-router-flux' - -// Process OPEN_SCREEN actions -export function * openScreen (action) { - const {screen, options = {}} = action - // Always reset the nav stack when opening a screen by default - // You can override the RESET type in the options passed to the OPEN_SCREEN dispatch - const mergedOptions = {type: ActionConst.RESET, ...options} - yield call(NavigationActions[screen], mergedOptions) -} diff --git a/boilerplate/App/Sagas/index.js b/boilerplate/App/Sagas/index.js index 8613af5..563f28e 100644 --- a/boilerplate/App/Sagas/index.js +++ b/boilerplate/App/Sagas/index.js @@ -8,14 +8,12 @@ import DebugConfig from '../Config/DebugConfig' import { StartupTypes } from '../Redux/StartupRedux' import { GithubTypes } from '../Redux/GithubRedux' import { LoginTypes } from '../Redux/LoginRedux' -import { OpenScreenTypes } from '../Redux/OpenScreenRedux' /* ------------- Sagas ------------- */ import { startup } from './StartupSagas' import { login } from './LoginSagas' import { getUserAvatar } from './GithubSagas' -import { openScreen } from './OpenScreenSagas' /* ------------- API ------------- */ @@ -30,7 +28,6 @@ export default function * root () { // some sagas only receive an action takeLatest(StartupTypes.STARTUP, startup), takeLatest(LoginTypes.LOGIN_REQUEST, login), - takeLatest(OpenScreenTypes.OPEN_SCREEN, openScreen), // some sagas receive extra parameters in addition to an action takeLatest(GithubTypes.USER_REQUEST, getUserAvatar, api) diff --git a/boilerplate/package.json.ejs b/boilerplate/package.json.ejs index 6b286f7..975d721 100644 --- a/boilerplate/package.json.ejs +++ b/boilerplate/package.json.ejs @@ -29,7 +29,7 @@ "react-native-config": "^0.2.1", "react-native-device-info": "^0.10.0", "react-native-drawer": "^2.3.0", - "react-native-router-flux": "^3.37.0", + "react-navigation": "^1.0.0-beta.7", "react-redux": "^5.0.2", "redux": "^3.6.0", "redux-persist": "^4.1.0", diff --git a/package.json b/package.json index 4b08edd..ce6f6ab 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { - "name": "ignite-ir-boilerplate-2016", + "name": "ignite-ir-next", "description": "Infinite Red's recommended app structure 2016", "license": "MIT", "repository": "infinitered/ignite", "homepage": "https://github.com/infinitered/ignite", - "version": "0.2.1", + "version": "0.0.2", "files": [ "boilerplate", "commands", From 0836e818786b06d047797e5863c95d80133614ab Mon Sep 17 00:00:00 2001 From: Gant Laborde Date: Wed, 22 Mar 2017 11:56:19 -0500 Subject: [PATCH 2/5] screen generator is using new nav --- commands/screen.js | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/commands/screen.js b/commands/screen.js index c34ded9..44167da 100644 --- a/commands/screen.js +++ b/commands/screen.js @@ -2,8 +2,9 @@ module.exports = async function (context) { // grab some features - const { parameters, print, strings, ignite } = context + const { parameters, print, strings, ignite, filesystem, patching } = context const { pascalCase, isBlank } = strings + const config = ignite.loadIgniteConfig() // validation if (isBlank(parameters.first)) { @@ -28,4 +29,34 @@ module.exports = async function (context) { // make the templates await ignite.copyBatch(context, jobs, props) + + // if using `react-navigation` go the extra step + // and insert the screen into the nav router + if (config.navigation === 'react-navigation') { + const screenName = `${name}Screen` + const appNavFilePath = `${process.cwd()}/App/Navigation/AppNavigation.js` + const importToAdd = `import ${screenName} from '../Containers/${screenName}'` + const routeToAdd = ` ${screenName}: { screen: ${screenName} },` + + if (!filesystem.exists(appNavFilePath)) { + const msg = `No '${appNavFilePath}' file found. Can't insert screen.` + print.error(msg) + process.exit(1) + } + + // insert screen import + ignite.patchInFile(appNavFilePath, { + after: 'import { StackNavigator } from', + insert: importToAdd + }) + + // insert screen route + ignite.patchInFile(appNavFilePath, { + after: 'const PrimaryNav', + insert: routeToAdd + }) + + } else { + print.log('Screen created, manually add it to your navigation') + } } From 7a7fa5c3497ea27a15cd01be6e3b29dd5316b226 Mon Sep 17 00:00:00 2001 From: Gant Laborde Date: Wed, 22 Mar 2017 11:56:32 -0500 Subject: [PATCH 3/5] existing boilerplate using new nav --- boilerplate/App/Containers/LoginScreen.js | 5 ++--- boilerplate/App/Navigation/AppNavigation.js | 3 +-- boilerplate/ignite.json.ejs | 3 ++- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/boilerplate/App/Containers/LoginScreen.js b/boilerplate/App/Containers/LoginScreen.js index 4f57094..2baabb9 100644 --- a/boilerplate/App/Containers/LoginScreen.js +++ b/boilerplate/App/Containers/LoginScreen.js @@ -13,7 +13,6 @@ import { connect } from 'react-redux' import Styles from './Styles/LoginScreenStyles' import {Images, Metrics} from '../Themes' import LoginActions from '../Redux/LoginRedux' -import { Actions as NavigationActions } from 'react-native-router-flux' class LoginScreen extends React.Component { @@ -42,7 +41,7 @@ class LoginScreen extends React.Component { this.forceUpdate() // Did the login attempt complete? if (this.isAttempting && !newProps.fetching) { - NavigationActions.pop() + this.props.navigation.goBack() } } @@ -142,7 +141,7 @@ class LoginScreen extends React.Component { Sign In - + this.props.navigation.goBack()}> Cancel diff --git a/boilerplate/App/Navigation/AppNavigation.js b/boilerplate/App/Navigation/AppNavigation.js index a9d1e0e..db6da2a 100644 --- a/boilerplate/App/Navigation/AppNavigation.js +++ b/boilerplate/App/Navigation/AppNavigation.js @@ -1,12 +1,11 @@ import { StackNavigator } from 'react-navigation' - import LaunchScreen from '../Containers/LaunchScreen' import LoginScreen from '../Containers/LoginScreen' import styles from './Styles/NavigationStyles' +// Manifest of possible screens const PrimaryNav = StackNavigator({ - // Manifest of possible screens LaunchScreen: { screen: LaunchScreen }, LoginScreen: { screen: LoginScreen, diff --git a/boilerplate/ignite.json.ejs b/boilerplate/ignite.json.ejs index 5212c2c..faa3f48 100644 --- a/boilerplate/ignite.json.ejs +++ b/boilerplate/ignite.json.ejs @@ -1,4 +1,5 @@ { "createdWith": "<%= props.igniteVersion %>", - "examples": "classic" + "examples": "classic", + "navigation": "react-navigation" } From b2bfbf98d25b03c255224a523a6e871840917f58 Mon Sep 17 00:00:00 2001 From: Gant Laborde Date: Wed, 22 Mar 2017 12:08:47 -0500 Subject: [PATCH 4/5] add feature to container --- commands/container.js | 33 ++++++++++++++++++++++++++++++++- commands/screen.js | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/commands/container.js b/commands/container.js index 4ea8e73..9f422ae 100644 --- a/commands/container.js +++ b/commands/container.js @@ -2,8 +2,9 @@ module.exports = async function (context) { // grab some features - const { parameters, strings, print, ignite } = context + const { parameters, strings, print, ignite, filesystem } = context const { pascalCase, isBlank } = strings + const config = ignite.loadIgniteConfig() // validation if (isBlank(parameters.first)) { @@ -27,4 +28,34 @@ module.exports = async function (context) { ] await ignite.copyBatch(context, jobs, props) + + // if using `react-navigation` go the extra step + // and insert the container into the nav router + if (config.navigation === 'react-navigation') { + const containerName = name + const appNavFilePath = `${process.cwd()}/App/Navigation/AppNavigation.js` + const importToAdd = `import ${containerName} from '../Containers/${containerName}'` + const routeToAdd = ` ${containerName}: { screen: ${containerName} },` + + if (!filesystem.exists(appNavFilePath)) { + const msg = `No '${appNavFilePath}' file found. Can't insert container.` + print.error(msg) + process.exit(1) + } + + // insert container import + ignite.patchInFile(appNavFilePath, { + after: 'import { StackNavigator } from', + insert: importToAdd + }) + + // insert container route + ignite.patchInFile(appNavFilePath, { + after: 'const PrimaryNav', + insert: routeToAdd + }) + + } else { + print.log('Container created, manually add it to your navigation') + } } diff --git a/commands/screen.js b/commands/screen.js index 44167da..ed9756c 100644 --- a/commands/screen.js +++ b/commands/screen.js @@ -2,7 +2,7 @@ module.exports = async function (context) { // grab some features - const { parameters, print, strings, ignite, filesystem, patching } = context + const { parameters, print, strings, ignite, filesystem } = context const { pascalCase, isBlank } = strings const config = ignite.loadIgniteConfig() From e323764fb74c71713d4e114a900f308c061e47a5 Mon Sep 17 00:00:00 2001 From: Gant Laborde Date: Wed, 22 Mar 2017 12:10:47 -0500 Subject: [PATCH 5/5] linting fixes --- commands/container.js | 1 - commands/screen.js | 1 - 2 files changed, 2 deletions(-) diff --git a/commands/container.js b/commands/container.js index 9f422ae..992d3f3 100644 --- a/commands/container.js +++ b/commands/container.js @@ -54,7 +54,6 @@ module.exports = async function (context) { after: 'const PrimaryNav', insert: routeToAdd }) - } else { print.log('Container created, manually add it to your navigation') } diff --git a/commands/screen.js b/commands/screen.js index ed9756c..c8e5165 100644 --- a/commands/screen.js +++ b/commands/screen.js @@ -55,7 +55,6 @@ module.exports = async function (context) { after: 'const PrimaryNav', insert: routeToAdd }) - } else { print.log('Screen created, manually add it to your navigation') }