| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | var async = require('async'); | 
					
						
							|  |  |  | var winston = require('winston'); | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  | module.exports = function(Topics) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Topics.getTotalUnread = function(uid, callback) { | 
					
						
							| 
									
										
										
										
											2015-07-13 14:47:09 -04:00
										 |  |  | 		Topics.getUnreadTids(0, uid, 0, 20, function(err, tids) { | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 			callback(err, tids ? tids.length : 0); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 14:47:09 -04:00
										 |  |  | 	Topics.getUnreadTopics = function(cid, uid, start, stop, callback) { | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		var unreadTopics = { | 
					
						
							|  |  |  | 			showSelect: true, | 
					
						
							|  |  |  | 			nextStart : 0, | 
					
						
							|  |  |  | 			topics: [] | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 18:19:30 -05:00
										 |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function(next) { | 
					
						
							| 
									
										
										
										
											2015-07-13 14:47:09 -04:00
										 |  |  | 				Topics.getUnreadTids(cid, uid, start, stop, next); | 
					
						
							| 
									
										
										
										
											2015-01-23 18:19:30 -05:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			function(tids, next) { | 
					
						
							|  |  |  | 				if (!tids.length) { | 
					
						
							|  |  |  | 					return next(null, []); | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-01-23 18:19:30 -05:00
										 |  |  | 				Topics.getTopicsByTids(tids, uid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			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); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 	Topics.unreadCutoff = function() { | 
					
						
							|  |  |  | 		return Date.now() - (parseInt(meta.config.unreadCutoff, 10) || 2) * 86400000; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 14:47:09 -04:00
										 |  |  | 	Topics.getUnreadTids = function(cid, uid, start, stop, 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-16 12:38:27 -04:00
										 |  |  | 		async.parallel({ | 
					
						
							|  |  |  | 			ignoredCids: function(next) { | 
					
						
							|  |  |  | 				user.getIgnoredCategories(uid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			recentTids: function(next) { | 
					
						
							| 
									
										
										
										
											2015-03-24 13:10:10 -04:00
										 |  |  | 				db.getSortedSetRevRangeByScoreWithScores('topics:recent', 0, -1, '+inf', cutoff, next); | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			userScores: function(next) { | 
					
						
							| 
									
										
										
										
											2015-03-24 13:10:10 -04:00
										 |  |  | 				db.getSortedSetRevRangeByScoreWithScores('uid:' + uid + ':tids_read', 0, -1, '+inf', cutoff, next); | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 			tids_unread: function(next) { | 
					
						
							|  |  |  | 				db.getSortedSetRevRangeWithScores('uid:' + uid + ':tids_unread', 0, -1, next); | 
					
						
							| 
									
										
										
										
											2014-09-16 12:38:27 -04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}, function(err, results) { | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 			if (results.recentTids && !results.recentTids.length && !results.tids_unread.length) { | 
					
						
							| 
									
										
										
										
											2014-09-16 12:38:27 -04:00
										 |  |  | 				return callback(null, []); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 			var userRead = {}; | 
					
						
							|  |  |  | 			results.userScores.forEach(function(userItem) { | 
					
						
							|  |  |  | 				userRead[userItem.value] = userItem.score; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 			results.recentTids = results.recentTids.concat(results.tids_unread); | 
					
						
							|  |  |  | 			results.recentTids.sort(function(a, b) { | 
					
						
							|  |  |  | 				return b.score - a.score; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 			var tids = results.recentTids.filter(function(recentTopic) { | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 				return !userRead[recentTopic.value] || recentTopic.score > userRead[recentTopic.value]; | 
					
						
							|  |  |  | 			}).map(function(topic) { | 
					
						
							|  |  |  | 				return topic.value; | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 			}).filter(function(tid, index, array) { | 
					
						
							|  |  |  | 				return array.indexOf(tid) === index; | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-14 14:27:45 -04:00
										 |  |  | 			tids = tids.slice(0, 100); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 14:47:09 -04:00
										 |  |  | 			filterTopics(uid, tids, cid, results.ignoredCids, function(err, tids) { | 
					
						
							| 
									
										
										
										
											2014-09-16 12:38:27 -04:00
										 |  |  | 				if (err) { | 
					
						
							|  |  |  | 					return callback(err); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 				if (stop === -1) { | 
					
						
							|  |  |  | 					tids = tids.slice(start); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					tids = tids.slice(start, stop + 1); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-14 19:52:25 -05:00
										 |  |  | 				callback(null, tids); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-13 14:47:09 -04:00
										 |  |  | 	function filterTopics(uid, tids, cid, ignoredCids, 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([ | 
					
						
							|  |  |  | 			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
										 |  |  | 			}, | 
					
						
							|  |  |  | 			function(tids, next) { | 
					
						
							|  |  |  | 				Topics.getTopicsFields(tids, ['tid', 'cid'], next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function(topics, next) { | 
					
						
							|  |  |  | 				tids = topics.filter(function(topic) { | 
					
						
							| 
									
										
										
										
											2015-07-13 14:47:09 -04:00
										 |  |  | 					return topic && topic.cid && ignoredCids.indexOf(topic.cid.toString()) === -1 && (!cid || parseInt(cid, 10) === parseInt(topic.cid, 10)); | 
					
						
							| 
									
										
										
										
											2014-09-16 12:38:27 -04: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); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-16 11:06:10 -04:00
										 |  |  | 	Topics.pushUnreadCount = function(uid, callback) { | 
					
						
							| 
									
										
										
										
											2014-09-16 11:07:59 -04:00
										 |  |  | 		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
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-09-16 11:06:10 -04: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
										 |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-10 21:44:19 -04:00
										 |  |  | 	Topics.markAsRead = function(tids, uid, callback) { | 
					
						
							|  |  |  | 		callback = callback || function() {}; | 
					
						
							|  |  |  | 		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-01-04 22:50:35 +02:00
										 |  |  | 		tids = tids.filter(function(tid, index, array) { | 
					
						
							|  |  |  | 			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), | 
					
						
							|  |  |  | 					userScores: async.apply(db.sortedSetScores, 'uid:' + uid + ':tids_read', tids) | 
					
						
							|  |  |  | 				}, next); | 
					
						
							| 
									
										
										
										
											2014-09-10 21:44:19 -04:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 			function (results, next) { | 
					
						
							|  |  |  | 				tids = tids.filter(function(tid, index) { | 
					
						
							|  |  |  | 					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(); | 
					
						
							|  |  |  | 				var scores = tids.map(function() { | 
					
						
							|  |  |  | 					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), | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 					topicData: async.apply(	Topics.getTopicsFields, tids, ['cid']) | 
					
						
							|  |  |  | 				}, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (results, next) { | 
					
						
							| 
									
										
										
										
											2014-10-14 02:39:20 -04:00
										 |  |  | 				var cids = results.topicData.map(function(topic) { | 
					
						
							|  |  |  | 					return topic && topic.cid; | 
					
						
							|  |  |  | 				}).filter(function(topic, index, array) { | 
					
						
							|  |  |  | 					return topic && array.indexOf(topic) === index; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-05 11:53:17 -05:00
										 |  |  | 				categories.markAsRead(cids, uid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				next(null, true); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:48:32 -04:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 14:33:47 +02:00
										 |  |  | 	Topics.markAllRead = function(uid, callback) { | 
					
						
							|  |  |  | 		async.waterfall([ | 
					
						
							|  |  |  | 			function (next) { | 
					
						
							|  |  |  | 				db.getSortedSetRevRangeByScore('topics:recent', 0, -1, '+inf', Topics.unreadCutoff(), next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			function (tids, next) { | 
					
						
							| 
									
										
										
										
											2016-01-04 15:08:07 +02:00
										 |  |  | 				for (var i=0; i<tids.length; ++i) { | 
					
						
							|  |  |  | 					Topics.markTopicNotificationsRead(tids[i], 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); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-21 17:48:32 -04:00
										 |  |  | 	Topics.markTopicNotificationsRead = function(tid, uid) { | 
					
						
							| 
									
										
										
										
											2014-09-19 19:45:16 -04:00
										 |  |  | 		if (!tid) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-07-28 15:52:33 -04:00
										 |  |  | 		user.notifications.getUnreadByField(uid, 'tid', tid, function(err, nids) { | 
					
						
							| 
									
										
										
										
											2014-09-08 23:03:37 -04:00
										 |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return winston.error(err.stack); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-07-28 15:52:33 -04:00
										 |  |  | 			notifications.markReadMultiple(nids, uid, function() { | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 				user.notifications.pushCount(uid); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Topics.markCategoryUnreadForAll = function(tid, callback) { | 
					
						
							|  |  |  | 		Topics.getTopicField(tid, 'cid', function(err, cid) { | 
					
						
							|  |  |  | 			if(err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			categories.markAsUnreadForAll(cid, callback); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Topics.hasReadTopics = function(tids, uid, callback) { | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 		if (!parseInt(uid, 10)) { | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 			return callback(null, tids.map(function() { | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			})); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 		async.parallel({ | 
					
						
							|  |  |  | 			recentScores: function(next) { | 
					
						
							|  |  |  | 				db.sortedSetScores('topics:recent', tids, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			userScores: function(next) { | 
					
						
							|  |  |  | 				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); | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}, function(err, results) { | 
					
						
							|  |  |  | 			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(); | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04: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
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Topics.hasReadTopic = function(tid, uid, callback) { | 
					
						
							| 
									
										
										
										
											2014-09-27 17:41:49 -04:00
										 |  |  | 		Topics.hasReadTopics([tid], uid, function(err, hasRead) { | 
					
						
							|  |  |  | 			callback(err, Array.isArray(hasRead) && hasRead.length ? hasRead[0] : false); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 11:22:35 +02:00
										 |  |  | 	Topics.markUnread = function(tid, uid, callback) { | 
					
						
							|  |  |  | 		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); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		], callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-10 20:31:57 +01:00
										 |  |  | }; |