added infinite scrolling to unread page, issue #141

v1.18.x
Baris Soner Usakli 12 years ago
parent cbd34a4411
commit 50c34e4f33

@ -48,20 +48,6 @@
updateAlertText(); updateAlertText();
}); });
$('#mark-allread-btn').on('click', function() {
var btn = $(this);
socket.emit('api:topics.markAllRead', {} , function(success) {
if(success) {
btn.remove();
$('#topics-container').empty();
$('#category-no-topics').removeClass('hidden');
app.alertSuccess('All topics marked as read!');
} else {
app.alertError('There was an error marking topics read!');
}
});
});
function onTopicsLoaded(topics) { function onTopicsLoaded(topics) {
var html = templates.prepare(templates['recent'].blocks['topics']).parse({ topics: topics }), var html = templates.prepare(templates['recent'].blocks['topics']).parse({ topics: topics }),

@ -0,0 +1,103 @@
(function() {
var loadingMoreTopics = false;
app.enter_room('recent_posts');
ajaxify.register_events([
'event:new_topic',
'event:new_post'
]);
var newTopicCount = 0, newPostCount = 0;
$('#new-topics-alert').on('click', function() {
$(this).hide();
});
socket.on('event:new_topic', function(data) {
++newTopicCount;
updateAlertText();
});
function updateAlertText() {
var text = '';
if(newTopicCount > 1)
text = 'There are ' + newTopicCount + ' new topics';
else if(newTopicCount === 1)
text = 'There is 1 new topic';
else
text = 'There are no new topics';
if(newPostCount > 1)
text += ' and ' + newPostCount + ' new posts.';
else if(newPostCount === 1)
text += ' and 1 new post.';
else
text += ' and no new posts.';
text += ' Click here to reload.';
$('#new-topics-alert').html(text).fadeIn('slow');
}
socket.on('event:new_post', function(data) {
++newPostCount;
updateAlertText();
});
$('#mark-allread-btn').on('click', function() {
var btn = $(this);
socket.emit('api:topics.markAllRead', {} , function(success) {
if(success) {
btn.remove();
$('#topics-container').empty();
$('#category-no-topics').removeClass('hidden');
app.alertSuccess('All topics marked as read!');
} else {
app.alertError('There was an error marking topics read!');
}
});
});
function onTopicsLoaded(topics) {
var html = templates.prepare(templates['unread'].blocks['topics']).parse({ topics: topics }),
container = $('#topics-container');
$('#category-no-topics').remove();
container.append(html);
}
function loadMoreTopics() {
loadingMoreTopics = true;
socket.emit('api:topics.loadMoreUnreadTopics', {after:parseInt($('#topics-container').attr('data-next-start'), 10)}, function(data) {
if(data.topics && data.topics.length) {
onTopicsLoaded(data.topics);
$('#topics-container').attr('data-next-start', data.nextStart);
}
loadingMoreTopics = false;
});
}
$(window).off('scroll').on('scroll', function() {
var windowHeight = document.body.offsetHeight - $(window).height(),
half = windowHeight / 2;
if (document.body.scrollTop > half && !loadingMoreTopics) {
loadMoreTopics();
}
});
if($("body").height() <= $(window).height() && $('#topics-container').children().length)
$('#load-more-btn').show();
$('#load-more-btn').on('click', function() {
loadMoreTopics();
});
})();

@ -21,7 +21,7 @@
<div class="category row"> <div class="category row">
<div class="{topic_row_size}"> <div class="{topic_row_size}">
<ul id="topics-container"> <ul id="topics-container" data-next-start="{nextStart}">
<!-- BEGIN topics --> <!-- BEGIN topics -->
<a href="../../topic/{topics.slug}" id="tid-{topics.tid}"> <a href="../../topic/{topics.slug}" id="tid-{topics.tid}">
<li class="category-item {topics.deleted-class}"> <li class="category-item {topics.deleted-class}">
@ -48,7 +48,8 @@
</a> </a>
<!-- END topics --> <!-- END topics -->
</ul> </ul>
<button id="load-more-btn" class="btn hide">Load More</button>
</div> </div>
</div> </div>
<script type="text/javascript" src="{relative_path}/src/forum/recent.js"></script> <script type="text/javascript" src="{relative_path}/src/forum/unread.js"></script>

@ -179,33 +179,29 @@ var RDB = require('./redis.js'),
}); });
} }
Posts.reply = function(socket, tid, uid, content, images) { Posts.emitTooManyPostsAlert = function(socket) {
if(content) {
content = content.trim();
}
if (uid < 1) {
socket.emit('event:alert', { socket.emit('event:alert', {
title: 'Reply Unsuccessful', title: 'Too many posts!',
message: 'You don&apos;t seem to be logged in, so you cannot reply.', message: 'You can only post every '+ (config.post_delay / 1000) + ' seconds.',
type: 'error', type: 'error',
timeout: 2000 timeout: 2000
}); });
return; }
} else if (!content || content.length < Posts.minimumPostLength) {
Posts.emitContentTooShortAlert(socket); Posts.reply = function(tid, uid, content, images, callback) {
if(content) {
content = content.trim();
}
if (!content || content.length < Posts.minimumPostLength) {
callback(new Error('content-too-short'), null);
return; return;
} }
user.getUserField(uid, 'lastposttime', function(lastposttime) { user.getUserField(uid, 'lastposttime', function(lastposttime) {
if(Date.now() - lastposttime < config.post_delay) { if(Date.now() - lastposttime < config.post_delay) {
socket.emit('event:alert', { callback(new Error('too-many-posts'), null);
title: 'Too many posts!',
message: 'You can only post every '+ (config.post_delay / 1000) + ' seconds.',
type: 'error',
timeout: 2000
});
return; return;
} }
@ -221,18 +217,8 @@ var RDB = require('./redis.js'),
}); });
}); });
Posts.getTopicPostStats(socket);
// Send notifications to users who are following this topic
threadTools.notify_followers(tid, uid); threadTools.notify_followers(tid, uid);
socket.emit('event:alert', {
title: 'Reply Successful',
message: 'You have successfully replied. Click here to view your reply.',
type: 'notify',
timeout: 2000
});
postData.content = postTools.markdownToHTML(postData.content); postData.content = postTools.markdownToHTML(postData.content);
postData.post_rep = 0; postData.post_rep = 0;
postData.relativeTime = utils.relativeTime(postData.timestamp) postData.relativeTime = utils.relativeTime(postData.timestamp)
@ -251,14 +237,9 @@ var RDB = require('./redis.js'),
io.sockets.in('recent_posts').emit('event:new_post', socketData); io.sockets.in('recent_posts').emit('event:new_post', socketData);
}); });
callback(null, 'Reply successful');
} else { } else {
socket.emit('event:alert', { callback(new Error('reply-error'), null);
title: 'Reply Unsuccessful',
message: 'Your reply could not be posted at this time. Please try again later.',
type: 'notify',
timeout: 2000
});
} }
}); });
}); });

