diff --git a/app/lib/methods/subscriptions/room.js b/app/lib/methods/subscriptions/room.js index 2dab116d5..46e3bba18 100644 --- a/app/lib/methods/subscriptions/room.js +++ b/app/lib/methods/subscriptions/room.js @@ -113,11 +113,14 @@ export default function subscribeRoom({ rid }) { // Do nothing } if (messageRecord) { - batch.push( - messageRecord.prepareUpdate(protectedFunction((m) => { + try { + const update = messageRecord.prepareUpdate((m) => { Object.assign(m, message); - })) - ); + }); + batch.push(update); + } catch (e) { + console.log(e); + } } else { batch.push( msgCollection.prepareCreate(protectedFunction((m) => { diff --git a/app/lib/methods/subscriptions/rooms.js b/app/lib/methods/subscriptions/rooms.js index f2ae92e45..91be40fc9 100644 --- a/app/lib/methods/subscriptions/rooms.js +++ b/app/lib/methods/subscriptions/rooms.js @@ -9,7 +9,6 @@ import random from '../../../utils/random'; import store from '../../createStore'; import { roomsRequest } from '../../../actions/rooms'; import { notificationReceived } from '../../../actions/notification'; -import buildMessage from '../helpers/buildMessage'; const removeListener = listener => listener.stop(); @@ -106,50 +105,56 @@ const createOrUpdateSubscription = async(subscription, room) => { const batch = []; if (sub) { - batch.push( - sub.prepareUpdate(protectedFunction((s) => { + try { + const update = sub.prepareUpdate((s) => { Object.assign(s, tmp); - })) - ); + }); + batch.push(update); + } catch (e) { + console.log(e); + } } else { - batch.push( - subCollection.prepareCreate(protectedFunction((s) => { + try { + const create = subCollection.prepareCreate((s) => { s._raw = sanitizedRaw({ id: tmp.rid }, subCollection.schema); Object.assign(s, tmp); if (s.roomUpdatedAt) { s.roomUpdatedAt = new Date(); } - })) - ); - } - - if (tmp.lastMessage) { - const lastMessage = buildMessage(tmp.lastMessage); - const messagesCollection = db.collections.get('messages'); - let messageRecord; - try { - messageRecord = await messagesCollection.find(lastMessage._id); - } catch (error) { - // Do nothing - } - - if (messageRecord) { - batch.push( - messageRecord.prepareUpdate(() => { - Object.assign(messageRecord, lastMessage); - }) - ); - } else { - batch.push( - messagesCollection.prepareCreate((m) => { - m._raw = sanitizedRaw({ id: lastMessage._id }, messagesCollection.schema); - m.subscription.id = lastMessage.rid; - return Object.assign(m, lastMessage); - }) - ); + }); + batch.push(create); + } catch (e) { + console.log(e); } } + // if (tmp.lastMessage) { + // const lastMessage = buildMessage(tmp.lastMessage); + // const messagesCollection = db.collections.get('messages'); + // let messageRecord; + // try { + // messageRecord = await messagesCollection.find(lastMessage._id); + // } catch (error) { + // // Do nothing + // } + + // if (messageRecord) { + // batch.push( + // messageRecord.prepareUpdate(() => { + // Object.assign(messageRecord, lastMessage); + // }) + // ); + // } else { + // batch.push( + // messagesCollection.prepareCreate((m) => { + // m._raw = sanitizedRaw({ id: lastMessage._id }, messagesCollection.schema); + // m.subscription.id = lastMessage.rid; + // return Object.assign(m, lastMessage); + // }) + // ); + // } + // } + await db.batch(...batch); }); } catch (e) { diff --git a/app/sagas/rooms.js b/app/sagas/rooms.js index 2ddc9cfa8..17da0b07f 100644 --- a/app/sagas/rooms.js +++ b/app/sagas/rooms.js @@ -11,7 +11,7 @@ import database from '../lib/database'; import log from '../utils/log'; import mergeSubscriptionsRooms from '../lib/methods/helpers/mergeSubscriptionsRooms'; import RocketChat from '../lib/rocketchat'; -import buildMessage from '../lib/methods/helpers/buildMessage'; +// import buildMessage from '../lib/methods/helpers/buildMessage'; const handleRoomsRequest = function* handleRoomsRequest() { try { @@ -32,7 +32,7 @@ const handleRoomsRequest = function* handleRoomsRequest() { } 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 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)); // TODO: subsToDelete? - const lastMessages = subscriptions - .map(sub => sub.lastMessage && buildMessage(sub.lastMessage)) - .filter(lm => lm); - const lastMessagesIds = lastMessages.map(lm => lm._id); - 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 messagesToCreate = lastMessages.filter(i1 => !existingMessages.find(i2 => i1._id === i2.id)); + // const lastMessages = subscriptions + // .map(sub => sub.lastMessage && buildMessage(sub.lastMessage)) + // .filter(lm => lm); + // const lastMessagesIds = lastMessages.map(lm => lm._id); + // 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 messagesToCreate = lastMessages.filter(i1 => !existingMessages.find(i2 => i1._id === i2.id)); const allRecords = [ ...subsToCreate.map(subscription => subCollection.prepareCreate((s) => { @@ -58,18 +58,18 @@ const handleRoomsRequest = function* handleRoomsRequest() { return subscription.prepareUpdate(() => { 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 { diff --git a/app/views/RoomView/List.js b/app/views/RoomView/List.js index 20ec82f39..fcafe65e7 100644 --- a/app/views/RoomView/List.js +++ b/app/views/RoomView/List.js @@ -3,10 +3,8 @@ import { ActivityIndicator, FlatList, InteractionManager } from 'react-native'; import PropTypes from 'prop-types'; -import debounce from 'lodash/debounce'; import orderBy from 'lodash/orderBy'; import { Q } from '@nozbe/watermelondb'; -import isEqual from 'lodash/isEqual'; import styles from './styles'; import database from '../../lib/database'; @@ -16,6 +14,7 @@ import log from '../../utils/log'; import EmptyRoom from './EmptyRoom'; import { isIOS } from '../../utils/deviceInfo'; import { animateNextTransition } from '../../utils/layoutAnimation'; +import debounce from '../../utils/debounce'; export class List extends React.Component { static propTypes = { @@ -63,16 +62,12 @@ export class List extends React.Component { } this.messagesObservable = db.collections .get('thread_messages') - .query( - Q.where('rid', tmid) - ) + .query(Q.where('rid', tmid)) .observeWithColumns(['_updated_at']); } else { this.messagesObservable = db.collections .get('messages') - .query( - Q.where('rid', rid) - ) + .query(Q.where('rid', rid)) .observeWithColumns(['_updated_at']); } @@ -84,8 +79,7 @@ export class List extends React.Component { } const messages = orderBy(data, ['ts'], ['desc']); if (this.mounted) { - animateNextTransition(); - this.setState({ messages }); + this.setState({ messages }, () => this.debouncedUpdate()); } else { this.state.messages = messages; } @@ -104,16 +98,13 @@ export class List extends React.Component { } shouldComponentUpdate(nextProps, nextState) { - const { messages, loading, end } = this.state; + const { loading, end } = this.state; if (loading !== nextState.loading) { return true; } if (end !== nextState.end) { return true; } - if (!isEqual(messages, nextState.messages)) { - return true; - } return false; } @@ -127,6 +118,9 @@ export class List extends React.Component { if (this.onEndReached && this.onEndReached.stop) { this.onEndReached.stop(); } + if (this.debouncedUpdate && this.debouncedUpdate.stop) { + this.debouncedUpdate.stop(); + } console.countReset(`${ this.constructor.name }.render calls`); } @@ -156,6 +150,17 @@ export class List extends React.Component { } }, 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 = () => { const { loading } = this.state; if (loading) { diff --git a/app/views/RoomView/index.js b/app/views/RoomView/index.js index a67b40324..e57ff2e12 100644 --- a/app/views/RoomView/index.js +++ b/app/views/RoomView/index.js @@ -152,6 +152,7 @@ class RoomView extends React.Component { this.beginAnimating = false; this.didFocusListener = props.navigation.addListener('didFocus', () => this.beginAnimating = true); this.messagebox = React.createRef(); + this.list = React.createRef(); this.willBlurListener = props.navigation.addListener('willBlur', () => this.mounted = false); this.mounted = false; console.timeEnd(`${ this.constructor.name } init`); @@ -496,6 +497,9 @@ class RoomView extends React.Component { sendMessage = (message, tmid) => { const { user } = this.props; RocketChat.sendMessage(this.rid, message, this.tmid || tmid, user).then(() => { + if (this.list && this.list.current) { + this.list.current.update(); + } this.setLastOpen(null); }); }; @@ -796,6 +800,7 @@ class RoomView extends React.Component {