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('Time: ' + new Date());
winston.info('Initializing NodeBB v' + pkg.version); winston.info('Initializing NodeBB v' + pkg.version);
winston.info('* using configuration stored in: ' + configFile); 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')); winston.info('* using themes stored in: ' + nconf.get('themes_path'));
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {

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

@ -8,6 +8,7 @@
"new_password": "New Password", "new_password": "New Password",
"repeat_password": "Confirm 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": "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", "password_reset_sent": "Password Reset Sent",
"invalid_email": "Invalid Email / Email does not exist!" "invalid_email": "Invalid Email / Email does not exist!"
} }

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

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

@ -1,14 +1,14 @@
{ {
"home": "Home", "home": "Home",
"unread": "Ongelezen Onderwerpen", "unread": "Ongelezen Onderwerpen",
"popular": "Popular Topics", "popular": "Populaire Onderwerpen",
"recent": "Recente Onderwerpen", "recent": "Recente Onderwerpen",
"users": "Geregistreerde Gebruikers", "users": "Geregistreerde Gebruikers",
"notifications": "Notificaties", "notifications": "Notificaties",
"user.edit": "\"%1\" aanpassen", "user.edit": "\"%1\" aanpassen",
"user.following": "Mensen %1 Volgt", "user.following": "Mensen %1 Volgt",
"user.followers": "Mensen die %1 Volgen", "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.favourites": "%1's Favoriete Berichten",
"user.settings": "Gebruikersinstellingen" "user.settings": "Gebruikersinstellingen"
} }

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

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

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

@ -91,8 +91,9 @@ define(function() {
groupMembersEl.empty(); groupMembersEl.empty();
for (x = 0; x < numMembers; x++) { for (x = 0; x < numMembers; x++) {
var memberIcon = $('<li />') var memberIcon = $('<li />')
.attr('data-uid', groupObj.members[x].uid)
.append($('<img />').attr('src', groupObj.members[x].picture)) .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); groupMembersEl.append(memberIcon);
} }
} }
@ -152,7 +153,7 @@ define(function() {
uid: uid uid: uid
}, function(err, data) { }, function(err, data) {
if (!err) { 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){ socket.emit('admin.groups.get', gid, function(err, groupObj){
if (!err){ 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) { bootbox.confirm('Are you sure you want to remove this user?', function(confirm) {
if (confirm){ if (confirm){
socket.emit('admin.groups.leave', { socket.emit('admin.groups.leave', {

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

@ -12,8 +12,17 @@ define(['forum/recent'], function(recent) {
recent.watchForNewPosts(); recent.watchForNewPosts();
$('#mark-allread-btn').on('click', function() { $('#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); var btn = $(this);
socket.emit('topics.markAllRead', function(err) {
socket.emit('topics.markAllRead', getUnreadTids(), function(err) {
if(err) { if(err) {
return app.alertError('There was an error marking topics read!'); return app.alertError('There was an error marking topics read!');
} }

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

@ -8,7 +8,7 @@
</ol> </ol>
<div class="alert alert-info"> <div class="alert alert-info">
[[reset_password:reset_password:enter_email]] [[reset_password:enter_email]]
</div> </div>
<div class="well"> <div class="well">
@ -21,7 +21,7 @@
<strong>[[reset_password:invalid_email]]</strong> <strong>[[reset_password:invalid_email]]</strong>
</div> </div>
<form onsubmit="return false;"> <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 /> <br />
<button class="btn btn-primary btn-block btn-lg" id="reset" type="submit">[[reset_password:reset_password]]</button> <button class="btn btn-primary btn-block btn-lg" id="reset" type="submit">[[reset_password:reset_password]]</button>

@ -27,9 +27,9 @@
</div> </div>
<form onsubmit="return false;" id="reset-form"> <form onsubmit="return false;" id="reset-form">
<label for="password">[[reset_password:new_password]]</label> <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> <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> <button class="btn btn-primary btn-lg btn-block" id="reset" type="submit">[[reset_password:reset_password]]</button>
</form> </form>
</div> </div>

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

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

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

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

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

@ -1,3 +1,6 @@
'use strict';
var topics = require('../topics'), var topics = require('../topics'),
categories = require('../categories'), categories = require('../categories'),
threadTools = require('../threadTools'), threadTools = require('../threadTools'),
@ -68,7 +71,7 @@ SocketTopics.post = function(socket, data, callback) {
type: 'success', type: 'success',
timeout: 2000 timeout: 2000
}); });
callback(null); callback();
} }
}); });
}; };
@ -88,14 +91,19 @@ SocketTopics.markAsRead = function(socket, data) {
}; };
SocketTopics.markAllRead = function(socket, data, callback) { 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) { if(err) {
return callback(err); return callback(err);
} }
index.server.sockets.in('uid_' + socket.uid).emit('event:unread.updateCount', null, []); 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.getTitleByPid = function(pid, callback) {
Topics.getTopicFieldByPid('title', 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) { Topics.markAsRead = function(tid, uid, callback) {
db.setAdd('tid:' + tid + ':read_by_uid', uid, function(err) { db.setAdd('tid:' + tid + ':read_by_uid', uid, function(err) {

Loading…
Cancel
Save