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", | ||||
|         "mubsub": "^1.4.0", | ||||
|         "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-emoji": "2.1.0", | ||||
|         "nodebb-plugin-emoji-android": "2.0.0", | ||||
| @@ -70,9 +70,9 @@ | ||||
|         "nodebb-plugin-spam-be-gone": "0.5.1", | ||||
|         "nodebb-rewards-essentials": "0.0.11", | ||||
|         "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-vanilla": "8.1.7", | ||||
|         "nodebb-theme-vanilla": "8.1.9", | ||||
|         "nodebb-widget-essentials": "4.0.1", | ||||
|         "nodemailer": "4.4.1", | ||||
|         "passport": "^0.4.0", | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
|     "guest-login-reply": "התחבר כדי לפרסם תגובה", | ||||
|     "edit": "עריכה", | ||||
|     "delete": "מחק", | ||||
|     "purge": "מחק הכל", | ||||
|     "purge": "מחק לצמיתות", | ||||
|     "restore": "שחזר", | ||||
|     "move": "הזז", | ||||
|     "fork": "פורק", | ||||
| @@ -94,7 +94,7 @@ | ||||
|     "merge_topics_instruction": "Click the topics you want to merge", | ||||
|     "composer.title_placeholder": "הכנס את כותרת הנושא כאן...", | ||||
|     "composer.handle_placeholder": "שם", | ||||
|     "composer.discard": "מחק", | ||||
|     "composer.discard": "ביטול", | ||||
|     "composer.submit": "שלח", | ||||
|     "composer.replying_to": "מגיב ל %1", | ||||
|     "composer.new_topic": "נושא חדש", | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| { | ||||
| 	"state": "State", | ||||
| 	"state": "Состояние", | ||||
| 	"reporter": "Reporter", | ||||
| 	"reported-at": "Reported At", | ||||
| 	"description": "Описание", | ||||
| @@ -9,7 +9,7 @@ | ||||
| 	"updated": "Обновлено", | ||||
| 	"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-reset": "Убрать фильтры", | ||||
| 	"filters": "Filter Options", | ||||
| @@ -17,13 +17,13 @@ | ||||
| 	"filter-targetUid": "Flagged UID", | ||||
| 	"filter-type": "Flag Type", | ||||
| 	"filter-type-all": "Весь контент", | ||||
| 	"filter-type-post": "Написать", | ||||
| 	"filter-state": "State", | ||||
| 	"filter-type-post": "Сообщение", | ||||
| 	"filter-state": "Состояние", | ||||
| 	"filter-assignee": "Assignee UID", | ||||
| 	"filter-cid": "Категория", | ||||
| 	"filter-quick-mine": "Assigned to me", | ||||
| 	"filter-cid-all": "Все категории", | ||||
| 	"apply-filters": "Apply Filters", | ||||
| 	"apply-filters": "Применить фильтры", | ||||
|  | ||||
| 	"quick-links": "Quick Links", | ||||
| 	"flagged-user": "Flagged User", | ||||
| @@ -32,7 +32,7 @@ | ||||
| 	"go-to-target": "View Flag Target", | ||||
|  | ||||
| 	"user-view": "Просмотреть профиль", | ||||
| 	"user-edit": "Изменить Профиль", | ||||
| 	"user-edit": "Изменить профиль", | ||||
|  | ||||
| 	"notes": "Flag Notes", | ||||
| 	"add-note": "Добавить примечание", | ||||
| @@ -42,8 +42,8 @@ | ||||
| 	"back": "Back to Flags List", | ||||
| 	"no-history": "No flag history.", | ||||
|  | ||||
| 	"state-all": "Все государства", | ||||
| 	"state-open": "Новый/Открыть", | ||||
| 	"state-all": "Все состояния", | ||||
| 	"state-open": "Новый/Открытый", | ||||
| 	"state-wip": "Work in Progress", | ||||
| 	"state-resolved": "Решен", | ||||
| 	"state-rejected": "Отклонен", | ||||
| @@ -53,12 +53,12 @@ | ||||
| 	"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-reason-spam": "Спам", | ||||
| 	"modal-reason-offensive": "Offensive", | ||||
| 	"modal-reason-other": "Other (specify below)", | ||||
| 	"modal-reason-custom": "Reason for reporting this content...", | ||||
| 	"modal-reason-offensive": "Оскорбительный", | ||||
| 	"modal-reason-other": "Другое (укажите ниже)", | ||||
| 	"modal-reason-custom": "Причина жалобы на содержимое...", | ||||
| 	"modal-submit": "Представить отчет", | ||||
| 	"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-help": "Submitting a quick report will overwrite any custom reasons defined." | ||||
| } | ||||
| @@ -1,7 +1,7 @@ | ||||
| 'use strict'; | ||||
|  | ||||
|  | ||||
| define('forum/popular', ['components'], function (components) { | ||||
| define('forum/popular', ['forum/recent', 'components', 'forum/infinitescroll'], function (recent, components, infinitescroll) { | ||||
| 	var Popular = {}; | ||||
|  | ||||
| 	Popular.init = function () { | ||||
| @@ -11,7 +11,30 @@ define('forum/popular', ['components'], function (components) { | ||||
| 			.removeClass('active') | ||||
| 			.find('a[href="' + window.location.pathname + '"]') | ||||
| 			.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; | ||||
| }); | ||||
|   | ||||
| @@ -113,7 +113,7 @@ helpers.getUserDataByUserSlug = function (userslug, callerUID, callback) { | ||||
| 				userData.fullname = ''; | ||||
| 			} | ||||
|  | ||||
| 			if (isAdmin || isSelf || (isGlobalModerator && !results.isTargetAdmin)) { | ||||
| 			if (isAdmin || isSelf || ((isGlobalModerator || isModerator) && !results.isTargetAdmin)) { | ||||
| 				userData.ips = results.ips; | ||||
| 			} | ||||
|  | ||||
|   | ||||
| @@ -3,9 +3,12 @@ | ||||
|  | ||||
| var async = require('async'); | ||||
| var nconf = require('nconf'); | ||||
|  | ||||
| var topics = require('../topics'); | ||||
| var meta = require('../meta'); | ||||
| var user = require('../user'); | ||||
| var helpers = require('./helpers'); | ||||
| var pagination = require('../pagination'); | ||||
|  | ||||
| var popularController = module.exports; | ||||
|  | ||||
| @@ -19,6 +22,7 @@ var terms = { | ||||
| }; | ||||
|  | ||||
| popularController.get = function (req, res, next) { | ||||
| 	var page = parseInt(req.query.page, 10) || 1; | ||||
| 	var term = terms[req.params.term]; | ||||
|  | ||||
| 	if (!term && req.params.term) { | ||||
| @@ -38,19 +42,25 @@ popularController.get = function (req, res, next) { | ||||
| 			return res.render('popular', anonCache[term]); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	var settings; | ||||
| 	async.waterfall([ | ||||
| 		function (next) { | ||||
| 			topics.getPopular(term, req.uid, meta.config.topicsPerList, next); | ||||
| 			user.getSettings(req.uid, next); | ||||
| 		}, | ||||
| 		function (topics) { | ||||
| 			var data = { | ||||
| 				title: meta.config.homePageTitle || '[[pages:home]]', | ||||
| 				topics: topics, | ||||
| 				'feeds:disableRSS': parseInt(meta.config['feeds:disableRSS'], 10) === 1, | ||||
| 				rssFeedUrl: nconf.get('relative_path') + '/popular/' + (req.params.term || 'daily') + '.rss', | ||||
| 				term: term, | ||||
| 			}; | ||||
| 		function (_settings, next) { | ||||
| 			settings = _settings; | ||||
| 			var start = Math.max(0, (page - 1) * settings.topicsPerPage); | ||||
| 			var stop = start + settings.topicsPerPage - 1; | ||||
| 			topics.getPopularTopics(term, req.uid, start, stop, next); | ||||
| 		}, | ||||
| 		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')) { | ||||
| 				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'])) { | ||||
| 		return res.redirect(meta.config['brand:touchIcon']); | ||||
| 	} | ||||
| 	var iconPath = '../../public'; | ||||
| 	var iconPath = ''; | ||||
| 	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 { | ||||
| 		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, | ||||
| 	}); | ||||
| }; | ||||
|   | ||||
| @@ -13,6 +13,7 @@ var meta = require('../meta'); | ||||
| var helpers = require('../controllers/helpers'); | ||||
| var privileges = require('../privileges'); | ||||
| var db = require('../database'); | ||||
| var utils = require('../utils'); | ||||
| var controllers404 = require('../controllers/404.js'); | ||||
|  | ||||
| module.exports = function (app, middleware) { | ||||
| @@ -105,7 +106,7 @@ function generateForTopic(req, res, callback) { | ||||
| 			var author = topicData.posts.length ? topicData.posts[0].username : ''; | ||||
|  | ||||
| 			var feed = new rss({ | ||||
| 				title: topicData.title, | ||||
| 				title: utils.stripHTMLTags(topicData.title, utils.stripTags), | ||||
| 				description: description, | ||||
| 				feed_url: nconf.get('url') + '/topic/' + tid + '.rss', | ||||
| 				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(); | ||||
|  | ||||
| 					feed.item({ | ||||
| 						title: 'Reply to ' + topicData.title + ' on ' + dateStamp, | ||||
| 						title: 'Reply to ' + utils.stripHTMLTags(topicData.title, utils.stripTags) + ' on ' + dateStamp, | ||||
| 						description: postData.content, | ||||
| 						url: nconf.get('url') + '/post/' + postData.pid, | ||||
| 						author: postData.user ? postData.user.username : '', | ||||
| @@ -252,16 +253,16 @@ function generateForPopular(req, res, next) { | ||||
|  | ||||
| 	async.waterfall([ | ||||
| 		function (next) { | ||||
| 			topics.getPopular(term, req.uid, 19, next); | ||||
| 			topics.getPopularTopics(term, req.uid, 0, 19, next); | ||||
| 		}, | ||||
| 		function (topics, next) { | ||||
| 		function (result, next) { | ||||
| 			generateTopicsFeed({ | ||||
| 				uid: req.uid, | ||||
| 				title: 'Popular Topics', | ||||
| 				description: 'A list of topics that are sorted by post count', | ||||
| 				feed_url: '/popular/' + (req.params.term || 'daily') + '.rss', | ||||
| 				site_url: '/popular/' + (req.params.term || 'daily'), | ||||
| 			}, topics, next); | ||||
| 			}, result.topics, next); | ||||
| 		}, | ||||
| 		function (feed) { | ||||
| 			sendFeed(feed, res); | ||||
| @@ -300,7 +301,7 @@ function generateTopicsFeed(feedOptions, feedTopics, callback) { | ||||
|  | ||||
| 	async.each(feedTopics, function (topicData, next) { | ||||
| 		var feedItem = { | ||||
| 			title: topicData.title, | ||||
| 			title: utils.stripHTMLTags(topicData.title, utils.stripTags), | ||||
| 			url: nconf.get('url') + '/topic/' + topicData.slug, | ||||
| 			date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString(), | ||||
| 		}; | ||||
|   | ||||
| @@ -88,37 +88,37 @@ module.exports = function (SocketTopics) { | ||||
| 	}; | ||||
|  | ||||
| 	SocketTopics.loadMoreUnreadTopics = function (socket, data, callback) { | ||||
| 		if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { | ||||
| 			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); | ||||
|  | ||||
| 		loadData(data, callback, function (start, stop) { | ||||
| 			topics.getUnreadTopics({ cid: data.cid, uid: socket.uid, start: start, stop: stop, filter: data.filter }, callback); | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	SocketTopics.loadMoreRecentTopics = function (socket, data, callback) { | ||||
| 		if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) { | ||||
| 			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); | ||||
|  | ||||
| 		loadData(data, callback, function (start, stop) { | ||||
| 			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) { | ||||
| 		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) { | ||||
| 			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.getTopTopics(data.cid, socket.uid, start, stop, data.filter, callback); | ||||
| 	}; | ||||
| 		loadFn(start, stop); | ||||
| 	} | ||||
|  | ||||
| 	SocketTopics.loadMoreFromSet = function (socket, data, callback) { | ||||
| 		if (!data || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0 || !data.set) { | ||||
|   | ||||
| @@ -2,39 +2,50 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| var async = require('async'); | ||||
|  | ||||
| var db = require('../database'); | ||||
| var privileges = require('../privileges'); | ||||
|  | ||||
| module.exports = function (Topics) { | ||||
| 	Topics.getPopular = function (term, uid, count, callback) { | ||||
| 		count = parseInt(count, 10) || 20; | ||||
|  | ||||
| 		if (term === 'alltime') { | ||||
| 			return getAllTimePopular(uid, count, callback); | ||||
| 		} | ||||
|  | ||||
| 		async.waterfall([ | ||||
| 			function (next) { | ||||
| 				Topics.getLatestTidsFromSet('topics:tid', 0, -1, term, next); | ||||
| 				Topics.getPopularTopics(term, uid, 0, count - 1, next); | ||||
| 			}, | ||||
| 			function (tids, next) { | ||||
| 				getTopics(tids, uid, count, next); | ||||
| 			function (data, next) { | ||||
| 				next(null, data.topics); | ||||
| 			}, | ||||
| 		], callback); | ||||
| 	}; | ||||
|  | ||||
| 	function getAllTimePopular(uid, count, callback) { | ||||
| 	Topics.getPopularTopics = function (term, uid, start, stop, callback) { | ||||
| 		var popularTopics = { | ||||
| 			nextStart: 0, | ||||
| 			topicCount: 0, | ||||
| 			topics: [], | ||||
| 		}; | ||||
| 		async.waterfall([ | ||||
| 			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) { | ||||
| 				data.topics.sort(sortPopular); | ||||
| 				next(null, data.topics); | ||||
| 			function (tids, next) { | ||||
| 				popularTopics.topicCount = tids.length; | ||||
| 				getTopics(tids, uid, start, stop, next); | ||||
| 			}, | ||||
| 			function (topics, next) { | ||||
| 				popularTopics.topics = topics; | ||||
| 				popularTopics.nextStart = stop + 1; | ||||
| 				next(null, popularTopics); | ||||
| 			}, | ||||
| 		], callback); | ||||
| 	} | ||||
| 	}; | ||||
|  | ||||
| 	function getTopics(tids, uid, count, callback) { | ||||
| 	function getTopics(tids, uid, start, stop, callback) { | ||||
| 		async.waterfall([ | ||||
| 			function (next) { | ||||
| 				Topics.getTopicsFields(tids, ['tid', 'postcount', 'deleted'], next); | ||||
| @@ -42,7 +53,7 @@ module.exports = function (Topics) { | ||||
| 			function (topics, next) { | ||||
| 				tids = topics.filter(function (topic) { | ||||
| 					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; | ||||
| 				}); | ||||
| 				privileges.topics.filterTids('read', tids, uid, next); | ||||
|   | ||||
| @@ -106,14 +106,14 @@ Digest.send = function (data, callback) { | ||||
| 					function (next) { | ||||
| 						async.parallel({ | ||||
| 							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); | ||||
| 					}, | ||||
| 					function (data, next) { | ||||
| 						var notifications = data.notifications.filter(Boolean); | ||||
|  | ||||
| 						// 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(); | ||||
| 						} | ||||
|  | ||||
| @@ -124,7 +124,7 @@ Digest.send = function (data, callback) { | ||||
| 						}); | ||||
|  | ||||
| 						// 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; | ||||
| 							if (user && user.picture && utils.isRelativeUrl(user.picture)) { | ||||
| 								user.picture = nconf.get('base_url') + user.picture; | ||||
| @@ -138,7 +138,7 @@ Digest.send = function (data, callback) { | ||||
| 							username: userObj.username, | ||||
| 							userslug: userObj.userslug, | ||||
| 							notifications: notifications, | ||||
| 							recent: data.topics, | ||||
| 							recent: data.popular.topics, | ||||
| 							interval: data.interval, | ||||
| 							showUnsubscribe: true, | ||||
| 						}, function (err) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user