mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into develop
This commit is contained in:
		| @@ -60,7 +60,7 @@ | |||||||
|         "mousetrap": "^1.6.1", |         "mousetrap": "^1.6.1", | ||||||
|         "mubsub": "^1.4.0", |         "mubsub": "^1.4.0", | ||||||
|         "nconf": "^0.9.1", |         "nconf": "^0.9.1", | ||||||
|         "nodebb-plugin-composer-default": "6.0.8", |         "nodebb-plugin-composer-default": "6.0.9", | ||||||
|         "nodebb-plugin-dbsearch": "2.0.9", |         "nodebb-plugin-dbsearch": "2.0.9", | ||||||
|         "nodebb-plugin-emoji": "2.1.0", |         "nodebb-plugin-emoji": "2.1.0", | ||||||
|         "nodebb-plugin-emoji-android": "2.0.0", |         "nodebb-plugin-emoji-android": "2.0.0", | ||||||
| @@ -70,9 +70,9 @@ | |||||||
|         "nodebb-plugin-spam-be-gone": "0.5.1", |         "nodebb-plugin-spam-be-gone": "0.5.1", | ||||||
|         "nodebb-rewards-essentials": "0.0.11", |         "nodebb-rewards-essentials": "0.0.11", | ||||||
|         "nodebb-theme-lavender": "5.0.1", |         "nodebb-theme-lavender": "5.0.1", | ||||||
|         "nodebb-theme-persona": "7.2.21", |         "nodebb-theme-persona": "7.2.20", | ||||||
|         "nodebb-theme-slick": "1.1.4", |         "nodebb-theme-slick": "1.1.4", | ||||||
|         "nodebb-theme-vanilla": "8.1.7", |         "nodebb-theme-vanilla": "8.1.9", | ||||||
|         "nodebb-widget-essentials": "4.0.1", |         "nodebb-widget-essentials": "4.0.1", | ||||||
|         "nodemailer": "4.4.1", |         "nodemailer": "4.4.1", | ||||||
|         "passport": "^0.4.0", |         "passport": "^0.4.0", | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ | |||||||
|     "guest-login-reply": "התחבר כדי לפרסם תגובה", |     "guest-login-reply": "התחבר כדי לפרסם תגובה", | ||||||
|     "edit": "עריכה", |     "edit": "עריכה", | ||||||
|     "delete": "מחק", |     "delete": "מחק", | ||||||
|     "purge": "מחק הכל", |     "purge": "מחק לצמיתות", | ||||||
|     "restore": "שחזר", |     "restore": "שחזר", | ||||||
|     "move": "הזז", |     "move": "הזז", | ||||||
|     "fork": "פורק", |     "fork": "פורק", | ||||||
| @@ -94,7 +94,7 @@ | |||||||
|     "merge_topics_instruction": "Click the topics you want to merge", |     "merge_topics_instruction": "Click the topics you want to merge", | ||||||
|     "composer.title_placeholder": "הכנס את כותרת הנושא כאן...", |     "composer.title_placeholder": "הכנס את כותרת הנושא כאן...", | ||||||
|     "composer.handle_placeholder": "שם", |     "composer.handle_placeholder": "שם", | ||||||
|     "composer.discard": "מחק", |     "composer.discard": "ביטול", | ||||||
|     "composer.submit": "שלח", |     "composer.submit": "שלח", | ||||||
|     "composer.replying_to": "מגיב ל %1", |     "composer.replying_to": "מגיב ל %1", | ||||||
|     "composer.new_topic": "נושא חדש", |     "composer.new_topic": "נושא חדש", | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| { | { | ||||||
| 	"state": "State", | 	"state": "Состояние", | ||||||
| 	"reporter": "Reporter", | 	"reporter": "Reporter", | ||||||
| 	"reported-at": "Reported At", | 	"reported-at": "Reported At", | ||||||
| 	"description": "Описание", | 	"description": "Описание", | ||||||
| @@ -9,7 +9,7 @@ | |||||||
| 	"updated": "Обновлено", | 	"updated": "Обновлено", | ||||||
| 	"target-purged": "The content this flag referred to has been purged and is no longer available.", | 	"target-purged": "The content this flag referred to has been purged and is no longer available.", | ||||||
|  |  | ||||||
| 	"quick-filters": "Quick Filters", | 	"quick-filters": "Быстрые фильтры", | ||||||
| 	"filter-active": "There are one or more filters active in this list of flags", | 	"filter-active": "There are one or more filters active in this list of flags", | ||||||
| 	"filter-reset": "Убрать фильтры", | 	"filter-reset": "Убрать фильтры", | ||||||
| 	"filters": "Filter Options", | 	"filters": "Filter Options", | ||||||
| @@ -17,13 +17,13 @@ | |||||||
| 	"filter-targetUid": "Flagged UID", | 	"filter-targetUid": "Flagged UID", | ||||||
| 	"filter-type": "Flag Type", | 	"filter-type": "Flag Type", | ||||||
| 	"filter-type-all": "Весь контент", | 	"filter-type-all": "Весь контент", | ||||||
| 	"filter-type-post": "Написать", | 	"filter-type-post": "Сообщение", | ||||||
| 	"filter-state": "State", | 	"filter-state": "Состояние", | ||||||
| 	"filter-assignee": "Assignee UID", | 	"filter-assignee": "Assignee UID", | ||||||
| 	"filter-cid": "Категория", | 	"filter-cid": "Категория", | ||||||
| 	"filter-quick-mine": "Assigned to me", | 	"filter-quick-mine": "Assigned to me", | ||||||
| 	"filter-cid-all": "Все категории", | 	"filter-cid-all": "Все категории", | ||||||
| 	"apply-filters": "Apply Filters", | 	"apply-filters": "Применить фильтры", | ||||||
|  |  | ||||||
| 	"quick-links": "Quick Links", | 	"quick-links": "Quick Links", | ||||||
| 	"flagged-user": "Flagged User", | 	"flagged-user": "Flagged User", | ||||||
| @@ -32,7 +32,7 @@ | |||||||
| 	"go-to-target": "View Flag Target", | 	"go-to-target": "View Flag Target", | ||||||
|  |  | ||||||
| 	"user-view": "Просмотреть профиль", | 	"user-view": "Просмотреть профиль", | ||||||
| 	"user-edit": "Изменить Профиль", | 	"user-edit": "Изменить профиль", | ||||||
|  |  | ||||||
| 	"notes": "Flag Notes", | 	"notes": "Flag Notes", | ||||||
| 	"add-note": "Добавить примечание", | 	"add-note": "Добавить примечание", | ||||||
| @@ -42,8 +42,8 @@ | |||||||
| 	"back": "Back to Flags List", | 	"back": "Back to Flags List", | ||||||
| 	"no-history": "No flag history.", | 	"no-history": "No flag history.", | ||||||
|  |  | ||||||
| 	"state-all": "Все государства", | 	"state-all": "Все состояния", | ||||||
| 	"state-open": "Новый/Открыть", | 	"state-open": "Новый/Открытый", | ||||||
| 	"state-wip": "Work in Progress", | 	"state-wip": "Work in Progress", | ||||||
| 	"state-resolved": "Решен", | 	"state-resolved": "Решен", | ||||||
| 	"state-rejected": "Отклонен", | 	"state-rejected": "Отклонен", | ||||||
| @@ -53,12 +53,12 @@ | |||||||
| 	"modal-title": "Report Inappropriate Content", | 	"modal-title": "Report Inappropriate Content", | ||||||
| 	"modal-body": "Please specify your reason for flagging %1 %2 for review. Alternatively, use one of the quick report buttons if applicable.", | 	"modal-body": "Please specify your reason for flagging %1 %2 for review. Alternatively, use one of the quick report buttons if applicable.", | ||||||
| 	"modal-reason-spam": "Спам", | 	"modal-reason-spam": "Спам", | ||||||
| 	"modal-reason-offensive": "Offensive", | 	"modal-reason-offensive": "Оскорбительный", | ||||||
| 	"modal-reason-other": "Other (specify below)", | 	"modal-reason-other": "Другое (укажите ниже)", | ||||||
| 	"modal-reason-custom": "Reason for reporting this content...", | 	"modal-reason-custom": "Причина жалобы на содержимое...", | ||||||
| 	"modal-submit": "Представить отчет", | 	"modal-submit": "Представить отчет", | ||||||
| 	"modal-submit-success": "Content has been flagged for moderation.", | 	"modal-submit-success": "Content has been flagged for moderation.", | ||||||
| 	"modal-submit-confirm": "Confirm Submission", | 	"modal-submit-confirm": "Подтвердить отправку", | ||||||
| 	"modal-submit-confirm-text": "You have a custom reason specified already. Are you sure you wish to submit via quick-report?", | 	"modal-submit-confirm-text": "You have a custom reason specified already. Are you sure you wish to submit via quick-report?", | ||||||
| 	"modal-submit-confirm-text-help": "Submitting a quick report will overwrite any custom reasons defined." | 	"modal-submit-confirm-text-help": "Submitting a quick report will overwrite any custom reasons defined." | ||||||
| } | } | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
|  |  | ||||||
| define('forum/popular', ['components'], function (components) { | define('forum/popular', ['forum/recent', 'components', 'forum/infinitescroll'], function (recent, components, infinitescroll) { | ||||||
| 	var Popular = {}; | 	var Popular = {}; | ||||||
|  |  | ||||||
| 	Popular.init = function () { | 	Popular.init = function () { | ||||||
| @@ -11,7 +11,30 @@ define('forum/popular', ['components'], function (components) { | |||||||
| 			.removeClass('active') | 			.removeClass('active') | ||||||
| 			.find('a[href="' + window.location.pathname + '"]') | 			.find('a[href="' + window.location.pathname + '"]') | ||||||
| 			.parent().addClass('active'); | 			.parent().addClass('active'); | ||||||
|  |  | ||||||
|  | 		if (!config.usePagination) { | ||||||
|  | 			infinitescroll.init(loadMoreTopics); | ||||||
|  | 		} | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	function loadMoreTopics(direction) { | ||||||
|  | 		if (direction < 0 || !$('[component="category"]').length) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		infinitescroll.loadMore('topics.loadMorePopularTopics', { | ||||||
|  | 			after: $('[component="category"]').attr('data-nextstart'), | ||||||
|  | 			count: config.topicsPerPage, | ||||||
|  | 			term: ajaxify.data.term, | ||||||
|  | 		}, function (data, done) { | ||||||
|  | 			if (data.topics && data.topics.length) { | ||||||
|  | 				recent.onTopicsLoaded('popular', data.topics, false, done); | ||||||
|  | 				$('[component="category"]').attr('data-nextstart', data.nextStart); | ||||||
|  | 			} else { | ||||||
|  | 				done(); | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return Popular; | 	return Popular; | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -113,7 +113,7 @@ helpers.getUserDataByUserSlug = function (userslug, callerUID, callback) { | |||||||
| 				userData.fullname = ''; | 				userData.fullname = ''; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (isAdmin || isSelf || (isGlobalModerator && !results.isTargetAdmin)) { | 			if (isAdmin || isSelf || ((isGlobalModerator || isModerator) && !results.isTargetAdmin)) { | ||||||
| 				userData.ips = results.ips; | 				userData.ips = results.ips; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,9 +3,12 @@ | |||||||
|  |  | ||||||
| var async = require('async'); | var async = require('async'); | ||||||
| var nconf = require('nconf'); | var nconf = require('nconf'); | ||||||
|  |  | ||||||
| var topics = require('../topics'); | var topics = require('../topics'); | ||||||
| var meta = require('../meta'); | var meta = require('../meta'); | ||||||
|  | var user = require('../user'); | ||||||
| var helpers = require('./helpers'); | var helpers = require('./helpers'); | ||||||
|  | var pagination = require('../pagination'); | ||||||
|  |  | ||||||
| var popularController = module.exports; | var popularController = module.exports; | ||||||
|  |  | ||||||
| @@ -19,6 +22,7 @@ var terms = { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| popularController.get = function (req, res, next) { | popularController.get = function (req, res, next) { | ||||||
|  | 	var page = parseInt(req.query.page, 10) || 1; | ||||||
| 	var term = terms[req.params.term]; | 	var term = terms[req.params.term]; | ||||||
|  |  | ||||||
| 	if (!term && req.params.term) { | 	if (!term && req.params.term) { | ||||||
| @@ -38,19 +42,25 @@ popularController.get = function (req, res, next) { | |||||||
| 			return res.render('popular', anonCache[term]); | 			return res.render('popular', anonCache[term]); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	var settings; | ||||||
| 	async.waterfall([ | 	async.waterfall([ | ||||||
| 		function (next) { | 		function (next) { | ||||||
| 			topics.getPopular(term, req.uid, meta.config.topicsPerList, next); | 			user.getSettings(req.uid, next); | ||||||
| 		}, | 		}, | ||||||
| 		function (topics) { | 		function (_settings, next) { | ||||||
| 			var data = { | 			settings = _settings; | ||||||
| 				title: meta.config.homePageTitle || '[[pages:home]]', | 			var start = Math.max(0, (page - 1) * settings.topicsPerPage); | ||||||
| 				topics: topics, | 			var stop = start + settings.topicsPerPage - 1; | ||||||
| 				'feeds:disableRSS': parseInt(meta.config['feeds:disableRSS'], 10) === 1, | 			topics.getPopularTopics(term, req.uid, start, stop, next); | ||||||
| 				rssFeedUrl: nconf.get('relative_path') + '/popular/' + (req.params.term || 'daily') + '.rss', | 		}, | ||||||
| 				term: term, | 		function (data) { | ||||||
| 			}; | 			var pageCount = Math.max(1, Math.ceil(data.topicCount / settings.topicsPerPage)); | ||||||
|  |  | ||||||
|  | 			data.title = meta.config.homePageTitle || '[[pages:home]]'; | ||||||
|  | 			data['feeds:disableRSS'] = parseInt(meta.config['feeds:disableRSS'], 10) === 1; | ||||||
|  | 			data.rssFeedUrl = nconf.get('relative_path') + '/popular/' + (req.params.term || 'alltime') + '.rss'; | ||||||
|  | 			data.term = term; | ||||||
|  | 			data.pagination = pagination.create(page, pageCount, req.query); | ||||||
|  |  | ||||||
| 			if (req.originalUrl.startsWith(nconf.get('relative_path') + '/api/popular') || req.originalUrl.startsWith(nconf.get('relative_path') + '/popular')) { | 			if (req.originalUrl.startsWith(nconf.get('relative_path') + '/api/popular') || req.originalUrl.startsWith(nconf.get('relative_path') + '/popular')) { | ||||||
| 				data.title = '[[pages:popular-' + term + ']]'; | 				data.title = '[[pages:popular-' + term + ']]'; | ||||||
|   | |||||||
| @@ -99,13 +99,14 @@ middleware.routeTouchIcon = function (req, res) { | |||||||
| 	if (meta.config['brand:touchIcon'] && validator.isURL(meta.config['brand:touchIcon'])) { | 	if (meta.config['brand:touchIcon'] && validator.isURL(meta.config['brand:touchIcon'])) { | ||||||
| 		return res.redirect(meta.config['brand:touchIcon']); | 		return res.redirect(meta.config['brand:touchIcon']); | ||||||
| 	} | 	} | ||||||
| 	var iconPath = '../../public'; | 	var iconPath = ''; | ||||||
| 	if (meta.config['brand:touchIcon']) { | 	if (meta.config['brand:touchIcon']) { | ||||||
| 		iconPath += meta.config['brand:touchIcon'].replace(/assets\/uploads/, 'uploads'); | 		iconPath = path.join(nconf.get('upload_path'), meta.config['brand:touchIcon'].replace(/assets\/uploads/, '')); | ||||||
| 	} else { | 	} else { | ||||||
| 		iconPath += '/logo.png'; | 		iconPath = path.join(nconf.get('base_dir'), 'public/logo.png'); | ||||||
| 	} | 	} | ||||||
| 	return res.sendFile(path.join(__dirname, iconPath), { |  | ||||||
|  | 	return res.sendFile(iconPath, { | ||||||
| 		maxAge: req.app.enabled('cache') ? 5184000000 : 0, | 		maxAge: req.app.enabled('cache') ? 5184000000 : 0, | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ var meta = require('../meta'); | |||||||
| var helpers = require('../controllers/helpers'); | var helpers = require('../controllers/helpers'); | ||||||
| var privileges = require('../privileges'); | var privileges = require('../privileges'); | ||||||
| var db = require('../database'); | var db = require('../database'); | ||||||
|  | var utils = require('../utils'); | ||||||
| var controllers404 = require('../controllers/404.js'); | var controllers404 = require('../controllers/404.js'); | ||||||
|  |  | ||||||
| module.exports = function (app, middleware) { | module.exports = function (app, middleware) { | ||||||
| @@ -105,7 +106,7 @@ function generateForTopic(req, res, callback) { | |||||||
| 			var author = topicData.posts.length ? topicData.posts[0].username : ''; | 			var author = topicData.posts.length ? topicData.posts[0].username : ''; | ||||||
|  |  | ||||||
| 			var feed = new rss({ | 			var feed = new rss({ | ||||||
| 				title: topicData.title, | 				title: utils.stripHTMLTags(topicData.title, utils.stripTags), | ||||||
| 				description: description, | 				description: description, | ||||||
| 				feed_url: nconf.get('url') + '/topic/' + tid + '.rss', | 				feed_url: nconf.get('url') + '/topic/' + tid + '.rss', | ||||||
| 				site_url: nconf.get('url') + '/topic/' + topicData.slug, | 				site_url: nconf.get('url') + '/topic/' + topicData.slug, | ||||||
| @@ -124,7 +125,7 @@ function generateForTopic(req, res, callback) { | |||||||
| 					dateStamp = new Date(parseInt(parseInt(postData.edited, 10) === 0 ? postData.timestamp : postData.edited, 10)).toUTCString(); | 					dateStamp = new Date(parseInt(parseInt(postData.edited, 10) === 0 ? postData.timestamp : postData.edited, 10)).toUTCString(); | ||||||
|  |  | ||||||
| 					feed.item({ | 					feed.item({ | ||||||
| 						title: 'Reply to ' + topicData.title + ' on ' + dateStamp, | 						title: 'Reply to ' + utils.stripHTMLTags(topicData.title, utils.stripTags) + ' on ' + dateStamp, | ||||||
| 						description: postData.content, | 						description: postData.content, | ||||||
| 						url: nconf.get('url') + '/post/' + postData.pid, | 						url: nconf.get('url') + '/post/' + postData.pid, | ||||||
| 						author: postData.user ? postData.user.username : '', | 						author: postData.user ? postData.user.username : '', | ||||||
| @@ -252,16 +253,16 @@ function generateForPopular(req, res, next) { | |||||||
|  |  | ||||||
| 	async.waterfall([ | 	async.waterfall([ | ||||||
| 		function (next) { | 		function (next) { | ||||||
| 			topics.getPopular(term, req.uid, 19, next); | 			topics.getPopularTopics(term, req.uid, 0, 19, next); | ||||||
| 		}, | 		}, | ||||||
| 		function (topics, next) { | 		function (result, next) { | ||||||
| 			generateTopicsFeed({ | 			generateTopicsFeed({ | ||||||
| 				uid: req.uid, | 				uid: req.uid, | ||||||
| 				title: 'Popular Topics', | 				title: 'Popular Topics', | ||||||
| 				description: 'A list of topics that are sorted by post count', | 				description: 'A list of topics that are sorted by post count', | ||||||
| 				feed_url: '/popular/' + (req.params.term || 'daily') + '.rss', | 				feed_url: '/popular/' + (req.params.term || 'daily') + '.rss', | ||||||
| 				site_url: '/popular/' + (req.params.term || 'daily'), | 				site_url: '/popular/' + (req.params.term || 'daily'), | ||||||
| 			}, topics, next); | 			}, result.topics, next); | ||||||
| 		}, | 		}, | ||||||
| 		function (feed) { | 		function (feed) { | ||||||
| 			sendFeed(feed, res); | 			sendFeed(feed, res); | ||||||
| @@ -300,7 +301,7 @@ function generateTopicsFeed(feedOptions, feedTopics, callback) { | |||||||
|  |  | ||||||
| 	async.each(feedTopics, function (topicData, next) { | 	async.each(feedTopics, function (topicData, next) { | ||||||
| 		var feedItem = { | 		var feedItem = { | ||||||
| 			title: topicData.title, | 			title: utils.stripHTMLTags(topicData.title, utils.stripTags), | ||||||
| 			url: nconf.get('url') + '/topic/' + topicData.slug, | 			url: nconf.get('url') + '/topic/' + topicData.slug, | ||||||
| 			date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString(), | 			date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString(), | ||||||
| 		}; | 		}; | ||||||
|   | |||||||
| @@ -88,37 +88,37 @@ module.exports = function (SocketTopics) { | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	SocketTopics.loadMoreUnreadTopics = function (socket, data, callback) { | 	SocketTopics.loadMoreUnreadTopics = function (socket, data, callback) { | ||||||
| 		if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { | 		loadData(data, callback, function (start, stop) { | ||||||
| 			return callback(new Error('[[error:invalid-data]]')); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		var start = parseInt(data.after, 10); |  | ||||||
| 		var stop = start + Math.max(0, Math.min(meta.config.topicsPerPage || 20, parseInt(data.count, 10) || meta.config.topicsPerPage || 20) - 1); |  | ||||||
|  |  | ||||||
| 			topics.getUnreadTopics({ cid: data.cid, uid: socket.uid, start: start, stop: stop, filter: data.filter }, callback); | 			topics.getUnreadTopics({ cid: data.cid, uid: socket.uid, start: start, stop: stop, filter: data.filter }, callback); | ||||||
|  | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	SocketTopics.loadMoreRecentTopics = function (socket, data, callback) { | 	SocketTopics.loadMoreRecentTopics = function (socket, data, callback) { | ||||||
| 		if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { | 		loadData(data, callback, function (start, stop) { | ||||||
| 			return callback(new Error('[[error:invalid-data]]')); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		var start = parseInt(data.after, 10); |  | ||||||
| 		var stop = start + Math.max(0, Math.min(meta.config.topicsPerPage || 20, parseInt(data.count, 10) || meta.config.topicsPerPage || 20) - 1); |  | ||||||
|  |  | ||||||
| 			topics.getRecentTopics(data.cid, socket.uid, start, stop, data.filter, callback); | 			topics.getRecentTopics(data.cid, socket.uid, start, stop, data.filter, callback); | ||||||
|  | 		}); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	SocketTopics.loadMorePopularTopics = function (socket, data, callback) { | ||||||
|  | 		loadData(data, callback, function (start, stop) { | ||||||
|  | 			topics.getPopularTopics(data.term, socket.uid, start, stop, callback); | ||||||
|  | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	SocketTopics.loadMoreTopTopics = function (socket, data, callback) { | 	SocketTopics.loadMoreTopTopics = function (socket, data, callback) { | ||||||
|  | 		loadData(data, callback, function (start, stop) { | ||||||
|  | 			topics.getTopTopics(data.cid, socket.uid, start, stop, data.filter, callback); | ||||||
|  | 		}); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	function loadData(data, callback, loadFn) { | ||||||
| 		if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { | 		if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { | ||||||
| 			return callback(new Error('[[error:invalid-data]]')); | 			return callback(new Error('[[error:invalid-data]]')); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var start = parseInt(data.after, 10); | 		var start = parseInt(data.after, 10); | ||||||
| 		var stop = start + Math.max(0, Math.min(meta.config.topicsPerPage || 20, parseInt(data.count, 10) || meta.config.topicsPerPage || 20) - 1); | 		var stop = start + Math.max(0, Math.min(meta.config.topicsPerPage || 20, parseInt(data.count, 10) || meta.config.topicsPerPage || 20) - 1); | ||||||
|  | 		loadFn(start, stop); | ||||||
| 		topics.getTopTopics(data.cid, socket.uid, start, stop, data.filter, callback); | 	} | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	SocketTopics.loadMoreFromSet = function (socket, data, callback) { | 	SocketTopics.loadMoreFromSet = function (socket, data, callback) { | ||||||
| 		if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0 || !data.set) { | 		if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0 || !data.set) { | ||||||
|   | |||||||
| @@ -2,39 +2,50 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
| var async = require('async'); | var async = require('async'); | ||||||
|  |  | ||||||
|  | var db = require('../database'); | ||||||
| var privileges = require('../privileges'); | var privileges = require('../privileges'); | ||||||
|  |  | ||||||
| module.exports = function (Topics) { | module.exports = function (Topics) { | ||||||
| 	Topics.getPopular = function (term, uid, count, callback) { | 	Topics.getPopular = function (term, uid, count, callback) { | ||||||
| 		count = parseInt(count, 10) || 20; | 		count = parseInt(count, 10) || 20; | ||||||
|  |  | ||||||
| 		if (term === 'alltime') { |  | ||||||
| 			return getAllTimePopular(uid, count, callback); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		async.waterfall([ | 		async.waterfall([ | ||||||
| 			function (next) { | 			function (next) { | ||||||
| 				Topics.getLatestTidsFromSet('topics:tid', 0, -1, term, next); | 				Topics.getPopularTopics(term, uid, 0, count - 1, next); | ||||||
| 			}, | 			}, | ||||||
| 			function (tids, next) { | 			function (data, next) { | ||||||
| 				getTopics(tids, uid, count, next); | 				next(null, data.topics); | ||||||
| 			}, | 			}, | ||||||
| 		], callback); | 		], callback); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	function getAllTimePopular(uid, count, callback) { | 	Topics.getPopularTopics = function (term, uid, start, stop, callback) { | ||||||
|  | 		var popularTopics = { | ||||||
|  | 			nextStart: 0, | ||||||
|  | 			topicCount: 0, | ||||||
|  | 			topics: [], | ||||||
|  | 		}; | ||||||
| 		async.waterfall([ | 		async.waterfall([ | ||||||
| 			function (next) { | 			function (next) { | ||||||
| 				Topics.getTopicsFromSet('topics:posts', uid, 0, count - 1, next); | 				if (term === 'alltime') { | ||||||
|  | 					db.getSortedSetRevRange('topics:posts', 0, 199, next); | ||||||
|  | 				} else { | ||||||
|  | 					Topics.getLatestTidsFromSet('topics:tid', 0, -1, term, next); | ||||||
|  | 				} | ||||||
| 			}, | 			}, | ||||||
| 			function (data, next) { | 			function (tids, next) { | ||||||
| 				data.topics.sort(sortPopular); | 				popularTopics.topicCount = tids.length; | ||||||
| 				next(null, data.topics); | 				getTopics(tids, uid, start, stop, next); | ||||||
|  | 			}, | ||||||
|  | 			function (topics, next) { | ||||||
|  | 				popularTopics.topics = topics; | ||||||
|  | 				popularTopics.nextStart = stop + 1; | ||||||
|  | 				next(null, popularTopics); | ||||||
| 			}, | 			}, | ||||||
| 		], callback); | 		], callback); | ||||||
| 	} | 	}; | ||||||
|  |  | ||||||
| 	function getTopics(tids, uid, count, callback) { | 	function getTopics(tids, uid, start, stop, callback) { | ||||||
| 		async.waterfall([ | 		async.waterfall([ | ||||||
| 			function (next) { | 			function (next) { | ||||||
| 				Topics.getTopicsFields(tids, ['tid', 'postcount', 'deleted'], next); | 				Topics.getTopicsFields(tids, ['tid', 'postcount', 'deleted'], next); | ||||||
| @@ -42,7 +53,7 @@ module.exports = function (Topics) { | |||||||
| 			function (topics, next) { | 			function (topics, next) { | ||||||
| 				tids = topics.filter(function (topic) { | 				tids = topics.filter(function (topic) { | ||||||
| 					return topic && parseInt(topic.deleted, 10) !== 1; | 					return topic && parseInt(topic.deleted, 10) !== 1; | ||||||
| 				}).sort(sortPopular).slice(0, count).map(function (topic) { | 				}).sort(sortPopular).slice(start, stop !== -1 ? stop - 1 : undefined).map(function (topic) { | ||||||
| 					return topic.tid; | 					return topic.tid; | ||||||
| 				}); | 				}); | ||||||
| 				privileges.topics.filterTids('read', tids, uid, next); | 				privileges.topics.filterTids('read', tids, uid, next); | ||||||
|   | |||||||
| @@ -106,14 +106,14 @@ Digest.send = function (data, callback) { | |||||||
| 					function (next) { | 					function (next) { | ||||||
| 						async.parallel({ | 						async.parallel({ | ||||||
| 							notifications: async.apply(user.notifications.getDailyUnread, userObj.uid), | 							notifications: async.apply(user.notifications.getDailyUnread, userObj.uid), | ||||||
| 							topics: async.apply(topics.getPopular, data.interval, userObj.uid, 10), | 							popular: async.apply(topics.getPopularTopics, data.interval, userObj.uid, 0, 9), | ||||||
| 						}, next); | 						}, next); | ||||||
| 					}, | 					}, | ||||||
| 					function (data, next) { | 					function (data, next) { | ||||||
| 						var notifications = data.notifications.filter(Boolean); | 						var notifications = data.notifications.filter(Boolean); | ||||||
|  |  | ||||||
| 						// If there are no notifications and no new topics, don't bother sending a digest | 						// If there are no notifications and no new topics, don't bother sending a digest | ||||||
| 						if (!notifications.length && !data.topics.length) { | 						if (!notifications.length && !data.popular.topics.length) { | ||||||
| 							return next(); | 							return next(); | ||||||
| 						} | 						} | ||||||
|  |  | ||||||
| @@ -124,7 +124,7 @@ Digest.send = function (data, callback) { | |||||||
| 						}); | 						}); | ||||||
|  |  | ||||||
| 						// Fix relative paths in topic data | 						// Fix relative paths in topic data | ||||||
| 						data.topics = data.topics.map(function (topicObj) { | 						data.popular.topics = data.popular.topics.map(function (topicObj) { | ||||||
| 							var user = topicObj.hasOwnProperty('teaser') && topicObj.teaser !== undefined ? topicObj.teaser.user : topicObj.user; | 							var user = topicObj.hasOwnProperty('teaser') && topicObj.teaser !== undefined ? topicObj.teaser.user : topicObj.user; | ||||||
| 							if (user && user.picture && utils.isRelativeUrl(user.picture)) { | 							if (user && user.picture && utils.isRelativeUrl(user.picture)) { | ||||||
| 								user.picture = nconf.get('base_url') + user.picture; | 								user.picture = nconf.get('base_url') + user.picture; | ||||||
| @@ -138,7 +138,7 @@ Digest.send = function (data, callback) { | |||||||
| 							username: userObj.username, | 							username: userObj.username, | ||||||
| 							userslug: userObj.userslug, | 							userslug: userObj.userslug, | ||||||
| 							notifications: notifications, | 							notifications: notifications, | ||||||
| 							recent: data.topics, | 							recent: data.popular.topics, | ||||||
| 							interval: data.interval, | 							interval: data.interval, | ||||||
| 							showUnsubscribe: true, | 							showUnsubscribe: true, | ||||||
| 						}, function (err) { | 						}, function (err) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user