Fixed add server navigation issues, fixed empty and slow Rooms List and Chat Messages

This commit is contained in:
Gilmar Quinelato 2017-09-12 16:47:03 -03:00
parent cc93645647
commit 927076d155
9 changed files with 89 additions and 87 deletions

View File

@ -4,7 +4,6 @@ import Meteor from 'react-native-meteor';
import { connect } from 'react-redux';
import { CachedImage } from 'react-native-img-cache';
import { Text, TouchableOpacity, View } from 'react-native';
// import { Navigation } from 'react-native-navigation';
import {
Card,
CardImage,
@ -16,23 +15,6 @@ import RocketChat from '../../lib/rocketchat';
import PhotoModal from './PhotoModal';
// const close = () => Navigation.dismissModal({
// animationType: 'slide-down'
// });
const close = () => { };
const CustomButton = ({ text }) => (
<TouchableOpacity onPress={close}>
<Text style={{ color: 'blue' }}>{text}</Text>
</TouchableOpacity>
);
CustomButton.propTypes = {
text: PropTypes.string
};
// Navigation.registerComponent('CustomButton', () => CustomButton);
@connect(state => ({
base: state.settings.Site_Url,

View File

@ -1,4 +1,5 @@
import Realm from 'realm';
import { AsyncStorage } from 'react-native';
const serversSchema = {
name: 'servers',
@ -153,8 +154,8 @@ const messagesSchema = {
// }
};
//
// Realm.clearTestState();
// AsyncStorage.clear();
Realm.clearTestState();
AsyncStorage.clear();
const realm = new Realm({
schema: [settingsSchema, serversSchema, subscriptionSchema, messagesSchema, usersSchema, attachment]
});

View File

@ -4,7 +4,7 @@ import { AsyncStorage } from 'react-native';
import { hashPassword } from 'react-native-meteor/lib/utils';
import RNFetchBlob from 'react-native-fetch-blob';
import reduxStore from '../lib/createStore';
import reduxStore from './createStore';
import settingsType from '../constants/settings';
import realm from './realm';
import * as actions from '../actions';
@ -366,33 +366,25 @@ const RocketChat = {
}
},
getRooms() {
// Meteor.Accounts.onLogin(() => {
return Promise.all([call('subscriptions/get'), call('rooms/get')]).then(([subscriptions, rooms]) => {
// console.log('getRooms resolved', reduxStore.getState().server, subscriptions);
subscriptions = subscriptions.sort((s1, s2) => (s1.rid > s2.rid ? 1 : -1));
rooms = rooms.sort((s1, s2) => (s1._id > s2._id ? 1 : -1));
const { server, login } = reduxStore.getState();
const data = subscriptions.map((subscription, index) => {
subscription._updatedAt = rooms[index]._updatedAt;
subscription._server = { id: server.server };
return subscription;
});
// Meteor.subscribe('stream-notify-user', `${ Meteor.userId() }/rooms-changed`, false);
realm.write(() => {
data.forEach((subscription) => {
// const subscription = {
// _id: item._id
// };
// if (typeof item.value === 'string') {
// subscription.value = item.value;
// }
subscription._server = { id: reduxStore.getState().server.server };
// write('subscriptions', subscription);
realm.create('subscriptions', subscription, true);
});
});
Meteor.subscribe('stream-notify-user', `${ reduxStore.getState().user.id }/subscriptions-changed`, false);
Meteor.subscribe('stream-notify-user', `${ login.user.id }/subscriptions-changed`, false);
return data;
}).then(data => data);
// });
});
},
logout() {
return AsyncStorage.clear();

View File

@ -63,46 +63,33 @@ const saveToken = function* saveToken() {
yield AsyncStorage.setItem(`${ TOKEN_KEY }-${ server }`, JSON.stringify(user));
};
const handleLoginRequest = function* handleLoginRequest() {
while (true) {
const { credentials } = yield take(types.LOGIN.REQUEST);
try {
const response = yield call(loginCall, credentials);
yield put(loginSuccess(response));
} catch (err) {
if (err.error === 403) {
yield put(logout());
} else {
yield put(loginFailure(err));
}
const handleLoginRequest = function* handleLoginRequest({ credentials }) {
try {
const response = yield call(loginCall, credentials);
yield put(loginSuccess(response));
} catch (err) {
if (err.error === 403) {
yield put(logout());
} else {
yield put(loginFailure(err));
}
}
};
const handleLoginSubmit = function* handleLoginSubmit() {
while (true) {
const { credentials } = yield take(types.LOGIN.SUBMIT);
// put a login request
yield put(loginRequest(credentials));
// wait for a response
const { error } = yield race({
success: take(types.LOGIN.SUCCESS),
error: take(types.LOGIN.FAILURE)
});
if (!error) {
// const { navigator } = yield select(state => state);
// navigator.resetTo({
// screen: 'Rooms'
// });
}
}
const handleLoginSubmit = function* handleLoginSubmit({ credentials }) {
// put a login request
yield put(loginRequest(credentials));
// wait for a response
yield race({
success: take(types.LOGIN.SUCCESS),
error: take(types.LOGIN.FAILURE)
});
};
const root = function* root() {
yield takeEvery(types.SERVER.CHANGED, handleLoginWhenServerChanges);
yield fork(handleLoginRequest);
yield takeEvery(types.LOGIN.REQUEST, handleLoginRequest);
yield takeEvery(types.LOGIN.SUCCESS, saveToken);
yield fork(handleLoginSubmit);
yield takeEvery(types.LOGIN.SUBMIT, handleLoginSubmit);
};
export default root;

View File

@ -13,6 +13,7 @@ const watchRoomsRequest = function* watchRoomsRequest() {
yield call(getRooms);
yield put(roomsSuccess());
} catch (err) {
console.log(err);
yield put(roomsFailure(err.status));
}
};

View File

@ -17,9 +17,6 @@ const selectServer = function* selectServer({ server }) {
yield put(changedServer(server));
yield call([AsyncStorage, 'setItem'], 'currentServer', server);
yield put(connectRequest(server));
// yield Navigation.dismissModal({
// animationType: 'slide-down'
// });
};
@ -45,9 +42,6 @@ const addServer = function* addServer({ server }) {
realm.write(() => {
realm.create('servers', { id: server, current: false }, true);
});
// Navigation.dismissModal({
// animationType: 'slide-down'
// });
}
};

View File

@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
// import { Navigation } from 'react-native-navigation';
import { Text, TextInput, View, StyleSheet } from 'react-native';
import { connect } from 'react-redux';
import { serverRequest, addServer } from '../actions/server';
@ -73,6 +72,22 @@ export default class NewServerView extends React.Component {
editable: true,
text: ''
};
this.adding = false;
this.props.validateServer(this.state.defaultServer); // Need to call because in case of submit with empty field
}
componentDidUpdate() {
if (this.adding) {
if (!this.props.validInstance) {
/* eslint-disable react/no-did-update-set-state */
this.setState({ editable: true });
this.adding = false;
}
if (this.props.validInstance && !this.props.validating) {
this.props.navigation.goBack();
this.adding = false;
}
}
}
onChangeText = (text) => {
@ -81,14 +96,16 @@ export default class NewServerView extends React.Component {
}
submit = () => {
this.setState({ editable: false });
this.adding = true;
this.props.addServer(this.completeUrl(this.state.text.trim() || this.state.defaultServer));
this.props.navigation.goBack();
}
completeUrl = (url) => {
url = url.trim();
if (/^(\w|[0-9-_]){3,}$/.test(url) && /^(htt(ps?)?)|(loca((l)?|(lh)?|(lho)?|(lhos)?|(lhost:?\d*)?)$)/.test(url) === false) {
if (/^(\w|[0-9-_]){3,}$/.test(url) &&
/^(htt(ps?)?)|(loca((l)?|(lh)?|(lho)?|(lhos)?|(lhost:?\d*)?)$)/.test(url) === false) {
url = `${ url }.rocket.chat`;
}

View File

@ -76,7 +76,7 @@ export default class RoomView extends React.Component {
this.data = realm.objects('messages').filtered('_server.id = $0 AND rid = $1', this.props.server, this.rid).sorted('ts', true);
this.state = {
dataSource: ds.cloneWithRows(this.data),
dataSource: [],
loaded: true,
joined: typeof props.rid === 'undefined'
};
@ -96,9 +96,13 @@ export default class RoomView extends React.Component {
// this.setState({
// loaded: true
// });
this.data.addListener(this.updateState);
realm.addListener('change', this.updateState);
// });
// this.updateState();
this.state = {
...this.state,
dataSource: ds.cloneWithRows(this.getData())
};
}
componentDidMount() {
@ -106,7 +110,7 @@ export default class RoomView extends React.Component {
}
componentWillUnmount() {
this.data.removeListener(this.updateState);
realm.removeListener('change', this.updateState);
}
onEndReached = () => {
@ -128,9 +132,16 @@ export default class RoomView extends React.Component {
}
}
getData() {
return realm
.objects('messages')
.filtered('_server.id = $0 AND rid = $1', this.props.server, this.rid)
.sorted('ts', true);
}
updateState = debounce(() => {
this.setState({
dataSource: ds.cloneWithRows(this.data)
dataSource: ds.cloneWithRows(this.getData())
});
// RocketChat.readMessages(this.rid);
// this.setState({

View File

@ -73,19 +73,27 @@ export default class RoomsListView extends React.Component {
constructor(props) {
super(props);
this.data = realm.objects('subscriptions').filtered('_server.id = $0', this.props.server);
this.state = {
dataSource: ds.cloneWithRows(this.data),
dataSource: [],
searching: false,
searchDataSource: [],
searchText: '',
login: false
};
this.data.addListener(this.updateState);
}
componentWillMount() {
realm.addListener('change', this.updateState);
this.state = {
...this.state,
dataSource: ds.cloneWithRows(this.getData())
};
}
componentWillUnmount() {
this.data.removeListener(this.updateState);
realm.removeListener('change', this.updateState);
}
onSearchChangeText = (text) => {
@ -146,10 +154,13 @@ export default class RoomsListView extends React.Component {
});
}
getData() {
return realm.objects('subscriptions').filtered('_server.id = $0', this.props.server);
}
updateState = () => {
this.setState({
dataSource: ds.cloneWithRows(this.data)
dataSource: ds.cloneWithRows(this.getData())
});
};
@ -196,9 +207,11 @@ export default class RoomsListView extends React.Component {
navigateToRoom({ sid: id });
clearSearch();
}
_createChannel() {
this.props.navigation.navigate('CreateChannel');
}
renderSearchBar = () => (
<View style={styles.searchBoxView}>
<TextInput
@ -223,6 +236,7 @@ export default class RoomsListView extends React.Component {
onPress={() => this._onPressItem(item._id, item)}
/>
)
renderList = () => (
<ListView
dataSource={this.state.dataSource}
@ -234,13 +248,16 @@ export default class RoomsListView extends React.Component {
keyboardShouldPersistTaps='always'
/>
)
renderCreateButtons = () => (
<ActionButton buttonColor='rgba(231,76,60,1)'>
<ActionButton.Item buttonColor='#9b59b6' title='Create Channel' onPress={() => { this._createChannel(); }} >
<Icon name='md-chatbubbles' style={styles.actionButtonIcon} />
</ActionButton.Item>
</ActionButton>);
render= () => (
</ActionButton>
);
render = () => (
<View style={styles.container}>
<Banner />
{this.renderList()}