@ -115,7 +115,7 @@ var user = require('./../user.js'),
app.get('/api/unread', function(req, res) { app.get('/api/unread', function(req, res) {
var uid = (req.user) ? req.user.uid : 0; var uid = (req.user) ? req.user.uid : 0;
topics.getUnreadTopics(uid, 0, -1, function(data) { topics.getUnreadTopics(uid, 0, 19, function(data) {
res.json(data); res.json(data);
}); });
}); });

@ -148,6 +148,7 @@ marked.setOptions({
function sendUnreadTopics(topicIds) { function sendUnreadTopics(topicIds) {
Topics.getTopicsByTids(topicIds, uid, function(topicData) { Topics.getTopicsByTids(topicIds, uid, function(topicData) {
unreadTopics.topics = topicData; unreadTopics.topics = topicData;
unreadTopics.nextStart = start + tids.length;
callback(unreadTopics); callback(unreadTopics);
}); });
} }
@ -532,7 +533,7 @@ marked.setOptions({
}); });
} }
Topics.post = function(socket, uid, title, content, category_id, images) { Topics.post = function(uid, title, content, category_id, images, callback) {
if (!category_id) if (!category_id)
throw new Error('Attempted to post without a category_id'); throw new Error('Attempted to post without a category_id');
@ -542,33 +543,20 @@ marked.setOptions({
title = title.trim(); title = title.trim();
if (uid === 0) { if (uid === 0) {
socket.emit('event:alert', { callback(new Error('not-logged-in'), null);
title: 'Thank you for posting', return;
message: 'Since you are unregistered, your post is awaiting approval. Click here to register now.',
type: 'warning',
timeout: 7500,
clickfn: function() {
ajaxify.go('register');
}
});
return; // for now, until anon code is written.
} else if(!title || title.length < Topics.minimumTitleLength) { } else if(!title || title.length < Topics.minimumTitleLength) {
Topics.emitTitleTooShortAlert(socket); callback(new Error('title-too-short'), null);
return; return;
} else if (!content || content.length < posts.miminumPostLength) { } else if (!content || content.length < posts.miminumPostLength) {
posts.emitContentTooShortAlert(socket); callback(new Error('content-too-short'), null);
return; return;
} }
user.getUserField(uid, 'lastposttime', function(lastposttime) { user.getUserField(uid, 'lastposttime', function(lastposttime) {
if(Date.now() - lastposttime < config.post_delay) { if(Date.now() - lastposttime < config.post_delay) {
socket.emit('event:alert', { callback(new Error('too-many-posts'), null);
title: 'Too many posts!',
message: 'You can only post every '+ (config.post_delay / 1000) + ' seconds.',
type: 'error',
timeout: 2000
});
return; return;
} }
@ -604,23 +592,6 @@ marked.setOptions({
topicSearch.index(title, tid); topicSearch.index(title, tid);
RDB.set('topicslug:' + slug + ':tid', tid); RDB.set('topicslug:' + slug + ':tid', tid);
posts.create(uid, tid, content, images, function(postData) {
if (postData) {
RDB.lpush(schema.topics(tid).posts, postData.pid);
// Auto-subscribe the post creator to the newly created topic
threadTools.toggleFollow(tid, uid);
// Notify any users looking at the category that a new topic has arrived
Topics.getTopicForCategoryView(tid, uid, function(topicData) {
io.sockets.in('category_' + category_id).emit('event:new_topic', topicData);
io.sockets.in('recent_posts').emit('event:new_topic', topicData);
});
posts.getTopicPostStats(socket);
}
});
user.addTopicIdToUser(uid, tid); user.addTopicIdToUser(uid, tid);
// let everyone know that there is an unread topic in this category // let everyone know that there is an unread topic in this category
@ -636,11 +607,21 @@ marked.setOptions({
feed.updateCategory(category_id); feed.updateCategory(category_id);
socket.emit('event:alert', { posts.create(uid, tid, content, images, function(postData) {
title: 'Thank you for posting', if (postData) {
message: 'You have successfully posted. Click here to view your post.', RDB.lpush(schema.topics(tid).posts, postData.pid);
type: 'notify',
timeout: 2000 // Auto-subscribe the post creator to the newly created topic
threadTools.toggleFollow(tid, uid);
// Notify any users looking at the category that a new topic has arrived
Topics.getTopicForCategoryView(tid, uid, function(topicData) {
io.sockets.in('category_' + category_id).emit('event:new_topic', topicData);
io.sockets.in('recent_posts').emit('event:new_topic', topicData);
});
callback(null, postData);
}
}); });
}); });
}); });

@ -400,6 +400,7 @@ var express = require('express'),
} }
}); });
}); });
}); });
}(WebServer)); }(WebServer));

