diff --git a/app/lib/methods/subscriptions/rooms.js b/app/lib/methods/subscriptions/rooms.js index f279f8b30..dca8c226e 100644 --- a/app/lib/methods/subscriptions/rooms.js +++ b/app/lib/methods/subscriptions/rooms.js @@ -9,6 +9,7 @@ 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(); @@ -103,19 +104,53 @@ const createOrUpdateSubscription = async(subscription, room) => { // Do nothing } + const batch = []; if (sub) { - await sub.update(protectedFunction((s) => { - Object.assign(s, tmp); - })); + batch.push( + sub.prepareUpdate(protectedFunction((s) => { + Object.assign(s, tmp); + })) + ); } else { - await subCollection.create(protectedFunction((s) => { - s._raw = sanitizedRaw({ id: tmp.rid }, subCollection.schema); - Object.assign(s, tmp); - if (s.roomUpdatedAt) { - s.roomUpdatedAt = new Date(); - } - })); + batch.push( + subCollection.prepareCreate(protectedFunction((s) => { + s._raw = sanitizedRaw({ id: tmp.rid }, subCollection.schema); + Object.assign(s, tmp); + if (s.roomUpdatedAt) { + s.roomUpdatedAt = new Date(); + } + })) + ); } + + if (sub.lastMessage) { + const lastMessage = buildMessage(sub.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) { log(e); diff --git a/app/sagas/rooms.js b/app/sagas/rooms.js index ef1d42dcf..2ddc9cfa8 100644 --- a/app/sagas/rooms.js +++ b/app/sagas/rooms.js @@ -11,6 +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'; const handleRoomsRequest = function* handleRoomsRequest() { try { @@ -26,17 +27,27 @@ const handleRoomsRequest = function* handleRoomsRequest() { const db = database.active; yield db.action(async() => { - const subCollection = db.collections.get('subscriptions'); if (!subscriptions.length) { return; } + const subCollection = db.collections.get('subscriptions'); + 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(); const subsToUpdate = existingSubs.filter(i1 => subscriptions.find(i2 => i1._id === i2._id)); 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 allRecords = [ ...subsToCreate.map(subscription => subCollection.prepareCreate((s) => { s._raw = sanitizedRaw({ id: subscription.rid }, subCollection.schema); @@ -47,6 +58,17 @@ 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); + }); }) ];