[FIX] Purged threads still show as unread (#18944)

Co-authored-by: Diego Sampaio <chinello@gmail.com>
Co-authored-by: Rodrigo Nascimento <rodrigoknascimento@gmail.com>
pull/18882/head^2
Felipe Parreira 6 years ago committed by GitHub
parent 14a2de551a
commit 995b4e3ff8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      app/lib/server/functions/cleanRoomHistory.js
  2. 23
      app/models/server/models/Messages.js
  3. 19
      app/models/server/models/Subscriptions.js
  4. 1
      server/startup/migrations/index.js
  5. 62
      server/startup/migrations/v206.js

@ -1,9 +1,9 @@
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { deleteRoom } from './deleteRoom';
import { FileUpload } from '../../../file-upload';
import { Messages, Rooms } from '../../../models';
import { Notifications } from '../../../notifications';
import { FileUpload } from '../../../file-upload/server';
import { Messages, Rooms, Subscriptions } from '../../../models/server';
import { Notifications } from '../../../notifications/server';
export const cleanRoomHistory = function({ rid, latest = new Date(), oldest = new Date('0001-01-01T00:00:00Z'), inclusive = true, limit = 0, excludePinned = true, ignoreDiscussion = true, filesOnly = false, fromUsers = [], ignoreThreads = true }) {
const gt = inclusive ? '$gte' : '$gt';
@ -39,7 +39,17 @@ export const cleanRoomHistory = function({ rid, latest = new Date(), oldest = ne
.forEach(({ drid }) => deleteRoom(drid));
}
const count = Messages.removeByIdPinnedTimestampLimitAndUsers(rid, excludePinned, ignoreDiscussion, ts, limit, fromUsers);
if (!ignoreThreads) {
const threads = new Set();
Messages.findThreadsByRoomIdPinnedTimestampAndUsers({ rid, pinned: excludePinned, ignoreDiscussion, ts, users: fromUsers }, { fields: { _id: 1 } })
.forEach(({ _id }) => threads.add(_id));
if (threads.size > 0) {
Subscriptions.removeUnreadThreadsByRoomId(rid, [...threads]);
}
}
const count = Messages.removeByIdPinnedTimestampLimitAndUsers(rid, excludePinned, ignoreDiscussion, ts, limit, fromUsers, ignoreThreads);
if (count) {
Rooms.resetLastMessageById(rid);
Notifications.notifyRoom(rid, 'deleteMessageBulk', {

@ -929,6 +929,29 @@ export class Messages extends Base {
return this.remove({ rid: { $in: rids } });
}
findThreadsByRoomIdPinnedTimestampAndUsers({ rid, pinned, ignoreDiscussion = true, ts, users = [] }, options) {
const query = {
rid,
ts,
tlm: { $exists: 1 },
tcount: { $exists: 1 },
};
if (pinned) {
query.pinned = { $ne: true };
}
if (ignoreDiscussion) {
query.drid = { $exists: 0 };
}
if (users.length > 0) {
query['u.username'] = { $in: users };
}
return this.find(query, options);
}
removeByIdPinnedTimestampLimitAndUsers(rid, pinned, ignoreDiscussion = true, ts, limit, users = [], ignoreThreads = true) {
const query = {
rid,

@ -1420,11 +1420,30 @@ export class Subscriptions extends Base {
const update = {
$unset: {
tunread: 1,
tunreadUser: 1,
tunreadGroup: 1,
},
};
return this.update(query, update);
}
removeUnreadThreadsByRoomId(rid, tunread) {
const query = {
rid,
tunread,
};
const update = {
$pullAll: {
tunread,
tunreadUser: tunread,
tunreadGroup: tunread,
},
};
return this.update(query, update, { multi: true });
}
}
export default new Subscriptions('subscription', true);

@ -202,4 +202,5 @@ import './v202';
import './v203';
import './v204';
import './v205';
import './v206';
import './xrun';

@ -0,0 +1,62 @@
import { Migrations } from '../../../app/migrations';
import { Subscriptions, Messages } from '../../../app/models/server/raw';
async function migrate() {
const subs = await Subscriptions.find({
$or: [{
'tunread.0': { $exists: true },
}, {
'tunreadUser.0': { $exists: true },
}, {
'tunreadGroup.0': { $exists: true },
}],
}, {
projection: {
_id: 0,
tunread: 1,
tunreadUser: 1,
tunreadGroup: 1,
},
}).toArray();
// Get unique thread ids
const tunreads = new Set();
for (const { tunread = [], tunreadUser = [], tunreadGroup = [] } of subs) {
tunread.forEach((i) => tunreads.add(i));
tunreadUser.forEach((i) => tunreads.add(i));
tunreadGroup.forEach((i) => tunreads.add(i));
}
const inexistentThreads = new Set();
for await (const tunread of tunreads) {
if (!await Messages.findOne({ _id: tunread }, { _id: 1 })) {
inexistentThreads.add(tunread);
}
}
const inexistentThreadsArr = [...inexistentThreads];
await Subscriptions.update({
$or: [{
tunread: { $in: inexistentThreadsArr },
}, {
tunreadUser: { $in: inexistentThreadsArr },
}, {
tunreadGroup: { $in: inexistentThreadsArr },
}],
}, {
$pullAll: {
tunread: inexistentThreadsArr,
tunreadUser: inexistentThreadsArr,
tunreadGroup: inexistentThreadsArr,
},
});
}
Migrations.add({
version: 206,
up() {
Promise.await(migrate());
},
});
Loading…
Cancel
Save