| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var async = require('async'), | 
					
						
							|  |  |  | 	winston = require('winston'), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 18:11:57 -04:00
										 |  |  | 	db = require('../database'), | 
					
						
							|  |  |  | 	user = require('../user'), | 
					
						
							|  |  |  | 	meta = require('../meta'), | 
					
						
							|  |  |  | 	notifications = require('../notifications'), | 
					
						
							|  |  |  | 	categories = require('../categories'), | 
					
						
							| 
									
										
										
										
											2014-05-15 10:38:02 -04:00
										 |  |  | 	privileges = require('../privileges'); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | module.exports = function(Topics) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Topics.getTotalUnread = function(uid, callback) { | 
					
						
							|  |  |  | 		Topics.getUnreadTids(uid, 0, 20, function(err, tids) { | 
					
						
							|  |  |  | 			callback(err, tids ? tids.length : 0); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 	Topics.getUnreadTopics = function(uid, start, stop, callback) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var unreadTopics = { | 
					
						
							|  |  |  | 			showSelect: true, | 
					
						
							|  |  |  | 			nextStart : 0, | 
					
						
							|  |  |  | 			topics: [] | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 		function sendUnreadTopics(tids, callback) { | 
					
						
							|  |  |  | 			if (!tids.length) { | 
					
						
							|  |  |  | 				return callback(null, unreadTopics); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 			Topics.getTopicsByTids(tids, uid, function(err, topicData) { | 
					
						
							|  |  |  | 				if (err) { | 
					
						
							|  |  |  | 					return callback(err); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (!Array.isArray(topicData) || !topicData.length) { | 
					
						
							|  |  |  | 					return callback(null, unreadTopics); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				db.sortedSetRevRank('topics:recent', topicData[topicData.length - 1].tid, function(err, rank) { | 
					
						
							|  |  |  | 					if (err) { | 
					
						
							|  |  |  | 						return callback(err); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					unreadTopics.topics = topicData; | 
					
						
							|  |  |  | 					unreadTopics.nextStart = parseInt(rank, 10) + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					callback(null, unreadTopics); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Topics.getUnreadTids(uid, start, stop, function(err, unreadTids) { | 
					
						
							|  |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 			sendUnreadTopics(unreadTids, callback); | 
					
						
							| 
									
										
										
										
											2014-08-29 14:50:24 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 	Topics.getUnreadTids = function(uid, start, stop, callback) { | 
					
						
							|  |  |  | 		var unreadTids = [], | 
					
						
							|  |  |  | 			done = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		uid = parseInt(uid, 10); | 
					
						
							| 
									
										
										
										
											2014-08-09 16:15:22 -04:00
										 |  |  | 		if (uid === 0) { | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 			return callback(null, unreadTids); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 18:11:57 -04:00
										 |  |  | 		var count = 0; | 
					
						
							|  |  |  | 		if (stop === -1) { | 
					
						
							|  |  |  | 			count = Infinity; | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2014-08-15 18:11:57 -04:00
										 |  |  | 			count = stop - start + 1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 		user.getIgnoredCategories(uid, function(err, ignoredCids) { | 
					
						
							|  |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 			async.whilst(function() { | 
					
						
							|  |  |  | 				return unreadTids.length < count && !done; | 
					
						
							|  |  |  | 			}, function(next) { | 
					
						
							| 
									
										
										
										
											2014-09-06 02:16:19 -04:00
										 |  |  | 				Topics.getLatestTids(start, stop, 'day', function(err, tids) { | 
					
						
							| 
									
										
										
										
											2014-08-09 16:15:22 -04:00
										 |  |  | 					if (err) { | 
					
						
							|  |  |  | 						return next(err); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-07-29 21:51:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 					if (tids && !tids.length) { | 
					
						
							|  |  |  | 						done = true; | 
					
						
							|  |  |  | 						return next(); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 					Topics.hasReadTopics(tids, uid, function(err, read) { | 
					
						
							| 
									
										
										
										
											2014-08-15 18:11:57 -04:00
										 |  |  | 						if (err) { | 
					
						
							|  |  |  | 							return next(err); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 						var newtids = tids.filter(function(tid, index) { | 
					
						
							|  |  |  | 							return !read[index]; | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						privileges.topics.filter('read', newtids, uid, function(err, newtids) { | 
					
						
							|  |  |  | 							if (err) { | 
					
						
							|  |  |  | 								return next(err); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							filterTopicsFromIgnoredCategories(newtids, ignoredCids, function(err, newtids) { | 
					
						
							|  |  |  | 								if (err) { | 
					
						
							|  |  |  | 									return next(err); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 								unreadTids.push.apply(unreadTids, newtids); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								start = stop + 1; | 
					
						
							|  |  |  | 								stop = start + 19; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 								next(); | 
					
						
							|  |  |  | 							}); | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2014-08-15 18:11:57 -04:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 			}, function(err) { | 
					
						
							|  |  |  | 				callback(err, unreadTids.slice(0, count)); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 	function filterTopicsFromIgnoredCategories(tids, ignoredCids, callback) { | 
					
						
							|  |  |  | 		if (!Array.isArray(ignoredCids) || !ignoredCids.length || !tids.length) { | 
					
						
							|  |  |  | 			return callback(null, tids); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var keys = tids.map(function(tid) { | 
					
						
							|  |  |  | 			return 'topic:' + tid; | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		db.getObjectsFields(keys, ['tid', 'cid'], function(err, topics) { | 
					
						
							|  |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			topics = topics.filter(function(topic) { | 
					
						
							|  |  |  | 				return topic && ignoredCids.indexOf(topic.cid.toString()) === -1; | 
					
						
							|  |  |  | 			}).map(function(topic) { | 
					
						
							|  |  |  | 				return topic.tid; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 15:57:20 -04:00
										 |  |  | 			callback(null, topics); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-16 11:06:10 -04: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
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-09-16 11:06:10 -04:00
										 |  |  | 			require('../socket.io').in('uid_' + uid).emit('event:unread.updateCount', null, count); | 
					
						
							|  |  |  | 			callback(); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Topics.markAsUnreadForAll = function(tid, callback) { | 
					
						
							|  |  |  | 		db.delete('tid:' + tid + ':read_by_uid', function(err) { | 
					
						
							|  |  |  | 			if(err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			Topics.markCategoryUnreadForAll(tid, callback); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-09-10 21:44:19 -04:00
										 |  |  | 		tids = tids.filter(Boolean); | 
					
						
							|  |  |  | 		var keys = tids.map(function(tid) { | 
					
						
							|  |  |  | 			return 'tid:' + tid + ':read_by_uid'; | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-10 21:44:19 -04:00
										 |  |  | 		async.parallel({ | 
					
						
							|  |  |  | 			markRead: function(next) { | 
					
						
							|  |  |  | 				db.setsAdd(keys, uid, next); | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			topicData: function(next) { | 
					
						
							|  |  |  | 				Topics.getTopicsFields(tids, ['cid'], next); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}, function(err, results) { | 
					
						
							| 
									
										
										
										
											2014-03-21 17:48:32 -04:00
										 |  |  | 			if (err) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-10 21:44:19 -04:00
										 |  |  | 			var cids = results.topicData.map(function(topic) { | 
					
						
							|  |  |  | 				return topic && topic.cid; | 
					
						
							|  |  |  | 			}).filter(function(topic, index, array) { | 
					
						
							|  |  |  | 				return topic && array.indexOf(topic) === index; | 
					
						
							| 
									
										
										
										
											2014-03-21 17:48:32 -04:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2014-09-10 21:44:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			categories.markAsRead(cids, uid, callback); | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2014-03-21 17:48:32 -04:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2014-03-21 15:40:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-21 17:48:32 -04:00
										 |  |  | 	Topics.markTopicNotificationsRead = function(tid, uid) { | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							|  |  |  | 		if(!parseInt(uid, 10)) { | 
					
						
							|  |  |  | 			return callback(null, tids.map(function() { | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			})); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var sets = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (var i = 0, ii = tids.length; i < ii; i++) { | 
					
						
							|  |  |  | 			sets.push('tid:' + tids[i] + ':read_by_uid'); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		db.isMemberOfSets(sets, uid, callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Topics.hasReadTopic = function(tid, uid, callback) { | 
					
						
							|  |  |  | 		if(!parseInt(uid, 10)) { | 
					
						
							|  |  |  | 			return callback(null, false); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		db.isSetMember('tid:' + tid + ':read_by_uid', uid, callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-10 20:31:57 +01:00
										 |  |  | }; |