v1.18.x
barisusakli 11 years ago
parent c57dc25ea7
commit f6f6ca7f76

@ -5,6 +5,7 @@
@import "./manage/categories";
@import "./manage/groups";
@import "./manage/tags";
@import "./manage/flags";
@import "./manage/users";
@import "./appearance/customise";
@import "./appearance/themes";
@ -23,6 +24,11 @@
padding: 0px 15px;
}
.user-img {
width:24px;
height:24px;
}
.nodebb-logo {
img {
height: 31px;
@ -44,7 +50,7 @@
width: 200px;
height: 100%;
-webkit-transform: translateX(-190px);
transform: translateX(-190px);
@ -81,7 +87,7 @@
max-height: 100%;
cursor: pointer;
max-height: 38px;
&.open {
max-height: 500px;
}

@ -0,0 +1,68 @@
"use strict";
/*global define, socket, app, admin, utils, bootbox, RELATIVE_PATH*/
define('forum/admin/manage/flags', ['forum/infinitescroll', 'admin/selectable'], function(infinitescroll, selectable) {
var Flags = {};
Flags.init = function() {
handleDismiss();
handleDelete();
handleInfiniteScroll();
};
function handleDismiss() {
$('.flags').on('click', '.dismiss', function() {
var btn = $(this);
var pid = btn.siblings('[data-pid]').attr('data-pid');
socket.emit('admin.dismissFlag', pid, function(err) {
done(err, btn);
});
});
}
function handleDelete() {
$('.flags').on('click', '.delete', function() {
var btn = $(this);
var pid = btn.siblings('[data-pid]').attr('data-pid');
var tid = btn.siblings('[data-pid]').attr('data-tid');
socket.emit('posts.delete', {pid: pid, tid: tid}, function(err) {
done(err, btn);
});
});
}
function done(err, btn) {
if (err) {
return app.alertError(err.messaage);
}
btn.parent().fadeOut(function() {
btn.remove();
});
if (!$('.flags [data-pid]').length) {
$('.post-container').text('No flagged posts!');
}
}
function handleInfiniteScroll() {
infinitescroll.init(function(direction) {
if (direction < 0 && !$('.flags').length) {
return;
}
infinitescroll.loadMore('admin.getMoreFlags', $('[data-next]').attr('data-next'), function(data, done) {
if (data.posts && data.posts.length) {
infinitescroll.parseAndTranslate('admin/manage/flags', 'posts', {posts: data.posts}, function(html) {
$('[data-next]').attr('data-next', data.next);
$('.post-container').append(html);
done();
});
} else {
done();
}
});
});
}
return Flags;
});

@ -6,6 +6,7 @@ var async = require('async'),
user = require('../user'),
categories = require('../categories'),
posts = require('../posts'),
topics = require('../topics'),
meta = require('../meta'),
db = require('../database'),
@ -21,6 +22,7 @@ var async = require('async'),
var adminController = {
categories: {},
tags: {},
flags: {},
topics: {},
groups: {},
appearance: {},
@ -154,6 +156,17 @@ adminController.tags.get = function(req, res, next) {
});
};
adminController.flags.get = function(req, res, next) {
var uid = req.user ? parseInt(req.user.uid, 10) : 0;
posts.getFlags(uid, 0, 19, function(err, posts) {
if (err) {
return next(err);
}
res.render('admin/manage/flags', {posts: posts, next: 20});
});
};
adminController.database.get = function(req, res, next) {
db.info(function (err, data) {
res.render('admin/advanced/database', data);

@ -28,6 +28,7 @@ var async = require('async'),
(function(Posts) {
require('./posts/recent')(Posts);
require('./posts/delete')(Posts);
require('./posts/flags')(Posts);
Posts.create = function(data, callback) {
var uid = data.uid,
@ -237,6 +238,7 @@ var async = require('async'),
Posts.getPostSummaryByPids = function(pids, uid, options, callback) {
options.stripTags = options.hasOwnProperty('stripTags') ? options.stripTags : false;
options.parse = options.hasOwnProperty('parse') ? options.parse : true;
options.extraFields = options.hasOwnProperty('extraFields') ? options.extraFields : [];
if (!Array.isArray(pids) || !pids.length) {
return callback(null, []);
@ -246,7 +248,9 @@ var async = require('async'),
return 'post:' + pid;
});
db.getObjectsFields(keys, ['pid', 'tid', 'content', 'uid', 'timestamp', 'deleted'], function(err, posts) {
var fields = ['pid', 'tid', 'content', 'uid', 'timestamp', 'deleted'].concat(options.extraFields);
db.getObjectsFields(keys, fields, function(err, posts) {
if (err) {
return callback(err);
}

@ -0,0 +1,45 @@
'use strict';
var async = require('async'),
db = require('../database');
module.exports = function(Posts) {
Posts.flag = function(pid, callback) {
async.parallel([
function(next) {
db.sortedSetAdd('posts:flagged', Date.now(), pid, next);
},
function(next) {
db.incrObjectField('post:' + pid, 'flags', next);
}
], function(err, results) {
callback(err);
});
};
Posts.dismissFlag = function(pid, callback) {
async.parallel([
function(next) {
db.sortedSetRemove('posts:flagged', pid, next);
},
function(next) {
db.deleteObjectField('post:' + pid, 'flags', next);
}
], function(err, results) {
callback(err);
});
};
Posts.getFlags = function(uid, start, end, callback) {
db.getSortedSetRevRange('posts:flagged', start, end, function(err, pids) {
if (err) {
return callback(err);
}
Posts.getPostSummaryByPids(pids, uid, {stripTags: false, extraFields: ['flags']}, callback);
});
};
};

@ -46,6 +46,8 @@ function addRoutes(router, middleware, controllers) {
router.get('/manage/tags', controllers.admin.tags.get);
router.get('/manage/flags', controllers.admin.flags.get);
router.get('/manage/users', controllers.admin.users.sortByJoinDate);
router.get('/manage/users/search', controllers.admin.users.search);
router.get('/manage/users/latest', controllers.admin.users.sortByJoinDate);

@ -12,6 +12,7 @@ var async = require('async'),
widgets = require('../widgets'),
user = require('../user'),
topics = require('../topics'),
posts = require('../posts'),
categories = require('../categories'),
logger = require('../logger'),
events = require('../events'),
@ -249,4 +250,22 @@ SocketAdmin.getMoreEvents = function(socket, next, callback) {
};
SocketAdmin.dismissFlag = function(socket, pid, callback) {
if (!pid) {
return callback('[[error:invalid-data]]');
}
posts.dismissFlag(pid, callback);
};
SocketAdmin.getMoreFlags = function(socket, after, callback) {
if (!parseInt(after, 10)) {
return callback('[[error:invalid-data]]');
}
after = parseInt(after, 10);
posts.getFlags(socket.uid, after, after + 19, function(err, posts) {
callback(err, {posts: posts, next: after + 20});
});
};
module.exports = SocketAdmin;

@ -322,6 +322,9 @@ SocketPosts.flag = function(socket, pid, callback) {
notifications.push(notification, adminGroup.members, next);
});
},
function(next) {
posts.flag(pid, next);
},
function(next) {
if (!parseInt(post.uid, 10)) {
return next();

@ -106,6 +106,7 @@
<li><a href="{relative_path}/admin/manage/tags">Tags</a></li>
<li><a href="{relative_path}/admin/manage/users">Users</a></li>
<li><a href="{relative_path}/admin/manage/groups">Groups</a></li>
<li><a href="{relative_path}/admin/manage/flags">Flags</a></li>
</ul>
</div>
<div class="sidebar-nav">

@ -0,0 +1,46 @@
<div class="flags">
<div class="col-lg-9">
<div class="panel panel-default">
<div class="panel-heading"><i class="fa fa-flag"></i> Flags</div>
<div class="panel-body post-container" data-next="{next}">
<!-- IF !posts.length -->
No flagged posts!
<!-- ENDIF !posts.length-->
<!-- BEGIN posts -->
<div>
<div class="panel panel-default" data-pid="{posts.pid}" data-tid="{posts.topic.tid}">
<div class="panel-body">
<a href="{relative_path}/user/{posts.user.userslug}">
<img title="{posts.user.username}" class="img-rounded user-img" src="{posts.user.picture}">
</a>
<a href="{relative_path}/user/{posts.user.userslug}">
<strong><span>{posts.user.username}</span></strong>
</a>
<div class="content">
<p>{posts.content}</p>
<p class="fade-out"></p>
</div>
<small>
<span class="pull-right footer">
Posted in <a href="{relative_path}/category/{posts.category.slug}"><i class="fa {posts.category.icon}"></i> {posts.category.name}</a>, <span class="timeago" title="{posts.relativeTime}"></span> &bull;
<a href="{relative_path}/topic/{posts.topic.slug}/{posts.index}">Read More</a>
</span>
</small>
</div>
</div>
<span class="badge badge-warning"><i class="fa fa-flag"></i> {posts.flags}</span>
<button class="btn btn-warning dismiss">Dismiss</button>
<button class="btn btn-danger delete">Delete</button>
<br/><br/>
</div>
<!-- END posts -->
</div>
</div>
</div>
</div>
Loading…
Cancel
Save