Skip to content

Commit

Permalink
Expo example (#3287)
Browse files Browse the repository at this point in the history
  • Loading branch information
daviscabral authored Sep 21, 2018
1 parent 2e68afa commit 47d54c7
Show file tree
Hide file tree
Showing 29 changed files with 7,469 additions and 2 deletions.
8 changes: 8 additions & 0 deletions examples/expo/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"presets": ["babel-preset-expo"],
"env": {
"development": {
"plugins": ["transform-react-jsx-source"]
}
}
}
3 changes: 3 additions & 0 deletions examples/expo/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "universe/native"
}
2 changes: 2 additions & 0 deletions examples/expo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/**/*
.expo/**/*
7 changes: 7 additions & 0 deletions examples/expo/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"printWidth": 100,
"tabWidth": 2,
"singleQuote": true,
"jsxBracketSameLine": true,
"trailingComma": "es5"
}
1 change: 1 addition & 0 deletions examples/expo/.watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
62 changes: 62 additions & 0 deletions examples/expo/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';
import { Platform, StatusBar, StyleSheet, View } from 'react-native';
import { AppLoading, Asset, Font, Icon } from 'expo';
import AppNavigator from './navigation/AppNavigator';

export default class App extends React.Component {
state = {
isLoadingComplete: false,
};

render() {
if (!this.state.isLoadingComplete && !this.props.skipLoadingScreen) {
return (
<AppLoading
startAsync={this._loadResourcesAsync}
onError={this._handleLoadingError}
onFinish={this._handleFinishLoading}
/>
);
} else {
return (
<View style={styles.container}>
{Platform.OS === 'ios' && <StatusBar barStyle="default" />}
<AppNavigator />
</View>
);
}
}

_loadResourcesAsync = async () => {
return Promise.all([
Asset.loadAsync([
require('./assets/images/robot-dev.png'),
require('./assets/images/robot-prod.png'),
]),
Font.loadAsync({
// This is the font that we are using for our tab bar
...Icon.Ionicons.font,
// We include SpaceMono because we use it in HomeScreen.js. Feel free
// to remove this if you are not using it in your app
'space-mono': require('./assets/fonts/SpaceMono-Regular.ttf'),
}),
]);
};

_handleLoadingError = error => {
// In this case, you might want to report the error to your error
// reporting service, for example Sentry
console.warn(error);
};

_handleFinishLoading = () => {
this.setState({ isLoadingComplete: true });
};
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});
22 changes: 22 additions & 0 deletions examples/expo/__tests__/App-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'react-native';
import React from 'react';
import renderer from 'react-test-renderer';
import NavigationTestUtils from 'react-navigation/NavigationTestUtils';
import App from '../App';

describe('App snapshot', () => {
jest.useFakeTimers();
beforeEach(() => {
NavigationTestUtils.resetInternalState();
});

it('renders the loading screen', async () => {
const tree = renderer.create(<App />).toJSON();
expect(tree).toMatchSnapshot();
});

it('renders the root without loading screen', async () => {
const tree = renderer.create(<App skipLoadingScreen />).toJSON();
expect(tree).toMatchSnapshot();
});
});
27 changes: 27 additions & 0 deletions examples/expo/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"expo": {
"name": "ExpoExample",
"description": "A very interesting project.",
"slug": "ExpoExample",
"privacy": "public",
"sdkVersion": "30.0.0",
"platforms": ["ios", "android"],
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"splash": {
"image": "./assets/images/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
}
}
}
Binary file added examples/expo/assets/fonts/SpaceMono-Regular.ttf
Binary file not shown.
Binary file added examples/expo/assets/images/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/expo/assets/images/robot-dev.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/expo/assets/images/robot-prod.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/expo/assets/images/splash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions examples/expo/components/DrawerContent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, Text, View, ViewPropTypes } from 'react-native';
import Button from 'react-native-button';
import { Actions } from 'react-native-router-flux';

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'transparent',
borderWidth: 2,
borderColor: 'red',
},
});

class DrawerContent extends React.Component {
static propTypes = {
name: PropTypes.string,
sceneStyle: ViewPropTypes.style,
title: PropTypes.string,
};

static contextTypes = {
drawer: PropTypes.object,
};

render() {
return (
<View style={styles.container}>
<Button onPress={Actions.pop}>Back</Button>
<Button onPress={Actions.main_home}>Switch to Home</Button>
<Button onPress={Actions.main_links}>Switch to Links</Button>
<Button onPress={Actions.main_settings}>Switch to Settings</Button>
</View>
);
}
}

export default DrawerContent;
8 changes: 8 additions & 0 deletions examples/expo/components/MenuIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import { Icon } from 'expo';

export default class MenuIcon extends React.Component {
render() {
return <Icon.Ionicons name={isAndroid ? 'md-more' : 'ios-more'} size={32} />;
}
}
8 changes: 8 additions & 0 deletions examples/expo/components/StyledText.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';
import { Text } from 'react-native';

