Improve ESLint

This commit is contained in:
Rodrigo Nascimento 2017-08-05 15:16:32 -03:00
parent 8104f04682
commit 7317fe63e7
9 changed files with 140 additions and 171 deletions

View File

@ -1,5 +1,6 @@
{ {
"parser": "babel-eslint", "parser": "babel-eslint",
"extends": "airbnb",
"parserOptions": { "parserOptions": {
"sourceType": "module", "sourceType": "module",
"ecmaVersion": 2017, "ecmaVersion": 2017,
@ -10,6 +11,8 @@
}, },
"plugins": [ "plugins": [
"react", "react",
"jsx-a11y",
"import",
"react-native" "react-native"
], ],
"env": { "env": {
@ -20,6 +23,23 @@
"jquery": true "jquery": true
}, },
"rules": { "rules": {
"react/jsx-filename-extension": [1, {
"extensions": [".js", ".jsx"]
}],
"react/require-default-props": [0],
"react/no-unused-prop-types": [2, {
"skipShapeProps": true
}],
"react/no-multi-comp": [0],
"react/jsx-indent": [2, "tab"],
"react/jsx-indent-props": [2, "tab"],
"react/forbid-prop-types": 0,
"jsx-quotes": [2, "prefer-single"],
"jsx-a11y/href-no-hash": 0,
"no-underscore-dangle": 0,
"no-return-assign": 0,
"no-param-reassign": 0,
"no-tabs": 0,
"no-multi-spaces": 2, "no-multi-spaces": 2,
"no-eval": 2, "no-eval": 2,
"no-extend-native": 2, "no-extend-native": 2,
@ -82,9 +102,7 @@
"block-scoped-var": 2, "block-scoped-var": 2,
"curly": [2, "all"], "curly": [2, "all"],
"eqeqeq": [2, "allow-null"], "eqeqeq": [2, "allow-null"],
"new-cap": [2, { "new-cap": [2],
"capIsNewExceptions": ["Match.Optional", "Match.Maybe", "Match.ObjectIncluding", "Push.Configure", "SHA256"]
}],
"use-isnan": 2, "use-isnan": 2,
"valid-typeof": 2, "valid-typeof": 2,
"linebreak-style": [2, "unix"], "linebreak-style": [2, "unix"],
@ -95,73 +113,5 @@
"prefer-const": 2, "prefer-const": 2,
"object-shorthand": 2 "object-shorthand": 2
}, },
"globals": { "globals": {}
"_" : false,
"__meteor_runtime_config__" : false,
"AccountBox" : false,
"Accounts" : false,
"AgentUsers" : false,
"Assets" : false,
"Blaze" : false,
"BlazeLayout" : false,
"browser" : false,
"ChatMessage" : false,
"ChatMessages" : false,
"ChatRoom" : false,
"ChatSubscription" : false,
"check" : false,
"CryptoJS" : false,
"Department" : false,
"DDPRateLimiter" : false,
"EJSON" : false,
"Email" : false,
"FlowRouter" : false,
"FileUpload" : false,
"HTTP" : false,
"getNextAgent" : false,
"handleError" : false,
"getAvatarUrlFromUsername" : false,
"LivechatCustomField" : false,
"LivechatDepartment" : false,
"LivechatDepartmentAgents" : false,
"livechatManagerRoutes" : true,
"LivechatPageVisited" : false,
"LivechatTrigger" : false,
"Logger" : false,
"Match" : false,
"Meteor" : false,
"moment" : false,
"Mongo" : false,
"Npm" : false,
"Package" : false,
"parentCall" : false,
"Promise" : false,
"Random" : false,
"ReactiveVar" : false,
"RocketChat" : true,
"RocketChatFile" : false,
"RoomHistoryManager" : false,
"RoomManager" : false,
"s" : false,
"ServiceConfiguration" : false,
"Session" : false,
"Settings" : false,
"SHA256" : false,
"SideNav" : false,
"swal" : false,
"t" : false,
"TAPi18n" : false,
"TAPi18next" : false,
"Template" : false,
"TimeSync" : false,
"toastr" : false,
"Tracker" : false,
"Trigger" : false,
"Triggers" : false,
"UAParser" : false,
"visitor" : false,
"WebApp" : false,
"VideoRecorder" : false,
"VRecDialog" : false
}
} }

View File

