diff --git a/public/css/style.less b/public/css/style.less
index 5d406dd732..5cb9d0b0ff 100644
--- a/public/css/style.less
+++ b/public/css/style.less
@@ -722,4 +722,15 @@ body .navbar .nodebb-inline-block {
max-width:200px;
max-height:60px;
}
+}
+
+.username-field {
+ .icon-circle {
+ font-size: 12px;
+ color: green;
+ }
+ .icon-circle-blank {
+ font-size: 12px;
+ color: red;
+ }
}
\ No newline at end of file
diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js
index abd7405c9f..19a5fd123f 100644
--- a/public/src/ajaxify.js
+++ b/public/src/ajaxify.js
@@ -56,6 +56,8 @@ var ajaxify = {};
callback();
}
+ app.process_page();
+
jQuery('#content, #footer').fadeIn(200);
}, url, template);
diff --git a/public/src/app.js b/public/src/app.js
index 6f77bb615a..7332acd59e 100644
--- a/public/src/app.js
+++ b/public/src/app.js
@@ -278,6 +278,35 @@ var socket,
app.current_room = room;
};
+ app.process_page = function() {
+
+ function populate_online_users() {
+ var uids = [];
+
+ jQuery('.post-row').each(function() {
+ uids.push(this.getAttribute('data-uid'));
+ });
+
+ socket.emit('api:user.get_online_users', uids);
+ }
+
+
+ populate_online_users();
+
+ }
+
+ socket.on('api:user.get_online_users', function(users) {
+ jQuery('.username-field').each(function() {
+ var uid = jQuery(this).parents('li').attr('data-uid');
+
+ if (uid && jQuery.inArray(uid, users) !== -1) {
+ jQuery(this).prepend('');
+ } else {
+ jQuery(this).prepend('');
+ }
+ });
+ });
+
jQuery('document').ready(function() {
app.enter_room('global');
diff --git a/public/templates/topic.tpl b/public/templates/topic.tpl
index c4912420e0..cef7b2a962 100644
--- a/public/templates/topic.tpl
+++ b/public/templates/topic.tpl
@@ -12,7 +12,7 @@
-
+
@@ -37,7 +37,7 @@
- posted {main_posts.relativeTime} ago by {main_posts.username}
+ posted {main_posts.relativeTime} ago by {main_posts.username}
@@ -52,7 +52,7 @@
-
+
@@ -272,6 +272,7 @@
}
});
+
$('.post-container').delegate('.edit', 'click', function(e) {
var pid = ($(this).attr('id') || $(this.parentNode).attr('id')).split('_')[1];
app.open_post_window('edit', "{topic_id}", "{topic_name}", pid);
@@ -297,6 +298,7 @@
'event:topic_moved', 'event:post_edited', 'event:post_deleted', 'event:post_restored',
'api:posts.favourite'
]);
+
socket.on('api:get_users_in_room', function(users) {
var anonymous = users.anonymous,
usernames = users.usernames,
diff --git a/src/redis.js b/src/redis.js
index 77382029cf..e03de19fb7 100644
--- a/src/redis.js
+++ b/src/redis.js
@@ -3,7 +3,8 @@
ERROR_LOGS = true,
redis = require('redis'),
- config = require('../config.js');
+ config = require('../config.js'),
+ utils = require('./utils.js');
RedisDB.exports = redis.createClient(config.redis.port, config.redis.host, config.redis.options);
@@ -22,4 +23,18 @@
}
}
+
+ /*
+ * A possibly more efficient way of doing multiple sismember calls
+ */
+ RedisDB.exports.sismembers = function(key, needles, callback) {
+ var tempkey = key + ':temp:' + utils.generateUUID();
+ RedisDB.exports.sadd(tempkey, needles, function() {
+ RedisDB.exports.sinter(key, tempkey, function(err, data) {
+ RedisDB.exports.del(tempkey);
+ callback(err, data);
+ });
+ });
+ };
+
}(module));
\ No newline at end of file
diff --git a/src/topics.js b/src/topics.js
index 75618dc453..f5f9a3dd5f 100644
--- a/src/topics.js
+++ b/src/topics.js
@@ -72,6 +72,15 @@ marked.setOptions({
callback(false);
return;
}
+ if (tids.length == 0) {
+ callback({
+ 'category_name' : category_id ? category_name : 'Recent',
+ 'show_topic_button' : category_id ? 'show' : 'hidden',
+ 'category_id': category_id || 0,
+ 'topics': topics
+ });
+ }
+
active_usernames = replies[1];
var topics = [];
diff --git a/src/user.js b/src/user.js
index 9f9faec16c..c57ed091c9 100644
--- a/src/user.js
+++ b/src/user.js
@@ -660,7 +660,22 @@ var config = require('../config.js'),
}
});
}
- }
+ };
+
+ User.get_online_users = function(socket, uids) {
+ RDB.sismembers('users:online', uids, function(err, data) {
+ socket.emit('api:user.get_online_users', data);
+ });
+ };
+
+ User.go_online = function(uid) {
+ RDB.sadd('users:online', uid);
+ };
+
+ User.go_offline = function(uid) {
+ RDB.srem('users:online', uid);
+ };
+
User.active = {
get_record : function(socket) {
diff --git a/src/websockets.js b/src/websockets.js
index 3d10d05718..87ae6e68b1 100644
--- a/src/websockets.js
+++ b/src/websockets.js
@@ -48,6 +48,7 @@ var SocketIO = require('socket.io').listen(global.server,{log:false}),
var hs = socket.handshake;
var uid = users[hs.sessionID];
+ user.go_online(uid);
/*process.on('uncaughtException', function(err) {
@@ -59,6 +60,7 @@ var SocketIO = require('socket.io').listen(global.server,{log:false}),
socket.emit('event:connect', {status: 1});
socket.on('disconnect', function() {
+ user.go_offline(uid);
delete users[hs.sessionID];
});
@@ -154,6 +156,10 @@ var SocketIO = require('socket.io').listen(global.server,{log:false}),
user.reset.commit(socket, data.code, data.password);
});
+ socket.on('api:user.get_online_users', function(data) {
+ user.get_online_users(socket, data);
+ });
+
socket.on('api:topics.post', function(data) {
topics.post(socket, uid, data.title, data.content, data.category_id);
});