Skip to content

Commit

Permalink
Add navigation screen stubs
Browse files Browse the repository at this point in the history
While this relies heavily on native-navigation, I did end up having to bring
in a cross-platform JS-based TabBar library because the TabBar implementation
in native-navigation does not seem to be fully fleshed out (works via custom
swift code)

With just a small bit of wrangling in the HomeScreen's implementation of
TabViewAnimated, I was able to achieve something that looks good.

That said, there is a bug (or some confusion) when returning state from
`Navigation.present` from `Navigation.dismiss` which is tracked at
airbnb/native-navigation#142
  • Loading branch information
dlindahl committed Aug 30, 2017
1 parent f350622 commit e81df4e
Show file tree
Hide file tree
Showing 13 changed files with 443 additions and 4 deletions.
42 changes: 38 additions & 4 deletions sloppymoose-react-native/index.ios.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,38 @@
import { AppRegistry } from 'react-native'
import App from './App'
import appConfig from './app.json'
AppRegistry.registerComponent(appConfig.name, () => App)
import {
ACTIVITY,
BADGES,
CHECK_IN,
// CHECK_IN_OK,
FORGOT_PASS,
HOME,
// SIGN_IN,
SIGN_UP,
SPLASH
} from './src/routes'
import { Navigation } from 'react-native-navigation'

import ActivityScreen from './src/screens/ActivityScreen'
import BadgesScreen from './src/screens/BadgesScreen'
import CheckInScreen from './src/screens/CheckInScreen'
import ForgotPasswordScreen from './src/screens/ForgotPasswordScreen'
import HomeScreen from './src/screens/HomeScreen'
import SignUpScreen from './src/screens/SignUpScreen'
import SplashScreen from './src/screens/SplashScreen'

Navigation.registerComponent(ACTIVITY, () => ActivityScreen)
Navigation.registerComponent(BADGES, () => BadgesScreen)
Navigation.registerComponent(CHECK_IN, () => CheckInScreen)
Navigation.registerComponent(FORGOT_PASS, () => ForgotPasswordScreen)
Navigation.registerComponent(HOME, () => HomeScreen)
Navigation.registerComponent(SIGN_UP, () => SignUpScreen)
Navigation.registerComponent(SPLASH, () => SplashScreen)

Navigation.startSingleScreenApp({
screen: {
navigatorStyle: {
navBarHidden: true,
statusBarTextColorScheme: 'light'
},
screen: SPLASH
}
})
1 change: 1 addition & 0 deletions sloppymoose-react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"preset": "jest-expo"
},
"dependencies": {
"prop-types": "^15.5.10",
"react": "16.0.0-alpha.12",
"react-native": "^0.47.0",
"react-native-navigation": "^1.1.206"
Expand Down
47 changes: 47 additions & 0 deletions sloppymoose-react-native/src/components/Screen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// import Navigator from 'native-navigation'
import React from 'react'
import { string, node } from 'prop-types'
import { StyleSheet, View } from 'react-native'

const THEMES = {
default: {
// TODO
// backgroundColor: undefined,
// titleColor: undefined
},
primary: {
// TODO
// backgroundColor: PRIMARY_COLOR,
// statusBarStyle: 'light',
// titleColor: SECONDARY_COLOR
},
secondary: {
// TODO
// alpha: 1,
// backgroundColor: SECONDARY_COLOR,
// statusBarStyle: 'light',
// titleColor: WHITE
}
}

const Screen = ({ children, theme = 'default', ...props }) =>
// <Navigator.Config {...THEMES[theme]} {...props}>
<View style={styles.container}>
{children}
</View>
// </Navigator.Config>

Screen.propTypes = {
children: node,
theme: string
}

const styles = StyleSheet.create({
container: {
alignItems: 'center',
flex: 1,
justifyContent: 'center'
}
})

export default Screen
9 changes: 9 additions & 0 deletions sloppymoose-react-native/src/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const ACTIVITY = 'SM/Activity'
export const BADGES = 'SM/Badges'
export const CHECK_IN = 'SM/CheckIn'
export const CHECK_IN_OK = 'SM/CheckInOk'
export const FORGOT_PASS = 'SM/ForgotPassword'
export const HOME = 'SM/Home'
export const SIGN_IN = 'SM/SignIn'
export const SIGN_UP = 'SM/SignUp'
export const SPLASH = 'SM/Splash'
23 changes: 23 additions & 0 deletions sloppymoose-react-native/src/screens/ActivityScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react'
import Screen from '../components/Screen'
import { StyleSheet, Text } from 'react-native'

export default class ActivityScreen extends React.Component {
componentWillMount () {
console.info('ActivityScreen#componentWillMount')
}
componentWillUnmount () {
console.info('ActivityScreen#componentWillUnmount')
}
render () {
return (
<Screen>
<Text style={styles.text}>ACTIVITIES</Text>
</Screen>
)
}
}

const styles = StyleSheet.create({
text: {}
})
17 changes: 17 additions & 0 deletions sloppymoose-react-native/src/screens/BadgesScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react'
import Screen from '../components/Screen'
import { StyleSheet, Text } from 'react-native'

export default class BadgesScreen extends React.Component {
render () {
return (
<Screen>
<Text style={styles.text}>BADGES</Text>
</Screen>
)
}
}

const styles = StyleSheet.create({
text: {}
})
55 changes: 55 additions & 0 deletions sloppymoose-react-native/src/screens/CheckInScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Button, StyleSheet, Text } from 'react-native'
// import Navigator from 'native-navigation'
import React from 'react'
import Screen from '../components/Screen'

