pull/4/head
bitpshr 5 years ago
parent 9e156db44b
commit e64123427b
  1. 3
      .babelrc
  2. 67
      .flowconfig
  3. 23
      .gitignore
  4. 7
      .prettierignore
  5. 10
      .travis.yml
  6. 1
      .watchmanconfig
  7. 49
      App.js
  8. 20
      LICENSE
  9. 30
      README.md
  10. 4
      app/common/testSetup.js
  11. 43
      app/components/App/__snapshots__/index.test.js.snap
  12. 11
      app/components/App/index.js
  13. 10
      app/components/App/index.test.js
  14. 120
      app/components/Browser/__snapshots__/index.test.js.snap
  15. 157
      app/components/Browser/index.js
  16. 75
      app/components/Browser/index.test.js
  17. 10
      app/components/BrowserScreen/__snapshots__/index.test.js.snap
  18. 7
      app/components/BrowserScreen/index.js
  19. 10
      app/components/BrowserScreen/index.test.js
  20. 42
      app/components/Screen/__snapshots__/index.test.js.snap
  21. 58
      app/components/Screen/index.js
  22. 15
      app/components/Screen/index.test.js
  23. 12
      app/styles/common.js
  24. 6
      index.js
  25. BIN
      logo.png
  26. 2476
      package-lock.json
  27. 85
      package.json

@ -1,3 +0,0 @@
{
"presets": ["react-native"]
}

@ -1,67 +0,0 @@
[ignore]
; We fork some components by platform
.*/*[.]android.js
; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/
; Ignore unexpected extra "@providesModule"
.*/node_modules/.*/node_modules/fbjs/.*
; Ignore duplicate module providers
; For RN Apps installed via npm, "Libraries" folder is inside
; "node_modules/react-native" but in the source repo it is in the root
.*/Libraries/react-native/React.js
; Ignore polyfills
.*/Libraries/polyfills/.*
; Ignore metro
.*/node_modules/metro/.*
[include]
[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow/
node_modules/react-native/flow-github/
[options]
emoji=true
module.system=haste
module.system.haste.use_name_reducers=true
# get basename
module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1'
# strip .js or .js.flow suffix
module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1'
# strip .ios suffix
module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1'
module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1'
module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1'
module.system.haste.paths.blacklist=.*/__tests__/.*
module.system.haste.paths.blacklist=.*/__mocks__/.*
module.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/Animated/src/polyfills/.*
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/Libraries/.*
munge_underscores=true
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
module.file_ext=.js
module.file_ext=.jsx
module.file_ext=.json
module.file_ext=.native.js
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
[version]
^0.75.0

23
.gitignore vendored

@ -1,9 +1,7 @@
# OSX
#
# osx
.DS_Store
# Xcode
#
# xcode
build/
*.pbxuser
!default.pbxuser
@ -22,8 +20,7 @@ DerivedData
*.xcuserstate
project.xcworkspace
# Android/IntelliJ
#
# android / intellij
build/
.idea
.gradle
@ -31,26 +28,22 @@ local.properties
*.iml
# node.js
#
node_modules/
npm-debug.log
yarn-error.log
# BUCK
# buck
buck-out/
\.buckd/
*.keystore
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/
*/fastlane/report.xml
*/fastlane/Preview.html
*/fastlane/screenshots
# Bundle artifact
# bundle artifact
*.jsbundle
# testing
coverage

@ -0,0 +1,7 @@
__snapshots__
android
coverage
ios
node_modules
package-lock.json
package.json

@ -0,0 +1,10 @@
language: node_js
node_js: "node"
install:
- travis_retry npm install -g codecov
- travis_retry npm install
script:
- npm run prettier
- npm run lint
- npm run test
- codecov

@ -1,49 +0,0 @@
import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import { createBottomTabNavigator } from 'react-navigation';
import BrowserView from './app/components/BrowserView'
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
android:
'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
class App extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Bar!</Text>
<Text style={styles.instructions}>To get started, edit App.js</Text>
<Text style={styles.instructions}>{instructions}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
export default createBottomTabNavigator({
Home: {
screen: BrowserView
},
});

@ -0,0 +1,20 @@
MIT License
Copyright (c) 2018 MetaMask
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

@ -1,9 +1,21 @@
- [ ] i18n
- [ ] design systems
- [ ] android
- [ ] ci
- [ ] integration testing
- [ ] repo structure
- [ ] documentation
- [ ] changelog
- [ ] enable http (not just https)
![Melfina logo](logo.png?raw=true)
MetaMask is mobile web browser that provides easy access to websites that use the [Ethereum](https://ethereum.org/) blockchain.
[http://metamask.io/](http://metamask.io/)
[![Build Status](https://travis-ci.org/bitpshr/MetaMask.svg?branch=master)](https://travis-ci.org/bitpshr/MetaMask)
[![codecov](https://codecov.io/gh/bitpshr/MetaMask/branch/master/graph/badge.svg)](https://codecov.io/gh/bitpshr/MetaMask)
## Development
The following instructions assume that the React Native [Getting Started](https://facebook.github.io/react-native/docs/getting-started.html) guide for your platform has been completed.
```
$ npm i
$ react-native run-ios
```
## License
[MIT](./LICENSE)

@ -0,0 +1,4 @@
import Adapter from 'enzyme-adapter-react-16';
import Enzyme from 'enzyme';
Enzyme.configure({ adapter: new Adapter() });

@ -0,0 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`App should render correctly 1`] = `
<Navigator
navigation={
Object {
"actions": Object {},
"addListener": [Function],
"dangerouslyGetParent": [Function],
"dispatch": [Function],
"getChildNavigation": [Function],
"getScreenProps": [Function],
"goBack": [Function],
"isFocused": [Function],
"navigate": [Function],
"router": Object {
"childRouters": Object {
"Home": null,
},
"getActionCreators": [Function],
"getActionForPathAndParams": [Function],
"getComponentForRouteName": [Function],
"getComponentForState": [Function],
"getPathAndParamsForState": [Function],
"getScreenOptions": [Function],
"getStateForAction": [Function],
},
"setParams": [Function],
"state": Object {
"index": 0,
"isTransitioning": false,
"routes": Array [
Object {
"key": "Home",
"params": undefined,
"routeName": "Home",
},
],
},
}
}
/>
`;

@ -0,0 +1,11 @@
import { createBottomTabNavigator } from 'react-navigation';
import BrowserScreen from '../BrowserScreen';
/**
* Root application component responsible for configurating the tab navigator
*/
export default createBottomTabNavigator({
Home: {
screen: BrowserScreen
}
});

@ -0,0 +1,10 @@
import React from 'react';
import { shallow } from 'enzyme';
import App from './';
describe('App', () => {
it('should render correctly', () => {
const wrapper = shallow(<App />);
expect(wrapper).toMatchSnapshot();
});
});

@ -0,0 +1,120 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Browser should render correctly 1`] = `
<Component
style={
Object {
"flex": 1,
}
}
>
<Component
style={
Object {
"alignItems": "stretch",
"backgroundColor": "#f1f2f6",
"flexDirection": "row",
"paddingVertical": 8,
}
}
>
<Icon
allowFontScaling={false}
disabled={true}
name="angle-left"
onPress={[Function]}
size={30}
style={
Object {
"color": "#ced6e0",
"flex": 0,
"height": 28,
"lineHeight": 28,
"paddingTop": 2,
"textAlign": "center",
"width": 36,
}
}
/>
<Icon
allowFontScaling={false}
disabled={true}
name="angle-right"
onPress={[Function]}
size={30}
style={
Object {
"color": "#ced6e0",
"flex": 0,
"height": 28,
"lineHeight": 28,
"paddingTop": 2,
"textAlign": "center",
"width": 36,
}
}
/>
<TextInput
allowFontScaling={true}
autoCapitalize="none"
autoCorrect={false}
clearButtonMode="while-editing"
keyboardType="url"
onChangeText={[Function]}
onSubmitEditing={[Function]}
placeholder="Enter website address"
placeholderTextColor="#747d8c"
returnKeyType="go"
style={
Object {
"backgroundColor": "#dfe4ea",
"borderRadius": 3,
"flex": 1,
"fontSize": 14,
"padding": 8,
}
}
underlineColorAndroid="transparent"
value="http://metamask.io"
/>
<Icon
allowFontScaling={false}
disabled={true}
name="refresh"
onPress={[Function]}
size={20}
style={
Object {
"color": "#2f3542",
"flex": 0,
"height": 28,
"lineHeight": 28,
"paddingTop": 2,
"textAlign": "center",
"width": 36,
}
}
/>
</Component>
<WebView
onNavigationStateChange={[Function]}
originWhitelist={
Array [
"http://*",
"https://*",
]
}
scalesPageToFit={true}
source={
Object {
"uri": "http://metamask.io",
}
}
style={
Object {
"width": 750,
}
}
/>
</Component>
`;

@ -1,73 +1,130 @@
import React, { Component } from 'react';
import {
Dimensions,
StyleSheet,
TextInput,
View,
WebView
} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { colors } from '../../styles/variables';
import PropTypes from 'prop-types';
import { Dimensions, StyleSheet, TextInput, View, WebView } from 'react-native';
import { colors, baseStyles } from '../../styles/common';
const styles = StyleSheet.create({
urlBar: {
alignItems: 'stretch',
backgroundColor: colors.concrete,
flexDirection: 'row',
paddingVertical: 8
},
icon: {
color: colors.tar,
flex: 0,
height: 28,
lineHeight: 28,
paddingTop: 2,
textAlign: 'center',
width: 36
},
disabledIcon: {
color: colors.ash
},
urlInput: {
backgroundColor: colors.slate,
borderRadius: 3,
flex: 1,
fontSize: 14,
padding: 8
}
});
/**
* Complete Web browser component with URL entry and history management
*/
export default class Browser extends Component {
static defaultProps = {
defaultProtocol: 'https://'
};
static propTypes = {
/**
* Protocol string to append to URLs that have none
*/
defaultProtocol: PropTypes.string,
/**
* Initial URL to load in the WebView
*/
defaultURL: PropTypes.string.isRequired
};
export default class App extends Component {
state = {
canGoBack: false,
canGoForward: false,
inputValue: this.props.defaultUrl,
url: this.props.defaultUrl
inputValue: this.props.defaultURL,
url: this.props.defaultURL
};
webview = React.createRef();
go = () => {
const url = this.state.inputValue;
const hasProtocol = url.match(/^[a-z]*:\/\//);
const sanitizedURL = hasProtocol ? url : `${this.props.defaultProtocol}${url}`;
this.setState({ url: sanitizedURL });
};
goBack = () => {
this.webview.current.goBack();
};
goForward = () => {
this.webview.current.goForward();
};
reload = () => {
this.webview.current.reload();
};
onPageChange = ({ canGoBack, canGoForward, url }) => {
this.setState({ canGoBack, canGoForward, inputValue: url });
};
onURLChange = inputValue => {
this.setState({ inputValue });
};
render() {
const {
canGoBack,
canGoForward,
inputValue,
url
} = this.state;
const { canGoBack, canGoForward, inputValue, url } = this.state;
return (
<View style={{ flex: 1 }}>
<View style={baseStyles.flexGrow}>
<View style={styles.urlBar}>
<Icon
disabled={true}
disabled={!canGoBack}
name="angle-left"
onPress={() => { this.webview.goBack(); }}
onPress={this.goBack}
size={30}
style={{...styles.icon, ...(!canGoBack ? styles.disabledIcon : {})}}
style={{ ...styles.icon, ...(!canGoBack ? styles.disabledIcon : {}) }}
/>
<Icon
disabled={!canGoForward}
name="angle-right"
onPress={() => { this.webview.goForward(); }}
onPress={this.goForward}
size={30}
style={{...styles.icon, ...(!canGoForward ? styles.disabledIcon : {})}}
style={{ ...styles.icon, ...(!canGoForward ? styles.disabledIcon : {}) }}
/>
<TextInput
autoCapitalize="none"
autoCorrect={false}
clearButtonMode="while-editing"
keyboardType="url"
onChangeText={(inputValue) => { this.setState({ inputValue }); }}
onSubmitEditing={() => { this.setState({ url: this.state.inputValue }) }}
onChangeText={this.onURLChange}
onSubmitEditing={this.go}
placeholder="Enter website address"
placeholderTextColor={colors.asphalt}
returnKeyType="go"
style={styles.urlInput}
value={inputValue}
/>
<Icon
disabled={!canGoForward}
name="refresh"
onPress={() => { this.webview.reload(); }}
size={20}
style={styles.icon}
/>
<Icon disabled={!canGoForward} name="refresh" onPress={this.reload} size={20} style={styles.icon} />
</View>
<WebView
onNavigationStateChange={({ canGoBack, canGoForward, url }) => {
this.setState({ canGoBack, canGoForward, inputValue: url });
}}
ref={(ref) => { this.webview = ref; }}
onNavigationStateChange={this.onPageChange}
ref={this.webview}
source={{ uri: url }}
style={{ width: Dimensions.get('window').width }}
/>
@ -75,31 +132,3 @@ export default class App extends Component {
);
}
}
const styles = StyleSheet.create({
urlBar: {
alignItems: 'stretch',
backgroundColor: colors.concrete,
flexDirection: 'row',
paddingVertical: 8
},
icon: {
color: colors.tar,
flex: 0,
height: 28,
lineHeight: 28,
paddingTop: 2,
textAlign: 'center',
width: 36,
},
disabledIcon: {
color: colors.ash
},
urlInput: {
backgroundColor: colors.slate,
borderRadius: 3,
flex: 1,
fontSize: 14,
padding: 8
}
});

@ -0,0 +1,75 @@
import React from 'react';
import { TextInput, WebView } from 'react-native';
import { shallow } from 'enzyme';
import Browser from './';
describe('Browser', () => {
it('should render correctly', () => {
const wrapper = shallow(<Browser defaultURL="http://metamask.io" />);
expect(wrapper).toMatchSnapshot();
});
it('should update input value', () => {
const wrapper = shallow(<Browser defaultURL="http://metamask.io" />);
wrapper.find(TextInput).simulate('ChangeText', 'foobar');
expect(wrapper.state().inputValue).toBe('foobar');
});
it('should enable back button', () => {
const wrapper = shallow(<Browser defaultURL="http://metamask.io" />);
expect(wrapper.find('[name="angle-left"]').prop('disabled')).toBe(true);
wrapper.find(WebView).simulate('NavigationStateChange', { canGoBack: true });
expect(wrapper.find('[name="angle-left"]').prop('disabled')).toBe(false);
});
it('should enable forward button', () => {
const wrapper = shallow(<Browser defaultURL="http://metamask.io" />);
expect(wrapper.find('[name="angle-right"]').prop('disabled')).toBe(true);
wrapper.find(WebView).simulate('NavigationStateChange', { canGoForward: true });
expect(wrapper.find('[name="angle-right"]').prop('disabled')).toBe(false);
});
it('should go back', () => {
const wrapper = shallow(<Browser defaultURL="http://metamask.io" />);
wrapper.setState({ inputValue: 'https://foobar' });
wrapper.find(TextInput).simulate('SubmitEditing');
expect(wrapper.state().url).toBe('https://foobar');
});
it('should add protocol', () => {
const wrapper = shallow(<Browser defaultURL="http://metamask.io" />);
wrapper.setState({ inputValue: 'foobar' });
wrapper.find(TextInput).simulate('SubmitEditing');
expect(wrapper.state().url).toBe('https://foobar');
});
it('should go back', () => {
const MockWebView = { goBack() {} }; // eslint-disable-line no-empty-function
const stub = spyOn(MockWebView, 'goBack');
const wrapper = shallow(<Browser defaultURL="http://metamask.io" />);
wrapper.find(WebView).simulate('NavigationStateChange', { canGoBack: true });
wrapper.instance().webview = { current: MockWebView };
wrapper.find('[name="angle-left"]').simulate('press');
expect(stub).toBeCalled();
});
it('should go forward', () => {
const MockWebView = { goForward() {} }; // eslint-disable-line no-empty-function
const stub = spyOn(MockWebView, 'goForward');
const wrapper = shallow(<Browser defaultURL="http://metamask.io" />);
wrapper.find(WebView).simulate('NavigationStateChange', { canGoBack: true });
wrapper.instance().webview = { current: MockWebView };
wrapper.find('[name="angle-right"]').simulate('press');
expect(stub).toBeCalled();
});
it('should reload', () => {
const MockWebView = { reload() {} }; // eslint-disable-line no-empty-function
const stub = spyOn(MockWebView, 'reload');
const wrapper = shallow(<Browser defaultURL="http://metamask.io" />);
wrapper.find(WebView).simulate('NavigationStateChange', {});
wrapper.instance().webview = { current: MockWebView };
wrapper.find('[name="refresh"]').simulate('press');
expect(stub).toBeCalled();
});
});

@ -0,0 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`BrowserScreen should render correctly 1`] = `
<Screen>
<Browser
defaultProtocol="https://"
defaultURL="http://metamask.io"
/>
</Screen>
`;

@ -2,11 +2,14 @@ import React, { Component } from 'react';
import Browser from '../Browser';
import Screen from '../Screen';
export default class BrowserView extends Component {
/**
* Main view component for the browser screen
*/
export default class BrowserScreen extends Component {
render() {
return (
<Screen>
<Browser defaultUrl="http://metamask.io" />
<Browser defaultURL="http://metamask.io" />
</Screen>
);
}

@ -0,0 +1,10 @@
import React from 'react';
import { shallow } from 'enzyme';
import BrowserScreen from './';
describe('BrowserScreen', () => {
it('should render correctly', () => {
const wrapper = shallow(<BrowserScreen />);
expect(wrapper).toMatchSnapshot();
});
});

@ -0,0 +1,42 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Screen should render correctly 1`] = `
<Component
style={
Object {
"flex": 1,
}
}
>
<Component
style={
Object {
"backgroundColor": "#2f3542",
"height": 1334,
"left": 0,
"position": "absolute",
"top": 0,
"width": 750,
}
}
>
<StatusBar
animated={false}
backgroundColor="#2f3542"
barStyle="light-content"
showHideTransition="fade"
/>
</Component>
<SafeAreaView
style={
Object {
"flex": 1,
}
}
>
<Component>
Foobar
</Component>
</SafeAreaView>
</Component>
`;

@ -1,36 +1,38 @@
import React from 'react';
import {
Dimensions,
SafeAreaView,
StatusBar,
StyleSheet,
View
} from 'react-native';
import { colors, common } from '../../styles/variables';
export default function({ children }) {
const { height, width } = Dimensions.get('window');
return (
<View style={common.flexGrow}>
<View style={{...styles.statusBarUnderlay, ...{ width, height }}}>
<StatusBar
backgroundColor={colors.tar}
barStyle="light-content"
/>
</View>
<SafeAreaView style={common.flexGrow}>
{children}
</SafeAreaView>
</View>
);
}
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Dimensions, SafeAreaView, StatusBar, StyleSheet, View } from 'react-native';
import { colors, baseStyles } from '../../styles/common';
const styles = StyleSheet.create({
statusBarUnderlay: {
underlay: {
backgroundColor: colors.tar,
left: 0,
position: 'absolute',
top: 0
}
});
/**
* Base view component providing consistent styling meant to wrap other views
*/
export default class Screen extends Component {
static propTypes = {
/**
* Content to wrap inside this view
*/
children: PropTypes.node
};
render() {
const { height, width } = Dimensions.get('window');
return (
<View style={baseStyles.flexGrow}>
<View style={{ ...styles.underlay, ...{ width, height } }}>
<StatusBar backgroundColor={colors.tar} barStyle="light-content" />
</View>
<SafeAreaView style={baseStyles.flexGrow}>{this.props.children}</SafeAreaView>
</View>
);
}
}

@ -0,0 +1,15 @@
import React from 'react';
import { shallow } from 'enzyme';
import { View } from 'react-native';
import Screen from './';
describe('Screen', () => {
it('should render correctly', () => {
const wrapper = shallow(
<Screen>
<View>Foobar</View>
</Screen>
);
expect(wrapper).toMatchSnapshot();
});
});

@ -1,3 +1,10 @@
/**
* Common styles and variables
*/
/**
* Map of color names to HEX values
*/
export const colors = {
ash: '#ced6e0',
asphalt: '#747d8c',
@ -6,7 +13,10 @@ export const colors = {
tar: '#2f3542'
};
export const common = {
/**
* Map of reusable base styles
*/
export const baseStyles = {
flexGrow: {
flex: 1
},

@ -1,4 +1,8 @@
import App from './App';
/**
* Common styles and variables
*/
import App from './app/components/App';
import { AppRegistry } from 'react-native';
import { name } from './app.json';

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

2476
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,12 +1,38 @@
{
"name": "MetaMask",
"name": "metamask",
"version": "0.0.1",
"private": true,
"scripts": {
"lint": "eslint **/*.js --ignore-path=.prettierignore",
"format": "prettier **/*.{js,json} --write",
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
"test": "jest",
"test:update": "jest -u"
},
"prettier": {
"printWidth": 120,
"singleQuote": true,
"tabWidth": 4,
"useTabs": true
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.js": [
"prettier --write",
"eslint --ignore-path=.prettierignore",
"git add"
],
"*.json": [
"prettier --write",
"git add"
]
},
"dependencies": {
"prop-types": "^15.6.2",
"react": "16.4.1",
"react-native": "0.56.0",
"react-native-vector-icons": "^4.6.0",
@ -15,10 +41,61 @@
"devDependencies": {
"babel-jest": "23.4.0",
"babel-preset-react-native": "5.0.2",
"enzyme": "^3.0.0",
"enzyme-adapter-react-16": "^1.1.1",
"enzyme-to-json": "^3.3.4",
"eslint-config-react-native": "^3.0.0",
"husky": "^1.0.0-rc.13",
"jest": "23.4.1",
"react-test-renderer": "16.4.1"
"lint-staged": "^7.2.0",
"prettier": "1.13.7",
"react-dom": "^16.4.1"
},
"babel": {
"presets": [
"react-native"
]
},
"eslintConfig": {
"parser": "babel-eslint",
"extends": [
"react-native"
],
"globals": {
"describe": true,
"expect": true,
"it": true,
"spyOn": true
},
"rules": {
"class-methods-use-this": 0,
"no-invalid-this": 0,
"react/jsx-handler-names": 0,
"react/prefer-stateless-function": 0
}
},
"jest": {
"preset": "react-native"
"preset": "react-native",
"setupFiles": [
"<rootDir>/app/common/testSetup.js"
],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
},
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-navigation|react-navigation-redux-helpers)"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"collectCoverage": true,
"coverageThreshold": {
"global": {
"branches": 100,
"functions": 100,
"lines": 100,
"statements": 100
}
}
}
}

Loading…
Cancel
Save