mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-07-01 10:58:06 +02:00
closes #6287
This commit is contained in:
@@ -69,9 +69,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.19",
|
||||
"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",
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -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 + ']]';
|
||||
|
||||
@@ -252,16 +252,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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
topics.getUnreadTopics({ cid: data.cid, uid: socket.uid, start: start, stop: stop, filter: data.filter }, callback);
|
||||
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]]'));
|
||||
}
|
||||
loadData(data, callback, function (start, stop) {
|
||||
topics.getRecentTopics(data.cid, socket.uid, start, stop, 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.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