Merge remote-tracking branch 'origin/master' into issue-1249

v1.18.x
Julian Lam 11 years ago
commit 7c08831aaf

@ -79,7 +79,7 @@
} }
winston.info('test_database flushed'); winston.info('test_database flushed');
/*
meta.configs.init(function () { meta.configs.init(function () {
nconf.set('url', nconf.get('base_url') + (nconf.get('use_port') ? ':' + nconf.get('port') : '') + nconf.get('relative_path')); nconf.set('url', nconf.get('base_url') + (nconf.get('use_port') ? ':' + nconf.get('port') : '') + nconf.get('relative_path'));
nconf.set('base_templates_path', path.join(nconf.get('themes_path'), 'nodebb-theme-vanilla/templates')); nconf.set('base_templates_path', path.join(nconf.get('themes_path'), 'nodebb-theme-vanilla/templates'));
@ -90,8 +90,7 @@
sockets.init(webserver.server); sockets.init(webserver.server);
done(); done();
});*/ });
done();
}); });
}); });
}); });

@ -12,7 +12,7 @@
"scripts": { "scripts": {
"start": "./nodebb start", "start": "./nodebb start",
"stop": "./nodebb stop", "stop": "./nodebb stop",
"test": "mocha ./tests/database.js -t 1000" "test": "mocha ./tests -t 1000"
}, },
"dependencies": { "dependencies": {
"express": "3.2.0", "express": "3.2.0",

@ -37,7 +37,7 @@
"content-too-short" : "Please enter a longer post. At least %1 characters.", "content-too-short" : "Please enter a longer post. At least %1 characters.",
"title-too-short" : "Please enter a longer title. At least %1 characters.", "title-too-short" : "Please enter a longer title. At least %1 characters.",
"title-too-long" : "Please enter a shorter title. Titles can't be longer than %1 characters.", "title-too-long" : "Please enter a shorter title. Titles can't be longer than %1 characters.",
"too-many-posts" : "You can only post every %1 seconds.'", "too-many-posts" : "You can only post every %1 seconds.",
"file-too-big" : "Maximum allowed file size is %1 kbs", "file-too-big" : "Maximum allowed file size is %1 kbs",
"cant-vote-self-post": "You cannot vote for your own post", "cant-vote-self-post": "You cannot vote for your own post",

@ -9,5 +9,13 @@
"continue_to": "Continue to", "continue_to": "Continue to",
"return_to": "Return to ", "return_to": "Return to ",
"new_notification": "New Notification", "new_notification": "New Notification",
"you_have_unread_notifications": "You have unread notifications." "you_have_unread_notifications": "You have unread notifications.",
"user_made_post": "<strong>%1</strong> made a new post",
"new_message_from": "New message from <strong>%1</strong>",
"upvoted_your_post": "<strong>%1</strong> has upvoted your post.",
"favourited_your_post": "<strong>%1</strong> has favourited your post.",
"user_flagged_post": "<strong>%1</strong> flagged a post.",
"user_posted_to" : "<strong>%1</strong> has posted a reply to: <strong>%2</strong>"
} }

@ -1,3 +1,6 @@
"use strict";
/* global define, app, socket */
define(function() { define(function() {
var Plugins = { var Plugins = {
init: function() { init: function() {
@ -19,10 +22,13 @@ define(function() {
app.alert({ app.alert({
alert_id: 'plugin_toggled', alert_id: 'plugin_toggled',
title: 'Plugin ' + (status.active ? 'Enabled' : 'Disabled'), title: 'Plugin ' + (status.active ? 'Enabled' : 'Disabled'),
message: 'Restarting your NodeBB <i class="fa fa-refresh fa-spin"></i>', message: 'Please restart your NodeBB to fully ' + (status.active ? 'activate' : 'deactivate') + ' this plugin',
type: 'warning', type: 'info',
timeout: 5000 timeout: 5000,
}) clickfn: function() {
socket.emit('admin.restart');
}
});
}); });
} else { } else {
pluginsList.append('<li><p><i>No plugins found.</i></p></li>'); pluginsList.append('<li><p><i>No plugins found.</i></p></li>');

@ -39,10 +39,13 @@ define(['forum/admin/settings'], function(Settings) {
app.alert({ app.alert({
alert_id: 'admin:theme', alert_id: 'admin:theme',
type: 'success', type: 'info',
title: 'Theme Changed', title: 'Theme Changed',
message: 'Restarting your NodeBB <i class="fa fa-refresh fa-spin"></i>', message: 'Please restart your NodeBB to fully activate this theme',
timeout: 3500 timeout: 5000,
clickfn: function() {
socket.emit('admin.restart');
}
}); });
}); });
} }
@ -251,7 +254,7 @@ define(['forum/admin/settings'], function(Settings) {
timeout: 2500 timeout: 2500
}); });
} }
}); });
}); });
} }

