mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 20:16:04 +01:00
Merge branch 'master' of https://github.com/psychobunny/NodeBB
Conflicts: src/posts.js src/topics.js
This commit is contained in:
@@ -36,6 +36,11 @@ var config = {
|
||||
"facebook": {
|
||||
"app_id": '',
|
||||
"secret": ''
|
||||
},
|
||||
|
||||
// Privileged Actions Reputation Thresholds
|
||||
"privilege_thresholds": {
|
||||
"manage_thread": 1000
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -204,6 +204,10 @@ footer.footer {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
&.deleted {
|
||||
-moz-opacity: 0.30;
|
||||
opacity: 0.30;
|
||||
}
|
||||
}
|
||||
|
||||
#user_label {
|
||||
|
||||
@@ -41,7 +41,6 @@ var ajaxify = {};
|
||||
jQuery('#content').fadeOut(100);
|
||||
|
||||
load_template(function() {
|
||||
console.log('called');
|
||||
exec_body_scripts(content);
|
||||
|
||||
ajaxify.enable();
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<ul class="topic-container">
|
||||
<!-- BEGIN topics -->
|
||||
<a href="../../topic/{topics.slug}"><li class="topic-row">
|
||||
<h4>{topics.title}</h4>
|
||||
<h4><i class="{topics.icon}"></i> {topics.title}</h4>
|
||||
<p>Posted {topics.relativeTime} ago by <span class="username">{topics.username}</span>. {topics.post_count} posts.</p>
|
||||
</li></a>
|
||||
<!-- END topics -->
|
||||
|
||||
@@ -35,31 +35,72 @@
|
||||
</ul>
|
||||
<hr />
|
||||
<button id="post_reply" class="btn btn-primary btn-large post_reply">Reply</button>
|
||||
<div class="btn-group pull-right">
|
||||
<div class="btn-group pull-right" id="thread-tools" style="visibility: hidden;">
|
||||
<button class="btn dropdown-toggle" data-toggle="dropdown">Thread Tools <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Lock/Unlock Thread</a></li>
|
||||
<li><a href="#" id="lock_thread"><i class="icon-lock"></i> Lock Thread</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#"><span class="text-error">Delete Thread</span></a></li>
|
||||
<li><a href="#" id="delete_thread"><span class="text-error"><i class="icon-trash"></i> Delete Thread</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var locked = '{locked}';
|
||||
var expose_tools = '{expose_tools}',
|
||||
tid = '{topic_id}',
|
||||
thread_state = {
|
||||
locked: '{locked}',
|
||||
deleted: '{deleted}'
|
||||
};
|
||||
|
||||
jQuery('document').ready(function() {
|
||||
var room = 'topic_' + '{topic_id}';
|
||||
var room = 'topic_' + '{topic_id}',
|
||||
adminTools = document.getElementById('thread-tools');
|
||||
|
||||
app.enter_room(room);
|
||||
set_up_posts();
|
||||
|
||||
if (locked === '1') set_locked_state(true);
|
||||
if (thread_state.locked === '1') set_locked_state(true);
|
||||
if (thread_state.deleted === '1') set_delete_state(true);
|
||||
|
||||
if (expose_tools === '1') {
|
||||
var deleteThreadEl = document.getElementById('delete_thread'),
|
||||
lockThreadEl = document.getElementById('lock_thread');
|
||||
|
||||
adminTools.style.visibility = 'inherit';
|
||||
|
||||
// Add events to the thread tools
|
||||
deleteThreadEl.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
if (thread_state.deleted !== '1') {
|
||||
if (confirm('really delete thread? (THIS DIALOG TO BE REPLACED WITH BOOTBOX)')) {
|
||||
socket.emit('api:topic.delete', { tid: tid });
|
||||
}
|
||||
} else {
|
||||
if (confirm('really restore thread? (THIS DIALOG TO BE REPLACED WITH BOOTBOX)')) {
|
||||
socket.emit('api:topic.restore', { tid: tid });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
lockThreadEl.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
if (thread_state.locked !== '1') {
|
||||
if (confirm('really lock thread? (THIS DIALOG TO BE REPLACED WITH BOOTBOX)')) {
|
||||
socket.emit('api:topic.lock', { tid: tid });
|
||||
}
|
||||
} else {
|
||||
if (confirm('really unlock thread? (THIS DIALOG TO BE REPLACED WITH BOOTBOX)')) {
|
||||
socket.emit('api:topic.unlock', { tid: tid });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
ajaxify.register_events(['event:rep_up', 'event:rep_down', 'event:new_post', 'api:get_users_in_room']);
|
||||
ajaxify.register_events(['event:rep_up', 'event:rep_down', 'event:new_post', 'api:get_users_in_room', 'event:topic_deleted']);
|
||||
socket.on('api:get_users_in_room', function(users) {
|
||||
var anonymous = users.anonymous,
|
||||
usernames = users.usernames,
|
||||
@@ -89,7 +130,6 @@
|
||||
adjust_rep(-1, data.pid, data.uid);
|
||||
});
|
||||
|
||||
|
||||
socket.on('event:new_post', function(data) {
|
||||
var html = templates.prepare(templates['topic'].blocks['posts']).parse(data),
|
||||
uniqueid = new Date().getTime();
|
||||
@@ -98,7 +138,31 @@
|
||||
set_up_posts(uniqueid);
|
||||
});
|
||||
|
||||
socket.on('event:topic_deleted', function(data) {
|
||||
if (data.tid === tid && data.status === 'ok') {
|
||||
set_locked_state(true);
|
||||
set_delete_state(true);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('event:topic_restored', function(data) {
|
||||
if (data.tid === tid && data.status === 'ok') {
|
||||
set_locked_state(false);
|
||||
set_delete_state(false);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('event:topic_locked', function(data) {
|
||||
if (data.tid === tid && data.status === 'ok') {
|
||||
set_locked_state(true);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('event:topic_unlocked', function(data) {
|
||||
if (data.tid === tid && data.status === 'ok') {
|
||||
set_locked_state(false);
|
||||
}
|
||||
});
|
||||
|
||||
function adjust_rep(value, pid, uid) {
|
||||
var post_rep = jQuery('.post_rep_' + pid),
|
||||
@@ -120,11 +184,11 @@
|
||||
else div = '#' + div;
|
||||
|
||||
jQuery(div + ' .post_reply').click(function() {
|
||||
if (locked !== '1') app.open_post_window('reply', "{topic_id}", "{topic_name}");
|
||||
if (thread_state.locked !== '1') app.open_post_window('reply', "{topic_id}", "{topic_name}");
|
||||
});
|
||||
|
||||
jQuery(div + ' .quote').click(function() {
|
||||
if (locked !== '1') app.open_post_window('quote', "{topic_id}", "{topic_name}");
|
||||
if (thread_state.locked !== '1') app.open_post_window('quote', "{topic_id}", "{topic_name}");
|
||||
|
||||
// this needs to be looked at, obviously. only single line quotes work well I think maybe replace all \r\n with > ?
|
||||
document.getElementById('post_content').innerHTML = '> ' + document.getElementById('content_' + this.id.replace('quote_', '')).innerHTML;
|
||||
@@ -143,6 +207,7 @@
|
||||
uid = ids[1];
|
||||
|
||||
|
||||
if (thread_state.locked !== '1') {
|
||||
if (this.children[1].className == 'icon-star-empty') {
|
||||
this.children[1].className = 'icon-star';
|
||||
socket.emit('api:posts.favourite', {pid: pid, room_id: app.current_room});
|
||||
@@ -151,6 +216,7 @@
|
||||
this.children[1].className = 'icon-star-empty';
|
||||
socket.emit('api:posts.unfavourite', {pid: pid, room_id: app.current_room});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -158,22 +224,61 @@
|
||||
var threadReplyBtn = document.getElementById('post_reply'),
|
||||
postReplyBtns = document.querySelectorAll('#post-container .post_reply'),
|
||||
quoteBtns = document.querySelectorAll('#post-container .quote'),
|
||||
editBtns = document.querySelectorAll('#post-container .edit'),
|
||||
deleteBtns = document.querySelectorAll('#post-container .delete'),
|
||||
numReplyBtns = postReplyBtns.length,
|
||||
lockThreadEl = document.getElementById('lock_thread'),
|
||||
x;
|
||||
if (locked === true) {
|
||||
lockThreadEl.innerHTML = '<i class="icon-unlock"></i> Unlock Thread';
|
||||
threadReplyBtn.disabled = true;
|
||||
threadReplyBtn.innerHTML = 'Locked <i class="icon-lock"></i>';
|
||||
for(x=0;x<numReplyBtns;x++) {
|
||||
postReplyBtns[x].innerHTML = 'Locked <i class="icon-lock"></i>';
|
||||
quoteBtns[x].style.display = 'none';
|
||||
editBtns[x].style.display = 'none';
|
||||
deleteBtns[x].style.display = 'none';
|
||||
}
|
||||
|
||||
thread_state.locked = '1';
|
||||
} else {
|
||||
lockThreadEl.innerHTML = '<i class="icon-lock"></i> Lock Thread';
|
||||
threadReplyBtn.disabled = false;
|
||||
threadReplyBtn.innerHTML = 'Reply';
|
||||
for(x=0;x<numReplyBtns;x++) {
|
||||
postReplyBtns[x].innerHTML = 'Reply <i class="icon-reply"></i>';
|
||||
quoteBtns[x].style.display = 'inline-block';
|
||||
editBtns[x].style.display = 'inline-block';
|
||||
deleteBtns[x].style.display = 'inline-block';
|
||||
}
|
||||
|
||||
thread_state.locked = '0';
|
||||
}
|
||||
}
|
||||
|
||||
function set_delete_state(deleted) {
|
||||
var deleteThreadEl = document.getElementById('delete_thread'),
|
||||
deleteTextEl = deleteThreadEl.getElementsByTagName('span')[0],
|
||||
threadEl = document.querySelector('.post-container'),
|
||||
deleteNotice = document.getElementById('thread-deleted') || document.createElement('div');
|
||||
|
||||
if (deleted) {
|
||||
deleteTextEl.innerHTML = '<i class="icon-comment"></i> Restore Thread';
|
||||
$(threadEl).addClass('deleted');
|
||||
|
||||
// Spawn a 'deleted' notice at the top of the page
|
||||
deleteNotice.setAttribute('id', 'thread-deleted');
|
||||
deleteNotice.className = 'alert';
|
||||
deleteNotice.innerHTML = 'This thread has been deleted. Only users with thread management privileges can see it.<br /><br /><a href="/">Home</a>';
|
||||
document.getElementById('content').insertBefore(deleteNotice, threadEl);
|
||||
|
||||
thread_state.deleted = '1';
|
||||
} else {
|
||||
deleteTextEl.innerHTML = '<i class="icon-trash"></i> Delete Thread';
|
||||
$(threadEl).removeClass('deleted');
|
||||
deleteNotice.parentNode.removeChild(deleteNotice);
|
||||
|
||||
thread_state.deleted = '0';
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
19
src/posts.js
19
src/posts.js
@@ -1,7 +1,8 @@
|
||||
var RDB = require('./redis.js'),
|
||||
utils = require('./utils.js'),
|
||||
marked = require('marked'),
|
||||
user = require('./user.js');
|
||||
user = require('./user.js'),
|
||||
config = require('../config.js');
|
||||
|
||||
(function(Posts) {
|
||||
|
||||
@@ -9,12 +10,12 @@ var RDB = require('./redis.js'),
|
||||
if (start == null) start = 0;
|
||||
if (end == null) end = start + 10;
|
||||
|
||||
var post_data, user_data, thread_data, vote_data;
|
||||
var post_data, user_data, thread_data, vote_data, viewer_data;
|
||||
|
||||
|
||||
//compile thread after all data is asynchronously called
|
||||
function generateThread() {
|
||||
if (!post_data ||! user_data || !thread_data || !vote_data) return;
|
||||
if (!post_data ||! user_data || !thread_data || !vote_data || !viewer_data) return;
|
||||
|
||||
var posts = [];
|
||||
|
||||
@@ -42,7 +43,9 @@ var RDB = require('./redis.js'),
|
||||
'category_name':thread_data.category_name,
|
||||
'category_slug':thread_data.category_slug,
|
||||
'locked': parseInt(thread_data.locked) || 0,
|
||||
'deleted': parseInt(thread_data.deleted) || 0,
|
||||
'topic_id': tid,
|
||||
'expose_tools': viewer_data.reputation >= config.privilege_thresholds.manage_thread ? 1 : 0,
|
||||
'posts': posts
|
||||
});
|
||||
}
|
||||
@@ -76,6 +79,7 @@ var RDB = require('./redis.js'),
|
||||
.get('tid:' + tid + ':locked')
|
||||
.get('tid:' + tid + ':category_name')
|
||||
.get('tid:' + tid + ':category_slug')
|
||||
.get('tid:' + tid + ':deleted')
|
||||
.exec(function(err, replies) {
|
||||
post_data = {
|
||||
pid: pids,
|
||||
@@ -89,7 +93,8 @@ var RDB = require('./redis.js'),
|
||||
topic_name: replies[4],
|
||||
locked: replies[5],
|
||||
category_name: replies[6],
|
||||
category_slug: replies[7]
|
||||
category_slug: replies[7],
|
||||
deleted: replies[8] || 0
|
||||
};
|
||||
|
||||
user.getMultipleUserFields(post_data.uid, ['username','reputation','picture'], function(user_details){
|
||||
@@ -97,7 +102,13 @@ var RDB = require('./redis.js'),
|
||||
generateThread();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
user.getUserField(current_user, 'reputation', function(reputation){
|
||||
viewer_data = {
|
||||
reputation: reputation
|
||||
};
|
||||
generateThread();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
var RDB = require('./redis.js'),
|
||||
posts = require('./posts.js'),
|
||||
utils = require('./utils.js'),
|
||||
user = require('./user.js')
|
||||
user = require('./user.js'),
|
||||
configs = require('../config.js'),
|
||||
categories = require('./categories.js');
|
||||
|
||||
(function(Topics) {
|
||||
@@ -24,14 +25,18 @@ var RDB = require('./redis.js'),
|
||||
uid = [],
|
||||
timestamp = [],
|
||||
slug = [],
|
||||
postcount = [];
|
||||
postcount = [],
|
||||
locked = [],
|
||||
deleted = [];
|
||||
|
||||
for (var i=0, ii=tids.length; i<ii; i++) {
|
||||
title.push('tid:' + tids[i] + ':title');
|
||||
uid.push('tid:' + tids[i] + ':uid');
|
||||
timestamp.push('tid:' + tids[i] + ':timestamp');
|
||||
slug.push('tid:' + tids[i] + ':slug');
|
||||
postcount.push('tid:' + tids[i] + ':postcount');
|
||||
postcount.push('tid:' + tids[i] + ':postcount'),
|
||||
locked.push('tid:' + tids[i] + ':locked'),
|
||||
deleted.push('tid:' + tids[i] + ':deleted');
|
||||
}
|
||||
|
||||
var multi = RDB.multi()
|
||||
@@ -44,6 +49,8 @@ var RDB = require('./redis.js'),
|
||||
.mget(timestamp)
|
||||
.mget(slug)
|
||||
.mget(postcount)
|
||||
.mget(locked)
|
||||
.mget(deleted)
|
||||
}
|
||||
|
||||
|
||||
@@ -57,9 +64,8 @@ var RDB = require('./redis.js'),
|
||||
timestamp = replies[3];
|
||||
slug = replies[4];
|
||||
postcount = replies[5];
|
||||
|
||||
|
||||
|
||||
locked = replies[6];
|
||||
deleted = replies[7];
|
||||
|
||||
user.get_usernames_by_uids(uid, function(userNames) {
|
||||
|
||||
@@ -72,7 +78,9 @@ var RDB = require('./redis.js'),
|
||||
'timestamp' : timestamp[i],
|
||||
'relativeTime': utils.relativeTime(timestamp[i]),
|
||||
'slug' : slug[i],
|
||||
'post_count' : postcount[i]
|
||||
'post_count' : postcount[i],
|
||||
'icon': locked[i] === '1' ? 'icon-lock' : 'hide',
|
||||
'deleted': deleted[i]
|
||||
});
|
||||
}
|
||||
|
||||
@@ -169,8 +177,71 @@ var RDB = require('./redis.js'),
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
Topics.lock = function(tid, uid, socket) {
|
||||
user.getUserField(uid, 'reputation', function(rep) {
|
||||
if (rep >= configs.privilege_thresholds.manage_thread) {
|
||||
// Mark thread as locked
|
||||
RDB.set('tid:' + tid + ':locked', 1);
|
||||
|
||||
if (socket) {
|
||||
io.sockets.in('topic_' + tid).emit('event:topic_locked', {
|
||||
tid: tid,
|
||||
status: 'ok'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Topics.unlock = function(tid, uid, socket) {
|
||||
user.getUserField(uid, 'reputation', function(rep) {
|
||||
if (rep >= configs.privilege_thresholds.manage_thread) {
|
||||
// Mark thread as locked
|
||||
RDB.del('tid:' + tid + ':locked');
|
||||
|
||||
if (socket) {
|
||||
io.sockets.in('topic_' + tid).emit('event:topic_unlocked', {
|
||||
tid: tid,
|
||||
status: 'ok'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Topics.delete = function(tid, uid, socket) {
|
||||
user.getUserField(uid, 'reputation', function(rep) {
|
||||
if (rep >= configs.privilege_thresholds.manage_thread) {
|
||||
// Mark thread as deleted
|
||||
RDB.set('tid:' + tid + ':deleted', 1);
|
||||
Topics.lock(tid, uid);
|
||||
|
||||
if (socket) {
|
||||
io.sockets.in('topic_' + tid).emit('event:topic_deleted', {
|
||||
tid: tid,
|
||||
status: 'ok'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Topics.restore = function(tid, uid, socket) {
|
||||
user.getUserField(uid, 'reputation', function(rep) {
|
||||
if (rep >= configs.privilege_thresholds.manage_thread) {
|
||||
// Mark thread as deleted
|
||||
RDB.del('tid:' + tid + ':deleted');
|
||||
Topics.unlock(tid, uid);
|
||||
|
||||
if (socket) {
|
||||
io.sockets.in('topic_' + tid).emit('event:topic_restored', {
|
||||
tid: tid,
|
||||
status: 'ok'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}(exports));
|
||||
@@ -393,9 +393,8 @@ passport.deserializeUser(function(uid, done) {
|
||||
}
|
||||
|
||||
app.get('/test', function(req, res) {
|
||||
global.modules.posts.get(function(data) {
|
||||
res.send('<pre>' + JSON.stringify(data, null, 4) + '</pre>');
|
||||
}, 1, 1);
|
||||
global.modules.topics.delete(1, 1);
|
||||
res.send();
|
||||
});
|
||||
}(WebServer));
|
||||
|
||||
|
||||
@@ -62,10 +62,7 @@ var SocketIO = require('socket.io').listen(global.server,{log:false}),
|
||||
socket.emit('event:connect', {status: 1});
|
||||
|
||||
socket.on('disconnect', function() {
|
||||
console.log('Got disconnect! SESSION ID : '+hs.sessionID+' USER ID : '+uid);
|
||||
|
||||
delete users[hs.sessionID];
|
||||
console.log(users);
|
||||
});
|
||||
|
||||
|
||||
@@ -177,6 +174,22 @@ var SocketIO = require('socket.io').listen(global.server,{log:false}),
|
||||
socket.on('api:user.active.get_record', function() {
|
||||
modules.user.active.get_record(socket);
|
||||
});
|
||||
|
||||
socket.on('api:topic.delete', function(data) {
|
||||
modules.topics.delete(data.tid, uid, socket);
|
||||
});
|
||||
|
||||
socket.on('api:topic.restore', function(data) {
|
||||
modules.topics.restore(data.tid, uid, socket);
|
||||
});
|
||||
|
||||
socket.on('api:topic.lock', function(data) {
|
||||
modules.topics.lock(data.tid, uid, socket);
|
||||
});
|
||||
|
||||
socket.on('api:topic.unlock', function(data) {
|
||||
modules.topics.unlock(data.tid, uid, socket);
|
||||
});
|
||||
});
|
||||
|
||||
}(SocketIO));
|
||||
|
||||
Reference in New Issue
Block a user