From 043aafd7b72c95ed505e3a830ec50f104a9e7c75 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Sun, 22 Sep 2013 20:40:10 -0400 Subject: [PATCH 01/16] closed #315 --- public/src/forum/footer.js | 12 ++++++++++-- src/routes/authentication.js | 13 ++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/public/src/forum/footer.js b/public/src/forum/footer.js index 254da9a2ce..876880f05f 100644 --- a/public/src/forum/footer.js +++ b/public/src/forum/footer.js @@ -26,7 +26,6 @@ fields: ['username', 'picture', 'userslug'] }); socket.on('api:updateHeader', function(data) { - jQuery('#search-button').on('click', function() { jQuery('#search-fields').removeClass('hide').show(); jQuery(this).hide(); @@ -67,7 +66,16 @@ '); rightMenu.append(userli); - var logoutli = $('
  • Log out
  • '); + var logoutli = $('
  • Log out
  • '); + logoutli.on('click', function() { + var csrf_token = $('#csrf_token').val(); + + $.post(RELATIVE_PATH + '/logout', { + _csrf: csrf_token + }, function() { + window.location = RELATIVE_PATH + '/'; + }); + }); rightMenu.append(logoutli); } } else { diff --git a/src/routes/authentication.js b/src/routes/authentication.js index f2b5212cc4..faa995b62d 100644 --- a/src/routes/authentication.js +++ b/src/routes/authentication.js @@ -90,19 +90,14 @@ } Auth.create_routes = function(app) { - - app.get('/logout', function(req, res) { + app.post('/logout', function(req, res) { if (req.user && req.user.uid > 0) { winston.info('[Auth] Session ' + req.sessionID + ' logout (uid: ' + req.user.uid + ')'); req.logout(); - app.build_header({ - req: req, - res: res - }, function(err, header) { - res.send(header + templates['logout'] + templates['footer']); - }); - } else res.redirect('/'); + } + + res.send(200) }); if (login_strategies.indexOf('twitter') !== -1) { From 7fdf83089d11e3437ba981b9911a883d692018c4 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 23 Sep 2013 12:50:27 -0400 Subject: [PATCH 02/16] linting --- src/webserver.js | 125 +++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/src/webserver.js b/src/webserver.js index 83bf304ad1..3e46fa3147 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -24,14 +24,14 @@ var express = require('express'), plugins = require('./plugins'), nconf = require('nconf'); -(function(app) { +(function (app) { var templates = null; /** * `options` object requires: req, res * accepts: metaTags */ - app.build_header = function(options, callback) { + app.build_header = function (options, callback) { var defaultMetaTags = [{ name: 'viewport', content: 'width=device-width, initial-scale=1.0' @@ -65,6 +65,7 @@ var express = require('express'), }; // Middlewares + app.use(express.compress()); app.use(express.favicon(path.join(__dirname, '../', 'public', 'favicon.ico'))); app.use(require('less-middleware')({ src: path.join(__dirname, '../', 'public'), @@ -74,7 +75,6 @@ var express = require('express'), app.use(express.bodyParser()); // Puts POST vars in request.body app.use(express.cookieParser()); // If you want to parse cookies (res.cookies) - app.use(express.compress()); app.use(express.session({ store: new RedisStore({ client: RDB, @@ -87,16 +87,16 @@ var express = require('express'), } })); app.use(express.csrf()); - app.use(function(req, res, next) { + app.use(function (req, res, next) { res.locals.csrf_token = req.session._csrf; next(); }); // Static Directories for NodeBB Plugins - app.configure(function() { + app.configure(function () { var tailMiddlewares = []; - plugins.ready(function() { + plugins.ready(function () { // Remove some middlewares until the router is gone // This is not recommended behaviour: http://stackoverflow.com/a/13691542/122353 // Also: https://www.exratione.com/2013/03/nodejs-abusing-express-3-to-enable-late-addition-of-middleware/ @@ -115,14 +115,14 @@ var express = require('express'), }); }); - module.exports.init = function() { + module.exports.init = function () { templates = global.templates; server.listen(nconf.get('PORT') || nconf.get('port')); } auth.initialize(app); - app.use(function(req, res, next) { + app.use(function (req, res, next) { nconf.set('https', req.secure); @@ -131,7 +131,7 @@ var express = require('express'), app.use(app.router); - app.use(function(req, res, next) { + app.use(function (req, res, next) { res.status(404); // respond with html page @@ -153,7 +153,7 @@ var express = require('express'), res.type('txt').send('Not found'); }); - app.use(function(err, req, res, next) { + app.use(function (err, req, res, next) { // we may use properties of the error object // here and next(err) appropriately, or if @@ -168,12 +168,12 @@ var express = require('express'), }); - app.create_route = function(url, tpl) { // to remove + app.create_route = function (url, tpl) { // to remove return ''; }; - app.namespace(nconf.get('relative_path'), function() { + app.namespace(nconf.get('relative_path'), function () { auth.create_routes(app); admin.create_routes(app); @@ -183,16 +183,16 @@ var express = require('express'), // Basic Routes (entirely client-side parsed, goal is to move the rest of the crap in this file into this one section) - (function() { + (function () { var routes = ['login', 'register', 'account', 'recent', 'unread', 'popular', 'active', '403', '404']; for (var i = 0, ii = routes.length; i < ii; i++) { - (function(route) { + (function (route) { - app.get('/' + route, function(req, res) { + app.get('/' + route, function (req, res) { if ((route === 'login' || route === 'register') && (req.user && req.user.uid > 0)) { - user.getUserField(req.user.uid, 'userslug', function(err, userslug) { + user.getUserField(req.user.uid, 'userslug', function (err, userslug) { res.redirect('/user/' + userslug); }); return; @@ -201,7 +201,7 @@ var express = require('express'), app.build_header({ req: req, res: res - }, function(err, header) { + }, function (err, header) { res.send(header + app.create_route(route) + templates['footer']); }); }); @@ -210,9 +210,9 @@ var express = require('express'), }()); - app.get('/', function(req, res) { + app.get('/', function (req, res) { async.parallel({ - "header": function(next) { + "header": function (next) { app.build_header({ req: req, res: res, @@ -231,17 +231,17 @@ var express = require('express'), }] }, next); }, - "categories": function(next) { - categories.getAllCategories(function(returnData) { - returnData.categories = returnData.categories.filter(function(category) { + "categories": function (next) { + categories.getAllCategories(function (returnData) { + returnData.categories = returnData.categories.filter(function (category) { if (category.disabled !== '1') return true; - else return false; + else return false; }); next(null, returnData); }, 0); } - }, function(err, data) { + }, function (err, data) { res.send( data.header + '\n\t' + @@ -252,14 +252,14 @@ var express = require('express'), }); - app.get('/topic/:topic_id/:slug?', function(req, res) { + app.get('/topic/:topic_id/:slug?', function (req, res) { var tid = req.params.topic_id; if (tid.match(/^\d+\.rss$/)) { tid = tid.slice(0, -4); var rssPath = path.join(__dirname, '../', 'feeds/topics', tid + '.rss'), - loadFeed = function() { - fs.readFile(rssPath, function(err, data) { + loadFeed = function () { + fs.readFile(rssPath, function (err, data) { if (err) res.type('text').send(404, "Unable to locate an rss feed at this location."); else res.type('xml').set('Content-Length', data.length).send(data); }); @@ -267,7 +267,7 @@ var express = require('express'), }; if (!fs.existsSync(rssPath)) { - feed.updateTopic(tid, function(err) { + feed.updateTopic(tid, function (err) { if (err) res.redirect('/404'); else loadFeed(); }); @@ -277,8 +277,8 @@ var express = require('express'), } async.waterfall([ - function(next) { - topics.getTopicWithPosts(tid, ((req.user) ? req.user.uid : 0), 0, -1, function(err, topicData) { + function (next) { + topics.getTopicWithPosts(tid, ((req.user) ? req.user.uid : 0), 0, -1, function (err, topicData) { if (topicData) { if (topicData.deleted === '1' && topicData.expose_tools === 0) return next(new Error('Topic deleted'), null); @@ -287,7 +287,7 @@ var express = require('express'), next(err, topicData); }); }, - function(topicData, next) { + function (topicData, next) { var lastMod = 0, timestamp; @@ -324,14 +324,14 @@ var express = require('express'), property: 'article:section', content: topicData.category_name }] - }, function(err, header) { + }, function (err, header) { next(err, { header: header, topics: topicData }); }); }, - ], function(err, data) { + ], function (err, data) { if (err) return res.redirect('404'); var topic_url = tid + (req.params.slug ? '/' + req.params.slug : ''); @@ -344,14 +344,14 @@ var express = require('express'), }); }); - app.get('/category/:category_id/:slug?', function(req, res) { + app.get('/category/:category_id/:slug?', function (req, res) { var cid = req.params.category_id; if (cid.match(/^\d+\.rss$/)) { cid = cid.slice(0, -4); var rssPath = path.join(__dirname, '../', 'feeds/categories', cid + '.rss'), - loadFeed = function() { - fs.readFile(rssPath, function(err, data) { + loadFeed = function () { + fs.readFile(rssPath, function (err, data) { if (err) res.type('text').send(404, "Unable to locate an rss feed at this location."); else res.type('xml').set('Content-Length', data.length).send(data); }); @@ -359,7 +359,7 @@ var express = require('express'), }; if (!fs.existsSync(rssPath)) { - feed.updateCategory(cid, function(err) { + feed.updateCategory(cid, function (err) { if (err) res.redirect('/404'); else loadFeed(); }); @@ -369,8 +369,8 @@ var express = require('express'), } async.waterfall([ - function(next) { - categories.getCategoryById(cid, 0, function(err, categoryData) { + function (next) { + categories.getCategoryById(cid, 0, function (err, categoryData) { if (categoryData) { if (categoryData.disabled === '1') @@ -379,7 +379,7 @@ var express = require('express'), next(err, categoryData); }); }, - function(categoryData, next) { + function (categoryData, next) { app.build_header({ req: req, res: res, @@ -393,14 +393,14 @@ var express = require('express'), property: "og:type", content: 'website' }] - }, function(err, header) { + }, function (err, header) { next(err, { header: header, categories: categoryData }); }); } - ], function(err, data) { + ], function (err, data) { if (err) return res.redirect('404'); var category_url = cid + (req.params.slug ? '/' + req.params.slug : ''); @@ -413,24 +413,24 @@ var express = require('express'), }); }); - app.get('/confirm/:code', function(req, res) { + app.get('/confirm/:code', function (req, res) { app.build_header({ req: req, res: res - }, function(err, header) { + }, function (err, header) { res.send(header + '' + templates['footer']); }); }); - app.get('/sitemap.xml', function(req, res) { + app.get('/sitemap.xml', function (req, res) { var sitemap = require('./sitemap.js'); - sitemap.render(function(xml) { + sitemap.render(function (xml) { res.type('xml').set('Content-Length', xml.length).send(xml); }); }); - app.get('/robots.txt', function(req, res) { + app.get('/robots.txt', function (req, res) { res.set('Content-Type', 'text/plain'); res.send("User-agent: *\n" + "Disallow: \n" + @@ -438,8 +438,8 @@ var express = require('express'), "Sitemap: " + nconf.get('url') + "sitemap.xml"); }); - app.get('/cid/:cid', function(req, res) { - categories.getCategoryData(req.params.cid, function(err, data) { + app.get('/cid/:cid', function (req, res) { + categories.getCategoryData(req.params.cid, function (err, data) { if (data) res.send(data); else @@ -447,8 +447,8 @@ var express = require('express'), }); }); - app.get('/tid/:tid', function(req, res) { - topics.getTopicData(req.params.tid, function(data) { + app.get('/tid/:tid', function (req, res) { + topics.getTopicData(req.params.tid, function (data) { if (data) res.send(data); else @@ -456,8 +456,8 @@ var express = require('express'), }); }); - app.get('/pid/:pid', function(req, res) { - posts.getPostData(req.params.pid, function(data) { + app.get('/pid/:pid', function (req, res) { + posts.getPostData(req.params.pid, function (data) { if (data) res.send(data); else @@ -465,13 +465,13 @@ var express = require('express'), }); }); - app.get('/outgoing', function(req, res) { + app.get('/outgoing', function (req, res) { if (!req.query.url) return res.redirect('/404'); app.build_header({ req: req, res: res - }, function(err, header) { + }, function (err, header) { res.send( header + '\n\t' + @@ -480,31 +480,31 @@ var express = require('express'), }); }); - app.get('/search', function(req, res) { + app.get('/search', function (req, res) { app.build_header({ req: req, res: res - }, function(err, header) { + }, function (err, header) { res.send(header + app.create_route("search", null, "search") + templates['footer']); }); }); - app.get('/search/:term', function(req, res) { + app.get('/search/:term', function (req, res) { app.build_header({ req: req, res: res - }, function(err, header) { + }, function (err, header) { res.send(header + app.create_route("search/" + req.params.term, null, "search") + templates['footer']); }); }); - app.get('/reindex', function(req, res) { - topics.reIndexAll(function(err) { + app.get('/reindex', function (req, res) { + topics.reIndexAll(function (err) { if (err) { return res.json(err); } - user.reIndexAll(function(err) { + user.reIndexAll(function (err) { if (err) { return res.json(err); } else { @@ -514,7 +514,6 @@ var express = require('express'), }); }); }); - }(WebServer)); From da2d014f0016974f997b65a6d0674199223e99d7 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Mon, 23 Sep 2013 12:55:21 -0400 Subject: [PATCH 03/16] added IRC link to wiki --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4e55deda6c..f1f90f2a98 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,12 @@ -Please support NodeBB development! Check out our IndieGoGo campaign and like, share, and follow us :) -[NodeBB Homepage](http://www.nodebb.org/ "NodeBB") # [Follow on Twitter](http://www.twitter.com/NodeBB/ "NodeBB Twitter") # [Like us on Facebook](http://www.facebook.com/NodeBB/ "NodeBB Facebook") # NodeBB **NodeBB** is a robust Node.js driven forum built on a redis database. It is powered by web sockets, and is compatible down to IE8. +* [NodeBB Homepage](http://www.nodebb.org/ "NodeBB") +* [Follow on Twitter](http://www.twitter.com/NodeBB/ "NodeBB Twitter") +* [Like us on Facebook](http://www.facebook.com/NodeBB/ "NodeBB Facebook") +* [Join us on IRC](https://kiwiirc.com/client/irc.freenode.net/nodebb) - #nodebb on Freenode + ![NodeBB Main Category Listing](http://i.imgur.com/ZBrHqLr.png) ![NodeBB Topic Page](http://i.imgur.com/YSBA6Vr.png) From 776b51fef7dac236175a3c6c3300b342905f862d Mon Sep 17 00:00:00 2001 From: Baris Usakli Date: Mon, 23 Sep 2013 13:43:15 -0400 Subject: [PATCH 04/16] closes #323 --- public/src/app.js | 2 +- public/src/forum/users.js | 35 +++++++++++++++++++++++------------ public/templates/users.tpl | 1 + src/plugins.js | 2 +- src/routes/user.js | 25 ++++++++++++++++++++++--- src/websockets.js | 24 +++++++++++++++--------- 6 files changed, 63 insertions(+), 26 deletions(-) diff --git a/public/src/app.js b/public/src/app.js index 00aaf7c47c..63a57bde7b 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -275,7 +275,7 @@ var socket, if (active) { jQuery('#main-nav li a').each(function() { var href = this.getAttribute('href'); - if (active == "sort-posts" || active == "sort-reputation" || active == "search" || active== "latest") + if (active == "sort-posts" || active == "sort-reputation" || active == "search" || active == "latest" || active == "online") active = 'users'; if (href && href.match(active)) { jQuery(this.parentNode).addClass('active'); diff --git a/public/src/forum/users.js b/public/src/forum/users.js index bf69cdad9f..37b73d3b34 100644 --- a/public/src/forum/users.js +++ b/public/src/forum/users.js @@ -74,7 +74,10 @@ }); - + socket.on('api:user.isOnline', function(data) { + $('#users-container').empty(); + startLoading('users:online', 0); + }); function onUsersLoaded(users) { var html = templates.prepare(templates['users'].blocks['users']).parse({ @@ -91,24 +94,32 @@ set = 'users:postcount'; } else if (active === 'sort-reputation') { set = 'users:reputation'; + } else if (active === 'online') { + set = 'users:online'; } if (set) { loadingMoreUsers = true; - socket.emit('api:users.loadMore', { - set: set, - after: $('#users-container').children().length - }, function(data) { - if (data.users.length) { - onUsersLoaded(data.users); - } else { - $('#load-more-users-btn').addClass('disabled'); - } - loadingMoreUsers = false; - }); + startLoading(set, $('#users-container').children().length); } } + function startLoading(set, after) { + socket.emit('api:users.loadMore', { + set: set, + after: after + }, function(data) { + if (data.users.length) { + onUsersLoaded(data.users); + $('#load-more-users-btn').removeClass('disabled'); + } else { + $('#load-more-users-btn').addClass('disabled'); + } + loadingMoreUsers = false; + }); + } + + $('#load-more-users-btn').on('click', loadMoreUsers); $(window).off('scroll').on('scroll', function() { diff --git a/public/templates/users.tpl b/public/templates/users.tpl index a6319080c1..ebc00cc62d 100644 --- a/public/templates/users.tpl +++ b/public/templates/users.tpl @@ -3,6 +3,7 @@
  • Latest Users
  • Top Posters
  • Most Reputation
  • +
  • Online
  • Search
  • diff --git a/src/plugins.js b/src/plugins.js index 1afdc3b211..c8e77de3f7 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -137,7 +137,7 @@ var fs = require('fs'), hookList = this.loadedHooks[hook]; if (hookList && Array.isArray(hookList)) { - if (global.env === 'development') winston.info('[plugins] Firing hook: \'' + hook + '\''); + //if (global.env === 'development') winston.info('[plugins] Firing hook: \'' + hook + '\''); var hookType = hook.split(':')[0]; switch (hookType) { case 'filter': diff --git a/src/routes/user.js b/src/routes/user.js index 78cd6da6c6..e6870823b8 100644 --- a/src/routes/user.js +++ b/src/routes/user.js @@ -25,7 +25,6 @@ var user = require('./../user.js'), }); } }); - }); app.get('/users', function(req, res) { @@ -64,6 +63,15 @@ var user = require('./../user.js'), }); }); + app.get('/users/online', function(req, res) { + app.build_header({ + req: req, + res: res + }, function(err, header) { + res.send(header + app.create_route("users/online", "users") + templates['footer']); + }); + }); + app.get('/users/search', function(req, res) { app.build_header({ req: req, @@ -136,7 +144,7 @@ var user = require('./../user.js'), app.post('/user/uploadpicture', function(req, res) { if (!req.user) return res.redirect('/403'); - + var uploadSize = meta.config.maximumProfileImageSize || 256; if (req.files.userPhoto.size > uploadSize * 1024) { @@ -342,7 +350,7 @@ var user = require('./../user.js'), return; } - + user.getUserFields(uid, ['username', 'userslug', 'showemail'], function(err, userData) { if (err) return next(err); @@ -436,6 +444,7 @@ var user = require('./../user.js'), app.get('/api/users/sort-posts', getUsersSortedByPosts); app.get('/api/users/sort-reputation', getUsersSortedByReputation); app.get('/api/users/latest', getUsersSortedByJoinDate); + app.get('/api/users/online', getOnlineUsers); app.get('/api/users/search', getUsersForSearch); @@ -469,6 +478,16 @@ var user = require('./../user.js'), }); } + function getOnlineUsers(req, res) { + user.getUsers('users:online', 0, 49, function(err, data) { + res.json({ + search_display: 'none', + loadmore_display: 'block', + users: data + }); + }); + } + function getUsersForSearch(req, res) { res.json({ search_display: 'block', diff --git a/src/websockets.js b/src/websockets.js index 38da997253..eec83d0693 100644 --- a/src/websockets.js +++ b/src/websockets.js @@ -23,6 +23,7 @@ var SocketIO = require('socket.io').listen(global.server, { client: RDB, ttl: 60 * 60 * 24 * 14 }), + nconf = require('nconf'), socketCookieParser = express.cookieParser(nconf.get('secret')), admin = { 'categories': require('./admin/categories.js'), @@ -53,14 +54,17 @@ var SocketIO = require('socket.io').listen(global.server, { userSockets[uid].push(socket); if (uid) { - socket.join('uid_' + uid); - io.sockets. in ('global').emit('api:user.isOnline', isUserOnline(uid)); - user.getUserField(uid, 'username', function(err, username) { - socket.emit('event:connect', { - status: 1, - username: username, - uid: uid + RDB.zadd('users:online', Date.now(), uid, function(err, data) { + socket.join('uid_' + uid); + io.sockets. in ('global').emit('api:user.isOnline', isUserOnline(uid)); + + user.getUserField(uid, 'username', function(err, username) { + socket.emit('event:connect', { + status: 1, + username: username, + uid: uid + }); }); }); } @@ -80,7 +84,9 @@ var SocketIO = require('socket.io').listen(global.server, { delete users[sessionID]; delete userSockets[uid]; if (uid) { - io.sockets. in ('global').emit('api:user.isOnline', isUserOnline(uid)); + RDB.zrem('users:online', uid, function(err, data) { + io.sockets. in ('global').emit('api:user.isOnline', isUserOnline(uid)); + }); } } @@ -100,7 +106,7 @@ var SocketIO = require('socket.io').listen(global.server, { socket.on('api:get_all_rooms', function(data) { socket.emit('api:get_all_rooms', io.sockets.manager.rooms); - }) + }); function updateRoomBrowsingText(roomName) { From b25c3d8b670b636256eb80e8f0878bc830d6fa1a Mon Sep 17 00:00:00 2001 From: Baris Usakli Date: Mon, 23 Sep 2013 14:40:31 -0400 Subject: [PATCH 05/16] closes #324 --- public/src/app.js | 8 ++++++-- public/src/forum/footer.js | 4 ++++ public/src/forum/search.js | 7 +++++++ public/src/forum/users.js | 8 +++++--- public/templates/header.tpl | 4 ++-- public/templates/search.tpl | 10 ++++++++++ src/webserver.js | 4 ++++ 7 files changed, 38 insertions(+), 7 deletions(-) diff --git a/public/src/app.js b/public/src/app.js index 63a57bde7b..f3201af211 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -286,6 +286,8 @@ var socket, $('span.timeago').timeago(); + + setTimeout(function() { window.scrollTo(0, 1); // rehide address bar on mobile after page load completes. }, 100); @@ -432,12 +434,14 @@ var socket, ajaxify.go("search/" + input.val(), null, "search"); input.val(''); return false; - }) + }); + + + }); showWelcomeMessage = location.href.indexOf('loggedin') !== -1; loadConfig(); - }()); \ No newline at end of file diff --git a/public/src/forum/footer.js b/public/src/forum/footer.js index 876880f05f..27a706d974 100644 --- a/public/src/forum/footer.js +++ b/public/src/forum/footer.js @@ -94,6 +94,10 @@ right_menu.appendChild(registerEl); right_menu.appendChild(loginEl); } + + $('#main-nav a,#right-menu a').on('click', function() { + $('.navbar-header button').click(); + }); }); // Notifications dropdown diff --git a/public/src/forum/search.js b/public/src/forum/search.js index 5044a9be76..f7238ef8c3 100644 --- a/public/src/forum/search.js +++ b/public/src/forum/search.js @@ -12,6 +12,13 @@ $('#search-form input').val(searchQuery); + + $('#mobile-search-form').off('submit').on('submit', function() { + var input = $(this).find('input'); + ajaxify.go("search/" + input.val(), null, "search"); + input.val(''); + return false; + }); }); })(); \ No newline at end of file diff --git a/public/src/forum/users.js b/public/src/forum/users.js index 37b73d3b34..ce2f4f7a41 100644 --- a/public/src/forum/users.js +++ b/public/src/forum/users.js @@ -75,8 +75,10 @@ }); socket.on('api:user.isOnline', function(data) { - $('#users-container').empty(); - startLoading('users:online', 0); + if(active == 'online') { + $('#users-container').empty(); + startLoading('users:online', 0); + } }); function onUsersLoaded(users) { @@ -99,12 +101,12 @@ } if (set) { - loadingMoreUsers = true; startLoading(set, $('#users-container').children().length); } } function startLoading(set, after) { + loadingMoreUsers = true; socket.emit('api:users.loadMore', { set: set, after: after diff --git a/public/templates/header.tpl b/public/templates/header.tpl index 0efb66394d..f7f6b41822 100644 --- a/public/templates/header.tpl +++ b/public/templates/header.tpl @@ -54,9 +54,9 @@
  • Users
  • - +
  • diff --git a/public/templates/search.tpl b/public/templates/search.tpl index 993f32c484..3aae132913 100644 --- a/public/templates/search.tpl +++ b/public/templates/search.tpl @@ -3,6 +3,16 @@
  • Search
  • + + +