mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-08-01 00:20:03 +02:00
closes #3039
This commit is contained in:
@@ -10,5 +10,12 @@
|
||||
"online-only": "Online only",
|
||||
"picture-only": "Picture only",
|
||||
"invite": "Invite",
|
||||
"invitation-email-sent": "An invitation email has been sent to %1"
|
||||
"invitation-email-sent": "An invitation email has been sent to %1",
|
||||
"user_list": "User List",
|
||||
"recent_topics": "Recent Topics",
|
||||
"popular_topics": "Popular Topics",
|
||||
"unread_topics": "Unread Topics",
|
||||
"categories": "Categories",
|
||||
"tags": "Tags",
|
||||
"map": "Map"
|
||||
}
|
||||
@@ -102,6 +102,10 @@
|
||||
border-color: #949FB1;
|
||||
background-color: #A8B3C5;
|
||||
}
|
||||
&.unread {
|
||||
border-color: #949FB1;
|
||||
background-color: #9FB194;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ define('admin/general/dashboard', ['semver'], function(semver) {
|
||||
});
|
||||
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
|
||||
|
||||
setupRealtimeButton();
|
||||
setupGraphs();
|
||||
initiateDashboard();
|
||||
@@ -237,13 +237,13 @@ define('admin/general/dashboard', ['semver'], function(semver) {
|
||||
value: 1,
|
||||
color: "#949FB1",
|
||||
highlight: "#A8B3C5",
|
||||
label: "Recent/Unread"
|
||||
label: "Recent"
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
color: "#4D5360",
|
||||
color: "#9FB194",
|
||||
highlight: "#A8B3C5",
|
||||
label: "Other"
|
||||
label: "Unread"
|
||||
}
|
||||
], {
|
||||
responsive: true
|
||||
@@ -317,7 +317,8 @@ define('admin/general/dashboard', ['semver'], function(semver) {
|
||||
graphs.presence.segments[1].value = users.topics;
|
||||
graphs.presence.segments[2].value = users.category;
|
||||
graphs.presence.segments[3].value = users.recent;
|
||||
graphs.presence.segments[4].value = users.other;
|
||||
graphs.presence.segments[4].value = users.unread;
|
||||
|
||||
|
||||
graphs.presence.update();
|
||||
}
|
||||
|
||||
@@ -100,9 +100,14 @@ app.cacheBuster = null;
|
||||
case 'category':
|
||||
room = 'category_' + url_parts[1];
|
||||
break;
|
||||
case 'recent': // intentional fall-through
|
||||
case 'recent':
|
||||
room = 'recent_topics';
|
||||
break;
|
||||
case 'unread':
|
||||
room = 'recent_posts';
|
||||
room = 'unread_topics';
|
||||
break;
|
||||
case 'popular':
|
||||
room = 'popular_topics';
|
||||
break;
|
||||
case 'admin':
|
||||
room = 'admin';
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
/* globals define, app, socket*/
|
||||
|
||||
define('forum/popular', ['forum/recent'], function(recent) {
|
||||
define('forum/popular', function() {
|
||||
var Popular = {};
|
||||
|
||||
Popular.init = function() {
|
||||
app.enterRoom('recent_posts');
|
||||
app.enterRoom('popular_topics');
|
||||
|
||||
selectActivePill();
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ define('forum/recent', ['forum/infinitescroll', 'components'], function(infinite
|
||||
});
|
||||
|
||||
Recent.init = function() {
|
||||
app.enterRoom('recent_posts');
|
||||
app.enterRoom('recent_topics');
|
||||
|
||||
Recent.watchForNewPosts();
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ define('forum/topic/browsing', ['translator'], function(translator) {
|
||||
addUserIcon(data.users[i]);
|
||||
}
|
||||
|
||||
updateUserCount(data.total);
|
||||
updateUserCount(data.hidden);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ define('forum/unread', ['forum/recent', 'topicSelect', 'forum/infinitescroll', '
|
||||
});
|
||||
|
||||
Unread.init = function() {
|
||||
app.enterRoom('recent_posts');
|
||||
app.enterRoom('unread_topics');
|
||||
|
||||
$('#new-topics-alert').on('click', function() {
|
||||
$(this).addClass('hide');
|
||||
|
||||
@@ -8,7 +8,7 @@ define('forum/users', ['translator'], function(translator) {
|
||||
var loadingMoreUsers = false;
|
||||
|
||||
Users.init = function() {
|
||||
|
||||
app.enterRoom('user_list');
|
||||
var active = getActiveSection();
|
||||
|
||||
$('.nav-pills li').removeClass('active');
|
||||
|
||||
@@ -3,8 +3,12 @@
|
||||
var usersController = {};
|
||||
|
||||
var async = require('async'),
|
||||
validator = require('validator'),
|
||||
|
||||
user = require('../user'),
|
||||
meta = require('../meta'),
|
||||
categories = require('../categories'),
|
||||
topics = require('../topics'),
|
||||
pagination = require('../pagination'),
|
||||
plugins = require('../plugins'),
|
||||
db = require('../database'),
|
||||
@@ -117,6 +121,73 @@ usersController.getUsersForSearch = function(req, res, next) {
|
||||
});
|
||||
};
|
||||
|
||||
usersController.getMap = function(req, res, next) {
|
||||
var socketIO = require('../socket.io');
|
||||
var rooms = require('../socket.io/rooms');
|
||||
|
||||
var roomNames = ['user_list', 'categories', 'unread_topics', 'recent_topics', 'popular_topics', 'tags'];
|
||||
var links = {
|
||||
user_list: '/users',
|
||||
categories: '/categories',
|
||||
unread_topics: '/unread',
|
||||
recent_topics: '/recent',
|
||||
popular_topics: '/popular',
|
||||
tags: '/tags'
|
||||
};
|
||||
|
||||
var keys = Object.keys(rooms.roomClients());
|
||||
|
||||
keys = keys.filter(function(key) {
|
||||
return key.startsWith('topic_') || key.startsWith('category_');
|
||||
});
|
||||
|
||||
roomNames = roomNames.concat(keys);
|
||||
|
||||
async.map(roomNames, function(roomName, next) {
|
||||
socketIO.getUsersInRoom(0, roomName, 0, 39, function(err, data) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (roomName.startsWith('category_')) {
|
||||
var cid = roomName.split('_')[1];
|
||||
categories.getCategoryFields(cid, ['slug', 'name'], function(err, categoryData) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
data.room = validator.escape(categoryData.name);
|
||||
data.link = '/category/' + categoryData.slug;
|
||||
next(null, data);
|
||||
});
|
||||
} else if (roomName.startsWith('topic_')) {
|
||||
var tid = roomName.split('_')[1];
|
||||
topics.getTopicFields(tid, ['slug', 'title'], function(err, topicData) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
data.room = validator.escape(topicData.title);
|
||||
data.link = '/topic/' + topicData.slug;
|
||||
next(null, data);
|
||||
});
|
||||
} else {
|
||||
next(null, data);
|
||||
}
|
||||
});
|
||||
}, function(err, data) {
|
||||
data.sort(function(a, b) {
|
||||
return b.total - a.total;
|
||||
});
|
||||
|
||||
data.forEach(function(room) {
|
||||
if (!room.link) {
|
||||
room.link = links[room.room];
|
||||
}
|
||||
});
|
||||
|
||||
res.render('usersMap', {names: roomNames, rooms: data});
|
||||
});
|
||||
};
|
||||
|
||||
function render(req, res, data, next) {
|
||||
plugins.fireHook('filter:users.build', {req: req, res: res, templateData: data}, function(err, data) {
|
||||
if (err) {
|
||||
|
||||
@@ -84,8 +84,10 @@ function userRoutes(app, middleware, controllers) {
|
||||
setupPageRoute(app, '/users/sort-reputation', middleware, middlewares, controllers.users.getUsersSortedByReputation);
|
||||
setupPageRoute(app, '/users/latest', middleware, middlewares, controllers.users.getUsersSortedByJoinDate);
|
||||
setupPageRoute(app, '/users/search', middleware, middlewares, controllers.users.getUsersForSearch);
|
||||
setupPageRoute(app, '/users/map', middleware, middlewares, controllers.users.getMap);
|
||||
}
|
||||
|
||||
|
||||
function groupRoutes(app, middleware, controllers) {
|
||||
var middlewares = [middleware.checkGlobalPrivacySettings, middleware.exposeGroupName];
|
||||
|
||||
|
||||
@@ -260,14 +260,17 @@ Sockets.isUsersOnline = function(uids, callback) {
|
||||
callback(null, uids.map(Sockets.isUserOnline));
|
||||
};
|
||||
|
||||
Sockets.getUsersInRoom = function (uid, roomName, callback) {
|
||||
Sockets.getUsersInRoom = function (uid, roomName, start, stop, callback) {
|
||||
if (!roomName) {
|
||||
return;
|
||||
}
|
||||
|
||||
var uids = Sockets.getUidsInRoom(roomName);
|
||||
var total = uids.length;
|
||||
uids = uids.slice(0, 9);
|
||||
if (stop !== -1) {
|
||||
uids = uids.slice(start, stop);
|
||||
}
|
||||
|
||||
if (uid && uids.indexOf(uid.toString()) === -1) {
|
||||
uids = [uid].concat(uids);
|
||||
}
|
||||
@@ -287,7 +290,8 @@ Sockets.getUsersInRoom = function (uid, roomName, callback) {
|
||||
callback(null, {
|
||||
users: users,
|
||||
room: roomName,
|
||||
total: Math.max(0, total - uids.length)
|
||||
total: total,
|
||||
hidden: Math.max(0, total - uids.length)
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -94,10 +94,11 @@ SocketMeta.rooms.getAll = function(socket, data, callback) {
|
||||
socketCount: websockets.getSocketCount(),
|
||||
users: {
|
||||
categories: roomClients.categories ? roomClients.categories.length : 0,
|
||||
recent: roomClients.recent_posts ? roomClients.recent_posts.length : 0,
|
||||
recent: roomClients.recent_topics ? roomClients.recent_topics.length : 0,
|
||||
unread: roomClients.unread_topics ? roomClients.unread_topics.length: 0,
|
||||
popular: roomClients.popular_topics ? roomClients.popular_topics.length: 0,
|
||||
topics: 0,
|
||||
category: 0,
|
||||
other: 0
|
||||
category: 0
|
||||
},
|
||||
topics: {}
|
||||
};
|
||||
@@ -124,14 +125,6 @@ SocketMeta.rooms.getAll = function(socket, data, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
for (var i in socketData.users) {
|
||||
if (socketData.users.hasOwnProperty(i)) {
|
||||
socketData.users.other -= socketData.users[i];
|
||||
}
|
||||
}
|
||||
|
||||
socketData.users.other += roomClients['online_users'].length;
|
||||
|
||||
var scoreKeys = Object.keys(scores),
|
||||
mostActive = scoreKeys.sort();
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ SocketTopics.enter = function(socket, tid, callback) {
|
||||
SocketTopics.markAsRead(socket, [tid], next);
|
||||
},
|
||||
users: function(next) {
|
||||
websockets.getUsersInRoom(socket.uid, 'topic_' + tid, next);
|
||||
websockets.getUsersInRoom(socket.uid, 'topic_' + tid, 0, 9, next);
|
||||
}
|
||||
}, function(err, result) {
|
||||
callback(err, result ? result.users : null);
|
||||
|
||||
@@ -128,7 +128,8 @@
|
||||
<li><div class="on-categories"></div><span>On categories list</span></li>
|
||||
<li><div class="reading-posts"></div><span>Reading posts</span></li>
|
||||
<li><div class="browsing-topics"></div><span>Browsing topics</span></li>
|
||||
<li><div class="recent"></div><span>Recent / Unread</span></li>
|
||||
<li><div class="recent"></div><span>Recent</span></li>
|
||||
<li><div class="unread"></div><span>Unread</span></li>
|
||||
</ul>
|
||||
<canvas id="analytics-presence"></canvas>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user