From 0f3f2bb859039116c18d4da71d745e3fd37bd1e1 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Wed, 1 May 2013 18:25:24 +0000 Subject: [PATCH 1/5] post replies, unfinished --- public/src/app.js | 8 ++++++-- public/templates/topic.tpl | 10 +++++++++- src/posts.js | 2 +- src/templates.js | 4 ++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/public/src/app.js b/public/src/app.js index 8b50d34af6..64dd8378ff 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -78,12 +78,16 @@ var socket, } } - var post_window = null; - app.open_post_window = function() { + var post_window = null, + mode = 'topic', + topic_id = null; + app.open_post_window = function(post_mode, id) { post_window = post_window || document.getElementById('post_window'); jQuery(post_window).slideToggle(250); document.getElementById('post_title').focus(); + mode = (post_mode == null) ? 'topic' : mode; + topic_id = (mode == 'reply') ? topic_id : null; }; app.post_topic = function() { diff --git a/public/templates/topic.tpl b/public/templates/topic.tpl index 56c230a31f..ed5de86aa8 100644 --- a/public/templates/topic.tpl +++ b/public/templates/topic.tpl @@ -5,4 +5,12 @@

Posted on {posts.timestamp} by user {posts.uid}.

- \ No newline at end of file + +
+ + \ No newline at end of file diff --git a/src/posts.js b/src/posts.js index c34d088232..b2cac90985 100644 --- a/src/posts.js +++ b/src/posts.js @@ -46,7 +46,7 @@ var RDB = require('./redis.js'); }); } - callback({'posts': posts}); + callback({'posts': posts, 'TOPIC_ID': tid}); }); } else { callback({}); diff --git a/src/templates.js b/src/templates.js index f38a195475..c74aba7934 100644 --- a/src/templates.js +++ b/src/templates.js @@ -60,11 +60,11 @@ 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, ''); } - + for (var d in data) { if (data.hasOwnProperty(d)) { if (data[d] instanceof String || data[d] === null) { From e658531a676ed1ab277bde47b4330c5c27bf6413 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Wed, 1 May 2013 20:58:36 +0000 Subject: [PATCH 2/5] replies are up --- public/src/app.js | 55 +++++++++++++++++++++++++++++++------ public/templates/header.tpl | 6 ++-- public/templates/topic.tpl | 2 +- src/posts.js | 13 +++++++-- src/redis.js | 4 +++ src/templates.js | 2 +- src/websockets.js | 4 +++ 7 files changed, 70 insertions(+), 16 deletions(-) diff --git a/public/src/app.js b/public/src/app.js index 64dd8378ff..20732a2b5a 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -79,17 +79,57 @@ var socket, } var post_window = null, - mode = 'topic', - topic_id = null; + submit_post_btn = null, + post_title = null, + post_content = null; + + app.open_post_window = function(post_mode, id) { + submit_post_btn = submit_post_btn || document.getElementById('submit_post_btn'); + post_title = post_title || document.getElementById('post_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(); - mode = (post_mode == null) ? 'topic' : mode; - topic_id = (mode == 'reply') ? topic_id : null; + if (post_mode == null || post_mode == 'topic') { + post_title.style.display = 'block'; + post_title.focus(); + submit_post_btn.onclick = function() { + app.post_topic(); + } + } else { + post_title.style.display = 'none'; + 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; @@ -99,10 +139,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; diff --git a/public/templates/header.tpl b/public/templates/header.tpl index d18ac06159..3f0ac6af5a 100644 --- a/public/templates/header.tpl +++ b/public/templates/header.tpl @@ -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 { @@ -161,7 +161,7 @@ diff --git a/public/templates/topic.tpl b/public/templates/topic.tpl index b5e32b08c4..fa901d285c 100644 --- a/public/templates/topic.tpl +++ b/public/templates/topic.tpl @@ -13,4 +13,4 @@ var post_reply = document.getElementById('post_reply'); post_reply.onclick = function() { app.open_post_window('reply', {TOPIC_ID}); } - + diff --git a/src/posts.js b/src/posts.js index 4c51b92ea5..b3117b3286 100644 --- a/src/posts.js +++ b/src/posts.js @@ -48,7 +48,7 @@ var RDB = require('./redis.js'), }); } - callback({'posts': posts, 'TOPIC_ID': tid}); + callback({'TOPIC_ID': tid, 'posts': posts}); }); } else { callback({}); @@ -60,8 +60,17 @@ var RDB = require('./redis.js'), } - Posts.reply = function() { + Posts.reply = function(tid, uid, content) { + Posts.create(uid, content, function(pid) { + RDB.rpush('tid:' + tid + ':posts', pid); + global.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) { diff --git a/src/redis.js b/src/redis.js index 0a6e633272..a71cc1e3d5 100644 --- a/src/redis.js +++ b/src/redis.js @@ -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); diff --git a/src/templates.js b/src/templates.js index c74aba7934..8fb384a2e6 100644 --- a/src/templates.js +++ b/src/templates.js @@ -93,7 +93,7 @@ var fs = require('fs'); block = parse(data[d], namespace, block); template = setBlock(regex, block, template); - } else { + } else { template = replace(namespace + d, data[d], template); } } diff --git a/src/websockets.js b/src/websockets.js index ba6786fc80..aa8fb58ac1 100644 --- a/src/websockets.js +++ b/src/websockets.js @@ -93,6 +93,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(); }); From b2bc967e9b63508590ab490717469841481e6d5a Mon Sep 17 00:00:00 2001 From: psychobunny Date: Wed, 1 May 2013 21:26:47 +0000 Subject: [PATCH 3/5] got ajaxify working with threads, some cleanup, fixed anon posting, got rid of a few more global.sockets calls --- public/src/ajaxify.js | 4 ++-- public/src/app.js | 6 +++++- public/src/templates.js | 9 +++++---- public/templates/home.tpl | 2 +- src/posts.js | 4 +--- src/topics.js | 4 ++-- src/webserver.js | 26 +++++++++++++++----------- 7 files changed, 31 insertions(+), 24 deletions(-) diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index ac3d7d4db0..9646720521 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -22,8 +22,8 @@ var ajaxify = {}; ajaxify.go = function(url, callback) { var url = url.replace(/\/$/, ""); - var tpl_url = (url === '') ? 'home' : url; - + var tpl_url = (url === '') ? 'home' : url.split('/')[0]; + if (templates[tpl_url]) { window.history.pushState({}, url, "/" + url); diff --git a/public/src/app.js b/public/src/app.js index 20732a2b5a..1061b2d935 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -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 : ''); diff --git a/public/src/templates.js b/public/src/templates.js index fe7036a778..7605f9191a 100644 --- a/public/src/templates.js +++ b/public/src/templates.js @@ -26,7 +26,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 +116,11 @@ 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 === '') ? 'home' : url; + + jQuery.get(API_URL + url, function(data) { - document.getElementById('content').innerHTML = templates[url].parse(JSON.parse(data)); + document.getElementById('content').innerHTML = templates[url.split('/')[0]].parse(JSON.parse(data)); if (callback) callback(); }); } \ No newline at end of file diff --git a/public/templates/home.tpl b/public/templates/home.tpl index e65f469776..b49f4c2e85 100644 --- a/public/templates/home.tpl +++ b/public/templates/home.tpl @@ -1,7 +1,7 @@
    -
  • +
  • {topics.title}

    Posted {topics.relativeTime} by user {topics.uid}. {topics.post_count} posts.

  • diff --git a/src/posts.js b/src/posts.js index b3117b3286..07e8fc239a 100644 --- a/src/posts.js +++ b/src/posts.js @@ -64,7 +64,7 @@ var RDB = require('./redis.js'), Posts.create(uid, content, function(pid) { RDB.rpush('tid:' + tid + ':posts', pid); - global.socket.emit('event:alert', { + socket.emit('event:alert', { title: 'Reply Successful', message: 'You have successfully replied. Click here to view your reply.', type: 'notify', @@ -74,8 +74,6 @@ var RDB = require('./redis.js'), }; Posts.create = function(uid, content, callback) { - console.log("global uid "+uid); - if (uid === null) return; RDB.incr('global:next_post_id', function(pid) { diff --git a/src/topics.js b/src/topics.js index aa41f8684e..15cadbb806 100644 --- a/src/topics.js +++ b/src/topics.js @@ -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', diff --git a/src/webserver.js b/src/webserver.js index e895b72200..740d0aefdf 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -69,32 +69,36 @@ var express = require('express'), }); - // 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('/api/:method', api_method); + app.get('/api/:method/:id', api_method); + app.get('/api/:method/:id*', api_method); app.get('/login', function(req, res) { res.send(templates['header'] + templates['login'] + templates['footer']); From 1bec9fc5aa86af17cea52edbe6c0ca14eb61f810 Mon Sep 17 00:00:00 2001 From: psychobunny Date: Wed, 1 May 2013 21:52:40 +0000 Subject: [PATCH 4/5] breadcrumbs, and changed home in nav to 'forum' --- public/src/app.js | 11 ++++-- public/src/templates.js | 1 - public/templates/header.tpl | 9 ++++- public/templates/topic.tpl | 9 ++++- src/posts.js | 78 ++++++++++++++++++------------------- 5 files changed, 63 insertions(+), 45 deletions(-) diff --git a/public/src/app.js b/public/src/app.js index 1061b2d935..a45effa90d 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -85,12 +85,14 @@ var socket, 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) { + 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'); @@ -98,13 +100,16 @@ var socket, jQuery(post_window).slideToggle(250); if (post_mode == null || post_mode == 'topic') { - post_title.style.display = 'block'; + 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'; + 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) diff --git a/public/src/templates.js b/public/src/templates.js index 7605f9191a..e7ead3b743 100644 --- a/public/src/templates.js +++ b/public/src/templates.js @@ -119,7 +119,6 @@ function load_template(callback) { url = (url === '') ? 'home' : url; jQuery.get(API_URL + url, function(data) { - document.getElementById('content').innerHTML = templates[url.split('/')[0]].parse(JSON.parse(data)); if (callback) callback(); }); diff --git a/public/templates/header.tpl b/public/templates/header.tpl index 3f0ac6af5a..45604a7adf 100644 --- a/public/templates/header.tpl +++ b/public/templates/header.tpl @@ -117,6 +117,11 @@ font-size: 12px; font-weight: bold; } + #reply_title { + font-size: 17px; + padding-top: 14px; + font-weight: 600; + } @@ -132,7 +137,7 @@
    +
    \ No newline at end of file diff --git a/public/templates/topic.tpl b/public/templates/topic.tpl index fa901d285c..6abc380cf8 100644 --- a/public/templates/topic.tpl +++ b/public/templates/topic.tpl @@ -1,3 +1,10 @@ +
    + +
    +
    • @@ -11,6 +18,6 @@ diff --git a/src/posts.js b/src/posts.js index 07e8fc239a..9e46407864 100644 --- a/src/posts.js +++ b/src/posts.js @@ -16,47 +16,47 @@ var RDB = require('./redis.js'), if (start == null) start = 0; if (end == null) end = start + 10; - RDB.lrange('tid:' + tid + ':posts', start, end, function(pids) { - - var content = [], - uid = [], - timestamp = []; - - for (var i=0, ii=pids.length; i 0) { - RDB.multi() - .mget(content) - .mget(uid) - .mget(timestamp) - .exec(function(err, replies) { - content = replies[0]; - uid = replies[1]; - timestamp = replies[2]; - - var posts = []; - for (var i=0, ii=content.length; i 0) { + RDB.multi() + .mget(content) + .mget(uid) + .mget(timestamp) + .exec(function(err, replies) { + content = replies[0]; + uid = replies[1]; + timestamp = replies[2]; + + var posts = []; + for (var i=0, ii=content.length; i Date: Wed, 1 May 2013 22:19:54 +0000 Subject: [PATCH 5/5] small refactor of routing, cleanup, templates are now parsed entirely on client side for /, /register, /login for now --- public/src/ajaxify.js | 2 +- public/src/templates.js | 16 +++++++++++++++- public/templates/header.tpl | 29 +++++++++++++++++++++++++++++ public/templates/topic.tpl | 4 ++-- src/webserver.js | 26 +++++++++++++------------- 5 files changed, 60 insertions(+), 17 deletions(-) diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index 9646720521..ac96a7d6be 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -22,7 +22,7 @@ var ajaxify = {}; ajaxify.go = function(url, callback) { var url = url.replace(/\/$/, ""); - var tpl_url = (url === '') ? 'home' : url.split('/')[0]; + var tpl_url = (url === '' || url === '/') ? 'home' : url.split('/')[0]; if (templates[tpl_url]) { window.history.pushState({}, url, "/" + url); diff --git a/public/src/templates.js b/public/src/templates.js index e7ead3b743..f18b1e50b6 100644 --- a/public/src/templates.js +++ b/public/src/templates.js @@ -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])); } @@ -116,7 +130,7 @@ function load_template(callback) { rootUrl = location.protocol + '//' + (location.hostname || location.host) + (location.port ? ':' + location.port : ''); var url = location.href.replace(rootUrl +'/', ''); - url = (url === '') ? 'home' : url; + url = (url === '' || url === '/') ? 'home' : url; jQuery.get(API_URL + url, function(data) { document.getElementById('content').innerHTML = templates[url.split('/')[0]].parse(JSON.parse(data)); diff --git a/public/templates/header.tpl b/public/templates/header.tpl index 45604a7adf..a22c9e7e0a 100644 --- a/public/templates/header.tpl +++ b/public/templates/header.tpl @@ -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; diff --git a/public/templates/topic.tpl b/public/templates/topic.tpl index 6abc380cf8..4c8ebfa9cb 100644 --- a/public/templates/topic.tpl +++ b/public/templates/topic.tpl @@ -5,9 +5,9 @@
    -
      +
        -
      • +
      • {posts.content}

        Posted {posts.relativeTime} by user {posts.uid}.

      • diff --git a/src/webserver.js b/src/webserver.js index 740d0aefdf..8a7a229c50 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -62,12 +62,20 @@ var express = require('express'), // 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; itemplates.ready(function(){ajaxify.go("' + route + '");});' + templates['footer']); + }); + }(routes[i])); + } + }()); + function generate_topic_body(req, res) { global.modules.topics.generate_topic_body(function(topic_body) { @@ -100,10 +108,6 @@ var express = require('express'), app.get('/api/:method/:id', api_method); app.get('/api/:method/:id*', api_method); - app.get('/login', function(req, res) { - res.send(templates['header'] + templates['login'] + templates['footer']); - }); - app.get('/logout', function(req, res) { console.log('info: [Auth] Session ' + res.sessionID + ' logout (uid: ' + global.uid + ')'); global.modules.user.logout(req.sessionID, function(logout) { @@ -124,10 +128,6 @@ var express = require('express'), 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']); });