mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-05-07 16:46:24 +02:00
infinite scrolling for topics in category view, changed how topics are stored in categories, using sorted sets instead of sets now, if you update to this commit run node app --upgrade to upgrade the redis schema, #141
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
googleEl = document.getElementById('google-share'),
|
||||
twitter_url = templates.get('twitter-intent-url'),
|
||||
facebook_url = templates.get('facebook-share-url'),
|
||||
google_url = templates.get('google-share-url');
|
||||
google_url = templates.get('google-share-url'),
|
||||
loadingMoreTopics = false;
|
||||
|
||||
app.enter_room(room);
|
||||
|
||||
@@ -26,7 +27,7 @@
|
||||
var new_post = document.getElementById('new_post');
|
||||
new_post.onclick = function() {
|
||||
require(['composer'], function(cmp) {
|
||||
cmp.push(0, cid);
|
||||
cmp.push(0, cid);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -34,7 +35,8 @@
|
||||
'event:new_topic'
|
||||
]);
|
||||
|
||||
socket.on('event:new_topic', function(data) {
|
||||
function onNewTopic(data) {
|
||||
|
||||
var html = templates.prepare(templates['category'].blocks['topics']).parse({ topics: [data] }),
|
||||
topic = document.createElement('div'),
|
||||
container = document.getElementById('topics-container'),
|
||||
@@ -59,8 +61,9 @@
|
||||
container.insertBefore(topic, null);
|
||||
$(topic).hide().fadeIn('slow');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
socket.on('event:new_topic', onNewTopic);
|
||||
|
||||
socket.emit('api:categories.getRecentReplies', cid);
|
||||
socket.on('api:categories.getRecentReplies', function(posts) {
|
||||
@@ -91,5 +94,41 @@
|
||||
recent_replies.appendChild(frag);
|
||||
}
|
||||
});
|
||||
|
||||
function onTopicsLoaded(topics) {
|
||||
|
||||
var html = templates.prepare(templates['category'].blocks['topics']).parse({ topics: topics }),
|
||||
container = $('#topics-container');
|
||||
|
||||
jQuery('#topics-container, .category-sidebar').removeClass('hidden');
|
||||
jQuery('#category-no-topics').remove();
|
||||
|
||||
container.append(html);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function loadMoreTopics(cid) {
|
||||
loadingMoreTopics = true;
|
||||
socket.emit('api:category.loadMore', {
|
||||
cid: cid,
|
||||
after: $('#topics-container').children().length
|
||||
}, function(data) {
|
||||
if(data.topics.length) {
|
||||
onTopicsLoaded(data.topics);
|
||||
loadingMoreTopics = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(window).off('scroll').on('scroll', function(ev) {
|
||||
var windowHeight = document.body.offsetHeight - $(window).height(),
|
||||
half = windowHeight / 2;
|
||||
|
||||
if (document.body.scrollTop > half && !loadingMoreTopics) {
|
||||
loadMoreTopics(cid);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
})();
|
||||
@@ -201,9 +201,8 @@
|
||||
}, false);
|
||||
|
||||
// Infinite scrolling of posts
|
||||
$(window).off('scroll');
|
||||
$(window).on('scroll', function() {
|
||||
var windowHeight = document.body.offsetHeight - $(window).height(),
|
||||
$(window).off('scroll').on('scroll', function() {
|
||||
var windowHeight = document.body.offsetHeight - $(window).height(),
|
||||
half = windowHeight / 2;
|
||||
|
||||
if (document.body.scrollTop > half && !app.infiniteLoaderActive && $('#post-container').children().length) {
|
||||
|
||||
@@ -17,8 +17,9 @@ var RDB = require('./redis.js'),
|
||||
category_description = categoryData.description;
|
||||
|
||||
function getTopicIds(next) {
|
||||
Categories.getTopicIds(category_id, next);
|
||||
Categories.getTopicIds(category_id, 0, 19, next);
|
||||
}
|
||||
|
||||
function getActiveUsers(next) {
|
||||
Categories.getActiveUsers(category_id, next);
|
||||
}
|
||||
@@ -44,15 +45,7 @@ var RDB = require('./redis.js'),
|
||||
|
||||
function getTopics(next) {
|
||||
topics.getTopicsByTids(tids, current_user, function(topicsData) {
|
||||
// Float pinned topics to the top
|
||||
topicsData = topicsData.sort(function(a, b) {
|
||||
if (a.pinned !== b.pinned) return b.pinned - a.pinned;
|
||||
else {
|
||||
return b.lastposttime - a.lastposttime;
|
||||
}
|
||||
});
|
||||
next(null, topicsData);
|
||||
|
||||
}, category_id);
|
||||
}
|
||||
|
||||
@@ -89,8 +82,16 @@ var RDB = require('./redis.js'),
|
||||
});
|
||||
}
|
||||
|
||||
Categories.getTopicIds = function(cid, callback) {
|
||||
RDB.smembers('categories:' + cid + ':tid', callback);
|
||||
Categories.getCategoryTopics = function(cid, start, stop, uid, callback) {
|
||||
Categories.getTopicIds(cid, start, stop, function(err, tids) {
|
||||
topics.getTopicsByTids(tids, uid, function(topicsData) {
|
||||
callback(topicsData);
|
||||
}, cid);
|
||||
});
|
||||
}
|
||||
|
||||
Categories.getTopicIds = function(cid, start, stop, callback) {
|
||||
RDB.zrevrange('categories:' + cid + ':tid', start, stop, callback);
|
||||
}
|
||||
|
||||
Categories.getActiveUsers = function(cid, callback) {
|
||||
@@ -144,7 +145,7 @@ var RDB = require('./redis.js'),
|
||||
}
|
||||
|
||||
Categories.isTopicsRead = function(cid, uid, callback) {
|
||||
RDB.smembers('categories:' + cid + ':tid', function(err, tids) {
|
||||
RDB.zrange('categories:' + cid + ':tid', 0, -1, function(err, tids) {
|
||||
|
||||
topics.hasReadTopics(tids, uid, function(hasRead) {
|
||||
|
||||
|
||||
46
src/posts.js
46
src/posts.js
@@ -108,6 +108,20 @@ var RDB = require('./redis.js'),
|
||||
});
|
||||
}
|
||||
|
||||
Posts.getPostField = function(pid, field, callback) {
|
||||
RDB.hget('post:' + pid, field, function(err, data) {
|
||||
if(err === null)
|
||||
callback(data);
|
||||
else
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
Posts.setPostField = function(pid, field, value) {
|
||||
RDB.hset('post:' + pid, field, value);
|
||||
}
|
||||
|
||||
|
||||
Posts.getPostsByPids = function(pids, callback) {
|
||||
var posts = [];
|
||||
|
||||
@@ -141,35 +155,6 @@ var RDB = require('./redis.js'),
|
||||
});
|
||||
}
|
||||
|
||||
Posts.getPostField = function(pid, field, callback) {
|
||||
RDB.hget('post:' + pid, field, function(err, data) {
|
||||
if(err === null)
|
||||
callback(data);
|
||||
else
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
Posts.setPostField = function(pid, field, value) {
|
||||
RDB.hset('post:' + pid, field, value);
|
||||
}
|
||||
|
||||
Posts.getPostFields = function(pid, fields, callback) {
|
||||
RDB.hmget('post:' + pid, fields, function(err, data) {
|
||||
if(err === null) {
|
||||
var returnData = {};
|
||||
|
||||
for(var i=0, ii=fields.length; i<ii; ++i) {
|
||||
returnData[fields[i]] = data[i];
|
||||
}
|
||||
|
||||
callback(returnData);
|
||||
}
|
||||
else
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
Posts.get_cid_by_pid = function(pid, callback) {
|
||||
Posts.getPostField(pid, 'tid', function(tid) {
|
||||
if (tid) {
|
||||
@@ -317,7 +302,8 @@ var RDB = require('./redis.js'),
|
||||
|
||||
feed.updateTopic(tid, cid);
|
||||
|
||||
RDB.zadd('categories:recent_posts:cid:' + cid, Date.now(), pid);
|
||||
RDB.zadd('categories:recent_posts:cid:' + cid, timestamp, pid);
|
||||
RDB.zadd('categories:' + cid + ':tid', timestamp, tid);
|
||||
|
||||
// this is a bit of a naive implementation, defn something to look at post-MVP
|
||||
RDB.scard('cid:' + cid + ':active_users', function(amount) {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
(function(RedisDB) {
|
||||
var redis = require('redis'),
|
||||
var redis = require('redis'),
|
||||
nconf = require('nconf'),
|
||||
utils = require('./../public/src/utils.js');
|
||||
|
||||
RedisDB.exports = redis.createClient(global.nconf.get('redis:port'), global.nconf.get('redis:host'));
|
||||
RedisDB.exports = redis.createClient(nconf.get('redis:port'), nconf.get('redis:host'));
|
||||
|
||||
if( global.nconf.get('redis:password') ) {
|
||||
RedisDB.exports.auth(global.nconf.get('redis:password'));
|
||||
if(nconf.get('redis:password')) {
|
||||
RedisDB.exports.auth(nconf.get('redis:password'));
|
||||
}
|
||||
|
||||
RedisDB.exports.handle = function(error) {
|
||||
|
||||
@@ -133,7 +133,10 @@ var RDB = require('./redis.js'),
|
||||
if (privileges.editable) {
|
||||
|
||||
topics.setTopicField(tid, 'pinned', 1);
|
||||
|
||||
topics.getTopicField(tid, 'cid', function(cid) {
|
||||
RDB.zadd('categories:' + cid + ':tid', Math.pow(2,53), tid);
|
||||
});
|
||||
|
||||
if (socket) {
|
||||
io.sockets.in('topic_' + tid).emit('event:topic_pinned', {
|
||||
tid: tid,
|
||||
@@ -154,7 +157,9 @@ var RDB = require('./redis.js'),
|
||||
if (privileges.editable) {
|
||||
|
||||
topics.setTopicField(tid, 'pinned', 0);
|
||||
|
||||
topics.getTopicFields(tid, ['cid', 'lastposttime'], function(topicData) {
|
||||
RDB.zadd('categories:' + topicData.cid + ':tid', topicData.lastposttime, tid);
|
||||
});
|
||||
if (socket) {
|
||||
io.sockets.in('topic_' + tid).emit('event:topic_unpinned', {
|
||||
tid: tid,
|
||||
@@ -172,13 +177,19 @@ var RDB = require('./redis.js'),
|
||||
|
||||
ThreadTools.move = function(tid, cid, socket) {
|
||||
|
||||
topics.getTopicField(tid, 'cid', function(oldCid) {
|
||||
topics.getTopicFields(tid, ['cid', 'lastposttime'], function(topicData) {
|
||||
var oldCid = topicData.cid;
|
||||
var multi = RDB.multi();
|
||||
|
||||
multi.zrem('categories:' + oldCid + ':tid', tid);
|
||||
multi.zadd('categories:' + cid + ':tid', topicData.lastposttime, tid);
|
||||
|
||||
multi.exec(function(err, result) {
|
||||
|
||||
RDB.smove('categories:' + oldCid + ':tid', 'categories:' + cid + ':tid', tid, function(err, result) {
|
||||
if (!err && result === 1) {
|
||||
|
||||
topics.setTopicField(tid, 'cid', cid);
|
||||
|
||||
|
||||
categories.moveRecentReplies(tid, oldCid, cid, function(err, data) {
|
||||
if(err) {
|
||||
console.log(err);
|
||||
|
||||
@@ -628,7 +628,7 @@ marked.setOptions({
|
||||
|
||||
|
||||
// in future it may be possible to add topics to several categories, so leaving the door open here.
|
||||
RDB.sadd('categories:' + category_id + ':tid', tid);
|
||||
RDB.zadd('categories:' + category_id + ':tid', timestamp, tid);
|
||||
RDB.hincrby('category:' + category_id, 'topic_count', 1);
|
||||
RDB.incr('totaltopiccount');
|
||||
|
||||
@@ -652,6 +652,17 @@ marked.setOptions({
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
Topics.getTopicFields = function(tid, fields, callback) {
|
||||
RDB.hmgetObject('topic:' + tid, fields, function(err, data) {
|
||||
if(err === null) {
|
||||
callback(data);
|
||||
}
|
||||
else {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Topics.setTopicField = function(tid, field, value) {
|
||||
RDB.hset('topic:' + tid, field, value);
|
||||
|
||||
@@ -1,6 +1,74 @@
|
||||
var RDB = require('./redis.js'),
|
||||
async = require('async');
|
||||
|
||||
|
||||
|
||||
function upgradeCategory(cid, callback) {
|
||||
RDB.type('categories:'+ cid +':tid', function(err, type) {
|
||||
if (type === 'set') {
|
||||
RDB.smembers('categories:' + cid + ':tid', function(err, tids) {
|
||||
|
||||
function moveTopic(tid, callback) {
|
||||
RDB.hget('topic:' + tid, 'timestamp', function(err, timestamp) {
|
||||
if(err)
|
||||
return callback(err);
|
||||
|
||||
RDB.zadd('temp_categories:'+ cid + ':tid', timestamp, tid);
|
||||
callback(null);
|
||||
});
|
||||
}
|
||||
|
||||
async.each(tids, moveTopic, function(err) {
|
||||
if(!err) {
|
||||
console.log('renaming ' + cid);
|
||||
RDB.rename('temp_categories:' + cid + ':tid', 'categories:' + cid + ':tid');
|
||||
callback(null);
|
||||
}
|
||||
else
|
||||
callback(err);
|
||||
});
|
||||
|
||||
});
|
||||
} else {
|
||||
console.log('category already upgraded '+ cid);
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
exports.upgrade = function() {
|
||||
console.log('upgrading nodebb now');
|
||||
|
||||
console.log('upgrading nodebb now');
|
||||
|
||||
var schema = [
|
||||
function upgradeCategories(next) {
|
||||
console.log('upgrading categories');
|
||||
|
||||
RDB.lrange('categories:cid', 0, -1, function(err, cids) {
|
||||
|
||||
async.each(cids, upgradeCategory, function(err) {
|
||||
if(!err)
|
||||
next(null, 'upgraded categories');
|
||||
else
|
||||
next(err, null);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
function upgradeUsers(next) {
|
||||
console.log('upgrading users');
|
||||
next(null, 'upgraded users');
|
||||
}
|
||||
];
|
||||
|
||||
async.series(schema, function(err, results) {
|
||||
if(!err)
|
||||
console.log('upgrade complete');
|
||||
else
|
||||
console.log(err);
|
||||
|
||||
process.exit();
|
||||
|
||||
});
|
||||
}
|
||||
@@ -554,12 +554,21 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
|
||||
|
||||
socket.on('api:topic.loadMore', function(data, callback) {
|
||||
var start = data.after,
|
||||
end = start + 10;
|
||||
end = start + 9;
|
||||
|
||||
topics.getTopicPosts(data.tid, start, end, uid, function(posts) {
|
||||
callback({posts:posts});
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('api:category.loadMore', function(data, callback) {
|
||||
var start = data.after,
|
||||
end = start + 9;
|
||||
|
||||
categories.getCategoryTopics(data.cid, start, end, uid, function(topics) {
|
||||
callback({topics:topics});
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('api:admin.topics.getMore', function(data) {
|
||||
topics.getAllTopics(data.limit, data.after, function(topics) {
|
||||
|
||||
Reference in New Issue
Block a user