diff --git a/public/language/en-GB/flags.json b/public/language/en-GB/flags.json index de083196e7..ad8456ebf6 100644 --- a/public/language/en-GB/flags.json +++ b/public/language/en-GB/flags.json @@ -1,5 +1,6 @@ { "quick-filters": "Quick Filters", + "state": "State", "reporter": "Reporter", "reported-at": "Reported At", "no-flags": "Hooray! No flags found." diff --git a/src/controllers/mods.js b/src/controllers/mods.js index 2a1aad09dc..f5a6e9b06d 100644 --- a/src/controllers/mods.js +++ b/src/controllers/mods.js @@ -6,15 +6,19 @@ var user = require('../user'); var flags = require('../flags'); // var adminFlagsController = require('./admin/flags'); -var modsController = {}; +var modsController = { + flags: {} +}; -modsController.flagged = function (req, res, next) { +modsController.flags.list = function (req, res, next) { async.parallel({ isAdminOrGlobalMod: async.apply(user.isAdminOrGlobalMod, req.uid), moderatedCids: async.apply(user.getModeratedCids, req.uid) }, function (err, results) { - if (err || !(results.isAdminOrGlobalMod || !!results.moderatedCids.length)) { + if (err) { return next(err); + } else if (!(results.isAdminOrGlobalMod || !!results.moderatedCids.length)) { + return next(new Error('[[error:no-privileges]]')); } if (!results.isAdminOrGlobalMod && results.moderatedCids.length) { @@ -22,11 +26,27 @@ modsController.flagged = function (req, res, next) { } flags.list({}, function(err, flags) { - res.render('flags', { + res.render('flags/list', { flags: flags }); }); }); }; +modsController.flags.detail = function (req, res, next) { + async.parallel({ + isAdminOrGlobalMod: async.apply(user.isAdminOrGlobalMod, req.uid), + moderatedCids: async.apply(user.getModeratedCids, req.uid), + flagData: async.apply(flags.get, req.params.flagId) + }, function (err, results) { + if (err || !results.flagData) { + return next(err || new Error('[[error:invalid-data]]')); + } else if (!(results.isAdminOrGlobalMod || !!results.moderatedCids.length)) { + return next(new Error('[[error:no-privileges]]')); + } + + res.render('flags/detail', results.flagData); + }); +}; + module.exports = modsController; diff --git a/src/flags.js b/src/flags.js index bdf1ac37bb..8734f811a8 100644 --- a/src/flags.js +++ b/src/flags.js @@ -18,6 +18,30 @@ var Flags = { } }; +Flags.get = function (flagId, callback) { + async.waterfall([ + async.apply(async.parallel, { + base: async.apply(db.getObject.bind(db), 'flag:' + flagId), + history: async.apply(db.getSortedSetRevRange.bind(db), 'flag:' + flagId + ':history', 0, -1), + notes: async.apply(db.getSortedSetRevRange.bind(db), 'flag:' + flagId + ':notes', 0, -1) + }), + function (data, next) { + user.getUserFields(data.base.uid, ['username', 'picture'], function (err, userObj) { + next(err, Object.assign(data.base, { + history: data.history, + notes: data.notes, + reporter: { + username: userObj.username, + picture: userObj.picture, + 'icon:bgColor': userObj['icon:bgColor'], + 'icon:text': userObj['icon:text'] + } + })); + }); + } + ], callback); +}; + Flags.list = function (filters, callback) { if (typeof filters === 'function' && !callback) { callback = filters; @@ -33,7 +57,7 @@ Flags.list = function (filters, callback) { function (flagObj, next) { user.getUserFields(flagObj.uid, ['username', 'picture'], function (err, userObj) { next(err, Object.assign(flagObj, { - user: { + reporter: { username: userObj.username, picture: userObj.picture, 'icon:bgColor': userObj['icon:bgColor'], @@ -63,7 +87,7 @@ Flags.list = function (filters, callback) { } next(null, Object.assign(flagObj, { - target_readable: flagObj.type.charAt(0).toUpperCase() + flagObj.type.slice(1) + ' ' + flagObj.id, + target_readable: flagObj.type.charAt(0).toUpperCase() + flagObj.type.slice(1) + ' ' + flagObj.targetId, datetimeISO: new Date(parseInt(flagObj.datetime, 10)).toISOString() })); }); @@ -95,18 +119,19 @@ Flags.create = function (type, id, uid, reason, callback) { } }); }, - function (next) { - var flagId = utils.generateUUID(); - + async.apply(db.incrObjectField, 'global', 'nextFlagId'), + function (flagId, next) { async.parallel([ async.apply(db.setObject.bind(db), 'flag:' + flagId, Object.assign({}, Flags._defaults, { + flagId: flagId, type: type, - id: id, + targetId: id, description: reason, uid: uid, datetime: Date.now() })), - async.apply(db.sortedSetAdd.bind(db), 'flags:datetime', Date.now(), flagId) + async.apply(db.sortedSetAdd.bind(db), 'flags:datetime', Date.now(), flagId), + async.apply(db.setObjectField.bind(db), 'flagHash:flagId', [type, id, uid].join(':'), flagId) ], next); } ], function (err) { @@ -280,32 +305,33 @@ Flags.dismissByUid = function (uid, callback) { }); }; -Flags.get = function (set, cid, uid, start, stop, callback) { - async.waterfall([ - function (next) { - if (Array.isArray(set)) { - db.getSortedSetRevIntersect({sets: set, start: start, stop: -1, aggregate: 'MAX'}, next); - } else { - db.getSortedSetRevRange(set, start, -1, next); - } - }, - function (pids, next) { - if (cid) { - posts.filterPidsByCid(pids, cid, next); - } else { - process.nextTick(next, null, pids); - } - }, - function (pids, next) { - getFlaggedPostsWithReasons(pids, uid, next); - }, - function (posts, next) { - var count = posts.length; - var end = stop - start + 1; - next(null, {posts: posts.slice(0, stop === -1 ? undefined : end), count: count}); - } - ], callback); -}; +// This is the old method to get list of flags, supercede by Flags.list(); +// Flags.get = function (set, cid, uid, start, stop, callback) { +// async.waterfall([ +// function (next) { +// if (Array.isArray(set)) { +// db.getSortedSetRevIntersect({sets: set, start: start, stop: -1, aggregate: 'MAX'}, next); +// } else { +// db.getSortedSetRevRange(set, start, -1, next); +// } +// }, +// function (pids, next) { +// if (cid) { +// posts.filterPidsByCid(pids, cid, next); +// } else { +// process.nextTick(next, null, pids); +// } +// }, +// function (pids, next) { +// getFlaggedPostsWithReasons(pids, uid, next); +// }, +// function (posts, next) { +// var count = posts.length; +// var end = stop - start + 1; +// next(null, {posts: posts.slice(0, stop === -1 ? undefined : end), count: count}); +// } +// ], callback); +// }; function getFlaggedPostsWithReasons(pids, uid, callback) { async.waterfall([ diff --git a/src/routes/index.js b/src/routes/index.js index 0273160745..f71eac2c62 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -40,7 +40,8 @@ function mainRoutes(app, middleware, controllers) { } function modRoutes(app, middleware, controllers) { - setupPageRoute(app, '/flags', middleware, [], controllers.mods.flagged); + setupPageRoute(app, '/flags', middleware, [], controllers.mods.flags.list); + setupPageRoute(app, '/flags/:flagId', middleware, [], controllers.mods.flags.detail); } function globalModRoutes(app, middleware, controllers) {