export class MonoText extends React.Component {
render() {
return <Text {...this.props} style={[this.props.style, { fontFamily: 'space-mono' }]} />;
}
}
17 changes: 17 additions & 0 deletions examples/expo/components/TabBarIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { Icon } from 'expo';

import Colors from '../constants/Colors';

export default class TabBarIcon extends React.Component {
render() {
return (
<Icon.Ionicons
name={this.props.name}
size={26}
style={{ marginBottom: -3 }}
color={this.props.focused ? Colors.tabIconSelected : Colors.tabIconDefault}
/>
);
}
}
10 changes: 10 additions & 0 deletions examples/expo/components/__tests__/StyledText-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'react-native';
import React from 'react';
import { MonoText } from '../StyledText';
import renderer from 'react-test-renderer';

it('renders correctly', () => {
const tree = renderer.create(<MonoText>Snapshot test!</MonoText>).toJSON();

expect(tree).toMatchSnapshot();
});
14 changes: 14 additions & 0 deletions examples/expo/constants/Colors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const tintColor = '#2f95dc';

export default {
tintColor,
tabIconDefault: '#ccc',
tabIconSelected: tintColor,
tabBar: '#fefefe',
errorBackground: 'red',
errorText: '#fff',
warningBackground: '#EAEB5E',
warningText: '#666804',
noticeBackground: tintColor,
noticeText: '#fff',
};
11 changes: 11 additions & 0 deletions examples/expo/constants/Layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Dimensions } from 'react-native';

const { width, height } = Dimensions.get('window');

export default {
window: {
width,
height,
},
isSmallDevice: width < 375,
};
130 changes: 130 additions & 0 deletions examples/expo/navigation/AppNavigator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import React from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import { StackViewStyleInterpolator } from 'react-navigation-stack';
import {
Scene,
Router,
Actions,
Reducer,
ActionConst,
Overlay,
Tabs,
Modal,
Drawer,
Stack,
Lightbox,
} from 'react-native-router-flux';
import TabBarIcon from '../components/TabBarIcon';
import MenuIcon from '../components/MenuIcon';
import DrawerContent from '../components/DrawerContent';
import HomeScreen from '../screens/HomeScreen';
import LinksScreen from '../screens/LinksScreen';
import SettingsScreen from '../screens/SettingsScreen';

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'transparent',
justifyContent: 'center',
alignItems: 'center',
},
tabBarStyle: {
backgroundColor: '#eee',
},
tabBarSelectedItemStyle: {
backgroundColor: '#ddd',
},
});

const reducerCreate = params => {
const defaultReducer = new Reducer(params);
return (state, action) => {
console.log('reducer: ACTION:', action);
return defaultReducer(state, action);
};
};

const stateHandler = (prevState, newState, action) => {
console.log('onStateChange: ACTION:', action);
};

const getSceneStyle = () => ({
backgroundColor: '#F5FCFF',
shadowOpacity: 1,
shadowRadius: 3,
});

// on Android, the URI prefix typically contains a host in addition to scheme
const prefix = Platform.OS === 'android' ? 'mychat://mychat/' : 'mychat://';

const transitionConfig = () => ({
screenInterpolator:
StackViewStyleInterpolator.forFadeFromBottomAndroid,
});

const AppNavigator = () => (
<Router
createReducer={reducerCreate}
onStateChange={stateHandler}
getSceneStyle={getSceneStyle}
uriPrefix={prefix}>
<Overlay key="overlay">
<Modal key="modal" hideNavBar transitionConfig={transitionConfig}>
<Lightbox key="lightbox">
<Stack key="root" hideNavBar titleStyle={{ alignSelf: 'center' }}>

<Drawer
hideNavBar
key="drawer"
onExit={() => {
console.log('Drawer closed');
}}
onEnter={() => {
console.log('Drawer opened');
}}
contentComponent={DrawerContent}
drawerIcon={MenuIcon}
drawerWidth={300}>
<Scene hideNavBar>
<Tabs
key="tabbar"
backToInitial
onTabOnPress={() => {
console.log('Back to initial and also print this');
}}
swipeEnabled
tabBarStyle={styles.tabBarStyle}
activeBackgroundColor="white"
inactiveBackgroundColor="rgba(255, 0, 0, 0.5)">
<Scene
key="main_home"
component={HomeScreen}
title="Home"
tabBarLabel="Home"
icon={TabBarIcon}
/>
<Scene
key="main_links"
component={LinksScreen}
title="Links"
tabBarLabel="Links"
icon={TabBarIcon}
/>
<Scene
key="main_settings"
component={SettingsScreen}
title="Settings"
tabBarLabel="Settings"
icon={TabBarIcon}
/>
</Tabs>
</Scene>
</Drawer>
</Stack>
</Lightbox>
</Modal>
</Overlay>
</Router>
);

export default AppNavigator;
Loading

0 comments on commit 47d54c7

Please sign in to comment.