<commit_before>import Exponent, { Font, Components } from 'exponent';
import React, { Component } from 'react';
import {
  AsyncStorage,
  Alert,
} from 'react-native';
import {
  NavigationProvider,
  StackNavigation,
} from '@exponent/ex-navigation';
import Router from './navigation/Router';
import * as firebase from 'firebase';
import { firebaseConfig, sentryURL } from './config/keys';
import { ActionSheetProvider } from '@exponent/react-native-action-sheet';
import DropdownAlertProvider from './components/DropdownAlertProvider';
import ExponentSentryClient from '@exponent/sentry-utils';
import { observer, Provider as MobXProvider } from 'mobx-react/native';
import authStore from './stores/AuthStore';
import eventStore from './stores/EventStore';
import trexStore from './stores/TrexStore';

if (!__DEV__) { // eslint-disable-line jsx-control-statements/jsx-jcs-no-undef
  // this guards against console usage in production builds since
  // babel transform of remove console won't work with react-native preset
  ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception',
    'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'profile', 'profileEnd',
    'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'].forEach(
    (methodName) => {
      console[methodName] = () => { /* noop */ };
    });

  ExponentSentryClient.setupSentry(
    sentryURL,
    require('./exp.json').version,
    require('./package.json').main,
  );
}

@observer
class App extends Component {
  state = {
    loading: true,
    loggedIn: false,
  }

  componentDidMount() {
    this.setup().catch(e => {
      Alert.alert(e.toString());
      this.setState(() => {
        return { loading: false, loggedIn: false };
      });
    });
  }

  /**
   *  Asks for permissions, loads fonts, and starts Firebase
   */
  async setup() {
    const { Permissions } = Exponent;
    await Permissions.askAsync(Permissions.LOCATION);

    await Font.loadAsync({
      'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'),
      'open-sans-light': require('./assets/fonts/OpenSans-Light.ttf'),
      'open-sans-extrabold': require('./assets/fonts/OpenSans-ExtraBold.ttf'),
      'open-sans': require('./assets/fonts/OpenSans-Regular.ttf'),
      'open-sans-semibold': require('./assets/fonts/OpenSans-Semibold.ttf'),
      'neutra-bold': require('./assets/fonts/NeutraTextBold.ttf'),
    });
    await this.startFirebase();
  }

  startFirebase = async () => {
    try {
      global.firebaseApp = firebase.initializeApp(firebaseConfig);
    } catch (error) {
      Alert.alert(null, 'Something\'s on fire. Please press \'OK\' to try again.', [
        { text: 'OK', onPress: this.startFirebase },
      ]);
    }
    try {
      await this.signIn();
    } catch (e) {
      this.setState(() => {
        return { loading: false, loggedIn: false };
      });
    }
  }

  signIn = async () => {
    let userCredentials = await AsyncStorage.getItem('@PUL:user');
    if (userCredentials !== null) {
      userCredentials = JSON.parse(userCredentials);
      global.firebaseApp.auth().signInWithEmailAndPassword(
        userCredentials.email,
        userCredentials.password,
      ).then((user) => {
        global.firebaseApp.database()
        .ref('users')
        .child(user.uid)
        .once('value')
        .then(userSnap => {
          // if userSnap.val().deviceId === undefined then give it one and continue sign in
          if (!userSnap.val().deviceId) {
            global.firebaseApp.database().ref('users').child(user.uid).update({
              deviceId: Exponent.Constants.deviceId,
            });
          } else if (userSnap.val().deviceId !== Exponent.Constants.deviceId) {
          // if this is not the same device as last time, sign out
            global.firebaseApp.auth().signOut();
            this.setState(() => {
              return { loading: false, loggedIn: false };
            });
            return;
          }

          const emailWatch = setInterval(() => {
            if (global.firebaseApp.auth().currentUser) {
              if (global.firebaseApp.auth().currentUser.emailVerified) {
                clearInterval(emailWatch);
              }
              global.firebaseApp.auth().currentUser.reload();
            }
          }, 1000);
          this.setState(() => {
            return { loading: false, loggedIn: true };
          });
        });
      }).catch(error => {
        switch (error.code) {
          case 'auth/network-request-failed':
            Alert.alert(null, 'No Internet connection. Please press \'OK\' when connected.', [
              { text: 'OK', onPress: this.signIn },
            ]);
            break;
          case 'auth/user-not-found':
          case 'auth/invalid-email':
          case 'auth/user-disabled':
          case 'auth/wrong-password':
            this.setState(() => {
              return { loading: false, loggedIn: false };
            });
            break;
          default:
            Alert.alert(null, 'Something is on fire.', [
              { text: 'OK' },
            ]);
            this.setState(() => {
              return { loading: false, loggedIn: false };
            });
        }
      });
    } else {
      this.setState(() => {
        return { loading: false };
      });
    }
  };

  render() {
    const route = this.state.loggedIn ? 'tabs' : 'onboarding';

    return (
      <Choose>
        <When condition={ this.state.loading }>
          <Components.AppLoading />
        </When>
        <Otherwise>
          <DropdownAlertProvider>
            <ActionSheetProvider>
              <NavigationProvider router={ Router }>
                <StackNavigation id="master" initialRoute={ Router.getRoute(route) } />
              </NavigationProvider>
            </ActionSheetProvider>
          </DropdownAlertProvider>
        </Otherwise>
      </Choose>
    );
  }
}


