ability for users to now follow/subscribe to threads

v1.18.x
Julian Lam 12 years ago
parent 7e55e7b3d2
commit 882b9a917f

@ -155,6 +155,46 @@
if (postEls[x].getAttribute('data-deleted') === '1') toggle_post_delete_state(postEls[x].getAttribute('data-pid'));
postEls[x].removeAttribute('data-deleted');
}
// Follow Thread State
var followEl = $('.main-post .follow'),
set_follow_state = function(state, quiet) {
if (state && !followEl.hasClass('btn-success')) {
followEl.addClass('btn-success');
followEl[0].title = 'You are currently receiving updates to this topic';
if (!quiet) {
app.alert({
alert_id: 'topic_follow',
timeout: 2500,
title: 'Following Topic',
message: 'You will now be receiving notifications when somebody posts to this topic.',
type: 'success'
});
}
} else if (!state && followEl.hasClass('btn-success')) {
followEl.removeClass('btn-success');
followEl[0].title = 'Be notified of new replies in this topic';
if (!quiet) {
app.alert({
alert_id: 'topic_follow',
timeout: 2500,
title: 'Not Following Topic',
message: 'You will no longer receive notifications from this topic.',
type: 'success'
});
}
}
};
socket.on('api:topic.followCheck', function(state) {
set_follow_state(state, true);
});
socket.on('api:topic.follow', function(data) {
set_follow_state(data.follow);
});
socket.emit('api:topic.followCheck', tid);
followEl[0].addEventListener('click', function() {
socket.emit('api:topic.follow', tid);
}, false);
});
@ -589,21 +629,46 @@
}
function toggle_post_delete_state(pid) {
var postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]'));
var postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]'));
if (postEl[0]) {
quoteEl = $(postEl[0].querySelector('.quote')),
favEl = $(postEl[0].querySelector('.favourite')),
replyEl = $(postEl[0].querySelector('.post_reply'));
if (!postEl.hasClass('deleted')) {
quoteEl.addClass('none');
favEl.addClass('none');
replyEl.addClass('none');
} else {
socket.once('api:post.privileges', function(privileges) {
if (privileges.editable) {
if (!postEl.hasClass('deleted')) {
toggle_post_tools(pid, false);
} else {
toggle_post_tools(pid, true);
}
}
if (privileges.view_deleted) {
postEl.toggleClass('deleted');
} else {
postEl.toggleClass('none');
}
});
socket.emit('api:post.privileges', pid);
}
}
function toggle_post_tools(pid, state) {
var postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')),
quoteEl = $(postEl[0].querySelector('.quote')),
favEl = $(postEl[0].querySelector('.favourite')),
replyEl = $(postEl[0].querySelector('.post_reply'));
if (state) {
quoteEl.removeClass('none');
favEl.removeClass('none');
replyEl.removeClass('none');
} else {
quoteEl.addClass('none');
favEl.addClass('none');
replyEl.addClass('none');
}
postEl.toggleClass('deleted');
}
})();

@ -31,6 +31,7 @@
<div class="topic-buttons pull-left">
<a href="/users/{main_posts.username}" class="username-field btn hidden-phone">{main_posts.username}</a>
<a target="_blank" class="btn hidden-phone" href="../{topic_id}.rss"><i class="icon-rss-sign"></i></a>
<button class="btn follow" type="button"><i class="icon-eye-open"></i></button>
<button id="ids_{main_posts.pid}_{main_posts.uid}" class="btn edit {main_posts.display_moderator_tools}" type="button"><i class="icon-pencil"></i></button>
<button id="ids_{main_posts.pid}_{main_posts.uid}" class="btn delete {main_posts.display_moderator_tools}" type="button"><i class="icon-trash"></i></button>
<button id="quote_{main_posts.pid}_{main_posts.uid}" class="btn quote" type="button"><i class="icon-quote-left"></i></button>

@ -1,5 +1,6 @@
var RDB = require('./redis.js'),
posts = require('./posts.js'),
topics = require('./topics'),
threadTools = require('./threadTools.js'),
user = require('./user.js'),
async = require('async'),

@ -199,6 +199,9 @@ marked.setOptions({
timeout: 2000
});
// Send notifications to users who are following this topic
threadTools.notify_followers(tid, uid);
user.getUserFields(uid, ['username','reputation','picture','signature'], function(data) {
var timestamp = new Date().getTime();

@ -2,8 +2,8 @@ var RDB = require('./redis.js'),
topics = require('./topics.js'),
categories = require('./categories.js'),
user = require('./user.js'),
async = require('async');
async = require('async'),
notifications = require('./notifications.js');
(function(ThreadTools) {
@ -160,4 +160,63 @@ var RDB = require('./redis.js'),
});
}
ThreadTools.isFollowing = function(tid, current_user, callback) {
RDB.sismember('tid:' + tid + ':followers', current_user, function(err, following) {
callback(following);
});
}
ThreadTools.toggleFollow = function(tid, current_user, callback) {
ThreadTools.isFollowing(tid, current_user, function(following) {
if (!following) {
RDB.sadd('tid:' + tid + ':followers', current_user, function(err, success) {
if (!err) {
callback({
status: 'ok',
follow: true
});
} else callback({ status: 'error' });
});
} else {
RDB.srem('tid:' + tid + ':followers', current_user, function(err, success) {
if (!err) {
callback({
status: 'ok',
follow: false
});
} else callback({ status: 'error' });
});
}
});
}
ThreadTools.get_followers = function(tid, callback) {
RDB.smembers('tid:' + tid + ':followers', function(err, followers) {
callback(err, followers);
});
}
ThreadTools.notify_followers = function(tid, exceptUid) {
async.parallel([
function(next) {
topics.get_topic(tid, 0, function(threadData) {
// console.log(threadData);
notifications.create(threadData.teaser_username + ' has posted a reply to: "' + threadData.title + '"', null, '/topic/' + tid, 'topic:' + tid, function(nid) {
next(null, nid);
});
});
},
function(next) {
ThreadTools.get_followers(tid, function(err, followers) {
if (followers.indexOf(exceptUid) !== -1) followers.splice(followers.indexOf(exceptUid), 1);
next(null, followers);
});
}
], function(err, results) {
if (!err) {
notifications.push(results[0], results[1]);
}
});
}
}(exports));

@ -264,9 +264,9 @@ var express = require('express'),
app.get('/api/:method/:id*', api_method);
app.get('/test', function(req, res) {
meta.config.get(function(config) {
res.send(JSON.stringify(config, null, 4));
});
var ThreadTools = require('./threadTools.js');
ThreadTools.notify_followers(3);
res.send();
});

@ -364,6 +364,24 @@ var SocketIO = require('socket.io').listen(global.server, { log:false }),
})
})
});
socket.on('api:post.privileges', function(pid) {
postTools.privileges(pid, uid, function(privileges) {
socket.emit('api:post.privileges', privileges);
});
});
socket.on('api:topic.followCheck', function(tid) {
threadTools.isFollowing(tid, uid, function(following) {
socket.emit('api:topic.followCheck', following);
});
});
socket.on('api:topic.follow', function(tid) {
threadTools.toggleFollow(tid, uid, function(follow) {
if (follow.status === 'ok') socket.emit('api:topic.follow', follow);
});
});
});
}(SocketIO));

Loading…
Cancel
Save