diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000000..212fef118c0f
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,38 @@
+# EditorConfig is awesome: http://EditorConfig.org
+
+# Howto with your editor:
+# Sublime: https://github.com/sindresorhus/editorconfig-sublime
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[**]
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+
+# Standard at: https://github.com/felixge/node-style-guide
+[**.js, **.json]
+trim_trailing_whitespace = true
+quote_type = single
+curly_bracket_next_line = false
+spaces_around_operators = true
+space_after_control_statements = true
+space_after_anonymous_functions = false
+spaces_in_brackets = false
+
+# No Standard. Please document a standard if different from .js
+[**.yml, **.html, **.css]
+trim_trailing_whitespace = true
+
+# No standard. Please document a standard if different from .js
+[**.md]
+
+# Standard at:
+[Makefile]
+
+[package*]
+indent_style = space
+indent_size = 2
diff --git a/index.js b/index.js
index 3242b0ba4e59..48e7a839f9e8 100644
--- a/index.js
+++ b/index.js
@@ -2,8 +2,8 @@
* @format
*/
-import {AppRegistry} from 'react-native';
+import { AppRegistry } from 'react-native';
import App from './js/App';
-import {name as appName} from './app.json';
+import { name as appName } from './app.json';
AppRegistry.registerComponent(appName, () => App);
diff --git a/js/Expensify.js b/js/Expensify.js
index d53e8e39102e..66886d19ef8e 100644
--- a/js/Expensify.js
+++ b/js/Expensify.js
@@ -1,64 +1,64 @@
-import {init as StoreInit} from './store/Store.js';
+import { init as StoreInit } from './store/Store.js';
import SignInPage from './page/SignInPage.js';
import HomePage from './page/HomePage/HomePage.js';
import * as Store from './store/Store.js';
import * as ActiveClientManager from './lib/ActiveClientManager.js';
-import {verifyAuthToken} from './store/actions/SessionActions.js';
+import { verifyAuthToken } from './store/actions/SessionActions.js';
import STOREKEYS from './store/STOREKEYS.js';
-import React, {Component} from 'react';
-import {Route, Router, Redirect, Switch} from './lib/Router';
+import React, { Component } from 'react';
+import { Route, Router, Redirect, Switch } from './lib/Router';
// Initialize the store when the app loads for the first time
StoreInit();
export default class Expensify extends Component {
- constructor(props) {
- super(props);
+ constructor(props) {
+ super(props);
- this.sessionChanged = this.sessionChanged.bind(this);
+ this.sessionChanged = this.sessionChanged.bind(this);
- this.state = {
- redirectTo: null,
- };
- }
+ this.state = {
+ redirectTo: null,
+ };
+ }
- async componentDidMount() {
- // Listen for when the app wants to redirect to a specific URL
- Store.subscribe(STOREKEYS.APP_REDIRECT_TO, (redirectTo) => {
- this.setState({redirectTo});
- });
+ async componentDidMount() {
+ // Listen for when the app wants to redirect to a specific URL
+ Store.subscribe(STOREKEYS.APP_REDIRECT_TO, (redirectTo) => {
+ this.setState({ redirectTo });
+ });
- // Verify that our authToken is OK to use
- verifyAuthToken();
+ // Verify that our authToken is OK to use
+ verifyAuthToken();
- // Initialize this client as being an active client
- await ActiveClientManager.init();
- //TODO: Refactor window events
- // window.addEventListener('beforeunload', () => {
- // ActiveClientManager.removeClient();
- // });
- }
+ // Initialize this client as being an active client
+ await ActiveClientManager.init();
+ //TODO: Refactor window events
+ // window.addEventListener('beforeunload', () => {
+ // ActiveClientManager.removeClient();
+ // });
+ }
- /**
- * When the session changes, change which page the user sees
- *
- * @param {object} newSession
- */
- sessionChanged(newSession) {
- this.setState({isAuthTokenValid: newSession && newSession.authToken});
- }
+ /**
+ * When the session changes, change which page the user sees
+ *
+ * @param {object} newSession
+ */
+ sessionChanged(newSession) {
+ this.setState({ isAuthTokenValid: newSession && newSession.authToken });
+ }
- render() {
- return (
-
- {/* If there is ever a property for redirecting, we do the redirect here */}
- {this.state.redirectTo && }
+ render() {
+ return (
+
+ {/* If there is ever a property for redirecting, we do the redirect here */}
+ {this.state.redirectTo && }
-
-
-
-
-
- );
- }
+
+
+
+
+
+ );
+ }
}
diff --git a/js/ROUTES.js b/js/ROUTES.js
index ca2c73306dbc..26da0e9d0fab 100644
--- a/js/ROUTES.js
+++ b/js/ROUTES.js
@@ -2,6 +2,6 @@
* This is a file containing constants for all of the routes we want to be able to go to
*/
export default {
- SIGNIN: '/signin',
- HOME: '/',
+ SIGNIN: '/signin',
+ HOME: '/',
};
diff --git a/js/config.js b/js/config.js
index 666fae80efe7..5eddf86f8b56 100644
--- a/js/config.js
+++ b/js/config.js
@@ -1,6 +1,6 @@
const CONFIG = {
- PUSHER: {
- APP_KEY: '829fd8fd2a6036568469',
- CLUSTER: 'us3',
- },
+ PUSHER: {
+ APP_KEY: '829fd8fd2a6036568469',
+ CLUSTER: 'us3',
+ },
};
diff --git a/js/lib/ActiveClientManager.js b/js/lib/ActiveClientManager.js
index 1ba3a478aed0..3dfff83993d7 100644
--- a/js/lib/ActiveClientManager.js
+++ b/js/lib/ActiveClientManager.js
@@ -8,20 +8,20 @@ const clientID = Guid();
* Add our client ID to the list of active IDs
*/
const init = async () => {
- const activeClientIDs = (await Store.get(STOREKEYS.ACTIVE_CLIENT_IDS)) || [];
- activeClientIDs.push(clientID);
- Store.set(STOREKEYS.ACTIVE_CLIENT_IDS, activeClientIDs);
+ const activeClientIDs = (await Store.get(STOREKEYS.ACTIVE_CLIENT_IDS)) || [];
+ activeClientIDs.push(clientID);
+ Store.set(STOREKEYS.ACTIVE_CLIENT_IDS, activeClientIDs);
};
/**
* Remove this client ID from the array of active client IDs when this client is exited
*/
function removeClient() {
- const activeClientIDs = Store.get(STOREKEYS.ACTIVE_CLIENT_IDS) || [];
- const newActiveClientIDs = activeClientIDs.filter(
- (activeClientID) => activeClientID !== clientID,
- );
- Store.set(STOREKEYS.ACTIVE_CLIENT_IDS, newActiveClientIDs);
+ const activeClientIDs = Store.get(STOREKEYS.ACTIVE_CLIENT_IDS) || [];
+ const newActiveClientIDs = activeClientIDs.filter(
+ (activeClientID) => activeClientID !== clientID,
+ );
+ Store.set(STOREKEYS.ACTIVE_CLIENT_IDS, newActiveClientIDs);
}
/**
@@ -30,11 +30,11 @@ function removeClient() {
* @returns {boolean}
*/
function isClientTheLeader() {
- const activeClientIDs = Store.get(STOREKEYS.ACTIVE_CLIENT_IDS) || [];
- if (!activeClientIDs.length) {
- return false;
- }
- return activeClientIDs[0] === clientID;
+ const activeClientIDs = Store.get(STOREKEYS.ACTIVE_CLIENT_IDS) || [];
+ if (!activeClientIDs.length) {
+ return false;
+ }
+ return activeClientIDs[0] === clientID;
}
-export {init, removeClient, isClientTheLeader};
+export { init, removeClient, isClientTheLeader };
diff --git a/js/lib/DateUtils.js b/js/lib/DateUtils.js
index f9f9b57c8400..b291d96975dd 100644
--- a/js/lib/DateUtils.js
+++ b/js/lib/DateUtils.js
@@ -11,7 +11,7 @@ import Str from './Str.js';
* @private
*/
function getTimezone() {
- return 'America/Los_Angeles';
+ return 'America/Los_Angeles';
}
/**
@@ -25,9 +25,9 @@ function getTimezone() {
* @private
*/
function getLocalMomentFromTimestamp(timestamp) {
- // We need a default here for flows where we may not have initialized the TIME_ZONE NVP like generatng PDFs in printablereport.php
- const timezone = getTimezone();
- return moment.unix(timestamp).tz(timezone);
+ // We need a default here for flows where we may not have initialized the TIME_ZONE NVP like generatng PDFs in printablereport.php
+ const timezone = getTimezone();
+ return moment.unix(timestamp).tz(timezone);
}
/**
@@ -44,15 +44,15 @@ function getLocalMomentFromTimestamp(timestamp) {
* @returns {String}
*/
function timestampToDateTime(timestamp, includeTimeZone = false) {
- const date = getLocalMomentFromTimestamp(timestamp);
- let format =
- moment().year() !== date.get('year')
- ? 'MMM D, YYYY [at] LT'
- : 'MMM D [at] LT';
- if (includeTimeZone) {
- format = `${format} [UTC]Z`;
- }
- return date.format(format);
+ const date = getLocalMomentFromTimestamp(timestamp);
+ let format =
+ moment().year() !== date.get('year')
+ ? 'MMM D, YYYY [at] LT'
+ : 'MMM D [at] LT';
+ if (includeTimeZone) {
+ format = `${format} [UTC]Z`;
+ }
+ return date.format(format);
}
/**
@@ -73,44 +73,44 @@ function timestampToDateTime(timestamp, includeTimeZone = false) {
* @returns {String}
*/
function timestampToRelative(timestamp) {
- const date = getLocalMomentFromTimestamp(timestamp);
- const durationFromLocalNow = moment.duration(
- date.diff(getLocalMomentFromTimestamp(moment().unix())),
- );
- const round = (num) => Math.floor(Math.abs(num));
+ const date = getLocalMomentFromTimestamp(timestamp);
+ const durationFromLocalNow = moment.duration(
+ date.diff(getLocalMomentFromTimestamp(moment().unix())),
+ );
+ const round = (num) => Math.floor(Math.abs(num));
- if (date.isAfter(moment().subtract(60, 'seconds'))) {
- return '< 1 minute ago';
- }
+ if (date.isAfter(moment().subtract(60, 'seconds'))) {
+ return '< 1 minute ago';
+ }
- if (date.isAfter(moment().subtract(60, 'minutes'))) {
- const minutes = round(durationFromLocalNow.asMinutes());
- return `${minutes} ${Str.pluralize('minute', 'minutes', minutes)} ago`;
- }
+ if (date.isAfter(moment().subtract(60, 'minutes'))) {
+ const minutes = round(durationFromLocalNow.asMinutes());
+ return `${minutes} ${Str.pluralize('minute', 'minutes', minutes)} ago`;
+ }
- if (date.isAfter(moment().subtract(24, 'hours'))) {
- const hours = round(durationFromLocalNow.asHours());
- return `${hours} ${Str.pluralize('hour', 'hours', hours)} ago`;
- }
+ if (date.isAfter(moment().subtract(24, 'hours'))) {
+ const hours = round(durationFromLocalNow.asHours());
+ return `${hours} ${Str.pluralize('hour', 'hours', hours)} ago`;
+ }
- if (date.isAfter(moment().subtract(30, 'days'))) {
- const days = round(durationFromLocalNow.asDays());
- return `${days} ${Str.pluralize('day', 'days', days)} ago`;
- }
+ if (date.isAfter(moment().subtract(30, 'days'))) {
+ const days = round(durationFromLocalNow.asDays());
+ return `${days} ${Str.pluralize('day', 'days', days)} ago`;
+ }
- if (date.isAfter(moment().subtract(1, 'year'))) {
- return date.format('MMM D');
- }
+ if (date.isAfter(moment().subtract(1, 'year'))) {
+ return date.format('MMM D');
+ }
- return date.format('MMM D, YYYY');
+ return date.format('MMM D, YYYY');
}
/**
* @namespace DateUtils
*/
const DateUtils = {
- timestampToRelative,
- timestampToDateTime,
+ timestampToRelative,
+ timestampToDateTime,
};
export default DateUtils;
diff --git a/js/lib/ExpensiMark.js b/js/lib/ExpensiMark.js
index 6492f40b8742..f2b9a6a11a7f 100644
--- a/js/lib/ExpensiMark.js
+++ b/js/lib/ExpensiMark.js
@@ -1,63 +1,63 @@
import Str from './Str.js';
export default class ExpensiMark {
- constructor() {
- /**
- * The list of regex replacements to do on a comment. Check the link regex is first so links are processed
- * before other delimiters
- *
- * @type {Object[]}
- */
- this.rules = [
- {
- name: 'link',
- regex:
- '([_*~]*?)(((?:https?):\\/\\/|www\\.)[^\\s<>*~_"\'´.-][^\\s<>"\'´]*?\\.[a-z\\d]+[^\\s<>*~"\']*)\\1',
- replacement: '$1$2$1',
- },
- {
+ constructor() {
/**
- * Use \b in this case because it will match on words, letters, and _: https://www.rexegg.com/regex-boundaries.html#wordboundary
- * The !_blank is to prevent the `target="_blank">` section of the link replacement from being captured
- * Additionally, something like `\b\_([^<>]*?)\_\b` doesn't work because it won't replace `_https://www.test.com_`
+ * The list of regex replacements to do on a comment. Check the link regex is first so links are processed
+ * before other delimiters
+ *
+ * @type {Object[]}
*/
- name: 'italic',
- regex: '(?!_blank">)\\b\\_(.*?)\\_\\b',
- replacement: '$1',
- },
- {
- // Use \B in this case because \b doesn't match * or ~. \B will match everything that \b doesn't, so it works for * and ~: https://www.rexegg.com/regex-boundaries.html#notb
- name: 'bold',
- regex: '\\B\\*(.*?)\\*\\B',
- replacement: '$1',
- },
- {
- name: 'strikethrough',
- regex: '\\B\\~(.*?)\\~\\B',
- replacement: '$1',
- },
- {
- name: 'newline',
- regex: '\\n',
- replacement: '
',
- },
- ];
- }
+ this.rules = [
+ {
+ name: 'link',
+ regex:
+ '([_*~]*?)(((?:https?):\\/\\/|www\\.)[^\\s<>*~_"\'´.-][^\\s<>"\'´]*?\\.[a-z\\d]+[^\\s<>*~"\']*)\\1',
+ replacement: '$1$2$1',
+ },
+ {
+ /**
+ * Use \b in this case because it will match on words, letters, and _: https://www.rexegg.com/regex-boundaries.html#wordboundary
+ * The !_blank is to prevent the `target="_blank">` section of the link replacement from being captured
+ * Additionally, something like `\b\_([^<>]*?)\_\b` doesn't work because it won't replace `_https://www.test.com_`
+ */
+ name: 'italic',
+ regex: '(?!_blank">)\\b\\_(.*?)\\_\\b',
+ replacement: '$1',
+ },
+ {
+ // Use \B in this case because \b doesn't match * or ~. \B will match everything that \b doesn't, so it works for * and ~: https://www.rexegg.com/regex-boundaries.html#notb
+ name: 'bold',
+ regex: '\\B\\*(.*?)\\*\\B',
+ replacement: '$1',
+ },
+ {
+ name: 'strikethrough',
+ regex: '\\B\\~(.*?)\\~\\B',
+ replacement: '$1',
+ },
+ {
+ name: 'newline',
+ regex: '\\n',
+ replacement: '
',
+ },
+ ];
+ }
- /**
- * Replaces markdown with html elements
- *
- * @param {String} text
- * @returns {String}
- */
- replace(text) {
- // This ensures that any html the user puts into the comment field shows as raw html
- text = Str.safeEscape(text);
+ /**
+ * Replaces markdown with html elements
+ *
+ * @param {String} text
+ * @returns {String}
+ */
+ replace(text) {
+ // This ensures that any html the user puts into the comment field shows as raw html
+ text = Str.safeEscape(text);
- this.rules.forEach((rule) => {
- text = text.replace(new RegExp(rule.regex, 'g'), rule.replacement);
- });
+ this.rules.forEach((rule) => {
+ text = text.replace(new RegExp(rule.regex, 'g'), rule.replacement);
+ });
- return text;
- }
+ return text;
+ }
}
diff --git a/js/lib/Guid.js b/js/lib/Guid.js
index 334e13b8e005..27dd71654e58 100644
--- a/js/lib/Guid.js
+++ b/js/lib/Guid.js
@@ -3,10 +3,10 @@
* @returns {String}
*/
export default function guid() {
- function s4() {
- return Math.floor((1 + Math.random()) * 0x10000)
- .toString(16)
- .substring(1);
- }
- return `${s4()}${s4()}-${s4()}-${s4()}-${s4()}-${s4()}${s4()}${s4()}`;
+ function s4() {
+ return Math.floor((1 + Math.random()) * 0x10000)
+ .toString(16)
+ .substring(1);
+ }
+ return `${s4()}${s4()}-${s4()}-${s4()}-${s4()}-${s4()}${s4()}${s4()}`;
}
diff --git a/js/lib/Network.js b/js/lib/Network.js
index fc3697765e1c..0ff15d7e693b 100644
--- a/js/lib/Network.js
+++ b/js/lib/Network.js
@@ -12,24 +12,24 @@ let isAppOffline = false;
* @returns {$.Deferred}
*/
async function request(command, data, type = 'post') {
- console.debug(`Making "${command}" ${type} request`);
- const formData = new FormData();
- formData.append('authToken', await Store.get('session', 'authToken'));
- for (const property in data) {
- formData.append(property, data[property]);
- }
- try {
- let response = await fetch(
- `https://expensify.com.dev/api?command=${command}`,
- {
- method: type,
- body: formData,
- },
- );
- return await response.json();
- } catch (error) {
- isAppOffline = true;
- }
+ console.debug(`Making "${command}" ${type} request`);
+ const formData = new FormData();
+ formData.append('authToken', await Store.get('session', 'authToken'));
+ for (const property in data) {
+ formData.append(property, data[property]);
+ }
+ try {
+ let response = await fetch(
+ `https://www.expensify.com.dev/api?command=${command}`,
+ {
+ method: type,
+ body: formData,
+ },
+ );
+ return await response.json();
+ } catch (error) {
+ isAppOffline = true;
+ }
}
// Holds a queue of all the write requests that need to happen
@@ -43,49 +43,49 @@ const delayedWriteQueue = [];
* @returns {$.Deferred}
*/
function delayedWrite(command, data, cb) {
- const promise = $.Deferred();
+ const promise = $.Deferred();
- // Add the write request to a queue of actions to perform
- delayedWriteQueue.push({
- command,
- data,
- promise,
- });
+ // Add the write request to a queue of actions to perform
+ delayedWriteQueue.push({
+ command,
+ data,
+ promise,
+ });
- return promise;
+ return promise;
}
/**
* Process the write queue by looping through the queue and attempting to make the requests
*/
function processWriteQueue() {
- if (isAppOffline) {
- // Make a simple request to see if we're online again
- request('Get', null, 'get').done(() => {
- isAppOffline = false;
- });
- return;
- }
+ if (isAppOffline) {
+ // Make a simple request to see if we're online again
+ request('Get', null, 'get').done(() => {
+ isAppOffline = false;
+ });
+ return;
+ }
- if (delayedWriteQueue.length === 0) {
- return;
- }
+ if (delayedWriteQueue.length === 0) {
+ return;
+ }
- for (let i = 0; i < delayedWriteQueue.length; i++) {
- // Take the request object out of the queue and make the request
- const delayedWriteRequest = delayedWriteQueue.shift();
+ for (let i = 0; i < delayedWriteQueue.length; i++) {
+ // Take the request object out of the queue and make the request
+ const delayedWriteRequest = delayedWriteQueue.shift();
- request(delayedWriteRequest.command, delayedWriteRequest.data)
- .done(delayedWriteRequest.promise.resolve)
- .fail(() => {
- // If the request failed, we need to put the request object back into the queue
- delayedWriteQueue.push(delayedWriteRequest);
- });
- }
+ request(delayedWriteRequest.command, delayedWriteRequest.data)
+ .done(delayedWriteRequest.promise.resolve)
+ .fail(() => {
+ // If the request failed, we need to put the request object back into the queue
+ delayedWriteQueue.push(delayedWriteRequest);
+ });
+ }
}
// TODO: Figure out setInterval
// Process our write queue very often
// setInterval(processWriteQueue, 1000);
-export {request, delayedWrite};
+export { request, delayedWrite };
diff --git a/js/lib/PersistentStorage.js b/js/lib/PersistentStorage.js
index 26c8f305ebdb..f5f8b346adcc 100644
--- a/js/lib/PersistentStorage.js
+++ b/js/lib/PersistentStorage.js
@@ -11,12 +11,12 @@ import AsyncStorage from '@react-native-community/async-storage';
* @param {string} key
*/
const get = async (key) => {
- try {
- const jsonValue = await AsyncStorage.getItem(key);
- return jsonValue != null ? JSON.parse(jsonValue) : null;
- } catch (e) {
- console.error(`Could not parse value from local storage. Key: ${key}`);
- }
+ try {
+ const jsonValue = await AsyncStorage.getItem(key);
+ return jsonValue != null ? JSON.parse(jsonValue) : null;
+ } catch (e) {
+ console.error(`Could not parse value from local storage. Key: ${key}`);
+ }
};
/**
@@ -26,14 +26,14 @@ const get = async (key) => {
* @param {mixed} val
*/
const set = async (key, val) => {
- await AsyncStorage.setItem(key, JSON.stringify(val));
+ await AsyncStorage.setItem(key, JSON.stringify(val));
};
/**
* Empty out the storage (like when the user signs out)
*/
const clear = async () => {
- await AsyncStorage.clear();
+ await AsyncStorage.clear();
};
-export {get, set, clear};
+export { get, set, clear };
diff --git a/js/lib/Router/index.js b/js/lib/Router/index.js
index e5a9aba68667..abe10c4aa5c6 100644
--- a/js/lib/Router/index.js
+++ b/js/lib/Router/index.js
@@ -1,11 +1,11 @@
import {
- BrowserRouter as Router,
- Link,
- Route,
- Redirect,
- Switch,
- withRouter,
+ BrowserRouter as Router,
+ Link,
+ Route,
+ Redirect,
+ Switch,
+ withRouter,
} from 'react-router-dom';
-export default {Link, Route, Redirect, Router, Switch, withRouter};
-export {Link, Route, Redirect, Router, Switch, withRouter};
+export default { Link, Route, Redirect, Router, Switch, withRouter };
+export { Link, Route, Redirect, Router, Switch, withRouter };
diff --git a/js/lib/Router/index.native.js b/js/lib/Router/index.native.js
index 9fa3bfbe78a9..9b8bd03726c1 100644
--- a/js/lib/Router/index.native.js
+++ b/js/lib/Router/index.native.js
@@ -1,11 +1,11 @@
import {
- NativeRouter as Router,
- Link,
- Route,
- Redirect,
- Switch,
- withRouter,
+ NativeRouter as Router,
+ Link,
+ Route,
+ Redirect,
+ Switch,
+ withRouter,
} from 'react-router-native';
-export default {Link, Route, Redirect, Router, Switch, withRouter};
-export {Link, Route, Redirect, Router, Switch, withRouter};
+export default { Link, Route, Redirect, Router, Switch, withRouter };
+export { Link, Route, Redirect, Router, Switch, withRouter };
diff --git a/js/lib/Str.js b/js/lib/Str.js
index a70b15a6cddd..d8660585d8c1 100644
--- a/js/lib/Str.js
+++ b/js/lib/Str.js
@@ -1,54 +1,54 @@
/* globals $, _ */
const Str = {
- /**
- * Returns the proper phrase depending on the count that is passed.
- * Example:
- * console.log(Str.pluralize('puppy', 'puppies', 1)); // puppy
- * console.log(Str.pluralize('puppy', 'puppies', 3)); // puppies
- *
- * @param {String} singular form of the phrase
- * @param {String} plural form of the phrase
- * @param {Number} n the count which determines the plurality
- *
- * @return {String}
- */
- pluralize(singular, plural, n) {
- if (!n || n > 1) {
- return plural;
- }
- return singular;
- },
+ /**
+ * Returns the proper phrase depending on the count that is passed.
+ * Example:
+ * console.log(Str.pluralize('puppy', 'puppies', 1)); // puppy
+ * console.log(Str.pluralize('puppy', 'puppies', 3)); // puppies
+ *
+ * @param {String} singular form of the phrase
+ * @param {String} plural form of the phrase
+ * @param {Number} n the count which determines the plurality
+ *
+ * @return {String}
+ */
+ pluralize(singular, plural, n) {
+ if (!n || n > 1) {
+ return plural;
+ }
+ return singular;
+ },
- /**
- * Escape text while preventing any sort of double escape, so 'X & Y' -> 'X & Y' and 'X & Y' -> 'X & Y'
- *
- * @param {String} s the string to escape
- * @return {String} the escaped string
- */
- safeEscape(s) {
- return _.escape(_.unescape(s));
- },
+ /**
+ * Escape text while preventing any sort of double escape, so 'X & Y' -> 'X & Y' and 'X & Y' -> 'X & Y'
+ *
+ * @param {String} s the string to escape
+ * @return {String} the escaped string
+ */
+ safeEscape(s) {
+ return _.escape(_.unescape(s));
+ },
- /**
- * Decodes the given HTML encoded string.
- *
- * @param {String} s The string to decode.
- * @return {String} The decoded string.
- */
- htmlDecode(s) {
- return $('').html(s).text();
- },
+ /**
+ * Decodes the given HTML encoded string.
+ *
+ * @param {String} s The string to decode.
+ * @return {String} The decoded string.
+ */
+ htmlDecode(s) {
+ return $('').html(s).text();
+ },
- /**
- * Convert new line to
- *
- * @param {String} str
- * @returns {string}
- */
- nl2br(str) {
- return str.replace(/\n/g, '
');
- },
+ /**
+ * Convert new line to
+ *
+ * @param {String} str
+ * @returns {string}
+ */
+ nl2br(str) {
+ return str.replace(/\n/g, '
');
+ },
};
export default Str;
diff --git a/js/page/HomePage/HomePage.js b/js/page/HomePage/HomePage.js
index b30119c0f302..46d8753ba15f 100644
--- a/js/page/HomePage/HomePage.js
+++ b/js/page/HomePage/HomePage.js
@@ -3,40 +3,40 @@
* @flow strict-local
*/
-import React, {Component} from 'react';
-import {SafeAreaView, Text, StatusBar, View, Button} from 'react-native';
-import {signOut} from '../../store/actions/SessionActions';
+import React, { Component } from 'react';
+import { SafeAreaView, Text, StatusBar, View, Button } from 'react-native';
+import { signOut } from '../../store/actions/SessionActions';
export default class App extends Component {
- constructor(props) {
- super(props);
+ constructor(props) {
+ super(props);
- this.signOut = this.signOut.bind(this);
- }
+ this.signOut = this.signOut.bind(this);
+ }
- async signOut() {
- await signOut();
- }
+ async signOut() {
+ await signOut();
+ }
- render() {
- return (
- <>
-
-
-
-
- {'React Native Chat Homepage!'}
-
-
-
-
- >
- );
- }
+ render() {
+ return (
+ <>
+
+
+
+
+ {'React Native Chat Homepage!'}
+
+
+
+
+ >
+ );
+ }
}
diff --git a/js/page/SignInPage.js b/js/page/SignInPage.js
index bdc685e3c6cb..7456ed7a0978 100644
--- a/js/page/SignInPage.js
+++ b/js/page/SignInPage.js
@@ -3,85 +3,85 @@
* @flow strict-local
*/
-import React, {Component} from 'react';
+import React, { Component } from 'react';
import {
- SafeAreaView,
- Text,
- StatusBar,
- Button,
- TextInput,
- View,
+ SafeAreaView,
+ Text,
+ StatusBar,
+ Button,
+ TextInput,
+ View,
} from 'react-native';
import * as Store from '../store/Store.js';
-import {signIn} from '../store/actions/SessionActions.js';
+import { signIn } from '../store/actions/SessionActions.js';
import STOREKEYS from '../store/STOREKEYS.js';
export default class App extends Component {
- constructor(props) {
- super(props);
+ constructor(props) {
+ super(props);
- this.submit = this.submit.bind(this);
- this.sessionChanged = this.sessionChanged.bind(this);
+ this.submit = this.submit.bind(this);
+ this.sessionChanged = this.sessionChanged.bind(this);
- this.state = {
- login: 'andrew@expensify.com',
- password: 'Password1',
- error: Store.get(STOREKEYS.SESSION, 'error'),
- };
- }
+ this.state = {
+ login: '',
+ password: '',
+ error: Store.get(STOREKEYS.SESSION, 'error'),
+ };
+ }
- componentDidMount() {
- // Listen for changes to our session
- Store.subscribe(STOREKEYS.SESSION, this.sessionChanged);
- }
+ componentDidMount() {
+ // Listen for changes to our session
+ Store.subscribe(STOREKEYS.SESSION, this.sessionChanged);
+ }
- componentWillUnmount() {
- Store.unsubscribe(STOREKEYS.SESSION, this.sessionChanged);
- }
+ componentWillUnmount() {
+ Store.unsubscribe(STOREKEYS.SESSION, this.sessionChanged);
+ }
- /**
- * When the session changes, change which page the user sees
- *
- * @param {object} newSession
- */
- sessionChanged(newSession) {
- this.setState({error: newSession && newSession.error});
- }
+ /**
+ * When the session changes, change which page the user sees
+ *
+ * @param {object} newSession
+ */
+ sessionChanged(newSession) {
+ this.setState({ error: newSession && newSession.error });
+ }
- /**
- * When the form is submitted, then we trigger our prop callback
- */
- submit() {
- signIn(this.state.login, this.state.password);
- }
+ /**
+ * When the form is submitted, then we trigger our prop callback
+ */
+ submit() {
+ signIn(this.state.login, this.state.password);
+ }
- render() {
- return (
- <>
-
-
-
- Login:
- this.setState({login: text})}
- />
-
-
- Password:
- this.setState({password: text})}
- />
-
-
-
-
-
- >
- );
- }
+ render() {
+ return (
+ <>
+
+
+
+ Login:
+ this.setState({ login: text })}
+ />
+
+
+ Password:
+ this.setState({ password: text })}
+ />
+
+
+
+
+
+ >
+ );
+ }
}
diff --git a/js/store/STOREKEYS.js b/js/store/STOREKEYS.js
index ac06965f41f4..c78b0577ff59 100644
--- a/js/store/STOREKEYS.js
+++ b/js/store/STOREKEYS.js
@@ -2,12 +2,12 @@
* This is a file containing constants for all the top level keys in our store
*/
export default {
- ACTIVE_CLIENT_IDS: 'activeClientIDs',
- APP_REDIRECT_TO: 'app_redirectTo',
- CREDENTIALS: 'credentials',
- REPORT: 'report',
- ACTIVE_REPORT: 'active_report',
- REPORTS: 'reports',
- SESSION: 'session',
- LAST_AUTHENTICATED: 'last_authenticated',
+ ACTIVE_CLIENT_IDS: 'activeClientIDs',
+ APP_REDIRECT_TO: 'app_redirectTo',
+ CREDENTIALS: 'credentials',
+ REPORT: 'report',
+ ACTIVE_REPORT: 'active_report',
+ REPORTS: 'reports',
+ SESSION: 'session',
+ LAST_AUTHENTICATED: 'last_authenticated',
};
diff --git a/js/store/Store.js b/js/store/Store.js
index cbee5f564963..695a0e64a52c 100644
--- a/js/store/Store.js
+++ b/js/store/Store.js
@@ -8,15 +8,15 @@ const callbackMapping = {};
* Initialize the store with actions and listening for storage events
*/
function init() {
- // Subscribe to the storage event so changes to local storage can be captured
- //TODO: Refactor window events
- // window.addEventListener('storage', (e) => {
- // try {
- // keyChanged(e.key, JSON.parse(e.newValue));
- // } catch (e) {
- // console.error(`Could not parse value from local storage. Key: ${e.key}`);
- // }
- // });
+ // Subscribe to the storage event so changes to local storage can be captured
+ //TODO: Refactor window events
+ // window.addEventListener('storage', (e) => {
+ // try {
+ // keyChanged(e.key, JSON.parse(e.newValue));
+ // } catch (e) {
+ // console.error(`Could not parse value from local storage. Key: ${e.key}`);
+ // }
+ // });
}
/**
@@ -26,10 +26,10 @@ function init() {
* @param {function} cb
*/
function subscribe(keyPattern, cb) {
- if (!callbackMapping[keyPattern]) {
- callbackMapping[keyPattern] = [];
- }
- callbackMapping[keyPattern].push(cb);
+ if (!callbackMapping[keyPattern]) {
+ callbackMapping[keyPattern] = [];
+ }
+ callbackMapping[keyPattern].push(cb);
}
/**
@@ -39,12 +39,12 @@ function subscribe(keyPattern, cb) {
* @param {function} cb
*/
function unsubscribe(keyPattern, cb) {
- if (!callbackMapping[keyPattern] || !callbackMapping[keyPattern].length) {
- return;
- }
- callbackMapping[keyPattern] = callbackMapping[keyPattern].filter(
- (existingCallback) => existingCallback !== cb,
- );
+ if (!callbackMapping[keyPattern] || !callbackMapping[keyPattern].length) {
+ return;
+ }
+ callbackMapping[keyPattern] = callbackMapping[keyPattern].filter(
+ (existingCallback) => existingCallback !== cb,
+ );
}
/**
@@ -54,18 +54,18 @@ function unsubscribe(keyPattern, cb) {
* @param {mixed} data
*/
function keyChanged(key, data) {
- for (const [keyPattern, callbacks] of Object.entries(callbackMapping)) {
- const regex = RegExp(keyPattern);
+ for (const [keyPattern, callbacks] of Object.entries(callbackMapping)) {
+ const regex = RegExp(keyPattern);
- // If there is a callback whose regex matches the key that was changed, then the callback for that regex
- // is called and passed the data that changed
- if (regex.test(key)) {
- for (let i = 0; i < callbacks.length; i++) {
- const callback = callbacks[i];
- callback(data);
- }
+ // If there is a callback whose regex matches the key that was changed, then the callback for that regex
+ // is called and passed the data that changed
+ if (regex.test(key)) {
+ for (let i = 0; i < callbacks.length; i++) {
+ const callback = callbacks[i];
+ callback(data);
+ }
+ }
}
- }
}
/**
@@ -75,12 +75,12 @@ function keyChanged(key, data) {
* @param {mixed} val
*/
function set(key, val) {
- // Write the thing to local storage, which will trigger a storage event for any other tabs open on this domain
- PersistentStorage.set(key, val);
+ // Write the thing to local storage, which will trigger a storage event for any other tabs open on this domain
+ PersistentStorage.set(key, val);
- // The storage event doesn't trigger for the current window, so just call keyChanged() manually to mimic
- // the storage event
- keyChanged(key, val);
+ // The storage event doesn't trigger for the current window, so just call keyChanged() manually to mimic
+ // the storage event
+ keyChanged(key, val);
}
/**
@@ -93,11 +93,11 @@ function set(key, val) {
* @returns {*}
*/
const get = async (key, extraPath, defaultValue) => {
- const val = await PersistentStorage.get(key);
- if (extraPath) {
- return _.get(val, extraPath, defaultValue);
- }
- return val;
+ const val = await PersistentStorage.get(key);
+ if (extraPath) {
+ return _.get(val, extraPath, defaultValue);
+ }
+ return val;
};
-export {subscribe, unsubscribe, set, get, init};
+export { subscribe, unsubscribe, set, get, init };
diff --git a/js/store/actions/ReportActions.js b/js/store/actions/ReportActions.js
index 6b03c2aecec7..88f9ea8f211c 100644
--- a/js/store/actions/ReportActions.js
+++ b/js/store/actions/ReportActions.js
@@ -1,6 +1,6 @@
/* globals moment */
import * as Store from '../Store.js';
-import {request, delayedWrite} from '../../lib/Network.js';
+import { request, delayedWrite } from '../../lib/Network.js';
import STOREKEYS from '../STOREKEYS.js';
import ExpensiMark from '../../lib/ExpensiMark.js';
import Guid from '../../lib/Guid.js';
@@ -9,42 +9,42 @@ import Guid from '../../lib/Guid.js';
* Get all of our reports
*/
function fetchAll() {
- request('Get', {
- returnValueList: 'reportListBeta',
- sortBy: 'starred',
- offset: 0,
- limit: 10,
- }).done((data) => {
- Store.set(STOREKEYS.REPORTS, data.reportListBeta);
- });
+ request('Get', {
+ returnValueList: 'reportListBeta',
+ sortBy: 'starred',
+ offset: 0,
+ limit: 10,
+ }).done((data) => {
+ Store.set(STOREKEYS.REPORTS, data.reportListBeta);
+ });
}
/**
* Get a single report
*/
function fetch(reportID) {
- request('Get', {
- returnValueList: 'reportStuff',
- reportIDList: reportID,
- shouldLoadOptionalKeys: true,
- }).done((data) => {
- Store.set(`${STOREKEYS.REPORT}_${reportID}`, data.reports[reportID]);
- });
+ request('Get', {
+ returnValueList: 'reportStuff',
+ reportIDList: reportID,
+ shouldLoadOptionalKeys: true,
+ }).done((data) => {
+ Store.set(`${STOREKEYS.REPORT}_${reportID}`, data.reports[reportID]);
+ });
}
/**
* Get the comments of a report
*/
function fetchComments(reportID) {
- request('Report_GetHistory', {
- reportID: reportID,
- offset: 0,
- }).done((data) => {
- const sortedData = data.history.sort(
- (a, b) => a.sequenceNumber - b.sequenceNumber,
- );
- Store.set(`${STOREKEYS.REPORT}_${reportID}_comments`, sortedData);
- });
+ request('Report_GetHistory', {
+ reportID: reportID,
+ offset: 0,
+ }).done((data) => {
+ const sortedData = data.history.sort(
+ (a, b) => a.sequenceNumber - b.sequenceNumber,
+ );
+ Store.set(`${STOREKEYS.REPORT}_${reportID}_comments`, sortedData);
+ });
}
/**
@@ -53,67 +53,67 @@ function fetchComments(reportID) {
* @param {string} commentText
*/
function addComment(reportID, commentText) {
- const messageParser = new ExpensiMark();
- const comments = Store.get(`${STOREKEYS.REPORT}_${reportID}_comments`);
- const newSequenceNumber =
- comments.length === 0
- ? 1
- : comments[comments.length - 1].sequenceNumber + 1;
- const guid = Guid();
+ const messageParser = new ExpensiMark();
+ const comments = Store.get(`${STOREKEYS.REPORT}_${reportID}_comments`);
+ const newSequenceNumber =
+ comments.length === 0
+ ? 1
+ : comments[comments.length - 1].sequenceNumber + 1;
+ const guid = Guid();
- // Optimistically add the new comment to the store before waiting to save it to the server
- Store.set(`${STOREKEYS.REPORT}_${reportID}_comments`, [
- ...comments,
- {
- tempGuid: guid,
- actionName: 'ADDCOMMENT',
- actorEmail: Store.get(STOREKEYS.SESSION, 'email'),
- person: [
+ // Optimistically add the new comment to the store before waiting to save it to the server
+ Store.set(`${STOREKEYS.REPORT}_${reportID}_comments`, [
+ ...comments,
{
- style: 'strong',
- text: '',
- // text: this.props.userDisplayName,
- type: 'TEXT',
+ tempGuid: guid,
+ actionName: 'ADDCOMMENT',
+ actorEmail: Store.get(STOREKEYS.SESSION, 'email'),
+ person: [
+ {
+ style: 'strong',
+ text: '',
+ // text: this.props.userDisplayName,
+ type: 'TEXT',
+ },
+ ],
+ automatic: false,
+ sequenceNumber: newSequenceNumber,
+ avatar: '',
+ // avatar: this.props.userAvatar,
+ timestamp: moment.unix(),
+ message: [
+ {
+ type: 'COMMENT',
+ html: messageParser.replace(commentText),
+ text: commentText,
+ },
+ ],
+ isFirstItem: false,
+ isAttachmentPlaceHolder: false,
},
- ],
- automatic: false,
- sequenceNumber: newSequenceNumber,
- avatar: '',
- // avatar: this.props.userAvatar,
- timestamp: moment.unix(),
- message: [
- {
- type: 'COMMENT',
- html: messageParser.replace(commentText),
- text: commentText,
- },
- ],
- isFirstItem: false,
- isAttachmentPlaceHolder: false,
- },
- ]);
+ ]);
- delayedWrite('Report_AddComment', {
- reportID: reportID,
- reportComment: commentText,
- }).done(() => {
- // When the delayed write is finished, we find the optimistic comment that was added to the store
- // and remove it's tempGuid because we know it's been written to the server
- const comments =
- Store.get(`${STOREKEYS.REPORT}_${reportID}_comments`) || [];
- Store.set(
- `${STOREKEYS.REPORT}_${reportID}_comments`,
- comments.map((comment) => {
- if (comment.tempGuid && comment.tempGuid === guid) {
- return {
- ...comment,
- tempGuid: null,
- };
- }
- return comment;
- }),
- );
- });
+ delayedWrite('Report_AddComment', {
+ reportID: reportID,
+ reportComment: commentText,
+ }).done(() => {
+ // When the delayed write is finished, we find the optimistic comment that was added to the store
+ // and remove it's tempGuid because we know it's been written to the server
+ const comments =
+ Store.get(`${STOREKEYS.REPORT}_${reportID}_comments`) || [];
+ Store.set(
+ `${STOREKEYS.REPORT}_${reportID}_comments`,
+ comments.map((comment) => {
+ if (comment.tempGuid && comment.tempGuid === guid) {
+ return {
+ ...comment,
+ tempGuid: null,
+ };
+ }
+ return comment;
+ }),
+ );
+ });
}
-export {fetchAll, fetch, fetchComments, addComment};
+export { fetchAll, fetch, fetchComments, addComment };
diff --git a/js/store/actions/SessionActions.js b/js/store/actions/SessionActions.js
index f45f213e3d29..b34e57a9e47b 100644
--- a/js/store/actions/SessionActions.js
+++ b/js/store/actions/SessionActions.js
@@ -1,5 +1,5 @@
import * as Store from '../Store.js';
-import {request} from '../../lib/Network.js';
+import { request } from '../../lib/Network.js';
import ROUTES from '../../ROUTES.js';
import STOREKEYS from '../STOREKEYS.js';
import * as PersistentStorage from '../../lib/PersistentStorage.js';
@@ -9,8 +9,8 @@ import * as _ from 'lodash';
const IS_IN_PRODUCTION = false;
const partnerName = IS_IN_PRODUCTION ? 'chat-expensify-com' : 'android';
const partnerPassword = IS_IN_PRODUCTION
- ? 'e21965746fd75f82bb66'
- : 'c3a9ac418ea3f152aae2';
+ ? 'e21965746fd75f82bb66'
+ : 'c3a9ac418ea3f152aae2';
/**
* Amount of time (in ms) after which an authToken is considered expired.
@@ -28,43 +28,47 @@ const AUTH_TOKEN_EXPIRATION_TIME = 1000 * 60;
* @param {boolean} useExpensifyLogin
*/
function signIn(login, password, useExpensifyLogin = false) {
- Store.set(STOREKEYS.CREDENTIALS, {login, password});
- Store.set(STOREKEYS.SESSION, {});
- return request('Authenticate', {
- useExpensifyLogin: useExpensifyLogin,
- partnerName: partnerName,
- partnerPassword: partnerPassword,
- partnerUserID: login,
- partnerUserSecret: password,
- })
- .then((data) => {
- // 404 We need to create a login
- if (data.jsonCode === 404 && !useExpensifyLogin) {
- signIn(login, password, true).then((expensifyLoginData) => {
- createLogin(expensifyLoginData.authToken, login, password);
- });
- return;
- }
+ Store.set(STOREKEYS.CREDENTIALS, { login, password });
+ Store.set(STOREKEYS.SESSION, {});
+ return request('Authenticate', {
+ useExpensifyLogin: useExpensifyLogin,
+ partnerName: partnerName,
+ partnerPassword: partnerPassword,
+ partnerUserID: login,
+ partnerUserSecret: password,
+ })
+ .then((data) => {
+ // 404 We need to create a login
+ if (data.jsonCode === 404 && !useExpensifyLogin) {
+ signIn(login, password, true).then((expensifyLoginData) => {
+ createLogin(expensifyLoginData.authToken, login, password);
+ });
+ return;
+ }
- // If we didn't get a 200 response from authenticate, the user needs to sign in again
- if (data.jsonCode !== 200) {
- console.warn(
- 'Did not get a 200 from authenticate, going back to sign in page',
- );
- Store.set(STOREKEYS.APP_REDIRECT_TO, ROUTES.SIGNIN);
- return;
- }
+ // If we didn't get a 200 response from authenticate, the user needs to sign in again
+ if (data.jsonCode !== 200) {
+ console.warn(
+ 'Did not get a 200 from authenticate, going back to sign in page',
+ );
+ Store.set(STOREKEYS.APP_REDIRECT_TO, ROUTES.SIGNIN);
+ return;
+ }
- Store.set(STOREKEYS.SESSION, data);
- Store.set(STOREKEYS.APP_REDIRECT_TO, ROUTES.HOME);
- Store.set(STOREKEYS.LAST_AUTHENTICATED, new Date().getTime());
+ Store.set(STOREKEYS.SESSION, data);
+ Store.set(STOREKEYS.APP_REDIRECT_TO, ROUTES.HOME);
+ Store.set(STOREKEYS.LAST_AUTHENTICATED, new Date().getTime());
- return data;
- })
- .catch((err) => {
- console.warn(err);
- Store.set(STOREKEYS.SESSION, {error: err});
- });
+ return data;
+ })
+ .then((data) => {
+ Store.set(STOREKEYS.SESSION, data);
+ Store.set(STOREKEYS.APP_REDIRECT_TO, ROUTES.HOME);
+ })
+ .catch((err) => {
+ console.warn(err);
+ Store.set(STOREKEYS.SESSION, { error: err });
+ });
}
/**
@@ -74,51 +78,51 @@ function signIn(login, password, useExpensifyLogin = false) {
* @param {string} password
*/
function createLogin(authToken, login, password) {
- request('CreateLogin', {
- authToken: authToken,
- partnerName,
- partnerPassword,
- partnerUserID: login,
- partnerUserSecret: password,
- }).catch((err) => {
- Store.set(STOREKEYS.SESSION, {error: err});
- });
+ request('CreateLogin', {
+ authToken: authToken,
+ partnerName,
+ partnerPassword,
+ partnerUserID: login,
+ partnerUserSecret: password,
+ }).catch((err) => {
+ Store.set(STOREKEYS.SESSION, { error: err });
+ });
}
/**
* Sign out of our application
*/
async function signOut() {
- Store.set(STOREKEYS.APP_REDIRECT_TO, ROUTES.SIGNIN);
- await PersistentStorage.clear();
+ Store.set(STOREKEYS.APP_REDIRECT_TO, ROUTES.SIGNIN);
+ await PersistentStorage.clear();
}
/**
* Make sure the authToken we have is OK to use
*/
async function verifyAuthToken() {
- const lastAuthenticated = await Store.get(STOREKEYS.LAST_AUTHENTICATED);
- const credentials = await Store.get(STOREKEYS.CREDENTIALS);
- const haveCredentials = !_.isNull(credentials);
- const haveExpiredAuthToken =
- lastAuthenticated < new Date().getTime() - AUTH_TOKEN_EXPIRATION_TIME;
+ const lastAuthenticated = await Store.get(STOREKEYS.LAST_AUTHENTICATED);
+ const credentials = await Store.get(STOREKEYS.CREDENTIALS);
+ const haveCredentials = !_.isNull(credentials);
+ const haveExpiredAuthToken =
+ lastAuthenticated < new Date().getTime() - AUTH_TOKEN_EXPIRATION_TIME;
- if (haveExpiredAuthToken && haveCredentials) {
- console.debug('Invalid auth token: Token has expired.');
- signIn(credentials.login, credentials.password);
- return;
- }
-
- request('Get', {returnValueList: 'account'}).then((data) => {
- if (data.jsonCode === 200) {
- console.debug('We have valid auth token');
- Store.set(STOREKEYS.SESSION, data);
- return;
+ if (haveExpiredAuthToken && haveCredentials) {
+ console.debug('Invalid auth token: Token has expired.');
+ signIn(credentials.login, credentials.password);
+ return;
}
- // If the auth token is bad and we didn't have credentials saved, we want them to go to the sign in page
- Store.set(STOREKEYS.APP_REDIRECT_TO, ROUTES.SIGNIN);
- });
+ request('Get', { returnValueList: 'account' }).then((data) => {
+ if (data.jsonCode === 200) {
+ console.debug('We have valid auth token');
+ Store.set(STOREKEYS.SESSION, data);
+ return;
+ }
+
+ // If the auth token is bad and we didn't have credentials saved, we want them to go to the sign in page
+ Store.set(STOREKEYS.APP_REDIRECT_TO, ROUTES.SIGNIN);
+ });
}
-export {signIn, signOut, verifyAuthToken};
+export { signIn, signOut, verifyAuthToken };
diff --git a/src/index.js b/src/index.js
index 3b80c5a5af18..997587c50140 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,8 +1,8 @@
-import {AppRegistry} from 'react-native';
+import { AppRegistry } from 'react-native';
import App from '../js/App';
AppRegistry.registerComponent('App', () => App);
AppRegistry.runApplication('App', {
- rootTag: document.getElementById('root'),
+ rootTag: document.getElementById('root'),
});