const Main = () => (
  <MobXProvider authStore={ authStore } eventStore={ eventStore } trexStore={ trexStore }>
    <App />
  </MobXProvider>
);

Exponent.registerRootComponent(Main);<commit_msg>use authStore's login<commit_after>import Exponent, { Font, Components } from 'exponent';
import React, { Component, PropTypes } from 'react';
import {
  AsyncStorage,
  Alert,
} from 'react-native';
import {
  NavigationProvider,
  StackNavigation,
} from '@exponent/ex-navigation';
import Router from './navigation/Router';
import * as firebase from 'firebase';
import { firebaseConfig, sentryURL } from './config/keys';
import { ActionSheetProvider } from '@exponent/react-native-action-sheet';
import DropdownAlertProvider from './components/DropdownAlertProvider';
import ExponentSentryClient from '@exponent/sentry-utils';
import connectDropdownAlert from './utils/connectDropdownAlert';
import { observer, Provider as MobXProvider, inject } from 'mobx-react/native';
import authStore from './stores/AuthStore';
import eventStore from './stores/EventStore';
import trexStore from './stores/TrexStore';

if (!__DEV__) { // eslint-disable-line jsx-control-statements/jsx-jcs-no-undef
  // this guards against console usage in production builds since
  // babel transform of remove console won't work with react-native preset
  ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception',
    'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'profile', 'profileEnd',
    'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'].forEach(
    (methodName) => {
      console[methodName] = () => { /* noop */ };
    });

  ExponentSentryClient.setupSentry(
    sentryURL,
    require('./exp.json').version,
    require('./package.json').main,
  );
}

@connectDropdownAlert
@inject('authStore') @observer
class App extends Component {
  static propTypes = {
    authStore: PropTypes.object,
    alertWithType: PropTypes.func,
  }
  state = {
    loading: true,
    loggedIn: false,
  }

  componentDidMount() {
    this.setup().catch(e => {
      Alert.alert(e.toString());
      this.setState(() => {
        return { loading: false, loggedIn: false };
      });
    });
  }

  /**
   *  Asks for permissions, loads fonts, and starts Firebase
   */
  async setup() {
    const { Permissions } = Exponent;
    await Permissions.askAsync(Permissions.LOCATION);

    await Font.loadAsync({
      'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'),
      'open-sans-light': require('./assets/fonts/OpenSans-Light.ttf'),
      'open-sans-extrabold': require('./assets/fonts/OpenSans-ExtraBold.ttf'),
      'open-sans': require('./assets/fonts/OpenSans-Regular.ttf'),
      'open-sans-semibold': require('./assets/fonts/OpenSans-Semibold.ttf'),
      'neutra-bold': require('./assets/fonts/NeutraTextBold.ttf'),
    });
    await this.startFirebase();
  }

  startFirebase = async () => {
    try {
      global.firebaseApp = firebase.initializeApp(firebaseConfig);
    } catch (error) {
      Alert.alert(null, 'Something\'s on fire. Please press \'OK\' to try again.', [
        { text: 'OK', onPress: this.startFirebase },
      ]);
    }
    try {
      await this.signIn();
    } catch (error) {
      this.props.alertWithType('error', 'Error', error.toString());
      this.setState(() => {
        return { loading: false };
      });
    }
  }

  signIn = async () => {
    let userCredentials = await AsyncStorage.getItem('@PUL:user');
    if (userCredentials !== null) {
      userCredentials = JSON.parse(userCredentials);

      try {
        await this.props.authStore.login(userCredentials);
        this.setState(() => {
          return { loading: false };
        });
      } catch (error) {
        if (error.code) {
          switch (error.code) {
            case 'auth/network-request-failed':
              Alert.alert(null, 'No Internet connection. Please press \'OK\' when connected.', [
                { text: 'OK', onPress: this.signIn },
              ]);
              break;
            case 'auth/user-not-found':
            case 'auth/invalid-email':
            case 'auth/user-disabled':
            case 'auth/wrong-password':
              this.setState(() => {
                return { loading: false };
              });
              break;
            default:
              Alert.alert(null, 'Something is on fire.', [
                { text: 'OK' },
              ]);
              this.setState(() => {
                return { loading: false };
              });
          }
        } else {
          this.props.alertWithType('error', 'Error', error.toString());
        }
      }
    } else {
      this.setState(() => {
        return { loading: false };
      });
    }
  };

  render() {
    const route = this.props.authStore.state === this.props.authStore.authStates[1] ? 'tabs' : 'onboarding';

    return (
      <Choose>
        <When condition={ this.state.loading }>
          <Components.AppLoading />
        </When>
        <Otherwise>
          <NavigationProvider router={ Router }>
            <StackNavigation id="master" initialRoute={ Router.getRoute(route) } />
          </NavigationProvider>
        </Otherwise>
      </Choose>
    );
  }
}

const Main = () => (
  <MobXProvider authStore={ authStore } eventStore={ eventStore } trexStore={ trexStore }>
    <DropdownAlertProvider>
      <ActionSheetProvider>
        <App />
      </ActionSheetProvider>
    </DropdownAlertProvider>
  </MobXProvider>
);

Exponent.registerRootComponent(Main);
{'fraction_non_alphanumeric': 0.1522745132279752, 'fraction_numerical': 0.0004365668383829564, 'mean_word_length': 2.3998219056099734, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 66, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4773525', 'n_tokens_mistral': 3380, 'n_tokens_neox': 3335, 'n_words': 698}