Improve code organization a bit
This commit is contained in:
parent
783e564c10
commit
2eee28797a
|
@ -0,0 +1 @@
|
|||
__tests__
|
|
@ -6,7 +6,7 @@ import Index from '../index.android.js';
|
|||
import renderer from 'react-test-renderer';
|
||||
|
||||
it('renders correctly', () => {
|
||||
const tree = renderer.create(
|
||||
<Index />
|
||||
);
|
||||
const tree = renderer.create(
|
||||
<Index />
|
||||
);
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@ import Index from '../index.ios.js';
|
|||
import renderer from 'react-test-renderer';
|
||||
|
||||
it('renders correctly', () => {
|
||||
const tree = renderer.create(
|
||||
<Index />
|
||||
);
|
||||
const tree = renderer.create(
|
||||
<Index />
|
||||
);
|
||||
});
|
||||
|
|
|
@ -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 (
|
||||
<View style={[styles.message, extraStyle]}>
|
||||
<Image style={styles.avatar} source={{ uri: `${ this.props.baseUrl }/avatar/${ this.props.item.u.username }` }} />
|
||||
<View style={styles.texts}>
|
||||
<Text onPress={this._onPress} style={styles.username}>
|
||||
{this.props.item.u.username}
|
||||
</Text>
|
||||
<Text style={styles.msg}>
|
||||
{this.props.item.msg}
|
||||
</Text>
|
||||
{/* <Markdown whitelist={['link', 'url']}>
|
||||
{this.props.item.msg}
|
||||
</Markdown> */}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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 (
|
||||
<Text onPress={this._onPress} style={styles.roomItem}>{ this.props.title }</Text>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
|
@ -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: {
|
||||
|
|
|
@ -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: {
|
|
@ -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 (
|
||||
<View style={[styles.roomItem, extraStyle]}>
|
||||
<Image style={styles.avatar} source={{ uri: `${ this.props.baseUrl }/avatar/${ this.props.item.u.username }` }} />
|
||||
<View style={styles.texts}>
|
||||
<Text onPress={this._onPress} style={styles.username}>
|
||||
{this.props.item.u.username}
|
||||
</Text>
|
||||
<Text style={styles.msg}>
|
||||
{this.props.item.msg}
|
||||
</Text>
|
||||
{/* <Markdown whitelist={['link', 'url']}>
|
||||
{this.props.item.msg}
|
||||
</Markdown> */}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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 }) => (
|
||||
<RoomItem
|
||||
id={item._id}
|
||||
item={item}
|
||||
baseUrl={this.url}
|
||||
/>
|
||||
);
|
||||
getMessages = () => realm.objects('messages').filtered('rid = $0', this.rid).sorted('ts', true)
|
||||
|
||||
renderSeparator = () => (
|
||||
<View style={styles.separator} />
|
||||
);
|
||||
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 = () => (
|
||||
<View style={styles.separator} />
|
||||
);
|
||||
|
||||
renderItem = ({ item }) => (
|
||||
<Message
|
||||
id={item._id}
|
||||
item={item}
|
||||
baseUrl={this.url}
|
||||
/>
|
||||
);
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
@ -172,7 +135,7 @@ export default class RoomView extends React.Component {
|
|||
onSubmitEditing={this.submit}
|
||||
autoFocus
|
||||
placeholder='New message'
|
||||
></TextInput>
|
||||
/>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
);
|
|
@ -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 (
|
||||
<Text onPress={this._onPress} style={styles.roomItem}>{ this.props.title }</Text>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
|
@ -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: (
|
||||
<Button
|
||||
title = "Add"
|
||||
onPress = {() => navigation.navigate('NewServer')}
|
||||
title='Add'
|
||||
onPress={() => navigation.navigate('NewServer')}
|
||||
/>
|
||||
)
|
||||
});
|
||||
|
@ -78,16 +78,17 @@ export default class ListServerView extends React.Component {
|
|||
}];
|
||||
|
||||
if (this.state.nearBy) {
|
||||
const nearBy = Object.keys(this.state.nearBy).filter(key => this.state.nearBy[key].addresses);
|
||||
const nearBy = Object.keys(this.state.nearBy)
|
||||
.filter(key => this.state.nearBy[key].addresses);
|
||||
if (nearBy.length) {
|
||||
sections.push({
|
||||
title: 'Nearby',
|
||||
data: nearBy.map((key) => {
|
||||
const server = this.state.nearBy[key];
|
||||
const address = `http://${ server.addresses[0] }:${ server.port }`
|
||||
const address = `http://${ server.addresses[0] }:${ server.port }`;
|
||||
return {
|
||||
id: address
|
||||
}
|
||||
};
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -108,7 +109,7 @@ export default class ListServerView extends React.Component {
|
|||
const currentServer = realm.objects('servers').filtered('current = true')[0];
|
||||
if (currentServer) {
|
||||
connect(() => {
|
||||
navigation.navigate('Login')
|
||||
navigation.navigate('Login');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -121,12 +122,14 @@ export default class ListServerView extends React.Component {
|
|||
realm.addListener('change', () => this.setState(getState()));
|
||||
|
||||
this.state = getState();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
onPressItem(item) {
|
||||
const { navigate } = this.props.navigation;
|
||||
realm.write(() => {
|
||||
realm.objects('servers').filtered('current = true').forEach(item => (item.current = false));
|
||||
realm.objects('servers').filtered('current = true').forEach(server => (server.current = false));
|
||||
realm.create('servers', { id: item.id, current: true }, true);
|
||||
});
|
||||
|
||||
|
@ -138,7 +141,7 @@ export default class ListServerView extends React.Component {
|
|||
renderItem = ({ item }) => (
|
||||
<Text
|
||||
style={styles.listItem}
|
||||
onPress={() => {this.onPressItem(item)}}
|
||||
onPress={() => { this.onPressItem(item); }}
|
||||
>
|
||||
{item.id}
|
||||
</Text>
|
||||
|
@ -160,11 +163,10 @@ export default class ListServerView extends React.Component {
|
|||
sections={this.state.sections}
|
||||
renderItem={this.renderItem}
|
||||
renderSectionHeader={this.renderSectionHeader}
|
||||
keyExtractor={(item) => item.id}
|
||||
keyExtractor={item => item.id}
|
||||
ItemSeparatorComponent={this.renderSeparator}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Zeroconf from 'react-native-zeroconf';
|
||||
import { View, Text, TextInput, Button, StyleSheet, KeyboardAvoidingView, Platform } from 'react-native';
|
||||
import { NavigationActions } from 'react-navigation'
|
||||
import { TextInput, StyleSheet, KeyboardAvoidingView, Platform } 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: {
|
||||
|
@ -28,14 +26,12 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
const zeroconf = new Zeroconf();
|
||||
|
||||
export default class NewServerView extends React.Component {
|
||||
static propTypes = {
|
||||
navigation: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
static navigationOptions = ({navigation}) => ({
|
||||
static navigationOptions = () => ({
|
||||
title: 'New Server Connection'
|
||||
});
|
||||
|
||||
|
@ -69,7 +65,7 @@ export default class NewServerView extends React.Component {
|
|||
});
|
||||
|
||||
connect(() => {
|
||||
navigate('ListServer', {newServer: url});
|
||||
navigate('ListServer', { newServer: url });
|
||||
});
|
||||
};
|
||||
}
|
|
@ -1488,6 +1488,11 @@
|
|||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
|
||||
"integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg="
|
||||
},
|
||||
"events": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
|
||||
"integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
|
||||
},
|
||||
"exec-sh": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.0.tgz",
|
||||
|
@ -4192,6 +4197,11 @@
|
|||
"resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-0.0.65.tgz",
|
||||
"integrity": "sha1-toXqMIH/fJZIbNmXNhAmxAcwLFk="
|
||||
},
|
||||
"react-native-zeroconf": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-zeroconf/-/react-native-zeroconf-0.7.1.tgz",
|
||||
"integrity": "sha1-zb+/JVCqcc89r4LYJnWI7+44uwE="
|
||||
},
|
||||
"react-navigation": {
|
||||
"version": "1.0.0-beta.11",
|
||||
"resolved": "https://registry.npmjs.org/react-navigation/-/react-navigation-1.0.0-beta.11.tgz",
|
||||
|
|
Loading…
Reference in New Issue