From 65989c85fc8227b8c2fd0c405ec3520f9c5dd512 Mon Sep 17 00:00:00 2001 From: fatchan Date: Sat, 20 Apr 2019 19:13:50 +0000 Subject: [PATCH 1/3] sticky, lock, sage + changed action handling significantly to combine queries --- controllers/forms.js | 163 +++++++++++++++---- db/posts.js | 83 +--------- gulp/res/img/locked.svg | 48 ++++++ gulp/res/img/saged.svg | 4 + gulp/res/img/sticky.svg | 240 ++++++++++++++++++++++++++++ helpers/actionchecker.js | 1 + models/forms/ban-poster.js | 7 +- models/forms/delete-post.js | 2 +- models/forms/deletepostsfiles.js | 22 +-- models/forms/dismiss-report.js | 21 ++- models/forms/dismissglobalreport.js | 23 ++- models/forms/globalreportpost.js | 19 ++- models/forms/lockposts.js | 23 +++ models/forms/make-post.js | 20 ++- models/forms/report-post.js | 14 +- models/forms/sageposts.js | 23 +++ models/forms/spoiler-post.js | 33 ++-- models/forms/stickyposts.js | 23 +++ views/includes/actionfooter.pug | 3 + views/mixins/post.pug | 7 + 20 files changed, 599 insertions(+), 180 deletions(-) create mode 100644 gulp/res/img/locked.svg create mode 100644 gulp/res/img/saged.svg create mode 100644 gulp/res/img/sticky.svg create mode 100644 models/forms/lockposts.js create mode 100644 models/forms/sageposts.js create mode 100644 models/forms/stickyposts.js 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 @@ + + + +image/svg+xml \ 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + 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 From 20e3a8a05387c86f9993529c0ffc39d788c36c00 Mon Sep 17 00:00:00 2001 From: fatchan Date: Sat, 20 Apr 2019 19:46:27 +0000 Subject: [PATCH 2/3] fix invisible sage icon, fix heights --- views/mixins/post.pug | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/views/mixins/post.pug b/views/mixins/post.pug index 8337b882..7296a149 100644 --- a/views/mixins/post.pug +++ b/views/mixins/post.pug @@ -23,11 +23,11 @@ mixin post(post, truncate, manage=false, globalmanage=false) span: a(href=postURL) ##{post.postId} if !post.thread if post.sticky - object(data='/img/sticky.svg' width='16' height='16') + img(src='/img/sticky.svg' height='14') if post.saged - object(data='/img/saged.svg' width='16' height='16') + img(src='/img/saged.svg' height='12') if post.locked - object(data='/img/locked.svg' width='16' height='16') + img(src='/img/locked.svg' height='16') .post-data if post.files.length > 0 .post-files From 6a24dac9bc3f7c0bbac9c092dab980c8700947ff Mon Sep 17 00:00:00 2001 From: fatchan Date: Sun, 21 Apr 2019 00:41:41 +0000 Subject: [PATCH 3/3] style touch ups --- gulp/res/css/style.css | 7 ++----- server.js | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/gulp/res/css/style.css b/gulp/res/css/style.css index 030aa04b..a0ff8e71 100644 --- a/gulp/res/css/style.css +++ b/gulp/res/css/style.css @@ -148,7 +148,7 @@ span { margin: 10px 0; } -.post-container, .pages { +.post-container, .pages, .toggle-label { background: #D6DAF0; border-color: #B7C5D9; border-width: 0 1px 1px 0; @@ -170,7 +170,7 @@ span { } .actions label { - margin: 2px 0; + padding: 2px 0; } .toggle-label:hover { @@ -178,11 +178,8 @@ span { } .toggle-label { - background: #D6DAF0; padding: 10px; - border-radius: 3px; text-align: center; - border: 1px solid lightgray; max-width: 100%; box-sizing: border-box; display: flex; diff --git a/server.js b/server.js index 1502d89f..fddc2577 100644 --- a/server.js +++ b/server.js @@ -53,7 +53,7 @@ const express = require('express') // use pug view engine app.set('view engine', 'pug'); app.set('views', path.join(__dirname, 'views/pages')); - //app.enable('view cache'); + app.enable('view cache'); // routes app.use('/forms', require(__dirname+'/controllers/forms.js'))