const CANCEL = {
systemItem: 'cancel',
title: 'Cancel'
}

export default class CheckInScreen extends React.Component {
componentWillMount () {
this.props.navigator.setOnNavigatorEvent(e => {
if (e.id === 'bottomTabSelected') {
this.props.navigator.showModal({
screen: 'SM/ForgotPassword',
title: 'Modal'
})
this.props.navigator.switchToTab({
tabIndex: 0
})
}
})
}
// handleCancel () {
// // Navigator.dismiss()
// }
// handleBadCheckIn () {
// alert('NOPE. Try again')
// }
// handleGoodCheckIn () {
// // Navigator.dismiss()
// }
render () {
return null
}
// render () {
// return (
// <Screen
// leftButtons={[CANCEL]}
// onLeftPress={this.handleCancel}
// title="Check In"
// >
// <Text style={styles.text}>CHECK IN</Text>
// <Button onPress={this.handleGoodCheckIn} title="Successful CheckIn" />
// <Button onPress={this.handleBadCheckIn} title="Bad CheckIn" />
// <Button onPress={this.handleCancel} title="Cancel" />
// </Screen>
// )
// }
}

const styles = StyleSheet.create({
text: {}
})
22 changes: 22 additions & 0 deletions sloppymoose-react-native/src/screens/CheckInSuccessScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Button, StyleSheet, Text } from 'react-native'
// import Navigator from 'native-navigation'
import React from 'react'
import Screen from '../components/Screen'

export default class CheckInSuccessScreen extends React.Component {
handleDismiss () {
// Navigator.dismiss()
}
render () {
return (
<Screen hidden>
<Text style={styles.text}>YOU GOT IT</Text>
<Button onPress={this.handleDismiss} title="Dismiss" />
</Screen>
)
}
}

const styles = StyleSheet.create({
text: {}
})
21 changes: 21 additions & 0 deletions sloppymoose-react-native/src/screens/ForgotPasswordScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import Screen from '../components/Screen'
import { Button, StyleSheet, Text } from 'react-native'

export default class ForgotPasswordScreen extends React.Component {
handleDismiss = () => {
this.props.navigator.dismissModal()
}
render () {
return (
<Screen title="Forgot Password">
<Text style={styles.text}>Coming Soon!</Text>
<Button onPress={this.handleDismiss} title="Successful CheckIn" />
</Screen>
)
}
}

const styles = StyleSheet.create({
text: {}
})
69 changes: 69 additions & 0 deletions sloppymoose-react-native/src/screens/HomeScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import ActivityScreen from './ActivityScreen'
import { CHECK_IN, CHECK_IN_OK, HOME } from '../routes'
import BadgesScreen from './BadgesScreen'
// import Navigator from 'native-navigation'
import React, { PureComponent } from 'react'
import { StyleSheet } from 'react-native'
import { TabViewAnimated, TabBar } from 'react-native-tab-view'

const ROUTES = [
{ key: '1', title: 'Activity' },
{ key: '2', title: 'Check-In' },
{ key: '3', title: 'Badges' }
]

function handleCheckInSuccess (success) {
console.info('handleCheckInSuccess', success)
if (success) {
// Navigator.present(CHECK_IN_OK)
}
}

function showCheckIn () {
// return Navigator.present(CHECK_IN).then(handleCheckInSuccess)
}

export default class HomeScreen extends PureComponent {
state = {
currentRoute: ROUTES[0],
index: 0,
routes: ROUTES
}
handleIndexChange = index => {
if (index === 1) {
return showCheckIn()
}
const currentRoute = this.state.routes[index]
this.setState({ currentRoute, index })
}
renderFooter = props => <TabBar {...props} />
renderScene = ({ route }) => {
switch (route.key) {
case '1':
return <ActivityScreen />
case '3':
return <BadgesScreen />
default:
return null
}
}
render () {
return (
// <Navigator.Config title={this.state.currentRoute.title}>
<TabViewAnimated
style={styles.container}
navigationState={this.state}
renderScene={this.renderScene}
renderFooter={this.renderFooter}
onIndexChange={this.handleIndexChange}
/>
// </Navigator.Config>
)
}
}

const styles = StyleSheet.create({
container: {
flex: 1
}
})
39 changes: 39 additions & 0 deletions sloppymoose-react-native/src/screens/SignInScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Button, StyleSheet, Text } from 'react-native'
import { FORGOT_PASS, SIGN_UP } from '../routes'
// import Navigator from 'native-navigation'
import React from 'react'
import Screen from '../components/Screen'

export default class SignInScreen extends React.Component {
handleBadSignIn = () => {
alert('NOPE, TRY AGAIN')
}
handleForgotPassword = () => {
// Navigator.push(FORGOT_PASS)
}
handleGoodSignIn = () => {
// TODO: Need to change state so that SignInScreen (or whatever) knows that
// signing up was successful
// Navigator.dismiss()
}
handleGoToSignUp = () => {
// Navigator.push(SIGN_UP)
}
render () {
return (
<Screen theme="secondary" title="Sign In">
<Text style={styles.text}>Sign In Screen</Text>
<Button onPress={this.handleGoodSignIn} title="Sign In OK" />
<Button onPress={this.handleBadSignIn} title="Sign In Bad" />
<Button onPress={this.handleGoToSignUp} title="Sign Up" />
<Button onPress={this.handleForgotPassword} title="Forgot Password" />
</Screen>
)
}
}

const styles = StyleSheet.create({
text: {
color: WHITE
}
})
Loading

0 comments on commit e81df4e

Please sign in to comment.