diff --git a/.gitignore b/.gitignore index 49f144eb0a..b5bda3e26f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ npm-debug.log node_modules/ sftp-config.json config.json +public/src/nodebb.min.js public/config.json public/css/*.css public/themes/* @@ -15,4 +16,4 @@ public/themes/* *.sublime-project *.sublime-workspace plugins/* -.project \ No newline at end of file +.project 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) diff --git a/app.js b/app.js index 33c765a012..8b506dc02a 100644 --- a/app.js +++ b/app.js @@ -24,8 +24,11 @@ nconf.argv().env(); var fs = require('fs'), + async = require('async'), winston = require('winston'), pkg = require('./package.json'), + path = require('path'), + uglifyjs = require('uglify-js'), meta; // Runtime environment @@ -69,6 +72,61 @@ winston.info('Base Configuration OK.'); } + // Minify JS + var toMinify = [ + '/vendor/jquery/js/jquery.js', + '/vendor/jquery/js/jquery-ui-1.10.3.custom.min.js', + '/vendor/jquery/js/jquery.timeago.js', + '/vendor/bootstrap/js/bootstrap.min.js', + '/src/app.js', + '/vendor/requirejs/require.js', + '/vendor/bootbox/bootbox.min.js', + '/src/templates.js', + '/src/ajaxify.js', + '/src/jquery.form.js', + '/src/utils.js' + ], + minified, mtime; + toMinify = toMinify.map(function (jsPath) { + return path.join(__dirname + '/public', jsPath); + }); + async.parallel({ + mtime: function (next) { + async.map(toMinify, fs.stat, function (err, stats) { + async.reduce(stats, 0, function (memo, item, callback) { + mtime = +new Date(item.mtime); + callback(null, mtime > memo ? mtime : memo); + }, next); + }); + }, + minFile: function (next) { + var minFile = path.join(__dirname, 'public/src/nodebb.min.js'); + if (!fs.existsSync(minFile)) { + winston.warn('No minified client-side library found'); + return next(null, 0); + } + + fs.stat(minFile, function (err, stat) { + next(err, +new Date(stat.mtime)); + }); + } + }, function (err, results) { + if (results.minFile > results.mtime) { + winston.info('No changes to client-side libraries -- skipping minification'); + } else { + winston.info('Minifying client-side libraries'); + minified = uglifyjs.minify(toMinify); + fs.writeFile(path.join(__dirname, '/public/src', 'nodebb.min.js'), minified.code, function (err) { + if (!err) { + winston.info('Minified client-side libraries'); + } else { + winston.error('Problem minifying client-side libraries, exiting.'); + process.exit(); + } + }); + } + }); + meta.configs.init(function () { // Initial setup for Redis & Reds var reds = require('reds'), diff --git a/package.json b/package.json index 73644585ab..adfd01d6be 100644 --- a/package.json +++ b/package.json @@ -1,69 +1,64 @@ { - "name": "nodebb", - "license": "GPLv3 or later", - "description": "NodeBB Forum", - "version": "0.0.6", - "homepage": "http://www.nodebb.org", - "repository": { - "type": "git", - "url": "https://github.com/designcreateplay/NodeBB/" - }, - "main": "app.js", - "dependencies": { - "socket.io": "~0.9.16", - "redis": "0.8.3", - "express": "3.2.0", - "express-namespace": "0.1.1", - "emailjs": "0.3.4", - "cookie": "0.0.6", - "connect-redis": "1.4.5", - "passport": "0.1.17", - "passport-local": "0.1.6", - "passport-twitter": "0.1.5", - "passport-google-oauth": "0.1.5", - "passport-facebook": "0.1.5", - "less-middleware": "0.1.12", - "marked": "0.2.8", - "bcrypt": "0.7.5", - "async": "0.2.8", - "node-imagemagick": "0.1.8", - "gravatar": "1.0.6", - "nconf": "~0.6.7", - "sitemap": "~0.6.0", - "request": "~2.25.0", - "reds": "~0.2.4", - "winston": "~0.7.2", - "nodebb-plugin-mentions": "~0.1.0", - "nodebb-plugin-markdown": "~0.1.0", - "rss": "~0.2.0", - "prompt": "~0.2.11" - }, - "bugs": { - "url": "https://github.com/designcreateplay/NodeBB/issues" - }, - "engines": { - "node": ">=0.8" - }, - "contributors": [ - { - "name": "Andrew Rodrigues", - "email": "andrew@designcreateplay.com" - }, - { - "name": "Julian Lam", - "email": "julian@designcreateplay.com" - }, - { - "name": "Barış Soner Uşaklı", - "email": "baris@designcreateplay.com" - }, - { - "name": "Damian Bushong", - "url": "https://github.com/damianb" - }, - { - "name": "Matt Smith", - "url": "https://github.com/soimafreak" - } - ] + "name": "nodebb", + "license": "GPLv3 or later", + "description": "NodeBB Forum", + "version": "0.0.6", + "homepage": "http://www.nodebb.org", + "repository": { + "type": "git", + "url": "https://github.com/designcreateplay/NodeBB/" + }, + "main": "app.js", + "dependencies": { + "socket.io": "~0.9.16", + "redis": "0.8.3", + "express": "3.2.0", + "express-namespace": "0.1.1", + "emailjs": "0.3.4", + "cookie": "0.0.6", + "connect-redis": "1.4.5", + "passport": "0.1.17", + "passport-local": "0.1.6", + "passport-twitter": "0.1.5", + "passport-google-oauth": "0.1.5", + "passport-facebook": "0.1.5", + "less-middleware": "0.1.12", + "marked": "0.2.8", + "bcrypt": "0.7.5", + "async": "0.2.8", + "node-imagemagick": "0.1.8", + "gravatar": "1.0.6", + "nconf": "~0.6.7", + "sitemap": "~0.6.0", + "request": "~2.25.0", + "reds": "~0.2.4", + "winston": "~0.7.2", + "nodebb-plugin-mentions": "~0.1.0", + "nodebb-plugin-markdown": "~0.1.0", + "rss": "~0.2.0", + "prompt": "~0.2.11", + "uglify-js": "~2.4.0" + }, + "bugs": { + "url": "https://github.com/designcreateplay/NodeBB/issues" + }, + "engines": { + "node": ">=0.8" + }, + "contributors": [{ + "name": "Andrew Rodrigues", + "email": "andrew@designcreateplay.com" + }, { + "name": "Julian Lam", + "email": "julian@designcreateplay.com" + }, { + "name": "Barış Soner Uşaklı", + "email": "baris@designcreateplay.com" + }, { + "name": "Damian Bushong", + "url": "https://github.com/damianb" + }, { + "name": "Matt Smith", + "url": "https://github.com/soimafreak" + }] } diff --git a/public/src/app.js b/public/src/app.js index 00aaf7c47c..b7dd3a8e20 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'); @@ -286,6 +286,7 @@ var socket, $('span.timeago').timeago(); + setTimeout(function() { window.scrollTo(0, 1); // rehide address bar on mobile after page load completes. }, 100); @@ -432,12 +433,11 @@ 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 254da9a2ce..eb04220b2c 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 { @@ -86,6 +94,11 @@ right_menu.appendChild(registerEl); right_menu.appendChild(loginEl); } + + $('#main-nav a,#right-menu a').off('click').on('click', function() { + if($('.navbar .navbar-collapse').hasClass('in')) + $('.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/topic.js b/public/src/forum/topic.js index 8f960577bd..33c62b4e78 100644 --- a/public/src/forum/topic.js +++ b/public/src/forum/topic.js @@ -223,6 +223,15 @@ } }); + var bookmark = localStorage.getItem('topic:' + tid + ':bookmark'); + + if(bookmark) { + // need to find out why it doesnt work without setTimeout -baris + setTimeout(function() { + app.scrollToPost(parseInt(bookmark, 10)); + }, 300); + } + $('#post-container').on('click', '.deleted', function(ev) { $(this).toggleClass('deleted-expanded'); }); @@ -659,6 +668,7 @@ var scrollBottom = scrollTop + windowHeight; if (scrollTop < 50 && postcount > 1) { + localStorage.removeItem("topic:" + tid + ":bookmark"); postAuthorImage.src = (jQuery('.main-post .avatar img').attr('src')); mobileAuthorOverlay.innerHTML = 'Posted by ' + jQuery('.main-post').attr('data-username') + ', ' + jQuery('.main-post').find('.relativeTimeAgo').html(); pagination.innerHTML = '0 out of ' + postcount; @@ -666,7 +676,7 @@ } - var count = 0; + var count = 0, smallestNonNegative = 0; jQuery('.sub-posts').each(function() { count++; @@ -682,6 +692,11 @@ if (inView) { + if(elTop - scrollTop > smallestNonNegative) { + localStorage.setItem("topic:" + tid + ":bookmark", el.attr('data-pid')); + smallestNonNegative = Number.MAX_VALUE; + } + pagination.innerHTML = this.postnumber + ' out of ' + postcount; postAuthorImage.src = (jQuery(this).find('.profile-image-block img').attr('src')); mobileAuthorOverlay.innerHTML = 'Posted by ' + jQuery(this).attr('data-username') + ', ' + jQuery(this).find('.relativeTimeAgo').html(); diff --git a/public/src/forum/users.js b/public/src/forum/users.js index bf69cdad9f..a5d29adaa7 100644 --- a/public/src/forum/users.js +++ b/public/src/forum/users.js @@ -74,7 +74,12 @@ }); - + socket.on('api:user.isOnline', function(data) { + if(active == 'online' && !loadingMoreUsers) { + $('#users-container').empty(); + startLoading('users:online', 0); + } + }); function onUsersLoaded(users) { var html = templates.prepare(templates['users'].blocks['users']).parse({ @@ -91,24 +96,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) { + loadingMoreUsers = true; + 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/header.tpl b/public/templates/header.tpl index 0efb66394d..cbdd8e9680 100644 --- a/public/templates/header.tpl +++ b/public/templates/header.tpl @@ -8,27 +8,16 @@ - - - - - - - + - - - - - @@ -54,9 +43,9 @@
  • Users
  • - +
  • diff --git a/public/templates/search.tpl b/public/templates/search.tpl index 993f32c484..30e8995925 100644 --- a/public/templates/search.tpl +++ b/public/templates/search.tpl @@ -3,8 +3,18 @@
  • Search
  • + + +