Merge remote-tracking branch 'origin/master' into webserver.js-refactor

Conflicts:
	src/routes/admin.js
v1.18.x
psychobunny 11 years ago
commit 48df0cf889

@ -105,7 +105,8 @@ function start() {
winston.info('Time: ' + new Date());
winston.info('Initializing NodeBB v' + pkg.version);
winston.info('* using configuration stored in: ' + configFile);
winston.info('* using ' + nconf.get('database') +' store at ' + nconf.get(nconf.get('database') + ':host') + ':' + nconf.get(nconf.get('database') + ':port'));
var host = nconf.get(nconf.get('database') + ':host');
winston.info('* using ' + nconf.get('database') +' store at ' + host + (host.indexOf('/') === -1 ? ':' + nconf.get(nconf.get('database') + ':port') : ''));
winston.info('* using themes stored in: ' + nconf.get('themes_path'));
if (process.env.NODE_ENV === 'development') {

@ -32,7 +32,7 @@
"rss": "~0.2.0",
"prompt": "~0.2.11",
"uglify-js": "~2.4.0",
"validator": "~3.2.1",
"validator": "^3.4.0",
"cron": "~1.0.1",
"semver": "~2.2.1",
"string": "~1.7.0",

@ -8,6 +8,7 @@
"new_password": "New Password",
"repeat_password": "Confirm Password",
"enter_email": "Please enter your <strong>email address</strong> and we will send you an email with instructions on how to reset your account.",
"enter_email_address": "Enter Email Address",
"password_reset_sent": "Password Reset Sent",
"invalid_email": "Invalid Email / Email does not exist!"
}

@ -10,16 +10,16 @@
"500.message": "Oeps! Het lijkt erop dat iets is fout gegaan!",
"register": "Registeren",
"login": "Inloggen",
"please_log_in": "Please Log In",
"posting_restriction_info": "Posting is currently restricted to registered members only, click here to log in.",
"welcome_back": "Welcome Back ",
"you_have_successfully_logged_in": "You have successfully logged in",
"please_log_in": "Log a.u.b. In",
"posting_restriction_info": "Reageren is momenteel beperkt tot geregistreerde leden, klik hier om in te loggen.",
"welcome_back": "Welkom Terug!",
"you_have_successfully_logged_in": "Je bent succesvol ingelogd",
"logout": "Uitloggen",
"logout.title": "Je bent nu uitgelogd.",
"logout.message": "Je bent met succes uitgelogd van NodeBB",
"save_changes": "Aanpassingen Opslaan",
"close": "Sluiten",
"pagination": "Pagination",
"pagination": "Paginering",
"header.admin": "Admin",
"header.recent": "Recent",
"header.unread": "Ongelezen",
@ -49,7 +49,7 @@
"posted": "geplaatst",
"in": "in",
"recentposts": "Recente Berichten",
"recentips": "Recently Logged In IPs",
"recentips": "Recente Ingelogde IPs",
"online": "Online",
"away": "Afwezig",
"dnd": "Niet Storen",

@ -1,6 +1,6 @@
{
"title": "Notificaties",
"no_notifs": "You have no new notifications",
"no_notifs": "Je hebt geen nieuwe notificaties",
"see_all": "Bekijk alle Notificaties",
"back_to_home": "Terug naar NodeBB",
"outgoing_link": "Uitgaande Link",

@ -1,14 +1,14 @@
{
"home": "Home",
"unread": "Ongelezen Onderwerpen",
"popular": "Popular Topics",
"popular": "Populaire Onderwerpen",
"recent": "Recente Onderwerpen",
"users": "Geregistreerde Gebruikers",
"notifications": "Notificaties",
"user.edit": "\"%1\" aanpassen",
"user.following": "Mensen %1 Volgt",
"user.followers": "Mensen die %1 Volgen",
"user.posts": "Posts made by %1",
"user.posts": "Berichten geplaatst door %1",
"user.favourites": "%1's Favoriete Berichten",
"user.settings": "Gebruikersinstellingen"
}

@ -11,7 +11,7 @@
"reply": "Reageren",
"edit": "Aanpassen",
"delete": "Verwijderen",
"restore": "Restore",
"restore": "Herstellen",
"move": "Verplaatsen",
"fork": "Fork",
"banned": "verbannen",
@ -19,17 +19,17 @@
"share": "Delen",
"tools": "Gereedschap",
"flag": "Markeren",
"bookmark_instructions": "Click here to return to your last position or close to discard.",
"bookmark_instructions": "Klik hier om terug te gaan naar je laatste positie of sluiten om te annuleren.",
"flag_title": "Dit bericht markeren voor moderatie",
"deleted_message": "Dit onderwerp is verwijderd. Alleen gebruikers met onderwerp management privileges kunnen dit onderwerp zien.",
"following_topic.title": "Following Topic",
"following_topic.message": "You will now be receiving notifications when somebody posts to this topic.",
"not_following_topic.title": "Not Following Topic",
"not_following_topic.message": "You will no longer receive notifications from this topic.",
"login_to_subscribe": "Please register or log in in order to subscribe to this topic.",
"markAsUnreadForAll.success": "Topic marked as unread for all.",
"watch": "Watch",
"share_this_post": "Share this Post",
"following_topic.title": "Volg Onderwerp",
"following_topic.message": "Je zult nu notificaties ontvangen wanneer iemand reageert op dit onderwerp.",
"not_following_topic.title": "Volgt Onderwerp Niet",
"not_following_topic.message": "Je zult niet langer notificaties ontvangen van dit onderwerp.",
"login_to_subscribe": "Log a.u.b. in om op dit onderwerp te abonneren.",
"markAsUnreadForAll.success": "Onderwerp gemarkeerd als gelezen voor iedereen.",
"watch": "Volgen",
"share_this_post": "Deel dit Bericht",
"thread_tools.title": "Thread Gereedschap",
"thread_tools.markAsUnreadForAll": "Ongelezen Markeren",
"thread_tools.pin": "Onderwerp Vastmaken",
@ -71,12 +71,12 @@
"composer.submit": "Opslaan",
"composer.replying_to": "Reageren op",
"composer.new_topic": "Nieuw Onderwerp",
"composer.uploading": "uploading...",
"composer.thumb_url_label": "Paste a topic thumbnail URL",
"composer.thumb_title": "Add a thumbnail to this topic",
"composer.uploading": "uploaden...",
"composer.thumb_url_label": "Plak een onderwerp thumbnail URL",
"composer.thumb_title": "Voeg een thumbnail toe aan dit onderwerp",
"composer.thumb_url_placeholder": "http://example.com/thumb.png",
"composer.thumb_file_label": "Or upload a file",
"composer.thumb_remove": "Clear fields",
"composer.drag_and_drop_images": "Drag and Drop Images Here",
"composer.upload_instructions": "Upload images by dragging & dropping them."
"composer.thumb_file_label": "Of upload een bestand",
"composer.thumb_remove": "Velden leegmaken",
"composer.drag_and_drop_images": "Sleep en Zet Afbeeldingen Hier",
"composer.upload_instructions": "Upload afbeeldingen door ze te slepen."
}

@ -20,19 +20,19 @@
"gravatar": "Gravatar",
"birthday": "Verjaardag",
"chat": "Chat",
"follow": "Follow",
"unfollow": "Unfollow",
"follow": "Volgen",
"unfollow": "Ontvolgen",
"change_picture": "Afbeelding Aanpassen",
"edit": "Aanpassen",
"uploaded_picture": "Afbeelding Uploaden",
"upload_new_picture": "Nieuwe Afbeelding Uploaden",
"current_password": "Current Password",
"current_password": "Huidige Wachtwoord",
"change_password": "Wachtwoord Aanpassen",
"confirm_password": "Bevestig Wachtwoord",
"password": "Wachtwoord",
"upload_picture": "Afbeelding Uploaden",
"upload_a_picture": "Upload een afbeelding",
"image_spec": "You may only upload PNG, JPG, or GIF files",
"image_spec": "Je mag alleen PNG, JPG, of GIF bestanden uploaden.",
"max": "max.",
"settings": "Instellingen",
"show_email": "Laat Mijn Email Zien",
@ -41,7 +41,7 @@
"has_no_posts": "Deze gebruiker heeft nog geen berichten geplaatst",
"email_hidden": "Email Verborgen",
"hidden": "verborgen",
"paginate_description": "Paginate topics and posts instead of using infinite scroll.",
"topics_per_page": "Topics per Page",
"posts_per_page": "Posts per Page"
"paginate_description": "Blader door onderwerpen en berichten in plaats van oneindig scrollen.",
"topics_per_page": "Onderwerpen per Pagina",
"posts_per_page": "Berichten per Pagina"
}

