diff --git a/Gruntfile.js b/Gruntfile.js index dd7a0115..ff91f02f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -114,7 +114,8 @@ module.exports = function(grunt) { ], options: { ignores: [ - 'src/js/**/*.ios.js' + 'src/js/**/*.ios.js', + 'src/js/native_react_views/*.js' ], curly: true, // sometimes triple equality is just redundant and unnecessary @@ -217,6 +218,7 @@ module.exports = function(grunt) { 'src/__tests__/casperjs/*.js', 'src/js/__tests__/create.js', 'src/js/__tests__/*.js', + 'src/js/native_react_views/*.js', 'src/js/**/*.ios.js' ] }, diff --git a/src/js/constants/AppStyles.js b/src/js/constants/AppStyles.js new file mode 100644 index 00000000..2d1ef06c --- /dev/null +++ b/src/js/constants/AppStyles.js @@ -0,0 +1,16 @@ +var AppStyles = { + blueBackground: '#5cbcfc', + terminalBackground: '#424242', + terminalText: 'rgb(238, 238, 238)', + terminalHeader: '#EFEDEE', + terminalBorder: '#303030', + terminalFontFamily: 'Courier', +}; + +AppStyles.terminalTextStyle = { + color: AppStyles.terminalText, + fontFamily: AppStyles.terminalFontFamily, + fontWeight: 'bold', +}; + +module.exports = AppStyles; diff --git a/src/js/constants/Routes.js b/src/js/constants/Routes.js new file mode 100644 index 00000000..d9af3475 --- /dev/null +++ b/src/js/constants/Routes.js @@ -0,0 +1,19 @@ +var assign = require('object-assign'); +var keyMirror = require('../util/keyMirror'); + +module.exports = keyMirror({ + NUX: null, + LOADING: null, + SEQUENCE_SELECT: null, + LEVEL_SELECT: null, +}); + +module.exports.getRouteWithParams = function(id, params) { + return assign({id: id}, params); +}; + +module.exports.getRouteForID = function(id) { + return { + id: id, + }; +}; diff --git a/src/js/native/index.ios.js b/src/js/native/index.ios.js index 2ed5543b..91973aea 100755 --- a/src/js/native/index.ios.js +++ b/src/js/native/index.ios.js @@ -4,98 +4,52 @@ */ 'use strict'; -var levels = require('../../levels/index.js'); -var LevelStore = require('../stores/LevelStore.js'); -var levelSequences = require('../../levels').levelSequences; - var React = require('react-native'); var { AppRegistry, - StyleSheet, Image, + Navigator, ScrollView, + StyleSheet, Text, TouchableHighlight, View, } = React; +var Routes = require('../constants/Routes'); +var SequenceSelectView = require('../native_react_views/SequenceSelectView'); +var LevelSelectView = require('../native_react_views/LevelSelectView'); +var NUXView = require('../native_react_views/NUXView'); + var LearnGitBranching = React.createClass({ + + _renderScene: function(route, navigator) { + switch (route.id) { + case Routes.SEQUENCE_SELECT: + return ; + case Routes.LEVEL_SELECT: + return ; + case Routes.NUX: + return ; + } + throw new Exception('No route found for ' + route.id); + }, + render: function() { return ( - - - - - Yo Whatup Peter - - {Object.keys(levelSequences).map(function(sequence) { - return ( - - - - - - {sequence} - - - - - - ); - })} - - + ); - } + }, + }); var styles = StyleSheet.create({ headerSpacer: { height: 40 }, - logo: { - width: 300, - borderRadius: 2, - justifyContent: 'center', - flexDirection: 'column', - alignItems: 'center', - height: 100 - }, - cardContainer: { - shadowColor: '#666', - shadowOpacity: 0.7, - marginBottom: 16, - shadowOffset: { - x: 100, - y: 100 - }, - }, - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: '#FFF', - }, - levelLabel: { - flexDirection: 'column', - backgroundColor: 'rgba(0, 0, 0, 0)', - alignItems: 'center', - justifyContent: 'center', - borderRadius: 10 - }, - sequenceName: { - color: '#FFF', - fontWeight: 'bold', - fontSize: 20, - }, - welcome: { - fontSize: 20, - textAlign: 'center', - margin: 10, - }, }); AppRegistry.registerComponent('LearnGitBranching', () => LearnGitBranching); diff --git a/src/js/native_react_views/LevelSelectView.js b/src/js/native_react_views/LevelSelectView.js new file mode 100644 index 00000000..b19a19f0 --- /dev/null +++ b/src/js/native_react_views/LevelSelectView.js @@ -0,0 +1,42 @@ +var NavButton = require('../native_react_views/NavButton'); +var React = require('react-native'); +var Routes = require('../constants/Routes'); + +var { + ScrollView, + StyleSheet, + Text, + View, +} = React; + +var LevelSelectView = React.createClass({ + + propTypes: { + navigator: React.PropTypes.object.isRequired, + }, + + render: function() { + return ( + + + + { + this.props.navigator.popToTop(); + }} + /> + + + ); + } + +}); + +var styles = StyleSheet.create({ + headerSpacer: { + height: 40 + }, +}); + +module.exports = LevelSelectView; diff --git a/src/js/native_react_views/NUXView.js b/src/js/native_react_views/NUXView.js new file mode 100644 index 00000000..61942eaf --- /dev/null +++ b/src/js/native_react_views/NUXView.js @@ -0,0 +1,91 @@ +var assign = require('object-assign'); +var React = require('react-native'); +var Routes = require('../constants/Routes'); +var { + ScrollView, + StyleSheet, + Text, + View, +} = React; + +var AppStyles = require('../constants/AppStyles'); +var TerminalCardView = require('../native_react_views/TerminalCardView'); +var NavButton = require('../native_react_views/NavButton'); + +var NUXView = React.createClass({ + + propTypes: { + navigator: React.PropTypes.object.isRequired, + }, + + render: function() { + return ( + + + + + + + Welcome To... + + + Learn Git Branching! + + + + Learn Git Branching is the most interactive + and visual way to master Git. + + + With over 30 tutorials and levels, everyone from + absolute beginners to experienced Git wizards + should find something challenging and new. + + + + { + this.props.navigator.push( + Routes.getRouteForID(Routes.LEVEL_SELECT) + ); + }} + /> + + + + ); + } +}); + +var styles = StyleSheet.create({ + buttonContainer: { + marginTop: 40, + }, + background: { + backgroundColor: AppStyles.blueBackground, + flex: 1 + }, + container: { + padding: 12, + }, + headerSpacer: { + height: 20, + backgroundColor: '#FFF' + }, + welcomeTextContainer: { + justifyContent: 'center', + alignItems: 'center', + }, + welcomeText: assign({}, AppStyles.terminalTextStyle, { + fontSize: 24, + marginBottom: 8 + }), + introText: assign({}, AppStyles.terminalTextStyle, { + marginTop: 8, + flex: 1, + marginBottom: 8 + }), +}); + +module.exports = NUXView; diff --git a/src/js/native_react_views/NavButton.js b/src/js/native_react_views/NavButton.js new file mode 100644 index 00000000..7aa1bd90 --- /dev/null +++ b/src/js/native_react_views/NavButton.js @@ -0,0 +1,32 @@ +var React = require('react-native'); +var { + PixelRatio, + StyleSheet, + Text, + TouchableHighlight, + View, +} = React; + +class NavButton extends React.Component { + render() { + return ( + + {this.props.text} + + ); + } +} + +var styles = StyleSheet.create({ + button: { + backgroundColor: 'white', + padding: 15, + borderBottomWidth: 1 / PixelRatio.get(), + borderBottomColor: '#CDCDCD', + }, +}); + +module.exports = NavButton; diff --git a/src/js/native_react_views/SequenceSelectView.js b/src/js/native_react_views/SequenceSelectView.js new file mode 100644 index 00000000..4b558eae --- /dev/null +++ b/src/js/native_react_views/SequenceSelectView.js @@ -0,0 +1,52 @@ +var NavButton = require('../native_react_views/NavButton'); +var React = require('react-native'); +var Routes = require('../constants/Routes'); +var { + ScrollView, + StyleSheet, + Text, + View, +} = React; + +var AppStyles = require('../constants/AppStyles'); + +var SequenceSelectView = React.createClass({ + + propTypes: { + navigator: React.PropTypes.object.isRequired, + }, + + render: function() { + return ( + + + + + { + this.props.navigator.push( + Routes.getRouteForID(Routes.LEVEL_SELECT) + ); + }} + /> + + + + ); + } + +}); + +var styles = StyleSheet.create({ + background: { + backgroundColor: AppStyles.blueBackground, + flex: 1 + }, + headerSpacer: { + height: 20, + backgroundColor: '#EFEDEE', + }, +}); + +module.exports = SequenceSelectView; diff --git a/src/js/native_react_views/TerminalCardView.js b/src/js/native_react_views/TerminalCardView.js new file mode 100644 index 00000000..ab5f411c --- /dev/null +++ b/src/js/native_react_views/TerminalCardView.js @@ -0,0 +1,102 @@ +var assign = require('object-assign'); +var React = require('react-native'); +var { + PixelRatio, + StyleSheet, + Text, + View, +} = React; + +var AppStyles = require('../constants/AppStyles'); + +var TerminalCardView = React.createClass({ + propTypes: { + text: React.PropTypes.string, + }, + + render: function() { + return ( + + + + + + + + {this.renderInner()} + + + ); + }, + + renderInner: function() { + return this.props.text ? + + {this.props.text} + : + this.props.children; + } + +}); + +var BORDER_WIDTH = 1 / PixelRatio.get(); +var BORDER_RADIUS = 4; +var BUTTON_SIZE = 12; +var BUTTON_BORDER_RADIUS = BUTTON_SIZE - 2; +var buttonStyle = { + height: BUTTON_SIZE, + width: BUTTON_SIZE, + borderRadius: BUTTON_BORDER_RADIUS, +}; + +var styles = StyleSheet.create({ + terminalHeader: { + height: 16, + backgroundColor: AppStyles.terminalHeader, + borderRadius: BORDER_RADIUS, + flexDirection: 'row', + justifyContent: 'flex-start', + alignItems: 'center', + paddingLeft: 4 + }, + + closeButton: assign({}, buttonStyle, { + backgroundColor: '#fb625f', + }), + + minimizeButton: assign({}, buttonStyle, { + backgroundColor: '#f9c57a', + }), + + maximizeButton: assign({}, buttonStyle, { + backgroundColor: '#8ac872', + }), + + terminalWindow: { + backgroundColor: AppStyles.terminalBackground, + borderRadius: BORDER_RADIUS, + shadowOpacity: 0.5, + shadowRadius: 4, + shadowOffset: { + h: 2, + w: 2, + }, + }, + + terminalTextContainer: { + padding: 12, + borderWidth: 1 / PixelRatio.get(), + borderColor: AppStyles.terminalBorder, + borderRadius: BORDER_RADIUS + }, + + terminalText: { + color: AppStyles.terminalText, + fontFamily: AppStyles.terminalFontFamily, + fontSize: 16, + fontWeight: 'bold' + }, + +}); + +module.exports = TerminalCardView;