@ -304,7 +304,41 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
}); });
socket.on('api:topics.post', function(data) { socket.on('api:topics.post', function(data) {
topics.post(socket, uid, data.title, data.content, data.category_id, data.images);
topics.post(uid, data.title, data.content, data.category_id, data.images, function(err, result) {
if(err) {
if(err.message === 'not-logged-in') {
socket.emit('event:alert', {
title: 'Thank you for posting',
message: 'Since you are unregistered, your post is awaiting approval. Click here to register now.',
type: 'warning',
timeout: 7500,
clickfn: function() {
ajaxify.go('register');
}
});
} else if(err.message === 'title-too-short') {
topics.emitTitleTooShortAlert(socket);
} else if(err.message === 'content-too-short') {
posts.emitContentTooShortAlert(socket);
} else if (err.message === 'too-many-posts') {
posts.emitTooManyPostsAlert(socket);
}
return;
}
if(result) {
posts.getTopicPostStats(socket);
socket.emit('event:alert', {
title: 'Thank you for posting',
message: 'You have successfully posted. Click here to view your post.',
type: 'notify',
timeout: 2000
});
}
});
}); });
socket.on('api:topics.markAllRead', function(data, callback) { socket.on('api:topics.markAllRead', function(data, callback) {
@ -318,7 +352,47 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
}); });
socket.on('api:posts.reply', function(data) { socket.on('api:posts.reply', function(data) {
posts.reply(socket, data.topic_id, uid, data.content, data.images); if(uid < 1) {
socket.emit('event:alert', {
title: 'Reply Unsuccessful',
message: 'You don&apos;t seem to be logged in, so you cannot reply.',
type: 'error',
timeout: 2000
});
return;
}
posts.reply(data.topic_id, uid, data.content, data.images, function(err, result) {
if(err) {
if(err.message === 'content-too-short') {
posts.emitContentTooShortAlert(socket);
} else if(err.messages === 'too-many-posts') {
posts.emitTooManyPostsAlert(socket);
} else if(err.message === 'reply-error') {
socket.emit('event:alert', {
title: 'Reply Unsuccessful',
message: 'Your reply could not be posted at this time. Please try again later.',
type: 'notify',
timeout: 2000
});
}
return;
}
if(result) {
posts.getTopicPostStats(socket);
socket.emit('event:alert', {
title: 'Reply Successful',
message: 'You have successfully replied. Click here to view your reply.',
type: 'notify',
timeout: 2000
});
}
});
}); });
socket.on('api:user.active.get', function() { socket.on('api:user.active.get', function() {
@ -579,6 +653,16 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
}); });
}); });
socket.on('api:topics.loadMoreUnreadTopics', function(data, callback) {
var start = data.after,
end = start + 9;
console.log(start, end);
topics.getUnreadTopics(uid, start, end, function(unreadTopics) {
callback(unreadTopics);
});
});
socket.on('api:admin.topics.getMore', function(data) { socket.on('api:admin.topics.getMore', function(data) {
topics.getAllTopics(data.limit, data.after, function(topics) { topics.getAllTopics(data.limit, data.after, function(topics) {
socket.emit('api:admin.topics.getMore', JSON.stringify(topics)); socket.emit('api:admin.topics.getMore', JSON.stringify(topics));

Loading…
Cancel
Save