mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-29 01:56:12 +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]]'));
|
topics.getUnreadTopics({ cid: data.cid, uid: socket.uid, start: start, stop: stop, filter: data.filter }, callback);
|
||||||
}
|
});
|
||||||
|
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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]]'));
|
topics.getRecentTopics(data.cid, socket.uid, start, stop, data.filter, callback);
|
||||||
}
|
});
|
||||||
|
};
|
||||||
|
|
||||||
var start = parseInt(data.after, 10);
|
SocketTopics.loadMorePopularTopics = function (socket, data, callback) {
|
||||||
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.getPopularTopics(data.term, socket.uid, start, stop, callback);
|
||||||
topics.getRecentTopics(data.cid, socket.uid, start, stop, data.filter, 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