@ -225,11 +225,13 @@ define(['composer', 'forum/pagination', 'share', 'navigator'], function(composer
}); });
} }
Category.onTopicsLoaded = function(topics, callback) { Category.onTopicsLoaded = function(data, callback) {
if(!topics || !topics.length) { if(!data || !data.topics.length) {
return; return;
} }
var topics = data.topics;
function removeAlreadyAddedTopics() { function removeAlreadyAddedTopics() {
topics = topics.filter(function(topic) { topics = topics.filter(function(topic) {
return $('#topics-container li[data-tid="' + topic.tid +'"]').length === 0; return $('#topics-container li[data-tid="' + topic.tid +'"]').length === 0;
@ -261,7 +263,7 @@ define(['composer', 'forum/pagination', 'share', 'navigator'], function(composer
findInsertionPoint(); findInsertionPoint();
ajaxify.loadTemplate('category', function(categoryTemplate) { ajaxify.loadTemplate('category', function(categoryTemplate) {
var html = templates.parse(templates.getBlock(categoryTemplate, 'topics'), {topics: topics}); var html = templates.parse(templates.getBlock(categoryTemplate, 'topics'), data);
translator.translate(html, function(translatedHTML) { translator.translate(html, function(translatedHTML) {
var container = $('#topics-container'), var container = $('#topics-container'),
@ -309,6 +311,7 @@ define(['composer', 'forum/pagination', 'share', 'navigator'], function(composer
cid: cid, cid: cid,
after: after after: after
}, function (err, data) { }, function (err, data) {
console.log(data);
loadingMoreTopics = false; loadingMoreTopics = false;
if(err) { if(err) {
@ -316,7 +319,7 @@ define(['composer', 'forum/pagination', 'share', 'navigator'], function(composer
} }
if (data && data.topics.length) { if (data && data.topics.length) {
Category.onTopicsLoaded(data.topics, callback); Category.onTopicsLoaded(data, callback);
$('#topics-container').attr('data-nextstart', data.nextStart); $('#topics-container').attr('data-nextstart', data.nextStart);
} else { } else {

@ -1,3 +1,8 @@
'use strict';
/* globals define, socket, translator, utils, config, app, ajaxify, Tinycon*/
define(['sounds'], function(sound) { define(['sounds'], function(sound) {
var Notifications = {}; var Notifications = {};
@ -13,50 +18,44 @@ define(['sounds'], function(sound) {
socket.emit('notifications.get', null, function(err, data) { socket.emit('notifications.get', null, function(err, data) {
var numRead = data.read.length, function createNotification(notification, callback) {
numUnread = data.unread.length, if (notification.image) {
x; image = '<img class="image" src="' + notification.image + '" />';
} else {
image = '';
}
return '<li class="' + (notification.readClass || '') + '"><a href="' + notification.path + '">' + image + '<span class="pull-right relTime">' + utils.relativeTime(notification.datetime, true) + '</span><span class="text">' + notification.text + '</span></a></li>';
}
var html = ''; var x, html = '';
if (!err && (data.read.length + data.unread.length) > 0) { if (!err && (data.read.length + data.unread.length) > 0) {
var image = ''; var image = '';
for (x = 0; x < numUnread; x++) { for (x = 0; x < data.unread.length; x++) {
if (data.unread[x].image) { html += createNotification(data.unread[x]);
image = '<img class="image" src="' + data.unread[x].image + '" />';
} else {
image = '';
}
html += '<li class="' + (data.unread[x].readClass || '') + '"><a href="' + data.unread[x].path + '">' + image + '<span class="pull-right relTime">' + utils.relativeTime(data.unread[x].datetime, true) + '</span><span class="text">' + data.unread[x].text + '</span></a></li>';
} }
for (x = 0; x < numRead; x++) { for (x = 0; x < data.read.length; x++) {
if (data.read[x].image) { html += createNotification(data.read[x]);
image = '<img src="' + data.read[x].image + '" />';
} else {
image = '';
}
html += '<li class="' + data.read[x].readClass + '"><a href="' + data.read[x].path + '">' + image + '<span class="pull-right relTime">' + utils.relativeTime(data.read[x].datetime, true) + '</span><span class="text">' + data.read[x].text + '</span></a></li>';
} }
addSeeAllLink(replaceHtml);
addSeeAllLink();
} else { } else {
translator.translate('<li class="no-notifs"><a>[[notifications:no_notifs]]</a></li>', function(translated) { html += '<li class="no-notifs"><a>[[notifications:no_notifs]]</a></li>';
html += translated; addSeeAllLink();
addSeeAllLink(replaceHtml);
});
} }
function addSeeAllLink(callback) { function addSeeAllLink() {
translator.translate('<li class="pagelink"><a href="' + RELATIVE_PATH + '/notifications">[[notifications:see_all]]</a></li>', function(translated) { html += '<li class="pagelink"><a href="' + config.relative_path + '/notifications">[[notifications:see_all]]</a></li>';
html += translated;
callback();
});
} }
function replaceHtml() {
notifList.html(html); translator.translate(html, function(translated) {
} notifList.html(translated);
});
updateNotifCount(data.unread.length); updateNotifCount(data.unread.length);

@ -2,6 +2,7 @@
var Groups = require('./groups'), var Groups = require('./groups'),
User = require('./user'), User = require('./user'),
categories = require('./categories'),
async = require('async'), async = require('async'),
db = require('./database'); db = require('./database');
@ -36,6 +37,9 @@ CategoryTools.exists = function(cid, callback) {
CategoryTools.privileges = function(cid, uid, callback) { CategoryTools.privileges = function(cid, uid, callback) {
async.parallel({ async.parallel({
"disabled": function(next) {
categories.getCategoryField(cid, 'disabled', next);
},
"+r": function(next) { "+r": function(next) {
internals.isMember('cid:' + cid + ':privileges:+r', uid, next); internals.isMember('cid:' + cid + ':privileges:+r', uid, next);
}, },
@ -62,6 +66,7 @@ CategoryTools.privileges = function(cid, uid, callback) {
"g+w": privileges['g+w'], "g+w": privileges['g+w'],
read: ( read: (
( (
parseInt(privileges.disabled, 10) !== 1 &&
(privileges['+r'] || privileges['+r'] === null) && (privileges['+r'] || privileges['+r'] === null) &&
(privileges['g+r'] || privileges['g+r'] === null) (privileges['g+r'] || privileges['g+r'] === null)
) || ) ||
@ -70,6 +75,7 @@ CategoryTools.privileges = function(cid, uid, callback) {
), ),
write: ( write: (
( (
parseInt(privileges.disabled, 10) !== 1 &&
(privileges['+w'] || privileges['+w'] === null) && (privileges['+w'] || privileges['+w'] === null) &&
(privileges['g+w'] || privileges['g+w'] === null) (privileges['g+w'] || privileges['g+w'] === null)
) || ) ||

@ -37,7 +37,8 @@ adminController.home = function(req, res, next) {
res.render('admin/index', { res.render('admin/index', {
version: pkg.version, version: pkg.version,
emailerInstalled: plugins.hasListeners('action:email.send'), emailerInstalled: plugins.hasListeners('action:email.send'),
searchInstalled: plugins.hasListeners('filter:search.query') searchInstalled: plugins.hasListeners('filter:search.query'),
restartRequired: meta.restartRequired
}); });
}; };

@ -68,14 +68,14 @@ categoriesController.get = function(req, res, next) {
async.waterfall([ async.waterfall([
function(next) { function(next) {
categoryTools.privileges(cid, uid, function(err, categoryPrivileges) { categoryTools.privileges(cid, uid, function(err, categoryPrivileges) {
if (!err) { if (err) {
if (!categoryPrivileges.read) { return next(err);
next(new Error('[[error:no-privileges]]')); }
} else {
next(null, categoryPrivileges); if (!categoryPrivileges.read) {
} next(new Error('[[error:no-privileges]]'));
} else { } else {
next(err); next(null, categoryPrivileges);
} }
}); });
}, },

@ -18,7 +18,9 @@ var fs = require('fs'),
User = require('./user'); User = require('./user');
(function (Meta) { (function (Meta) {
Meta.restartRequired = false;
Meta.config = {}; Meta.config = {};
Meta.configs = { Meta.configs = {
init: function (callback) { init: function (callback) {
delete Meta.config; delete Meta.config;
@ -159,6 +161,9 @@ var fs = require('fs'),
db.setObjectField('config', 'theme:src', data.src, callback); db.setObjectField('config', 'theme:src', data.src, callback);
break; break;
} }
// Restart Required flag
meta.restartRequired = true;
} }
}; };

@ -383,6 +383,8 @@ var fs = require('fs'),
return; return;
} }
// Restart Required flag
meta.restartRequired = true;
if(active) { if(active) {
Plugins.fireHook('action:plugin.deactivate', id); Plugins.fireHook('action:plugin.deactivate', id);

@ -79,7 +79,6 @@ SocketAdmin.themes.set = function(socket, data, callback) {
widgets.reset(function(err) { widgets.reset(function(err) {
meta.themes.set(data, function() { meta.themes.set(data, function() {
callback(); callback();
meta.restart();
}); });
}); });
}; };
@ -87,7 +86,6 @@ SocketAdmin.themes.set = function(socket, data, callback) {
SocketAdmin.plugins.toggle = function(socket, plugin_id) { SocketAdmin.plugins.toggle = function(socket, plugin_id) {
plugins.toggleActive(plugin_id, function(status) { plugins.toggleActive(plugin_id, function(status) {
socket.emit('admin.plugins.toggle', status); socket.emit('admin.plugins.toggle', status);
meta.restart();
}); });
}; };

@ -1,6 +1,7 @@
'use strict'; 'use strict';
var categories = require('../categories'), var async = require('async'),
categories = require('../categories'),
categoryTools = require('../categoryTools'), categoryTools = require('../categoryTools'),
meta = require('./../meta'), meta = require('./../meta'),
user = require('./../user'), user = require('./../user'),
@ -30,12 +31,29 @@ SocketCategories.loadMore = function(socket, data, callback) {
return callback(new Error('[[error:invalid-data]]')); return callback(new Error('[[error:invalid-data]]'));
} }
user.getSettings(socket.uid, function(err, settings) { async.parallel({
privileges: function(next) {
categoryTools.privileges(data.cid, socket.uid, next);
},
settings: function(next) {
user.getSettings(socket.uid, next);
}
}, function(err, results) {
if (err) {
return callback(err);
}
var start = parseInt(data.after, 10), var start = parseInt(data.after, 10),
end = start + settings.topicsPerPage - 1; end = start + results.settings.topicsPerPage - 1;
categories.getCategoryTopics(data.cid, start, end, socket.uid, function(err, data) {
if (err) {
return callback(err);
}
categories.getCategoryTopics(data.cid, start, end, socket.uid, callback); data.privileges = results.privileges;
callback(null, data);
});
}); });
}; };

@ -194,7 +194,7 @@ SocketModules.chats.send = function(socket, data, callback) {
function sendChatNotification(fromuid, touid, username) { function sendChatNotification(fromuid, touid, username) {
if (!module.parent.exports.isUserOnline(touid)) { if (!module.parent.exports.isUserOnline(touid)) {
var notifText = 'New message from <strong>' + username + '</strong>'; var notifText = '[[notifications:new_message_from,' + username + ']]';
notifications.create({ notifications.create({
text: notifText, text: notifText,
path: 'javascript:app.openChat(&apos;' + username + '&apos;, ' + fromuid + ');', path: 'javascript:app.openChat(&apos;' + username + '&apos;, ' + fromuid + ');',

@ -33,14 +33,11 @@ SocketPosts.reply = function(socket, data, callback) {
} }
if (postData) { if (postData) {
websockets.server.sockets.emit('event:new_post', {
module.parent.exports.emitTopicPostStats();
var socketData = {
posts: [postData] posts: [postData]
}; });
websockets.server.sockets.emit('event:new_post', socketData); module.parent.exports.emitTopicPostStats();
callback(); callback();
} }
@ -49,7 +46,7 @@ SocketPosts.reply = function(socket, data, callback) {
SocketPosts.upvote = function(socket, data, callback) { SocketPosts.upvote = function(socket, data, callback) {
favouriteCommand('upvote', 'voted', socket, data, callback); favouriteCommand('upvote', 'voted', socket, data, callback);
sendNotificationToPostOwner(data, socket.uid, 'has upvoted your post'); sendNotificationToPostOwner(data, socket.uid, 'notifications:upvoted_your_post');
}; };
SocketPosts.downvote = function(socket, data, callback) { SocketPosts.downvote = function(socket, data, callback) {
@ -62,7 +59,7 @@ SocketPosts.unvote = function(socket, data, callback) {
SocketPosts.favourite = function(socket, data, callback) { SocketPosts.favourite = function(socket, data, callback) {
favouriteCommand('favourite', 'favourited', socket, data, callback); favouriteCommand('favourite', 'favourited', socket, data, callback);
sendNotificationToPostOwner(data, socket.uid, 'has favourited your post'); sendNotificationToPostOwner(data, socket.uid, 'notifications:favourited_your_post');
}; };
SocketPosts.unfavourite = function(socket, data, callback) { SocketPosts.unfavourite = function(socket, data, callback) {
@ -87,7 +84,7 @@ function favouriteCommand(command, eventName, socket, data, callback) {
} }
} }
function sendNotificationToPostOwner(data, uid, message) { function sendNotificationToPostOwner(data, uid, notification) {
if(data && data.pid && uid) { if(data && data.pid && uid) {
posts.getPostFields(data.pid, ['tid', 'uid'], function(err, postData) { posts.getPostFields(data.pid, ['tid', 'uid'], function(err, postData) {
if (err) { if (err) {
@ -109,8 +106,9 @@ function sendNotificationToPostOwner(data, uid, message) {
if (err) { if (err) {
return; return;
} }
notifications.create({ notifications.create({
text: '<strong>' + results.username + '</strong> ' + message, text: '[[' + notification + ', ' + results.username + ']]',
path: nconf.get('relative_path') + '/topic/' + results.slug + '#' + data.pid, path: nconf.get('relative_path') + '/topic/' + results.slug + '#' + data.pid,
uniqueId: 'post:' + data.pid, uniqueId: 'post:' + data.pid,
from: uid from: uid
@ -258,7 +256,7 @@ SocketPosts.flag = function(socket, pid, callback) {
user.getUserField(socket.uid, 'username', next); user.getUserField(socket.uid, 'username', next);
}, },
function(username, next) { function(username, next) {
message = '<strong>' + username + '</strong> flagged a post.'; message = '[[notifications:user_flagged_post, ' + username + ']]';
posts.getPostField(pid, 'tid', next); posts.getPostField(pid, 'tid', next);
}, },
function(tid, next) { function(tid, next) {

@ -229,7 +229,7 @@ var winston = require('winston'),
} }
notifications.create({ notifications.create({
text: '<strong>' + username + '</strong> has posted a reply to: "<strong>' + topicData.title + '</strong>"', text: '[[notifications:user_posted_to, ' + username + ', ' + topicData.title + ']]',
path: nconf.get('relative_path') + '/topic/' + topicData.slug + '#' + pid, path: nconf.get('relative_path') + '/topic/' + topicData.slug + '#' + pid,
uniqueId: 'topic:' + tid, uniqueId: 'topic:' + tid,
from: exceptUid from: exceptUid

@ -49,7 +49,6 @@ module.exports = function(User) {
} }
if (exists) { if (exists) {
async.forever(function(next) { async.forever(function(next) {
// Append a random number to the username
var newUsername = userData.username + (Math.floor(Math.random() * 255) + 1); var newUsername = userData.username + (Math.floor(Math.random() * 255) + 1);
User.exists(newUsername, function(err, exists) { User.exists(newUsername, function(err, exists) {
if (!exists) { if (!exists) {
@ -87,10 +86,11 @@ module.exports = function(User) {
if (err) { if (err) {
return callback(err); return callback(err);
} }
userData = results[results.length - 1];
userData = results[results.length - 1];
var userNameChanged = !!results[3];
// If a new username was picked... // If a new username was picked...
if (results[3]) { if (userNameChanged) {
userData.username = results[3]; userData.username = results[3];
userData.userslug = utils.slugify(results[3]); userData.userslug = utils.slugify(results[3]);
} }
@ -149,16 +149,13 @@ module.exports = function(User) {
groups.join('registered-users', uid); groups.join('registered-users', uid);
// If their username was automatically changed... if (userNameChanged) {
if (results[3]) { notifications.create({
translator.translate('[[user:username_taken_workaround, ' + userData.username + ']]', function(notifText) { text: '[[user:username_taken_workaround, ' + userData.username + ']]',
notifications.create({ picture: 'brand:logo',
text: notifText, datetime: Date.now()
picture: 'brand:logo', }, function(nid) {
datetime: Date.now() notifications.push(nid, uid);
}, function(nid) {
notifications.push(nid, uid);
});
}); });
} }

@ -153,7 +153,7 @@ var async = require('async'),
db.getSetMembers('followers:' + uid, function(err, followers) { db.getSetMembers('followers:' + uid, function(err, followers) {
if (followers && followers.length) { if (followers && followers.length) {
topics.getTopicField(tid, 'slug', function(err, slug) { topics.getTopicField(tid, 'slug', function(err, slug) {
var message = '<strong>' + username + '</strong> made a new post'; var message = '[[notifications:user_made_post, ' + username + ']]';
notifications.create({ notifications.create({
text: message, text: message,

Loading…
Cancel
Save