mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-03 20:45:58 +01:00
Merge branch 'master' of https://github.com/psychobunny/NodeBB
This commit is contained in:
@@ -33,6 +33,8 @@ var socket,
|
|||||||
|
|
||||||
// use unique alert_id to have multiple alerts visible at a time, use the same alert_id to fade out the current instance
|
// use unique alert_id to have multiple alerts visible at a time, use the same alert_id to fade out the current instance
|
||||||
// type : error, success, info, warning/notify
|
// type : error, success, info, warning/notify
|
||||||
|
// title = bolded title text
|
||||||
|
// message = alert message content
|
||||||
// timeout default = permanent
|
// timeout default = permanent
|
||||||
// location : notification_window (default) or content
|
// location : notification_window (default) or content
|
||||||
app.alert = function(params) {
|
app.alert = function(params) {
|
||||||
@@ -41,7 +43,7 @@ var socket,
|
|||||||
strong = document.createElement('strong'),
|
strong = document.createElement('strong'),
|
||||||
p = document.createElement('p');
|
p = document.createElement('p');
|
||||||
|
|
||||||
var alert_id = 'alert_button_' + ((alert_id) ? alert_id : new Date().getTime());
|
var alert_id = 'alert_button_' + ((params.alert_id) ? params.alert_id : new Date().getTime());
|
||||||
|
|
||||||
jQuery('#'+alert_id).fadeOut(500, function() {
|
jQuery('#'+alert_id).fadeOut(500, function() {
|
||||||
this.remove();
|
this.remove();
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
|
<div class="container">
|
||||||
|
<ul class="breadcrumb">
|
||||||
|
<li><a href="/">Home</a><span class="divider">/</span></li>
|
||||||
|
<li class="active">{category_name}</li>
|
||||||
|
<div id="category_active_users"></div>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button id="new_post" class="btn btn-primary btn-large {show_topic_button}">New Topic</button>
|
<button id="new_post" class="btn btn-primary btn-large {show_topic_button}">New Topic</button>
|
||||||
<ul class="topic-container">
|
<ul class="topic-container">
|
||||||
<!-- BEGIN topics -->
|
<!-- BEGIN topics -->
|
||||||
<a href="../../topic/{topics.slug}"><li class="topic-row">
|
<a href="../../topic/{topics.slug}"><li class="topic-row">
|
||||||
<h4><i class="{topics.icon}"></i> {topics.title}</h4>
|
<h4><i class="{topics.pin-icon}"></i><i class="{topics.lock-icon}"></i> {topics.title}</h4>
|
||||||
<p>Posted {topics.relativeTime} ago by <span class="username">{topics.username}</span>. {topics.post_count} posts.</p>
|
<p>Posted {topics.relativeTime} ago by <span class="username">{topics.username}</span>. {topics.post_count} posts.</p>
|
||||||
</li></a>
|
</li></a>
|
||||||
<!-- END topics -->
|
<!-- END topics -->
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<ul class="breadcrumb">
|
<ul class="breadcrumb">
|
||||||
<li><a href="/">Home</a> <span class="divider">/</span></li>
|
<li><a href="/">Home</a><span class="divider">/</span></li>
|
||||||
|
<li><a href="/category/{category_slug}">{category_name}</a><span class="divider">/</span></li>
|
||||||
<li class="active">{topic_name}</li>
|
<li class="active">{topic_name}</li>
|
||||||
<div id="thread_active_users"></div>
|
<div id="thread_active_users"></div>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -37,6 +38,7 @@
|
|||||||
<div class="btn-group pull-right" id="thread-tools" style="visibility: hidden;">
|
<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>
|
<button class="btn dropdown-toggle" data-toggle="dropdown">Thread Tools <span class="caret"></span></button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
|
<li><a href="#" id="pin_thread"><i class="icon-pushpin"></i> Pin Thread</a></li>
|
||||||
<li><a href="#" id="lock_thread"><i class="icon-lock"></i> Lock Thread</a></li>
|
<li><a href="#" id="lock_thread"><i class="icon-lock"></i> Lock Thread</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="#" id="delete_thread"><span class="text-error"><i class="icon-trash"></i> 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>
|
||||||
@@ -50,7 +52,8 @@
|
|||||||
tid = '{topic_id}',
|
tid = '{topic_id}',
|
||||||
thread_state = {
|
thread_state = {
|
||||||
locked: '{locked}',
|
locked: '{locked}',
|
||||||
deleted: '{deleted}'
|
deleted: '{deleted}',
|
||||||
|
pinned: '{pinned}'
|
||||||
};
|
};
|
||||||
|
|
||||||
jQuery('document').ready(function() {
|
jQuery('document').ready(function() {
|
||||||
@@ -62,10 +65,12 @@
|
|||||||
|
|
||||||
if (thread_state.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 (thread_state.deleted === '1') set_delete_state(true);
|
||||||
|
if (thread_state.pinned === '1') set_pinned_state(true);
|
||||||
|
|
||||||
if (expose_tools === '1') {
|
if (expose_tools === '1') {
|
||||||
var deleteThreadEl = document.getElementById('delete_thread'),
|
var deleteThreadEl = document.getElementById('delete_thread'),
|
||||||
lockThreadEl = document.getElementById('lock_thread');
|
lockThreadEl = document.getElementById('lock_thread'),
|
||||||
|
pinThreadEl = document.getElementById('pin_thread');
|
||||||
|
|
||||||
adminTools.style.visibility = 'inherit';
|
adminTools.style.visibility = 'inherit';
|
||||||
|
|
||||||
@@ -86,13 +91,18 @@
|
|||||||
lockThreadEl.addEventListener('click', function(e) {
|
lockThreadEl.addEventListener('click', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (thread_state.locked !== '1') {
|
if (thread_state.locked !== '1') {
|
||||||
if (confirm('really lock thread? (THIS DIALOG TO BE REPLACED WITH BOOTBOX)')) {
|
|
||||||
socket.emit('api:topic.lock', { tid: tid });
|
socket.emit('api:topic.lock', { tid: tid });
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (confirm('really unlock thread? (THIS DIALOG TO BE REPLACED WITH BOOTBOX)')) {
|
|
||||||
socket.emit('api:topic.unlock', { tid: tid });
|
socket.emit('api:topic.unlock', { tid: tid });
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pinThreadEl.addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (thread_state.pinned !== '1') {
|
||||||
|
socket.emit('api:topic.pin', { tid: tid });
|
||||||
|
} else {
|
||||||
|
socket.emit('api:topic.unpin', { tid: tid });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -153,13 +163,25 @@
|
|||||||
|
|
||||||
socket.on('event:topic_locked', function(data) {
|
socket.on('event:topic_locked', function(data) {
|
||||||
if (data.tid === tid && data.status === 'ok') {
|
if (data.tid === tid && data.status === 'ok') {
|
||||||
set_locked_state(true);
|
set_locked_state(true, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('event:topic_unlocked', function(data) {
|
socket.on('event:topic_unlocked', function(data) {
|
||||||
if (data.tid === tid && data.status === 'ok') {
|
if (data.tid === tid && data.status === 'ok') {
|
||||||
set_locked_state(false);
|
set_locked_state(false, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('event:topic_pinned', function(data) {
|
||||||
|
if (data.tid === tid && data.status === 'ok') {
|
||||||
|
set_pinned_state(true, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('event:topic_unpinned', function(data) {
|
||||||
|
if (data.tid === tid && data.status === 'ok') {
|
||||||
|
set_pinned_state(false, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -219,13 +241,16 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_locked_state(locked) {
|
function set_locked_state(locked, alert) {
|
||||||
var threadReplyBtn = document.getElementById('post_reply'),
|
var threadReplyBtn = document.getElementById('post_reply'),
|
||||||
postReplyBtns = document.querySelectorAll('#post-container .post_reply'),
|
postReplyBtns = document.querySelectorAll('#post-container .post_reply'),
|
||||||
quoteBtns = document.querySelectorAll('#post-container .quote'),
|
quoteBtns = document.querySelectorAll('#post-container .quote'),
|
||||||
|
editBtns = document.querySelectorAll('#post-container .edit'),
|
||||||
|
deleteBtns = document.querySelectorAll('#post-container .delete'),
|
||||||
numReplyBtns = postReplyBtns.length,
|
numReplyBtns = postReplyBtns.length,
|
||||||
lockThreadEl = document.getElementById('lock_thread'),
|
lockThreadEl = document.getElementById('lock_thread'),
|
||||||
x;
|
x;
|
||||||
|
|
||||||
if (locked === true) {
|
if (locked === true) {
|
||||||
lockThreadEl.innerHTML = '<i class="icon-unlock"></i> Unlock Thread';
|
lockThreadEl.innerHTML = '<i class="icon-unlock"></i> Unlock Thread';
|
||||||
threadReplyBtn.disabled = true;
|
threadReplyBtn.disabled = true;
|
||||||
@@ -233,6 +258,18 @@
|
|||||||
for(x=0;x<numReplyBtns;x++) {
|
for(x=0;x<numReplyBtns;x++) {
|
||||||
postReplyBtns[x].innerHTML = 'Locked <i class="icon-lock"></i>';
|
postReplyBtns[x].innerHTML = 'Locked <i class="icon-lock"></i>';
|
||||||
quoteBtns[x].style.display = 'none';
|
quoteBtns[x].style.display = 'none';
|
||||||
|
editBtns[x].style.display = 'none';
|
||||||
|
deleteBtns[x].style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alert) {
|
||||||
|
app.alert({
|
||||||
|
'alert_id': 'thread_lock',
|
||||||
|
type: 'success',
|
||||||
|
title: 'Thread Locked',
|
||||||
|
message: 'Thread has been successfully locked',
|
||||||
|
timeout: 5000
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_state.locked = '1';
|
thread_state.locked = '1';
|
||||||
@@ -243,6 +280,18 @@
|
|||||||
for(x=0;x<numReplyBtns;x++) {
|
for(x=0;x<numReplyBtns;x++) {
|
||||||
postReplyBtns[x].innerHTML = 'Reply <i class="icon-reply"></i>';
|
postReplyBtns[x].innerHTML = 'Reply <i class="icon-reply"></i>';
|
||||||
quoteBtns[x].style.display = 'inline-block';
|
quoteBtns[x].style.display = 'inline-block';
|
||||||
|
editBtns[x].style.display = 'inline-block';
|
||||||
|
deleteBtns[x].style.display = 'inline-block';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alert) {
|
||||||
|
app.alert({
|
||||||
|
'alert_id': 'thread_lock',
|
||||||
|
type: 'success',
|
||||||
|
title: 'Thread Unlocked',
|
||||||
|
message: 'Thread has been successfully unlocked',
|
||||||
|
timeout: 5000
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_state.locked = '0';
|
thread_state.locked = '0';
|
||||||
@@ -262,7 +311,7 @@
|
|||||||
// Spawn a 'deleted' notice at the top of the page
|
// Spawn a 'deleted' notice at the top of the page
|
||||||
deleteNotice.setAttribute('id', 'thread-deleted');
|
deleteNotice.setAttribute('id', 'thread-deleted');
|
||||||
deleteNotice.className = 'alert';
|
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>';
|
deleteNotice.innerHTML = 'This thread has been deleted. Only users with thread management privileges can see it.';
|
||||||
document.getElementById('content').insertBefore(deleteNotice, threadEl);
|
document.getElementById('content').insertBefore(deleteNotice, threadEl);
|
||||||
|
|
||||||
thread_state.deleted = '1';
|
thread_state.deleted = '1';
|
||||||
@@ -274,5 +323,37 @@
|
|||||||
thread_state.deleted = '0';
|
thread_state.deleted = '0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function set_pinned_state(pinned, alert) {
|
||||||
|
var pinEl = document.getElementById('pin_thread');
|
||||||
|
|
||||||
|
if (pinned) {
|
||||||
|
pinEl.innerHTML = '<i class="icon-pushpin"></i> Unpin Thread';
|
||||||
|
if (alert) {
|
||||||
|
app.alert({
|
||||||
|
'alert_id': 'thread_pin',
|
||||||
|
type: 'success',
|
||||||
|
title: 'Thread Pinned',
|
||||||
|
message: 'Thread has been successfully pinned',
|
||||||
|
timeout: 5000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_state.pinned = '1';
|
||||||
|
} else {
|
||||||
|
pinEl.innerHTML = '<i class="icon-pushpin"></i> Pin Thread';
|
||||||
|
if (alert) {
|
||||||
|
app.alert({
|
||||||
|
'alert_id': 'thread_pin',
|
||||||
|
type: 'success',
|
||||||
|
title: 'Thread Unpinned',
|
||||||
|
message: 'Thread has been successfully unpinned',
|
||||||
|
timeout: 5000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_state.pinned = '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
@@ -25,10 +25,17 @@ var RDB = require('./redis.js'),
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Categories.edit = function(data, callback) {
|
||||||
|
// just a reminder to self that name + slugs are stored into topics data as well.
|
||||||
|
};
|
||||||
|
|
||||||
Categories.get = function(callback) {
|
Categories.get = function(callback) {
|
||||||
RDB.lrange('categories:cid', 0, -1, function(cids) {
|
RDB.lrange('categories:cid', 0, -1, function(cids) {
|
||||||
|
Categories.get_category(cids, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Categories.get_category = function(cids, callback) {
|
||||||
var name = [],
|
var name = [],
|
||||||
description = [],
|
description = [],
|
||||||
icon = [],
|
icon = [],
|
||||||
@@ -78,7 +85,6 @@ var RDB = require('./redis.js'),
|
|||||||
callback({'categories': categories});
|
callback({'categories': categories});
|
||||||
});
|
});
|
||||||
} else callback({'categories' : []});
|
} else callback({'categories' : []});
|
||||||
});
|
};
|
||||||
}
|
|
||||||
|
|
||||||
}(exports));
|
}(exports));
|
||||||
15
src/posts.js
15
src/posts.js
@@ -40,8 +40,11 @@ var RDB = require('./redis.js'),
|
|||||||
|
|
||||||
callback({
|
callback({
|
||||||
'topic_name':thread_data.topic_name,
|
'topic_name':thread_data.topic_name,
|
||||||
|
'category_name':thread_data.category_name,
|
||||||
|
'category_slug':thread_data.category_slug,
|
||||||
'locked': parseInt(thread_data.locked) || 0,
|
'locked': parseInt(thread_data.locked) || 0,
|
||||||
'deleted': parseInt(thread_data.deleted) || 0,
|
'deleted': parseInt(thread_data.deleted) || 0,
|
||||||
|
'pinned': parseInt(thread_data.pinned) || 0,
|
||||||
'topic_id': tid,
|
'topic_id': tid,
|
||||||
'expose_tools': viewer_data.reputation >= config.privilege_thresholds.manage_thread ? 1 : 0,
|
'expose_tools': viewer_data.reputation >= config.privilege_thresholds.manage_thread ? 1 : 0,
|
||||||
'posts': posts
|
'posts': posts
|
||||||
@@ -61,10 +64,6 @@ var RDB = require('./redis.js'),
|
|||||||
pid.push(pids[i]);
|
pid.push(pids[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
RDB.get('tid:' + tid + ':title', function(topic_name) {
|
|
||||||
thread_data = {topic_name: topic_name};
|
|
||||||
generateThread();
|
|
||||||
});
|
|
||||||
|
|
||||||
Posts.getFavouritesByPostIDs(pids, current_user, function(fav_data) {
|
Posts.getFavouritesByPostIDs(pids, current_user, function(fav_data) {
|
||||||
vote_data = fav_data;
|
vote_data = fav_data;
|
||||||
@@ -79,7 +78,10 @@ var RDB = require('./redis.js'),
|
|||||||
.mget(post_rep)
|
.mget(post_rep)
|
||||||
.get('tid:' + tid + ':title')
|
.get('tid:' + tid + ':title')
|
||||||
.get('tid:' + tid + ':locked')
|
.get('tid:' + tid + ':locked')
|
||||||
|
.get('tid:' + tid + ':category_name')
|
||||||
|
.get('tid:' + tid + ':category_slug')
|
||||||
.get('tid:' + tid + ':deleted')
|
.get('tid:' + tid + ':deleted')
|
||||||
|
.get('tid:' + tid + ':pinned')
|
||||||
.exec(function(err, replies) {
|
.exec(function(err, replies) {
|
||||||
post_data = {
|
post_data = {
|
||||||
pid: pids,
|
pid: pids,
|
||||||
@@ -92,7 +94,10 @@ var RDB = require('./redis.js'),
|
|||||||
thread_data = {
|
thread_data = {
|
||||||
topic_name: replies[4],
|
topic_name: replies[4],
|
||||||
locked: replies[5] || 0,
|
locked: replies[5] || 0,
|
||||||
deleted: replies[6] || 0
|
category_name: replies[6],
|
||||||
|
category_slug: replies[7],
|
||||||
|
deleted: replies[8] || 0,
|
||||||
|
pinned: replies[9] || 0
|
||||||
};
|
};
|
||||||
|
|
||||||
user.getMultipleUserFields(post_data.uid, ['username','reputation','picture'], function(user_details){
|
user.getMultipleUserFields(post_data.uid, ['username','reputation','picture'], function(user_details){
|
||||||
|
|||||||
114
src/topics.js
114
src/topics.js
@@ -2,7 +2,8 @@ var RDB = require('./redis.js'),
|
|||||||
posts = require('./posts.js'),
|
posts = require('./posts.js'),
|
||||||
utils = require('./utils.js'),
|
utils = require('./utils.js'),
|
||||||
user = require('./user.js'),
|
user = require('./user.js'),
|
||||||
configs = require('../config.js');
|
configs = require('../config.js'),
|
||||||
|
categories = require('./categories.js');
|
||||||
|
|
||||||
(function(Topics) {
|
(function(Topics) {
|
||||||
|
|
||||||
@@ -26,20 +27,25 @@ var RDB = require('./redis.js'),
|
|||||||
slug = [],
|
slug = [],
|
||||||
postcount = [],
|
postcount = [],
|
||||||
locked = [],
|
locked = [],
|
||||||
deleted = [];
|
deleted = [],
|
||||||
|
pinned = [];
|
||||||
|
|
||||||
for (var i=0, ii=tids.length; i<ii; i++) {
|
for (var i=0, ii=tids.length; i<ii; i++) {
|
||||||
title.push('tid:' + tids[i] + ':title');
|
title.push('tid:' + tids[i] + ':title');
|
||||||
uid.push('tid:' + tids[i] + ':uid');
|
uid.push('tid:' + tids[i] + ':uid');
|
||||||
timestamp.push('tid:' + tids[i] + ':timestamp');
|
timestamp.push('tid:' + tids[i] + ':timestamp');
|
||||||
slug.push('tid:' + tids[i] + ':slug');
|
slug.push('tid:' + tids[i] + ':slug');
|
||||||
postcount.push('tid:' + tids[i] + ':postcount'),
|
postcount.push('tid:' + tids[i] + ':postcount');
|
||||||
locked.push('tid:' + tids[i] + ':locked'),
|
locked.push('tid:' + tids[i] + ':locked');
|
||||||
deleted.push('tid:' + tids[i] + ':deleted');
|
deleted.push('tid:' + tids[i] + ':deleted');
|
||||||
|
pinned.push('tid:' + tids[i] + ':pinned');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var multi = RDB.multi()
|
||||||
|
.get('cid:' + category_id + ':name');
|
||||||
|
|
||||||
if (tids.length > 0) {
|
if (tids.length > 0) {
|
||||||
RDB.multi()
|
multi
|
||||||
.mget(title)
|
.mget(title)
|
||||||
.mget(uid)
|
.mget(uid)
|
||||||
.mget(timestamp)
|
.mget(timestamp)
|
||||||
@@ -47,20 +53,27 @@ var RDB = require('./redis.js'),
|
|||||||
.mget(postcount)
|
.mget(postcount)
|
||||||
.mget(locked)
|
.mget(locked)
|
||||||
.mget(deleted)
|
.mget(deleted)
|
||||||
.exec(function(err, replies) {
|
.mget(pinned)
|
||||||
title = replies[0];
|
}
|
||||||
uid = replies[1];
|
|
||||||
timestamp = replies[2];
|
|
||||||
slug = replies[3];
|
|
||||||
postcount = replies[4];
|
|
||||||
locked = replies[5];
|
|
||||||
deleted = replies[6];
|
|
||||||
|
|
||||||
user.get_usernames_by_uids(uid, function(userNames) {
|
|
||||||
|
multi.exec(function(err, replies) {
|
||||||
|
category_name = replies[0];
|
||||||
var topics = [];
|
var topics = [];
|
||||||
|
|
||||||
|
if (tids.length > 0) {
|
||||||
|
title = replies[1];
|
||||||
|
uid = replies[2];
|
||||||
|
timestamp = replies[3];
|
||||||
|
slug = replies[4];
|
||||||
|
postcount = replies[5];
|
||||||
|
locked = replies[6];
|
||||||
|
deleted = replies[7];
|
||||||
|
pinned = replies[8];
|
||||||
|
|
||||||
|
user.get_usernames_by_uids(uid, function(userNames) {
|
||||||
|
|
||||||
for (var i=0, ii=title.length; i<ii; i++) {
|
for (var i=0, ii=title.length; i<ii; i++) {
|
||||||
if (deleted[i] === '1') continue;
|
|
||||||
|
|
||||||
topics.push({
|
topics.push({
|
||||||
'title' : title[i],
|
'title' : title[i],
|
||||||
@@ -70,26 +83,45 @@ var RDB = require('./redis.js'),
|
|||||||
'relativeTime': utils.relativeTime(timestamp[i]),
|
'relativeTime': utils.relativeTime(timestamp[i]),
|
||||||
'slug' : slug[i],
|
'slug' : slug[i],
|
||||||
'post_count' : postcount[i],
|
'post_count' : postcount[i],
|
||||||
icon: locked[i] === '1' ? 'icon-lock' : 'hide',
|
'lock-icon': locked[i] === '1' ? 'icon-lock' : 'hide',
|
||||||
deleted: deleted[i]
|
'deleted': deleted[i],
|
||||||
|
'pinned': parseInt(pinned[i] || 0), // For sorting purposes
|
||||||
|
'pin-icon': pinned[i] === '1' ? 'icon-pushpin' : 'hide'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Float pinned topics to the top
|
||||||
|
topics = topics.sort(function(a, b) {
|
||||||
|
return b.pinned - a.pinned;
|
||||||
|
});
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
|
'category_name' : category_id ? category_name : 'Recent',
|
||||||
'show_topic_button' : category_id ? 'show' : 'hidden',
|
'show_topic_button' : category_id ? 'show' : 'hidden',
|
||||||
'category_id': category_id,
|
'category_id': category_id,
|
||||||
'topics': topics
|
'topics': topics
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
else {
|
||||||
} else callback({'category_id': category_id, 'topics': []});
|
callback({
|
||||||
|
'category_name' : category_id ? category_name : 'Recent',
|
||||||
|
'show_topic_button' : category_id ? 'show' : 'hidden',
|
||||||
|
'category_id': category_id,
|
||||||
|
'topics': []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
//} else callback({'category_id': category_id, 'topics': []});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Topics.post = function(socket, uid, title, content, category_id) {
|
Topics.post = function(socket, uid, title, content, category_id) {
|
||||||
|
if (!category_id) throw new Error('Attempted to post without a category_id');
|
||||||
|
|
||||||
if (uid === 0) {
|
if (uid === 0) {
|
||||||
socket.emit('event:alert', {
|
socket.emit('event:alert', {
|
||||||
@@ -147,6 +179,14 @@ var RDB = require('./redis.js'),
|
|||||||
type: 'notify',
|
type: 'notify',
|
||||||
timeout: 2000
|
timeout: 2000
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// in future it may be possible to add topics to several categories, so leaving the door open here.
|
||||||
|
categories.get_category([category_id], function(data) {
|
||||||
|
RDB.set('tid:' + tid + ':category_name', data.categories[0].name);
|
||||||
|
RDB.set('tid:' + tid + ':category_slug', data.categories[0].slug);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -215,4 +255,36 @@ var RDB = require('./redis.js'),
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Topics.pin = 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 + ':pinned', 1);
|
||||||
|
|
||||||
|
if (socket) {
|
||||||
|
io.sockets.in('topic_' + tid).emit('event:topic_pinned', {
|
||||||
|
tid: tid,
|
||||||
|
status: 'ok'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Topics.unpin = 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 + ':pinned');
|
||||||
|
|
||||||
|
if (socket) {
|
||||||
|
io.sockets.in('topic_' + tid).emit('event:topic_unpinned', {
|
||||||
|
tid: tid,
|
||||||
|
status: 'ok'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}(exports));
|
}(exports));
|
||||||
@@ -145,15 +145,17 @@ passport.deserializeUser(function(uid, done) {
|
|||||||
|
|
||||||
// Complex Routes
|
// Complex Routes
|
||||||
app.get('/topic/:topic_id/:slug?', function(req, res) {
|
app.get('/topic/:topic_id/:slug?', function(req, res) {
|
||||||
res.send(templates['header'] + '<script>templates.ready(function(){ajaxify.go("' + 'topic/' + req.params.topic_id + '");});</script>' + templates['footer']);
|
var topic_url = req.params.topic_id + (req.params.slug ? '/' + req.params.slug : '');
|
||||||
|
res.send(templates['header'] + '<script>templates.ready(function(){ajaxify.go("topic/' + topic_url + '");});</script>' + templates['footer']);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/category/:category_id/:slug?', function(req, res) {
|
app.get('/category/:category_id/:slug?', function(req, res) {
|
||||||
res.send(templates['header'] + '<script>templates.ready(function(){ajaxify.go("' + 'category/' + req.params.category_id + '");});</script>' + templates['footer']);
|
var category_url = req.params.category_id + (req.params.slug ? '/' + req.params.slug : '');
|
||||||
|
res.send(templates['header'] + '<script>templates.ready(function(){ajaxify.go("category/' + category_url + '");});</script>' + templates['footer']);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/confirm/:code', function(req, res) {
|
app.get('/confirm/:code', function(req, res) {
|
||||||
res.send(templates['header'] + '<script>templates.ready(function(){ajaxify.go("' + 'confirm/' + req.params.code + '");});</script>' + templates['footer']);
|
res.send(templates['header'] + '<script>templates.ready(function(){ajaxify.go("confirm/' + req.params.code + '");});</script>' + templates['footer']);
|
||||||
});
|
});
|
||||||
|
|
||||||
// These functions are called via ajax once the initial page is loaded to populate templates with data
|
// These functions are called via ajax once the initial page is loaded to populate templates with data
|
||||||
|
|||||||
@@ -192,6 +192,14 @@ var SocketIO = require('socket.io').listen(global.server,{log:false}),
|
|||||||
socket.on('api:topic.unlock', function(data) {
|
socket.on('api:topic.unlock', function(data) {
|
||||||
modules.topics.unlock(data.tid, uid, socket);
|
modules.topics.unlock(data.tid, uid, socket);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on('api:topic.pin', function(data) {
|
||||||
|
modules.topics.pin(data.tid, uid, socket);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('api:topic.unpin', function(data) {
|
||||||
|
modules.topics.unpin(data.tid, uid, socket);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}(SocketIO));
|
}(SocketIO));
|
||||||
|
|||||||
Reference in New Issue
Block a user