mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 12:05:57 +01:00
Merge branch 'master' of github.com:psychobunny/node-forum
This commit is contained in:
@@ -22,7 +22,7 @@ var ajaxify = {};
|
||||
|
||||
ajaxify.go = function(url, callback) {
|
||||
var url = url.replace(/\/$/, "");
|
||||
var tpl_url = (url === '') ? 'home' : url;
|
||||
var tpl_url = (url === '' || url === '/') ? 'home' : url.split('/')[0];
|
||||
|
||||
if (templates[tpl_url]) {
|
||||
window.history.pushState({}, url, "/" + url);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
var socket,
|
||||
config,
|
||||
app = {};
|
||||
app = {},
|
||||
|
||||
API_URL = null;
|
||||
|
||||
// todo: cleanup,etc
|
||||
(function() {
|
||||
@@ -8,6 +10,8 @@ var socket,
|
||||
$.ajax({
|
||||
url: '/config.json?v=' + new Date().getTime(),
|
||||
success: function(data) {
|
||||
API_URL = data.api_url;
|
||||
|
||||
config = data;
|
||||
socket = io.connect('http://' + config.socket.address + config.socket.port? ':' + config.socket.port : '');
|
||||
|
||||
@@ -78,14 +82,63 @@ var socket,
|
||||
}
|
||||
}
|
||||
|
||||
var post_window = null;
|
||||
app.open_post_window = function() {
|
||||
var post_window = null,
|
||||
submit_post_btn = null,
|
||||
post_title = null,
|
||||
reply_title = null,
|
||||
post_content = null;
|
||||
|
||||
|
||||
app.open_post_window = function(post_mode, id, title) {
|
||||
submit_post_btn = submit_post_btn || document.getElementById('submit_post_btn');
|
||||
post_title = post_title || document.getElementById('post_title');
|
||||
reply_title = reply_title || document.getElementById('reply_title');
|
||||
post_content = post_content || document.getElementById('post_content');
|
||||
|
||||
|
||||
post_window = post_window || document.getElementById('post_window');
|
||||
jQuery(post_window).slideToggle(250);
|
||||
document.getElementById('post_title').focus();
|
||||
|
||||
if (post_mode == null || post_mode == 'topic') {
|
||||
post_title.style.display = "block";
|
||||
reply_title.style.display = "none";
|
||||
post_title.focus();
|
||||
submit_post_btn.onclick = function() {
|
||||
app.post_topic();
|
||||
}
|
||||
} else {
|
||||
post_title.style.display = "none";
|
||||
reply_title.style.display = "block";
|
||||
reply_title.innerHTML = 'You are replying to "' + title + '"';
|
||||
post_content.focus();
|
||||
submit_post_btn.onclick = function() {
|
||||
app.post_reply(id)
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
app.post_reply = function(topic_id) {
|
||||
var content = document.getElementById('post_content').value;
|
||||
|
||||
if (content.length < 5) {
|
||||
app.alert({
|
||||
title: 'Reply Failure',
|
||||
message: 'You need to write more dude.',
|
||||
type: 'error',
|
||||
timeout: 2000
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
socket.emit('api:posts.reply', {
|
||||
'topic_id' : topic_id,
|
||||
'content' : content
|
||||
});
|
||||
jQuery(post_window).slideToggle(250);
|
||||
|
||||
};
|
||||
app.post_topic = function() {
|
||||
var title = document.getElementById('post_title').value,
|
||||
content = document.getElementById('post_content').value;
|
||||
@@ -95,10 +148,7 @@ var socket,
|
||||
title: 'Topic Post Failure',
|
||||
message: 'You need to write more dude.',
|
||||
type: 'error',
|
||||
timeout: 2000,
|
||||
clickfn: function() {
|
||||
ajaxify.go('register');
|
||||
}
|
||||
timeout: 2000
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
var templates = {};
|
||||
|
||||
(function() {
|
||||
var ready_callback;
|
||||
|
||||
templates.ready = function(callback) {
|
||||
//quick implementation because introducing a lib to handle several async callbacks
|
||||
if (callback == null) ready_callback();
|
||||
else ready_callback = callback;
|
||||
}
|
||||
|
||||
function loadTemplates(templatesToLoad) {
|
||||
var timestamp = new Date().getTime();
|
||||
var loaded = templatesToLoad.length;
|
||||
|
||||
for (var t in templatesToLoad) {
|
||||
(function(file) {
|
||||
@@ -18,6 +26,12 @@ var templates = {};
|
||||
template.prototype.html = String(html);
|
||||
|
||||
templates[file] = new template;
|
||||
|
||||
loaded--;
|
||||
if (loaded == 0) templates.ready();
|
||||
}).fail(function() {
|
||||
loaded--;
|
||||
if (loaded == 0) templates.ready();
|
||||
});
|
||||
}(templatesToLoad[t]));
|
||||
}
|
||||
@@ -26,7 +40,7 @@ var templates = {};
|
||||
|
||||
function init() {
|
||||
loadTemplates([
|
||||
'header', 'footer', 'register', 'home',
|
||||
'header', 'footer', 'register', 'home', 'topic',
|
||||
'login', 'reset', 'reset_code', 'account_settings',
|
||||
'emails/reset', 'emails/reset_plaintext'
|
||||
]);
|
||||
@@ -116,10 +130,10 @@ function load_template(callback) {
|
||||
rootUrl = location.protocol + '//' + (location.hostname || location.host) + (location.port ? ':' + location.port : '');
|
||||
|
||||
var url = location.href.replace(rootUrl +'/', '');
|
||||
if (url == '') url = 'home';
|
||||
jQuery.get('api/' + url, function(data) {
|
||||
url = (url === '' || url === '/') ? 'home' : url;
|
||||
|
||||
document.getElementById('content').innerHTML = templates[url].parse(JSON.parse(data));
|
||||
jQuery.get(API_URL + url, function(data) {
|
||||
document.getElementById('content').innerHTML = templates[url.split('/')[0]].parse(JSON.parse(data));
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
@@ -90,10 +90,10 @@
|
||||
border: 1px solid #eee;
|
||||
margin-top: 50px;
|
||||
}
|
||||
.topic-container li.topic-row:nth-child(odd) {
|
||||
.topic-container a:nth-child(odd) li.topic-row {
|
||||
background-color:#fdfdfd;
|
||||
}
|
||||
.topic-container li.topic-row:nth-child(even) {
|
||||
.topic-container a:nth-child(even) li.topic-row {
|
||||
background-color:#fff;
|
||||
}
|
||||
.topic-container li.topic-row {
|
||||
@@ -108,6 +108,35 @@
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.post-container {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 1px solid #eee;
|
||||
|
||||
}
|
||||
.post-container li.post-row:nth-child(odd) {
|
||||
background-color:#fdfdfd;
|
||||
}
|
||||
.post-container li.post-row:nth-child(even) {
|
||||
background-color:#fff;
|
||||
}
|
||||
.post-container li.post-row {
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 10px;
|
||||
}
|
||||
.post-container li:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
.post-container li.post-row:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#user_label img {
|
||||
border: 1px solid #999;
|
||||
margin-right: 8px;
|
||||
@@ -117,6 +146,11 @@
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
#reply_title {
|
||||
font-size: 17px;
|
||||
padding-top: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -132,7 +166,7 @@
|
||||
</button>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li class="active"><a href="/">Home</a></li>
|
||||
<li class="active"><a href="/">Forum</a></li>
|
||||
<li><a href="/register">Register</a></li>
|
||||
<li><a href="/login">Login</a></li>
|
||||
</ul>
|
||||
@@ -148,6 +182,7 @@
|
||||
<div class="post-title-container">
|
||||
<div class="container">
|
||||
<input id="post_title" placeholder="Enter your topic title here." />
|
||||
<span id="reply_title"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="post-content-container">
|
||||
@@ -161,7 +196,7 @@
|
||||
<a class="btn btn-link" href="#" tabindex="-1"><i class="icon-list"></i></a>
|
||||
</div>
|
||||
<div class="btn-group" style="float: right; margin-right: -12px">
|
||||
<a class="btn" onclick="app.post_topic()"><i class="icon-ok"></i> Submit</a>
|
||||
<a id="submit_post_btn" class="btn" onclick="app.post_topic()"><i class="icon-ok"></i> Submit</a>
|
||||
<a class="btn" onclick="jQuery(post_window).slideToggle(250);"><i class="icon-remove"></i> Discard</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -172,4 +207,5 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="notification_window"></div>
|
||||
|
||||
<div class="container" id="content">
|
||||
@@ -1,7 +1,7 @@
|
||||
<button id="new_post" class="btn btn-primary btn-large">New Post</button>
|
||||
<ul class="topic-container">
|
||||
<!-- BEGIN topics -->
|
||||
<a href="topics/{topics.slug}"><li class="topic-row">
|
||||
<a href="topic/{topics.slug}"><li class="topic-row">
|
||||
<h4>{topics.title}</h4>
|
||||
<p>Posted {topics.relativeTime} by user {topics.uid}. {topics.post_count} posts.</p>
|
||||
</li></a>
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
<ul class="topic-container">
|
||||
<div class="container">
|
||||
<ul class="breadcrumb">
|
||||
<li><a href="/">Home</a> <span class="divider">/</span></li>
|
||||
<li class="active">{TOPIC_NAME}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<ul class="post-container">
|
||||
<!-- BEGIN posts -->
|
||||
<li class="topic-row">
|
||||
<li class="post-row">
|
||||
<p>{posts.content}</p>
|
||||
<p>Posted {posts.relativeTime} by user {posts.uid}.</p>
|
||||
</li>
|
||||
<!-- END posts -->
|
||||
</ul>
|
||||
<hr />
|
||||
<button id="post_reply" class="btn btn-primary btn-large">Reply</button>
|
||||
<script type="text/javascript">
|
||||
var post_reply = document.getElementById('post_reply');
|
||||
post_reply.onclick = function() {
|
||||
app.open_post_window('reply', "{TOPIC_ID}", "{TOPIC_NAME}");
|
||||
}
|
||||
</script>
|
||||
|
||||
21
src/posts.js
21
src/posts.js
@@ -16,8 +16,8 @@ var RDB = require('./redis.js'),
|
||||
if (start == null) start = 0;
|
||||
if (end == null) end = start + 10;
|
||||
|
||||
RDB.get('tid:' + tid + ':title', function(topic_name) { //do these asynch later
|
||||
RDB.lrange('tid:' + tid + ':posts', start, end, function(pids) {
|
||||
|
||||
var content = [],
|
||||
uid = [],
|
||||
timestamp = [];
|
||||
@@ -48,25 +48,32 @@ var RDB = require('./redis.js'),
|
||||
});
|
||||
}
|
||||
|
||||
callback({'posts': posts});
|
||||
callback({'TOPIC_NAME':topic_name, 'TOPIC_ID': tid, 'posts': posts});
|
||||
});
|
||||
} else {
|
||||
callback({});
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
Posts.reply = function() {
|
||||
Posts.reply = function(tid, uid, content) {
|
||||
Posts.create(uid, content, function(pid) {
|
||||
RDB.rpush('tid:' + tid + ':posts', pid);
|
||||
|
||||
socket.emit('event:alert', {
|
||||
title: 'Reply Successful',
|
||||
message: 'You have successfully replied. Click here to view your reply.',
|
||||
type: 'notify',
|
||||
timeout: 2000
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Posts.create = function(uid, content, callback) {
|
||||
console.log("global uid "+uid);
|
||||
|
||||
if (uid === null) return;
|
||||
|
||||
RDB.incr('global:next_post_id', function(pid) {
|
||||
|
||||
@@ -76,6 +76,10 @@
|
||||
db.lpush(key, item);
|
||||
}
|
||||
|
||||
RedisDB.rpush = function(key, item) {
|
||||
db.rpush(key, item);
|
||||
}
|
||||
|
||||
RedisDB.lrange = function(key, start, end, callback, error_handler) {
|
||||
db.lrange(key, start, end, function(error, data) {
|
||||
return_handler(error, data, callback, error_handler);
|
||||
|
||||
@@ -60,7 +60,7 @@ var fs = require('fs');
|
||||
var template = this.html, regex, block;
|
||||
|
||||
return (function parse(data, namespace, template) {
|
||||
if (data.length == 0) {
|
||||
if (Object.keys(data).length == 0) {
|
||||
regex = makeRegex('[^]*');
|
||||
template = template.replace(regex, '');
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ var RDB = require('./redis.js'),
|
||||
|
||||
Topics.post = function(uid, title, content, category) {
|
||||
if (uid === 0) {
|
||||
global.socket.emit('event:alert', {
|
||||
socket.emit('event:alert', {
|
||||
title: 'Thank you for posting',
|
||||
message: 'Since you are unregistered, your post is awaiting approval. Click here to register now.',
|
||||
type: 'warning',
|
||||
@@ -145,7 +145,7 @@ var RDB = require('./redis.js'),
|
||||
RDB.lpush('uid:' + uid + ':topics', tid);
|
||||
|
||||
|
||||
global.socket.emit('event:alert', {
|
||||
socket.emit('event:alert', {
|
||||
title: 'Thank you for posting',
|
||||
message: 'You have successfully posted. Click here to view your post.',
|
||||
type: 'notify',
|
||||
|
||||
@@ -89,43 +89,51 @@ passport.deserializeUser(function(uid, done) {
|
||||
// Useful if you want to use app.put and app.delete (instead of app.post all the time)
|
||||
// app.use(express.methodOverride());
|
||||
|
||||
app.get('/', function(req, res) {
|
||||
global.modules.topics.generate_forum_body(function(forum_body) {
|
||||
res.send(templates['header'] + forum_body + templates['footer']);
|
||||
});
|
||||
|
||||
// Basic Routes (entirely client-side parsed, goal is to move the rest of the crap in this file into this one section)
|
||||
(function() {
|
||||
var routes = ['', 'login', 'register'];
|
||||
|
||||
for (var i=0, ii=routes.length; i<ii; i++) {
|
||||
(function(route) {
|
||||
app.get('/' + route, function(req, res) {
|
||||
res.send(templates['header'] + '<script>templates.ready(function(){ajaxify.go("' + route + '");});</script>' + templates['footer']);
|
||||
});
|
||||
}(routes[i]));
|
||||
}
|
||||
}());
|
||||
|
||||
|
||||
// need a proper way to combine these two routes together
|
||||
app.get('/topics/:topic_id', function(req, res) {
|
||||
function generate_topic_body(req, res) {
|
||||
global.modules.topics.generate_topic_body(function(topic_body) {
|
||||
res.send(templates['header'] + topic_body + templates['footer']);
|
||||
}, req.params.topic_id)
|
||||
});
|
||||
app.get('/topics/:topic_id/:slug', function(req, res) {
|
||||
global.modules.topics.generate_topic_body(function(topic_body) {
|
||||
res.send(templates['header'] + topic_body + templates['footer']);
|
||||
}, req.params.topic_id)
|
||||
});
|
||||
}, req.params.topic_id);
|
||||
}
|
||||
app.get('/topic/:topic_id', generate_topic_body);
|
||||
app.get('/topic/:topic_id*', generate_topic_body);
|
||||
|
||||
|
||||
|
||||
app.get('/api/:method', function(req, res) {
|
||||
function api_method(req, res) {
|
||||
switch(req.params.method) {
|
||||
case 'home' :
|
||||
global.modules.topics.get(function(data) {
|
||||
res.send(JSON.stringify(data));
|
||||
});
|
||||
break;
|
||||
case 'topic' :
|
||||
global.modules.posts.get(function(data) {
|
||||
res.send(JSON.stringify(data));
|
||||
}, req.params.id);
|
||||
break;
|
||||
default :
|
||||
res.send('{}');
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/login', function(req, res) {
|
||||
res.send(templates['header'] + templates['login'] + templates['footer']);
|
||||
});
|
||||
}
|
||||
app.get('/api/:method', api_method);
|
||||
app.get('/api/:method/:id', api_method);
|
||||
app.get('/api/:method/:id*', api_method);
|
||||
|
||||
app.post('/login', passport.authenticate('local', {
|
||||
successRedirect: '/',
|
||||
@@ -148,10 +156,6 @@ passport.deserializeUser(function(uid, done) {
|
||||
res.send(templates['header'] + templates['reset'] + templates['footer']);
|
||||
});
|
||||
|
||||
app.get('/register', function(req, res) {
|
||||
res.send(templates['header'] + templates['register'] + templates['footer']);
|
||||
});
|
||||
|
||||
app.get('/403', function(req, res) {
|
||||
res.send(templates['header'] + templates['403'] + templates['footer']);
|
||||
});
|
||||
|
||||
@@ -94,6 +94,10 @@ var SocketIO = require('socket.io').listen(global.server),
|
||||
modules.topics.post(uid, data.title, data.content);
|
||||
});
|
||||
|
||||
socket.on('api:posts.reply', function(data) {
|
||||
modules.posts.reply(data.topic_id, uid, data.content);
|
||||
});
|
||||
|
||||
socket.on('api:user.active.get', function() {
|
||||
modules.user.active.get();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user