diff --git a/controllers/forms.js b/controllers/forms.js
index 919f2eb1..0e3b3e4b 100644
--- a/controllers/forms.js
+++ b/controllers/forms.js
@@ -6,6 +6,7 @@ const express = require('express')
, Posts = require(__dirname+'/../db/posts.js')
, Trips = require(__dirname+'/../db/trips.js')
, Bans = require(__dirname+'/../db/bans.js')
+ , Mongo = require(__dirname+'/../db/db.js')
, banPoster = require(__dirname+'/../models/forms/ban-poster.js')
, removeBans = require(__dirname+'/../models/forms/removebans.js')
, makePost = require(__dirname+'/../models/forms/make-post.js')
@@ -13,6 +14,9 @@ const express = require('express')
, deleteBanners = require(__dirname+'/../models/forms/deletebanners.js')
, deletePosts = require(__dirname+'/../models/forms/delete-post.js')
, spoilerPosts = require(__dirname+'/../models/forms/spoiler-post.js')
+ , stickyPosts = require(__dirname+'/../models/forms/stickyposts.js')
+ , sagePosts = require(__dirname+'/../models/forms/sageposts.js')
+ , lockPosts = require(__dirname+'/../models/forms/lockposts.js')
, deletePostsFiles = require(__dirname+'/../models/forms/deletepostsfiles.js')
, reportPosts = require(__dirname+'/../models/forms/report-post.js')
, globalReportPosts = require(__dirname+'/../models/forms/globalreportpost.js')
@@ -25,9 +29,7 @@ const express = require('express')
, checkPerms = require(__dirname+'/../helpers/hasperms.js')
, numberConverter = require(__dirname+'/../helpers/number-converter.js')
, banCheck = require(__dirname+'/../helpers/bancheck.js')
- , actionChecker = require(__dirname+'/../helpers/actionchecker.js')
- , actions = ['report', 'global_report', 'spoiler', 'delete', 'delete_file', 'dismiss', 'global_dismiss', 'ban', 'global_ban']
- , authActions = ['dismiss', 'global_dismiss', 'ban', 'global_ban'];
+ , actionChecker = require(__dirname+'/../helpers/actionchecker.js');
// login to account
router.post('/login', (req, res, next) => {
@@ -331,14 +333,20 @@ router.post('/board/:board/actions', Boards.exists, banCheck, numberConverter, a
})
}
- let passwordPosts = posts;
+ //get the ids
+ const postMongoIds = posts.map(post => Mongo.ObjectId(post._id));
+ let passwordPostMongoIds = [];
+ let passwordPosts = [];
if (!hasPerms && anyPasswords) {
- //if any actions require passwords, filter to ones with correct password
+ //just to avoid multiple filters and mapping, do it all here
passwordPosts = posts.filter(post => {
- return post.password != null
- && post.password.length > 0
- && post.password == req.body.password
- });
+ if (post.password != null
+ && post.password.length > 0
+ && post.password == req.body.password) {
+ passwordPostMongoIds.push(Mongo.ObjectId(post._id))
+ return true;
+ }
+ });
if (passwordPosts.length === 0) {
return res.status(403).render('message', {
'title': 'Forbidden',
@@ -346,40 +354,116 @@ router.post('/board/:board/actions', Boards.exists, banCheck, numberConverter, a
'redirect': `/${req.params.board}`
});
}
+ } else {
+ passwordPosts = posts;
+ passwordPostMongoIds = postMongoIds;
}
const messages = [];
+ const combinedQuery = {};
+ const passwordCombinedQuery = {};
try {
if (hasPerms) {
// if getting global banned, board ban doesnt matter
if (req.body.global_ban) {
- messages.push((await banPoster(req, res, next, null, posts)));
+ const { message } = await banPoster(req, res, next, null, posts);
+ messages.push(message);
} else if (req.body.ban) {
- messages.push((await banPoster(req, res, next, req.params.board, posts)));
+ const { message } = await banPoster(req, res, next, req.params.board, posts);
+ messages.push(message);
}
}
if (req.body.delete) {
- messages.push((await deletePosts(req, res, next, passwordPosts)));
+ const { message } = await deletePosts(req, res, next, passwordPosts);
+ messages.push(message);
} else {
// if it was getting deleted, we cant do any of these
if (req.body.delete_file) {
- messages.push((await deletePostsFiles(req, res, next, passwordPosts)));
+ const { message, action, query } = await deletePostsFiles(passwordPosts);
+ if (action) {
+ passwordCombinedQuery[action] = { ...passwordCombinedQuery[action], ...query}
+ }
+ messages.push(message);
} else if (req.body.spoiler) {
- messages.push((await spoilerPosts(req, res, next, passwordPosts)));
+ const { message, action, query } = spoilerPosts(passwordPosts);
+ if (action) {
+ passwordCombinedQuery[action] = { ...passwordCombinedQuery[action], ...query}
+ }
+ messages.push(message);
+ }
+ if (hasPerms) {
+ //lock, sticky, sage
+ if (req.body.sage) {
+ const { message, action, query } = sagePosts(posts);
+ if (action) {
+ combinedQuery[action] = { ...combinedQuery[action], ...query}
+ }
+ messages.push(message);
+ }
+ if (req.body.lock) {
+ const { message, action, query } = lockPosts(posts);
+ if (action) {
+ combinedQuery[action] = { ...combinedQuery[action], ...query}
+ }
+ messages.push(message);
+ }
+ if (req.body.sticky) {
+ const { message, action, query } = stickyPosts(posts);
+ if (action) {
+ combinedQuery[action] = { ...combinedQuery[action], ...query}
+ }
+ messages.push(message);
+ }
}
// cannot report and dismiss at same time
if (req.body.report) {
- messages.push((await reportPosts(req, res, next)));
+ const { message, action, query } = reportPosts(req, posts);
+ if (action) {
+ combinedQuery[action] = { ...combinedQuery[action], ...query}
+ }
+ messages.push(message);
} else if (hasPerms && req.body.dismiss) {
- messages.push((await dismissReports(req, res, next)));
+ const { message, action, query } = dismissReports(posts);
+ if (action) {
+ combinedQuery[action] = { ...combinedQuery[action], ...query}
+ }
+ messages.push(message);
}
// cannot report and dismiss at same time
if (req.body.global_report) {
- messages.push((await globalReportPosts(req, res, next, posts)));
+ const { message, action, query } = globalReportPosts(req, posts);
+ if (action) {
+ combinedQuery[action] = { ...combinedQuery[action], ...query}
+ }
+ messages.push(message);
} else if (hasPerms && req.body.global_dismiss) {
- messages.push((await dismissGlobalReports(req, res, next, posts)));
+ const { message, action, query } = dismissGlobalReports(posts);
+ if (action) {
+ combinedQuery[action] = { ...combinedQuery[action], ...query}
+ }
+ messages.push(message);
}
}
+ const dbPromises = []
+ if (Object.keys(combinedQuery).length > 0) {
+ dbPromises.push(
+ Posts.db.updateMany({
+ '_id': {
+ '$in': postMongoIds
+ }
+ }, combinedQuery)
+ )
+ }
+ if (Object.keys(passwordCombinedQuery).length > 0) {
+ dbPromises.push(
+ Posts.db.updateMany({
+ '_id': {
+ '$in': passwordPostMongoIds
+ }
+ }, passwordCombinedQuery)
+ )
+ }
+ await Promise.all(dbPromises);
} catch (err) {
return next(err);
}
@@ -460,7 +544,7 @@ router.post('/global/actions', checkPermsMiddleware, numberConverter, async(req,
return res.status(400).render('message', {
'title': 'Bad request',
'errors': errors,
- 'redirect': `/${req.params.board}`
+ 'redirect': '/globalmanage'
})
}
@@ -474,39 +558,48 @@ router.post('/global/actions', checkPermsMiddleware, numberConverter, async(req,
})
}
+ //get the ids
+ const postMongoIds = posts.map(post => Mongo.ObjectId(post._id));
const messages = [];
+ const combinedQuery = {};
try {
- //ban before delete
if (req.body.global_ban) {
- messages.push((await banPoster(req, res, next, null, posts)));
+ const { message } = await banPoster(req, res, next, null, posts);
+ messages.push(message);
}
- // if its getting deleted, we cant do anythign else
if (req.body.delete) {
- messages.push((await deletePosts(req, res, next, posts)));
- } else{
+ const { message } = await deletePosts(req, res, next, posts);
+ messages.push(message);
+ } else {
+ // if it was getting deleted, we cant do any of these
if (req.body.delete_file) {
- messages.push((await deletePostsFiles(req, res, next, posts)));
- } else if (req.body.spoiler) {
- // if it was getting deleted, we cant spoiler
- messages.push((await spoilerPosts(req, res, next, posts)));
+ const { message, action, query } = await deletePostsFiles(posts);
+ if (action) {
+ combinedQuery[action] = { ...combinedQuery[action], ...query}
+ }
+ messages.push(message);
}
if (req.body.global_dismiss) {
- messages.push((await dismissGlobalReports(req, res, next, posts)));
+ const { message, action, query } = dismissGlobalReports(posts);
+ if (action) {
+ combinedQuery[action] = { ...combinedQuery[action], ...query}
+ }
+ messages.push(message);
}
}
+ await Posts.db.updateMany({
+ '_id': {
+ '$in': postMongoIds
+ }
+ }, combinedQuery)
} catch (err) {
- if (err.status) {
- // return out special error
- return res.status(err.status).render('message', err.message);
- }
- //some other error, use regular error handler
return next(err);
}
return res.render('message', {
'title': 'Success',
'messages': messages,
- 'redirect': `/${req.params.board}`
+ 'redirect': '/globalmanage'
});
});
diff --git a/db/posts.js b/db/posts.js
index efc3ced6..007bb106 100644
--- a/db/posts.js
+++ b/db/posts.js
@@ -23,7 +23,8 @@ module.exports = {
'globalreports': 0,
}
}).sort({
- 'bumped': -1
+ 'sticky': -1,
+ 'bumped': -1,
}).skip(10*(page-1)).limit(10).toArray();
// add last 5 posts in reverse order to preview
@@ -198,7 +199,7 @@ module.exports = {
}).toArray();
},
- insertOne: async (board, data) => {
+ insertOne: async (board, data, thread) => {
if (data.thread !== null) {
//if not a thread, update reply and image count on op document;
@@ -213,7 +214,7 @@ module.exports = {
}
}
// bump thread if name not sage
- if (data.email !== 'sage') {
+ if (data.email !== 'sage' && !thread.saged) {
query['$set'] = {
'bumped': Date.now()
}
@@ -233,31 +234,6 @@ module.exports = {
},
- reportMany: (board, ids, report) => {
- return db.updateMany({
- 'postId': {
- '$in': ids
- },
- 'board': board
- }, {
- '$push': {
- 'reports': report
- }
- });
- },
-
- globalReportMany: (ids, report) => {
- return db.updateMany({
- '_id': {
- '$in': ids
- },
- }, {
- '$push': {
- 'globalreports': report
- }
- });
- },
-
getReports: (board) => {
return db.find({
'reports.0': {
@@ -274,19 +250,6 @@ module.exports = {
}).toArray();
},
- dismissReports: (board, ids) => {
- return db.updateMany({
- 'postId': {
- '$in': ids
- },
- 'board': board
- }, {
- '$set': {
- 'reports': []
- }
- });
- },
-
getGlobalReports: () => {
return db.find({
'globalreports.0': {
@@ -302,34 +265,10 @@ module.exports = {
}).toArray();
},
- dismissGlobalReports: (ids) => {
- return db.updateMany({
- '_id': {
- '$in': ids
- },
- }, {
- '$set': {
- 'globalreports': []
- }
- });
- },
-
deleteOne: (board, options) => {
return db.deleteOne(options);
},
- deleteFilesMany: (ids) => {
- return db.updateMany({
- '_id': {
- '$in': ids
- }
- }, {
- '$set': {
- 'files': []
- }
- });
- },
-
deleteMany: (ids) => {
return db.deleteMany({
@@ -340,20 +279,6 @@ module.exports = {
},
- spoilerMany: (ids) => {
-
- return db.updateMany({
- '_id': {
- '$in': ids
- }
- }, {
- '$set': {
- 'spoiler': true
- }
- });
-
- },
-
deleteAll: (board) => {
return db.deleteMany({
'board': board
diff --git a/gulp/res/img/locked.svg b/gulp/res/img/locked.svg
new file mode 100644
index 00000000..f46b3e06
--- /dev/null
+++ b/gulp/res/img/locked.svg
@@ -0,0 +1,48 @@
+
+
+
+
\ No newline at end of file
diff --git a/gulp/res/img/saged.svg b/gulp/res/img/saged.svg
new file mode 100644
index 00000000..7baba2c7
--- /dev/null
+++ b/gulp/res/img/saged.svg
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/gulp/res/img/sticky.svg b/gulp/res/img/sticky.svg
new file mode 100644
index 00000000..6b760b58
--- /dev/null
+++ b/gulp/res/img/sticky.svg
@@ -0,0 +1,240 @@
+
+
+
+
diff --git a/helpers/actionchecker.js b/helpers/actionchecker.js
index c97743b9..5a823e41 100644
--- a/helpers/actionchecker.js
+++ b/helpers/actionchecker.js
@@ -3,6 +3,7 @@
const actions = [
{name:'lock', global:false, auth:true, passwords:false},
{name:'sticky', global:false, auth:true, passwords:false},
+ {name:'sage', global:false, auth:true, passwords:false},
{name:'report', global:false, auth:false, passwords:false},
{name:'global_report', global:false, auth:false, passwords:false},
{name:'spoiler', global:true, auth:false, passwords:true},
diff --git a/models/forms/ban-poster.js b/models/forms/ban-poster.js
index ace121ab..49617116 100644
--- a/models/forms/ban-poster.js
+++ b/models/forms/ban-poster.js
@@ -1,9 +1,6 @@
'use strict';
-const uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js')
- , hasPerms = require(__dirname+'/../../helpers/hasperms.js')
- , Bans = require(__dirname+'/../../db/bans.js')
- , Posts = require(__dirname+'/../../db/posts.js');
+const Bans = require(__dirname+'/../../db/bans.js')
module.exports = async (req, res, next, board, posts) => {
@@ -21,6 +18,6 @@ module.exports = async (req, res, next, board, posts) => {
const bannedIps = await Bans.insertMany(bans).then(result => result.insertedCount);
- return `Banned ${bannedIps} ips`;
+ return { message:`Banned ${bannedIps} ips` };
}
diff --git a/models/forms/delete-post.js b/models/forms/delete-post.js
index 7d0d3fca..e78e2b13 100644
--- a/models/forms/delete-post.js
+++ b/models/forms/delete-post.js
@@ -49,6 +49,6 @@ module.exports = async (req, res, next, posts) => {
}));
//hooray!
- return `Deleted ${boardThreads.length} threads and ${deletedPosts-boardThreads.length} posts`
+ return { message:`Deleted ${boardThreads.length} threads and ${deletedPosts-boardThreads.length} posts` };
}
diff --git a/models/forms/deletepostsfiles.js b/models/forms/deletepostsfiles.js
index ec49f162..06fbd7af 100644
--- a/models/forms/deletepostsfiles.js
+++ b/models/forms/deletepostsfiles.js
@@ -5,11 +5,8 @@ const path = require('path')
, fs = require('fs')
, unlink = util.promisify(fs.unlink)
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js')
- , hasPerms = require(__dirname+'/../../helpers/hasperms.js')
- , Mongo = require(__dirname+'/../../db/db.js')
- , Posts = require(__dirname+'/../../db/posts.js');
-module.exports = async (req, res, next, posts) => {
+module.exports = async (posts) => {
//get filenames from all the posts
let fileNames = [];
@@ -26,11 +23,18 @@ module.exports = async (req, res, next, posts) => {
])
}));
- //delete posts from DB
- const postMongoIds = posts.map(post => Mongo.ObjectId(post._id))
- const deletedFilesPosts = await Posts.deleteFilesMany(postMongoIds).then(result => result.deletedCount);
+ if (fileNames.length === 0) {
+ return {
+ message: 'No files to delete'
+ }
+ }
- //hooray!
- return `Deleted ${fileNames.length} files across ${deletedFilesPosts} posts`
+ return {
+ message:`Deleted ${fileNames.length} file(s) across ${posts.length} post(s)`,
+ action:'$set',
+ query: {
+ 'files': []
+ }
+ };
}
diff --git a/models/forms/dismiss-report.js b/models/forms/dismiss-report.js
index 090416b0..2b7b1a86 100644
--- a/models/forms/dismiss-report.js
+++ b/models/forms/dismiss-report.js
@@ -1,12 +1,23 @@
'use strict';
-const Posts = require(__dirname+'/../../db/posts.js')
- , hasPerms = require(__dirname+'/../../helpers/hasperms.js');
+module.exports = (posts) => {
-module.exports = async (req, res, next) => {
+ const filteredposts = posts.filter(post => {
+ return post.reports.length > 0
+ })
- const dismissedReports = await Posts.dismissReports(req.params.board, req.body.checkedposts).then(result => result.modifiedCount);
+ if (filteredposts.length === 0) {
+ return {
+ message: 'No report(s) to dismiss'
+ }
+ }
- return `Dismissed ${dismissedReports} reports successfully`;
+ return {
+ message: 'Dismissed reports',
+ action: '$set',
+ query: {
+ 'reports': []
+ }
+ };
}
diff --git a/models/forms/dismissglobalreport.js b/models/forms/dismissglobalreport.js
index 8d6ec4f9..2e04f54a 100644
--- a/models/forms/dismissglobalreport.js
+++ b/models/forms/dismissglobalreport.js
@@ -1,14 +1,23 @@
'use strict';
-const Mongo = require(__dirname+'/../../db/db.js')
- , Posts = require(__dirname+'/../../db/posts.js')
- , hasPerms = require(__dirname+'/../../helpers/hasperms.js');
+module.exports = (posts) => {
-module.exports = async (req, res, next, posts) => {
+ const filteredposts = posts.filter(post => {
+ return post.globalreports.length > 0
+ })
- const postMongoIds = posts.map(post => Mongo.ObjectId(post._id))
- const dismissedCount = await Posts.dismissGlobalReports(postMongoIds).then(result => result.modifiedCount);
+ if (filteredposts.length === 0) {
+ return {
+ message: 'No global report(s) to dismiss'
+ }
+ }
- return `Dismissed ${dismissedCount} reports successfully`;
+ return {
+ message: 'Dismissed global report(s)',
+ action: '$set',
+ query: {
+ 'globalreports': []
+ }
+ };
}
diff --git a/models/forms/globalreportpost.js b/models/forms/globalreportpost.js
index 278f312c..2c10f806 100644
--- a/models/forms/globalreportpost.js
+++ b/models/forms/globalreportpost.js
@@ -1,9 +1,8 @@
'use strict';
-const Mongo = require(__dirname+'/../../db/db.js')
- , Posts = require(__dirname+'/../../db/posts.js');
+const Posts = require(__dirname+'/../../db/posts.js');
-module.exports = async (req, res, next, posts) => {
+module.exports = (req, posts) => {
const ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
const report = {
@@ -12,12 +11,12 @@ module.exports = async (req, res, next, posts) => {
'ip': ip
}
- const ids = posts.map(p => Mongo.ObjectId(p._id))
-
- //push the report to all checked posts
- const reportedPosts = await Posts.globalReportMany(ids, report).then(result => result.modifiedCount);
-
- //hooray!
- return `Global reported ${reportedPosts} posts successfully`
+ return {
+ message: `Global reported ${posts.length} post(s)`,
+ action: '$push',
+ query: {
+ 'globalreports': report
+ }
+ };
}
diff --git a/models/forms/lockposts.js b/models/forms/lockposts.js
new file mode 100644
index 00000000..b2fea9bc
--- /dev/null
+++ b/models/forms/lockposts.js
@@ -0,0 +1,23 @@
+'use strict';
+
+module.exports = (posts) => {
+
+ const filteredposts = posts.filter(post => {
+ return !post.locked
+ })
+
+ if (filteredposts.length === 0) {
+ return {
+ message: 'Post(s) already locked',
+ };
+ }
+
+ return {
+ message: `Locked ${filteredposts.length} post(s)`,
+ action: '$set',
+ query: {
+ 'locked': true
+ }
+ };
+
+}
diff --git a/models/forms/make-post.js b/models/forms/make-post.js
index 37b7faf4..3283cc54 100644
--- a/models/forms/make-post.js
+++ b/models/forms/make-post.js
@@ -19,7 +19,7 @@ const uuidv4 = require('uuid/v4')
}
}
, nameRegex = /^(?[^\s#]+)?(?:##(?[^ ]{1}[^\s#]+))?(?:## (?[^\s#]+))?$/
- , hasPerms = require(__dirname+'/../../helpers/hasperms.js')
+ , permsCheck = require(__dirname+'/../../helpers/hasperms.js')
, fileUpload = require(__dirname+'/../../helpers/files/file-upload.js')
, fileCheckMimeType = require(__dirname+'/../../helpers/files/file-check-mime-types.js')
, imageThumbnail = require(__dirname+'/../../helpers/files/image-thumbnail.js')
@@ -33,8 +33,9 @@ module.exports = async (req, res, next, numFiles) => {
// check if this is responding to an existing thread
let redirect = `/${req.params.board}`
let salt = '';
+ let thread;
+ let hasPerms = permsCheck(req, res);
if (req.body.thread) {
- let thread;
try {
thread = await Posts.getPost(req.params.board, req.body.thread, true);
} catch (err) {
@@ -47,6 +48,13 @@ module.exports = async (req, res, next, numFiles) => {
'redirect': redirect
});
}
+ if (thread.locked && !hasPerms) {
+ return res.status(400).render('message', {
+ 'title': 'Bad request',
+ 'message': 'Thread Locked',
+ 'redirect': redirect
+ });
+ }
salt = thread.salt;
redirect += `/thread/${req.body.thread}`
}
@@ -151,7 +159,7 @@ module.exports = async (req, res, next, numFiles) => {
tripcode = `!!${(await getTripCode(groups.tripcode))}`;
}
//capcode
- if (groups.capcode && hasPerms(req, res)) {
+ if (groups.capcode && hasPerms) {
// TODO: add proper code for different capcodes
capcode = groups.capcode;
}
@@ -185,13 +193,17 @@ module.exports = async (req, res, next, numFiles) => {
'files': files,
'reports': [],
'globalreports': [],
+ 'sticky': false,
+ 'locked': false,
+ 'saged': false,
+ 'cyclic': false,
'replyposts': 0,
'replyimages': 0,
};
let postId;
try {
- postId = await Posts.insertOne(req.params.board, data);
+ postId = await Posts.insertOne(req.params.board, data, thread);
} catch (err) {
return next(err);
}
diff --git a/models/forms/report-post.js b/models/forms/report-post.js
index 49bb7efb..c5a0f4de 100644
--- a/models/forms/report-post.js
+++ b/models/forms/report-post.js
@@ -2,7 +2,7 @@
const Posts = require(__dirname+'/../../db/posts.js');
-module.exports = async (req, res, next) => {
+module.exports = (req, posts) => {
const ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
const report = {
@@ -11,10 +11,12 @@ module.exports = async (req, res, next) => {
'ip': ip
}
- //push the report to all checked posts
- const reportedCount = await Posts.reportMany(req.params.board, req.body.checkedposts, report).then(result => result.modifiedCount);
-
- //hooray!
- return `Reported ${reportedCount} posts successfully`
+ return {
+ message: `Reported ${posts.length} post(s)`,
+ action: '$push',
+ query: {
+ 'reports': report
+ }
+ };
}
diff --git a/models/forms/sageposts.js b/models/forms/sageposts.js
new file mode 100644
index 00000000..522394b2
--- /dev/null
+++ b/models/forms/sageposts.js
@@ -0,0 +1,23 @@
+'use strict';
+
+module.exports = (posts) => {
+
+ const filteredposts = posts.filter(post => {
+ return !post.saged
+ })
+
+ if (filteredposts.length === 0) {
+ return {
+ message: 'Post(s) already saged',
+ };
+ }
+
+ return {
+ message: `Saged ${filteredposts.length} post(s)`,
+ action: '$set',
+ query: {
+ 'saged': true
+ }
+ };
+
+}
diff --git a/models/forms/spoiler-post.js b/models/forms/spoiler-post.js
index 1f1eac0f..f974b492 100644
--- a/models/forms/spoiler-post.js
+++ b/models/forms/spoiler-post.js
@@ -1,29 +1,24 @@
'use strict';
-const path = require('path')
- , util = require('util')
- , fs = require('fs')
- , unlink = util.promisify(fs.unlink)
- , uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js')
- , hasPerms = require(__dirname+'/../../helpers/hasperms.js')
- , Mongo = require(__dirname+'/../../db/db.js')
- , Posts = require(__dirname+'/../../db/posts.js');
-
-module.exports = async (req, res, next, posts) => {
+module.exports = (posts) => {
// filter to ones not spoilered
- posts = posts.filter(post => {
+ const filteredPosts = posts.filter(post => {
return !post.spoiler
});
- if (posts.length === 0) {
- return 'Posts already spoilered';
- }
- // spoiler posts
- const postMongoIds = posts.map(post => Mongo.ObjectId(post._id));
- const spoileredPosts = await Posts.spoilerMany(postMongoIds).then(result => result.modifiedCount);
+ if (filteredPosts.length === 0) {
+ return {
+ message:'Post(s) already spoilered'
+ };
+ }
- //hooray!
- return `Spoilered ${spoileredPosts} posts`
+ return {
+ message: `Spoilered ${filteredPosts.length} post(s)`,
+ action: '$set',
+ query: {
+ 'spoiler': true
+ }
+ };
}
diff --git a/models/forms/stickyposts.js b/models/forms/stickyposts.js
new file mode 100644
index 00000000..4d5a3246
--- /dev/null
+++ b/models/forms/stickyposts.js
@@ -0,0 +1,23 @@
+'use strict';
+
+module.exports = (posts) => {
+
+ const filteredposts = posts.filter(post => {
+ return !post.sticky
+ })
+
+ if (filteredposts.length === 0) {
+ return {
+ message: 'Post(s) already stickied',
+ };
+ }
+
+ return {
+ message: `Stickied ${filteredposts.length} post(s)`,
+ action: '$set',
+ query: {
+ 'sticky': true
+ }
+ };
+
+}
diff --git a/views/includes/actionfooter.pug b/views/includes/actionfooter.pug
index a66bb96d..40f3fb80 100644
--- a/views/includes/actionfooter.pug
+++ b/views/includes/actionfooter.pug
@@ -30,6 +30,9 @@ label.toggle-label Toggle Post Actions
label
input.post-check(type='checkbox', name='lock' value=1)
| Lock
+ label
+ input.post-check(type='checkbox', name='sage' value=1)
+ | Sage
label
input.post-check(type='checkbox', name='ban' value=1)
| Ban Poster
diff --git a/views/mixins/post.pug b/views/mixins/post.pug
index 3e0590e1..8337b882 100644
--- a/views/mixins/post.pug
+++ b/views/mixins/post.pug
@@ -21,6 +21,13 @@ mixin post(post, truncate, manage=false, globalmanage=false)
span #{post.date.toLocaleString()}
span.user-id(style=`background: #${post.userId}`) #{post.userId}
span: a(href=postURL) ##{post.postId}
+ if !post.thread
+ if post.sticky
+ object(data='/img/sticky.svg' width='16' height='16')
+ if post.saged
+ object(data='/img/saged.svg' width='16' height='16')
+ if post.locked
+ object(data='/img/locked.svg' width='16' height='16')
.post-data
if post.files.length > 0
.post-files