Skip to content

Commit

Permalink
[FIX] Purged threads still show as unread (#18944)
Browse files Browse the repository at this point in the history
Co-authored-by: Diego Sampaio <chinello@gmail.com>
Co-authored-by: Rodrigo Nascimento <rodrigoknascimento@gmail.com>
  • Loading branch information
3 people committed Sep 21, 2020
1 parent 14a2de5 commit 995b4e3
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 4 deletions.
18 changes: 14 additions & 4 deletions app/lib/server/functions/cleanRoomHistory.js
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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', {
Expand Down
23 changes: 23 additions & 0 deletions app/models/server/models/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
19 changes: 19 additions & 0 deletions app/models/server/models/Subscriptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
1 change: 1 addition & 0 deletions server/startup/migrations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,5 @@ import './v202';
import './v203';
import './v204';
import './v205';
import './v206';
import './xrun';
62 changes: 62 additions & 0 deletions server/startup/migrations/v206.js
Original file line number Diff line number Diff line change
@@ -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());
},
});

0 comments on commit 995b4e3

Please sign in to comment.