3 var Promise = require('bluebird');
4 var persistence = require('gitter-web-persistence');
5 var _ = require('lodash');
6 var debug = require('debug')('gitter:app:recent-room-core');
9 var DEFAULT_LAST_ACCESS_TIME = new Date('2015-07-01T00:00:00Z');
11 function clearLastVisitedTroupeforUserId(userId, troupeId) {
12 debug('recent-rooms: Clearing last visited Troupe for user: %s to troupe %s', userId, troupeId);
15 setOp['troupes.' + troupeId] = 1;
17 // Update UserTroupeLastAccess
18 return persistence.UserTroupeLastAccess.update(
21 { upsert: true, new: true }
26 * Returns Promise of true if an update actually happened
28 function saveUserTroupeLastAccess(userId, troupeId, lastAccessTime) {
30 if (!(lastAccessTime instanceof Date)) {
31 lastAccessTime = new Date(lastAccessTime);
34 lastAccessTime = new Date();
38 maxOp['troupes.' + troupeId] = lastAccessTime;
39 maxOp['last.' + troupeId] = lastAccessTime;
41 return persistence.UserTroupeLastAccess.update(
48 .then(function(result) {
49 return !!(result.nModified || (result.upserted && result.upserted.length));
53 function getTroupeLastAccessTimesForUserExcludingHidden(userId) {
54 return persistence.UserTroupeLastAccess.findOne(
56 { _id: 0, troupes: 1 },
60 .then(function(userTroupeLastAccess) {
61 if (!userTroupeLastAccess || !userTroupeLastAccess.troupes) return {};
62 return userTroupeLastAccess.troupes;
67 * Get the last access times for a user.
68 * @param userId user we're getting the last access time for
69 * @return promise of a hash of { troupeId1: accessDate, troupeId2: accessDate ... }
71 function getTroupeLastAccessTimesForUser(userId) {
72 return persistence.UserTroupeLastAccess.findOne(
74 { _id: 0, last: 1, troupes: 1 },
78 .then(function(userTroupeLastAccess) {
79 if (!userTroupeLastAccess) return {};
81 // Merge the results from `last` and `troupe`, giving priority to
82 // the values from last
83 return _.extend({}, userTroupeLastAccess.troupes, userTroupeLastAccess.last);
88 * Returns a hash of the last access times for an array of userIds for a given room.
89 * If the user has never accessed the room, the value will represent the
90 * date the user was added to the room, or the date this feature was deployed
91 * as a default ~1 July 2015.
93 function findLastAccessTimesForUsersInRoom(roomId, userIds) {
94 if (!userIds.length) return Promise.resolve({});
96 var troupesKey = 'troupes.' + roomId;
97 var lastKey = 'last.' + roomId;
98 var addedKey = 'added.' + roomId;
100 var orClause = [{}, {}, {}];
101 orClause[0][troupesKey] = { $exists: true };
102 orClause[1][lastKey] = { $exists: true };
103 orClause[2][addedKey] = { $exists: true };
105 var query = { userId: { $in: userIds }, $or: orClause };
107 var select = { userId: 1, _id: 0 };
108 select[troupesKey] = 1;
110 select[addedKey] = 1;
112 return persistence.UserTroupeLastAccess.find(query, select, { lean: true })
114 .then(function(lastAccessTimes) {
115 var lastAccessTimesHash = lastAccessTimes.reduce(function(memo, item) {
116 // Use the last date by default, falling back to the troupes hash for
117 // backwards compatibility
119 (item.last && item.last[roomId]) ||
120 (item.troupes && item.troupes[roomId]) ||
121 (item.added && item.added[roomId]);
125 return userIds.reduce(function(memo, userId) {
126 memo[userId] = lastAccessTimesHash[userId] || DEFAULT_LAST_ACCESS_TIME;
133 saveUserTroupeLastAccess,
134 getTroupeLastAccessTimesForUserExcludingHidden,
135 getTroupeLastAccessTimesForUser,
136 findLastAccessTimesForUsersInRoom,
137 clearLastVisitedTroupeforUserId