@ -252,6 +252,7 @@ define(['uploader'], function(uploader) {
var numResults = results.length,
resultObj;
resultsEl.html('');
for(var x = 0; x < numResults; x++) {
resultObj = results[x];
liEl = $('<li />')
@ -305,6 +306,8 @@ define(['uploader'], function(uploader) {
trEl,
resultObj;
groupsResultsEl.empty();
for(var x = 0; x < numResults; x++) {
resultObj = results[x];
trEl = $('<tr />')
@ -346,12 +349,14 @@ define(['uploader'], function(uploader) {
readMembers = modalEl.find('#category-permissions-read'),
writeMembers = modalEl.find('#category-permissions-write'),
moderatorsEl = modalEl.find('#category-permissions-mods');
socket.emit('admin.categories.getPrivilegeSettings', cid, function(err, privilegeList) {
var readLength = privilegeList['+r'].length,
writeLength = privilegeList['+w'].length,
modLength = privilegeList['mods'].length,
liEl, x, userObj;
readMembers.html('');
if (readLength > 0) {
for(x = 0; x < readLength; x++) {
userObj = privilegeList['+r'][x];
@ -363,10 +368,11 @@ define(['uploader'], function(uploader) {
readMembers.append(liEl);
}
writeMembers.html('');
if (writeLength > 0) {
for(x=0;x<writeLength;x++) {
userObj = privilegeList['+w'][x];
$('<li />').attr('data-uid', userObj.uid).html('<img src="' + userObj.picture + '" title="' + userObj.username + '" />');
liEl = $('<li />').attr('data-uid', userObj.uid).html('<img src="' + userObj.picture + '" title="' + userObj.username + '" />');
writeMembers.append(liEl);
}
} else {
@ -374,6 +380,7 @@ define(['uploader'], function(uploader) {
writeMembers.append(liEl);
}
moderatorsEl.html('');
if (modLength > 0) {
for(x = 0;x < modLength; x++) {
userObj = privilegeList['mods'][x];
@ -382,7 +389,7 @@ define(['uploader'], function(uploader) {
}
} else {
liEl = $('<li />').addClass('empty').html('No moderators');
moderatorsEl.appendChild(liEl);
moderatorsEl.append(liEl);
}
});
};

@ -91,8 +91,9 @@ define(function() {
groupMembersEl.empty();
for (x = 0; x < numMembers; x++) {
var memberIcon = $('<li />')
.attr('data-uid', groupObj.members[x].uid)
.append($('<img />').attr('src', groupObj.members[x].picture))
.append($('<span />').attr('data-uid', groupObj.members[x].uid).html(groupObj.members[x].username));
.append($('<span />').html(groupObj.members[x].username));
groupMembersEl.append(memberIcon);
}
}
@ -152,7 +153,7 @@ define(function() {
uid: uid
}, function(err, data) {
if (!err) {
groupMembersEl.append(userLabel.cloneNode(true));
groupMembersEl.append(userLabel.clone(true));
}
});
}
@ -164,10 +165,6 @@ define(function() {
socket.emit('admin.groups.get', gid, function(err, groupObj){
if (!err){
if (groupObj.name == 'Administrators' && uid == yourid){
bootbox.alert('You cannot remove yourself from the Administrator Group');
return;
}
bootbox.confirm('Are you sure you want to remove this user?', function(confirm) {
if (confirm){
socket.emit('admin.groups.leave', {

@ -3,14 +3,14 @@ define(function() {
Search.init = function() {
var searchQuery = $('#topic-results').attr('data-search-query');
$('.search-result-text').children().each(function() {
var text = $(this).text();
$('.search-result-text').each(function() {
var text = $(this).html();
var regex = new RegExp(searchQuery, 'gi');
text = text.replace(regex, '<span class="label label-success">' + searchQuery + '</span>');
$(this).html(text);
});
$('#search-form input').val(searchQuery);
$('#mobile-search-form').off('submit').on('submit', function() {

@ -12,8 +12,17 @@ define(['forum/recent'], function(recent) {
recent.watchForNewPosts();
$('#mark-allread-btn').on('click', function() {
function getUnreadTids() {
var tids = [];
$('#topics-container .category-item[data-tid]').each(function() {
tids.push($(this).attr('data-tid'));
});
return tids;
}
var btn = $(this);
socket.emit('topics.markAllRead', function(err) {
socket.emit('topics.markAllRead', getUnreadTids(), function(err) {
if(err) {
return app.alertError('There was an error marking topics read!');
}

@ -1,4 +1,5 @@
<div class="home">
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">Welcome to NodeBB</div>
@ -11,32 +12,19 @@
</p>
</div>
</div>
</div>
<div class="col-sm-6 pull-right">
<div class="panel panel-default">
<div class="panel-heading">Updates</div>
<div class="panel-heading">Notices</div>
<div class="panel-body">
<div class="alert alert-info version-check">
<p>You are running <strong>NodeBB v<span id="version">{version}</span></strong>.</p>
<div>
<!-- IF emailerInstalled --><i class="fa fa-check alert-success"></i><!-- ELSE --><i class="fa fa-times alert-danger"></i><!-- ENDIF emailerInstalled --> Emailer Installed
</div>
<p>
Always make sure that your <strong>NodeBB</strong> is up to date for the latest security patches and bug fixes.
</p>
<p class="pull-right">
<button class="btn btn-warning restart">Restart NodeBB</button>
</p>
<div>
<!-- IF searchInstalled --><i class="fa fa-check alert-success"></i><!-- ELSE --><i class="fa fa-times alert-danger"></i><!-- ENDIF searchInstalled --> Search Plugin Installed
</div>
</div>
</div>
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">Active Users <small><span class="badge" id="connections"></span> socket connections</small></div>
<div class="panel-body">
<div id="active_users"></div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">Unique Visitors</div>
<div class="panel-body">
@ -60,5 +48,32 @@
</div>
</div>
</div>
</div>
<div class="col-sm-6 pull-right">
<div class="panel panel-default">
<div class="panel-heading">Updates</div>
<div class="panel-body">
<div class="alert alert-info version-check">
<p>You are running <strong>NodeBB v<span id="version">{version}</span></strong>.</p>
</div>
<p>
Always make sure that your <strong>NodeBB</strong> is up to date for the latest security patches and bug fixes.
</p>
<p class="pull-right">
<button class="btn btn-warning restart">Restart NodeBB</button>
</p>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Active Users <small><span class="badge" id="connections"></span> socket connections</small></div>
<div class="panel-body">
<div id="active_users"></div>
</div>
</div>
</div>
</div>

@ -8,7 +8,7 @@
</ol>
<div class="alert alert-info">
[[reset_password:reset_password:enter_email]]
[[reset_password:enter_email]]
</div>
<div class="well">
@ -21,7 +21,7 @@
<strong>[[reset_password:invalid_email]]</strong>
</div>
<form onsubmit="return false;">
<input type="text" class="form-control input-block input-lg" placeholder="Enter Email Address" id="email" />
<input type="text" class="form-control input-block input-lg" placeholder="[[reset_password:enter_email_address]]" id="email" />
<br />
<button class="btn btn-primary btn-block btn-lg" id="reset" type="submit">[[reset_password:reset_password]]</button>

@ -27,9 +27,9 @@
</div>
<form onsubmit="return false;" id="reset-form">
<label for="password">[[reset_password:new_password]]</label>
<input class="form-control input-lg" type="password" placeholder="A new password" id="password" /><br />
<input class="form-control input-lg" type="password" placeholder="[[reset_password:new_password]]" id="password" /><br />
<label for="repeat">[[reset_password:repeat_password]]</label>
<input class="form-control input-lg" type="password" placeholder="The same password" id="repeat" /><br />
<input class="form-control input-lg" type="password" placeholder="[[reset_password:repeat_password]]" id="repeat" /><br />
<button class="btn btn-primary btn-lg btn-block" id="reset" type="submit">[[reset_password:reset_password]]</button>
</form>
</div>

@ -13,7 +13,7 @@
</div>
</form>
<div class="search favourites">
<div class="search">
<div class="{show_results} row">
<div id="topic-results" class="col-md-12" data-search-query="{search_query}">
@ -28,25 +28,19 @@
<!-- BEGIN topics -->
<div class="topic-row panel panel-default clearfix">
<div class="panel-body">
<a href="../../user/{topics.userslug}">
<img title="{topics.username}" class="img-rounded user-img" src="{topics.picture}">
</a>
<a href="../../user/{topics.userslug}">
<strong><span>{topics.username}</span></strong>
<a href="../../topic/{topics.slug}" class="search-result-text">
{topics.title}
</a>
<span class="search-result-text">
<p>{topics.title}</p>
</span>
<div>
<small>
<span class="pull-right">
<a href="../../topic/{topics.slug}">posted</a>
in
<a href="../../category/{topics.categorySlug}">
<i class="fa {topics.categoryIcon}"></i> {topics.categoryName}
</a>
<a href="../../user/{topics.userslug}"><img title="{topics.username}" class="img-rounded user-img" src="{topics.picture}"></a>
<a href="../../topic/{topics.slug}"> [[global:posted]]</a>
[[global:in]]
<a href="../../category/{topics.category.slug}"><i class="fa {topics.category.icon}"></i> {topics.category.name}</a>
<span class="timeago" title="{topics.relativeTime}"></span>
</span>
</small>
@ -67,20 +61,16 @@
<!-- BEGIN posts -->
<div class="topic-row panel panel-default clearfix">
<div class="panel-body">
<a href="../../user/{posts.userslug}">
<img title="{posts.username}" class="img-rounded user-img" src="{posts.picture}">
</a>
<a href="../../user/{posts.userslug}">
<strong><span>{posts.username}</span></strong>
</a>
<span class="search-result-text">
<a href="../../topic/{posts.topicSlug}#{posts.pid}" class="search-result-text">
{posts.content}
</span>
</a>
<div>
<small>
<span class="pull-right">
<a href="../../user/{posts.userslug}">
<img title="{posts.username}" class="img-rounded user-img" src="{posts.picture}">
</a>
<a href="../../topic/{posts.topicSlug}#{posts.pid}">posted</a>
in
<a href="../../category/{posts.categorySlug}">

@ -19,7 +19,7 @@
<div class="col-md-12">
<ul id="topics-container" data-nextstart="{nextStart}">
<!-- BEGIN topics -->
<li class="category-item <!-- IF topics.deleted --> deleted<!-- ENDIF topics.deleted -->">
<li class="category-item<!-- IF topics.deleted --> deleted<!-- ENDIF topics.deleted -->" data-tid="{topics.tid}">
<div class="col-md-12 col-xs-12 panel panel-default topic-row">
<a href="{relative_path}/user/{topics.userslug}" class="pull-left">
<img class="img-rounded user-img" src="{topics.picture}" title="{topics.username}" />

@ -29,7 +29,9 @@ var adminController = {
adminController.home = function(req, res, next) {
var data = {
version: pkg.version
version: pkg.version,
emailerInstalled: plugins.hasListeners('action:email.send'),
searchInstalled: plugins.hasListeners('filter:search.query')
};
if (res.locals.isAPI) {

@ -294,6 +294,10 @@
};
module.getObjectField = function(key, field, callback) {
if(typeof field !== 'string') {
field = field.toString();
}
field = field.replace(/\./g, '\uff0E');
module.getObjectFields(key, [field], function(err, data) {
if(err) {
return callback(err);
@ -307,11 +311,12 @@
var _fields = {};
for(var i=0; i<fields.length; ++i) {
if(typeof fields[i] !== 'string') {
_fields[fields[i].toString().replace(/\./g, '\uff0E')] = 1;
} else {
_fields[fields[i].replace(/\./g, '\uff0E')] = 1;
if (typeof fields[i] !== 'string') {
fields[i] = fields[i].toString();
}
fields[i] = fields[i].replace(/\./g, '\uff0E');
_fields[fields[i]] = 1;
}
db.collection('objects').findOne({_key:key}, _fields, function(err, item) {

@ -175,7 +175,7 @@ var fs = require('fs'),
(function(staticDir) {
fs.exists(staticDir, function(exists) {
if (exists) {
Plugins.staticDirs[path.join(pluginData.id, mappedPath)] = staticDir;
Plugins.staticDirs[pluginData.id + '/' + mappedPath] = staticDir;
} else {
winston.warn('[plugins/' + pluginData.id + '] Mapped path \'' + mappedPath + ' => ' + staticDir + '\' not found.');
}

@ -1,3 +1,6 @@
'use strict';
var topics = require('../topics'),
categories = require('../categories'),
threadTools = require('../threadTools'),
@ -68,7 +71,7 @@ SocketTopics.post = function(socket, data, callback) {
type: 'success',
timeout: 2000
});
callback(null);
callback();
}
});
};
@ -88,14 +91,19 @@ SocketTopics.markAsRead = function(socket, data) {
};
SocketTopics.markAllRead = function(socket, data, callback) {
topics.markAllRead(socket.uid, function(err) {
if (!Array.isArray(data)) {
return callback(new Error('invalid-data'));
}
topics.markAllRead(socket.uid, data, function(err) {
if(err) {
return callback(err);
}
index.server.sockets.in('uid_' + socket.uid).emit('event:unread.updateCount', null, []);
callback(null);
callback();
});
};

@ -797,24 +797,6 @@ var async = require('async'),
});
};
Topics.markAllRead = function(uid, callback) {
Topics.getLatestTids(0, -1, 'month', function(err, tids) {
if (err) {
return callback(err);
}
if(!tids || !tids.length) {
return callback();
}
function markRead(tid, next) {
Topics.markAsRead(tid, uid, next);
}
async.each(tids, markRead, callback);
});
};
Topics.getTitleByPid = function(pid, callback) {
Topics.getTopicFieldByPid('title', pid, callback);
};
@ -862,6 +844,16 @@ var async = require('async'),
});
};
Topics.markAllRead = function(uid, tids, callback) {
if(!tids || !tids.length) {
return callback();
}
async.each(tids, function (tid, next) {
Topics.markAsRead(tid, uid, next);
}, callback);
};
Topics.markAsRead = function(tid, uid, callback) {
db.setAdd('tid:' + tid + ':read_by_uid', uid, function(err) {

Loading…
Cancel
Save