@ -1,7 +1,8 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { View, TextInput, StyleSheet } from 'react-native'; import { View, TextInput, StyleSheet } from 'react-native';
import realm from './realm'; import realm from './realm';
import {loginWithPassword} from './meteor'; import { loginWithPassword } from './meteor';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@ -24,7 +25,11 @@ const styles = StyleSheet.create({
} }
}); });
export class LoginView extends React.Component { export default class LoginView extends React.Component {
static propTypes = {
navigation: PropTypes.object.isRequired
}
static navigationOptions = () => ({ static navigationOptions = () => ({
title: realm.objectForPrimaryKey('settings', 'Site_Name').value title: realm.objectForPrimaryKey('settings', 'Site_Name').value
}); });
@ -40,10 +45,10 @@ export class LoginView extends React.Component {
const { navigate } = this.props.navigation; const { navigate } = this.props.navigation;
this.submit = () => { this.submit = () => {
loginWithPassword({username: this.state.username}, this.state.password, function() { loginWithPassword({ username: this.state.username }, this.state.password, () => {
console.log(arguments);
navigate('Rooms'); navigate('Rooms');
}); });
// let url = this.state.text.trim(); // let url = this.state.text.trim();
// if (!url) { // if (!url) {
// url = defaultServer; // url = defaultServer;
@ -65,30 +70,30 @@ export class LoginView extends React.Component {
<View style={styles.view}> <View style={styles.view}>
<TextInput <TextInput
style={styles.input} style={styles.input}
onChangeText={(username) => this.setState({username})} onChangeText={username => this.setState({ username })}
keyboardType='email-address' keyboardType='email-address'
autoCorrect={false} autoCorrect={false}
returnKeyType='done' returnKeyType='done'
autoCapitalize='none' autoCapitalize='none'
autoFocus={true} autoFocus
onSubmitEditing={this.submit} onSubmitEditing={this.submit}
placeholder='Email or username' /> placeholder='Email or username'
/>
<TextInput <TextInput
style={styles.input} style={styles.input}
onChangeText={(password) => this.setState({password})} onChangeText={password => this.setState({ password })}
secureTextEntry={true} secureTextEntry
autoCorrect={false} autoCorrect={false}
returnKeyType='done' returnKeyType='done'
autoCapitalize='none' autoCapitalize='none'
onSubmitEditing={this.submit} onSubmitEditing={this.submit}
placeholder='Password' /> placeholder='Password'
/>
</View> </View>
); );
} }
} }
// export class LoginView extends React.Component { // export class LoginView extends React.Component {
// renderRow(setting) { // renderRow(setting) {
// return ( // return (

View File

