]> git.rustad.me Git - geoguessr/commitdiff
Initial commit master
authorBjørn Rustad <bjorn@rustad.me>
Thu, 16 Aug 2018 17:03:47 +0000 (19:03 +0200)
committerBjørn Rustad <bjorn@rustad.me>
Thu, 16 Aug 2018 17:03:47 +0000 (19:03 +0200)
20 files changed:
.gitignore [new file with mode: 0644]
App.js [new file with mode: 0644]
__tests__/App-test.js [new file with mode: 0644]
app.json [new file with mode: 0644]
assets/fonts/SpaceMono-Regular.ttf [new file with mode: 0755]
assets/images/icon.png [new file with mode: 0644]
assets/images/robot-dev.png [new file with mode: 0644]
assets/images/robot-prod.png [new file with mode: 0644]
assets/images/splash.png [new file with mode: 0644]
components/StyledText.js [new file with mode: 0644]
components/TabBarIcon.js [new file with mode: 0644]
components/__tests__/StyledText-test.js [new file with mode: 0644]
constants/Colors.js [new file with mode: 0644]
constants/Layout.js [new file with mode: 0644]
navigation/AppNavigator.js [new file with mode: 0644]
navigation/MainTabNavigator.js [new file with mode: 0644]
package.json [new file with mode: 0644]
screens/HomeScreen.js [new file with mode: 0644]
screens/LinksScreen.js [new file with mode: 0644]
screens/SettingsScreen.js [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..db133b1
--- /dev/null
@@ -0,0 +1,2 @@
+.expo
+node_modules
diff --git a/App.js b/App.js
new file mode 100644 (file)
index 0000000..fe59c3f
--- /dev/null
+++ b/App.js
@@ -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',
+  },
+});
diff --git a/__tests__/App-test.js b/__tests__/App-test.js
new file mode 100644 (file)
index 0000000..2d73499
--- /dev/null
@@ -0,0 +1,22 @@
+import 'react-native';
+import React from 'react';
+import App from '../App';
+import renderer from 'react-test-renderer';
+import NavigationTestUtils from 'react-navigation/NavigationTestUtils';
+
+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();
+  });
+});
diff --git a/app.json b/app.json
new file mode 100644 (file)
index 0000000..3bf8881
--- /dev/null
+++ b/app.json
@@ -0,0 +1,27 @@
+{
+  "expo": {
+    "name": "geoguessr",
+    "description": "A very interesting project.",
+    "slug": "geoguessr",
+    "privacy": "public",
+    "sdkVersion": "29.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
+    }
+  }
+}
diff --git a/assets/fonts/SpaceMono-Regular.ttf b/assets/fonts/SpaceMono-Regular.ttf
new file mode 100755 (executable)
index 0000000..28d7ff7
Binary files /dev/null and b/assets/fonts/SpaceMono-Regular.ttf differ
diff --git a/assets/images/icon.png b/assets/images/icon.png
new file mode 100644 (file)
index 0000000..3f5bbc0
Binary files /dev/null and b/assets/images/icon.png differ
diff --git a/assets/images/robot-dev.png b/assets/images/robot-dev.png
new file mode 100644 (file)
index 0000000..177de0c
Binary files /dev/null and b/assets/images/robot-dev.png differ
diff --git a/assets/images/robot-prod.png b/assets/images/robot-prod.png
new file mode 100644 (file)
index 0000000..6511d10
Binary files /dev/null and b/assets/images/robot-prod.png differ
diff --git a/assets/images/splash.png b/assets/images/splash.png
new file mode 100644 (file)
index 0000000..4f9ade6
Binary files /dev/null and b/assets/images/splash.png differ
diff --git a/components/StyledText.js b/components/StyledText.js
new file mode 100644 (file)
index 0000000..24c7b9b
--- /dev/null
@@ -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' }]} />;
+  }
+}
diff --git a/components/TabBarIcon.js b/components/TabBarIcon.js
new file mode 100644 (file)
index 0000000..2f1ebed
--- /dev/null
@@ -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}
+      />
+    );
+  }
+}
\ No newline at end of file
diff --git a/components/__tests__/StyledText-test.js b/components/__tests__/StyledText-test.js
new file mode 100644 (file)
index 0000000..04453f8
--- /dev/null
@@ -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();
+});
diff --git a/constants/Colors.js b/constants/Colors.js
new file mode 100644 (file)
index 0000000..d8bd415
--- /dev/null
@@ -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',
+};
diff --git a/constants/Layout.js b/constants/Layout.js
new file mode 100644 (file)
index 0000000..1a15a93
--- /dev/null
@@ -0,0 +1,12 @@
+import { Dimensions } from 'react-native';
+
+const width = Dimensions.get('window').width;
+const height = Dimensions.get('window').height;
+
+export default {
+  window: {
+    width,
+    height,
+  },
+  isSmallDevice: width < 375,
+};
diff --git a/navigation/AppNavigator.js b/navigation/AppNavigator.js
new file mode 100644 (file)
index 0000000..df564c5
--- /dev/null
@@ -0,0 +1,10 @@
+import React from 'react';
+import { createSwitchNavigator } from 'react-navigation';
+
+import MainTabNavigator from './MainTabNavigator';
+
+export default createSwitchNavigator({
+  // You could add another route here for authentication.
+  // Read more at https://reactnavigation.org/docs/en/auth-flow.html
+  Main: MainTabNavigator,
+});
\ No newline at end of file
diff --git a/navigation/MainTabNavigator.js b/navigation/MainTabNavigator.js
new file mode 100644 (file)
index 0000000..b8f2274
--- /dev/null
@@ -0,0 +1,60 @@
+import React from 'react';
+import { Platform } from 'react-native';
+import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';
+
+import TabBarIcon from '../components/TabBarIcon';
+import HomeScreen from '../screens/HomeScreen';
+import LinksScreen from '../screens/LinksScreen';
+import SettingsScreen from '../screens/SettingsScreen';
+
+const HomeStack = createStackNavigator({
+  Home: HomeScreen,
+});
+
+HomeStack.navigationOptions = {
+  tabBarLabel: 'Home',
+  tabBarIcon: ({ focused }) => (
+    <TabBarIcon
+      focused={focused}
+      name={
+        Platform.OS === 'ios'
+          ? `ios-information-circle${focused ? '' : '-outline'}`
+          : 'md-information-circle'
+      }
+    />
+  ),
+};
+
+const LinksStack = createStackNavigator({
+  Links: LinksScreen,
+});
+
+LinksStack.navigationOptions = {
+  tabBarLabel: 'Links',
+  tabBarIcon: ({ focused }) => (
+    <TabBarIcon
+      focused={focused}
+      name={Platform.OS === 'ios' ? `ios-link${focused ? '' : '-outline'}` : 'md-link'}
+    />
+  ),
+};
+
+const SettingsStack = createStackNavigator({
+  Settings: SettingsScreen,
+});
+
+SettingsStack.navigationOptions = {
+  tabBarLabel: 'Settings',
+  tabBarIcon: ({ focused }) => (
+    <TabBarIcon
+      focused={focused}
+      name={Platform.OS === 'ios' ? `ios-options${focused ? '' : '-outline'}` : 'md-options'}
+    />
+  ),
+};
+
+export default createBottomTabNavigator({
+  HomeStack,
+  LinksStack,
+  SettingsStack,
+});
diff --git a/package.json b/package.json
new file mode 100644 (file)
index 0000000..a7be056
--- /dev/null
@@ -0,0 +1,25 @@
+{
+  "name": "my-new-project",
+  "main": "node_modules/expo/AppEntry.js",
+  "private": true,
+  "scripts": {
+    "start": "expo start",
+    "android": "expo start --android",
+    "ios": "expo start --ios",
+    "eject": "expo eject",
+    "test": "node ./node_modules/jest/bin/jest.js --watchAll"
+  },
+  "jest": {
+    "preset": "jest-expo"
+  },
+  "dependencies": {
+    "@expo/samples": "2.1.1",
+    "expo": "29.0.0",
+    "react": "16.3.1",
+    "react-native": "https://github.com/expo/react-native/archive/sdk-29.0.0.tar.gz",
+    "react-navigation": "^2.9.3"
+  },
+  "devDependencies": {
+    "jest-expo": "29.0.0"
+  }
+}
diff --git a/screens/HomeScreen.js b/screens/HomeScreen.js
new file mode 100644 (file)
index 0000000..0d3548e
--- /dev/null
@@ -0,0 +1,188 @@
+import React from 'react';
+import {
+  Image,
+  Platform,
+  ScrollView,
+  StyleSheet,
+  Text,
+  TouchableOpacity,
+  View,
+} from 'react-native';
+import { WebBrowser } from 'expo';
+
+import { MonoText } from '../components/StyledText';
+
+export default class HomeScreen extends React.Component {
+  static navigationOptions = {
+    header: null,
+  };
+
+  render() {
+    return (
+      <View style={styles.container}>
+        <ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
+          <View style={styles.welcomeContainer}>
+            <Image
+              source={
+                __DEV__
+                  ? require('../assets/images/robot-dev.png')
+                  : require('../assets/images/robot-prod.png')
+              }
+              style={styles.welcomeImage}
+            />
+          </View>
+
+          <View style={styles.getStartedContainer}>
+            {this._maybeRenderDevelopmentModeWarning()}
+
+            <Text style={styles.getStartedText}>Get started by opening</Text>
+
+            <View style={[styles.codeHighlightContainer, styles.homeScreenFilename]}>
+              <MonoText style={styles.codeHighlightText}>screens/HomeScreen.js</MonoText>
+            </View>
+
+            <Text style={styles.getStartedText}>
+              Change this text and your app will automatically reload.
+            </Text>
+          </View>
+
+          <View style={styles.helpContainer}>
+            <TouchableOpacity onPress={this._handleHelpPress} style={styles.helpLink}>
+              <Text style={styles.helpLinkText}>Help, it didn’t automatically reload!</Text>
+            </TouchableOpacity>
+          </View>
+        </ScrollView>
+
+        <View style={styles.tabBarInfoContainer}>
+          <Text style={styles.tabBarInfoText}>This is a tab bar. You can edit it in:</Text>
+
+          <View style={[styles.codeHighlightContainer, styles.navigationFilename]}>
+            <MonoText style={styles.codeHighlightText}>navigation/MainTabNavigator.js</MonoText>
+          </View>
+        </View>
+      </View>
+    );
+  }
+
+  _maybeRenderDevelopmentModeWarning() {
+    if (__DEV__) {
+      const learnMoreButton = (
+        <Text onPress={this._handleLearnMorePress} style={styles.helpLinkText}>
+          Learn more
+        </Text>
+      );
+
+      return (
+        <Text style={styles.developmentModeText}>
+          Development mode is enabled, your app will be slower but you can use useful development
+          tools. {learnMoreButton}
+        </Text>
+      );
+    } else {
+      return (
+        <Text style={styles.developmentModeText}>
+          You are not in development mode, your app will run at full speed.
+        </Text>
+      );
+    }
+  }
+
+  _handleLearnMorePress = () => {
+    WebBrowser.openBrowserAsync('https://docs.expo.io/versions/latest/guides/development-mode');
+  };
+
+  _handleHelpPress = () => {
+    WebBrowser.openBrowserAsync(
+      'https://docs.expo.io/versions/latest/guides/up-and-running.html#can-t-see-your-changes'
+    );
+  };
+}
+
+const styles = StyleSheet.create({
+  container: {
+    flex: 1,
+    backgroundColor: '#fff',
+  },
+  developmentModeText: {
+    marginBottom: 20,
+    color: 'rgba(0,0,0,0.4)',
+    fontSize: 14,
+    lineHeight: 19,
+    textAlign: 'center',
+  },
+  contentContainer: {
+    paddingTop: 30,
+  },
+  welcomeContainer: {
+    alignItems: 'center',
+    marginTop: 10,
+    marginBottom: 20,
+  },
+  welcomeImage: {
+    width: 100,
+    height: 80,
+    resizeMode: 'contain',
+    marginTop: 3,
+    marginLeft: -10,
+  },
+  getStartedContainer: {
+    alignItems: 'center',
+    marginHorizontal: 50,
+  },
+  homeScreenFilename: {
+    marginVertical: 7,
+  },
+  codeHighlightText: {
+    color: 'rgba(96,100,109, 0.8)',
+  },
+  codeHighlightContainer: {
+    backgroundColor: 'rgba(0,0,0,0.05)',
+    borderRadius: 3,
+    paddingHorizontal: 4,
+  },
+  getStartedText: {
+    fontSize: 17,
+    color: 'rgba(96,100,109, 1)',
+    lineHeight: 24,
+    textAlign: 'center',
+  },
+  tabBarInfoContainer: {
+    position: 'absolute',
+    bottom: 0,
+    left: 0,
+    right: 0,
+    ...Platform.select({
+      ios: {
+        shadowColor: 'black',
+        shadowOffset: { height: -3 },
+        shadowOpacity: 0.1,
+        shadowRadius: 3,
+      },
+      android: {
+        elevation: 20,
+      },
+    }),
+    alignItems: 'center',
+    backgroundColor: '#fbfbfb',
+    paddingVertical: 20,
+  },
+  tabBarInfoText: {
+    fontSize: 17,
+    color: 'rgba(96,100,109, 1)',
+    textAlign: 'center',
+  },
+  navigationFilename: {
+    marginTop: 5,
+  },
+  helpContainer: {
+    marginTop: 15,
+    alignItems: 'center',
+  },
+  helpLink: {
+    paddingVertical: 15,
+  },
+  helpLinkText: {
+    fontSize: 14,
+    color: '#2e78b7',
+  },
+});
diff --git a/screens/LinksScreen.js b/screens/LinksScreen.js
new file mode 100644 (file)
index 0000000..7bb4a62
--- /dev/null
@@ -0,0 +1,27 @@
+import React from 'react';
+import { ScrollView, StyleSheet } from 'react-native';
+import { ExpoLinksView } from '@expo/samples';
+
+export default class LinksScreen extends React.Component {
+  static navigationOptions = {
+    title: 'Links',
+  };
+
+  render() {
+    return (
+      <ScrollView style={styles.container}>
+        {/* Go ahead and delete ExpoLinksView and replace it with your
+           * content, we just wanted to provide you with some helpful links */}
+        <ExpoLinksView />
+      </ScrollView>
+    );
+  }
+}
+
+const styles = StyleSheet.create({
+  container: {
+    flex: 1,
+    paddingTop: 15,
+    backgroundColor: '#fff',
+  },
+});
diff --git a/screens/SettingsScreen.js b/screens/SettingsScreen.js
new file mode 100644 (file)
index 0000000..6957dcb
--- /dev/null
@@ -0,0 +1,14 @@
+import React from 'react';
+import { ExpoConfigView } from '@expo/samples';
+
+export default class SettingsScreen extends React.Component {
+  static navigationOptions = {
+    title: 'app.json',
+  };
+
+  render() {
+    /* Go ahead and delete ExpoConfigView and replace it with your
+     * content, we just wanted to give you a quick view of your config */
+    return <ExpoConfigView />;
+  }
+}