diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..c912533dd --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +__tests__ diff --git a/__tests__/index.android.js b/__tests__/index.android.js index b49b9087f..c154e11ee 100644 --- a/__tests__/index.android.js +++ b/__tests__/index.android.js @@ -6,7 +6,7 @@ import Index from '../index.android.js'; import renderer from 'react-test-renderer'; it('renders correctly', () => { - const tree = renderer.create( - - ); + const tree = renderer.create( + + ); }); diff --git a/__tests__/index.ios.js b/__tests__/index.ios.js index ba7c5b5e1..8031c711e 100644 --- a/__tests__/index.ios.js +++ b/__tests__/index.ios.js @@ -6,7 +6,7 @@ import Index from '../index.ios.js'; import renderer from 'react-test-renderer'; it('renders correctly', () => { - const tree = renderer.create( - - ); + const tree = renderer.create( + + ); }); diff --git a/app/components/Message.js b/app/components/Message.js new file mode 100644 index 000000000..8206b4a08 --- /dev/null +++ b/app/components/Message.js @@ -0,0 +1,43 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { View, Text, StyleSheet, Image } from 'react-native'; + +const styles = StyleSheet.create({ + message: { + borderColor: '#aaa', + padding: 14, + flexDirection: 'row', + transform: [{ scaleY: -1 }] + } +}); + +export default class Message extends React.PureComponent { + static propTypes = { + item: PropTypes.object.isRequired, + baseUrl: PropTypes.string.isRequired + } + + render() { + const extraStyle = {}; + if (this.props.item.temp) { + extraStyle.opacity = 0.3; + } + + return ( + + + + + {this.props.item.u.username} + + + {this.props.item.msg} + + {/* + {this.props.item.msg} + */} + + + ); + } +} diff --git a/app/components/RoomItem.js b/app/components/RoomItem.js new file mode 100644 index 000000000..4e1fcf7cb --- /dev/null +++ b/app/components/RoomItem.js @@ -0,0 +1,30 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Text, StyleSheet } from 'react-native'; + +const styles = StyleSheet.create({ + roomItem: { + lineHeight: 18, + borderTopWidth: 2, + borderColor: '#aaa', + padding: 14 + } +}); + +export default class RoomItem extends React.PureComponent { + static propTypes = { + onPressItem: PropTypes.func.isRequired, + title: PropTypes.string.isRequired, + id: PropTypes.string.isRequired + } + + _onPress = () => { + this.props.onPressItem(this.props.id); + }; + + render() { + return ( + { this.props.title } + ); + } +} diff --git a/app/meteor.js b/app/lib/meteor.js similarity index 87% rename from app/meteor.js rename to app/lib/meteor.js index 85502eb76..1a8cef961 100644 --- a/app/meteor.js +++ b/app/lib/meteor.js @@ -33,25 +33,23 @@ export function connect(cb) { cb(); }); - Meteor.ddp.on("changed", ddbMessage => { + Meteor.ddp.on('changed', (ddbMessage) => { console.log('changed', ddbMessage); if (ddbMessage.collection === 'stream-room-messages') { - setTimeout(function() { + setTimeout(() => { realm.write(() => { const message = ddbMessage.fields.args[0]; message.temp = false; realm.create('messages', message, true); }); - }, 1000) + }, 1000); } }); }); } export function loginWithPassword(selector, password, cb) { - Meteor.loginWithPassword(selector, password, (err, data) => { - cb && cb(); - }); + Meteor.loginWithPassword(selector, password, () => cb && cb()); } export function loadSubscriptions(cb) { @@ -72,7 +70,7 @@ export function loadSubscriptions(cb) { }); }); - cb && cb(); + return cb && cb(); }); } @@ -102,8 +100,8 @@ export function sendMessage(rid, msg, cb) { _id, rid, msg, - ts: new Date, - _updatedAt: new Date, + ts: new Date(), + _updatedAt: new Date(), temp: true, u: { _id: user._id, @@ -112,7 +110,5 @@ export function sendMessage(rid, msg, cb) { }, true); }); - Meteor.call('sendMessage', {_id, rid, msg}, (err, data) => { - cb && cb(); - }); + Meteor.call('sendMessage', { _id, rid, msg }, () => cb && cb()); } diff --git a/app/realm.js b/app/lib/realm.js similarity index 100% rename from app/realm.js rename to app/lib/realm.js diff --git a/app/navigation.js b/app/navigation.js index 166a41f04..ab99e4f71 100644 --- a/app/navigation.js +++ b/app/navigation.js @@ -1,9 +1,9 @@ import { StackNavigator } from 'react-navigation'; -import LoginView from './login'; -import NewServerView from './servers/new'; -import ListServerView from './servers/list'; -import RoomsView from './rooms'; -import RoomView from './room'; +import LoginView from './views/login'; +import NewServerView from './views/serverNew'; +import ListServerView from './views/serverList'; +import RoomsListView from './views/roomsList'; +import RoomView from './views/room'; const navigationOptions = { // headerStyle: { @@ -24,7 +24,7 @@ export default new StackNavigator({ navigationOptions }, Login: { screen: LoginView }, - Rooms: { screen: RoomsView }, + Rooms: { screen: RoomsListView }, Room: { screen: RoomView // navigationOptions: { diff --git a/app/login.js b/app/views/login.js similarity index 92% rename from app/login.js rename to app/views/login.js index 9735c05f6..1f72183e8 100644 --- a/app/login.js +++ b/app/views/login.js @@ -1,9 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { View, TextInput, StyleSheet, KeyboardAvoidingView, Platform } from 'react-native'; -import realm from './realm'; -import { loginWithPassword, loadSubscriptions, Accounts } from './meteor'; - +import { TextInput, StyleSheet, KeyboardAvoidingView, Platform } from 'react-native'; +import realm from '../lib/realm'; +import { loginWithPassword, loadSubscriptions, Accounts } from '../lib/meteor'; const styles = StyleSheet.create({ view: { diff --git a/app/room.js b/app/views/room.js similarity index 69% rename from app/room.js rename to app/views/room.js index fac263aba..efaf4dd10 100644 --- a/app/room.js +++ b/app/views/room.js @@ -1,18 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { View, KeyboardAvoidingView, Text, TextInput, FlatList, StyleSheet, Image, Platform } from 'react-native'; +import { View, KeyboardAvoidingView, TextInput, FlatList, StyleSheet, Platform } from 'react-native'; // import Markdown from 'react-native-simple-markdown'; -import realm from './realm'; -import { loadMessagesForRoom, sendMessage } from './meteor'; +import realm from '../lib/realm'; +import { loadMessagesForRoom, sendMessage } from '../lib/meteor'; +import Message from '../components/Message'; const styles = StyleSheet.create({ - roomItem: { - borderColor: '#aaa', - padding: 14, - flexDirection: 'row', - transform: [{ scaleY: -1 }] - }, avatar: { backgroundColor: '#ccc', width: 40, @@ -54,36 +49,6 @@ const styles = StyleSheet.create({ } }); -class RoomItem extends React.PureComponent { - static propTypes = { - item: PropTypes.object.isRequired - } - - render() { - const extraStyle = {}; - if (this.props.item.temp) { - extraStyle.opacity = .3; - } - - return ( - - - - - {this.props.item.u.username} - - - {this.props.item.msg} - - {/* - {this.props.item.msg} - */} - - - ); - } -} - export default class RoomView extends React.Component { static propTypes = { navigation: PropTypes.object.isRequired @@ -106,16 +71,6 @@ export default class RoomView extends React.Component { this.url = realm.objectForPrimaryKey('settings', 'Site_Url').value; } - getMessages = () => { - return realm.objects('messages').filtered('rid = $0', this.rid).sorted('ts', true); - } - - updateState = () => { - this.setState({ - dataSource: this.getMessages() - }); - }; - componentWillMount() { loadMessagesForRoom(this.rid); realm.addListener('change', this.updateState); @@ -125,17 +80,13 @@ export default class RoomView extends React.Component { realm.removeListener('change', this.updateState); } - renderItem = ({ item }) => ( - - ); + getMessages = () => realm.objects('messages').filtered('rid = $0', this.rid).sorted('ts', true) - renderSeparator = () => ( - - ); + updateState = () => { + this.setState({ + dataSource: this.getMessages() + }); + }; submit = () => { console.log(this.state.text); @@ -149,7 +100,19 @@ export default class RoomView extends React.Component { ...this.state, text: '' }); - } + }; + + renderSeparator = () => ( + + ); + + renderItem = ({ item }) => ( + + ); render() { return ( @@ -172,7 +135,7 @@ export default class RoomView extends React.Component { onSubmitEditing={this.submit} autoFocus placeholder='New message' - > + /> ); diff --git a/app/rooms.js b/app/views/roomsList.js similarity index 59% rename from app/rooms.js rename to app/views/roomsList.js index 937060176..0b489d84b 100644 --- a/app/rooms.js +++ b/app/views/roomsList.js @@ -1,16 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { View, Text, FlatList, StyleSheet } from 'react-native'; -import realm from './realm'; +import { View, FlatList, StyleSheet } from 'react-native'; +import realm from '../lib/realm'; +import RoomItem from '../components/RoomItem'; const styles = StyleSheet.create({ - roomItem: { - lineHeight: 18, - borderTopWidth: 2, - borderColor: '#aaa', - padding: 14 - }, container: { flex: 1 }, @@ -22,25 +17,7 @@ const styles = StyleSheet.create({ } }); -class RoomItem extends React.PureComponent { - static propTypes = { - onPressItem: PropTypes.func.isRequired, - title: PropTypes.string.isRequired, - id: PropTypes.string.isRequired - } - - _onPress = () => { - this.props.onPressItem(this.props.id); - }; - - render() { - return ( - { this.props.title } - ); - } -} - -export default class RoomsView extends React.Component { +export default class RoomsListView extends React.Component { static propTypes = { navigation: PropTypes.object.isRequired } @@ -53,10 +30,6 @@ export default class RoomsView extends React.Component { }; } - componentWillMount() { - realm.addListener('change', () => this.setState(getState())); - } - _onPressItem = (id) => { const { navigate } = this.props.navigation; console.log('pressed', id); diff --git a/app/servers/list.js b/app/views/serverList.js similarity index 81% rename from app/servers/list.js rename to app/views/serverList.js index 6e08d3ce1..4c0c91160 100644 --- a/app/servers/list.js +++ b/app/views/serverList.js @@ -1,10 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import Zeroconf from 'react-native-zeroconf'; -import { H1, View, TouchableOpacity, Text, TextInput, SectionList, Button, StyleSheet } from 'react-native'; +import { View, Text, SectionList, Button, StyleSheet } from 'react-native'; -import realm from '../realm'; -import { connect } from '../meteor'; +import realm from '../lib/realm'; +import { connect } from '../lib/meteor'; const styles = StyleSheet.create({ view: { @@ -53,12 +53,12 @@ export default class ListServerView extends React.Component { navigation: PropTypes.object.isRequired } - static navigationOptions = ({navigation}) => ({ + static navigationOptions = ({ navigation }) => ({ title: 'Servers', headerRight: (