mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 19:15:58 +01:00 
			
		
		
		
	closes #2659
This commit is contained in:
		| @@ -42,6 +42,7 @@ | ||||
| 	"login_to_subscribe": "Please register or log in in order to subscribe to this topic.", | ||||
|  | ||||
| 	"markAsUnreadForAll.success" : "Topic marked as unread for all.", | ||||
| 	"mark_unread": "Mark unread", | ||||
|  | ||||
| 	"watch": "Watch", | ||||
| 	"unwatch": "Unwatch", | ||||
|   | ||||
| @@ -53,6 +53,11 @@ define('forum/topic/threadTools', [ | ||||
| 			return false; | ||||
| 		}); | ||||
|  | ||||
| 		topicContainer.on('click', '[component="topic/mark-unread"]', function() { | ||||
| 			socket.emit('topics.markUnread', tid); | ||||
| 			return false; | ||||
| 		}); | ||||
|  | ||||
| 		topicContainer.on('click', '[component="topic/mark-unread-for-all"]', function() { | ||||
| 			var btn = $(this); | ||||
| 			socket.emit('topics.markAsUnreadForAll', [tid], function(err) { | ||||
|   | ||||
| @@ -25,7 +25,7 @@ module.exports = function(middleware) { | ||||
| 				options = {}; | ||||
| 			} | ||||
|  | ||||
| 			options.loggedIn = req.user ? parseInt(req.user.uid, 10) !== 0 : false; | ||||
| 			options.loggedIn = !!req.uid; | ||||
| 			options.relative_path = nconf.get('relative_path'); | ||||
| 			options.template = {name: template}; | ||||
| 			options.template[template] = true; | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| var async = require('async'), | ||||
| var async = require('async'); | ||||
|  | ||||
| 	db = require('../../database'), | ||||
| 	user = require('../../user'), | ||||
| 	topics = require('../../topics'), | ||||
| 	utils = require('../../../public/src/utils'); | ||||
| var db = require('../../database'); | ||||
| var user = require('../../user'); | ||||
| var topics = require('../../topics'); | ||||
| var utils = require('../../../public/src/utils'); | ||||
|  | ||||
| module.exports = function(SocketTopics) { | ||||
|  | ||||
| @@ -62,6 +62,19 @@ module.exports = function(SocketTopics) { | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	SocketTopics.markUnread = function(socket, tid, callback) { | ||||
| 		if (!tid || !socket.uid) { | ||||
| 			return callback(); | ||||
| 		} | ||||
| 		topics.markUnread(tid, socket.uid, function(err) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			topics.pushUnreadCount(socket.uid); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	SocketTopics.markAsUnreadForAll = function(socket, tids, callback) { | ||||
| 		if (!Array.isArray(tids)) { | ||||
| 			return callback(new Error('[[error:invalid-tid]]')); | ||||
|   | ||||
| @@ -1,14 +1,14 @@ | ||||
|  | ||||
| 'use strict'; | ||||
|  | ||||
| var async = require('async'), | ||||
| 	winston = require('winston'), | ||||
| var async = require('async'); | ||||
| var winston = require('winston'); | ||||
|  | ||||
| 	db = require('../database'), | ||||
| 	user = require('../user'), | ||||
| 	notifications = require('../notifications'), | ||||
| 	categories = require('../categories'), | ||||
| 	privileges = require('../privileges'); | ||||
| var db = require('../database'); | ||||
| var user = require('../user'); | ||||
| var notifications = require('../notifications'); | ||||
| var categories = require('../categories'); | ||||
| var privileges = require('../privileges'); | ||||
|  | ||||
| module.exports = function(Topics) { | ||||
|  | ||||
| @@ -69,13 +69,16 @@ module.exports = function(Topics) { | ||||
| 			}, | ||||
| 			userScores: function(next) { | ||||
| 				db.getSortedSetRevRangeByScoreWithScores('uid:' + uid + ':tids_read', 0, -1, '+inf', cutoff, next); | ||||
| 			}, | ||||
| 			tids_unread: function(next) { | ||||
| 				db.getSortedSetRevRangeWithScores('uid:' + uid + ':tids_unread', 0, -1, next); | ||||
| 			} | ||||
| 		}, function(err, results) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			if (results.recentTids && !results.recentTids.length) { | ||||
| 			if (results.recentTids && !results.recentTids.length && !results.tids_unread.length) { | ||||
| 				return callback(null, []); | ||||
| 			} | ||||
|  | ||||
| @@ -84,11 +87,17 @@ module.exports = function(Topics) { | ||||
| 				userRead[userItem.value] = userItem.score; | ||||
| 			}); | ||||
|  | ||||
| 			results.recentTids = results.recentTids.concat(results.tids_unread); | ||||
| 			results.recentTids.sort(function(a, b) { | ||||
| 				return b.score - a.score; | ||||
| 			}); | ||||
|  | ||||
| 			var tids = results.recentTids.filter(function(recentTopic, index) { | ||||
| 			var tids = results.recentTids.filter(function(recentTopic) { | ||||
| 				return !userRead[recentTopic.value] || recentTopic.score > userRead[recentTopic.value]; | ||||
| 			}).map(function(topic) { | ||||
| 				return topic.value; | ||||
| 			}).filter(function(tid, index, array) { | ||||
| 				return array.indexOf(tid) === index; | ||||
| 			}); | ||||
|  | ||||
| 			tids = tids.slice(0, 100); | ||||
| @@ -142,6 +151,7 @@ module.exports = function(Topics) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			require('../socket.io').in('uid_' + uid).emit('event:unread.updateCount', count); | ||||
| 			callback(); | ||||
| 		}); | ||||
| @@ -184,6 +194,7 @@ module.exports = function(Topics) { | ||||
|  | ||||
| 				async.parallel({ | ||||
| 					markRead: async.apply(db.sortedSetAdd, 'uid:' + uid + ':tids_read', scores, tids), | ||||
| 					markUnread: async.apply(db.sortedSetRemove, 'uid:' + uid + ':tids_unread', tids), | ||||
| 					topicData: async.apply(	Topics.getTopicsFields, tids, ['cid']) | ||||
| 				}, next); | ||||
| 			}, | ||||
| @@ -227,7 +238,7 @@ module.exports = function(Topics) { | ||||
| 	}; | ||||
|  | ||||
| 	Topics.hasReadTopics = function(tids, uid, callback) { | ||||
| 		if(!parseInt(uid, 10)) { | ||||
| 		if (!parseInt(uid, 10)) { | ||||
| 			return callback(null, tids.map(function() { | ||||
| 				return false; | ||||
| 			})); | ||||
| @@ -239,14 +250,20 @@ module.exports = function(Topics) { | ||||
| 			}, | ||||
| 			userScores: function(next) { | ||||
| 				db.sortedSetScores('uid:' + uid + ':tids_read', tids, next); | ||||
| 			}, | ||||
| 			tids_unread: function (next) { | ||||
| 				db.sortedSetScores('uid:' + uid + ':tids_unread', tids, next); | ||||
| 			} | ||||
| 		}, function(err, results) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 			} | ||||
|  | ||||
| 			var cutoff = Date.now() - unreadCutoff; | ||||
| 			var result = tids.map(function(tid, index) { | ||||
| 				return results.recentScores[index] < cutoff || !!(results.userScores[index] && results.userScores[index] >= results.recentScores[index]); | ||||
| 				return !results.tids_unread[index] && | ||||
| 					(results.recentScores[index] < cutoff || | ||||
| 					!!(results.userScores[index] && results.userScores[index] >= results.recentScores[index])); | ||||
| 			}); | ||||
|  | ||||
| 			callback(null, result); | ||||
| @@ -259,5 +276,21 @@ module.exports = function(Topics) { | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	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); | ||||
| 	}; | ||||
|  | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user