Created
May 10, 2018 02:17
-
-
Save machadogj/e266fdc36076492e78f0ad5516848938 to your computer and use it in GitHub Desktop.
State based navigation PoC
This file contains hidden or 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 { View } from 'react-native'; | |
import { | |
Container, | |
Title, | |
Message, | |
Button | |
} from '../components'; | |
import { connect } from 'react-redux'; | |
import { actions as mainActions} from '../store/models/main'; | |
import { selectors as mainSelectors } from '../store/models/main'; | |
const { addCigarette } = mainActions; | |
class Home extends Component { | |
static propTypes = { | |
cardToken: PropTypes.string, | |
dailyCigarettes: PropTypes.number.isRequired, | |
todaysCigarettes: PropTypes.number.isRequired, | |
onAdd: PropTypes.func.isRequired | |
}; | |
constructor(props) { | |
super(props); | |
this.state = { | |
}; | |
} | |
handleSubmit = () => { | |
let { dailyCigarettes, todaysCigarettes, cardToken } = this.props; | |
let availableCigarettes = dailyCigarettes - todaysCigarettes; | |
this.props.onAdd(availableCigarettes, cardToken); | |
} | |
handleAddCreditCard = () => { | |
this.props.navigator.push({key: 'credit-card'}); | |
} | |
render() { | |
let { dailyCigarettes, todaysCigarettes, cardToken } = this.props; | |
let availableCigarettes = dailyCigarettes - todaysCigarettes; | |
let nextCigaretteCost = availableCigarettes > 0 ? 0 : Math.pow(2, Math.abs(availableCigarettes)); | |
return ( | |
<Container> | |
<View style={ {flex: 1} }> | |
<Title text={ 'Stay strong!' }/> | |
<Message | |
text={ `Daily Cigarettes: ${this.props.dailyCigarettes}` } | |
/> | |
<Message | |
text={ `Today's Cigarettes: ${this.props.todaysCigarettes}` } | |
/> | |
<Message | |
text={ `Available Cigarettes: ${this.props.dailyCigarettes - this.props.todaysCigarettes}` } | |
/> | |
<Message | |
text={ `Your next cigarette will cost you!` } | |
/> | |
{ !nextCigaretteCost ? null : ( | |
<Message | |
style={ {color: 'red'} } | |
text={ `When you tap on the button below, you will be charged USD${nextCigaretteCost}.00 to your credit card. So think twice before you smoke that next cigarette!` } | |
/> | |
)} | |
</View> | |
<Message | |
text="Every time you smoke a cigarette, tap on the button below!" | |
/> | |
{ | |
nextCigaretteCost > 1 && !cardToken ? | |
<Button text="Add Credit Card" onPress={ this.handleAddCreditCard }/> | |
: | |
<Button text="Add Cigarette!" onPress={ this.handleSubmit }/> | |
} | |
</Container> | |
); | |
} | |
} | |
export default connect( | |
(state) => ({ | |
dailyCigarettes: state.get('config').toJS().dailyCigarettes, | |
todaysCigarettes: mainSelectors.todaysCigarettes(state), | |
cardToken: state.get('config').toJS().cardToken | |
}), //eslint-disable-line | |
(dispatch, props) => ({ | |
onAdd: (/*availableCigarettes, cardToken*/) => { | |
// let { navigator } = props; | |
// let needToCharge = availableCigarettes <= 0; | |
// console.log(availableCigarettes, needToCharge, cardToken); | |
// if (needToCharge && !cardToken) { | |
// navigator.push({key:'credit-card'}) | |
// } | |
dispatch(addCigarette()) | |
} | |
}) | |
)(Home); |
This file contains hidden or 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 { | |
Navigator | |
} from 'react-native'; | |
import Init from './scenes/init'; | |
import Tour from './scenes/tour'; | |
import Monthly from './scenes/monthly'; | |
import Daily from './scenes/dailyCigarettes'; | |
import Home from './scenes/home'; | |
import Email from './scenes/email'; | |
import CreditCard from './scenes/creditCard'; | |
import store from './store'; | |
import { connect } from 'react-redux'; | |
import { actions as appActions} from './store/models/app'; | |
import { selectors as mainSelectors } from './store/models/main'; | |
const routes = { | |
'init': Init, | |
'tour': Tour, | |
'monthly': Monthly, | |
'daily': Daily, | |
'home': Home, | |
'email': Email, | |
'credit-card': CreditCard | |
}; | |
const transitionMatrix = { | |
init: [{ | |
condition: (props) => { | |
let onboarded = props.config.monthly && props.config.dailyCigarettes; | |
return props.app.initialized && !onboarded | |
}, | |
route: { key: 'tour' } | |
}, { | |
condition: (props) => props.app.initialized, | |
route: { key: 'home', transition: 'resetTo' } | |
}], | |
home: [{ | |
condition: (props) => { | |
let { needToCharge } = props; | |
let { email } = props.config; | |
return needToCharge && !email; | |
}, | |
route: { key: 'email' } | |
}, { | |
condition: (props) => { | |
let { needToCharge } = props; | |
let { cardId } = props.config; | |
return needToCharge && !cardId; | |
}, | |
route: { key: 'credit-card' } | |
}] | |
} | |
class Router extends Component { | |
componentDidMount() { | |
this.navigator.navigationContext.addListener('didfocus', (event) => { | |
this.onDidFocus(); | |
}); | |
store.dispatch(appActions.init()); | |
} | |
componentDidUpdate(prevProps, prevState) { | |
this.onDidFocus(); | |
} | |
onDidFocus = () => { | |
let currentRoutes = this.navigator.getCurrentRoutes(); | |
console.log('onDidFocus', currentRoutes.map(r => r.key)); | |
let currentRoute = currentRoutes[currentRoutes.length-1]; | |
let rules = transitionMatrix[currentRoute.key]; | |
if (!rules) { | |
console.log('currentRoute.key has no router rules!', currentRoute.key); | |
return; | |
} | |
for (let rule of rules) { | |
if (rule.condition(this.props)) { | |
this.navigator[rule.transition || 'push'](rule.route); | |
break; //only support one rule at a time (?) | |
} | |
} | |
} | |
_renderScene(route, navigator) { | |
const Scene = routes[route.key]; | |
return <Scene navigator={navigator} {...route.data}/> | |
} | |
render () { | |
return ( | |
<Navigator | |
ref={ n => this.navigator = n } | |
initialRoute={{ key: 'init' }} | |
renderScene={this._renderScene} | |
/> | |
); | |
} | |
} | |
export default connect( | |
(state) => ({ | |
app: state.get('app').toJS(), | |
config: state.get('config').toJS(), | |
needToCharge: mainSelectors.needToCharge(state) | |
}), | |
(dispatch) => ({}) | |
)(Router) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment