Unverified Commit 61ad81c0 authored by Hanwen Cheng's avatar Hanwen Cheng Committed by GitHub
Browse files

fix: add Linter and fix caught errors (#337)

* feat: introduce eslint and configurations

* add lint sort key plugin

* fix lint catched errors

* fix lint errors

* update editor config

* add husky with pre-commit hooks

* fix default screen error

* fix screen orders

* removed non-unused-vars warnings

* upgrade flow versions

* fix non-unused-vars error in for loop

* escalate unused-var from warning to error
parent eadd7655
Pipeline #53933 failed with stage
root = true
[*]
indent_style = space
indent_size = 2
indent_style = tab
indent_size = tab
tab_width = 2
end_of_line = lf
charset = utf-8
......@@ -13,6 +13,3 @@ insert_final_newline = true
[*.plist]
indent_size = 4
tab_width = 4
[*.{js,jsx}]
indent_style = tab
# /node_modules/* and /bower_components/* in the project root are ignored by default
/NDK
**/build
module.exports = {
root: true,
extends: '@react-native-community',
};
\ No newline at end of file
extends: ["@react-native-community", "plugin:prettier/recommended"],
parserOptions: {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
},
},
settings: {
react: {
"pragma": "React", // Pragma to use, default to "React"
"version": "16.9.0", // React version, default to the latest React stable release
},
},
rules: {
"comma-dangle": ["error", "never"],
"object-curly-spacing": ["error", "always"],
"quotes": ["error", "single", { "avoidEscape": true }],
"no-unused-vars": ["error", { "args": "none" }],
"react-native/no-inline-styles": "off",
"sort-keys": ["error", "asc", {"caseSensitive": true, "natural": false, "minKeys": 2}]
}
};
......@@ -78,4 +78,4 @@ untyped-import
untyped-type-import
[version]
^0.98.0
\ No newline at end of file
^0.109.0
{
"printWidth": 80,
"parser": "flow",
"singleQuote": true
"singleQuote": true,
"useTabs": true,
"tabWidth": 2
}
......@@ -11,4 +11,5 @@ install:
- yarn
script:
- yarn run lint
- yarn run test
......@@ -15,11 +15,17 @@
"clean": "watchman watch-del-all && rm -rf /tmp/metro-bundler-cache-* && rm -rf /tmp/haste-map-react-native-packager-* && rm -rf node_modules/ && yarn cache clean --force",
"commit": "commit-wizard",
"ios": "yarn run build-rust-ios && react-native run-ios",
"lint": "eslint",
"lint": "npx eslint ./src/ --ext .js,.jsx",
"lint:fix": "npx eslint ./src/ --ext .js,.jsx --fix",
"postinstall": "npx jetify",
"start": "NODE_OPTIONS=--max_old_space_size=8192 react-native start",
"test": "jest"
},
"husky": {
"hooks": {
"pre-commit": "yarn run lint"
}
},
"dependencies": {
"@plugnet/util": "^1.1.100",
"@plugnet/wasm-crypto-js": "^0.11.102",
......@@ -58,10 +64,13 @@
"@babel/plugin-transform-runtime": "^7.5.0",
"@babel/runtime": "^7.5.4",
"@react-native-community/eslint-config": "^0.0.5",
"babel-eslint": "^10.0.3",
"babel-eslint": "10.0.3",
"babel-jest": "^24.9.0",
"babel-plugin-rewrite-require": "^1.14.5",
"eslint": "^6.2.2",
"eslint": "^6.3.0",
"eslint-config-prettier": "^6.2.0",
"eslint-plugin-prettier": "^3.1.0",
"husky": "^3.0.8",
"jest": "^24.9.0",
"jetifier": "^1.6.4",
"metro-react-native-babel-preset": "^0.56.0",
......
/* eslint-disable */
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity.
......@@ -23,12 +21,12 @@ import '../shim';
import '@polkadot/types/injector';
import React, { Component } from 'react';
import {StatusBar, YellowBox} from 'react-native';
import { StatusBar, YellowBox } from 'react-native';
import {
createAppContainer,
createStackNavigator,
HeaderBackButton,
withNavigation
createAppContainer,
createStackNavigator,
HeaderBackButton,
withNavigation
} from 'react-navigation';
import { Provider as UnstatedProvider } from 'unstated';
import { MenuProvider } from 'react-native-popup-menu';
......@@ -61,180 +59,181 @@ import TermsAndConditions from './screens/TermsAndConditions';
import TxDetails from './screens/TxDetails';
export default class App extends Component {
constructor() {
super();
if (__DEV__) {
YellowBox.ignoreWarnings([
'Warning: componentWillReceiveProps',
'Warning: componentWillMount',
'Warning: componentWillUpdate'
]);
}
}
constructor() {
super();
if (__DEV__) {
YellowBox.ignoreWarnings([
'Warning: componentWillReceiveProps',
'Warning: componentWillMount',
'Warning: componentWillUpdate'
]);
}
}
render() {
return (
<UnstatedProvider>
<MenuProvider backHandler={true}>
<StatusBar barStyle="light-content" />
<Background />
<ScreensContainer />
</MenuProvider>
</UnstatedProvider>
);
}
render() {
return (
<UnstatedProvider>
<MenuProvider backHandler={true}>
<StatusBar barStyle="light-content" />
<Background />
<ScreensContainer />
</MenuProvider>
</UnstatedProvider>
);
}
}
const globalStackNavigationOptions = {
headerTintColor: colors.card_bg,
headerRight: <SecurityHeader />,
headerStyle: {
backgroundColor: colors.bg,
height: 60,
paddingTop: 0,
paddingBottom: 0,
borderBottomWidth: 0.5,
borderBottomColor: colors.bg_text_sec
},
headerTitleStyle: {
display: 'none',
},
headerBackTitleStyle: {
fontSize: 20,
fontFamily: fonts.semiBold
}
headerBackTitleStyle: {
fontFamily: fonts.semiBold,
fontSize: 20
},
headerRight: <SecurityHeader />,
headerStyle: {
backgroundColor: colors.bg,
borderBottomColor: colors.bg_text_sec,
borderBottomWidth: 0.5,
height: 60,
paddingBottom: 0,
paddingTop: 0
},
headerTintColor: colors.card_bg,
headerTitleStyle: {
display: 'none'
}
};
// A workaround for https://github.com/react-navigation/react-navigation/issues/88
const SecurityHeaderBackButton = withNavigation(
class _HeaderBackButton extends Component {
render() {
const { navigation } = this.props;
return (
<HeaderBackButton
{...this.props}
titleStyle={globalStackNavigationOptions.headerBackTitleStyle}
title="Back"
tintColor={colors.card_bg}
onPress={() => navigation.goBack(null)}
/>
);
}
}
class _HeaderBackButton extends Component {
render() {
const { navigation } = this.props;
return (
<HeaderBackButton
{...this.props}
titleStyle={globalStackNavigationOptions.headerBackTitleStyle}
title="Back"
tintColor={colors.card_bg}
onPress={() => navigation.goBack(null)}
/>
);
}
}
);
/* eslint-disable sort-keys */
const Screens = createStackNavigator(
{
Loading: {
screen: Loading
},
Security: {
screen: createStackNavigator(
{
Security: {
screen: Security,
navigationOptions: {
headerLeft: <SecurityHeaderBackButton/>,
headerRight: null
}
}
},
{
defaultNavigationOptions: globalStackNavigationOptions,
headerMode: 'screen',
}
),
},
TocAndPrivacyPolicy: {
screen: createStackNavigator(
{
TermsAndConditions: {
screen: TermsAndConditions,
navigationOptions: {
headerLeft: <HeaderLeftHome />
}
},
PrivacyPolicy: {
screen: PrivacyPolicy
}
},
{
defaultNavigationOptions: globalStackNavigationOptions,
initialRouteParams: {
isWelcome: true
}
}
)
},
Welcome: {
screen: createStackNavigator(
{
AccountList: {
screen: AccountList,
navigationOptions: {
headerLeft: <HeaderLeftHome />
}
},
AccountNetworkChooser: {
screen: AccountNetworkChooser
},
AccountNew: {
screen: AccountNew
},
AccountRecover: {
screen: AccountRecover
},
AccountBackup: {
screen: AccountBackup
},
AccountPin: {
screen: AccountPin
},
QrScanner: {
screen: QrScanner,
},
TxDetails: {
screen: TxDetails
},
AccountUnlockAndSign: {
screen: AccountUnlockAndSign
},
SignedTx: {
screen: SignedTx
},
SignedMessage: {
screen: SignedMessage
},
MessageDetails: {
screen: MessageDetails
},
About: {
screen: About
},
AccountDetails: {
screen: AccountDetails
},
AccountUnlock: {
screen: AccountUnlock
},
AccountEdit: {
screen: AccountEdit
}
},
{
defaultNavigationOptions: globalStackNavigationOptions,
initialRouteParams: {
isWelcome: true
}
}
)
},
},
{
defaultNavigationOptions: globalStackNavigationOptions,
headerMode: 'none',
mode: 'card'
}
{
Loading: {
screen: Loading
},
Security: {
screen: createStackNavigator(
{
Security: {
navigationOptions: {
headerLeft: <SecurityHeaderBackButton />,
headerRight: null
},
screen: Security
}
},
{
defaultNavigationOptions: globalStackNavigationOptions,
headerMode: 'screen'
}
)
},
TocAndPrivacyPolicy: {
screen: createStackNavigator(
{
TermsAndConditions: {
navigationOptions: {
headerLeft: <HeaderLeftHome />
},
screen: TermsAndConditions
},
PrivacyPolicy: {
screen: PrivacyPolicy
}
},
{
defaultNavigationOptions: globalStackNavigationOptions,
initialRouteParams: {
isWelcome: true
}
}
)
},
Welcome: {
screen: createStackNavigator(
{
AccountList: {
navigationOptions: {
headerLeft: <HeaderLeftHome />
},
screen: AccountList
},
About: {
screen: About
},
AccountBackup: {
screen: AccountBackup
},
AccountDetails: {
screen: AccountDetails
},
AccountEdit: {
screen: AccountEdit
},
AccountNetworkChooser: {
screen: AccountNetworkChooser
},
AccountNew: {
screen: AccountNew
},
AccountPin: {
screen: AccountPin
},
AccountRecover: {
screen: AccountRecover
},
AccountUnlock: {
screen: AccountUnlock
},
AccountUnlockAndSign: {
screen: AccountUnlockAndSign
},
MessageDetails: {
screen: MessageDetails
},
QrScanner: {
screen: QrScanner
},
SignedMessage: {
screen: SignedMessage
},
SignedTx: {
screen: SignedTx
},
TxDetails: {
screen: TxDetails
}
},
{
defaultNavigationOptions: globalStackNavigationOptions,
initialRouteParams: {
isWelcome: true
}
}
)
}
},
{
defaultNavigationOptions: globalStackNavigationOptions,
headerMode: 'none',
mode: 'card'
}
);
const ScreensContainer = createAppContainer(Screens);
......@@ -15,13 +15,13 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default {
bg: '#1D1D1D',
bg_button: '#48acf0',
bg_text: '#FFFFFF',
bg_text_sec: '#B4B5B0',
bg_warning: '#FAE265',
bg_alert: '#ED332B',
card_bg: '#F9F9F9',
card_text: '#1A1A1A',
card_bg_text_sec: '#B4B5B0'
bg: '#1D1D1D',
bg_alert: '#ED332B',
bg_button: '#48acf0',
bg_text: '#FFFFFF',
bg_text_sec: '#B4B5B0',
bg_warning: '#FAE265',
card_bg: '#F9F9F9',
card_bg_text_sec: '#B4B5B0',
card_text: '#1A1A1A'
};
......@@ -27,127 +27,124 @@ import { NETWORK_LIST, NetworkProtocols } from '../constants';
import fonts from '../fonts';
import TouchableItem from './TouchableItem';
export default class AccountCard extends React.PureComponent {
static propTypes = {
address: PropTypes.string.isRequired,
networkKey: PropTypes.string,
onPress: PropTypes.func,
seedType: PropTypes.string,
style: ViewPropTypes.style,
title: PropTypes.string
};
static propTypes = {
address: PropTypes.string.isRequired,
networkKey: PropTypes.string,
onPress: PropTypes.func,
seedType: PropTypes.string,
style: ViewPropTypes.style,
title: PropTypes.string
};
static defaultProps = {
title: 'no name',
onPress: () => {}
};
static defaultProps = {
onPress: () => {},
title: 'no name'
};
render() {
const { address, networkKey, onPress, seedType, style } = this.props;
let { title } = this.props;
title = title.length ? title : AccountCard.defaultProps.title;
const seedTypeDisplay = seedType || '';
const network = NETWORK_LIST[networkKey] || NETWORK_LIST[NetworkProtocols.UNKNOWN];
render() {
const { address, networkKey, onPress, seedType, style } = this.props;
let { title } = this.props;
title = title.length ? title : AccountCard.defaultProps.title;
const seedTypeDisplay = seedType || '';
const network =
NETWORK_LIST[networkKey] || NETWORK_LIST[NetworkProtocols.UNKNOWN];
return (
<TouchableItem
accessibilityComponentType="button"
disabled={false}
onPress={onPress}
>
<View style={[styles.body, style]}>
<View style={styles.content}>
<AccountIcon
address={address}
protocol={network.protocol}
style={styles.icon}
/>
<View style={styles.desc}>
<Text numberOfLines={1} style={styles.titleText}>
{title}
</Text>
<Address
address={address}
protocol={network.protocol}
/>
</View>
</View>
<View
style={[
styles.footer,
{
backgroundColor: network.color
}
]}
>
<Text
style={[
styles.footerSeedType,
{
color: network.secondaryColor
}
]}
>
{seedTypeDisplay}
</Text>
<Text
style={[
styles.footerNetwork,
{
color: network.secondaryColor
}
]}
>
{network.title}
</Text>
</View>