@ -1,5 +1,5 @@
import realm from './realm';
import Meteor from 'react-native-meteor'; import Meteor from 'react-native-meteor';
import realm from './realm';
export function connect(cb) { export function connect(cb) {
const currentServer = realm.objects('servers').filtered('current = true')[0]; const currentServer = realm.objects('servers').filtered('current = true')[0];
@ -9,16 +9,16 @@ export function connect(cb) {
Meteor.connect(url); Meteor.connect(url);
Meteor.ddp.on('connected', function() { Meteor.ddp.on('connected', () => {
console.log('connected'); console.log('connected');
Meteor.call('public-settings/get', function(err, data) { Meteor.call('public-settings/get', (err, data) => {
if (err) { if (err) {
console.error(err); console.error(err);
} }
realm.write(() => { realm.write(() => {
data.forEach(item => { data.forEach((item) => {
const setting = { const setting = {
_id: item._id _id: item._id
}; };
@ -35,14 +35,14 @@ export function connect(cb) {
} }
export function loginWithPassword(selector, password, cb) { export function loginWithPassword(selector, password, cb) {
Meteor.loginWithPassword(selector, password, function() { Meteor.loginWithPassword(selector, password, () => {
Meteor.call('subscriptions/get', function(err, data) { Meteor.call('subscriptions/get', (err, data) => {
if (err) { if (err) {
console.error(err); console.error(err);
} }
realm.write(() => { realm.write(() => {
data.forEach(subscription => { data.forEach((subscription) => {
// const subscription = { // const subscription = {
// _id: item._id // _id: item._id
// }; // };
@ -58,14 +58,14 @@ export function loginWithPassword(selector, password, cb) {
} }
export function loadMessagesForRoom(rid) { export function loadMessagesForRoom(rid) {
Meteor.call('loadHistory', rid, null, 50, function(err, data) { Meteor.call('loadHistory', rid, null, 50, (err, data) => {
if (err) { if (err) {
console.error(err); console.error(err);
} }
console.log(data); console.log(data);
realm.write(() => { realm.write(() => {
data.messages.forEach(message => { data.messages.forEach((message) => {
realm.create('messages', message, true); realm.create('messages', message, true);
}); });
}); });

View File

@ -1,8 +1,8 @@
import { StackNavigator } from 'react-navigation'; import { StackNavigator } from 'react-navigation';
import { LoginView } from './login'; import LoginView from './login';
import { NewServerView } from './new-server'; import NewServerView from './new-server';
import { RoomsView } from './rooms'; import RoomsView from './rooms';
import { RoomView } from './room'; import RoomView from './room';
export default new StackNavigator({ export default new StackNavigator({

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { View, TextInput, StyleSheet } from 'react-native'; import { View, TextInput, StyleSheet } from 'react-native';
import realm from './realm'; import realm from './realm';
import { connect } from './meteor'; import { connect } from './meteor';
@ -23,7 +24,11 @@ const styles = StyleSheet.create({
const defaultServer = 'http://localhost:3000'; const defaultServer = 'http://localhost:3000';
export class NewServerView extends React.Component { export default class NewServerView extends React.Component {
static propTypes = {
navigation: PropTypes.object.isRequired
}
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
@ -41,8 +46,8 @@ export class NewServerView extends React.Component {
// TODO: validate URL // TODO: validate URL
realm.write(() => { realm.write(() => {
realm.objects('servers').filtered('current = true').forEach(item => item.current = false); realm.objects('servers').filtered('current = true').forEach(item => (item.current = false));
realm.create('servers', {id: url, current: true}, true); realm.create('servers', { id: url, current: true }, true);
}); });
connect(() => { connect(() => {
@ -57,14 +62,15 @@ export class NewServerView extends React.Component {
<View style={styles.view}> <View style={styles.view}>
<TextInput <TextInput
style={styles.input} style={styles.input}
onChangeText={(text) => this.setState({text})} onChangeText={text => this.setState({ text })}
keyboardType='url' keyboardType='url'
autoCorrect={false} autoCorrect={false}
returnKeyType='done' returnKeyType='done'
autoCapitalize='none' autoCapitalize='none'
autoFocus={true} autoFocus
onSubmitEditing={this.submit} onSubmitEditing={this.submit}
placeholder={defaultServer} /> placeholder={defaultServer}
/>
</View> </View>
); );
} }

View File

@ -14,7 +14,7 @@ const settingsSchema = {
primaryKey: '_id', primaryKey: '_id',
properties: { properties: {
_id: 'string', _id: 'string',
value: {type: 'string', optional: true} value: { type: 'string', optional: true }
} }
}; };
@ -27,7 +27,7 @@ const subscriptionSchema = {
ts: 'date', ts: 'date',
ls: 'date', ls: 'date',
name: 'string', name: 'string',
fname: {type: 'string', optional: true}, fname: { type: 'string', optional: true },
rid: 'string', rid: 'string',
// u: { _id: 'hKCY2XGzHYk89SAaM', username: 'rodrigo', name: null }, // u: { _id: 'hKCY2XGzHYk89SAaM', username: 'rodrigo', name: null },
open: 'bool', open: 'bool',
@ -46,16 +46,16 @@ const usersSchema = {
properties: { properties: {
_id: 'string', _id: 'string',
username: 'string', username: 'string',
name: {type: 'string', optional: true} name: { type: 'string', optional: true }
} }
} };
const messagesSchema = { const messagesSchema = {
name: 'messages', name: 'messages',
primaryKey: '_id', primaryKey: '_id',
properties: { properties: {
_id: 'string', _id: 'string',
msg: {type: 'string', optional: true}, msg: { type: 'string', optional: true },
rid: 'string', rid: 'string',
ts: 'date', ts: 'date',
u: 'users', u: 'users',

View File

@ -1,8 +1,9 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { View, Text, FlatList, StyleSheet, Image } from 'react-native'; import { View, Text, FlatList, StyleSheet, Image } from 'react-native';
// import Markdown from 'react-native-simple-markdown';
import realm from './realm'; import realm from './realm';
import { loadMessagesForRoom } from './meteor'; import { loadMessagesForRoom } from './meteor';
import Markdown from 'react-native-simple-markdown';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@ -34,46 +35,38 @@ const styles = StyleSheet.create({
}); });
class RoomItem extends React.PureComponent { class RoomItem extends React.PureComponent {
_onPress = () => { static propTypes = {
this.props.onPressItem(this.props.id); item: PropTypes.object.isRequired
}; }
render() { render() {
return ( return (
<View style={styles.roomItem}> <View style={styles.roomItem}>
<Image style={styles.avatar} source={{uri: `http://localhost:3000/avatar/${ this.props.item.u.username }`}}> <Image style={styles.avatar} source={{ uri: `http://localhost:3000/avatar/${ this.props.item.u.username }` }} />
</Image>
<View> <View>
<Text onPress={this._onPress} style={styles.username}> <Text onPress={this._onPress} style={styles.username}>
{this.props.item.u.username} {this.props.item.u.username}
</Text> </Text>
<Markdown whitelist={['link', 'url']}> <Text>
{this.props.item.msg} {this.props.item.msg}
</Markdown> </Text>
{/* <Markdown whitelist={['link', 'url']}>
{this.props.item.msg}
</Markdown> */}
</View> </View>
</View> </View>
); );
} }
} }
export class RoomView extends React.Component { export default class RoomView extends React.Component {
static navigationOptions = ({ navigation }) => ({ static propTypes = {
title: realm.objectForPrimaryKey('subscriptions', navigation.state.params.sid).name navigation: PropTypes.object.isRequired
// title: navigation.state.params.rid
});
_onPressItem(id) {
console.log('pressed', id);
} }
renderItem = ({item}) => ( static navigationOptions = ({ navigation }) => ({
<RoomItem title: realm.objectForPrimaryKey('subscriptions', navigation.state.params.sid).name
id={item._id} });
onPressItem={this._onPressItem}
selected={true}
item={item}
/>
);
constructor(props) { constructor(props) {
super(props); super(props);
@ -82,24 +75,26 @@ export class RoomView extends React.Component {
loadMessagesForRoom(this.rid); loadMessagesForRoom(this.rid);
const getState = () => { const getState = () => ({
return { selected: new Map(),
selected: new Map(), dataSource: realm.objects('messages').filtered('rid = $0', this.rid)
dataSource: realm.objects('messages').filtered('rid = $0', this.rid) });
};
};
realm.addListener('change', () => this.setState(getState())); realm.addListener('change', () => this.setState(getState()));
this.state = getState(); this.state = getState();
} }
renderSeparator = () => { renderItem = ({ item }) => (
return ( <RoomItem
<View style={styles.separator} /> id={item._id}
); item={item}
}; />
);
renderSeparator = () => (
<View style={styles.separator} />
);
render() { render() {
return ( return (

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { View, Text, FlatList, StyleSheet } from 'react-native'; import { View, Text, FlatList, StyleSheet } from 'react-native';
import realm from './realm'; import realm from './realm';
@ -22,54 +23,58 @@ const styles = StyleSheet.create({
}); });
class RoomItem extends React.PureComponent { class RoomItem extends React.PureComponent {
static propTypes = {
onPressItem: PropTypes.func.isRequired,
title: PropTypes.string.isRequired,
id: PropTypes.string.isRequired
}
_onPress = () => { _onPress = () => {
this.props.onPressItem(this.props.id); this.props.onPressItem(this.props.id);
}; };
render() { render() {
return ( return (
<Text onPress={this._onPress} style={styles.roomItem}>{this.props.title}</Text> <Text onPress={this._onPress} style={styles.roomItem}>{ this.props.title }</Text>
); );
} }
} }
export class RoomsView extends React.Component { export default class RoomsView extends React.Component {
_onPressItem = (id) => { static propTypes = {
const { navigate } = this.props.navigation; navigation: PropTypes.object.isRequired
console.log('pressed', id);
navigate('Room', {sid: id});
} }
renderItem = ({item}) => (
<RoomItem
id={item._id}
onPressItem={this._onPressItem}
selected={true}
title={item.name}
/>
);
constructor(props) { constructor(props) {
super(props); super(props);
const getState = () => { const getState = () => ({
return { selected: new Map(),
selected: new Map(), dataSource: realm.objects('subscriptions')
dataSource: realm.objects('subscriptions') });
};
};
realm.addListener('change', () => this.setState(getState())); realm.addListener('change', () => this.setState(getState()));
this.state = getState(); this.state = getState();
} }
renderSeparator = () => { _onPressItem = (id) => {
return ( const { navigate } = this.props.navigation;
<View style={styles.separator} /> console.log('pressed', id);
); navigate('Room', { sid: id });
}; }
renderItem = ({ item }) => (
<RoomItem
id={item._id}
onPressItem={this._onPressItem}
title={item.name}
/>
);
renderSeparator = () => (
<View style={styles.separator} />
);
render() { render() {
return ( return (

View File

@ -1,12 +1,16 @@
{ {
"name": "RocketChatRN", "name": "rocket-chat-rn",
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start", "start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest" "test": "jest",
"lint": "eslint .",
"ios": "react-native run-ios",
"android": "react-native run-android"
}, },
"dependencies": { "dependencies": {
"prop-types": "^15.5.10",
"react": "16.0.0-alpha.12", "react": "16.0.0-alpha.12",
"react-native": "0.47.1", "react-native": "0.47.1",
"react-native-meteor": "^1.1.0", "react-native-meteor": "^1.1.0",
@ -16,6 +20,10 @@
"devDependencies": { "devDependencies": {
"babel-jest": "20.0.3", "babel-jest": "20.0.3",
"babel-preset-react-native": "2.1.0", "babel-preset-react-native": "2.1.0",
"eslint": "^4.4.0",
"eslint-config-airbnb": "^15.1.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-react": "^7.1.0", "eslint-plugin-react": "^7.1.0",
"jest": "20.0.4", "jest": "20.0.4",
"react-test-renderer": "16.0.0-alpha.12" "react-test-renderer": "16.0.0-alpha.12"