diff --git a/install/data/defaults.json b/install/data/defaults.json
index b81b1b8523..5507ad0822 100644
--- a/install/data/defaults.json
+++ b/install/data/defaults.json
@@ -15,6 +15,14 @@
"field": "initialPostDelay",
"value": 10
},
+ {
+ "field": "newbiePostDelay",
+ "value": 120
+ },
+ {
+ "field": "newbiePostDelayThreshold",
+ "value": 3
+ },
{
"field": "minimumPostLength",
"value": 8
diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json
index 6f0c2653da..f0c4bc4d45 100644
--- a/public/language/en_GB/error.json
+++ b/public/language/en_GB/error.json
@@ -49,6 +49,7 @@
"title-too-long": "Please enter a shorter title. Titles can't be longer than %1 characters.",
"invalid-title": "Invalid title!",
"too-many-posts": "You can only post once every %1 seconds - please wait before posting again",
+ "too-many-posts-newbie": "As a new registrant, you can only post once every %1 seconds until you have earned %2 reputation - please wait before posting again",
"file-too-big": "Maximum allowed file size is %1 kbs - please upload a smaller file",
"cant-vote-self-post": "You cannot vote for your own post",
diff --git a/public/src/admin/admin.js b/public/src/admin/admin.js
index 77dbe50947..e9a061bc52 100644
--- a/public/src/admin/admin.js
+++ b/public/src/admin/admin.js
@@ -89,6 +89,15 @@ var admin = {};
socket.emit('admin.restart');
});
+ Mousetrap.bind('ctrl+shift+a d', function() {
+ var tid = ajaxify.variables.get('topic_id'),
+ cid = ajaxify.variables.get('category_id');
+
+ if (tid && cid) {
+ socket.emit('topics.delete', { tids: [tid], cid: cid });
+ }
+ });
+
Mousetrap.bind('/', function(e) {
$('#acp-search input').focus();
diff --git a/src/categories.js b/src/categories.js
index f91309b04c..1a87c0d3b9 100644
--- a/src/categories.js
+++ b/src/categories.js
@@ -50,13 +50,14 @@ var db = require('./database'),
imageClass: 'auto'
};
- db.setObject('category:' + cid, category, function(err) {
- if(err) {
+ async.series([
+ async.apply(db.setObject, 'category:' + cid, category),
+ async.apply(db.sortedSetAdd, 'categories:cid', data.order, cid)
+ ], function(err) {
+ if (err) {
return callback(err);
}
- db.sortedSetAdd('categories:cid', data.order, cid);
-
callback(null, category);
});
});
diff --git a/src/user.js b/src/user.js
index a4920e14da..74299cb8bf 100644
--- a/src/user.js
+++ b/src/user.js
@@ -148,7 +148,7 @@ var async = require('async'),
async.parallel({
userData: function(next) {
- User.getUserFields(uid, ['banned', 'lastposttime', 'joindate', 'email', 'email:confirmed'], next);
+ User.getUserFields(uid, ['banned', 'lastposttime', 'joindate', 'email', 'email:confirmed', 'reputation'], next);
},
exists: function(next) {
db.exists('user:' + uid, next);
@@ -185,9 +185,12 @@ var async = require('async'),
var lastposttime = userData.lastposttime || 0;
- if (now - parseInt(lastposttime, 10) < parseInt(meta.config.postDelay, 10) * 1000) {
+ if (parseInt(meta.config.newbiePostDelay, 10) > 0 && parseInt(meta.config.newbiePostDelayThreshold, 10) > parseInt(userData.reputation, 10) && now - parseInt(lastposttime, 10) < parseInt(meta.config.newbiePostDelay, 10) * 1000) {
+ return callback(new Error('[[error:too-many-posts-newbie, ' + meta.config.postDelay + ', ' + meta.config.newbiePostDelayThreshold + ']]'));
+ } else if (now - parseInt(lastposttime, 10) < parseInt(meta.config.postDelay, 10) * 1000) {
return callback(new Error('[[error:too-many-posts, ' + meta.config.postDelay + ']]'));
}
+
callback();
});
};
diff --git a/src/views/admin/settings/post.tpl b/src/views/admin/settings/post.tpl
index a451e701e2..af1b927fbe 100644
--- a/src/views/admin/settings/post.tpl
+++ b/src/views/admin/settings/post.tpl
@@ -13,11 +13,34 @@
- Seconds between Posts
- Seconds before new user can post
- Minimum Title Length
- Maximum Title Length
- Minimum Post Length
+