Merge branch 'master' of github.com:psychobunny/node-forum

Conflicts:
	src/webserver.js
v1.18.x
Julian Lam 12 years ago
commit 71e410d571

@ -1,5 +1,7 @@
var modules = {
user: require('./src/user.js'),
topics: require('./src/topics.js'),
posts: require('./src/posts.js'),
templates: require('./src/templates.js'),
webserver: require('./src/webserver.js'),
websockets: require('./src/websockets.js')
@ -11,6 +13,8 @@ var modules = {
global.configuration = {};
global.modules = modules;
// change this to = null when auth module is complete
global.uid = 1;

@ -2,6 +2,7 @@ var socket,
config,
app = {};
// todo: cleanup,etc
(function() {
$.ajax({
@ -42,7 +43,7 @@ var socket,
p.innerHTML = params.message;
strong.innerHTML = params.title;
div.className = "alert " + ((params.type=='warning') ? '' : "alert-" + params.type);
div.className = "alert toaster-alert " + ((params.type=='warning') ? '' : "alert-" + params.type);
div.setAttribute('id', alert_id);
div.appendChild(button);
@ -61,9 +62,52 @@ var socket,
if (params.timeout) {
setTimeout(function() {
jQuery(div).fadeOut('1000');
jQuery(div).fadeOut(1000);
}, params.timeout)
}
if (params.clickfn) {
div.onclick = function() {
params.clickfn();
jQuery(div).fadeOut(500);
}
}
}
var post_window = null;
app.open_post_window = function() {
post_window = post_window || document.getElementById('post_window');
jQuery(post_window).slideToggle(250);
};
app.post_topic = function() {
var title = document.getElementById('post_title').innerHTML,
content = document.getElementById('post_content').innerHTML;
if (title.length < 5 || content.length < 5) {
app.alert({
title: 'Topic Post Failure',
message: 'You need to write more dude.',
type: 'error',
timeout: 2000,
clickfn: function() {
ajaxify.go('register');
}
});
return;
}
socket.emit('topics.post', {
'title' : title,
'content' : content
});
jQuery(post_window).slideToggle(250);
};
jQuery('document').ready(function() {
jQuery('#post_window').slideToggle(0);
})
}());

@ -2,7 +2,7 @@
</div><!--END container -->
<!-- START Forum Info -->
<div class="container">
<div class="container" style="padding-top: 50px;">
<div class="alert alert-info">
<span id="number_of_users"></span><br />
<span id="latest_user"></span>

@ -10,6 +10,7 @@
<script type="text/javascript" src="/src/app.js"></script>
<script type="text/javascript" src="/src/templates.js"></script>
<script type="text/javascript" src="/src/ajaxify.js"></script>
<script type="text/javascript" src="/vendor/ckeditor/ckeditor.js"></script>
<style type="text/css">
body {
padding-top: 60px;
@ -21,8 +22,13 @@
top: 80px;
width: 300px;
height: 0px;
}
.toaster-alert {
cursor: pointer;
}
footer.footer {
color: #555;
text-align: center;
@ -30,6 +36,47 @@
footer.footer a {
color: #222;
}
#post_window {
width: 100%;
position: absolute;
height: 350px;
left: 0px;
bottom: 0px;
opacity: 0.8;
}
#post_window input {
width: 100%;
height: 30px;
padding: 5px;
}
#post_window textarea {
width: 100%;
background: #222;
height: 220px;
resize: none;
border-radius: 0;
border: 1px solid #111;
font-size: 16px;
color: #bebebe;
}
#post_window textarea:focus {
outline: none;
border:none !important;
box-shadow:none !important;
}
#post_window .post-title-container {
height: 50px;
}
#post_window .post-content-container {
background: #000;
width: 100%;
height: 300px;
}
</style>
</head>
@ -47,6 +94,32 @@
</div>
</div>
</div>
<div id="notification_window"></div>
<div class="container" id="content">
<div id="post_window">
<div class="post-title-container">
<div class="container">
<input id="post_title" placeholder="Enter your topic title here." />
</div>
</div>
<div class="post-content-container">
<div class="container">
<div class="btn-toolbar">
<div class="btn-group">
<a class="btn btn-link" href="#"><i class="icon-bold"></i></a>
<a class="btn btn-link" href="#"><i class="icon-italic"></i></a>
<a class="btn btn-link" href="#"><i class="icon-font"></i></a>
<a class="btn btn-link" href="#"><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 class="btn" onclick="jQuery(post_window).slideToggle(250);"><i class="icon-remove"></i> Discard</a>
</div>
</div>
<textarea id="post_content" placeholder="Type your message here."></textarea>
</div>
</div>
</div>
<div id="notification_window"></div>
<div class="container" id="content">

