[FIX] Load messages issues (#1373)

This commit is contained in:
Diego Mello 2019-11-07 16:53:39 -03:00 committed by GitHub
parent 5e4ce8feac
commit 0b68e98c2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 91 additions and 73 deletions

View File

@ -113,11 +113,14 @@ export default function subscribeRoom({ rid }) {
// Do nothing // Do nothing
} }
if (messageRecord) { if (messageRecord) {
batch.push( try {
messageRecord.prepareUpdate(protectedFunction((m) => { const update = messageRecord.prepareUpdate((m) => {
Object.assign(m, message); Object.assign(m, message);
})) });
); batch.push(update);
} catch (e) {
console.log(e);
}
} else { } else {
batch.push( batch.push(
msgCollection.prepareCreate(protectedFunction((m) => { msgCollection.prepareCreate(protectedFunction((m) => {

View File

@ -9,7 +9,6 @@ import random from '../../../utils/random';
import store from '../../createStore'; import store from '../../createStore';
import { roomsRequest } from '../../../actions/rooms'; import { roomsRequest } from '../../../actions/rooms';
import { notificationReceived } from '../../../actions/notification'; import { notificationReceived } from '../../../actions/notification';
import buildMessage from '../helpers/buildMessage';
const removeListener = listener => listener.stop(); const removeListener = listener => listener.stop();
@ -106,49 +105,55 @@ const createOrUpdateSubscription = async(subscription, room) => {
const batch = []; const batch = [];
if (sub) { if (sub) {
batch.push( try {
sub.prepareUpdate(protectedFunction((s) => { const update = sub.prepareUpdate((s) => {
Object.assign(s, tmp); Object.assign(s, tmp);
})) });
); batch.push(update);
} catch (e) {
console.log(e);
}
} else { } else {
batch.push( try {
subCollection.prepareCreate(protectedFunction((s) => { const create = subCollection.prepareCreate((s) => {
s._raw = sanitizedRaw({ id: tmp.rid }, subCollection.schema); s._raw = sanitizedRaw({ id: tmp.rid }, subCollection.schema);
Object.assign(s, tmp); Object.assign(s, tmp);
if (s.roomUpdatedAt) { if (s.roomUpdatedAt) {
s.roomUpdatedAt = new Date(); s.roomUpdatedAt = new Date();
} }
})) });
); batch.push(create);
} catch (e) {
console.log(e);
}
} }
if (tmp.lastMessage) { // if (tmp.lastMessage) {
const lastMessage = buildMessage(tmp.lastMessage); // const lastMessage = buildMessage(tmp.lastMessage);
const messagesCollection = db.collections.get('messages'); // const messagesCollection = db.collections.get('messages');
let messageRecord; // let messageRecord;
try { // try {
messageRecord = await messagesCollection.find(lastMessage._id); // messageRecord = await messagesCollection.find(lastMessage._id);
} catch (error) { // } catch (error) {
// Do nothing // // Do nothing
} // }
if (messageRecord) { // if (messageRecord) {
batch.push( // batch.push(
messageRecord.prepareUpdate(() => { // messageRecord.prepareUpdate(() => {
Object.assign(messageRecord, lastMessage); // Object.assign(messageRecord, lastMessage);
}) // })
); // );
} else { // } else {
batch.push( // batch.push(
messagesCollection.prepareCreate((m) => { // messagesCollection.prepareCreate((m) => {
m._raw = sanitizedRaw({ id: lastMessage._id }, messagesCollection.schema); // m._raw = sanitizedRaw({ id: lastMessage._id }, messagesCollection.schema);
m.subscription.id = lastMessage.rid; // m.subscription.id = lastMessage.rid;
return Object.assign(m, lastMessage); // return Object.assign(m, lastMessage);
}) // })
); // );
} // }
} // }
await db.batch(...batch); await db.batch(...batch);
}); });

View File

@ -11,7 +11,7 @@ import database from '../lib/database';
import log from '../utils/log'; import log from '../utils/log';
import mergeSubscriptionsRooms from '../lib/methods/helpers/mergeSubscriptionsRooms'; import mergeSubscriptionsRooms from '../lib/methods/helpers/mergeSubscriptionsRooms';
import RocketChat from '../lib/rocketchat'; import RocketChat from '../lib/rocketchat';
import buildMessage from '../lib/methods/helpers/buildMessage'; // import buildMessage from '../lib/methods/helpers/buildMessage';
const handleRoomsRequest = function* handleRoomsRequest() { const handleRoomsRequest = function* handleRoomsRequest() {
try { try {
@ -32,7 +32,7 @@ const handleRoomsRequest = function* handleRoomsRequest() {
} }
const subCollection = db.collections.get('subscriptions'); const subCollection = db.collections.get('subscriptions');
const messagesCollection = db.collections.get('messages'); // const messagesCollection = db.collections.get('messages');
const subsIds = subscriptions.map(sub => sub.rid); const subsIds = subscriptions.map(sub => sub.rid);
const existingSubs = await subCollection.query(Q.where('id', Q.oneOf(subsIds))).fetch(); const existingSubs = await subCollection.query(Q.where('id', Q.oneOf(subsIds))).fetch();
@ -40,13 +40,13 @@ const handleRoomsRequest = function* handleRoomsRequest() {
const subsToCreate = subscriptions.filter(i1 => !existingSubs.find(i2 => i1._id === i2._id)); const subsToCreate = subscriptions.filter(i1 => !existingSubs.find(i2 => i1._id === i2._id));
// TODO: subsToDelete? // TODO: subsToDelete?
const lastMessages = subscriptions // const lastMessages = subscriptions
.map(sub => sub.lastMessage && buildMessage(sub.lastMessage)) // .map(sub => sub.lastMessage && buildMessage(sub.lastMessage))
.filter(lm => lm); // .filter(lm => lm);
const lastMessagesIds = lastMessages.map(lm => lm._id); // const lastMessagesIds = lastMessages.map(lm => lm._id);
const existingMessages = await messagesCollection.query(Q.where('id', Q.oneOf(lastMessagesIds))).fetch(); // const existingMessages = await messagesCollection.query(Q.where('id', Q.oneOf(lastMessagesIds))).fetch();
const messagesToUpdate = existingMessages.filter(i1 => lastMessages.find(i2 => i1.id === i2._id)); // const messagesToUpdate = existingMessages.filter(i1 => lastMessages.find(i2 => i1.id === i2._id));
const messagesToCreate = lastMessages.filter(i1 => !existingMessages.find(i2 => i1._id === i2.id)); // const messagesToCreate = lastMessages.filter(i1 => !existingMessages.find(i2 => i1._id === i2.id));
const allRecords = [ const allRecords = [
...subsToCreate.map(subscription => subCollection.prepareCreate((s) => { ...subsToCreate.map(subscription => subCollection.prepareCreate((s) => {
@ -58,18 +58,18 @@ const handleRoomsRequest = function* handleRoomsRequest() {
return subscription.prepareUpdate(() => { return subscription.prepareUpdate(() => {
Object.assign(subscription, newSub); Object.assign(subscription, newSub);
}); });
}),
...messagesToCreate.map(message => messagesCollection.prepareCreate((m) => {
m._raw = sanitizedRaw({ id: message._id }, messagesCollection.schema);
m.subscription.id = message.rid;
return Object.assign(m, message);
})),
...messagesToUpdate.map((message) => {
const newMessage = lastMessages.find(m => m._id === message.id);
return message.prepareUpdate(() => {
Object.assign(message, newMessage);
});
}) })
// ...messagesToCreate.map(message => messagesCollection.prepareCreate((m) => {
// m._raw = sanitizedRaw({ id: message._id }, messagesCollection.schema);
// m.subscription.id = message.rid;
// return Object.assign(m, message);
// })),
// ...messagesToUpdate.map((message) => {
// const newMessage = lastMessages.find(m => m._id === message.id);
// return message.prepareUpdate(() => {
// Object.assign(message, newMessage);
// });
// })
]; ];
try { try {

View File

@ -3,10 +3,8 @@ import {
ActivityIndicator, FlatList, InteractionManager ActivityIndicator, FlatList, InteractionManager
} from 'react-native'; } from 'react-native';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import debounce from 'lodash/debounce';
import orderBy from 'lodash/orderBy'; import orderBy from 'lodash/orderBy';
import { Q } from '@nozbe/watermelondb'; import { Q } from '@nozbe/watermelondb';
import isEqual from 'lodash/isEqual';
import styles from './styles'; import styles from './styles';
import database from '../../lib/database'; import database from '../../lib/database';
@ -16,6 +14,7 @@ import log from '../../utils/log';
import EmptyRoom from './EmptyRoom'; import EmptyRoom from './EmptyRoom';
import { isIOS } from '../../utils/deviceInfo'; import { isIOS } from '../../utils/deviceInfo';
import { animateNextTransition } from '../../utils/layoutAnimation'; import { animateNextTransition } from '../../utils/layoutAnimation';
import debounce from '../../utils/debounce';
export class List extends React.Component { export class List extends React.Component {
static propTypes = { static propTypes = {
@ -63,16 +62,12 @@ export class List extends React.Component {
} }
this.messagesObservable = db.collections this.messagesObservable = db.collections
.get('thread_messages') .get('thread_messages')
.query( .query(Q.where('rid', tmid))
Q.where('rid', tmid)
)
.observeWithColumns(['_updated_at']); .observeWithColumns(['_updated_at']);
} else { } else {
this.messagesObservable = db.collections this.messagesObservable = db.collections
.get('messages') .get('messages')
.query( .query(Q.where('rid', rid))
Q.where('rid', rid)
)
.observeWithColumns(['_updated_at']); .observeWithColumns(['_updated_at']);
} }
@ -84,8 +79,7 @@ export class List extends React.Component {
} }
const messages = orderBy(data, ['ts'], ['desc']); const messages = orderBy(data, ['ts'], ['desc']);
if (this.mounted) { if (this.mounted) {
animateNextTransition(); this.setState({ messages }, () => this.debouncedUpdate());
this.setState({ messages });
} else { } else {
this.state.messages = messages; this.state.messages = messages;
} }
@ -104,16 +98,13 @@ export class List extends React.Component {
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
const { messages, loading, end } = this.state; const { loading, end } = this.state;
if (loading !== nextState.loading) { if (loading !== nextState.loading) {
return true; return true;
} }
if (end !== nextState.end) { if (end !== nextState.end) {
return true; return true;
} }
if (!isEqual(messages, nextState.messages)) {
return true;
}
return false; return false;
} }
@ -127,6 +118,9 @@ export class List extends React.Component {
if (this.onEndReached && this.onEndReached.stop) { if (this.onEndReached && this.onEndReached.stop) {
this.onEndReached.stop(); this.onEndReached.stop();
} }
if (this.debouncedUpdate && this.debouncedUpdate.stop) {
this.debouncedUpdate.stop();
}
console.countReset(`${ this.constructor.name }.render calls`); console.countReset(`${ this.constructor.name }.render calls`);
} }
@ -156,6 +150,17 @@ export class List extends React.Component {
} }
}, 300) }, 300)
// eslint-disable-next-line react/sort-comp
update = () => {
animateNextTransition();
this.forceUpdate();
};
// eslint-disable-next-line react/sort-comp
debouncedUpdate = debounce(() => {
this.update();
}, 300)
renderFooter = () => { renderFooter = () => {
const { loading } = this.state; const { loading } = this.state;
if (loading) { if (loading) {

View File

@ -152,6 +152,7 @@ class RoomView extends React.Component {
this.beginAnimating = false; this.beginAnimating = false;
this.didFocusListener = props.navigation.addListener('didFocus', () => this.beginAnimating = true); this.didFocusListener = props.navigation.addListener('didFocus', () => this.beginAnimating = true);
this.messagebox = React.createRef(); this.messagebox = React.createRef();
this.list = React.createRef();
this.willBlurListener = props.navigation.addListener('willBlur', () => this.mounted = false); this.willBlurListener = props.navigation.addListener('willBlur', () => this.mounted = false);
this.mounted = false; this.mounted = false;
console.timeEnd(`${ this.constructor.name } init`); console.timeEnd(`${ this.constructor.name } init`);
@ -496,6 +497,9 @@ class RoomView extends React.Component {
sendMessage = (message, tmid) => { sendMessage = (message, tmid) => {
const { user } = this.props; const { user } = this.props;
RocketChat.sendMessage(this.rid, message, this.tmid || tmid, user).then(() => { RocketChat.sendMessage(this.rid, message, this.tmid || tmid, user).then(() => {
if (this.list && this.list.current) {
this.list.current.update();
}
this.setLastOpen(null); this.setLastOpen(null);
}); });
}; };
@ -796,6 +800,7 @@ class RoomView extends React.Component {
<SafeAreaView style={styles.container} testID='room-view' forceInset={{ vertical: 'never' }}> <SafeAreaView style={styles.container} testID='room-view' forceInset={{ vertical: 'never' }}>
<StatusBar /> <StatusBar />
<List <List
ref={this.list}
rid={rid} rid={rid}
t={t} t={t}
tmid={this.tmid} tmid={this.tmid}