| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | var async = require('async'); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | var db = require('../database'); | 
					
						
							|  |  |  | var user = require('../user'); | 
					
						
							|  |  |  | var notifications = require('../notifications'); | 
					
						
							|  |  |  | var categories = require('../categories'); | 
					
						
							|  |  |  | var privileges = require('../privileges'); | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | var meta = require('../meta'); | 
					
						
							|  |  |  | var utils = require('../../public/src/utils'); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | module.exports = function (Topics) { | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.getTotalUnread = function (uid, filter, callback) { | 
					
						
							| 
									
										
										
										
											2016-03-25 22:18:49 -05:00
										 |  |  | 		if (!callback) { | 
					
						
							| 
									
										
										
										
											2016-04-08 13:42:47 -05:00
										 |  |  | 			callback = filter; | 
					
						
							|  |  |  | 			filter = ''; | 
					
						
							| 
									
										
										
										
											2016-03-25 22:18:49 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 		Topics.getUnreadTids(0, uid, filter, function (err, tids) { | 
					
						
							| 
									
										
										
										
											2016-05-13 14:08:50 +03:00
										 |  |  | 			callback(err, Array.isArray(tids) ? tids.length : 0); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-13 14:08:50 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.getUnreadTopics = function (cid, uid, start, stop, filter, callback) { | 
					
						
							| 
									
										
										
										
											2016-03-25 22:18:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 		var unreadTopics = { | 
					
						
							|  |  |  | 			showSelect: true, | 
					
						
							| 
									
										
										
										
											2017-02-18 01:27:46 -07:00
										 |  |  | 			nextStart: 0, | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			topics: [], | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 18:19:30 -05:00
										 |  |  | 		async.waterfall([ | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (next) { | 
					
						
							| 
									
										
										
										
											2016-05-13 14:08:50 +03:00
										 |  |  | 				Topics.getUnreadTids(cid, uid, filter, next); | 
					
						
							| 
									
										
										
										
											2015-01-23 18:19:30 -05:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (tids, next) { | 
					
						
							| 
									
										
										
										
											2016-05-13 14:08:50 +03:00
										 |  |  | 				unreadTopics.topicCount = tids.length; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 18:19:30 -05:00
										 |  |  | 				if (!tids.length) { | 
					
						
							|  |  |  | 					return next(null, []); | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-05-13 14:08:50 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (stop === -1) { | 
					
						
							|  |  |  | 					tids = tids.slice(start); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					tids = tids.slice(start, stop + 1); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 18:19:30 -05:00
										 |  |  | 				Topics.getTopicsByTids(tids, uid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (topicData, next) { | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 				if (!Array.isArray(topicData) || !topicData.length) { | 
					
						
							| 
									
										
										
										
											2015-01-23 18:19:30 -05:00
										 |  |  | 					return next(null, unreadTopics); | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-02 17:46:39 -04:00
										 |  |  | 				unreadTopics.topics = topicData; | 
					
						
							|  |  |  | 				unreadTopics.nextStart = stop + 1; | 
					
						
							| 
									
										
										
										
											2015-01-23 18:19:30 -05:00
										 |  |  | 				next(null, unreadTopics); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2015-01-23 18:19:30 -05:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.unreadCutoff = function () { | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 		return Date.now() - (parseInt(meta.config.unreadCutoff, 10) || 2) * 86400000; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.getUnreadTids = function (cid, uid, filter, callback) { | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 		uid = parseInt(uid, 10); | 
					
						
							| 
									
										
										
										
											2014-08-09 16:15:22 -04:00
										 |  |  | 		if (uid === 0) { | 
					
						
							| 
									
										
										
										
											2014-09-16 12:38:27 -04:00
										 |  |  | 			return callback(null, []); | 
					
						
							| 
									
										
										
										
											2014-08-15 18:11:57 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 		var cutoff = Topics.unreadCutoff(); | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 		var ignoredCids; | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				async.parallel({ | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 					ignoredCids: function (next) { | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 						if (filter === 'watched') { | 
					
						
							|  |  |  | 							return next(null, []); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						user.getIgnoredCategories(uid, next); | 
					
						
							|  |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 					ignoredTids: function (next) { | 
					
						
							| 
									
										
										
										
											2016-05-18 19:02:43 +03:00
										 |  |  | 						user.getIgnoredTids(uid, 0, -1, next); | 
					
						
							|  |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 					recentTids: function (next) { | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 						db.getSortedSetRevRangeByScoreWithScores('topics:recent', 0, -1, '+inf', cutoff, next); | 
					
						
							|  |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 					userScores: function (next) { | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 						db.getSortedSetRevRangeByScoreWithScores('uid:' + uid + ':tids_read', 0, -1, '+inf', cutoff, next); | 
					
						
							|  |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 					tids_unread: function (next) { | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 						db.getSortedSetRevRangeWithScores('uid:' + uid + ':tids_unread', 0, -1, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 				}, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (results, next) { | 
					
						
							|  |  |  | 				if (results.recentTids && !results.recentTids.length && !results.tids_unread.length) { | 
					
						
							|  |  |  | 					return callback(null, []); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 				ignoredCids = results.ignoredCids; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				var userRead = {}; | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				results.userScores.forEach(function (userItem) { | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 					userRead[userItem.value] = userItem.score; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				results.recentTids = results.recentTids.concat(results.tids_unread); | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				results.recentTids.sort(function (a, b) { | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 					return b.score - a.score; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				var tids = results.recentTids.filter(function (recentTopic) { | 
					
						
							| 
									
										
										
										
											2016-05-18 19:02:43 +03:00
										 |  |  | 					if (results.ignoredTids.indexOf(recentTopic.value.toString()) !== -1) { | 
					
						
							|  |  |  | 						return false; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 					switch (filter) { | 
					
						
							|  |  |  | 						case 'new': | 
					
						
							|  |  |  | 							return !userRead[recentTopic.value]; | 
					
						
							|  |  |  | 						default: | 
					
						
							|  |  |  | 							return !userRead[recentTopic.value] || recentTopic.score > userRead[recentTopic.value]; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				}).map(function (topic) { | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 					return topic.value; | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				}).filter(function (tid, index, array) { | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 					return array.indexOf(tid) === index; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (filter === 'watched') { | 
					
						
							| 
									
										
										
										
											2016-11-03 13:06:21 +03:00
										 |  |  | 					Topics.filterWatchedTids(tids, uid, next); | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 				} else { | 
					
						
							|  |  |  | 					next(null, tids); | 
					
						
							| 
									
										
										
										
											2016-04-08 13:42:47 -05:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			function (tids, next) { | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-13 14:08:50 +03:00
										 |  |  | 				tids = tids.slice(0, 200); | 
					
						
							| 
									
										
										
										
											2014-10-14 14:27:45 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-19 13:11:42 +03:00
										 |  |  | 				filterTopics(uid, tids, cid, ignoredCids, filter, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-04-18 15:44:07 +03:00
										 |  |  | 		], callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-19 13:11:42 +03:00
										 |  |  | 	function filterTopics(uid, tids, cid, ignoredCids, filter, callback) { | 
					
						
							| 
									
										
										
										
											2014-09-16 12:38:27 -04:00
										 |  |  | 		if (!Array.isArray(ignoredCids) || !tids.length) { | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 			return callback(null, tids); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-14 19:52:25 -05:00
										 |  |  | 		async.waterfall([ | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (next) { | 
					
						
							| 
									
										
										
										
											2015-04-18 16:34:32 -04:00
										 |  |  | 				privileges.topics.filterTids('read', tids, uid, next); | 
					
						
							| 
									
										
										
										
											2014-11-14 19:52:25 -05:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (tids, next) { | 
					
						
							| 
									
										
										
										
											2016-05-19 13:11:42 +03:00
										 |  |  | 				async.parallel({ | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 					topics: function (next) { | 
					
						
							| 
									
										
										
										
											2016-05-19 13:11:42 +03:00
										 |  |  | 						Topics.getTopicsFields(tids, ['tid', 'cid'], next); | 
					
						
							|  |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 					isTopicsFollowed: function (next) { | 
					
						
							| 
									
										
										
										
											2016-05-19 13:11:42 +03:00
										 |  |  | 						if (filter === 'watched' || filter === 'new') { | 
					
						
							|  |  |  | 							return next(null, []); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						db.sortedSetScores('uid:' + uid + ':followed_tids', tids, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2016-05-19 13:11:42 +03:00
										 |  |  | 				}, next); | 
					
						
							| 
									
										
										
										
											2014-11-14 19:52:25 -05:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (results, next) { | 
					
						
							| 
									
										
										
										
											2016-05-19 13:11:42 +03:00
										 |  |  | 				var topics = results.topics; | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				tids = topics.filter(function (topic, index) { | 
					
						
							| 
									
										
										
										
											2016-05-19 13:11:42 +03:00
										 |  |  | 					return topic && topic.cid && | 
					
						
							|  |  |  | 						(!!results.isTopicsFollowed[index] || ignoredCids.indexOf(topic.cid.toString()) === -1) && | 
					
						
							|  |  |  | 						(!cid || parseInt(cid, 10) === parseInt(topic.cid, 10)); | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				}).map(function (topic) { | 
					
						
							| 
									
										
										
										
											2014-11-14 19:52:25 -05:00
										 |  |  | 					return topic.tid; | 
					
						
							| 
									
										
										
										
											2014-11-14 17:31:39 -05:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2014-11-14 19:52:25 -05:00
										 |  |  | 				next(null, tids); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2014-11-14 19:52:25 -05:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.pushUnreadCount = function (uid, callback) { | 
					
						
							|  |  |  | 		callback = callback || function () {}; | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-16 11:06:10 -04:00
										 |  |  | 		if (!uid || parseInt(uid, 10) === 0) { | 
					
						
							|  |  |  | 			return callback(); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 		Topics.getTotalUnread(uid, function (err, count) { | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 			if (err) { | 
					
						
							| 
									
										
										
										
											2014-09-16 11:06:10 -04:00
										 |  |  | 				return callback(err); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-20 19:19:50 -04:00
										 |  |  | 			require('../socket.io').in('uid_' + uid).emit('event:unread.updateCount', count); | 
					
						
							| 
									
										
										
										
											2014-09-16 11:06:10 -04:00
										 |  |  | 			callback(); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.markAsUnreadForAll = function (tid, callback) { | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 		Topics.markCategoryUnreadForAll(tid, callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.markAsRead = function (tids, uid, callback) { | 
					
						
							|  |  |  | 		callback = callback || function () {}; | 
					
						
							| 
									
										
										
										
											2014-09-10 21:44:19 -04:00
										 |  |  | 		if (!Array.isArray(tids) || !tids.length) { | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 			return callback(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 		tids = tids.filter(function (tid, index, array) { | 
					
						
							| 
									
										
										
										
											2016-01-04 22:50:35 +02:00
										 |  |  | 			return tid && utils.isNumber(tid) && array.indexOf(tid) === index; | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-27 10:36:30 -05:00
										 |  |  | 		if (!tids.length) { | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 			return callback(null, false); | 
					
						
							| 
									
										
										
										
											2015-01-27 10:36:30 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				async.parallel({ | 
					
						
							|  |  |  | 					topicScores: async.apply(db.sortedSetScores, 'topics:recent', tids), | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 					userScores: async.apply(db.sortedSetScores, 'uid:' + uid + ':tids_read', tids), | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 				}, next); | 
					
						
							| 
									
										
										
										
											2014-09-10 21:44:19 -04:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 			function (results, next) { | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				tids = tids.filter(function (tid, index) { | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 					return results.topicScores[index] && (!results.userScores[index] || results.userScores[index] < results.topicScores[index]); | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2015-01-27 10:36:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 				if (!tids.length) { | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 					return callback(null, false); | 
					
						
							| 
									
										
										
										
											2014-10-14 02:39:20 -04:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 				var now = Date.now(); | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				var scores = tids.map(function () { | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 					return now; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				async.parallel({ | 
					
						
							|  |  |  | 					markRead: async.apply(db.sortedSetAdd, 'uid:' + uid + ':tids_read', scores, tids), | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 					markUnread: async.apply(db.sortedSetRemove, 'uid:' + uid + ':tids_unread', tids), | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 					topicData: async.apply(Topics.getTopicsFields, tids, ['cid']), | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 				}, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (results, next) { | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				var cids = results.topicData.map(function (topic) { | 
					
						
							| 
									
										
										
										
											2014-10-14 02:39:20 -04:00
										 |  |  | 					return topic && topic.cid; | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 				}).filter(function (topic, index, array) { | 
					
						
							| 
									
										
										
										
											2014-10-14 02:39:20 -04:00
										 |  |  | 					return topic && array.indexOf(topic) === index; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 				categories.markAsRead(cids, uid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				next(null, true); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:48:32 -04:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.markAllRead = function (uid, callback) { | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				db.getSortedSetRevRangeByScore('topics:recent', 0, -1, '+inf', Topics.unreadCutoff(), next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (tids, next) { | 
					
						
							| 
									
										
										
										
											2016-09-19 23:43:50 +03:00
										 |  |  | 				Topics.markTopicNotificationsRead(tids, uid); | 
					
						
							| 
									
										
										
										
											2016-01-07 20:29:31 +02:00
										 |  |  | 				Topics.markAsRead(tids, uid, next); | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			function (markedRead, next) { | 
					
						
							|  |  |  | 				db.delete('uid:' + uid + ':tids_unread', next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 		], callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-28 14:15:20 +03:00
										 |  |  | 	Topics.markTopicNotificationsRead = function (tids, uid, callback) { | 
					
						
							|  |  |  | 		callback = callback || function () {}; | 
					
						
							| 
									
										
										
										
											2016-09-19 23:43:50 +03:00
										 |  |  | 		if (!Array.isArray(tids) || !tids.length) { | 
					
						
							| 
									
										
										
										
											2016-11-28 14:15:20 +03:00
										 |  |  | 			return callback(); | 
					
						
							| 
									
										
										
										
											2014-09-19 19:45:16 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-09-19 23:43:50 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		async.waterfall([ | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (next) { | 
					
						
							| 
									
										
										
										
											2016-09-19 23:43:50 +03:00
										 |  |  | 				user.notifications.getUnreadByField(uid, 'tid', tids, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			function (nids, next) { | 
					
						
							| 
									
										
										
										
											2016-09-19 23:43:50 +03:00
										 |  |  | 				notifications.markReadMultiple(nids, uid, next); | 
					
						
							| 
									
										
										
										
											2016-11-28 14:15:20 +03:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				user.notifications.pushCount(uid); | 
					
						
							|  |  |  | 				next(); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-11-28 14:15:20 +03:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.markCategoryUnreadForAll = function (tid, callback) { | 
					
						
							| 
									
										
										
										
											2016-11-28 14:15:20 +03:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				Topics.getTopicField(tid, 'cid', next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (cid, next) { | 
					
						
							|  |  |  | 				categories.markAsUnreadForAll(cid, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-11-28 14:15:20 +03:00
										 |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.hasReadTopics = function (tids, uid, callback) { | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 		if (!parseInt(uid, 10)) { | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			return callback(null, tids.map(function () { | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 				return false; | 
					
						
							|  |  |  | 			})); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 		async.parallel({ | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			recentScores: function (next) { | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 				db.sortedSetScores('topics:recent', tids, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			userScores: function (next) { | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 				db.sortedSetScores('uid:' + uid + ':tids_read', tids, next); | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			tids_unread: function (next) { | 
					
						
							|  |  |  | 				db.sortedSetScores('uid:' + uid + ':tids_unread', tids, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 		}, function (err, results) { | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 			var cutoff = Topics.unreadCutoff(); | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 			var result = tids.map(function (tid, index) { | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 				return !results.tids_unread[index] && | 
					
						
							|  |  |  | 					(results.recentScores[index] < cutoff || | 
					
						
							|  |  |  | 					!!(results.userScores[index] && results.userScores[index] >= results.recentScores[index])); | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 			callback(null, result); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.hasReadTopic = function (tid, uid, callback) { | 
					
						
							|  |  |  | 		Topics.hasReadTopics([tid], uid, function (err, hasRead) { | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 			callback(err, Array.isArray(hasRead) && hasRead.length ? hasRead[0] : false); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 11:43:39 +02:00
										 |  |  | 	Topics.markUnread = function (tid, uid, callback) { | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				Topics.exists(tid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (exists, next) { | 
					
						
							|  |  |  | 				if (!exists) { | 
					
						
							|  |  |  | 					return next(new Error('[[error:no-topic]]')); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				db.sortedSetRemove('uid:' + uid + ':tids_read', tid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				db.sortedSetAdd('uid:' + uid + ':tids_unread', Date.now(), tid, next); | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 		], callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-03 13:06:21 +03:00
										 |  |  | 	Topics.filterNewTids = function (tids, uid, callback) { | 
					
						
							|  |  |  | 		db.sortedSetScores('uid:' + uid + ':tids_read', tids, function (err, scores) { | 
					
						
							|  |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			tids = tids.filter(function (tid, index) { | 
					
						
							|  |  |  | 				return tid && !scores[index]; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 			callback(null, tids); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-10 20:31:57 +01:00
										 |  |  | }; |