@ -1,6 +1,13 @@
dis is home nibs
<button id="new_post" class="btn btn-primary btn-large">New Post</button>
<script type="text/javascript">
var new_post = document.getElementById('new_post');
new_post.onclick = function() {
app.open_post_window();
}
/*app.alert({
title: 'Welcome back',
message: 'Some welcome message to test alerts!',

@ -1,70 +0,0 @@
// https://gist.github.com/balupton/858093/raw/187833dc344a576e404fbdd40ef96de1f944b33b/ajaxify-html4.js
console.log('derp2');
(function(window,undefined){
// Prepare our Variables
var
document = window.document,
$ = window.jQuery;
// Wait for Document
$(document).ready(function(){
// Prepare Variables
var
$content = $('#content'),
$body = $(document.body),
rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host);
console.log('derp');
// Ajaxify our Internal Links
$.fn.ajaxify = function(){
// Ajaxify internal links
$(this).find('a[href^="/"],a[href^="'+rootUrl+'"]').unbind('click').bind('click',function(event){
var $this = $(this), url = $this.attr('href'), title = $this.attr('title')||null, relativeUrl = $(this).attr('href').replace(rootUrl,'');
document.location.hash = '!' + relativeUrl;
event.preventDefault();
return false;
});
// Chain
return this;
};
// Ajaxify Page
$body.ajaxify();
// Hook into State Changes
$(window).bind('hashchange',function(){
// Prepare
var
relativeUrl = document.location.hash.replace(/^\//,'').replace(/^#!/,''),
fullUrl = rootUrl+relativeUrl;
// Set Loading
$body.addClass('loading');
// Start Fade Out
$content.fadeOut(800);
// Ajax Request the Traditional Page
$.get(fullUrl,function(data){
console.log('here');
// Find the content in the page's html, and apply it to our current page's content
$content.stop(true,true).show();
$content.html(data).ajaxify();
//$content.html($(data).find('#content')).ajaxify();
if ( $content.ScrollTo||false ) $content.ScrollTo(); // http://balupton.com/projects/jquery-scrollto
$body.removeClass('loading');
// Inform Google Analytics of the change
if ( typeof pageTracker !== 'undefined' ) {
pageTracker._trackPageview(relativeUrl);
}
}); // end get
}); // end onStateChange
}); // end onDomLoad
})(window); // end closure

@ -0,0 +1,40 @@
var RDB = require('./redis.js');
(function(Posts) {
//data structure
//*global:next_post_id
// *pid:1:content
// *pid:1:uid
// *pid:1:timestamp
// ***pid:1:replies
// *uid:1:posts
Posts.get = function(topic) {
}
Posts.reply = function() {
};
Posts.create = function(content, callback) {
if (global.uid === null) return;
RDB.incr('global:next_post_id', function(pid) {
// Posts Info
RDB.set('pid:' + pid + ':content', content);
RDB.set('pid:' + pid + ':uid', global.uid);
RDB.set('pid:' + pid + ':timestamp', new Date().getTime());
// User Details - move this out later
RDB.lpush('uid:' + uid + ':posts', pid);
if (callback) callback(pid);
});
}
}(exports));

@ -0,0 +1,111 @@
var RDB = require('./redis.js'),
posts = require('./posts.js');
(function(Topics) {
//data structure
//*global:next_topic_id
// *tid:1:title
// *tid:1:uid
// *tid:1:posts (array of pid)
// *tid:1:timestamp
// *uid:1:topics
// *topic:slug:how-to-eat-chicken:tid
Topics.get_by_category = function(category, start, end) {
}
Topics.get = function(start, end) {
if (start == null) start = 0;
if (end == null) end = start + 10;
RDB.lrange('topics:tid', start, end, function() {
global.socket.emit
});
}
Topics.post = function(title, content, category) {
if (global.uid === null) {
global.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',
timeout: 7500,
clickfn: function() {
ajaxify.go('register');
}
});
return; // for now, until anon code is written.
}
RDB.incr('global:next_topic_id', function(tid) {
// Global Topics
if (global.uid !== null) {
RDB.lpush('topics:tid', tid);
} else {
// need to add some unique key sent by client so we can update this with the real uid later
RDB.lpush('topics:queued:tid', tid);
}
if (category) {
RDB.lpush('topics:' + category + ':tid', tid);
}
// Topic Info
RDB.set('tid:' + tid + ':title', title);
RDB.set('tid:' + tid + ':uid', global.uid);
RDB.set('tid:' + tid + ':timestamp', new Date().getTime());
RDB.set('topic:slug:' + slugify(title) + ':tid', tid);
// Posts
posts.create(content, function(pid) {
RDB.lpush('tid:' + tid + ':posts', pid);
});
// User Details - move this out later
RDB.lpush('uid:' + uid + ':topics', tid);
global.socket.emit('event:alert', {
title: 'Thank you for registering',
message: 'You have successfully registered - welcome to nodebb!',
type: 'notify',
timeout: 2000
});
});
};
}(exports));
//http://dense13.com/blog/2009/05/03/converting-string-to-slug-javascript/
function slugify(str) {
str = str.replace(/^\s+|\s+$/g, ''); // trim
str = str.toLowerCase();
// remove accents, swap ñ for n, etc
var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;";
var to = "aaaaeeeeiiiioooouuuunc------";
for (var i=0, l=from.length ; i<l ; i++) {
str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
}
str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
.replace(/\s+/g, '-') // collapse whitespace and replace by -
.replace(/-+/g, '-'); // collapse dashes
return str;
}

@ -34,27 +34,22 @@ var express = require('express'),
// app.use(express.methodOverride());
app.get('/', function(req, res) {
refreshTemplates();
res.send(templates['header'] + templates['home'] + templates['footer']);
});
app.get('/login', function(req, res) {
refreshTemplates();
res.send(templates['header'] + templates['login'] + templates['footer']);
});
app.get('/reset/:code', function(req, res) {
refreshTemplates();
res.send(templates['header'] + templates['reset_code'].parse({ reset_code: req.params.code }) + templates['footer']);
});
app.get('/reset', function(req, res) {
refreshTemplates();
res.send(templates['header'] + templates['reset'] + templates['footer']);
});
app.get('/register', function(req, res) {
refreshTemplates();
res.send(templates['header'] + templates['register'] + templates['footer']);
});

@ -79,6 +79,10 @@ var SocketIO = require('socket.io').listen(global.server),
socket.on('user:reset.commit', function(data) {
modules.user.reset.commit(data.code, data.password);
});
socket.on('api:topics.post', function(data) {
modules.topics.post(data.title, data.content);
});
});
}(SocketIO));

Loading…
Cancel
Save